0

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?

Cœur
  • 32,421
  • 21
  • 173
  • 232
Snigdha203
  • 101
  • 1
  • 10

1 Answers1

1

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)

Community
  • 1
  • 1
Greg
  • 16,013
  • 5
  • 43
  • 61
  • Thanks for your answer. Flattening `prob` variable works. I will look into other possibilities you have mentioned. – Snigdha203 Jun 24 '16 at 21:50