7

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?

2
  • Which tool is this? Can you post the minimum code that compiles with the error? Commented Jul 27, 2011 at 16:47
  • The tool is Quartus. The error is: Error (10734): Verilog HDL error at top.v(733): i is not a constant. I heavily edited my code when i posted it here. That's all I can post. Commented Jul 27, 2011 at 17:31

1 Answer 1

5

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].

Sign up to request clarification or add additional context in comments.

1 Comment

thanks a lot! I am such an idiot for not thinking of this... of course this is the obvious solution! I just double checked, and the Quartus compiler was only giving an error on the ranged assignments, not the one with [3-i]. And you did assume everything correctly :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.