From d3601dd5612919fbe587e7b59d7c3f2205ea66bc Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 12 Aug 2012 15:15:21 -0400 Subject: [PATCH] Support '{} assignment pattern on structures, part of bug355. --- Changes | 2 + bin/verilator | 6 + src/V3AstNodes.h | 39 +++++ src/V3ParseImp.h | 1 + src/V3Width.cpp | 167 ++++++++++++++++--- src/verilog.y | 67 +++++++- test_regress/t/t_array_packed_value_list.v | 76 ++++----- test_regress/t/t_array_packed_write_read.v | 84 +++++----- test_regress/t/t_struct_init.v | 23 ++- test_regress/t/t_struct_packed_value_list.pl | 2 - test_regress/t/t_struct_packed_value_list.v | 40 +++-- 11 files changed, 378 insertions(+), 129 deletions(-) diff --git a/Changes b/Changes index c6d8a3656..db95bdbfc 100644 --- a/Changes +++ b/Changes @@ -5,6 +5,8 @@ indicates the contributor was also the author of the fix; Thanks! * Verilator 3.84*** devel +*** Support '{} assignment pattern on structures, part of bug355. + **** Fix double-deep parameter cell WIDTHs, bug541. [Hiroki Honda] **** Fix imports under multiple instantiated cells, bug542. [Alex Solomatnikov] diff --git a/bin/verilator b/bin/verilator index 91ef54718..d1bd22e94 100755 --- a/bin/verilator +++ b/bin/verilator @@ -2374,6 +2374,12 @@ Increment/decrement can only be used as standalone statements or in for loops. They cannot be used as side effect operators inside more complicate expressions ("a = b++;"). +=item '{} operator + +Assignment patterns with order based, default, constant integer (array) or +member identifier (struct/union) keys are supported. Data type keys and +keys which are computed from a constant expression are not supported. + =item cast operator Casting is supported only between simple scalar types, signed and unsigned, diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index d69d6ccee..eb648811f 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -3905,6 +3905,45 @@ struct AstFGetS : public AstNodeBiop { AstNode* filep() const { return rhsp(); } }; +struct AstPattern : public AstNodeMath { + // Verilog '{a,b,c,d...} + // Parents: AstNodeAssign, AstPattern, ... + // Children: expression, AstPattern, AstPatReplicate + AstPattern(FileLine* fl, AstNode* itemsp) : AstNodeMath(fl) { + addNOp1p(itemsp); + } + ASTNODE_NODE_FUNCS(Pattern, PATTERN) + virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially + virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; } + virtual string emitC() { V3ERROR_NA; return "";} + virtual string emitSimpleOperator() { V3ERROR_NA; return "";} + virtual bool cleanOut() {V3ERROR_NA; return "";} + virtual int instrCount() const { return widthInstrs(); } + AstNode* itemsp() const { return op1p(); } // op1 = AstPatReplicate, AstPatMember, etc +}; +struct AstPatMember : public AstNodeMath { + // Verilog '{a} or '{a{b}} + // Parents: AstPattern + // Children: expression, AstPattern, replication count +private: + bool m_default; +public: + AstPatMember(FileLine* fl, AstNode* lhsp, AstNode* keyp, AstNode* repp) : AstNodeMath(fl) { + setOp1p(lhsp), setNOp2p(keyp), setNOp3p(repp); m_default = false; } + ASTNODE_NODE_FUNCS(PatMember, PATMEMBER) + virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; } + virtual string emitVerilog() { return lhsp()?"%f{%r{%k%l}}":"%l"; } + virtual string emitC() { V3ERROR_NA; return "";} + virtual string emitSimpleOperator() { V3ERROR_NA; return "";} + virtual bool cleanOut() {V3ERROR_NA; return "";} + virtual int instrCount() const { return widthInstrs()*2; } + AstNode* lhsp() const { return op1p(); } // op1 = expression to assign or another AstPattern + AstNode* keyp() const { return op2p(); } // op2 = assignment key (Const, id Text) + AstNode* repp() const { return op3p(); } // op3 = replication count, or NULL for count 1 + bool isDefault() const { return m_default; } + void isDefault(bool flag) { m_default = flag; } +}; + //====================================================================== // SysVerilog assertions diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index 8e3cfe8b9..c0f3169c3 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -75,6 +75,7 @@ struct V3ParseBisonYYSType { AstNodeVarRef* varnodep; AstPackage* packagep; AstParseRef* parserefp; + AstPatMember* patmemberp; AstPin* pinp; AstRange* rangep; AstSenTree* sentreep; diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 09283a477..e3e4506c0 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -119,6 +119,7 @@ private: AstFunc* m_funcp; // Current function AstInitial* m_initialp; // Current initial block AstAttrOf* m_attrp; // Current attribute + AstNodeDType* m_assDTypep; // Assign LHS data type for assignment pattern bool m_doGenerate; // Do errors later inside generate statement // CLASSES @@ -995,6 +996,126 @@ private: pushDeletep(nodep); nodep=NULL; } } + + virtual void visit(AstPattern* nodep, AstNUser* vup) { + if (nodep->didWidthAndSet()) return; + UINFO(9,"PATTERN "<v3error("Unsupported/Illegal: Assignment pattern not underneath an assignment"); + m_assDTypep = m_assDTypep->skipRefp(); + UINFO(9," adtypep "<dtypep(m_assDTypep); + if (AstNodeClassDType* classp = m_assDTypep->castNodeClassDType()) { + // Due to "default" and tagged patterns, we need to determine + // which member each AstPatMember corresponds to before we can + // determine the dtypep for that PatMember's value, and then + // width the initial value appropriately. + typedef map PatMap; + PatMap patmap; + AstPatMember* defaultp = NULL; + { + AstMemberDType* memp = classp->membersp(); + AstPatMember* patp = nodep->itemsp()->castPatMember(); + for (; memp || patp; ) { + // Determine replication count, and replicate initial value as widths need to be individually determined + if (patp) { + int times = visitPatMemberRep(patp); + for (int i=1; icloneTree(false); + patp->addNextHere(newp); + // This loop will see the new elements as part of nextp() + } + if (patp->keyp()) { + if (AstText* textp = patp->keyp()->castText()) { + memp = classp->findMember(textp->text()); + if (!memp) { + patp->keyp()->v3error("Assignment pattern key '"<text()<<"' not found as member"); + continue; + } + } else { + patp->keyp()->v3error("Assignment pattern key not supported/understood: "<keyp()->prettyTypeName()); + } + } + } + if (patp && patp->isDefault()) { + if (defaultp) nodep->v3error("Multiple '{ default: } clauses"); + defaultp = patp; + } else if (memp && !patp) { + // Missing init elements, warn below + memp=NULL; patp=NULL; break; + } else if (!memp && patp) { patp->v3error("Assignment pattern contains too many elements"); + memp=NULL; patp=NULL; break; + } else { + patmap.insert(make_pair(memp, patp)); + } + // Next + if (memp) memp = memp->nextp()->castMemberDType(); + if (patp) patp = patp->nextp()->castPatMember(); + } + } + AstNode* newp = NULL; + for (AstMemberDType* memp = classp->membersp(); memp; memp=memp->nextp()->castMemberDType()) { + PatMap::iterator it = patmap.find(memp); + AstPatMember* newpatp = NULL; + AstPatMember* patp = NULL; + if (it == patmap.end()) { + if (defaultp) { + newpatp = defaultp->cloneTree(false); + patp = newpatp; + } + else { + patp->v3error("Assignment pattern missed initializing elements: "<prettyTypeName()); + } + } else { + patp = it->second; + } + // Determine initial values + m_assDTypep = memp; + patp->dtypep(memp); + patp->accept(*this,WidthVP(patp->width(),patp->width(),BOTH).p()); + // Convert to concat for now + if (!newp) newp = patp->lhsp()->unlinkFrBack(); + else { + AstConcat* concatp = new AstConcat(patp->fileline(), newp, patp->lhsp()->unlinkFrBack()); + newp = concatp; + newp->dtypeSetLogicSized(concatp->lhsp()->width()+concatp->rhsp()->width(), + concatp->lhsp()->width()+concatp->rhsp()->width(), + nodep->dtypep()->numeric()); + } + if (newpatp) pushDeletep(newpatp); + } + if (newp) nodep->replaceWith(newp); + else nodep->v3error("Assignment pattern with no members"); + pushDeletep(nodep); nodep = NULL; // Deletes defaultp also, if present + } else { + nodep->v3error("Unsupported: Assignment pattern applies against non struct/union: "<prettyTypeName()); + } + } + m_assDTypep = oldAssDTypep; + } + virtual void visit(AstPatMember* nodep, AstNUser* vup) { + if (!nodep->dtypep()) nodep->v3fatalSrc("Pattern member type not assigned by AstPattern visitor"); + if (!m_assDTypep) nodep->v3error("Unsupported/Illegal: Assignment pattern member not underneath an assignment"); + nodep->lhsp()->dtypeFrom(nodep); + nodep->iterateChildren(*this,WidthVP(nodep->dtypep()->width(),nodep->dtypep()->width(),BOTH).p()); + widthCheck(nodep,"LHS",nodep->lhsp(),nodep->width(),nodep->width()); + } + int visitPatMemberRep(AstPatMember* nodep) { + uint32_t times = 1; + if (nodep->repp()) { // else repp()==NULL shorthand for rep count 1 + nodep->repp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); + checkCvtUS(nodep->repp()); + V3Const::constifyParamsEdit(nodep->repp()); // repp may change + AstConst* constp = nodep->repp()->castConst(); + if (!constp) { nodep->v3error("Replication value isn't a constant."); times=0; } + else times = constp->toUInt(); + if (times==0) { nodep->v3error("Pattern replication value of 0 is not legal."); times=1; } + nodep->repp()->unlinkFrBackWithNext()->deleteTree(); // Done with replicate before cloning + } + return times; + } + virtual void visit(AstPslClocked* nodep, AstNUser*) { nodep->propp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p()); nodep->sensesp()->iterateAndNext(*this); @@ -1077,27 +1198,32 @@ private: virtual void visit(AstNodeAssign* nodep, AstNUser*) { // TOP LEVEL NODE //if (debug()) nodep->dumpTree(cout," AssignPre: "); - nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); - nodep->rhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p()); - if (!nodep->lhsp()->dtypep()) nodep->v3fatalSrc("How can LHS be untyped?"); - if (!nodep->lhsp()->dtypep()->widthSized()) nodep->v3fatalSrc("How can LHS be unsized?"); - if (!nodep->lhsp()->isDouble() && nodep->rhsp()->isDouble()) { - spliceCvtS(nodep->rhsp(), false); // Round RHS - } else if (nodep->lhsp()->isDouble() && !nodep->rhsp()->isDouble()) { - spliceCvtD(nodep->rhsp()); + AstNodeDType* oldAssDTypep = m_assDTypep; + { + nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); + if (!nodep->lhsp()->dtypep()) nodep->v3fatalSrc("How can LHS be untyped?"); + if (!nodep->lhsp()->dtypep()->widthSized()) nodep->v3fatalSrc("How can LHS be unsized?"); + m_assDTypep = nodep->lhsp()->dtypep(); + nodep->rhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p()); + if (!nodep->lhsp()->isDouble() && nodep->rhsp()->isDouble()) { + spliceCvtS(nodep->rhsp(), false); // Round RHS + } else if (nodep->lhsp()->isDouble() && !nodep->rhsp()->isDouble()) { + spliceCvtD(nodep->rhsp()); + } + int awidth = nodep->lhsp()->width(); + if (awidth==0) { + awidth = nodep->rhsp()->width(); // Parameters can propagate by unsized assignment + } + nodep->rhsp()->iterateAndNext(*this,WidthVP(awidth,awidth,FINAL).p()); + nodep->dtypeFrom(nodep->lhsp()); + nodep->dtypeChgWidth(awidth,awidth); // We know the assign will truncate, so rather + // than using "width" and have the optimizer truncate the result, we do + // it using the normal width reduction checks. + //UINFO(0,"aw "<rhsp()->width()<<" m"<rhsp()->widthMin()<rhsp(),awidth,awidth); + //if (debug()) nodep->dumpTree(cout," AssignOut: "); } - int awidth = nodep->lhsp()->width(); - if (awidth==0) { - awidth = nodep->rhsp()->width(); // Parameters can propagate by unsized assignment - } - nodep->rhsp()->iterateAndNext(*this,WidthVP(awidth,awidth,FINAL).p()); - nodep->dtypeFrom(nodep->lhsp()); - nodep->dtypeChgWidth(awidth,awidth); // We know the assign will truncate, so rather - // than using "width" and have the optimizer truncate the result, we do - // it using the normal width reduction checks. - //UINFO(0,"aw "<rhsp()->width()<<" m"<rhsp()->widthMin()<rhsp(),awidth,awidth); - //if (debug()) nodep->dumpTree(cout," AssignOut: "); + m_assDTypep = oldAssDTypep; } virtual void visit(AstSFormatF* nodep, AstNUser*) { // Excludes NodeDisplay, see below @@ -2200,6 +2326,7 @@ public: m_funcp = NULL; m_initialp = NULL; m_attrp = NULL; + m_assDTypep = NULL; m_doGenerate = doGenerate; } AstNode* mainAcceptEdit(AstNode* nodep) { diff --git a/src/verilog.y b/src/verilog.y index 22cd4e618..47cbfe47a 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -2188,6 +2188,71 @@ caseCondList: // IEEE: part of case_item | caseCondList ',' expr { $$ = $1;$1->addNext($3); } ; +patternNoExpr: // IEEE: pattern **Excluding Expr* + '.' id/*variable*/ { $1->v3error("Unsupported: '{} tagged patterns"); $$=NULL; } + | yP_DOTSTAR { $1->v3error("Unsupported: '{} tagged patterns"); $$=NULL; } + // // IEEE: "expr" excluded; expand in callers + // // "yTAGGED id [expr]" Already part of expr + //UNSUP yTAGGED id/*member_identifier*/ patternNoExpr { $1->v3error("Unsupported: '{} tagged patterns"); $$=NULL; } + // // "yP_TICKBRA patternList '}'" part of expr under assignment_pattern + ; + +patternList: // IEEE: part of pattern + patternOne { $$ = $1; } + | patternList ',' patternOne { $$ = $1->addNextNull($3); } + ; + +patternOne: // IEEE: part of pattern + expr { $$ = new AstPatMember($1->fileline(),$1,NULL,NULL); } + | expr '{' argsExprList '}' { $$ = new AstPatMember($2,$3,NULL,$1); } + | patternNoExpr { $$ = $1; } + ; + +patternMemberList: // IEEE: part of pattern and assignment_pattern + patternMemberOne { $$ = $1; } + | patternMemberList ',' patternMemberOne { $$ = $1->addNextNull($3); } + ; + +patternMemberOne: // IEEE: part of pattern and assignment_pattern + patternKey ':' expr { $$ = new AstPatMember($2,$3,$1,NULL); } + | patternKey ':' patternNoExpr { $2->v3error("Unsupported: '{} .* patterns"); $$=NULL; } + // // From assignment_pattern_key + | yDEFAULT ':' expr { $$ = new AstPatMember($2,$3,NULL,NULL); $$->isDefault(true); } + | yDEFAULT ':' patternNoExpr { $2->v3error("Unsupported: '{} .* patterns"); $$=NULL; } + ; + +patternKey: // IEEE: merge structure_pattern_key, array_pattern_key, assignment_pattern_key + // // IEEE: structure_pattern_key + // // id/*member*/ is part of constExpr below + //UNSUP constExpr { $$ = $1; } + // // IEEE: assignment_pattern_key + //UNSUP simple_type { $1->v3error("Unsupported: '{} with data type as key"); $$=$1; } + // // simple_type reference looks like constExpr + // // Verilator: + // // The above expressions cause problems because "foo" may be a constant identifier + // // (if array) or a reference to the "foo"member (if structure) + // // So for now we only allow a true constant number, or a identifier which we treat as a structure member name + yaINTNUM { $$ = new AstConst($1,*$1); } + | yaFLOATNUM { $$ = new AstConst($1,AstConst::RealDouble(),$1); } + | yaID__ETC { $$ = new AstText($1,*$1); } + ; + +assignment_pattern: // ==IEEE: assignment_pattern + // This doesn't match the text of the spec. I think a : is missing, or example code needed + // yP_TICKBRA constExpr exprList '}' { $$="'{"+$2+" "+$3"}"; } + // // "'{ const_expression }" is same as patternList with one entry + // // From patternNoExpr + // // also IEEE: "''{' expression { ',' expression } '}'" + // // matches since patternList includes expr + yP_TICKBRA patternList '}' { $$ = new AstPattern($1,$2); } + // // From patternNoExpr + // // also IEEE "''{' structure_pattern_key ':' ... + // // also IEEE "''{' array_pattern_key ':' ... + | yP_TICKBRA patternMemberList '}' { $$ = new AstPattern($1,$2); } + // // IEEE: Not in grammar, but in VMM + | yP_TICKBRA '}' { $1->v3error("Unsupported: Empty '{}"); $$=NULL; } + ; + // "datatype id = x {, id = x }" | "yaId = x {, id=x}" is legal for_initialization: // ==IEEE: for_initialization + for_variable_declaration + extra terminating ";" // // IEEE: for_variable_declaration @@ -2705,7 +2770,7 @@ exprOkLvalue: // expression that's also OK to use as a variable_lvalue // // We allow more here than the spec requires //UNSUP ~l~exprScope assignment_pattern { UNSUP } //UNSUP data_type assignment_pattern { UNSUP } - //UNSUP assignment_pattern { UNSUP } + | assignment_pattern { $$ = $1; } // //UNSUP streaming_concatenation { UNSUP } ; diff --git a/test_regress/t/t_array_packed_value_list.v b/test_regress/t/t_array_packed_value_list.v index 1561c2cce..5e049db11 100644 --- a/test_regress/t/t_array_packed_value_list.v +++ b/test_regress/t/t_array_packed_value_list.v @@ -39,24 +39,24 @@ module t (/*AUTOARG*/ // big endian always @ (posedge clk) if (cnt[1:0]==2'd0) begin - // initialize to defaults (all bits 1'bx) - if (cnt[30:2]== 0) array_bg <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]== 1) array_bg <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]== 2) array_bg <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]== 3) array_bg <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]== 4) array_bg <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]== 5) array_bg <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]== 6) array_bg <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]== 7) array_bg <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]== 8) array_bg <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]== 9) array_bg <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]==10) array_bg <= {WA{ {WB{1'bx}} }}; + // initialize to defaults (all bits 1'b0) + if (cnt[30:2]== 0) array_bg <= '0; + else if (cnt[30:2]== 1) array_bg <= '0; + else if (cnt[30:2]== 2) array_bg <= '0; + else if (cnt[30:2]== 3) array_bg <= '0; + else if (cnt[30:2]== 4) array_bg <= '0; + else if (cnt[30:2]== 5) array_bg <= '0; + else if (cnt[30:2]== 6) array_bg <= '0; + else if (cnt[30:2]== 7) array_bg <= '0; + else if (cnt[30:2]== 8) array_bg <= '0; + else if (cnt[30:2]== 9) array_bg <= '0; + else if (cnt[30:2]==10) array_bg <= '0; end else if (cnt[1:0]==2'd1) begin // write data into whole or part of the array using literals if (cnt[30:2]== 0) begin end else if (cnt[30:2]== 1) array_bg <= '{ 3 ,2 ,1, 0 }; - else if (cnt[30:2]== 2) array_bg <= '{0:4, 1:5, 2:6, 3:7}; - else if (cnt[30:2]== 3) array_bg <= '{default:13}; + else if (cnt[30:2]== 2) array_bg <= '{default:13}; + else if (cnt[30:2]== 3) array_bg <= '{0:4, 1:5, 2:6, 3:7}; else if (cnt[30:2]== 4) array_bg <= '{2:15, default:13}; else if (cnt[30:2]== 5) array_bg <= '{WA { {WB/2 {2'b10}} }}; else if (cnt[30:2]== 6) array_bg <= '{WA { {3'b101, {WB/2-1{2'b10}}} }}; @@ -66,40 +66,40 @@ module t (/*AUTOARG*/ else if (cnt[30:2]==10) array_bg <= '{cnt+0, cnt+1, cnt+2, cnt+3}; end else if (cnt[1:0]==2'd2) begin // chack array agains expected value - if (cnt[30:2]== 0) begin if (array_bg !== 16'bxxxxxxxxxxxxxxxx) begin $display("%b", array_bg); $stop(); end end + if (cnt[30:2]== 0) begin if (array_bg !== 16'b0000000000000000) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]== 1) begin if (array_bg !== 16'b0011001000010000) begin $display("%b", array_bg); $stop(); end end - else if (cnt[30:2]== 2) begin if (array_bg !== 16'b0111011001010100) begin $display("%b", array_bg); $stop(); end end - else if (cnt[30:2]== 3) begin if (array_bg !== 16'b1101110111011101) begin $display("%b", array_bg); $stop(); end end + else if (cnt[30:2]== 2) begin if (array_bg !== 16'b1101110111011101) begin $display("%b", array_bg); $stop(); end end + else if (cnt[30:2]== 3) begin if (array_bg !== 16'b0111011001010100) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]== 4) begin if (array_bg !== 16'b1101111111011101) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]== 5) begin if (array_bg !== 16'b1010101010101010) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]== 6) begin if (array_bg !== 16'b0110011001100110) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]== 7) begin if (array_bg !== 16'b0010001000100010) begin $display("%b", array_bg); $stop(); end end - else if (cnt[30:2]== 8) begin if (array_bg !== 16'b10101010xxxxxxxx) begin $display("%b", array_bg); $stop(); end end - else if (cnt[30:2]== 9) begin if (array_bg !== 16'bxxxxxxxx10101010) begin $display("%b", array_bg); $stop(); end end + else if (cnt[30:2]== 8) begin if (array_bg !== 16'b1010101000000000) begin $display("%b", array_bg); $stop(); end end + else if (cnt[30:2]== 9) begin if (array_bg !== 16'b0000000010101010) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]==10) begin if (array_bg !== 16'b1001101010111100) begin $display("%b", array_bg); $stop(); end end end // little endian always @ (posedge clk) if (cnt[1:0]==2'd0) begin - // initialize to defaults (all bits 1'bx) - if (cnt[30:2]== 0) array_lt <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]== 1) array_lt <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]== 2) array_lt <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]== 3) array_lt <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]== 4) array_lt <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]== 5) array_lt <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]== 6) array_lt <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]== 7) array_lt <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]== 8) array_lt <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]== 9) array_lt <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]==10) array_lt <= {WA{ {WB{1'bx}} }}; + // initialize to defaults (all bits 1'b0) + if (cnt[30:2]== 0) array_lt <= '0; + else if (cnt[30:2]== 1) array_lt <= '0; + else if (cnt[30:2]== 2) array_lt <= '0; + else if (cnt[30:2]== 3) array_lt <= '0; + else if (cnt[30:2]== 4) array_lt <= '0; + else if (cnt[30:2]== 5) array_lt <= '0; + else if (cnt[30:2]== 6) array_lt <= '0; + else if (cnt[30:2]== 7) array_lt <= '0; + else if (cnt[30:2]== 8) array_lt <= '0; + else if (cnt[30:2]== 9) array_lt <= '0; + else if (cnt[30:2]==10) array_lt <= '0; end else if (cnt[1:0]==2'd1) begin // write data into whole or part of the array using literals if (cnt[30:2]== 0) begin end else if (cnt[30:2]== 1) array_lt <= '{ 3 ,2 ,1, 0 }; - else if (cnt[30:2]== 2) array_lt <= '{3:4, 2:5, 1:6, 0:7}; - else if (cnt[30:2]== 3) array_lt <= '{default:13}; + else if (cnt[30:2]== 2) array_lt <= '{default:13}; + else if (cnt[30:2]== 3) array_lt <= '{3:4, 2:5, 1:6, 0:7}; else if (cnt[30:2]== 4) array_lt <= '{1:15, default:13}; else if (cnt[30:2]== 5) array_lt <= '{WA { {WB/2 {2'b10}} }}; else if (cnt[30:2]== 6) array_lt <= '{WA { {3'b101, {WB/2-1{2'b10}}} }}; @@ -109,16 +109,16 @@ module t (/*AUTOARG*/ else if (cnt[30:2]==10) array_lt <= '{cnt+0, cnt+1, cnt+2, cnt+3}; end else if (cnt[1:0]==2'd2) begin // chack array agains expected value - if (cnt[30:2]== 0) begin if (array_lt !== 16'bxxxxxxxxxxxxxxxx) begin $display("%b", array_lt); $stop(); end end + if (cnt[30:2]== 0) begin if (array_lt !== 16'b0000000000000000) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]== 1) begin if (array_lt !== 16'b0011001000010000) begin $display("%b", array_lt); $stop(); end end - else if (cnt[30:2]== 2) begin if (array_lt !== 16'b0111011001010100) begin $display("%b", array_lt); $stop(); end end - else if (cnt[30:2]== 3) begin if (array_lt !== 16'b1101110111011101) begin $display("%b", array_lt); $stop(); end end + else if (cnt[30:2]== 2) begin if (array_lt !== 16'b1101110111011101) begin $display("%b", array_lt); $stop(); end end + else if (cnt[30:2]== 3) begin if (array_lt !== 16'b0111011001010100) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]== 4) begin if (array_lt !== 16'b1101111111011101) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]== 5) begin if (array_lt !== 16'b1010101010101010) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]== 6) begin if (array_lt !== 16'b0110011001100110) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]== 7) begin if (array_lt !== 16'b0010001000100010) begin $display("%b", array_lt); $stop(); end end - else if (cnt[30:2]== 8) begin if (array_lt !== 16'b10101010xxxxxxxx) begin $display("%b", array_lt); $stop(); end end - else if (cnt[30:2]== 9) begin if (array_lt !== 16'bxxxxxxxx10101010) begin $display("%b", array_lt); $stop(); end end + else if (cnt[30:2]== 8) begin if (array_lt !== 16'b1010101000000000) begin $display("%b", array_lt); $stop(); end end + else if (cnt[30:2]== 9) begin if (array_lt !== 16'b0000000010101010) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]==10) begin if (array_lt !== 16'b1001101010111100) begin $display("%b", array_lt); $stop(); end end end diff --git a/test_regress/t/t_array_packed_write_read.v b/test_regress/t/t_array_packed_write_read.v index c41edf9fa..7012a708f 100644 --- a/test_regress/t/t_array_packed_write_read.v +++ b/test_regress/t/t_array_packed_write_read.v @@ -39,17 +39,17 @@ module t (/*AUTOARG*/ // big endian always @ (posedge clk) if (cnt[1:0]==2'd0) begin - // initialize to defaaults (all bits to x) - if (cnt[30:2]==0) array_bg <= {WA *WB{1'bx} }; - else if (cnt[30:2]==1) array_bg <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]==2) array_bg <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]==3) array_bg <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]==4) array_bg <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]==5) array_bg <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]==6) array_bg <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]==7) array_bg <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]==8) array_bg <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]==9) array_bg <= {WA{ {WB{1'bx}} }}; + // initialize to defaaults (all bits to 0) + if (cnt[30:2]==0) array_bg <= '0; + else if (cnt[30:2]==1) array_bg <= '0; + else if (cnt[30:2]==2) array_bg <= '0; + else if (cnt[30:2]==3) array_bg <= '0; + else if (cnt[30:2]==4) array_bg <= '0; + else if (cnt[30:2]==5) array_bg <= '0; + else if (cnt[30:2]==6) array_bg <= '0; + else if (cnt[30:2]==7) array_bg <= '0; + else if (cnt[30:2]==8) array_bg <= '0; + else if (cnt[30:2]==9) array_bg <= '0; end else if (cnt[1:0]==2'd1) begin // write value to array if (cnt[30:2]==0) begin end @@ -64,19 +64,19 @@ module t (/*AUTOARG*/ else if (cnt[30:2]==9) array_bg [WA -1 ][WB -1 ] <= {1 *1 +0{1'b1}}; end else if (cnt[1:0]==2'd2) begin // check array value - if (cnt[30:2]==0) begin if (array_bg !== 64'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) begin $display("%b", array_bg); $stop(); end end + if (cnt[30:2]==0) begin if (array_bg !== 64'b0000000000000000000000000000000000000000000000000000000000000000) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]==1) begin if (array_bg !== 64'b1111111111111111111111111111111111111111111111111111111111111111) begin $display("%b", array_bg); $stop(); end end - else if (cnt[30:2]==2) begin if (array_bg !== 64'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx11111111111111111111111111111111) begin $display("%b", array_bg); $stop(); end end - else if (cnt[30:2]==3) begin if (array_bg !== 64'b11111111111111111111111111111111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) begin $display("%b", array_bg); $stop(); end end - else if (cnt[30:2]==4) begin if (array_bg !== 64'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx11111111) begin $display("%b", array_bg); $stop(); end end - else if (cnt[30:2]==5) begin if (array_bg !== 64'b11111111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) begin $display("%b", array_bg); $stop(); end end - else if (cnt[30:2]==6) begin if (array_bg !== 64'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1111) begin $display("%b", array_bg); $stop(); end end - else if (cnt[30:2]==7) begin if (array_bg !== 64'b1111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) begin $display("%b", array_bg); $stop(); end end - else if (cnt[30:2]==8) begin if (array_bg !== 64'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1) begin $display("%b", array_bg); $stop(); end end - else if (cnt[30:2]==9) begin if (array_bg !== 64'b1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) begin $display("%b", array_bg); $stop(); end end + else if (cnt[30:2]==2) begin if (array_bg !== 64'b0000000000000000000000000000000011111111111111111111111111111111) begin $display("%b", array_bg); $stop(); end end + else if (cnt[30:2]==3) begin if (array_bg !== 64'b1111111111111111111111111111111100000000000000000000000000000000) begin $display("%b", array_bg); $stop(); end end + else if (cnt[30:2]==4) begin if (array_bg !== 64'b0000000000000000000000000000000000000000000000000000000011111111) begin $display("%b", array_bg); $stop(); end end + else if (cnt[30:2]==5) begin if (array_bg !== 64'b1111111100000000000000000000000000000000000000000000000000000000) begin $display("%b", array_bg); $stop(); end end + else if (cnt[30:2]==6) begin if (array_bg !== 64'b0000000000000000000000000000000000000000000000000000000000001111) begin $display("%b", array_bg); $stop(); end end + else if (cnt[30:2]==7) begin if (array_bg !== 64'b1111000000000000000000000000000000000000000000000000000000000000) begin $display("%b", array_bg); $stop(); end end + else if (cnt[30:2]==8) begin if (array_bg !== 64'b0000000000000000000000000000000000000000000000000000000000000001) begin $display("%b", array_bg); $stop(); end end + else if (cnt[30:2]==9) begin if (array_bg !== 64'b1000000000000000000000000000000000000000000000000000000000000000) begin $display("%b", array_bg); $stop(); end end end else if (cnt[1:0]==2'd3) begin // read value from array (not a very good test for now) - if (cnt[30:2]==0) begin if (array_bg !== {WA *WB {1'bx}}) $stop(); end + if (cnt[30:2]==0) begin if (array_bg !== {WA *WB {1'b0}}) $stop(); end else if (cnt[30:2]==1) begin if (array_bg !== {WA *WB +0{1'b1}}) $stop(); end else if (cnt[30:2]==2) begin if (array_bg [WA/2-1:0 ] !== {WA/2*WB +0{1'b1}}) $stop(); end else if (cnt[30:2]==3) begin if (array_bg [WA -1:WA/2] !== {WA/2*WB +0{1'b1}}) $stop(); end @@ -91,17 +91,17 @@ module t (/*AUTOARG*/ // little endian always @ (posedge clk) if (cnt[1:0]==2'd0) begin - // initialize to defaaults (all bits to x) - if (cnt[30:2]==0) array_lt <= {WA *WB{1'bx} }; - else if (cnt[30:2]==1) array_lt <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]==2) array_lt <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]==3) array_lt <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]==4) array_lt <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]==5) array_lt <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]==6) array_lt <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]==7) array_lt <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]==8) array_lt <= {WA{ {WB{1'bx}} }}; - else if (cnt[30:2]==9) array_lt <= {WA{ {WB{1'bx}} }}; + // initialize to defaaults (all bits to 0) + if (cnt[30:2]==0) array_lt <= '0; + else if (cnt[30:2]==1) array_lt <= '0; + else if (cnt[30:2]==2) array_lt <= '0; + else if (cnt[30:2]==3) array_lt <= '0; + else if (cnt[30:2]==4) array_lt <= '0; + else if (cnt[30:2]==5) array_lt <= '0; + else if (cnt[30:2]==6) array_lt <= '0; + else if (cnt[30:2]==7) array_lt <= '0; + else if (cnt[30:2]==8) array_lt <= '0; + else if (cnt[30:2]==9) array_lt <= '0; end else if (cnt[1:0]==2'd1) begin // write value to array if (cnt[30:2]==0) begin end @@ -116,19 +116,19 @@ module t (/*AUTOARG*/ else if (cnt[30:2]==9) array_lt [ WA -1][ WB -1] <= {1 *1 +0{1'b1}}; end else if (cnt[1:0]==2'd2) begin // check array value - if (cnt[30:2]==0) begin if (array_lt !== 64'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) begin $display("%b", array_lt); $stop(); end end + if (cnt[30:2]==0) begin if (array_lt !== 64'b0000000000000000000000000000000000000000000000000000000000000000) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]==1) begin if (array_lt !== 64'b1111111111111111111111111111111111111111111111111111111111111111) begin $display("%b", array_lt); $stop(); end end - else if (cnt[30:2]==2) begin if (array_lt !== 64'b11111111111111111111111111111111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) begin $display("%b", array_lt); $stop(); end end - else if (cnt[30:2]==3) begin if (array_lt !== 64'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx11111111111111111111111111111111) begin $display("%b", array_lt); $stop(); end end - else if (cnt[30:2]==4) begin if (array_lt !== 64'b11111111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) begin $display("%b", array_lt); $stop(); end end - else if (cnt[30:2]==5) begin if (array_lt !== 64'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx11111111) begin $display("%b", array_lt); $stop(); end end - else if (cnt[30:2]==6) begin if (array_lt !== 64'b1111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) begin $display("%b", array_lt); $stop(); end end - else if (cnt[30:2]==7) begin if (array_lt !== 64'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1111) begin $display("%b", array_lt); $stop(); end end - else if (cnt[30:2]==8) begin if (array_lt !== 64'b1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) begin $display("%b", array_lt); $stop(); end end - else if (cnt[30:2]==9) begin if (array_lt !== 64'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1) begin $display("%b", array_lt); $stop(); end end + else if (cnt[30:2]==2) begin if (array_lt !== 64'b1111111111111111111111111111111100000000000000000000000000000000) begin $display("%b", array_lt); $stop(); end end + else if (cnt[30:2]==3) begin if (array_lt !== 64'b0000000000000000000000000000000011111111111111111111111111111111) begin $display("%b", array_lt); $stop(); end end + else if (cnt[30:2]==4) begin if (array_lt !== 64'b1111111100000000000000000000000000000000000000000000000000000000) begin $display("%b", array_lt); $stop(); end end + else if (cnt[30:2]==5) begin if (array_lt !== 64'b0000000000000000000000000000000000000000000000000000000011111111) begin $display("%b", array_lt); $stop(); end end + else if (cnt[30:2]==6) begin if (array_lt !== 64'b1111000000000000000000000000000000000000000000000000000000000000) begin $display("%b", array_lt); $stop(); end end + else if (cnt[30:2]==7) begin if (array_lt !== 64'b0000000000000000000000000000000000000000000000000000000000001111) begin $display("%b", array_lt); $stop(); end end + else if (cnt[30:2]==8) begin if (array_lt !== 64'b1000000000000000000000000000000000000000000000000000000000000000) begin $display("%b", array_lt); $stop(); end end + else if (cnt[30:2]==9) begin if (array_lt !== 64'b0000000000000000000000000000000000000000000000000000000000000001) begin $display("%b", array_lt); $stop(); end end end else if (cnt[1:0]==2'd3) begin // read value from array (not a very good test for now) - if (cnt[30:2]==0) begin if (array_lt !== {WA *WB {1'bx}}) $stop(); end + if (cnt[30:2]==0) begin if (array_lt !== {WA *WB {1'b0}}) $stop(); end else if (cnt[30:2]==1) begin if (array_lt !== {WA *WB +0{1'b1}}) $stop(); end else if (cnt[30:2]==2) begin if (array_lt [0 :WA/2-1] !== {WA/2*WB +0{1'b1}}) $stop(); end else if (cnt[30:2]==3) begin if (array_lt [WA/2:WA -1] !== {WA/2*WB +0{1'b1}}) $stop(); end diff --git a/test_regress/t/t_struct_init.v b/test_regress/t/t_struct_init.v index 93345fee8..5f1fb9ddb 100644 --- a/test_regress/t/t_struct_init.v +++ b/test_regress/t/t_struct_init.v @@ -15,6 +15,11 @@ module t; bit b0; } b4_t; + typedef struct packed { // [3:0] + b4_t x1; + b4_t x0; + } b4x2_t; + typedef union packed { // [3:0] bit [3:0] quad0; b4_t quad1; @@ -60,7 +65,6 @@ module t; if (arr[1].four !== 4'b1010) $stop; // // Initialization -`ifndef VERILATOR // UNSUPPORTED begin b4_t q = '{1'b1, 1'b1, 1'b0, 1'b0}; if (q != 4'b1100) $stop; @@ -74,18 +78,21 @@ module t; if (q != 4'b1111) $stop; end begin - b4_t q = '{b0:1'b1, b2:1'b1, b3:1'b1, b1:1'b0}; - if (q != 4'b1101) $stop; + b4x2_t m = '{4'b1001, '{1'b1, 1'b0, 1'b1, 1'b1}}; + if (m != 8'b10011011) $stop; end begin b4_t q = '{default:1'b1}; if (q != 4'b1111) $stop; - q.b1 = 0; - if (q != 4'b1101) $stop; - {q.b3,q.b2} = 2'b10; - if (q != 4'b1001) $stop; end -`endif + begin + b4_t q = '{b0:1'b1, b2:1'b1, b3:1'b1, b1:1'b0}; + if (q != 4'b1101) $stop; + end + begin + b4_t q = '{b2:1'b0, default:1'b1}; + if (q != 4'b1011) $stop; + end $write("*-* All Finished *-*\n"); $finish; diff --git a/test_regress/t/t_struct_packed_value_list.pl b/test_regress/t/t_struct_packed_value_list.pl index 8b6510320..7058e622f 100755 --- a/test_regress/t/t_struct_packed_value_list.pl +++ b/test_regress/t/t_struct_packed_value_list.pl @@ -7,8 +7,6 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Lesser General Public License Version 3 or the Perl Artistic License # Version 2.0. -$Self->{vlt} and $Self->unsupported("Verilator unsupported, bug355"); - compile ( ); diff --git a/test_regress/t/t_struct_packed_value_list.v b/test_regress/t/t_struct_packed_value_list.v index 0a833ffee..308547afb 100644 --- a/test_regress/t/t_struct_packed_value_list.v +++ b/test_regress/t/t_struct_packed_value_list.v @@ -48,26 +48,28 @@ module t (/*AUTOARG*/ // big endian always @ (posedge clk) if (cnt[1:0]==2'd0) begin - // initialize to defaults (all bits 1'bx) - if (cnt[30:2]==0) struct_bg <= {WS{1'bx}}; - else if (cnt[30:2]==1) struct_bg <= {WS{1'bx}}; - else if (cnt[30:2]==2) struct_bg <= {WS{1'bx}}; - else if (cnt[30:2]==3) struct_bg <= {WS{1'bx}}; - else if (cnt[30:2]==4) struct_bg <= {WS{1'bx}}; - else if (cnt[30:2]==5) struct_bg <= {WS{1'bx}}; - else if (cnt[30:2]==6) struct_bg <= {WS{1'bx}}; + // initialize to defaults (all bits 1'b0) + if (cnt[30:2]==0) struct_bg <= '0; + else if (cnt[30:2]==1) struct_bg <= '0; + else if (cnt[30:2]==2) struct_bg <= '0; + else if (cnt[30:2]==3) struct_bg <= '0; + else if (cnt[30:2]==4) struct_bg <= '0; + else if (cnt[30:2]==5) struct_bg <= '0; + else if (cnt[30:2]==6) struct_bg <= '0; end else if (cnt[1:0]==2'd1) begin // write data into whole or part of the array using literals if (cnt[30:2]==0) begin end else if (cnt[30:2]==1) struct_bg <= '{0 ,1 , 2, 3}; else if (cnt[30:2]==2) struct_bg <= '{e0:1, e1:2, e2:3, e3:4}; else if (cnt[30:2]==3) struct_bg <= '{e3:6, e2:4, e1:2, e0:0}; + // verilator lint_off WIDTH else if (cnt[30:2]==4) struct_bg <= '{default:13}; else if (cnt[30:2]==5) struct_bg <= '{e2:8'haa, default:1}; else if (cnt[30:2]==6) struct_bg <= '{cnt+0 ,cnt+1 , cnt+2, cnt+3}; + // verilator lint_on WIDTH end else if (cnt[1:0]==2'd2) begin // chack array agains expected value - if (cnt[30:2]==0) begin if (struct_bg !== 15'bx_xx_xxxx_xxxxxxxx) begin $display("%b", struct_bg); $stop(); end end + if (cnt[30:2]==0) begin if (struct_bg !== 15'b0_00_0000_00000000) begin $display("%b", struct_bg); $stop(); end end else if (cnt[30:2]==1) begin if (struct_bg !== 15'b0_01_0010_00000011) begin $display("%b", struct_bg); $stop(); end end else if (cnt[30:2]==2) begin if (struct_bg !== 15'b1_10_0011_00000100) begin $display("%b", struct_bg); $stop(); end end else if (cnt[30:2]==3) begin if (struct_bg !== 15'b0_10_0100_00000110) begin $display("%b", struct_bg); $stop(); end end @@ -79,26 +81,28 @@ module t (/*AUTOARG*/ // little endian always @ (posedge clk) if (cnt[1:0]==2'd0) begin - // initialize to defaults (all bits 1'bx) - if (cnt[30:2]==0) struct_lt <= {WS{1'bx}}; - else if (cnt[30:2]==1) struct_lt <= {WS{1'bx}}; - else if (cnt[30:2]==2) struct_lt <= {WS{1'bx}}; - else if (cnt[30:2]==3) struct_lt <= {WS{1'bx}}; - else if (cnt[30:2]==4) struct_lt <= {WS{1'bx}}; - else if (cnt[30:2]==5) struct_lt <= {WS{1'bx}}; - else if (cnt[30:2]==6) struct_lt <= {WS{1'bx}}; + // initialize to defaults (all bits 1'b0) + if (cnt[30:2]==0) struct_lt <= '0; + else if (cnt[30:2]==1) struct_lt <= '0; + else if (cnt[30:2]==2) struct_lt <= '0; + else if (cnt[30:2]==3) struct_lt <= '0; + else if (cnt[30:2]==4) struct_lt <= '0; + else if (cnt[30:2]==5) struct_lt <= '0; + else if (cnt[30:2]==6) struct_lt <= '0; end else if (cnt[1:0]==2'd1) begin // write data into whole or part of the array using literals if (cnt[30:2]==0) begin end else if (cnt[30:2]==1) struct_lt <= '{0 ,1 , 2, 3}; else if (cnt[30:2]==2) struct_lt <= '{e0:1, e1:2, e2:3, e3:4}; else if (cnt[30:2]==3) struct_lt <= '{e3:6, e2:4, e1:2, e0:0}; + // verilator lint_off WIDTH else if (cnt[30:2]==4) struct_lt <= '{default:13}; else if (cnt[30:2]==5) struct_lt <= '{e2:8'haa, default:1}; else if (cnt[30:2]==6) struct_lt <= '{cnt+0 ,cnt+1 , cnt+2, cnt+3}; + // verilator lint_on WIDTH end else if (cnt[1:0]==2'd2) begin // chack array agains expected value - if (cnt[30:2]==0) begin if (struct_lt !== 15'bx_xx_xxxx_xxxxxxxx) begin $display("%b", struct_lt); $stop(); end end + if (cnt[30:2]==0) begin if (struct_lt !== 15'b0_00_0000_00000000) begin $display("%b", struct_lt); $stop(); end end else if (cnt[30:2]==1) begin if (struct_lt !== 15'b0_01_0010_00000011) begin $display("%b", struct_lt); $stop(); end end else if (cnt[30:2]==2) begin if (struct_lt !== 15'b1_10_0011_00000100) begin $display("%b", struct_lt); $stop(); end end else if (cnt[30:2]==3) begin if (struct_lt !== 15'b0_10_0100_00000110) begin $display("%b", struct_lt); $stop(); end end