nickg / nvc

VHDL compiler and simulator
https://www.nickg.me.uk/nvc/
GNU General Public License v3.0
588 stars 75 forks source link

Verilog - Support `celldefine`, `endcelldefine`, `ifdef` and `else` #811

Open Blebowski opened 6 months ago

Blebowski commented 6 months ago

Hi,

after seeing https://github.com/nickg/nvc/issues/808 I gave it a shot at compiling Verilog standard cell libraries I have available for a PDK that we use. I see couple of macros unsupported:

** Warning: macro celldefine undefined
      > /projects/pdks/fancy_pdk_name_that_is_unfortunately_under_nda.v:1671
      |
 1671 | `celldefine
      | ^^^^^^^^^^^
** Warning: macro endcelldefine undefined
      > /projects/pdks/fancy_pdk_name_that_is_unfortunately_under_nda.v:1669
      |
 1669 | `endcelldefine
      | ^^^^^^^^^^^^^^
** Warning: macro ifdef undefined
      > /projects/pdks/fancy_pdk_name_that_is_unfortunately_under_nda.v:1676
      |
 1676 |    `ifdef FUNCTIONAL  //  functional //
      |    ^^^^^^
** Warning: macro else undefined
      > /projects/pdks/fancy_pdk_name_that_is_unfortunately_under_nda.v:1680
      |
 1680 |    `else
      |    ^^^^^
** Warning: macro endif undefined
      > /projects/pdks/fancy_pdk_name_that_is_unfortunately_under_nda.v:1807
      |
 1807 |    `endif
      |    ^^^^^^

Tried to put together MVP example of the cell from PDK:

`timescale 1ns/1ps

`celldefine
module AND_GATE(A,B,Y);
input A, B;
output Y;

   `ifdef FUNCTIONAL  //  functional //

        AND_GATE_func AND_GATE_behav_inst(.A(A),.B(B),.Y(Y));

   `else

        AND_GATE_func AND_GATE_behav_inst(.A(A),.B(B),.Y(Y));

   specify

        // specify_block_begin

        if(B===1'b0)
          // comb arc A --> Y
          (A => Y) = (1.0,1.0);

        if(B===1'b1)
          // comb arc A --> Y
          (A => Y) = (1.0,1.0);

        if(A===1'b0)
          // comb arc B --> Y
          (B => Y) = (1.0,1.0);

        if(A===1'b1)
          // comb arc B --> Y
          (B => Y) = (1.0,1.0);

     endspecify

   `endif

endmodule
`endcelldefine

Note that this has several other issues (non-ANSI port declaration, specify blocks), but its the most rudimentary cell definition I could create. Feel free to close/do whatever with the issue if it is too soon and the verilog implementation is not yet there.

Blebowski commented 1 week ago

Hi,

with latest master, I get further. Now the stopping point are the non-ANSI port declarations:

module ADD2( CO, ICO, S, A, B, C, D );
input A, B, C, D;
output CO, ICO, S;
endmodule;

Produces something like:

** Error: syntax error, unexpected ',', expecting ';'
   > /projects/pdks/<fancy_pdk_under_nda>/<standard_cell_type>/0v2/behav_model/<again_fancy_pdk>.v:5
   |
 5 | input A, B, C, D;
   |           ^
Blebowski commented 1 week ago

Hi @nickg , thanks for the fixes.

With latest master I now get up parsing the underlying "func" instance that is before the specify block:

[oille@runner4 build]$ nvc -a /projects/pdks/<pdk_under_nda>/<standard_cell_library>/0v2/behav_model/pdk_under_nda.v
** Error: syntax error, unexpected '.', expecting identifier
    > /projects/pdks/<pdk_under_nda>/<standard_cell_library>/0v2/behav_model/pdk_under_nda.v:14
    |
 14 |         SIMPLE_GATE_func SIMPLE_GATE_inst(.CO(CO),.ICO(ICO),.S(S),.A(A),.B(B),.C(C),.D(D));
    |  
Blebowski commented 1 week ago

Maybe better than posting here from proprietary PDK is referencing something public.

I tried to compile standard cell models of IHP 130 nm PDK: IHP 130 std cells model

Currently it fails with:

[oille@runner4 build]$ nvc -a ../sg13g2_stdcell.v
** Error: syntax error, unexpected '(', expecting identifier
    > ../sg13g2_stdcell.v:25
    |
 25 |         and (int_fwire_0, A1, A2);
    |             ^

Looking at that PDK, I think following features are still missing to at least parse it: