diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 4cef449b3..88379135b 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -354,7 +354,7 @@ AstNode* AstArraySel::baseFromp(AstNode* nodep) { ///< What is the base variable while (nodep) { if (nodep->castArraySel()) { nodep=nodep->castArraySel()->fromp(); continue; } else if (nodep->castSel()) { nodep=nodep->castSel()->fromp(); continue; } - // AstNodeSelPre stashes the associated variable under a ATTROF so it isn't constified + // AstNodeSelPre stashes the associated variable under a ATTROF of AstAttrType::VAR_BASE/MEMBER_BASE so it isn't constified else if (nodep->castAttrOf()) { nodep=nodep->castAttrOf()->fromp(); continue; } else if (nodep->castNodePreSel()) { if (nodep->castNodePreSel()->attrp()) { diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index 0a90434f1..cd2aa4d93 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -309,7 +309,7 @@ private: // Below 2 lines may change nodep->widthp() V3Const::constifyParamsEdit(nodep->thsp()); // May relink pointed to node checkConstantOrReplace(nodep->thsp(), "Width of :+ or :- bit extract isn't a constant"); - // Now replace it with a AstSel + // Now replace it with an AstSel AstNode* basefromp = AstArraySel::baseFromp(nodep->attrp()); int dimension = AstArraySel::dimension(nodep->fromp()); // Not attrp as need hierarchy AstNode* fromp = nodep->lhsp()->unlinkFrBack(); diff --git a/test_regress/t/t_struct_init.v b/test_regress/t/t_struct_init.v index 08d29695f..93345fee8 100644 --- a/test_regress/t/t_struct_init.v +++ b/test_regress/t/t_struct_init.v @@ -8,73 +8,87 @@ module t; //Several simulators don't support this. //typedef struct pack2; // Forward declaration - typedef struct packed { + typedef struct packed { // [3:0] bit b3; bit b2; bit b1; bit b0; } b4_t; - typedef union packed { + typedef union packed { // [3:0] bit [3:0] quad0; b4_t quad1; } q4_t; - typedef struct packed { + typedef struct packed { // [5:0] bit msb; q4_t four; bit lsb; } pack2_t; - typedef union packed { + typedef union packed { // [5:0] pack2_t pack2; - bit [5:0] pvec; - // Vector not allowed in packed structure: (Seems cheezy to disallow this) + bit [6:1] pvec; + // Vector not allowed in packed structure, per spec: // bit vec[6]; // bit vec2d[2][3]; } pack3_t; + pack2_t arr[2]; + initial begin pack3_t tsu; - tsu = 6'b100110; - if (tsu!=6'b100110) $stop; - if (tsu.pvec!=6'b100110) $stop; + tsu = 6'b110110; + // 543210 + if (tsu!=6'b110110) $stop; + if (tsu[5:4]!=2'b11) $stop; + if (tsu[5:4] == tsu[1:0]) $stop; // Not a good extraction test if LSB subtraction doesn't matter + if (tsu.pvec!=6'b110110) $stop; + if (tsu.pvec[6:5]!=2'b11) $stop; + if (tsu.pack2[5:1] != 5'b11011) $stop; if (tsu.pack2.msb != 1'b1) $stop; if (tsu.pack2.lsb != 1'b0) $stop; - if (tsu.pack2.four.quad0 != 4'b0011) $stop; + if (tsu.pack2.four.quad0 != 4'b1011) $stop; if (tsu.pack2.four.quad1.b0 != 1'b1) $stop; if (tsu.pack2.four.quad1.b1 != 1'b1) $stop; if (tsu.pack2.four.quad1.b2 != 1'b0) $stop; - if (tsu.pack2.four.quad1.b3 != 1'b0) $stop; + if (tsu.pack2.four.quad1.b3 != 1'b1) $stop; + // + arr[0] = 6'b101010; + arr[1] = 6'b010101; + if (arr[0].four !== 4'b0101) $stop; + 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; + end + begin + b4_t q = '{3{1'b1}, 1'b0}; + if (q != 4'b1110) $stop; + end + begin + b4_t q = '{4{1'b1}}; // Repeats the {} + 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; + 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 $write("*-* All Finished *-*\n"); $finish; end - initial begin - $display("Need init fix\n"); - $stop; - end -//UNSUP // Initialization -//UNSUP initial begin -//UNSUP b4_t q = '{1'b1, 1'b1, 1'b0, 1'b0}; -//UNSUP if (q != 4'b1100) $stop; -//UNSUP end -//UNSUP initial begin -//UNSUP b4_t q = '{4{1'b1}}; // Repeats the {} -//UNSUP if (q != 4'b1111) $stop; -//UNSUP end -//UNSUP initial begin -//UNSUP b4_t q = '{b0:1'b1, b2:1'b1, b3:1'b1, b1:1'b0}; -//UNSUP if (q != 4'b1101) $stop; -//UNSUP end -//UNSUP initial begin -//UNSUP b4_t q = '{default:1'b1}; -//UNSUP if (q != 4'b1111) $stop; -//UNSUP q.b1 = 0; -//UNSUP if (q != 4'b1101) $stop; -//UNSUP {q.b3,q.b2} = 2'b10; -//UNSUP if (q != 4'b1001) $stop; -//UNSUP end - endmodule diff --git a/test_regress/t/t_struct_packed_write_read.v b/test_regress/t/t_struct_packed_write_read.v index de2ba3ea3..3b689e935 100644 --- a/test_regress/t/t_struct_packed_write_read.v +++ b/test_regress/t/t_struct_packed_write_read.v @@ -48,32 +48,32 @@ 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) 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}}; + // initialize to defaaults (all bits to 0) + 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; end else if (cnt[1:0]==2'd1) begin // write value to structure if (cnt[30:2]==0) begin end - else if (cnt[30:2]==1) struct_bg <= {WS{1'b1}}; - else if (cnt[30:2]==2) struct_bg.e0 <= {WS{1'b1}}; - else if (cnt[30:2]==3) struct_bg.e1 <= {WS{1'b1}}; - else if (cnt[30:2]==4) struct_bg.e2 <= {WS{1'b1}}; - else if (cnt[30:2]==5) struct_bg.e3 <= {WS{1'b1}}; + else if (cnt[30:2]==1) struct_bg <= '1; + else if (cnt[30:2]==2) struct_bg.e0 <= '1; + else if (cnt[30:2]==3) struct_bg.e1 <= '1; + else if (cnt[30:2]==4) struct_bg.e2 <= '1; + else if (cnt[30:2]==5) struct_bg.e3 <= '1; end else if (cnt[1:0]==2'd2) begin // check structure value - if (cnt[30:2]==0) begin if (struct_bg !== 15'bxxxxxxxxxxxxxxx) begin $display("%b", struct_bg); $stop(); end end + if (cnt[30:2]==0) begin if (struct_bg !== 15'b000000000000000) begin $display("%b", struct_bg); $stop(); end end else if (cnt[30:2]==1) begin if (struct_bg !== 15'b111111111111111) begin $display("%b", struct_bg); $stop(); end end - else if (cnt[30:2]==2) begin if (struct_bg !== 15'b1xxxxxxxxxxxxxx) begin $display("%b", struct_bg); $stop(); end end - else if (cnt[30:2]==3) begin if (struct_bg !== 15'bx11xxxxxxxxxxxx) begin $display("%b", struct_bg); $stop(); end end - else if (cnt[30:2]==4) begin if (struct_bg !== 15'bxxx1111xxxxxxxx) begin $display("%b", struct_bg); $stop(); end end - else if (cnt[30:2]==5) begin if (struct_bg !== 15'bxxxxxxx11111111) begin $display("%b", struct_bg); $stop(); end end + else if (cnt[30:2]==2) begin if (struct_bg !== 15'b100000000000000) begin $display("%b", struct_bg); $stop(); end end + else if (cnt[30:2]==3) begin if (struct_bg !== 15'b011000000000000) begin $display("%b", struct_bg); $stop(); end end + else if (cnt[30:2]==4) begin if (struct_bg !== 15'b000111100000000) begin $display("%b", struct_bg); $stop(); end end + else if (cnt[30:2]==5) begin if (struct_bg !== 15'b000000011111111) begin $display("%b", struct_bg); $stop(); end end end else if (cnt[1:0]==2'd3) begin // read value from structure (not a very good test for now) - if (cnt[30:2]==0) begin if (struct_bg !== {WS{1'bx}}) $stop(); end + if (cnt[30:2]==0) begin if (struct_bg !== {WS{1'b0}}) $stop(); end else if (cnt[30:2]==1) begin if (struct_bg !== {WS{1'b1}}) $stop(); end else if (cnt[30:2]==2) begin if (struct_bg.e0 !== { 1{1'b1}}) $stop(); end else if (cnt[30:2]==3) begin if (struct_bg.e1 !== { 2{1'b1}}) $stop(); end @@ -84,32 +84,32 @@ 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) 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}}; + // initialize to defaaults (all bits to 0) + 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; end else if (cnt[1:0]==2'd1) begin // write value to structure if (cnt[30:2]==0) begin end - else if (cnt[30:2]==1) struct_lt <= {WS{1'b1}}; - else if (cnt[30:2]==2) struct_lt.e0 <= {WS{1'b1}}; - else if (cnt[30:2]==3) struct_lt.e1 <= {WS{1'b1}}; - else if (cnt[30:2]==4) struct_lt.e2 <= {WS{1'b1}}; - else if (cnt[30:2]==5) struct_lt.e3 <= {WS{1'b1}}; + else if (cnt[30:2]==1) struct_lt <= '1; + else if (cnt[30:2]==2) struct_lt.e0 <= '1; + else if (cnt[30:2]==3) struct_lt.e1 <= '1; + else if (cnt[30:2]==4) struct_lt.e2 <= '1; + else if (cnt[30:2]==5) struct_lt.e3 <= '1; end else if (cnt[1:0]==2'd2) begin // check structure value - if (cnt[30:2]==0) begin if (struct_lt !== 15'bxxxxxxxxxxxxxxx) begin $display("%b", struct_lt); $stop(); end end + if (cnt[30:2]==0) begin if (struct_lt !== 15'b000000000000000) begin $display("%b", struct_lt); $stop(); end end else if (cnt[30:2]==1) begin if (struct_lt !== 15'b111111111111111) begin $display("%b", struct_lt); $stop(); end end - else if (cnt[30:2]==2) begin if (struct_lt !== 15'b1xxxxxxxxxxxxxx) begin $display("%b", struct_lt); $stop(); end end - else if (cnt[30:2]==3) begin if (struct_lt !== 15'bx11xxxxxxxxxxxx) begin $display("%b", struct_lt); $stop(); end end - else if (cnt[30:2]==4) begin if (struct_lt !== 15'bxxx1111xxxxxxxx) begin $display("%b", struct_lt); $stop(); end end - else if (cnt[30:2]==5) begin if (struct_lt !== 15'bxxxxxxx11111111) begin $display("%b", struct_lt); $stop(); end end + else if (cnt[30:2]==2) begin if (struct_lt !== 15'b100000000000000) begin $display("%b", struct_lt); $stop(); end end + else if (cnt[30:2]==3) begin if (struct_lt !== 15'b011000000000000) begin $display("%b", struct_lt); $stop(); end end + else if (cnt[30:2]==4) begin if (struct_lt !== 15'b000111100000000) begin $display("%b", struct_lt); $stop(); end end + else if (cnt[30:2]==5) begin if (struct_lt !== 15'b000000011111111) begin $display("%b", struct_lt); $stop(); end end end else if (cnt[1:0]==2'd3) begin // read value from structure (not a very good test for now) - if (cnt[30:2]==0) begin if (struct_lt !== {WS{1'bx}}) $stop(); end + if (cnt[30:2]==0) begin if (struct_lt !== {WS{1'b0}}) $stop(); end else if (cnt[30:2]==1) begin if (struct_lt !== {WS{1'b1}}) $stop(); end else if (cnt[30:2]==2) begin if (struct_lt.e0 !== { 1{1'b1}}) $stop(); end else if (cnt[30:2]==3) begin if (struct_lt.e1 !== { 2{1'b1}}) $stop(); end diff --git a/test_regress/t/t_struct_port.v b/test_regress/t/t_struct_port.v index 80319c36d..18d749bea 100644 --- a/test_regress/t/t_struct_port.v +++ b/test_regress/t/t_struct_port.v @@ -21,7 +21,7 @@ module t (/*AUTOARG*/ // Take CRC data and apply to testblock inputs pack_t in; - always @* in = crc[10:0]; + always @* in = crc[9:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs)