问题
I am trying to make a module (a DSP in my case) with a standardized memory interface in SystemVerilog, and would like the variables in the module to size automatically based on the bus widths in the attached interface. My rationale: this makes the code more portable by allowing it to auto-size to any connected interface, instead of requiring an HDL coder to pass in parameters that tell the module the widths of all the interface busses that will connect to it (not that this would be terrible, it just seems cleaner without the parameters).
I can't seem to get this to work, however. Here's an example that illustrates the problem; the following synthesizes in Quartus II 12.1:
// Top level module with some 15-bit ports
module top ( input [14:0] data_in,
output [14:0] data_out1, data_out2,
data_out3, data_out4 );
test_interface my_interface(); // Initialize the interface
test_module my_module(.*); // Initialize & connect module
endmodule
// Define a simple interface:
interface test_interface ();
logic [8:0] my_port;
endinterface
// Define the module:
module test_module ( input [14:0] data_in,
test_interface my_interface,
output [14:0] data_out1, data_out2,
data_out3, data_out4 );
localparam width1 = $size(data_in); // should be 15
localparam width2 = $size(my_interface.my_port); // should be 9
logic [width1-1:0] auto_sized1; // gets correct size (14:0)
logic [width2-1:0] auto_sized2; // **PROBLEM**: gets size of 0:0!
always_comb begin
auto_sized1 = 5; // ok
auto_sized2 = 5; // problem; value now truncated to 1
data_out1 = data_in + width1; // Yields data_in + 15 (ok)
data_out2 = data_in + width2; // Yields data_in + 9 (ok...!)
data_out3 = data_in + auto_sized1; // Yields data_in + 5 (ok)
data_out4 = data_in + auto_sized2; // Yields data_in + 1 (problem)
end
endmodule
Note that width2
does eventually get the correct value (9) - just too late for it to correctly set the width of auto_sized2
. I initially thought that $size
was simply evaluated after all variables had been assigned their widths, but this doesn't seem to be the case either since $size(data_in)
works just fine for setting the width of auto_sized1
.
Any thoughts? Again, it's not critical to the project's success, I'm mostly curious at this point!
Thanks -
回答1:
Looks like a compiler bug. I'd probably use a parameter in the interface definition.
module top ( input [14:0] data_in,
output [14:0] data_out1, data_out2,
data_out3, data_out4 );
test_interface #(.port_size(8)) my_interface(); // Initialize the interface
test_module my_module(.*); // Initialize & connect module
endmodule
interface test_interface ();
parameter port_size = 1;
logic [port_size-1:0] my_port;
endinterface
module test_module ( input [14:0] data_in,
test_interface my_interface,
output [14:0] data_out1, data_out2,
data_out3, data_out4 );
localparam width1 = $size(data_in);
localparam width2 = my_interface.port_size;
endmodule
来源:https://stackoverflow.com/questions/14307306/automatic-systemverilog-variable-size-using-interface-width-and-size