在verilog任务中生成语句

时间:2013-05-27 10:01:07

标签: verilog hdl

我想在任务中使用generate语句。以下代码给出了编译错误(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

我还尝试将generate放在行integer i之后,但仍然产生错误。有什么想法吗?

编辑:我还尝试在genvarbegin语句之间添加generate声明。它仍然产生编译器错误

提前致谢,

杰伊·奥拉宾德

2 个答案:

答案 0 :(得分:4)

您正在尝试的是不可能的 - 生成区域(generate..endgenerate block)仅允许在模块描述(也称为“顶级”)中,即您具有参数,电线,始终和 - 的相同级别初始区域等(参见IEEE Std.1364-2005中的语法12-5)。在任务中,生成区域例如是与assign语句无效。

但是,您可以在任务中使用非生成for循环(这也是可合成的)。

无论哪种方式,你都不能在可合成代码中从0到i-1计数,因为'i'不是常数。另请注意,j ++不是有效的verilog,您必须编写j = j + 1。最后,您可能希望使用非阻塞分配(&lt; =)而不是阻塞分配(=),但这取决于您打算如何使用此任务。

答案 1 :(得分:1)

genvars应该在generate语句之前定义:

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

虽然你在这里的用法看起来不像需要一个生成语句,for循环就可以了。

正如@CliffordVienna所指出的,生成语句用于构建基于编译时常量的层次结构和连线。即,可以为可重复使用的代码更改参数,但在给定的模拟中这些参数是常量。任务不包含层次结构,因此生成的使用无效。

任何可以展开的for循环都是可综合的,有些类似于:

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

任务是可综合的,只要它们不包含任何时序控制,而您的时间控制不包含任何时序控制。根据给出的信息,这应该是可综合的。

注意:我会将数据宽度和地址宽度分开,它们现在可能相同,但您可能希望转移到8位​​寻址和16位数据。