Question

I want to use generate statement inside a task. The following code is giving compile errors (iverilog).

task write_mem; //for generic use with 8, 16 and 32 bit mem writes
      input [WIDTH-1:0] data;
      input [WIDTH-1:0] addr;
      output [WIDTH-1:0] MEM;
      integer i;

      begin
         generate
            genvar j;
            for(j=0; j<i;j++)
            MEM[addr+(i-j-1)] = data[(j*8):((j*8) + 8)-1];
         endgenerate
      end
endtask // write_mem

I also tried putting generate just after the line integer i, but still its producing errors. Any thoughts?

EDIT: I also tried putting genvar declaration between begin and generate statement in the above code. Its still producing compiler errors

Thanks in advance,

Jay Aurabind

Was it helpful?

Solution

What you are trying is not possible - a generate region (generate..endgenerate block) is only allowed in the module description (aka "top level"), i.e. the same level where you have parameters, wires, always- and inital-regions, etc. (see Syntax 12-5 in the IEEE Std. 1364-2005). Within a task a generate region is e.g. as invalid as an assign statement.

However, you can use a non-generate for-loop in a task (this is also synthesizeable).

Either way, you can not count from 0 to i-1 in synthesizeable code as 'i' is not constant. Also note that j++ is not valid verilog, you must write j=j+1 instead. Finally you probably want to use a nonblocking assignment (<=) instead of a blocking assignment (=), but this depends on how you intent to use this task.

OTHER TIPS

genvars should be defined before the generate statement:

genvar j;
generate
  for(j=0; j<i;j++)
    MEM[addr+(i-j-1)] = data[(j*8):((j*8) + 8)-1];
endgenerate

Although your usage here does not look like it needs a generate statement a for loop would have done.

As pointed out by @CliffordVienna generate statements are for building hierarchy and wiring based on compile time constants. ie parameters can be changed for reusable code but are constant in a given simulation. Tasks do not contain hierarchy and therefore the use of a generate is invalid.

Any for loop that can be unrolled is synthesizable, some thing like:

task write_mem; //for generic use with 8, 16 and 32 bit mem writes
  input  [WIDTH-1:0] data;
  input  [WIDTH-1:0] addr;
  output [WIDTH-1:0] mem;
  integer i = WIDTH / 8; // CONSTANT   

  begin
    for(j=0; j<i;j++) begin
      mem[addr+(i-j-1)] = data[(j*8):((j*8) + 8)-1];
    end
  end
endtask // write_mem

Tasks are synthesizable as long as they do not contain any timing control, which yours does not. From the information given this should be synthesizable.

NB: I would separate data width and addr width, they might be the same now but you might want to move to 8 bit addressing and 16 bit data.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top