From 5ad4849454f538a1d9d620280ad476bdb84bacdd Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sun, 22 Mar 2020 19:33:57 -0400 Subject: [PATCH] fix slicing direction for multi-packed arrays --- src/Convert/MultiplePacked.hs | 32 ++++++++++++++++++++++---------- test/basic/multipack_port.sv | 13 ++++++++----- test/basic/multipack_port.v | 19 +++++++++++-------- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/Convert/MultiplePacked.hs b/src/Convert/MultiplePacked.hs index 5a38a44..1409caf 100644 --- a/src/Convert/MultiplePacked.hs +++ b/src/Convert/MultiplePacked.hs @@ -166,8 +166,9 @@ traverseExpr typeMap = fieldType = fieldMap Map.! x levels _ = Nothing - -- given an expression, returns the two innermost packed dimensions and a - -- tagged version of the expression, if possible + -- given an expression, returns the two most significant (innermost, + -- leftmost) packed dimensions and a tagged version of the expression, + -- if possible dims :: Expr -> Maybe (Range, Range, Expr) dims expr = case levels expr of @@ -266,18 +267,29 @@ traverseExpr typeMap = range' = (base, len) rewriteExpr (orig @ (Range expr mode range)) = if isJust maybeDims && expr == rewriteExpr expr - then Range expr' mode range' + then Range expr' mode' range' else orig where maybeDims = dims expr - Just (_, dimOuter, expr') = maybeDims + Just (dimInner, dimOuter, expr') = maybeDims sizeOuter = rangeSize dimOuter - base = BinOp Add (BinOp Mul sizeOuter (fst range)) start - len = BinOp Mul sizeOuter (snd range) - range' = (base, len) - start = + offsetOuter = uncurry (endianCondExpr dimOuter) $ swap dimOuter + (baseOrig, lenOrig) = range + lenOrigMinusOne = BinOp Sub lenOrig (Number "1") + baseSwapped = + orientIdx dimInner $ case mode of - IndexedPlus -> endianCondExpr dimOuter (snd dimOuter) (fst dimOuter) - IndexedMinus -> endianCondExpr dimOuter (fst dimOuter) (snd dimOuter) + IndexedPlus -> + endianCondExpr dimInner + baseOrig + (BinOp Add baseOrig lenOrigMinusOne) + IndexedMinus -> + endianCondExpr dimInner + (BinOp Sub baseOrig lenOrigMinusOne) + baseOrig NonIndexed -> error "invariant violated" + base = BinOp Add offsetOuter (BinOp Mul sizeOuter baseSwapped) + mode' = IndexedPlus + len = BinOp Mul sizeOuter lenOrig + range' = (base, len) rewriteExpr other = other diff --git a/test/basic/multipack_port.sv b/test/basic/multipack_port.sv index f19f73c..ac43198 100644 --- a/test/basic/multipack_port.sv +++ b/test/basic/multipack_port.sv @@ -1,11 +1,12 @@ module Producer(clock, data); parameter INIT = 0; + parameter CHUNKS = 5; input logic clock; - output logic [10:0] data [5]; - initial data[0][0] = INIT; + output logic [10:0] data [CHUNKS]; + initial data[0] = INIT; always @(clock) begin integer i, j; - for (i = 4; i >= 0; i--) begin + for (i = CHUNKS - 1; i >= 0; i--) begin for (j = 9; j >= 0; j--) begin data[i][j + 1] = data[i][j]; end @@ -28,8 +29,10 @@ module top; Producer #(.INIT(0)) p1(clock, foo); logic [10:0] bar [10]; - Producer #(.INIT(0)) p2(clock, bar[0:4]); - Producer #(.INIT(1)) p3(clock, bar[5:9]); + Producer #(.INIT(0), .CHUNKS(3)) p2(clock, bar[0:2]); + Producer #(.INIT(1), .CHUNKS(1)) p3(clock, bar[3:3]); + Producer #(.INIT(2), .CHUNKS(1)) p4(clock, bar[4+:1]); + Producer #(.INIT(3)) p5(clock, bar[5:9]); initial $monitor("%d %b%b%b%b%b %b%b%b%b%b%b%b%b%b%b", $time, diff --git a/test/basic/multipack_port.v b/test/basic/multipack_port.v index a8f6296..ce4bef8 100644 --- a/test/basic/multipack_port.v +++ b/test/basic/multipack_port.v @@ -1,18 +1,19 @@ module Producer(clock, data); parameter INIT = 0; + parameter CHUNKS = 5; input clock; - output reg [54:0] data; - initial data[11*4] = INIT; + output reg [11*CHUNKS - 1:0] data; + initial data[11*(CHUNKS - 1)+:11] = INIT; always @(clock) begin : block_name integer i, j; - for (i = 4; i >= 0; i--) begin + for (i = (CHUNKS-1); i >= 0; i--) begin for (j = 9; j >= 0; j--) begin - data[11*(4-i) + j + 1] = data[11*(4-i) + j]; + data[11*((CHUNKS-1)-i) + j + 1] = data[11*((CHUNKS-1)-i) + j]; end if (i != 0) - data[11*(4-i) + 0] = data[11*(4-(i-1)) + 10]; + data[11*((CHUNKS-1)-i) + 0] = data[11*((CHUNKS-1)-(i-1)) + 10]; end - data[11*4] = ~data[11*4]; + data[11*(CHUNKS-1)] = ~data[11*(CHUNKS-1)]; end endmodule @@ -28,8 +29,10 @@ module top; Producer #(.INIT(0)) p1(clock, foo); wire [109:0] bar; - Producer #(.INIT(0)) p2(clock, bar[54:0]); - Producer #(.INIT(1)) p3(clock, bar[109:55]); + Producer #(.INIT(0), .CHUNKS(3)) p2(clock, bar[109-:33]); + Producer #(.INIT(1), .CHUNKS(1)) p3(clock, bar[76-:11]); + Producer #(.INIT(2), .CHUNKS(1)) p4(clock, bar[55+:11]); + Producer #(.INIT(3)) p5(clock, bar[54-:55]); initial $monitor("%d %b %b", $time, foo, bar);