1

我想在任务中使用生成语句。以下代码给出编译错误(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在 line 之后放置integer i,但仍然会产生错误。有什么想法吗?

编辑:我还尝试在上面的代码中genvar声明begin和声明。generate它仍然产生编译器错误

提前致谢,

杰·奥拉宾德

4

2 回答 2

5

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

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

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

于 2013-05-27T19:01:42.200 回答
1

genvars 应该在生成语句之前定义:

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 位数据。

于 2013-05-27T11:12:44.393 回答