MikePopoloski / slang

SystemVerilog compiler and language services
MIT License
555 stars 120 forks source link

primitive elaboration too strict #926

Closed udif closed 2 months ago

udif commented 2 months ago

Describe the bug When multiple table rows in a primitive overlap but don't contradict, slang issues an error.

To Reproduce The test below was extracted from a library:

 primitive D (q, clk, d, _c, _s);
          output reg q;
          input clk, d, _c, _s;
          table
          // clk in  _c  _s  : Qt  : Qt+1                             
            r    0    1   1  : ?   :  0;
            *    0    ?   1  : 0   :  -;
          endtable
 endprimitive

When run, I get:

t.v:7:13: error: primitive table row duplicates a set of inputs with a different specified output value
            *    0    ?   1  : 0   :  -;
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
t.v:6:13: note: previous definition here
            r    0    1   1  : ?   :  0;
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

Additional context

Section 29.3.4 of IEEE1800-2017 says:

It shall be illegal to have the same combination of inputs, including edges, specify different output values.

It doesn't say inputs can't overlap (and when using wildcards it is hard to avoid).
In the case above, the inputs partially overlap, but don't contradict where they do.
Regardless of whether this should be reported or now, I think it should be a warning in the worst case.

MikePopoloski commented 2 months ago

Hmm, looks like the bit of logic that slang is missing is to qualify an "unchanged" or '-' output by looking back at what the "current state" field is set to, which is what makes this entry legal.

The Big Three all throw a hard error if you change the current state field on the second line from '0' to '1', which is also the behavior the LRM specifies so it seems to me that it should remain an error in slang as well. I just need to fix the handling of '-'.