diff --git a/src/Convert/Struct.hs b/src/Convert/Struct.hs index ef30e32..db479f3 100644 --- a/src/Convert/Struct.hs +++ b/src/Convert/Struct.hs @@ -34,10 +34,11 @@ convertDescription (description @ (Part _ _ _ _ _ _)) = where description' @ (Part extern kw lifetime name ports items) = scopedConversion traverseDeclM traverseModuleItemM traverseStmtM - Map.empty description + tfArgTypes description -- collect information about this description structs = execWriter $ collectModuleItemsM (collectTypesM collectStructM) description + tfArgTypes = execWriter $ collectModuleItemsM collectTFArgsM description -- determine which of the packer functions we actually need calledFuncs = execWriter $ collectModuleItemsM (collectExprsM $ collectNestedExprsM collectCallsM) description' @@ -51,6 +52,9 @@ convertDescription (description @ (Part _ _ _ _ _ _)) = traverseExprsM traverseExprM item >>= traverseAsgnsM traverseAsgnM traverseStmtM :: Stmt -> State Types Stmt + traverseStmtM (Subroutine f args) = do + stateTypes <- get + return $ uncurry Subroutine $ convertCall structs stateTypes f args traverseStmtM stmt = traverseStmtExprsM traverseExprM stmt >>= traverseStmtAsgnsM traverseAsgnM @@ -133,6 +137,24 @@ collectCallsM :: Expr -> Writer Idents () collectCallsM (Call f _) = tell $ Set.singleton f 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 traverseDeclM :: Decl -> State Types Decl traverseDeclM origDecl = do @@ -356,6 +378,12 @@ convertAsgn structs types (lhs, expr) = (_, []) -> Implicit Unspecified [] (tf, rs) -> tf $ tail rs (_, 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 -- recurse into. That said, it's not clear to me how much we really -- expect to see things like concatenated packed structs, for example. @@ -371,3 +399,20 @@ convertAsgn structs types (lhs, expr) = lookupFieldType :: [(Type, Identifier)] -> Identifier -> Type lookupFieldType fields fieldName = fieldMap Map.! fieldName 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) + diff --git a/test/basic/struct_shadow.sv b/test/basic/struct_shadow.sv index 8bd8419..d5e88c5 100644 --- a/test/basic/struct_shadow.sv +++ b/test/basic/struct_shadow.sv @@ -100,4 +100,61 @@ module top; endtask 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 diff --git a/test/basic/struct_shadow.v b/test/basic/struct_shadow.v index 1d070e0..d5094ea 100644 --- a/test/basic/struct_shadow.v +++ b/test/basic/struct_shadow.v @@ -44,5 +44,21 @@ module top; $display("D: 101 -> 635563"); $display("D: 110 -> 353656"); $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 endmodule