mirror of https://github.com/zachjs/sv2v.git
allow type parameters to depend on other parameters
This commit is contained in:
parent
219a57c37b
commit
671101a30b
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
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
|
||||
Loading…
Reference in New Issue