Reputation: 101
I want to instantiate sequential counter block in another module. These are the following modules. When I synthesize these modules in synopsys design vision environment it provides the following error message,
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
Instantiation of the counter block:
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
Can anyone please point out what is wrong with the code?
Upvotes: 0
Views: 745
Reputation: 19132
Verilog does not support multi-dimensional arrays through ports. SystemVerilog does support multi-dimensional array ports. However, not all SystemVerilog synthesizers support this feature.
Before addressing how to get around the multi-dimensional port constraint, I want to point out that probe
should be declared as a wire
not a reg
. In Verilog, a variable should be declared as a reg
when it is assigned by an procedural block (i.e. always
or initial
) in the current module (not its sub-module or parent module), otherwise it should be declared as a wire
. With SystemVerilog you could also use logic
and may use the logic
type more liberally; all places where you use reg
and most places where you use wire
(exclude wires
that have multiple drives).
If you change probe
from reg
to wire
it may make your synthesizer happy, but it probably won't.
One way is to flatten prob
into a single vector: change output reg [m-1:0] prob [0:Ir-1]
to output wire [Ir*m-1:0] prob
. Then change the connections between out and probe into an slice of new prob vector: .out(prob[i])
to .out(prob[i*m +: m])
(See Indexing vectors and arrays with +:). This approach is works with SystemVerilog and Verilog (IEEE1364-2001 and above).
module prob_calculator #(parameter n=32,parameter m=6,parameter Ir=14) (input
[n-1:0]b,input clk,input reset,output wire [Ir*m-1:0] 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[i*m +: m]));
end
endgenerate
endmodule
SystemVerilog offers other possibilities such as using (typedef
, packed struct
, interface
, modport
) that may work as work around if multi-dimensional port are not directly supported. It is best to refer to your synthesizer's manual, ensure the SystemVerilog option is enabled and check for what features are/are-not supported.
FYI: With SystemVerilog its recommenced to use always_ff@(posedge clk)
instead of always@(posedge clk)
Upvotes: 1