From 8714ee591fd5ecbd1d6dd446ac3ebe4db3681288 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 20 Dec 2006 20:45:13 +0000 Subject: [PATCH] Yet another round of dotted generate fixes git-svn-id: file://localhost/svn/verilator/trunk/verilator@856 77ca24e4-aefa-0310-84f0-b9a241c72d87 --- Changes | 6 ++ bin/verilator | 20 ++-- src/V3Link.cpp | 16 ++- src/V3LinkResolve.cpp | 28 ----- src/V3Unroll.cpp | 14 ++- src/verilog.y | 2 +- test_regress/t/t_gen_for.v | 6 +- test_regress/t/t_gen_intdot.v | 6 +- test_regress/t/t_gen_intdot2.pl | 18 ++++ test_regress/t/t_gen_intdot2.v | 178 ++++++++++++++++++++++++++++++++ 10 files changed, 238 insertions(+), 56 deletions(-) create mode 100755 test_regress/t/t_gen_intdot2.pl create mode 100644 test_regress/t/t_gen_intdot2.v diff --git a/Changes b/Changes index 2127e652d..f88ff7bc1 100644 --- a/Changes +++ b/Changes @@ -3,6 +3,12 @@ Revision history for Verilator The contributors that suggested a given feature are shown in []. [by ...] indicates the contributor was also the author of the fix; Thanks! +* Verilator 3.63* + +**** Fix again dotted references into generate cells. [David Hewson] + Verilator no longer accepts duplicated variables inside unique + generate blocks as this is illegal according to the specification. + * Verilator 3.630 12/19/2006 ** Support $readmemb and $readmemh. [Eugene Weber, Arthur Kahlich] diff --git a/bin/verilator b/bin/verilator index 40d0f026a..3656ca549 100755 --- a/bin/verilator +++ b/bin/verilator @@ -1177,17 +1177,15 @@ standard; arrayed instances are named {cellName}__{instanceNumber}. For example a[2] is instead a__2. Thus you cannot use a parameter or variable to select the index number; expand it into a case statement manually. -References into generate statements also use different names from the -Verilog standard; the top level generate, any begin statement, and any -place where there is a implied begin statement (under each generate-if or -generate-case) adds a hierarchy level named genblkI. And -each generate-for adds genforI. The best bet is to comment out -the references and run with --debug and look in the at the _begin.tree -file, and see the hierarchy by looking at the names of all of the CELLs in -question. Replace __DOT__ with . in your program. For example most cells -under a for loop would be something like -"genblk__DOT__genfor0__DOT__I"; so use genblk.genfor0.I to -see inside that cell. +References into generate statements should match the names from the Verilog +standard; subject to converting generate-for a[#] to a__# as described +above. When a dotted signal cannot be resolved, Verilator will print a +list of known scopes to help debugging. + +Verilator creates numbered "genblk" when a begin: name is not specified +around a block inside a generate statement. These numbers may differ +between other simulators, but the Verilog specification does not allow +users to use these names, so it should not matter. =head2 Latches diff --git a/src/V3Link.cpp b/src/V3Link.cpp index e2aac6432..a98ace639 100644 --- a/src/V3Link.cpp +++ b/src/V3Link.cpp @@ -65,6 +65,7 @@ private: int m_paramNum; // Parameter number, for position based connection V3SymTable* m_curVarsp; // Symbol table of variables and tasks under table we're inserting into V3SymTable* m_cellVarsp; // Symbol table of variables under cell's module + int m_beginNum; // Begin block number, 0=none seen vector m_delSymps; // Symbol tables to delete //int debug() { return 9; } @@ -131,6 +132,7 @@ private: if (!m_curVarsp) nodep->v3fatalSrc("NULL"); m_cellVarsp = NULL; m_paramNum = 0; + m_beginNum = 0; nodep->iterateChildren(*this); // Prep for next m_curVarsp = NULL; @@ -158,7 +160,7 @@ private: findvarp->combineType(nodep); nodep->unlinkFrBack(); nodep=NULL; } else { - nodep->v3error("Duplicate declaration of signal."); + nodep->v3error("Duplicate declaration of signal: "<prettyName()); findvarp->v3error("... Location of original declaration"); } } else { @@ -244,6 +246,16 @@ private: // Link variables underneath blocks // Remember the existing symbol table scope V3SymTable* upperVarsp = m_curVarsp; + // Rename "genblk"s to include a number + // All blocks are numbered in the standard, IE we start with "genblk1" even if only one. + UINFO(8," "<name() == "genblk") { + ++m_beginNum; + nodep->name(nodep->name()+cvtToStr(m_beginNum)); + } + // Recurse + int oldNum = m_beginNum; + m_beginNum = 0; { // Create symbol table for the task's vars if (V3SymTable* localVarsp = nodep->userp()->castSymTable()) { @@ -256,6 +268,7 @@ private: nodep->iterateChildren(*this); } m_curVarsp = upperVarsp; + m_beginNum = oldNum; } virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) { // NodeFTaskRef: Resolve its reference @@ -399,6 +412,7 @@ public: m_cellVarsp = NULL; m_modp = NULL; m_paramNum = 0; + m_beginNum = 0; // rootp->accept(*this); } diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index 37475bf94..f166c3618 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -55,8 +55,6 @@ private: AstModule* m_modp; // Current module AstNodeFTask* m_ftaskp; // Function or task we're inside bool m_setRefLvalue; // Set VarRefs to lvalues for pin assignments - AstBegin* m_beginLastp; // Last begin block seen (not present one) - int m_beginNum; // Begin block number, 0=none seen //int debug() { return 9; } @@ -72,33 +70,9 @@ private: // Module: Create sim table for entire module and iterate UINFO(8,"MODULE "<iterateChildren(*this); m_modp = NULL; } - virtual void visit(AstBegin* nodep, AstNUser*) { - // Rename "genblk"s to include a number if there was more then one per block - // This is better then doing it at parse time, because if there's only one, it's named logically. - UINFO(8," "<v3fatalSrc("Where was first begin?"); - m_beginLastp->name(m_beginLastp->name()+"1"); - } - if (m_beginNum > 1) { // Now us - nodep->name(nodep->name()+cvtToStr(m_beginNum)); - } - // Recurse - int oldNum = m_beginNum; - m_beginNum = 0; - m_beginLastp = NULL; - { - nodep->iterateChildren(*this); - } - m_beginNum = oldNum; - m_beginLastp = nodep; // Us, so 2nd begin can change our name - } virtual void visit(AstVar* nodep, AstNUser*) { nodep->iterateChildren(*this); if (nodep->arraysp() && nodep->isIO()) { @@ -389,8 +363,6 @@ public: m_ftaskp = NULL; m_modp = NULL; m_setRefLvalue = false; - m_beginNum = 0; - m_beginLastp = NULL; // rootp->accept(*this); } diff --git a/src/V3Unroll.cpp b/src/V3Unroll.cpp index 38b036096..663814a9d 100644 --- a/src/V3Unroll.cpp +++ b/src/V3Unroll.cpp @@ -342,18 +342,16 @@ private: nodep->iterateChildren(*this); m_inBegin = lastBegin; - if (m_varModeReplace && !m_inBegin // above begin, not this one + if (m_varModeReplace && !m_inBegin // no upper begin, excluding this one ) { // Rename it, as otherwise we may get a conflict // V3Begin sees these DOTs and makes CellInlines for us. string nname = (string)"genfor"+cvtToStr(m_varValuep->asInt())+"__DOT__"+nodep->name(); - if (nodep->name() != "genblk" - && nodep->name().find("__DOT__") == string::npos) { - // Verilog seems to drop the for loop name and tack on [#] - //nname = nodep->name() + "__BRA__" + cvtToStr(m_varValuep->asInt()) + "__KET__"; - // However we don't parse [#]'s correctly, so just use __ for now. - nname = nodep->name() + "__" + cvtToStr(m_varValuep->asInt()); - } + // Verilog seems to drop the for loop name and tack on [#] + //nname = nodep->name() + "__BRA__" + cvtToStr(m_varValuep->asInt()) + "__KET__"; + // However we don't parse [#]'s correctly, so just use __ for now. + // (Fixing parsing to allow hardcoded numbers then leads to shift/reduce conflicts.) + nname = nodep->name() + "__" + cvtToStr(m_varValuep->asInt()); //UINFO(8," Rename begin "<name(nname); } diff --git a/src/verilog.y b/src/verilog.y index 52618d9b9..25c3f11d2 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -442,7 +442,7 @@ genItemBlock: genItem { $$ = new AstBegin(CRELINE(),"genblk",$1); } | genItemBegin { $$ = $1; } ; -genTopBlock: genItemList { $$ = new AstBegin(CRELINE(),"genblk",$1); } +genTopBlock: genItemList { $$ = $1; } | genItemBegin { $$ = $1; } ; diff --git a/test_regress/t/t_gen_for.v b/test_regress/t/t_gen_for.v index 97df26ff4..316c662f7 100644 --- a/test_regress/t/t_gen_for.v +++ b/test_regress/t/t_gen_for.v @@ -88,14 +88,13 @@ module paramed (/*AUTOARG*/ // No else endgenerate + genvar i; generate - genvar i; // Empty loop body for (i=0; i<3; i=i+1) begin end endgenerate generate - genvar i; if (MODE==0) begin // Flip bitorder, direct assign method for (i=0; i1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_gen_intdot2.v b/test_regress/t/t_gen_intdot2.v new file mode 100644 index 000000000..deeaa1b7b --- /dev/null +++ b/test_regress/t/t_gen_intdot2.v @@ -0,0 +1,178 @@ +// $Id: t_gen_intdot.v 840 2006-12-18 18:14:53Z wsnyder $ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2003-2006 by Wilson Snyder. + +module t (/*AUTOARG*/ + // Inputs + clk + ); + input clk; + integer cyc=0; + + reg check; + initial check = 1'b0; + Genit g (.clk(clk), .check(check)); + + always @ (posedge clk) begin + //$write("[%0t] cyc==%0d %x %x\n",$time, cyc, check, out); + cyc <= cyc + 1; + if (cyc==0) begin + // Setup + check <= 1'b0; + end + else if (cyc==1) begin + check <= 1'b1; + end + else if (cyc==9) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + +//`define WAVES +`ifdef WAVES + initial begin + $dumpfile("obj_dir/t_gen_intdot.vcd"); + $dumpvars(12, t); + end +`endif + +endmodule + +module One; + wire one = 1'b1; +endmodule + +module Genit ( + input clk, + input check); + + // ARRAY + One cellarray1[1:0] (); //cellarray[0..1][0..1] +`ifdef verilator + always @ (posedge clk) if (cellarray1__0.one !== 1'b1) $stop; + always @ (posedge clk) if (cellarray1__1.one !== 1'b1) $stop; +`else + always @ (posedge clk) if (cellarray1[0].one !== 1'b1) $stop; + always @ (posedge clk) if (cellarray1[1].one !== 1'b1) $stop; +`endif + + // IF + generate + // genblk1 refers to the if's name, not the "generate" itself. + if (1'b1) // IMPLIED begin: genblk1 + One ifcell1(); // genblk1.ifcell1 + else + One ifcell1(); // genblk1.ifcell1 + endgenerate + // On compliant simulators "Implicit name" not allowed here; IE we can't use "genblk1" etc +`ifdef verilator + always @ (posedge clk) if (genblk1.ifcell1.one !== 1'b1) $stop; +//`else // NOT SUPPORTED accoring to spec - generic block references +`endif + + generate + begin : namedif2 + if (1'b1) + One ifcell2(); // namedif2.genblk1.ifcell2 + end + endgenerate +`ifdef verilator + always @ (posedge clk) if (namedif2.genblk1.ifcell2.one !== 1'b1) $stop; +//`else // NOT SUPPORTED accoring to spec - generic block references +`endif + + generate + if (1'b1) + begin : namedif3 + One ifcell3(); // namedif3.ifcell3 + end + endgenerate + always @ (posedge clk) if (namedif3.ifcell3.one !== 1'b1) $stop; + + // CASE + generate + case (1'b1) + 1'b1 : + One casecell10(); // genblk3.casecell10 + endcase + endgenerate +`ifdef verilator + always @ (posedge clk) if (genblk3.casecell10.one !== 1'b1) $stop; +//`else // NOT SUPPORTED accoring to spec - generic block references +`endif + + generate + case (1'b1) + 1'b1 : begin : namedcase11 + One casecell11(); + end + endcase + endgenerate + always @ (posedge clk) if (namedcase11.casecell11.one !== 1'b1) $stop; + + genvar i; + genvar j; + + // IF + generate + for (i = 0; i < 2; i = i + 1) + One cellfor20 (); // genblk5[0..1].cellfor20 + endgenerate +`ifdef verilator + always @ (posedge clk) if (genblk4__0.cellfor20.one !== 1'b1) $stop; + always @ (posedge clk) if (genblk4__1.cellfor20.one !== 1'b1) $stop; +//`else // NOT SUPPORTED accoring to spec - generic block references +`endif + + // COMBO + generate + for (i = 0; i < 2; i = i + 1) + begin : namedfor21 + One cellfor21 (); // namedfor21[0..1].cellfor21 + end + endgenerate +`ifdef verilator + always @ (posedge clk) if (namedfor21__0.cellfor21.one !== 1'b1) $stop; + always @ (posedge clk) if (namedfor21__1.cellfor21.one !== 1'b1) $stop; +`else + always @ (posedge clk) if (namedfor21[0].cellfor21.one !== 1'b1) $stop; + always @ (posedge clk) if (namedfor21[1].cellfor21.one !== 1'b1) $stop; +`endif + + generate + for (i = 0; i < 2; i = i + 1) + begin : namedfor30 + for (j = 0; j < 2; j = j + 1) + begin : forb30 + if (j == 0) + begin : forif30 + One cellfor30a (); // namedfor30[0..1].forb30[0].forif30.cellfor30a + end + else +`ifdef verilator + begin : forif30b +`else + begin : forif30 // forif30 seems to work on some simulators, not verilator yet +`endif + One cellfor30b (); // namedfor30[0..1].forb30[1].forif30.cellfor30b + end + end + end + endgenerate +`ifdef verilator + always @ (posedge clk) if (namedfor30__0.forb30__0.forif30.cellfor30a.one !== 1'b1) $stop; + always @ (posedge clk) if (namedfor30__0.forb30__1.forif30b.cellfor30b.one !== 1'b1) $stop; + always @ (posedge clk) if (namedfor30__1.forb30__0.forif30.cellfor30a.one !== 1'b1) $stop; + always @ (posedge clk) if (namedfor30__1.forb30__1.forif30b.cellfor30b.one !== 1'b1) $stop; +`else + always @ (posedge clk) if (namedfor30[0].forb30[0].forif30.cellfor30a.one !== 1'b1) $stop; + always @ (posedge clk) if (namedfor30[0].forb30[1].forif30.cellfor30b.one !== 1'b1) $stop; + always @ (posedge clk) if (namedfor30[1].forb30[0].forif30.cellfor30a.one !== 1'b1) $stop; + always @ (posedge clk) if (namedfor30[1].forb30[1].forif30.cellfor30b.one !== 1'b1) $stop; +`endif + +endmodule +