Project

General

Profile

[logo] 
 
Home
News
Activity
About/Contact
Major Tools
  Dinotrace
  Verilator
  Verilog-mode
  Verilog-Perl
Other Tools
  IPC::Locker
  Parallel::Forker
  Voneline
General Info
  Papers

Verilator fails to warn/error on procedural assignment to wire

Added by Neil Turton about 5 years ago

I have been developing a project using Verilator for a couple of years and during that time, Verilator has been great. I then came to port the project to the Xilinx tool chain and found that my Verilog code was somewhat less than perfect. :-) The Xilinx tools reported various problems which could have been spotted by Verilator. In all of these cases, I hadn't noticed the problem because Verilator did what I wanted the code to do. This isn't a support request as I have corrected my code.

Are you interested in this kind of thing? Is this the right place to report them?

I reduced these down to 7 different cases as follows:

error1:  Procedural assignment to a wire
error3:  Implicit wire before explicit declaration
error4:  Operator ++ not recognised
error5:  Assignment in an output declaration
error6:  ANSI declaration followed by reg declaration
error7:  Always block has no sensitivity list
error8:  Reg variable used in an output/inout port connection

[error2 is a duplicate of error1, so not included]

I have attached the verilog to reproduce error1. The problem here is that there is a procedural assignment to a wire. The variable "out" should be declared as a reg or logic.

error1.v - Example procedural assignment to wire (307 Bytes)


Replies (7)

RE: Verilator fails to warn/error on procedural assignment to wire - Added by Peter Gerst about 1 year ago

Hi Neil,

I have been facing with the same problem 4 years after your post. verilator (used with --lint-only) does not signal procedural assignment on a wire. Nor continuous assignment on a reg. It is not that critical but I am curious about anything you may got on this issue. Did you find a way to overcome this?

BR, Peter

RE: Verilator fails to warn/error on procedural assignment to wire - Added by Neil Turton about 1 year ago

Hi Peter,

I don't have an update on this issue. I modified my code to keep the Xilinx tools happy, so I've not even tried running incorrect Verilog through Verilator recently. Maybe it would be worth raising a bug instead of discussing it on the forum.

My only other suggestion would be to try a different lint tool.

Kind regards, Neil.

RE: Verilator fails to warn/error on procedural assignment to wire - Added by Wilson Snyder about 1 year ago

I would encourage a bug as this enhancement request got lost. Perhaps one of you would be willing to attempt a patch? If you make an appropriate test case, then run with --debug you'll see the tree files, and should be able to add an appropriate warning in e.g. V3Width.cpp

RE: Verilator fails to warn/error on procedural assignment to wire - Added by Wilson Snyder about 1 year ago

Added a new warning for this to git, towards 4.008.

RE: Verilator fails to warn/error on procedural assignment to wire - Added by Peter Gerst about 1 year ago

Thank you for the fix! It works fine for procedural assignment on wire. I submitted an issue about continuous assignment on reg: [[https://www.veripool.org/issues/1369-Verilator-verilator-does-not-raise-error-warning-on-continous-assignment-to-reg]]

RE: Verilator fails to warn/error on procedural assignment to wire - Added by Kris Jeon 5 months ago

In order to raise the warning for port, I've changed like the following:

In 'V3ParseGrammar.cpp'
AstVar* V3ParseGrammar::createVariable(FileLine* fileline, string name,
                                       AstNodeRange* arrayp, AstNode* attrsp) {
    AstNodeDType* dtypep = GRAMMARP->m_varDTypep;
    UINFO(5,"  creVar "<<name<<"  decl="<<GRAMMARP->m_varDecl
          <<"  io="<<GRAMMARP->m_varIO<<"  dt="<<(dtypep?"set":"")<<endl);
    // added lines -->
    if (v3Global.opt.lintOnly() && !fileline->language().systemVerilog()
        && GRAMMARP->m_varDecl == AstVarType::PORT && GRAMMARP->m_varIO == VDirection::OUTPUT && (!dtypep)) {
        GRAMMARP->m_varDecl = AstVarType::WIRE;
    } // <--
...
In 'V3Undriven.cpp'
    virtual void visit(AstNodeVarRef* nodep) {
        // Any variable
        if (nodep->lvalue()
            && !VN_IS(nodep, VarXRef)) {  // Ignore interface variables and similar ugly items
            if (m_inProcAssign && !nodep->varp()->varType().isProcAssignable()) {
                nodep->v3warn(PROCASSWIRE, "Procedural assignment to wire, perhaps intended var" 
                              " (IEEE 2017 6.5): " 
                              +nodep->prettyName());
            }
            if (m_inContAssign && !nodep->varp()->varType().isContAssignable()
                && !nodep->fileline()->language().systemVerilog()) {
                nodep->v3warn(CONTASSREG, "Continuous assignment to reg, perhaps intended wire" 
                              " (IEEE 2005 6.1; Verilog only, legal in SV): " 
                              +nodep->prettyName());
            }
            // added lines -->
            if (v3Global.opt.lintOnly() && m_inContAssign && nodep->varp()->varType() == AstVarType::PORT
                && !nodep->fileline()->language().systemVerilog()) {
                nodep->v3warn(CONTASSREG, "Continuous assignment to reg, perhaps intended wire" 
                              " (IEEE 2005 6.1; Verilog only, legal in SV): " 
                              +nodep->prettyName());
            } // <--
        }
    (1-7/7)