diff --git a/CHANGELOG.md b/CHANGELOG.md index c2421e5..0b52f97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * Added support for attributes in unary, binary, and ternary expressions * Added support for shadowing interface names with local typenames +* Added support for streaming concatenations within ternary expressions * Added support for passing through `wait` statements ### Bug Fixes diff --git a/src/Convert/Stream.hs b/src/Convert/Stream.hs index d278bf5..174eaf2 100644 --- a/src/Convert/Stream.hs +++ b/src/Convert/Stream.hs @@ -47,7 +47,7 @@ traverseModuleItemM :: ModuleItem -> Scoper () ModuleItem traverseModuleItemM (Assign opt lhs (Stream StreamL chunk exprs)) = injectItem (MIPackageItem func) >> return (Assign opt lhs expr') where - fnName = streamerFuncName $ shortHash lhs + fnName = streamerFuncName $ shortHash (lhs, chunk, exprs) t = TypeOf $ lhsToExpr lhs arg = Concat exprs func = streamerFunc fnName chunk (TypeOf arg) t @@ -56,12 +56,25 @@ traverseModuleItemM (Assign opt (LHSStream StreamL chunk lhss) expr) = traverseModuleItemM $ Assign opt (LHSConcat lhss) (Stream StreamL chunk [expr]) +traverseModuleItemM (Assign opt lhs (Mux cond expr@Stream{} other)) = do + (lhs', expr') <- indirectAssign lhs expr + return $ Assign opt lhs' $ Mux cond expr' other +traverseModuleItemM (Assign opt lhs (Mux cond other expr@Stream{})) = do + (lhs', expr') <- indirectAssign lhs expr + return $ Assign opt lhs' $ Mux cond other expr' traverseModuleItemM (Assign opt lhs expr) = traverseExprM expr' >>= return . Assign opt lhs' where Asgn AsgnOpEq Nothing lhs' expr' = traverseAsgn (lhs, expr) (Asgn AsgnOpEq Nothing) traverseModuleItemM item = return item +indirectAssign :: LHS -> Expr -> Scoper () (LHS, Expr) +indirectAssign lhs expr = do + let item = Assign AssignOptionNone lhs expr + item' <- traverseModuleItemM item + let Assign AssignOptionNone lhs' expr' = item' + return (lhs', expr') + traverseStmtM :: Stmt -> Scoper () Stmt traverseStmtM (Subroutine fn (Args args [])) = do args' <- traverseCall fn args @@ -190,6 +203,12 @@ traverseAsgn (LHSStream StreamL chunk lhss, expr) constructor = lhs = LHSConcat lhss lhsSize = sizeof $ lhsToExpr lhs exprSize = sizeof expr +traverseAsgn (lhs, Mux cond e1@Stream{} e2) constructor = + traverseAsgn (lhs, e1) constructor' + where constructor' lhs' e1' = constructor lhs' $ Mux cond e1' e2 +traverseAsgn (lhs, Mux cond e1 e2@Stream{}) constructor = + traverseAsgn (lhs, e2) constructor' + where constructor' lhs' e2' = constructor lhs' $ Mux cond e1 e2' traverseAsgn (lhs, expr) constructor = constructor lhs expr diff --git a/test/core/stream.sv b/test/core/stream.sv index 8a96942..13c1847 100644 --- a/test/core/stream.sv +++ b/test/core/stream.sv @@ -124,4 +124,15 @@ module top; #1 in = 24'h12E3B8; end + logic [31:0] mux1, mux2, mux3, mux4, mux5, mux6; + initial $monitor("%b %b %b %b %b %b", mux1, mux2, mux3, mux4, mux5, mux6); + assign mux1 = i ? {<<1 {in}} : 32'b0; + assign mux2 = i ? {>>1 {in}} : {<<1 {in}}; + assign mux3 = i ? {<<1 {in}} : {<<1 {m}}; + always @* begin + mux4 = i ? {<<1 {in}} : 32'b0; + mux5 = i ? {>>1 {in}} : {<<1 {in}}; + mux6 = i ? {<<1 {in}} : {<<1 {m}}; + end + endmodule diff --git a/test/core/stream.v b/test/core/stream.v index 078b252..868e6ac 100644 --- a/test/core/stream.v +++ b/test/core/stream.v @@ -141,4 +141,23 @@ module top; #1 in = 24'h12E3B8; end + function automatic [31:0] reverse; + input [31:0] inp; + integer i; + for (i = 0; i < 32; i = i + 1) + reverse[i] = inp[31 - i]; + endfunction + + wire [31:0] mux1, mux2, mux3; + reg [31:0] mux4, mux5, mux6; + initial $monitor("%b %b %b %b %b %b", mux1, mux2, mux3, mux4, mux5, mux6); + assign mux1 = i ? reverse(in) : 32'b0; + assign mux2 = i ? in << 8 : reverse(in); + assign mux3 = i ? reverse(in) : reverse(m); + always @* begin + mux4 = i ? reverse(in) : 32'b0; + mux5 = i ? in << 8 : reverse(in); + mux6 = i ? reverse(in) : reverse(m); + end + endmodule