From 0048b04540fdd22e53f51e39f6db6a05bd79185d Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 21 Apr 2012 19:30:08 -0400 Subject: [PATCH] Merge from Tristate branch, part 1 of 2. No functional change intended --- bin/verilator | 6 +++--- src/V3Ast.h | 6 +++++- src/V3AstNodes.cpp | 3 ++- src/V3AstNodes.h | 5 +++++ src/V3Inst.cpp | 6 ++++-- src/V3Inst.h | 2 +- test_regress/t/t_tri_gate.cpp | 18 ++++++++++++------ test_regress/t/t_tri_pullup.cpp | 15 ++++++++++----- test_regress/t/t_tri_select.cpp | 14 +++++++++----- 9 files changed, 51 insertions(+), 24 deletions(-) diff --git a/bin/verilator b/bin/verilator index c601a58ed..4c530f38c 100755 --- a/bin/verilator +++ b/bin/verilator @@ -3463,9 +3463,9 @@ Many people have provided ideas and other assistance with Verilator. The major corporate sponsors of Verilator, by providing significant contributions of time or funds include include Cavium Networks, Compaq -Corporation, Digital Equipment Corporation, Embecosm Ltd., Intel -Corporation, Mindspeed Technologies Inc., MicroTune Inc., picoChip Designs -Ltd., Sun Microsystems, Nauticus Networks, and SiCortex Inc. +Corporation, Digital Equipment Corporation, Embecosm Ltd., Hicamp Systems, +Intel Corporation, Mindspeed Technologies Inc., MicroTune Inc., picoChip +Designs Ltd., Sun Microsystems, Nauticus Networks, and SiCortex Inc. The people who have contributed major functionality are Byron Bradley, Jeremy Bennett, Lane Brooks, Duane Galbi, Paul Wasson, and Wilson Snyder. diff --git a/src/V3Ast.h b/src/V3Ast.h index a2ace870e..226da8e35 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -365,6 +365,8 @@ public: WIRE, IMPLICITWIRE, TRIWIRE, + TRI0, + TRI1, PORT, // Temp type used in parser only BLOCKTEMP, MODULETEMP, @@ -380,7 +382,9 @@ public: static const char* names[] = { "?","GPARAM","LPARAM","GENVAR", "VAR","INPUT","OUTPUT","INOUT", - "SUPPLY0","SUPPLY1","WIRE","IMPLICITWIRE","TRIWIRE","PORT", + "SUPPLY0","SUPPLY1","WIRE","IMPLICITWIRE", + "TRIWIRE","TRI0","TRI1", + "PORT", "BLOCKTEMP","MODULETEMP","STMTTEMP","XTEMP"}; return names[m_e]; } }; diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 6096284d2..67b86c371 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -83,7 +83,8 @@ void AstVar::combineType(AstVarType type) { m_input = true; if (type==AstVarType::OUTPUT || type==AstVarType::INOUT) m_output = true; - if (type==AstVarType::INOUT || type==AstVarType::TRIWIRE) + if (type==AstVarType::INOUT || type==AstVarType::TRIWIRE + || type==AstVarType::TRI0 || type==AstVarType::TRI1) m_tristate = true; } diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 4729b2264..3254689ef 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -2715,6 +2715,8 @@ struct AstNot : public AstNodeUniop { struct AstExtend : public AstNodeUniop { // Expand a value into a wider entity by 0 extension. Width is implied from nodep->width() AstExtend(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {} + AstExtend(FileLine* fl, AstNode* lhsp, int width) : AstNodeUniop(fl, lhsp) { + dtypeSetLogicSized(width,width,AstNumeric::UNSIGNED); } ASTNODE_NODE_FUNCS(Extend, EXTEND) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); } virtual string emitVerilog() { return "%l"; } @@ -2726,6 +2728,8 @@ struct AstExtend : public AstNodeUniop { struct AstExtendS : public AstNodeUniop { // Expand a value into a wider entity by sign extension. Width is implied from nodep->width() AstExtendS(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {} + AstExtendS(FileLine* fl, AstNode* lhsp, int width) : AstNodeUniop(fl, lhsp) { + dtypeSetLogicSized(width,width,AstNumeric::UNSIGNED); } ASTNODE_NODE_FUNCS(ExtendS, EXTENDS) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opExtendS(lhs); } virtual string emitVerilog() { return "%l"; } @@ -3670,6 +3674,7 @@ struct AstReplicate : public AstNodeBiop { }; struct AstBufIf1 : public AstNodeBiop { // lhs is enable, rhs is data to drive + // Note unlike the Verilog bufif1() UDP, this allows any width; each lhsp bit enables respective rhsp bit AstBufIf1(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { if (lhsp) widthSignedFrom(lhsp); } ASTNODE_NODE_FUNCS(BufIf1, BUFIF1) diff --git a/src/V3Inst.cpp b/src/V3Inst.cpp index 0e4bd34d1..9c217ce5b 100644 --- a/src/V3Inst.cpp +++ b/src/V3Inst.cpp @@ -241,14 +241,16 @@ public: //###################################################################### // Inst class functions -void V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule* modp) { +AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule* modp) { // If a pin connection is "simple" leave it as-is // Else create a intermediate wire to perform the interconnect + // Return the new assignment, if one was made // Note this module calles cloneTree() via new AstVar AstVar* pinVarp = pinp->modVarp(); AstVarRef* connectRefp = pinp->exprp()->castVarRef(); AstBasicDType* pinBasicp = pinVarp->dtypep()->basicp(); // Maybe NULL AstBasicDType* connBasicp = NULL; + AstAssignW* assignp = NULL; if (connectRefp) connBasicp = connectRefp->varp()->dtypep()->basicp(); // if (connectRefp @@ -268,7 +270,6 @@ void V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule* mod } else { // Make a new temp wire //if (1||debug()>=9) { pinp->dumpTree(cout,"in_pin:"); } - AstAssignW* assignp = NULL; AstNode* pinexprp = pinp->exprp()->unlinkFrBack(); string newvarname = "__Vcellinp__"+cellp->name()+"__"+pinp->name(); AstVar* newvarp = new AstVar (pinVarp->fileline(), AstVarType::MODULETEMP, newvarname, pinVarp); @@ -303,6 +304,7 @@ void V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule* mod //if (1||debug()) { pinp->dumpTree(cout," out:"); } //if (1||debug()) { assignp->dumpTree(cout," aout:"); } } + return assignp; } //###################################################################### diff --git a/src/V3Inst.h b/src/V3Inst.h index 1c78d5543..222883a92 100644 --- a/src/V3Inst.h +++ b/src/V3Inst.h @@ -33,7 +33,7 @@ class V3Inst { public: static void instAll(AstNetlist* nodep); static void dearrayAll(AstNetlist* nodep); - static void pinReconnectSimple(AstPin* nodep, AstCell* cellp, AstNodeModule* modp); + static AstAssignW* pinReconnectSimple(AstPin* nodep, AstCell* cellp, AstNodeModule* modp); }; #endif // Guard diff --git a/test_regress/t/t_tri_gate.cpp b/test_regress/t/t_tri_gate.cpp index effb3f15c..ed97541bc 100644 --- a/test_regress/t/t_tri_gate.cpp +++ b/test_regress/t/t_tri_gate.cpp @@ -26,17 +26,23 @@ double sc_time_stamp() { bool check() { bool pass; int c = (tb->A >> tb->SEL) & 0x1; +#ifdef TEST_VERBOSE + bool verbose = true; +#else + bool verbose = false; +#endif - if(tb->Z == c && tb->Y == c && tb->X == c && tb->W == c) { + if(tb->W == c && tb->X == c && tb->Y == c && tb->Z == c) { pass = true; - printf("PASS: "); + if (verbose) printf("- pass: "); } else { pass = false; - printf("FAIL: "); + verbose = true; + printf("%%E-FAIL: "); + } + if (verbose) { + printf("SEL=%d A=%d W=%d X=%d Y=%d Z=%d c=%d\n", tb->SEL, tb->A, tb->W, tb->X, tb->Y, tb->Z, c); } -#ifdef TEST_VERBOSE - printf("SEL=%d A=%d W=%d X=%d Y=%d Z=%d\n", tb->SEL, tb->A, tb->W, tb->X, tb->Y, tb->Z); -#endif return pass; } diff --git a/test_regress/t/t_tri_pullup.cpp b/test_regress/t/t_tri_pullup.cpp index c35973b2b..cd1c3e2dd 100644 --- a/test_regress/t/t_tri_pullup.cpp +++ b/test_regress/t/t_tri_pullup.cpp @@ -24,16 +24,21 @@ bool check() { X = 1; } +#ifdef TEST_VERBOSE + bool verbose = true; +#else + bool verbose = false; +#endif + if (tb->Z == Z && tb->Y == Y && tb->X == X) { - printf("PASS: "); + if (verbose) printf("PASS: "); pass = true; } else { - printf("FAIL: "); + printf("%%E-FAIL: "); + verbose = true; pass = false; } -#ifdef TEST_VERBOSE - printf("OE=%d A=%d X=%d Y=%d Z=%d\n", tb->OE, tb->A, tb->X, tb->Y, tb->Z); -#endif + if (verbose) printf("OE=%d A=%d X=%d xexp=%d Y=%d yexp=%d Z=%d zexp=%d\n", tb->OE, tb->A, tb->X,X, tb->Y,Y, tb->Z,Z); return pass; } diff --git a/test_regress/t/t_tri_select.cpp b/test_regress/t/t_tri_select.cpp index 2c3fceae6..29d52cf0b 100644 --- a/test_regress/t/t_tri_select.cpp +++ b/test_regress/t/t_tri_select.cpp @@ -10,6 +10,11 @@ double sc_time_stamp() { bool check() { bool pass = true; +#ifdef TEST_VERBOSE + bool verbose = true; +#else + bool verbose = false; +#endif int Y = (tb->OE1 & !tb->OE2) ? tb->A1 : (!tb->OE1 & tb->OE2) ? tb->A2 @@ -21,15 +26,14 @@ bool check() { if(tb->Y1 == tb->Y2 && tb->Y1 == Y && tb->W == W) { pass = true; - printf("Pass: "); + if (verbose) printf("- pass: "); } else { pass = false; - printf("Fail: "); + verbose = true; + printf("%%E-Fail: "); } -#ifdef TEST_VERBOSE - printf("Read: OE1=%d OE2=%d A1=0x%x A2=0x%x Y1=0x%x Y2=0x%x W=0x%x Expected: Y1=Y2=%d and W=0x%x\n", tb->OE1, tb->OE2, tb->A1, tb->A2, tb->Y1, tb->Y2, tb->W, Y,W); -#endif + if (verbose) printf("Read: OE1=%d OE2=%d A1=0x%x A2=0x%x Y1=0x%x Y2=0x%x W=0x%x Expected: Y1=Y2=%d and W=0x%x\n", tb->OE1, tb->OE2, tb->A1, tb->A2, tb->Y1, tb->Y2, tb->W, Y,W); return pass; }