Nic30 / hdlConvertor

Fast Verilog/VHDL parser preprocessor and code generator for C++/Python based on ANTLR4
MIT License
274 stars 63 forks source link

`Conversion to Python object not implemented` Error from Primitive Structural Verilog Code #173

Closed TheMatt2 closed 1 year ago

TheMatt2 commented 1 year ago

HdlConvertor seems to throw and warning and not successfully parse structural verilog code.

The problem seems to appear in statements such as:

and a1 (tmp, a, b);

This is defined to be valid in IEEE 1800-2017, Section 28.4 "and, nand, nor, or, xor, and xnor gates" (page 803?)

The instance declaration of a multiple input logic gate shall begin with one of the following keywords: and nand nor or xor xnor The delay specification shall be zero, one, or two delays. If the specification contains two delays, the first delay shall determine the output rise delay, the second delay shall determine the output fall delay, and the smaller of the two delays shall apply to output transitions to x. If only one delay is specified, it shall specify both the rise delay and the fall delay. If there is no delay specification, there shall be no propagation delay through the gate.

Steps to Reproduce

An example code that will demonstrate the issue.

module example (a, b, c, d);
input a, b, c;
output d;

wire tmp;
and a1 (tmp, a, b);
or o1 (d, tmp, d);
endmodule

This can then be loaded and run with this Python code.

from hdlConvertorAst.language import Language
from hdlConvertor import HdlConvertor

c = HdlConvertor()
d = c.parse(["example.v"], Language.VERILOG, [], hierarchyOnly=False, debug=True)

This shows the error message:

example.v:5:4: VerGateParser.visitGate_instantiation Conversion to Python object not implemented
    ...anda1(tmp,a,b);...
example.v:6:4: VerGateParser.visitGate_instantiation Conversion to Python object not implemented
    ...oro1(d,tmp,d);...

The parsed value can be returned by running this Python code:

from hdlConvertorAst.to.verilog.verilog2005 import ToVerilog2005

tv = ToVerilog2005(sys.stdout)
tv.visit_HdlContext(d)

Which prints the coverted Verilog code.

module example (
    input wire A,
    input wire B,
    input wire C,
    output wire D
);
    wire TMP;
endmodule

The and and or definitions are now missing.

By looking at the JSON, it seems the assignments are missing from parsed output.

from hdlConvertorAst.to.json import ToJson
import json
tj = ToJson()
j = tj.visit_HdlContext(d)
print(json.dumps(j[0]["objs"], sort_keys=True,indent=4))

You can see the tmp declaration, but there is nothing else here. This is where I expect the assignment to be (I'm new, I could be wrong).

[
    {
        "__class__": "HdlIdDef",
        "direction": "INTERNAL",
        "name": {
            "__class__": "str",
            "val": "TMP"
        },
        "position": [
            5,
            6,
            5,
            8
        ],
        "type": {
            "__class__": "HdlTypeAuto"
        }
    }
]

I trying to analyze some Verilog code, and unfortunate this issue is preventing the analysis from working correctly. hdlConvertor was installed via pip3 on Ubuntu.

AmeyaVS commented 1 year ago

@Nic30 , any comment on how to handle this?

AmeyaVS commented 1 year ago

Update: The issue mentioned below does not exist. I am currently missing the instance name for dummy module instantiated.

While trying to add this feature, I actually found another related issue.

For the following code example.v:

module dummy(c, a, b);
output c;
input a, b;
assign c = a & b;
endmodule

module example (a, b, c, d);
input a, b, c;
output d;

wire tmp;
wire tmp2;
and a1 (tmp, a, b);
dummy(tmp2, b, c);
or o1 (d, tmp, tmp2);
endmodule

I am observing the following Verilog source being generated:

module dummy (
    output wire c,
    input wire a,
    input wire b
);
    assign c = a & b;
endmodule

module example (
    input wire a,
    input wire b,
    input wire c,
    output wire d
);
    wire tmp;
    wire tmp2;
    and a1 (
        tmp,
        a,
        b
    );

    or o1 (
        d,
        tmp,
        tmp2
    );

endmodule

The dummy module instance is missing from the example module.

Used following python source example.py to generate verilog:

import sys
from hdlConvertorAst.language import Language
from hdlConvertor import HdlConvertor

c = HdlConvertor()
d = c.parse(["example.v"], Language.VERILOG, [], hierarchyOnly=False, debug=True)

# Convert to HDL
from hdlConvertorAst.to.verilog.verilog2005 import ToVerilog2005

tv = ToVerilog2005(sys.stdout)
tv.visit_HdlContext(d)
AmeyaVS commented 1 year ago

The PR #176 , has this particular test added. And it seems to be working, after providing the instance name it is part of the Generated Verilog Source.