Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specifying variable range in Verilog using for loop

I am trying to write this code:

 for (i = 0; i <= CONST - 1'b1; i = i + 1'b1)
                    begin : loop_inst

                        if (i < 3)
                        begin
                            if (changed[i] & !done_q[i])
                            begin
                                writedata[3-i] = en[i];
                                writedata[2-i:0] = readdata[2-i:0];
                                writedata[15:4-i] = readdata[15:4-i];
                            end
                        end
                        else
                        ...

Basically, the location of the bit I am trying to write to (en) changes depending on which address I am talking to, depending on i. This code is not synthesizable because i is not a constant.

Is there any other workaround to this? The only workaround I know is writing out those three statements CONST times. I am hoping I DON'T have to do that in the end. Is there any other solution?

like image 326
typon Avatar asked Jul 27 '11 16:07

typon


People also ask

How do you define a for loop in Verilog?

A for loop is the most widely used loop in software, but it is primarily used to replicate hardware logic in Verilog. The idea behind a for loop is to iterate a set of statements given within the loop as long as the given condition is true.

Can we write for loop in Verilog?

Verilog For Loop. When writing verilog code, we use the for loop to execute a block of code a fixed number of times. As with the while loop, the for loop will execute for as long as a given condition is true. The specified condition is evaluated before each iteration of the loop.

Can we use always block inside for loop?

It seems that the for loop isn't allowed inside a always block (The n doesn't seems to reset).


1 Answers

It looks like you're trying to copy readdata to writedata all the time, but fill in the LSBs with en if certain special case conditions are met. I'm also going to assume that the for loop you have is in an always block, and that you're intending to build combo logic.

The for loop as you've it written doesn't make much sense to me from a hardware perspective. A for loop is used for building arrays of logic, and as you've written it you'll have at least 3 logic cones trying to set values on the entire writedata bus. (If it generates anything at all, it'll be some weird priority structure).

That said, it's probably the range selects that your compiler is complaining about, ie the writedata[2-i:0] rather than the writedata[3-i] = en[i]; (anything with : in the part select). If you want to do something along those lines, you can use 'indexed part selects' ( +: or -:) but there are better solutions in this case.

I'd rewrite it as follows - assuming I've assumed correctly :)

always @( /*whatever*/ ) begin

    // default assignment
    writedata = readdata;

    // overwrite some bits in writedata for special cases
    for(i=0; i<3; i++) begin
        if( changed[i] & !done_q[i] )
             writedata[3-i] = en[i];
    end
end

In this code, I'm setting writedata to readdata, and then tweaking the resulting value of writedata if the special cases are in play. The for loop is building 3 logic cones, one for each of the bits in writedata[3:1]. I'd double-check if the bit mapping is what you intend -ie, mapping en[2:0] on to writedata[1:3].

like image 99
Marty Avatar answered Sep 22 '22 02:09

Marty