Commit 36fcce89 by Zachary Snow

fix param type default pollution

parent 84986cc1
...@@ -9,7 +9,7 @@ module Convert.ParamType (convert) where ...@@ -9,7 +9,7 @@ module Convert.ParamType (convert) where
import Control.Monad.Writer.Strict import Control.Monad.Writer.Strict
import Data.Either (isLeft) import Data.Either (isLeft)
import Data.Maybe (isJust, isNothing, fromJust) import Data.Maybe (isJust, fromJust)
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import qualified Data.Set as Set import qualified Data.Set as Set
...@@ -44,18 +44,16 @@ convert files = ...@@ -44,18 +44,16 @@ convert files =
else else
(:) part $ (:) part $
filter (not . alreadyExists) $ filter (not . alreadyExists) $
filter isNonDefault $
map (rewriteModule part) theseInstances map (rewriteModule part) theseInstances
where where
theseInstances = map snd $ filter ((== name) . fst) instances theseInstances = map snd $ filter ((== name) . fst) instances
isNonDefault = (name /=) . moduleName
alreadyExists = (flip Map.member info) . moduleName alreadyExists = (flip Map.member info) . moduleName
moduleName :: Description -> Identifier moduleName :: Description -> Identifier
moduleName = \(Part _ _ _ _ x _ _) -> x moduleName = \(Part _ _ _ _ x _ _) -> x
explodeDescription other = [other] explodeDescription other = [other]
-- remove or rewrite source modules that are no longer needed -- remove source modules that are no longer needed
files''' = map (\a -> concatMap (replaceDefault a) a) files'' files''' = map (filter keepDescription) files''
(usageMapRaw, usedTypedModulesRaw) = (usageMapRaw, usedTypedModulesRaw) =
execWriter $ mapM (mapM collectUsageInfoM) files'' execWriter $ mapM (mapM collectUsageInfoM) files''
usageMap = Map.unionsWith Set.union $ map (uncurry Map.singleton) usageMap = Map.unionsWith Set.union $ map (uncurry Map.singleton)
...@@ -80,42 +78,13 @@ convert files = ...@@ -80,42 +78,13 @@ convert files =
then tell (Set.empty, Set.singleton m) then tell (Set.empty, Set.singleton m)
else tell (Set.singleton m, Set.empty) else tell (Set.singleton m, Set.empty)
collectModuleItemM _ = return () collectModuleItemM _ = return ()
replaceDefault :: [Description] -> Description -> [Description] keepDescription :: Description -> Bool
replaceDefault existing (part @ (Part _ _ _ _ name _ _)) = keepDescription (Part _ _ _ _ name _ _) =
if Map.notMember name info then Map.notMember name info ||
[part] Map.null maybeTypeMap ||
else if Map.null maybeTypeMap then (Map.member name usedTypedModules && isUsed name)
[part] where maybeTypeMap = info Map.! name
else if Map.member name usedTypedModules && isUsed name then keepDescription _ = True
[part]
else if all isNothing maybeTypeMap then
[]
else
filter (not . alreadyExists) $
(:) (removeDefaultTypeParams part) $
if isNothing typeMap
then []
else [rewriteModule part $ fromJust typeMap]
where
maybeTypeMap = info Map.! name
typeMap = defaultInstance maybeTypeMap
existingNames = map moduleName existing
alreadyExists = (flip elem existingNames) . moduleName
moduleName :: Description -> Identifier
moduleName (Part _ _ _ _ x _ _) = x
moduleName _ = ""
replaceDefault _ other = [other]
removeDefaultTypeParams :: Description -> Description
removeDefaultTypeParams part =
Part attrs extern kw ml (moduleDefaultName name) p items
where
Part attrs extern kw ml name p items =
traverseModuleItems (traverseDecls rewriteDecl) part
rewriteDecl :: Decl -> Decl
rewriteDecl (ParamType Parameter x _) =
ParamType Parameter x UnknownType
rewriteDecl other = other
isUsed :: Identifier -> Bool isUsed :: Identifier -> Bool
isUsed name = isUsed name =
...@@ -150,9 +119,11 @@ convert files = ...@@ -150,9 +119,11 @@ convert files =
rewriteModuleItem = traverseNestedModuleItems $ traverseNodes rewriteModuleItem = traverseNestedModuleItems $ traverseNodes
rewriteExpr rewriteDecl rewriteType rewriteLHS rewriteStmt rewriteExpr rewriteDecl rewriteType rewriteLHS rewriteStmt
rewriteDecl :: Decl -> Decl rewriteDecl :: Decl -> Decl
rewriteDecl (ParamType Parameter x _) = rewriteDecl (ParamType Parameter x t) =
ParamType Localparam x t ParamType Localparam x $ rewriteType $
where t = rewriteType $ fst $ typeMap Map.! x case Map.lookup x typeMap of
Nothing -> t
Just (t', _) -> t'
rewriteDecl other = rewriteDecl other =
traverseDeclTypes rewriteType $ traverseDeclTypes rewriteType $
traverseDeclExprs rewriteExpr other traverseDeclExprs rewriteExpr other
...@@ -219,26 +190,10 @@ collectDescriptionM (part @ (Part _ _ _ _ name _ _)) = ...@@ -219,26 +190,10 @@ collectDescriptionM (part @ (Part _ _ _ _ name _ _)) =
collectDeclM _ = return () collectDeclM _ = return ()
collectDescriptionM _ = return () collectDescriptionM _ = return ()
-- produces the default type mapping of a module, if there is one
defaultInstance :: MaybeTypeMap -> Maybe Instance
defaultInstance maybeTypeMap =
if any isNothing maybeTypeMap
then Nothing
else Just $ Map.map ((, Set.empty) . fromJust) maybeTypeMap
-- generate a "unique" name for a particular module type instance -- generate a "unique" name for a particular module type instance
moduleInstanceName :: Identifier -> Instance -> Identifier moduleInstanceName :: Identifier -> Instance -> Identifier
moduleInstanceName m inst = m ++ "_" ++ shortHash (m, inst) moduleInstanceName m inst = m ++ "_" ++ shortHash (m, inst)
-- name for the module without any default type parameters
moduleDefaultName :: Identifier -> Identifier
moduleDefaultName m = m ++ defaultTag
isDefaultName :: Identifier -> Bool
isDefaultName m =
defaultTag == (reverse $ (take $ length defaultTag) $ reverse m)
defaultTag :: Identifier
defaultTag = "_sv2v_default"
-- checks where a type is sufficiently resolved to be substituted -- checks where a type is sufficiently resolved to be substituted
isSimpleType :: Type -> Bool isSimpleType :: Type -> Bool
isSimpleType typ = isSimpleType typ =
...@@ -301,12 +256,8 @@ convertModuleItemM info (orig @ (Instance m bindings x r p)) = ...@@ -301,12 +256,8 @@ convertModuleItemM info (orig @ (Instance m bindings x r p)) =
else if any (isLeft . snd) bindings' then else if any (isLeft . snd) bindings' then
error $ "param type resolution left type params: " ++ show orig error $ "param type resolution left type params: " ++ show orig
++ " converted to: " ++ show bindings' ++ " converted to: " ++ show bindings'
else if any (not . isSimpleType . fst) resolvedTypes then do else if any (not . isSimpleType . fst) resolvedTypes then
let defaults = Map.map (Left . fst) resolvedTypes return orig
let bindingsDefaulted = Map.toList $ Map.union bindingsMap defaults
if isDefaultName m || bindingsDefaulted == Map.toList bindingsMap
then return $ Instance m bindings x r p
else return $ Instance (moduleDefaultName m) bindingsDefaulted x r p
else do else do
tell $ Set.singleton (m, resolvedTypes) tell $ Set.singleton (m, resolvedTypes)
let m' = moduleInstanceName m resolvedTypes let m' = moduleInstanceName m resolvedTypes
...@@ -317,17 +268,14 @@ convertModuleItemM info (orig @ (Instance m bindings x r p)) = ...@@ -317,17 +268,14 @@ convertModuleItemM info (orig @ (Instance m bindings x r p)) =
maybeTypeMap = info Map.! m maybeTypeMap = info Map.! m
-- determine the types corresponding to each type parameter -- determine the types corresponding to each type parameter
bindingsMap = Map.fromList bindings bindingsMap = Map.fromList bindings
resolvedTypesWithDecls = Map.mapWithKey resolveType maybeTypeMap resolvedTypesWithDecls = Map.mapMaybeWithKey resolveType bindingsMap
resolvedTypes = Map.map (\(a, (b, _)) -> (a, b)) resolvedTypesWithDecls resolvedTypes = Map.map (\(a, (b, _)) -> (a, b)) resolvedTypesWithDecls
addedDecls = concatMap (snd . snd . snd) $ addedDecls = concatMap (snd . snd . snd) $
Map.toList resolvedTypesWithDecls Map.toList resolvedTypesWithDecls
resolveType :: Identifier -> Maybe Type -> (Type, (IdentSet, [Decl])) resolveType :: Identifier -> TypeOrExpr -> Maybe (Type, (IdentSet, [Decl]))
resolveType paramName defaultType = resolveType _ Right{} = Nothing
case Map.lookup paramName bindingsMap of resolveType paramName (Left t) =
Nothing -> (t, (Set.empty, [])) Just $ prepareTypeExprs x paramName t
where Just t = defaultType
Just b -> prepareTypeExprs x paramName t
where Left t = b
-- leave only the normal expression params behind -- leave only the normal expression params behind
isParamType = flip Map.member maybeTypeMap isParamType = flip Map.member maybeTypeMap
......
module mod #(
parameter STR = "",
parameter type T = logic,
parameter WIDTH = 32,
parameter type WIDTH_T = logic [WIDTH-1:0],
parameter T INDIRECT = 0,
parameter type OTHER_T = struct packed { type(INDIRECT) x, y; }
);
initial begin
$display("%s $bits(T) = %0d", STR, $bits(T));
$display("%s WIDTH = %0d", STR, WIDTH);
$display("%s $bits(WIDTH_T) = %0d", STR, $bits(WIDTH_T));
$display("%s $bits(OTHER_T) = %0d", STR, $bits(OTHER_T));
end
endmodule
module top;
typedef struct packed { byte y; } W;
W w;
typedef struct packed { type(w) x, y; } V;
V v;
typedef logic [$bits(v)*2-1:0] U;
U u;
`define TEST(x) \
assign x = 0; \
mod #(`"x`", type(x)) m``x();
`TEST(w)
`TEST(v)
`TEST(u)
mod #("t") mt();
endmodule
module mod #(
parameter STR = "",
parameter T = 1
);
initial begin
$display("%s $bits(T) = %0d", STR, T);
$display("%s WIDTH = %0d", STR, 32);
$display("%s $bits(WIDTH_T) = %0d", STR, 32);
$display("%s $bits(OTHER_T) = %0d", STR, 2 * T);
end
endmodule
module top;
`define TEST(x, w) \
wire [w-1:0] x; \
assign x = 0; \
mod #(`"x`", w) m``x();
`TEST(w, 8)
`TEST(v, 16)
`TEST(u, 32)
mod #("t") mt();
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