mirror of https://github.com/zachjs/sv2v.git
support streaming concatenations in task and function arguments
This commit is contained in:
parent
2e06d45ca0
commit
9bc946ce7e
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
module Convert.Stream (convert) where
|
||||
|
||||
import Control.Monad (zipWithM)
|
||||
|
||||
import Convert.Scoper
|
||||
import Convert.Traverse
|
||||
import Language.SystemVerilog.AST
|
||||
|
|
@ -36,6 +38,8 @@ traverseDeclM (Variable d t x [] (expr @ (Stream StreamL chunk exprs))) = do
|
|||
fnName = streamerFuncName x
|
||||
func = streamerFunc fnName chunk (TypeOf $ Concat exprs) t
|
||||
expr' = Call (Ident fnName) (Args [Concat exprs] [])
|
||||
traverseDeclM (Variable d t x a expr) =
|
||||
traverseExprM expr >>= return . Variable d t x a
|
||||
traverseDeclM decl @ Net{} = traverseNetAsVarM traverseDeclM decl
|
||||
traverseDeclM decl = return decl
|
||||
|
||||
|
|
@ -53,15 +57,45 @@ traverseModuleItemM (Assign opt (LHSStream StreamL chunk lhss) expr) =
|
|||
Assign opt (LHSConcat lhss)
|
||||
(Stream StreamL chunk [expr])
|
||||
traverseModuleItemM (Assign opt lhs expr) =
|
||||
return $ 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
|
||||
|
||||
traverseStmtM :: Stmt -> Scoper () Stmt
|
||||
traverseStmtM (Asgn op mt lhs expr) =
|
||||
return $ traverseAsgn (lhs, expr) (Asgn op mt)
|
||||
traverseStmtM other = return other
|
||||
traverseStmtM (Subroutine fn (Args args [])) = do
|
||||
args' <- traverseCall fn args
|
||||
return $ Subroutine fn $ Args args' []
|
||||
traverseStmtM (Asgn op mt lhs expr) = do
|
||||
expr' <- traverseExprM expr
|
||||
return $ traverseAsgn (lhs, expr') (Asgn op mt)
|
||||
traverseStmtM stmt = traverseStmtExprsM traverseExprM stmt
|
||||
|
||||
-- replace streaming concatenations in function arguments
|
||||
traverseExprM :: Expr -> Scoper () Expr
|
||||
traverseExprM (Call fn (Args args [])) = do
|
||||
args' <- traverseCall fn args
|
||||
return $ Call fn $ Args args' []
|
||||
traverseExprM expr = traverseSinglyNestedExprsM traverseExprM expr
|
||||
|
||||
traverseCall :: Expr -> [Expr] -> Scoper () [Expr]
|
||||
traverseCall fn = zipWithM wrapper ([0..] :: [Int])
|
||||
where wrapper = traverseCallArg . TypeOf . Dot fn . show
|
||||
|
||||
-- task and function arguments are "assignment-like contexts"
|
||||
traverseCallArg :: Type -> Expr -> Scoper () Expr
|
||||
traverseCallArg t expr@(Stream op _ _) = do
|
||||
inProcedure <- withinProcedureM
|
||||
if inProcedure && op == StreamL
|
||||
then injectDecl decl >> return (Ident tmp)
|
||||
else do
|
||||
decl' <- traverseDeclM decl
|
||||
let Variable _ _ _ _ expr' = decl'
|
||||
return expr'
|
||||
where
|
||||
tmp = "_arg_tmp_" ++ shortHash (t, expr)
|
||||
decl = Variable Local t tmp [] expr
|
||||
traverseCallArg _ arg = traverseExprM arg
|
||||
|
||||
-- produces a function used to capture an inline streaming concatenation
|
||||
streamerFunc :: Identifier -> Expr -> Type -> Type -> PackageItem
|
||||
|
|
|
|||
|
|
@ -12,6 +12,17 @@ module top;
|
|||
$display("packet data = %b", packet.data);
|
||||
end
|
||||
|
||||
function automatic [23:0] indirect;
|
||||
input [23:0] inp;
|
||||
indirect = inp;
|
||||
endfunction
|
||||
|
||||
task printer;
|
||||
input [23:0] inpA;
|
||||
input [23:0] inpB;
|
||||
$display("printer(%h, %h)", inpA, inpB);
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
logic [23:0] temp;
|
||||
|
||||
|
|
@ -39,6 +50,39 @@ module top;
|
|||
$display("%h", temp);
|
||||
temp = {<<7{16'h0708}};
|
||||
$display("%h", temp);
|
||||
|
||||
temp = indirect({>>7{16'h0708}});
|
||||
$display("%h", temp);
|
||||
temp = indirect({<<7{16'h0708}});
|
||||
$display("%h", temp);
|
||||
|
||||
printer({>>7{16'h0708}}, {<<7{16'h0708}});
|
||||
end
|
||||
|
||||
reg [23:0] init_simple_stream_var = {<<7{16'h0718}};
|
||||
wire [23:0] init_simple_stream_net = {<<7{16'h0728}};
|
||||
reg [23:0] init_indirect_stream_var = indirect({<<7{16'h0738}});
|
||||
wire [23:0] init_indirect_stream_net = indirect({<<7{16'h0748}});
|
||||
|
||||
reg [23:0] asgn_simple_stream_var;
|
||||
wire [23:0] asgn_simple_stream_net;
|
||||
reg [23:0] asgn_indirect_stream_var;
|
||||
wire [23:0] asgn_indirect_stream_net;
|
||||
initial asgn_simple_stream_var = {<<7{16'h0758}};
|
||||
assign asgn_simple_stream_net = {<<7{16'h0768}};
|
||||
initial asgn_indirect_stream_var = indirect({<<7{16'h0778}});
|
||||
assign asgn_indirect_stream_net = indirect({<<7{16'h0788}});
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
$display("%b", init_simple_stream_var);
|
||||
$display("%b", init_simple_stream_net);
|
||||
$display("%b", init_indirect_stream_var);
|
||||
$display("%b", init_indirect_stream_net);
|
||||
$display("%b", asgn_simple_stream_var);
|
||||
$display("%b", asgn_simple_stream_net);
|
||||
$display("%b", asgn_indirect_stream_var);
|
||||
$display("%b", asgn_indirect_stream_net);
|
||||
end
|
||||
|
||||
task test_unpack;
|
||||
|
|
@ -67,4 +111,17 @@ module top;
|
|||
test_unpack(24'h12E3B8);
|
||||
end
|
||||
|
||||
logic [0:0] i;
|
||||
logic [1:0] j;
|
||||
logic [2:0] k;
|
||||
logic [5:0] l;
|
||||
logic [11:0] m;
|
||||
logic [23:0] in;
|
||||
assign {<<7{i, j, k, l, m}} = in;
|
||||
initial begin
|
||||
#1 in = 24'h060708;
|
||||
#1 in = 24'hC02375;
|
||||
#1 in = 24'h12E3B8;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -5,6 +5,12 @@ module top;
|
|||
$display("packet data = %b", {2'b00, 2'b11});
|
||||
end
|
||||
|
||||
task printer;
|
||||
input [23:0] inpA;
|
||||
input [23:0] inpB;
|
||||
$display("printer(%h, %h)", inpA, inpB);
|
||||
endtask
|
||||
|
||||
function automatic [23:0] pack_r_8_24;
|
||||
input [23:0] in;
|
||||
integer i;
|
||||
|
|
@ -43,12 +49,10 @@ module top;
|
|||
function automatic [23:0] pack_l_7_24;
|
||||
input [23:0] in;
|
||||
integer i;
|
||||
integer e;
|
||||
begin
|
||||
for (i = 0; i < 24; i = i + 7) begin
|
||||
for (i = 0; i + 7 < 24; i = i + 7) begin
|
||||
pack_l_7_24[23-i-:7] = in[i+:7];
|
||||
end
|
||||
i = i - 7;
|
||||
pack_l_7_24[0+:24%7] = in[i+:24%7];
|
||||
end
|
||||
endfunction
|
||||
|
|
@ -67,6 +71,33 @@ module top;
|
|||
|
||||
$display("%h", pack_r_7_24(24'h070800));
|
||||
$display("%h", pack_l_7_24(24'h000708));
|
||||
|
||||
$display("%h", pack_r_7_24(24'h070800));
|
||||
$display("%h", pack_l_7_24(24'h000708));
|
||||
|
||||
printer(pack_r_7_24(24'h070800), pack_l_7_24(24'h000708));
|
||||
end
|
||||
|
||||
reg [23:0] init_simple_stream_var = pack_l_7_24(24'h000718);
|
||||
wire [23:0] init_simple_stream_net = pack_l_7_24(24'h000728);
|
||||
reg [23:0] init_indirect_stream_var = pack_l_7_24(24'h000738);
|
||||
wire [23:0] init_indirect_stream_net = pack_l_7_24(24'h000748);
|
||||
|
||||
reg [23:0] asgn_simple_stream_var = pack_l_7_24(24'h000758);
|
||||
wire [23:0] asgn_simple_stream_net = pack_l_7_24(24'h000768);
|
||||
reg [23:0] asgn_indirect_stream_var = pack_l_7_24(24'h000778);
|
||||
wire [23:0] asgn_indirect_stream_net = pack_l_7_24(24'h000788);
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
$display("%b", init_simple_stream_var);
|
||||
$display("%b", init_simple_stream_net);
|
||||
$display("%b", init_indirect_stream_var);
|
||||
$display("%b", init_indirect_stream_net);
|
||||
$display("%b", asgn_simple_stream_var);
|
||||
$display("%b", asgn_simple_stream_net);
|
||||
$display("%b", asgn_indirect_stream_var);
|
||||
$display("%b", asgn_indirect_stream_net);
|
||||
end
|
||||
|
||||
task test_unpack;
|
||||
|
|
@ -97,4 +128,17 @@ module top;
|
|||
test_unpack(24'h12E3B8);
|
||||
end
|
||||
|
||||
wire [0:0] i;
|
||||
wire [1:0] j;
|
||||
wire [2:0] k;
|
||||
wire [5:0] l;
|
||||
wire [11:0] m;
|
||||
reg [23:0] in;
|
||||
assign {i, j, k, l, m} = pack_l_7_24(in);
|
||||
initial begin
|
||||
#1 in = 24'h060708;
|
||||
#1 in = 24'hC02375;
|
||||
#1 in = 24'h12E3B8;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Reference in New Issue