Commit 4cf65dd4 by Zachary Snow

support for struct type parameters

- param type conversion properly supports deferred param type resolution
- fixed struct conversion incomplete Subroutine traversal
- struct conversion excludes param types from conversion
- parameters are defaulted to have integer type
parent 2f8ee303
...@@ -220,6 +220,8 @@ isSimpleType (IntegerVector _ _ _) = True ...@@ -220,6 +220,8 @@ isSimpleType (IntegerVector _ _ _) = True
isSimpleType (IntegerAtom _ _ ) = True isSimpleType (IntegerAtom _ _ ) = True
isSimpleType (NonInteger _ ) = True isSimpleType (NonInteger _ ) = True
isSimpleType (Net _ _ _) = True isSimpleType (Net _ _ _) = True
isSimpleType (Struct _ fields _) = all (isSimpleType . fst) fields
isSimpleType (Union _ fields _) = all (isSimpleType . fst) fields
isSimpleType _ = False isSimpleType _ = False
-- attempt to rewrite instantiations with type parameters -- attempt to rewrite instantiations with type parameters
...@@ -235,7 +237,7 @@ convertModuleItemM info (orig @ (Instance m bindings x r p)) = ...@@ -235,7 +237,7 @@ convertModuleItemM info (orig @ (Instance m bindings x r p)) =
else if any (not . isSimpleType) resolvedTypes then do else if any (not . isSimpleType) resolvedTypes then do
let defaults = Map.map Left resolvedTypes let defaults = Map.map Left resolvedTypes
let bindingsDefaulted = Map.toList $ Map.union bindingsMap defaults let bindingsDefaulted = Map.toList $ Map.union bindingsMap defaults
if isDefaultName m if isDefaultName m || bindingsDefaulted /= Map.toList bindingsMap
then return $ Instance m bindingsNamed x r p then return $ Instance m bindingsNamed x r p
else return $ Instance (moduleDefaultName m) bindingsDefaulted x r p else return $ Instance (moduleDefaultName m) bindingsDefaulted x r p
else do else do
......
...@@ -27,7 +27,7 @@ convert = map $ traverseDescriptions convertDescription ...@@ -27,7 +27,7 @@ convert = map $ traverseDescriptions convertDescription
convertDescription :: Description -> Description convertDescription :: Description -> Description
convertDescription (description @ Part{}) = convertDescription (description @ Part{}) =
traverseModuleItems (traverseTypes $ 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
description' @ (Part attrs extern kw lifetime name ports items) = description' @ (Part attrs extern kw lifetime name ports items) =
...@@ -53,8 +53,11 @@ convertDescription (description @ Part{}) = ...@@ -53,8 +53,11 @@ convertDescription (description @ Part{}) =
traverseStmtM :: Stmt -> State Types Stmt traverseStmtM :: Stmt -> State Types Stmt
traverseStmtM (Subroutine expr args) = do traverseStmtM (Subroutine expr args) = do
stateTypes <- get stateTypes <- get
return $ Subroutine expr $ let stmt' = Subroutine expr $ convertCall
convertCall structs stateTypes expr args structs stateTypes expr args
traverseStmtLHSsM traverseLHSM stmt' >>=
traverseStmtExprsM traverseExprM >>=
traverseStmtAsgnsM traverseAsgnM
traverseStmtM stmt = traverseStmtM stmt =
traverseStmtLHSsM traverseLHSM stmt >>= traverseStmtLHSsM traverseLHSM stmt >>=
traverseStmtExprsM traverseExprM >>= traverseStmtExprsM traverseExprM >>=
......
...@@ -9,6 +9,7 @@ module Convert.Traverse ...@@ -9,6 +9,7 @@ module Convert.Traverse
, Mapper , Mapper
, CollectorM , CollectorM
, TFStrategy (..) , TFStrategy (..)
, TypeStrategy (..)
, unmonad , unmonad
, collectify , collectify
, traverseDescriptionsM , traverseDescriptionsM
...@@ -53,6 +54,9 @@ module Convert.Traverse ...@@ -53,6 +54,9 @@ module Convert.Traverse
, traverseExprTypesM , traverseExprTypesM
, traverseExprTypes , traverseExprTypes
, collectExprTypesM , collectExprTypesM
, traverseTypesM'
, traverseTypes'
, collectTypesM'
, traverseTypesM , traverseTypesM
, traverseTypes , traverseTypes
, collectTypesM , collectTypesM
...@@ -101,6 +105,11 @@ data TFStrategy ...@@ -101,6 +105,11 @@ data TFStrategy
| ExcludeTFs | ExcludeTFs
deriving Eq deriving Eq
data TypeStrategy
= IncludeParamTypes
| ExcludeParamTypes
deriving Eq
unmonad :: (MapperM (State ()) a -> MapperM (State ()) b) -> Mapper a -> Mapper b unmonad :: (MapperM (State ()) a -> MapperM (State ()) b) -> Mapper a -> Mapper b
unmonad traverser mapper thing = unmonad traverser mapper thing =
evalState (traverser (return . mapper) thing) () evalState (traverser (return . mapper) thing) ()
...@@ -910,8 +919,8 @@ traverseExprTypes = unmonad traverseExprTypesM ...@@ -910,8 +919,8 @@ traverseExprTypes = unmonad traverseExprTypesM
collectExprTypesM :: Monad m => CollectorM m Type -> CollectorM m Expr collectExprTypesM :: Monad m => CollectorM m Type -> CollectorM m Expr
collectExprTypesM = collectify traverseExprTypesM collectExprTypesM = collectify traverseExprTypesM
traverseTypesM :: Monad m => MapperM m Type -> MapperM m ModuleItem traverseTypesM' :: Monad m => TypeStrategy -> MapperM m Type -> MapperM m ModuleItem
traverseTypesM mapper item = traverseTypesM' strategy mapper item =
miMapper item >>= miMapper item >>=
traverseDeclsM declMapper >>= traverseDeclsM declMapper >>=
traverseExprsM (traverseNestedExprsM exprMapper) traverseExprsM (traverseNestedExprsM exprMapper)
...@@ -938,14 +947,23 @@ traverseTypesM mapper item = ...@@ -938,14 +947,23 @@ traverseTypesM mapper item =
return $ Instance m params' x r p return $ Instance m params' x r p
where where
mapParam (i, Left t) = mapParam (i, Left t) =
fullMapper t >>= \t' -> return (i, Left t') if strategy == IncludeParamTypes
then fullMapper t >>= \t' -> return (i, Left t')
else return (i, Left t)
mapParam (i, Right e) = return $ (i, Right e) mapParam (i, Right e) = return $ (i, Right e)
miMapper other = return other miMapper other = return other
traverseTypes' :: TypeStrategy -> Mapper Type -> Mapper ModuleItem
traverseTypes' strategy = unmonad $ traverseTypesM' strategy
collectTypesM' :: Monad m => TypeStrategy -> CollectorM m Type -> CollectorM m ModuleItem
collectTypesM' strategy = collectify $ traverseTypesM' strategy
traverseTypesM :: Monad m => MapperM m Type -> MapperM m ModuleItem
traverseTypesM = traverseTypesM' IncludeParamTypes
traverseTypes :: Mapper Type -> Mapper ModuleItem traverseTypes :: Mapper Type -> Mapper ModuleItem
traverseTypes = unmonad traverseTypesM traverseTypes = traverseTypes' IncludeParamTypes
collectTypesM :: Monad m => CollectorM m Type -> CollectorM m ModuleItem collectTypesM :: Monad m => CollectorM m Type -> CollectorM m ModuleItem
collectTypesM = collectify traverseTypesM collectTypesM = collectTypesM' IncludeParamTypes
traverseGenItemsM :: Monad m => MapperM m GenItem -> MapperM m ModuleItem traverseGenItemsM :: Monad m => MapperM m GenItem -> MapperM m ModuleItem
traverseGenItemsM mapper = moduleItemMapper traverseGenItemsM mapper = moduleItemMapper
......
...@@ -51,7 +51,10 @@ traverseDeclM decl = do ...@@ -51,7 +51,10 @@ traverseDeclM decl = do
UnpackedType t'' a' -> Variable d t'' ident a' me UnpackedType t'' a' -> Variable d t'' ident a' me
_ -> Variable d t' ident [] me _ -> Variable d t' ident [] me
Param _ t ident _ -> do Param _ t ident _ -> do
modify $ Map.insert ident t let t' = if t == Implicit Unspecified []
then IntegerAtom TInteger Unspecified
else t
modify $ Map.insert ident t'
return decl' return decl'
ParamType{} -> return decl' ParamType{} -> return decl'
CommentDecl{} -> return decl' CommentDecl{} -> return decl'
......
// TODO Add support for parameters without default values.
module Module #(parameter type T, parameter N = 1);
T t;
type(t.a) x;
type(t.b) y;
initial begin
$display("$bits(T)=", $bits(T));
$display("$bits(t)=", $bits(t));
$display("$bits(t.a)=", $bits(t.a));
$display("$bits(t.b)=", $bits(t.b));
$display("$bits(x)=", $bits(x));
$display("$bits(y)=", $bits(y));
$display("$bits(N)=", $bits(N));
$display("N=", N);
end
endmodule
module top;
typedef struct packed {
logic a;
logic [2] b;
} Struct1;
typedef struct packed {
logic [5] a;
Struct1 b;
logic [2] c;
logic d;
} Struct2;
Module #(Struct1, $bits(Struct1)) m1();
Module #(Struct2, $bits(Struct2)) m2();
endmodule
module Module1 #(parameter N = 1);
initial begin
$display("$bits(T)=", 3);
$display("$bits(t)=", 3);
$display("$bits(t.a)=", 1);
$display("$bits(t.b)=", 2);
$display("$bits(x)=", 1);
$display("$bits(y)=", 2);
$display("$bits(N)=", 32);
$display("N=", N);
end
endmodule
module Module2 #(parameter N = 1);
initial begin
$display("$bits(T)=", 11);
$display("$bits(t)=", 11);
$display("$bits(t.a)=", 5);
$display("$bits(t.b)=", 3);
$display("$bits(x)=", 5);
$display("$bits(y)=", 3);
$display("$bits(N)=", 32);
$display("N=", N);
end
endmodule
module top;
Module1 #(3) m1();
Module2 #(11) m2();
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