Jay Aurabind
Jay Aurabind

Reputation: 261

Generate statement inside verilog task

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

Upvotes: 1

Views: 11530

Answers (2)

Morgan
Morgan

Reputation: 20514

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.

Upvotes: 1

CliffordVienna
CliffordVienna

Reputation: 8235

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.

Upvotes: 5

Related Questions