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?
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.
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.
It seems that the for loop isn't allowed inside a always block (The n doesn't seems to reset).
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]
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With