FPGARelated.com
Forums

initializing a small array in Verilog

Started by David Bridgham January 12, 2019
In my Verilog code I have this line:

   reg [1:0] ip_list [0:3] = { 2'd2, 2'd1, 2'd0, 2'd1 };

Both Icarus and Vivado seem happy with it and it does what I expect.

However, I recently discovered Verilator and its lint capability so I've
been running it over all my code to see if there is anything I ought to
clean up.  Verilator does not like this code, it says the LHS only has 2
bits while the right is 8 bits, so I'm wondering if I should be writing
it differently.  Maybe I've only been lucky so far that it's worked at
all and I'd rather have my code correct than lucky.

Thanks for any help,
Dave
On Saturday, January 12, 2019 at 3:34:25 PM UTC-7, David Bridgham wrote:
> In my Verilog code I have this line: > > reg [1:0] ip_list [0:3] = { 2'd2, 2'd1, 2'd0, 2'd1 }; > > Both Icarus and Vivado seem happy with it and it does what I expect. > > However, I recently discovered Verilator and its lint capability so I've > been running it over all my code to see if there is anything I ought to > clean up. Verilator does not like this code, it says the LHS only has 2 > bits while the right is 8 bits, so I'm wondering if I should be writing > it differently. Maybe I've only been lucky so far that it's worked at > all and I'd rather have my code correct than lucky. > > Thanks for any help, > Dave
That does not look like it should work. If you set the tool to SystemVeriliog mode you should be able to initialize the reg like this: reg [1:0] ip_list [0:3] = '{ 2'd2, 2'd1, 2'd0, 2'd1 }; // note extra tick In Verilog-2005 mode, I think you should only be able to set the unpacked elements individually or with $readmemh.
On 1/13/19 12:28 PM, Kevin Neilson wrote:

> > That does not look like it should work. If you set the tool to SystemVeriliog mode you should be able to initialize the reg like this: > > reg [1:0] ip_list [0:3] = '{ 2'd2, 2'd1, 2'd0, 2'd1 }; // note extra tick > > In Verilog-2005 mode, I think you should only be able to set the unpacked elements individually or with $readmemh.
Neither $readmemh nor setting the entries individually are particularly appealing so I guess it's time to learn about SystemVerilog. And, in fact, I've been reading up on it since seeing your response. Enums and structs, I should have looked into this before. I could like this language. So that extra single quote you added, what are the semantics of that? I see it often enough in examples when I'm reading about SystemVerilog but I have yet to find anything that describes what it actually means. Thanks, Dave
SystemVerilog is great if your tools support it.  Most synthesis tools have at least some support.  Unfortunately the stuff I write has to be support a lot of different tools, some of which are very primitive, so I'm stuck with Verilog-2005 and sometimes even that is too advanced.

I think the extra tick is to show that you are referring to an "unpacked" dimension (one specified on the right of the variable name).  You can also initialize multiple unpacked dimensions, something like this:

  reg [1:0] ip_list [0:1][0:3] = '{  '{2'd2, 2'd1, 2'd0, 2'd1 }, '{2'd2, 2'd1, 2'd0, 2'd1 } };  // tick for each unpacked group

I don't think you need to specify the size of the packed elements since they will be sized to the packed dimension:

  reg [1:0] ip_list [0:1][0:3] = '{  '{2, 1, 0, 1 }, '{2, 1, 0, 1 } };  // packed elements resized to 2 bits

There is also an unordered syntax that lets you specify just some elements and in whatever order you'd like.  It's something like this:

  reg [1:0] ip_list [0:3] = '{1:2, 3:2, default:0}; // ip_list[1]=2, ip_list[3]=2, others=0