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 中,当变量在当前模块(不是其子模块或父模块)中被程序块(即 always
或 initial
)赋值时,应声明为 reg
), 否则应声明为 wire
。使用 SystemVerilog,您还可以使用 logic
并且可以更自由地使用 logic
类型;所有使用 reg
的地方和大多数使用 wire
的地方(不包括具有多个驱动器的 wires
)。
如果您将 probe
从 reg
更改为 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)
我想在另一个模块中实例化顺序计数器块。这些是以下模块。当我在 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 中,当变量在当前模块(不是其子模块或父模块)中被程序块(即 always
或 initial
)赋值时,应声明为 reg
), 否则应声明为 wire
。使用 SystemVerilog,您还可以使用 logic
并且可以更自由地使用 logic
类型;所有使用 reg
的地方和大多数使用 wire
的地方(不包括具有多个驱动器的 wires
)。
如果您将 probe
从 reg
更改为 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)