From 2535d689aa4ce6a4dccb5fc24f16d64f91bcb8df Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sat, 20 Jun 2020 22:39:13 -0400 Subject: [PATCH] fix struct/interface/logic conversion interactions - interface conversion only waits for type resolution of modports - typeof conversion resolves struct field accesses - logic conversion only converts logic data declarations - struct conversion only converts within modules - fix nested type traversal order causing premature struct conversion --- src/Convert/Interface.hs | 8 +++++++- src/Convert/Logic.hs | 11 ++++++++++- src/Convert/Struct.hs | 2 +- src/Convert/Traverse.hs | 2 +- src/Convert/TypeOf.hs | 9 +++++++++ test/basic/interface_struct.sv | 30 ++++++++++++++++++++++++++++++ test/basic/interface_struct.v | 12 ++++++++++++ 7 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 test/basic/interface_struct.sv create mode 100644 test/basic/interface_struct.v diff --git a/src/Convert/Interface.hs b/src/Convert/Interface.hs index ad41aab..5fb9ad0 100644 --- a/src/Convert/Interface.hs +++ b/src/Convert/Interface.hs @@ -62,8 +62,14 @@ convert = fullyResolved :: ModuleItem -> Bool fullyResolved = not . any isTypeOf . execWriter . - collectNestedModuleItemsM (collectTypesM collectType) + collectNestedModuleItemsM collectModport where + collectModport :: ModuleItem -> Writer [Type] () + collectModport (Modport _ modportDecls) = + mapM collectModportDecl modportDecls >> return () + collectModport _ = return () + collectModportDecl :: ModportDecl -> Writer [Type] () + collectModportDecl (_, _, t, _) = collectType t collectType :: Type -> Writer [Type] () collectType t = tell [t] isTypeOf TypeOf{} = True diff --git a/src/Convert/Logic.hs b/src/Convert/Logic.hs index 26a2743..420b40f 100644 --- a/src/Convert/Logic.hs +++ b/src/Convert/Logic.hs @@ -74,7 +74,16 @@ convertDescription ports orig = PackageItem _ -> True Package _ _ _ -> False - origIdents = execWriter (collectModuleItemsM regIdents orig) + logics = execWriter (collectModuleItemsM collectLogicM orig) + collectLogicM :: ModuleItem -> Writer Idents () + collectLogicM (MIPackageItem (Decl (Variable _ t x _ _))) = + case t of + IntegerVector TLogic _ _ -> tell $ Set.singleton x + _ -> return () + collectLogicM _ = return () + + origIdents = Set.intersection logics $ + execWriter (collectModuleItemsM regIdents orig) fixed = traverseModuleItems fixModuleItem orig fixedIdents = execWriter (collectModuleItemsM regIdents fixed) conversion = traverseDecls convertDecl . convertModuleItem diff --git a/src/Convert/Struct.hs b/src/Convert/Struct.hs index 4b3e694..b3e0a1e 100644 --- a/src/Convert/Struct.hs +++ b/src/Convert/Struct.hs @@ -26,7 +26,7 @@ convert :: [AST] -> [AST] convert = map $ traverseDescriptions convertDescription convertDescription :: Description -> Description -convertDescription (description @ Part{}) = +convertDescription (description @ (Part _ _ Module _ _ _ _)) = traverseModuleItems (traverseTypes' ExcludeParamTypes $ convertType structs) $ Part attrs extern kw lifetime name ports (items ++ funcs) where diff --git a/src/Convert/Traverse.hs b/src/Convert/Traverse.hs index 9b51b7a..eebbc6e 100644 --- a/src/Convert/Traverse.hs +++ b/src/Convert/Traverse.hs @@ -837,7 +837,7 @@ collectDeclsM = collectDeclsM' IncludeTFs traverseNestedTypesM :: Monad m => MapperM m Type -> MapperM m Type traverseNestedTypesM mapper = fullMapper where - fullMapper t = tm t >>= mapper + fullMapper = mapper >=> tm tm (Alias ps xx rs) = return $ Alias ps xx rs tm (Net kw sg rs) = return $ Net kw sg rs tm (Implicit sg rs) = return $ Implicit sg rs diff --git a/src/Convert/TypeOf.hs b/src/Convert/TypeOf.hs index 5c00724..f2b6a6d 100644 --- a/src/Convert/TypeOf.hs +++ b/src/Convert/TypeOf.hs @@ -15,6 +15,7 @@ import Control.Monad.State import Data.List (elemIndex) import Data.Maybe (fromMaybe, mapMaybe) import Data.Int (Int32) +import Data.Tuple (swap) import qualified Data.Map.Strict as Map import Convert.Traverse @@ -100,6 +101,14 @@ typeof (orig @ (Range e mode r)) = do NonIndexed -> snd r IndexedPlus -> BinOp Sub (uncurry (BinOp Add) r) (Number "1") IndexedMinus -> BinOp Add (uncurry (BinOp Sub) r) (Number "1") +typeof (orig @ (Dot e x)) = do + t <- typeof e + return $ case t of + Struct _ fields [] -> + case lookup x $ map swap fields of + Just typ -> typ + Nothing -> TypeOf orig + _ -> TypeOf orig typeof (orig @ (Cast (Right (Ident x)) _)) = do typeMap <- get if Map.member x typeMap diff --git a/test/basic/interface_struct.sv b/test/basic/interface_struct.sv new file mode 100644 index 0000000..50723c2 --- /dev/null +++ b/test/basic/interface_struct.sv @@ -0,0 +1,30 @@ +typedef struct packed { + logic c, d; +} T; +typedef struct packed { + logic a, b; + T y; +} S; + +interface I; + S x; + type(x.y) w; + modport D(input x); +endinterface + +module M(m); + I.D m; + initial begin + $display("%b", m.x.a); + $display("%b", m.x.b); + $display("%b", m.x.y.c); + $display("%b", m.x.y.d); + end +endmodule + +module top; + I i(); + M m(i); + assign i.x = 4'b1001; + initial i.w = 2'b10; +endmodule diff --git a/test/basic/interface_struct.v b/test/basic/interface_struct.v new file mode 100644 index 0000000..b7854bd --- /dev/null +++ b/test/basic/interface_struct.v @@ -0,0 +1,12 @@ +module top; + wire [3:0] i_x; + reg [1:0] i_w; + assign i_x = 4'b1001; + initial i_w = 2'b10; + initial begin + $display("%b", i_x[3]); + $display("%b", i_x[2]); + $display("%b", i_x[1]); + $display("%b", i_x[0]); + end +endmodule