6

I have an array that I would like to initialize to all 1. To do this, I used the following code snippet:

logic [15:0] memory [8];
always_ff @(posedge clk or posedge reset) begin
   if(reset) begin
      memory <= '{default:'1};
   end
   else begin
      ...
   end  
end

My simulator does what I think is the correct thing and sets the registers to 16'hFFFF on reset. However, my lint tool gives me a warning that bit 0 has an async set while bits 1 through 15 have async resets. This implies that the linter thinks that this code assigns 16'h0001 to the registers.

Since both tools come from the same vendor I file a bug report since they can't both be right.

The question is: Which behavior is correct according to the spec? There is no example that shows this exact situation. Section 5.7.1 mentions that:

An unsized single-bit value can be specified by preceding the single-bit value with an apostrophe ( ' ), but without the base specifier. All bits of the unsized value shall be set to the value of the specified bit. In a self-determined context, an unsized single-bit value shall have a width of 1 bit, and the value shall be treated as unsigned.

'0, '1, 'X, 'x, 'Z, 'z // sets all bits to specified value

I f this is a "self-determined context" then the answer is 1 bit sign extended to 16'h0001, but if it is not, then I guess the example which says it "sets all bits to the specified value" applies. I am not sure if this is a self -determined context.

nguthrie
  • 2,615
  • 6
  • 26
  • 43
  • I think you could validly do `memory <= '1;` here - no need for the struct-and-cast for an simple array. – Chiggs Mar 28 '14 at 16:48
  • @Chiggs That would be great. I am working on a design that has a bunch of arrays and anything that simplifies the syntax is appreciated. I'll try it out. – nguthrie Mar 28 '14 at 17:22
  • 1
    @Chiggs No dice: compilation error. – nguthrie Mar 28 '14 at 17:24
  • It should work for packed arrays - I hadn't noticed you were using unpacked (I tend to always use packed arrays)... – Chiggs Mar 28 '14 at 17:30
  • [Example using packed arrays on EDAPlayground](http://www.edaplayground.com/x/2g2) with Modelsim (which also fails with unpacked arrays). – Chiggs Mar 28 '14 at 17:32

1 Answers1

7

The simulator is correct: memory <= '{default:'1}; will assign all each bit in memory to 1. The linting tool does have a bug. See IEEE Std 1800-2012 § 10.9.1 Array assignment patterns:

  • The **default:***value* applies to elements or subarrays that are not matched by either index or type key. If the type of the element or subarray is a simple bit vector type, matches the self-determined type of the value, or is not an array or structure type, then the value is evaluated in the context of each assignment to an element or subarray by the default and shall be castable to the type of the element or subarray; otherwise, an error is generated. ...

The LRM goes beyond what is synthesizable when it comes to assignment patterns. And most of the tools are sill playing catchup with supporting all the SystemVerilog features. Experiment to make sure your tools (simulator,synthesizer, lint tool, logic-equivalency-checker, etc.) all have the necessary support for the features you want.

Greg
  • 18,111
  • 5
  • 46
  • 68
  • I am definitely going to run an equivalency check and simulate the gates to make sure synthesis doesn't goof like lint did. – nguthrie Mar 28 '14 at 11:12
  • 1
    FYI there's a bug in Quartus where `default: '1` generally works, but if you have nested structs and a literal for one of the struct members uses a `'1` it messes up the assignment. – Chiggs Mar 28 '14 at 14:10
  • @Greg out of curiosity can you give an example of a non-synthesisable assignment pattern? Or were you referring to tool support. AFAIK the LRM doesn't define anywhere whether any construct is intended to be synthesisable or not. – Chiggs Mar 28 '14 at 16:50
  • For example from LRM § 10.9.2 `struct { logic [7:0] a; bit b; bit signed [31:0] c; string s; } s2 = '{int:1, default:0, string:""};` cannot synthesize because `string` is not synthesizable. In theory the following can synthesize but my not be supported: LRM § 10.9 `integer i = '{31:1, 23:1, 15:1, 8:1, default:0};` and `struct { int A; struct { int B, C; } BC1, BC2;} ABC = '{A:1, BC1:'{B:2, C:3}, BC2:'{B:4,C:5}};`. Most projects you try not to mix async set/reset in the same assignment. I'm not sure where it would be practical to assign complex sturcts in one shot outside of a testbench. – Greg Mar 28 '14 at 20:46