I noticed XST 9.1 still doesn't support multi-dim arrays in an always @* block. Here's a (perhaps poor) example:
reg signed [15:0] table [0:255]; reg signed [23:0] sum;
integer i; always @* begin sum = 0; for ( i =0; i < 256; i = i + 1 ) sum = sum + table[i]; // yes, I know this will synthesize a suboptimal imbalanced adder-tree! end
Correct me if I'm wrong, but I believe that this is not valid verilog
- you cannot use an array as a term in the always() sensitivity list, and the always* implies that the array is in the sensitivity list. I know that the ncverilog simulator warns about this (but does work). It states that this is non-portable verilog. Synopsys DC does indeed synthesize this correctly, but it's not a good idea to use non- standard verilog statements. ISE seems to err on the side of adhering to the strict rules of the verilog language. I could be wrong about this, but from the warning given by ncverilog, I believe this to be the case. Maybe try a verilog linting tool? formality/conformal should set you straight, if you have them. Cheers John
always@* | ncvlog: *W,STARMR (array.v,8|6): @* containing memory reference not standard or portable. out = array[idx]; ncvlog: *W,MRSTAR (array.v,10|11): memory reference that was not standard in @*. module worklib.test:v
So clearly always @* when used with an array is non part of the verilog standard.
Maybe, but it would not work if the contents of the array were updated by a different process, independent of idx. I'm not sure how this would be syntesized - It may infer latches on the output, or error out. I'd be interested to see what happens
Personally, for this example (asynch read of array elements) I'd use a continuous assignment.
But personally I think verilog language should support @* in an array context, it works in all other contexts, and prevents unintentional latch inferral. As we can see from Duth, this will be added to ISE soon, and some other tools support it too, but they just warn that it is not strictly part of the standard.
I've heard that this is a "grey" area of the Verilog standard. It shouldn't be at all - the intended behavior is quite clear in your example, and the tools should do the correct thing. Unfortunetly XST doesn't get it right yet. Xilinx promised to fix this is ISE9.x. Now, they've put it off again until 10.x.
We've used VERY similar constructs - except we used SystemVerilog packed arrays, instead of your verilog-2001 "unpacked" array equivalent. This has worked fine for us in ASIC and FPGA flows. It works with VCS, modelsim, dc_shell, and Precision. Of course, you'll need to use the "Systemverilog" switch of the tools - which Xilinx doesn't have yet either.
For your example in SystemVerilog, just change the table definition to: reg signed [ 255 : 0 ] [ 15 : 0 ] table;
And it would work. I'm thinking in the IEEE Std 1800-2005 (SystemVerilog IEEE standard), they may have cleaned this up, and you're original example would work.
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.