Automatic SystemVerilog variable size using interface width and $size?

我的未来我决定 提交于 2019-12-05 00:47:51

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!