简体   繁体   中英

For loop in always block

I have a cache memory module that I want word addressable but have write enable signals for bytes.

always @ (posedge clk) begin
    //stuff...
    if(write) begin
        //Word accessible only
        //memData[lastInIndex][lastInOffset] <= lastWriteData;

        //Supporting byte accessible
        if(lastWrEn[0])
            memData[lastInIndex][lastInOffset][7:0] <= lastWriteData[7:0];
        if(lastWrEn[1])
            memData[lastInIndex][lastInOffset][15:8] <= lastWriteData[15:8];
        if(lastWrEn[2])
            memData[lastInIndex][lastInOffset][23:16] <= lastWriteData[23:16];
        if(lastWrEn[3])
            memData[lastInIndex][lastInOffset][31:24] <= lastWriteData[31:24];
    end
    //more stuff...
end

If I am writing a word to memory, I can specify which bytes should be ignored and which bytes should be written within each word. I have tested this code and it simulates just fine. I would like to parameterize how many bytes are in a word (in the 64 bit case, there are now 8 bytes per word). Rather than just copy and paste more nearly identical lines, I was hoping to have some sort of for loop to instantiate my logic.

always @ (posedge clk) begin
    //stuff...
    if(write) begin
        //Word accessible only
        //memData[lastInIndex][lastInOffset] <= lastWriteData;

        //Supporting byte accessible
        begin : BYTE_SELECTION_GENERATE
            integer i;
            for(i=0; i<bytesPerWord; i=i+1)
                if(lastWrEn[i])
                    memData[lastInIndex][lastInOffset][i*8+7:i*8] <= lastWriteData[i*8+7:i*8];
        end
    end
    //more stuff...
end

I have a parameter called wordSize that specifies how many bits each word contains (usually 32 or 64). There is another parameter that is parameter bytesPerWord = wordSize/8 . When I try to compile this version, I get an error that says i is not a constant . I have also tried genvar and generate but those are not allowed in always blocks. Is there a way to generate the hardware that I want based off of a bytesPerWord parameter, or am I going to have to rely on an ugly string of `ifdef statements?

The error i is not a constant you are getting is because verilog does not allow part selects with dynamic values for the upper and lower value of the range ( net[i:j] ), as this would allow the number of bits in the bus to dynamically change, which is not possible in hardware.

However in your special case since the number of bits being selected is always constant, you can use the indexed part select operator, which looks like:

memData[lastInIndex][lastInOffset][i*8 +: 8];

This does the same thing you are currently attempting to do (select 8 bits starting from i*8), but it uses a special operator to do it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM