04-12-2018 01:28 PM
A full version of the summarized SystemVerilog code below is handled by the Vivado simulator without issue, but synthesis raises "cannot resolve hierarchical name for the item 'data'" where the localparam DATA_WIDTH is assigned to $bits(din.data). Synthesis doesn't complain when din.data is accessed in the logic (e.g., data <= din.data). Is there a different syntax I should be using, or is this a bug? Thanks.
interface MyBus #(DATA_WIDTH = 8) (); logic [(DATA_WIDTH-1):0] data; ... endinterface
module MyModule (input MyBus din);
localparam DATA_WIDTH = $bits(din.data); // SYNTHESIS CANNOT RESOLVE HIERARCHICAL NAME
data <= din.data; // SYNTHESIS DOESN'T COMPLAIN
MyBus #(.DATA_WIDTH(32)) bus_i ();
MyModule module_i (.din(bus_i));
04-12-2018 05:20 PM - edited 04-12-2018 09:51 PM
04-12-2018 08:18 PM
Hi @trothlis ,
What Vivado version are you using ?
SystemVerilog hierarchical name support has only been added in one of the latest Vivado revs.
Using 2017.4. Note that the hierarchical name is accepted in the always blocks. It's only the attempt to use it in the localparam that fails.
04-16-2018 03:23 PM
An alternative solution - which also doesn't work (well, I've not checked since Vivado 2016.4) - but REALLY should work. I'd tried this before I knew about the $bits system task.
interface MyBus #(DATA_WIDTH = 8) (); logic [(DATA_WIDTH-1):0] data; function int get_data_size; return( DATA_WIDTH ); endfunction ... endinterface module MyModule (input MyBus din); localparam DATA_WIDTH = din.get_data_size(); ... data <= din.data; // SYNTHESIS DOESN'T COMPLAIN ... endmodule module TopModule(); MyBus #(.DATA_WIDTH(32)) bus_i (); MyModule module_i (.din(bus_i)); ... endmodule
These sorts of things would really go a long way into abstracting concepts, allow a much higher level of design. I'm hoping Xilinx will eventually support this...
04-25-2018 10:34 AM - edited 04-25-2018 12:09 PM
You can't create a localparam like that, annoyingly, but you can use $bits() directly in the declaration of a variable or to initialise a const int. So:
const int DATA_WIDTH = $bits(din.data); logic [$bits(din.data)/2-1:0] lsbs; assign lsbs = din.data[DATA_WIDTH/2-1:0];
Gets you most of the way there, and seems to synthesise and simulate.
Also, in 2018.1 you can access the parameters in synthesis but not simulation, and use $bits in simulation but not synthesis, so you can also do:
`ifdef SYNTHESIS localparam DATA_WIDTH = din.DATA_WIDTH; `else localparam DATA_WIDTH = $bits(din.data); `endif
Hopefully Xilinx will sort this out properly soon, it's all so nearly there.
04-25-2018 02:08 PM
Thanks for this info! That's a good find. I may be able to take advantage of these features.
Any comments from Xilinx? Both forms that @patstew listed, as well as my example, and the example from @trothlis should all work in Vivado.
Personally, I only care about Vivado Synthesis, but I'm sure that other Xilinx users would desire on par results from both Synthesis and Simulation. The fact that the two tools only support differing implementation isn't ideal at all.