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?

tk421
  • 5,775
  • 6
  • 23
  • 34
typon
  • 103
  • 1
  • 6
  • Which tool is this? Can you post the minimum code that compiles with the error? –  Jul 27 '11 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. – typon Jul 27 '11 at 17:31

1 Answers1

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

Marty
  • 6,494
  • 3
  • 37
  • 40
  • 2
    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 :) – typon Jul 27 '11 at 17:17