MikePopoloski / slang

SystemVerilog compiler and language services
MIT License
558 stars 122 forks source link

Assertion 'T::isKind(kind)' failed #1002

Closed udif closed 1 week ago

udif commented 1 month ago

Describe the bug A full SoC run passes with slang but when it is ran with slang-netlist (no additional flags), it fails with:

Assertion 'T::isKind(kind)' failed
  in file /home/udif/git2/slang/tools/netlist/../../include/slang/ast/Statements.h, line 238
  function: const T& slang::ast::Statement::as() const [with T = slang::ast::TimedStatement]

.

To Reproduce At the moment that would be hard, as it is the result of proprietary SoC full tree run.

Additional context I wish I could give out more information, but if the assertion could provide a SourceLocation I might be able to reduce it to an MRE.

udif commented 1 month ago

I'll try producing a stack backtrace tomorrow.

udif commented 1 month ago

This was ran on 3567fc084b335513cf3fc55714043dc421b8323f which is fairly recent (1-2 days old).

slang::assert::assertFailed(const char * expr, const char * file, int line, const char * func) (\\home\udif\git\slang\source\util\Util.cpp:23)
slang::ast::Statement::as<slang::ast::TimedStatement>(const slang::ast::Statement * const this) (\\home\udif\git\slang\include\slang\ast\Statements.h:238)
netlist::NetlistVisitor::handle(netlist::NetlistVisitor * const this, const slang::ast::ProceduralBlockSymbol & symbol) (\\home\udif\git\slang\tools\netlist\include\NetlistVisitor.h:608)
slang::ast::ASTVisitor<netlist::NetlistVisitor, true, false, false>::visit<slang::ast::ProceduralBlockSymbol>(slang::ast::ASTVisitor<netlist::NetlistVisitor, true, false, false> * const this, const slang::ast::ProceduralBlockSymbol & t) (\\home\udif\git\slang\include\slang\ast\ASTVisitor.h:68)
slang::ast::Symbol::visit<netlist::NetlistVisitor&>(const slang::ast::Symbol * const this, netlist::NetlistVisitor & visitor) (\\home\udif\git\slang\include\slang\ast\ASTVisitor.h:166)
slang::ast::ASTVisitor<netlist::NetlistVisitor, true, false, false>::visitDefault<slang::ast::InstanceBodySymbol>(slang::ast::ASTVisitor<netlist::NetlistVisitor, true, false, false> * const this, const slang::ast::InstanceBodySymbol & t) (\\home\udif\git\slang\include\slang\ast\ASTVisitor.h:96)
slang::ast::ASTVisitor<netlist::NetlistVisitor, true, false, false>::visit<slang::ast::InstanceBodySymbol>(slang::ast::ASTVisitor<netlist::NetlistVisitor, true, false, false> * const this, const slang::ast::InstanceBodySymbol & t) (\\home\udif\git\slang\include\slang\ast\ASTVisitor.h:72)
slang::ast::Symbol::visit<netlist::NetlistVisitor&>(const slang::ast::Symbol * const this, netlist::NetlistVisitor & visitor) (\\home\udif\git\slang\include\slang\ast\ASTVisitor.h:159)
netlist::NetlistVisitor::handle(netlist::NetlistVisitor * const this, const slang::ast::InstanceSymbol & symbol) (\\home\udif\git\slang\tools\netlist\include\NetlistVisitor.h:600)
slang::ast::ASTVisitor<netlist::NetlistVisitor, true, false, false>::visit<slang::ast::InstanceSymbol>(slang::ast::ASTVisitor<netlist::NetlistVisitor, true, false, false> * const this, const slang::ast::InstanceSymbol & t) (\\home\udif\git\slang\include\slang\ast\ASTVisitor.h:68)
slang::ast::Symbol::visit<netlist::NetlistVisitor&>(const slang::ast::Symbol * const this, netlist::NetlistVisitor & visitor) (\\home\udif\git\slang\include\slang\ast\ASTVisitor.h:158)
slang::ast::ASTVisitor<netlist::NetlistVisitor, true, false, false>::visitDefault<slang::ast::RootSymbol>(slang::ast::ASTVisitor<netlist::NetlistVisitor, true, false, false> * const this, const slang::ast::RootSymbol & t) (\\home\udif\git\slang\include\slang\ast\ASTVisitor.h:96)
slang::ast::ASTVisitor<netlist::NetlistVisitor, true, false, false>::visit<slang::ast::RootSymbol>(slang::ast::ASTVisitor<netlist::NetlistVisitor, true, false, false> * const this, const slang::ast::RootSymbol & t) (\\home\udif\git\slang\include\slang\ast\ASTVisitor.h:72)
slang::ast::Symbol::visit<netlist::NetlistVisitor&>(const slang::ast::Symbol * const this, netlist::NetlistVisitor & visitor) (\\home\udif\git\slang\include\slang\ast\ASTVisitor.h:145)
main(int argc, char ** argv) (\\home\udif\git\slang\tools\netlist\netlist.cpp:257)
udif commented 1 month ago

OK, here is a way to reconstruct this:

wget https://raw.githubusercontent.com/jkopanski/802.15.4/master/doc/amba/sva/Axi4PC.sv
wget https://raw.githubusercontent.com/jkopanski/802.15.4/master/doc/amba/sva/Axi4PC_defs.v
wget https://raw.githubusercontent.com/jkopanski/802.15.4/master/doc/amba/sva/Axi4PC_message_defs.v
wget https://raw.githubusercontent.com/jkopanski/802.15.4/master/doc/amba/sva/Axi4PC_undefs.v
wget https://raw.githubusercontent.com/jkopanski/802.15.4/master/doc/amba/sva/Axi4PC_message_undefs.v
slang-netlist Axi4PC.sv

The error is triggered by the first property. The code responsible for this is in NetlistVisitor.h:608 :

    void handle(const ast::ProceduralBlockSymbol& symbol) {
        ast::EdgeKind edgeKind = ast::EdgeKind::None;
        if (symbol.procedureKind == ast::ProceduralBlockKind::AlwaysFF ||
            symbol.procedureKind == ast::ProceduralBlockKind::Always) {
            auto tck = symbol.getBody().as<ast::TimedStatement>().timing.kind;

Apparently, I made this change. Perhaps it doesn't like properties. @jameshanlon I think we just need to skip properties. I'll work on a PR.

jameshanlon commented 1 month ago

It looks like the issue is that the AST node returned from symbol.getBody() is not a TimedStatement. If you dump the AST in JSON format, you can see what is actually there. You'll need to update the logic to handle the various possibilities of body nodes.

udif commented 1 month ago

Yes, I'm already past that. I compared the ASTs of a property vs regular blocks, and will complete a PR later today.