Commit 671101a3 by Zachary Snow

allow type parameters to depend on other parameters

parent 219a57c3
......@@ -143,15 +143,19 @@ convert files =
-- substitute in a particular instance's parameter types
rewriteModule :: Description -> Instance -> Description
rewriteModule part typeMap =
Part attrs extern kw ml m' p items'
Part attrs extern kw ml m' p (additionalParamItems ++ items')
where
Part attrs extern kw ml m p items = part
m' = moduleInstanceName m typeMap
items' = map rewriteDecl items
rewriteDecl :: ModuleItem -> ModuleItem
rewriteDecl (MIPackageItem (Decl (ParamType Parameter x _))) =
MIPackageItem $ Typedef (typeMap Map.! x) x
MIPackageItem $ Typedef (typeMap' Map.! x) x
rewriteDecl other = other
explodedTypeMap = Map.mapWithKey prepareTypeIdents typeMap
typeMap' = Map.map fst explodedTypeMap
additionalParamItems = concatMap makeAddedParams $
Map.toList $ Map.map snd explodedTypeMap
-- TODO FIXME: Typedef conversion must be made to handle
-- ParamTypes!
-----items' = map (traverseDecls rewriteDecl) items
......@@ -160,6 +164,22 @@ convert files =
----- ParamType Localparam x (Just $ typeMap Map.! x)
-----rewriteDecl other = other
makeAddedParams :: (Identifier, IdentSet) -> [ModuleItem]
makeAddedParams (paramName, identSet) =
map (MIPackageItem . Decl) $
map toTypeParam idents ++ map toParam idents
where
idents = Set.toList identSet
toParam :: Identifier -> Decl
toParam ident =
Param Parameter typ name (Number "0")
where
typ = Alias (addedParamTypeName paramName ident) []
name = addedParamName paramName ident
toTypeParam :: Identifier -> Decl
toTypeParam ident = ParamType Parameter name Nothing
where name = addedParamTypeName paramName ident
-- write down module parameter names and type parameters
collectDescriptionM :: Description -> Writer Info ()
collectDescriptionM (part @ (Part _ _ _ _ name _ _)) =
......@@ -236,10 +256,29 @@ typeHasQueries =
(collectNestedExprsM collectUnresolvedExprM)
where
collectUnresolvedExprM :: Expr -> Writer [Expr] ()
collectUnresolvedExprM Ident{} = return ()
collectUnresolvedExprM (expr @ PSIdent{}) = tell [expr]
collectUnresolvedExprM (expr @ CSIdent{}) = tell [expr]
collectUnresolvedExprM (expr @ DimsFn{}) = tell [expr]
collectUnresolvedExprM (expr @ DimFn {}) = tell [expr]
collectUnresolvedExprM _ = return ()
prepareTypeIdents :: Identifier -> Type -> (Type, IdentSet)
prepareTypeIdents prefix typ =
runWriter $ traverseTypeExprsM (traverseNestedExprsM prepareExprIdents) typ
where
prepareExprIdents :: Expr -> Writer IdentSet Expr
prepareExprIdents (Ident x) = do
tell $ Set.singleton x
return $ Ident $ prefix ++ '_' : x
prepareExprIdents other = return other
addedParamName :: Identifier -> Identifier -> Identifier
addedParamName paramName var = paramName ++ '_' : var
addedParamTypeName :: Identifier -> Identifier -> Identifier
addedParamTypeName paramName var = paramName ++ '_' : var ++ "_type"
-- attempt to rewrite instantiations with type parameters
convertModuleItemM :: Info -> ModuleItem -> Writer Instances ModuleItem
convertModuleItemM info (orig @ (Instance m bindings x r p)) =
......@@ -259,7 +298,7 @@ convertModuleItemM info (orig @ (Instance m bindings x r p)) =
else do
tell $ Set.singleton (m, resolvedTypes)
let m' = moduleInstanceName m resolvedTypes
return $ Instance m' bindings' x r p
return $ Instance m' (additionalBindings ++ bindings') x r p
where
(paramNames, maybeTypeMap) = info Map.! m
-- attach names to unnamed parameters
......@@ -294,4 +333,21 @@ convertModuleItemM info (orig @ (Instance m bindings x r p)) =
-- leave only the normal expression params behind
isParamType = flip Map.member maybeTypeMap
bindings' = filter (not . isParamType . fst) bindingsNamed
-- create additional parameters needed to specify existing type params
explodedTypes = Map.mapWithKey prepareTypeIdents resolvedTypes
additionalBindings = concatMap makeAddedParams $
Map.toList $ Map.map snd explodedTypes
makeAddedParams :: (Identifier, IdentSet) -> [ParamBinding]
makeAddedParams (paramName, identSet) =
map toTypeParam idents ++ map toParam idents
where
idents = Set.toList identSet
toParam :: Identifier -> ParamBinding
toParam ident =
(addedParamName paramName ident, Right $ Ident ident)
toTypeParam :: Identifier -> ParamBinding
toTypeParam ident =
(addedParamTypeName paramName ident, Left $ TypeOf $ Ident ident)
convertModuleItemM _ other = return other
package PKG;
typedef struct packed {
int W;
} F_t;
localparam F_t F_v = '{
W: 64
};
endpackage
module M0 #(
parameter type T,
parameter ID = "NONE"
);
T v;
initial $display("%s %0d %0d", ID, $bits(T), $bits(v));
endmodule
module M1 #(parameter PKG::F_t F = PKG::F_v) ();
typedef struct packed {
logic [F.W-1:0] field;
} local_t;
local_t v;
M0 #(.ID("A"), .T(local_t)) a();
M0 #(.ID("B"), .T(PKG::F_t)) b();
endmodule
module top;
typedef struct packed {
byte W;
} F_t;
localparam F_t F = '{
W: 16
};
typedef struct packed {
logic [F.W-1:0] field;
} local_t;
local_t v;
M1 m1();
M0 #(.ID("C"), .T(local_t)) c();
M0 #(.ID("D"), .T(PKG::F_t)) d();
M0 #(.ID("E"), .T(F_t)) e();
endmodule
module top;
localparam FORMAT = "%s %0d %0d";
initial begin
$display(FORMAT, "A", 64, 64);
$display(FORMAT, "B", 32, 32);
$display(FORMAT, "C", 16, 16);
$display(FORMAT, "D", 32, 32);
$display(FORMAT, "E", 8, 8);
end
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