verilog实例化时序块的方法

Method of instantiating sequential block in verilog

我想在另一个模块中实例化顺序计数器块。这些是以下模块。当我在 synopsys 设计视觉环境中综合这些模块时,它提供了以下错误消息,

prob_calculator.sv:1: Illegal reference to memory prob. (VER-253)

module counter #(parameter m=16) (input en,input clk,input reset,output reg [m-1:0] out);

always @(posedge clk)
if(reset) begin
    out <= 0;
end
else if (en) begin
    out <= out+1;
end
endmodule

计数器块的实例化:

module prob_calculator #(parameter n=32,parameter m=6,parameter Ir=14) (input
[n-1:0]b,input clk,input reset,output reg [m-1:0] prob [0:Ir-1]);

genvar i;
generate
for (i=0;i<Ir;i=i+1) begin:x1
counter #(.m(m)) count_blck(.en(1),.clk(clk),.reset(reset),.out(prob[i]));
end
endgenerate
endmodule

任何人都可以指出代码有什么问题吗?

Verilog 不支持通过端口的多维数组。 SystemVerilog 确实支持多维数组端口。但是,并非所有 SystemVerilog 合成器都支持此功能。

在解决如何绕过多维端口限制之前,我想指出 probe 应该声明为 wire 而不是 reg。在 Verilog 中,当变量在当前模块(不是其子模块或父模块)中被程序块(即 alwaysinitial)赋值时,应声明为 reg ), 否则应声明为 wire。使用 SystemVerilog,您还可以使用 logic 并且可以更自由地使用 logic 类型;所有使用 reg 的地方和大多数使用 wire 的地方(不包括具有多个驱动器的 wires)。

如果您将 probereg 更改为 wire 它可能会让您的合成器满意,但它可能不会。

一种方法是将 prob 展平为单个向量:将 output reg [m-1:0] prob [0:Ir-1] 更改为 output wire [Ir*m-1:0] prob。然后将 out 和 probe 之间的连接更改为新概率向量的一部分:.out(prob[i]).out(prob[i*m +: m])(参见 Indexing vectors and arrays with +:)。这种方法适用于 SystemVerilog 和 Verilog(IEEE1364-2001 及更高版本)。

module prob_calculator #(parameter n=32,parameter m=6,parameter Ir=14) (input
[n-1:0]b,input clk,input reset,output <b><i>wire</i></b> [<b><i>Ir*m-1:0</i></b>] prob);

  genvar i;
  generate
    for (i=0;i<Ir;i=i+1) begin:x1
      counter #(.m(m)) count_blck(.en(1),.clk(clk),.reset(reset),.out(prob[<b><i>i*m +: m</i></b>]));
    end
  endgenerate
endmodule

SystemVerilog 提供了其他可能性,例如使用 (typedef, packed struct, interface, modport) 如果多维端口是不直接支持。最好参考您的合成器手册,确保启用 SystemVerilog 选项并检查支持的功能 are/are-not。


仅供参考:对于 SystemVerilog,它重新开始使用 always_ff@(posedge clk) 而不是 always@(posedge clk)