From abcb95b8a11c7ff7de42aef0c4a3a6d5e24e2896 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 26 Jan 2010 08:06:39 -0500 Subject: [PATCH] Fix order of packed arrays, bug216 --- src/verilog.y | 17 +++++++----- test_regress/t/t_mem_packed.v | 49 ++++++++++++++++++++++++++++++++--- 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/verilog.y b/src/verilog.y index 90bae4f9d..8458b682b 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -114,19 +114,24 @@ public: return pkgp; } AstNodeDType* addRange(AstBasicDType* dtypep, AstRange* rangesp) { - // If dtypep isn't basic, then call createArray() instead + // If dtypep isn't basic, don't use this, call createArray() instead if (!rangesp) { return dtypep; } else { - // Only the first range becomes the basicdtype range; everything else is arraying + // If rangesp is "wire [3:3][2:2][1:1] foo [5:5][4:4]" + // then [1:1] becomes the basicdtype range; everything else is arraying + // the final [5:5][4:4] will be passed in another call to createArray AstRange* rangearraysp = NULL; if (dtypep->rangep()) { rangearraysp = rangesp; // Already a range; everything is an array } else { - if (rangesp->nextp()) { - rangearraysp = rangesp->nextp()->unlinkFrBackWithNext()->castRange(); + AstRange* finalp = rangesp; + while (finalp->nextp()) finalp=finalp->nextp()->castRange(); + if (finalp != rangesp) { + finalp->unlinkFrBack(); + rangearraysp = rangesp; } - dtypep->rangep(rangesp); + dtypep->rangep(finalp); dtypep->implicit(false); } return createArray(dtypep, rangearraysp); @@ -1549,8 +1554,6 @@ rangeList: // IEEE: {packed_dimension} wirerangeE: /* empty */ { $$ = new AstBasicDType(CRELINE(), LOGIC); } // not implicit | rangeList { $$ = GRAMMARP->addRange(new AstBasicDType(CRELINE(), LOGIC),$1); } // not implicit - // // Verilator doesn't support 2D wiring yet - //UNSUP rangeListE { $$ = $1; } ; // IEEE: select diff --git a/test_regress/t/t_mem_packed.v b/test_regress/t/t_mem_packed.v index 75ad5f031..52109b081 100644 --- a/test_regress/t/t_mem_packed.v +++ b/test_regress/t/t_mem_packed.v @@ -10,6 +10,12 @@ module t (/*AUTOARG*/ input clk; + //Simple debug: + //wire [1:1] wir_a [3:3] [2:2]; //11 + //logic [1:1] log_a [3:3] [2:2]; //12 + //wire [3:3] [2:2] [1:1] wir_p; //13 + //logic [3:3] [2:2] [1:1] log_p; //14 + integer cyc; initial cyc = 0; `ifdef iverilog reg [7:0] arr [3:0]; @@ -24,7 +30,7 @@ module t (/*AUTOARG*/ initial begin for (i0=0; i0<5; i0=i0+1) begin - arr[i0] = 1 << i0[1:0]; + arr[i0] = 1 << (i0[1:0]*2); end end @@ -38,16 +44,51 @@ module t (/*AUTOARG*/ sum_w <= 0; end else if (cyc >= 10 && cyc < 14) begin - sum <= sum + {4'b0,arr[cyc-10]}; - sum_w <= sum_w + {4'b0,arr_w[cyc-10]}; + sum <= sum + arr[cyc-10]; + + sum_w <= sum_w + arr_w[cyc-10]; end else if (cyc==99) begin $write("[%0t] cyc==%0d sum=%x\n",$time, cyc, sum); - if (sum != 8'h0f) $stop; + if (sum != 8'h55) $stop; if (sum != sum_w) $stop; $write("*-* All Finished *-*\n"); $finish; end end + // Test ordering of packed dimensions + logic [31:0] data_out; + logic [31:0] data_out2; + logic [0:0] [2:0] [31:0] data_in; + logic [31:0] data_in2 [0:0] [2:0]; + assign data_out = data_in[0][0] + data_in[0][1] + data_in[0][2]; + assign data_out2 = data_in2[0][0] + data_in2[0][1] + data_in2[0][2]; + + logic [31:0] last_data_out; + always @ (posedge clk) begin + if (cyc <= 2) begin + data_in[0][0] <= 0; + data_in[0][1] <= 0; + data_in[0][2] <= 0; + data_in2[0][0] <= 0; + data_in2[0][1] <= 0; + data_in2[0][2] <= 0; + end + else if (cyc > 2 && cyc < 99) begin + data_in[0][0] <= data_in[0][0] + 1; + data_in[0][1] <= data_in[0][1] + 1; + data_in[0][2] <= data_in[0][2] + 1; + data_in2[0][0] <= data_in2[0][0] + 1; + data_in2[0][1] <= data_in2[0][1] + 1; + data_in2[0][2] <= data_in2[0][2] + 1; + last_data_out <= data_out; +`ifdef TEST_VERBOSE + $write("data_out %0x %0x\n", data_out, last_data_out); +`endif + if (cyc > 4 && data_out != last_data_out + 3) $stop; + if (cyc > 4 && data_out != data_out2) $stop; + end + end + endmodule