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
This commit is contained in:
Zachary Snow 2020-06-20 22:39:13 -04:00
parent bd1c07231f
commit 2535d689aa
7 changed files with 70 additions and 4 deletions

View File

@ -62,8 +62,14 @@ convert =
fullyResolved :: ModuleItem -> Bool fullyResolved :: ModuleItem -> Bool
fullyResolved = fullyResolved =
not . any isTypeOf . execWriter . not . any isTypeOf . execWriter .
collectNestedModuleItemsM (collectTypesM collectType) collectNestedModuleItemsM collectModport
where 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 :: Type -> Writer [Type] ()
collectType t = tell [t] collectType t = tell [t]
isTypeOf TypeOf{} = True isTypeOf TypeOf{} = True

View File

@ -74,7 +74,16 @@ convertDescription ports orig =
PackageItem _ -> True PackageItem _ -> True
Package _ _ _ -> False 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 fixed = traverseModuleItems fixModuleItem orig
fixedIdents = execWriter (collectModuleItemsM regIdents fixed) fixedIdents = execWriter (collectModuleItemsM regIdents fixed)
conversion = traverseDecls convertDecl . convertModuleItem conversion = traverseDecls convertDecl . convertModuleItem

View File

@ -26,7 +26,7 @@ convert :: [AST] -> [AST]
convert = map $ traverseDescriptions convertDescription convert = map $ traverseDescriptions convertDescription
convertDescription :: Description -> Description convertDescription :: Description -> Description
convertDescription (description @ Part{}) = convertDescription (description @ (Part _ _ Module _ _ _ _)) =
traverseModuleItems (traverseTypes' ExcludeParamTypes $ convertType structs) $ traverseModuleItems (traverseTypes' ExcludeParamTypes $ convertType structs) $
Part attrs extern kw lifetime name ports (items ++ funcs) Part attrs extern kw lifetime name ports (items ++ funcs)
where where

View File

@ -837,7 +837,7 @@ collectDeclsM = collectDeclsM' IncludeTFs
traverseNestedTypesM :: Monad m => MapperM m Type -> MapperM m Type traverseNestedTypesM :: Monad m => MapperM m Type -> MapperM m Type
traverseNestedTypesM mapper = fullMapper traverseNestedTypesM mapper = fullMapper
where where
fullMapper t = tm t >>= mapper fullMapper = mapper >=> tm
tm (Alias ps xx rs) = return $ Alias ps xx rs tm (Alias ps xx rs) = return $ Alias ps xx rs
tm (Net kw sg rs) = return $ Net kw sg rs tm (Net kw sg rs) = return $ Net kw sg rs
tm (Implicit sg rs) = return $ Implicit sg rs tm (Implicit sg rs) = return $ Implicit sg rs

View File

@ -15,6 +15,7 @@ import Control.Monad.State
import Data.List (elemIndex) import Data.List (elemIndex)
import Data.Maybe (fromMaybe, mapMaybe) import Data.Maybe (fromMaybe, mapMaybe)
import Data.Int (Int32) import Data.Int (Int32)
import Data.Tuple (swap)
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import Convert.Traverse import Convert.Traverse
@ -100,6 +101,14 @@ typeof (orig @ (Range e mode r)) = do
NonIndexed -> snd r NonIndexed -> snd r
IndexedPlus -> BinOp Sub (uncurry (BinOp Add) r) (Number "1") IndexedPlus -> BinOp Sub (uncurry (BinOp Add) r) (Number "1")
IndexedMinus -> BinOp Add (uncurry (BinOp Sub) 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 typeof (orig @ (Cast (Right (Ident x)) _)) = do
typeMap <- get typeMap <- get
if Map.member x typeMap if Map.member x typeMap

View File

@ -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

View File

@ -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