Commit d41dcb2b by Zachary Snow

struct conversion supports struct literals as task/function args

parent addc5500
...@@ -34,10 +34,11 @@ convertDescription (description @ (Part _ _ _ _ _ _)) = ...@@ -34,10 +34,11 @@ convertDescription (description @ (Part _ _ _ _ _ _)) =
where where
description' @ (Part extern kw lifetime name ports items) = description' @ (Part extern kw lifetime name ports items) =
scopedConversion traverseDeclM traverseModuleItemM traverseStmtM scopedConversion traverseDeclM traverseModuleItemM traverseStmtM
Map.empty description tfArgTypes description
-- collect information about this description -- collect information about this description
structs = execWriter $ collectModuleItemsM structs = execWriter $ collectModuleItemsM
(collectTypesM collectStructM) description (collectTypesM collectStructM) description
tfArgTypes = execWriter $ collectModuleItemsM collectTFArgsM description
-- determine which of the packer functions we actually need -- determine which of the packer functions we actually need
calledFuncs = execWriter $ collectModuleItemsM calledFuncs = execWriter $ collectModuleItemsM
(collectExprsM $ collectNestedExprsM collectCallsM) description' (collectExprsM $ collectNestedExprsM collectCallsM) description'
...@@ -51,6 +52,9 @@ convertDescription (description @ (Part _ _ _ _ _ _)) = ...@@ -51,6 +52,9 @@ convertDescription (description @ (Part _ _ _ _ _ _)) =
traverseExprsM traverseExprM item >>= traverseExprsM traverseExprM item >>=
traverseAsgnsM traverseAsgnM traverseAsgnsM traverseAsgnM
traverseStmtM :: Stmt -> State Types Stmt traverseStmtM :: Stmt -> State Types Stmt
traverseStmtM (Subroutine f args) = do
stateTypes <- get
return $ uncurry Subroutine $ convertCall structs stateTypes f args
traverseStmtM stmt = traverseStmtM stmt =
traverseStmtExprsM traverseExprM stmt >>= traverseStmtExprsM traverseExprM stmt >>=
traverseStmtAsgnsM traverseAsgnM traverseStmtAsgnsM traverseAsgnM
...@@ -133,6 +137,24 @@ collectCallsM :: Expr -> Writer Idents () ...@@ -133,6 +137,24 @@ collectCallsM :: Expr -> Writer Idents ()
collectCallsM (Call f _) = tell $ Set.singleton f collectCallsM (Call f _) = tell $ Set.singleton f
collectCallsM _ = return () collectCallsM _ = return ()
collectTFArgsM :: ModuleItem -> Writer Types ()
collectTFArgsM (MIPackageItem item) = do
_ <- case item of
Function _ t f decls _ -> do
tell $ Map.singleton f t
mapM (collect f) (zip [0..] decls)
Task _ f decls _ ->
mapM (collect f) (zip [0..] decls)
_ -> return []
return ()
where
collect :: Identifier -> (Int, Decl) -> Writer Types ()
collect f (idx, (Variable _ t x _ _)) = do
tell $ Map.singleton (f ++ ":" ++ show idx) t
tell $ Map.singleton (f ++ ":" ++ x) t
collect _ _ = return ()
collectTFArgsM _ = return ()
-- write down the types of declarations -- write down the types of declarations
traverseDeclM :: Decl -> State Types Decl traverseDeclM :: Decl -> State Types Decl
traverseDeclM origDecl = do traverseDeclM origDecl = do
...@@ -356,6 +378,12 @@ convertAsgn structs types (lhs, expr) = ...@@ -356,6 +378,12 @@ convertAsgn structs types (lhs, expr) =
(_, []) -> Implicit Unspecified [] (_, []) -> Implicit Unspecified []
(tf, rs) -> tf $ tail rs (tf, rs) -> tf $ tail rs
(_, i') = convertSubExpr i (_, i') = convertSubExpr i
convertSubExpr (Call f args) =
(retType, uncurry Call $ convertCall structs types f args)
where
retType = case Map.lookup f types of
Nothing -> Implicit Unspecified []
Just t -> t
-- TODO: There are other expression cases that we probably need to -- TODO: There are other expression cases that we probably need to
-- recurse into. That said, it's not clear to me how much we really -- recurse into. That said, it's not clear to me how much we really
-- expect to see things like concatenated packed structs, for example. -- expect to see things like concatenated packed structs, for example.
...@@ -371,3 +399,20 @@ convertAsgn structs types (lhs, expr) = ...@@ -371,3 +399,20 @@ convertAsgn structs types (lhs, expr) =
lookupFieldType :: [(Type, Identifier)] -> Identifier -> Type lookupFieldType :: [(Type, Identifier)] -> Identifier -> Type
lookupFieldType fields fieldName = fieldMap Map.! fieldName lookupFieldType fields fieldName = fieldMap Map.! fieldName
where fieldMap = Map.fromList $ map swap fields where fieldMap = Map.fromList $ map swap fields
-- attempts to convert based on the assignment-like contexts of TF arguments
convertCall :: Structs -> Types -> Identifier -> Args -> (Identifier, Args)
convertCall structs types f (Args pnArgs kwArgs) =
(f, args)
where
idxs = map show ([0..] :: [Int])
args = Args
(map snd $ map convertArg $ zip idxs pnArgs)
(map convertArg kwArgs)
convertArg :: (Identifier, Maybe Expr) -> (Identifier, Maybe Expr)
convertArg (x, Nothing) = (x, Nothing)
convertArg (x, Just e ) = (x, Just e')
where
(_, e') = convertAsgn structs types
(LHSIdent $ f ++ ":" ++ x, e)
...@@ -100,4 +100,61 @@ module top; ...@@ -100,4 +100,61 @@ module top;
endtask endtask
initial foo(); initial foo();
task bar;
input integer i, j, k;
input StructE a;
input StructF b;
input StructA c;
input StructB d;
input StructC e;
input StructD f;
$display("E: %1d%1d%1d -> ", i,j,k, a,b,c,d,e,f);
endtask
initial begin
integer i, j, k;
for (i = 0; i < 2; i++) begin
for (j = 0; j < 2; j++) begin
for (k = 0; k < 2; k++) begin
bar(i,j,k
, '{ w:i, x:j, y:k }
, '{ w:i, x:j, y:k }
, '{ w:i, x:j, y:k }
, '{ w:i, x:j, y:k }
, '{ w:i, x:j, y:k }
, '{ w:i, x:j, y:k }
);
end
end
end
end
function baz;
input integer i, j, k;
input StructF a;
input StructA b;
input StructB c;
input StructC d;
input StructD e;
input StructE f;
$display("F: %1d%1d%1d -> ", i,j,k, a,b,c,d,e,f);
baz = 0;
endfunction
initial begin
integer i, j, k;
integer unused;
for (i = 0; i < 2; i++) begin
for (j = 0; j < 2; j++) begin
for (k = 0; k < 2; k++) begin
unused = baz(i,j,k
, '{ w:i, x:j, y:k }
, '{ w:i, x:j, y:k }
, '{ w:i, x:j, y:k }
, '{ w:i, x:j, y:k }
, '{ w:i, x:j, y:k }
, '{ w:i, x:j, y:k }
);
end
end
end
end
endmodule endmodule
...@@ -44,5 +44,21 @@ module top; ...@@ -44,5 +44,21 @@ module top;
$display("D: 101 -> 635563"); $display("D: 101 -> 635563");
$display("D: 110 -> 353656"); $display("D: 110 -> 353656");
$display("D: 111 -> 777777"); $display("D: 111 -> 777777");
$display("E: 000 -> 000000");
$display("E: 001 -> 241214");
$display("E: 010 -> 422141");
$display("E: 011 -> 663355");
$display("E: 100 -> 114422");
$display("E: 101 -> 355636");
$display("E: 110 -> 536563");
$display("E: 111 -> 777777");
$display("F: 000 -> 000000");
$display("F: 001 -> 412142");
$display("F: 010 -> 221414");
$display("F: 011 -> 633556");
$display("F: 100 -> 144221");
$display("F: 101 -> 556363");
$display("F: 110 -> 365635");
$display("F: 111 -> 777777");
end end
endmodule endmodule
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment