问题
I am getting the following error in System Verilog with VCS synthesizer:
The following access has an invalid number of indices. bus[i]
I am basically trying to do a parametrizable mux made of interfaces, with the select bus being one-hot:
module myMux
#(int unsigned WIDTH=3)
(
my_interface bus[WIDTH-1:0],
input logic [WIDTH-1:0] select,
output logic [31:0] out_data
)
always_comb begin
out_data = 'x;
for (int unsigned i=0; i < WIDTH; i++) begin
if (select[i]) out_data = bus[i].in_data;
end
end
endmodule
I tried the different methods outlined in this answer here (including using |= ) but I always get the same error. Using a "genvar i" instead of an int does not even compile.
If I replace bus[i] with bus[0], then it compiles (but it is not what I want) . . . also, replacing WIDTH with a number in the for statement (ie i < 1) gives me the same error even though it is less than the value of WIDTH.
Any ideas? the code needs to be synthesizable.
回答1:
Accessing an instances of an arrayed interface can only be accessed via a simulation constant (parameter, genvar, or hard-coded number). Data types and design elements both use dotted names to access there respected member or hierarchical-name, but the rules for accessing index arrays are different. Best description I can quickly find is in IEEE Std 1800-2012 § 23.6 Hierarchical names and § 23.7 Member selects and hierarchical names.
Here are two possible solutions:
Tri-state solution: floating if select is 0, x on the bit with multiple conflicting drivers.
module myMux
#(int unsigned WIDTH=3)
(
my_interface bus[WIDTH-1:0],
input logic [WIDTH-1:0] select,
output wire [31:0] out_data
);
for (genvar i=0; i < WIDTH; i++) begin : loop
assign out_data = select[i] ? bus[i].in_data : 'z;
end
endmodule
Priority selector: using a local 2D array to map the interface instances. This map
can be accessed in an always block. If you are on FPGA, this is the better solution as it doesn't need tri-state.
module myMux
#(int unsigned WIDTH=3)
(
my_interface bus[WIDTH-1:0],
input logic [WIDTH-1:0] select,
output logic [31:0] out_data
);
logic [31:0] map [WIDTH];
for (genvar i=0; i < WIDTH; i++) begin : loop
assign map[i] = bus[i].in_data;
end
always_comb begin
out_data = 'x;
for(int unsigned i=0; i<WIDTH; i++) begin
if (select[i]) out_data = map[i];
end
end
endmodule
来源:https://stackoverflow.com/questions/33580513/how-do-i-implement-a-parametrizable-mux-in-systemverilog