Commit 5cc4dce0 by Zachary Snow

refactor positional binding checking and resolution

parent ba270acb
...@@ -37,8 +37,8 @@ import qualified Convert.Package ...@@ -37,8 +37,8 @@ import qualified Convert.Package
import qualified Convert.ParamNoDefault import qualified Convert.ParamNoDefault
import qualified Convert.ParamType import qualified Convert.ParamType
import qualified Convert.RemoveComments import qualified Convert.RemoveComments
import qualified Convert.ResolveBindings
import qualified Convert.Simplify import qualified Convert.Simplify
import qualified Convert.StarPort
import qualified Convert.Stream import qualified Convert.Stream
import qualified Convert.StringParam import qualified Convert.StringParam
import qualified Convert.Struct import qualified Convert.Struct
...@@ -100,11 +100,11 @@ initialPhases selectExclude = ...@@ -100,11 +100,11 @@ initialPhases selectExclude =
, Convert.Unique.convert , Convert.Unique.convert
, Convert.LogOp.convert , Convert.LogOp.convert
, Convert.Foreach.convert , Convert.Foreach.convert
, Convert.StarPort.convert
, selectExclude Job.Assert Convert.Assertion.convert , selectExclude Job.Assert Convert.Assertion.convert
, selectExclude Job.Always Convert.AlwaysKW.convert , selectExclude Job.Always Convert.AlwaysKW.convert
, Convert.Package.convert , Convert.Package.convert
, Convert.ParamNoDefault.convert , Convert.ParamNoDefault.convert
, Convert.ResolveBindings.convert
] ]
convert :: [Job.Exclude] -> Phase convert :: [Job.Exclude] -> Phase
......
...@@ -96,15 +96,11 @@ convertDescription parts (Part attrs extern Module lifetime name ports items) = ...@@ -96,15 +96,11 @@ convertDescription parts (Part attrs extern Module lifetime name ports items) =
inlineInstance rs modportBindings partItems inlineInstance rs modportBindings partItems
part instanceName paramBindings portBindings part instanceName paramBindings portBindings
where where
Instance part rawParamBindings instanceName rs rawPortBindings = Instance part paramBindings instanceName rs portBindings =
instanceItem instanceItem
maybePartInfo = Map.lookup part parts maybePartInfo = Map.lookup part parts
Just partInfo = maybePartInfo Just partInfo = maybePartInfo
PartInfo partKind partPorts partItems = partInfo PartInfo partKind _ partItems = partInfo
partParams = parameterNames partItems
paramBindings = resolveBindings partParams rawParamBindings
portBindings = resolveBindings partPorts rawPortBindings
modportInstances = extractModportInstances partInfo modportInstances = extractModportInstances partInfo
getModportBindings modports = mapMaybe getModportBindings modports = mapMaybe
...@@ -583,16 +579,6 @@ pattern InstArrKey expr = Dot (Bit expr (RawNum 0)) InstArrName ...@@ -583,16 +579,6 @@ pattern InstArrKey expr = Dot (Bit expr (RawNum 0)) InstArrName
pattern InstArrEncoded :: Expr -> Expr -> ModuleItem pattern InstArrEncoded :: Expr -> Expr -> ModuleItem
pattern InstArrEncoded l r = Modport InstArrName (InstArrVal l r) pattern InstArrEncoded l r = Modport InstArrName (InstArrVal l r)
-- given a list of module items, produces the parameter names in order
parameterNames :: [ModuleItem] -> [Identifier]
parameterNames =
execWriter . mapM (collectNestedModuleItemsM $ collectDeclsM collectDeclM)
where
collectDeclM :: Decl -> Writer [Identifier] ()
collectDeclM (Param Parameter _ x _) = tell [x]
collectDeclM (ParamType Parameter x _) = tell [x]
collectDeclM _ = return ()
-- determines the lower bound for the given slice -- determines the lower bound for the given slice
sliceLo :: PartSelectMode -> Range -> Expr sliceLo :: PartSelectMode -> Range -> Expr
sliceLo NonIndexed (l, r) = endianCondExpr (l, r) r l sliceLo NonIndexed (l, r) = endianCondExpr (l, r) r l
......
...@@ -450,8 +450,9 @@ resolveCSIdent className paramBindings scopeKeys itemName = do ...@@ -450,8 +450,9 @@ resolveCSIdent className paramBindings scopeKeys itemName = do
"could not find class " ++ show className "could not find class " ++ show className
let Just (classParams, classItems) = maybeClass let Just (classParams, classItems) = maybeClass
-- resolve the provided parameters -- resolve the provided parameters
let resolveMsg = "parameters in class specialization of " ++ show className
let paramNames = mapMaybe extractParameterName classParams let paramNames = mapMaybe extractParameterName classParams
let paramBindings' = resolveBindings paramNames paramBindings let paramBindings' = resolveBindings resolveMsg paramNames paramBindings
-- generate a unique name for this synthetic package -- generate a unique name for this synthetic package
let packageName = className ++ '_' : shortHash (scopeKeys, paramBindings') let packageName = className ++ '_' : shortHash (scopeKeys, paramBindings')
-- process the synthetic package and inject the given parameters -- process the synthetic package and inject the given parameters
......
...@@ -74,9 +74,8 @@ traverseModuleItem parts (orig @ (Instance part params name _ _)) = ...@@ -74,9 +74,8 @@ traverseModuleItem parts (orig @ (Instance part params name _ _)) =
where where
maybePartInfo = Map.lookup part parts maybePartInfo = Map.lookup part parts
Just partInfo = maybePartInfo Just partInfo = maybePartInfo
paramsResolved = resolveBindings (map fst partInfo) params
paramsWithNoDefault = map fst $ filter snd partInfo paramsWithNoDefault = map fst $ filter snd partInfo
missingParams = filter (needsDefault paramsResolved) paramsWithNoDefault missingParams = filter (needsDefault params) paramsWithNoDefault
traverseModuleItem _ other = other traverseModuleItem _ other = other
-- whether a given parameter is unspecified in the given parameter bindings -- whether a given parameter is unspecified in the given parameter bindings
......
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
- Conversion for `.*` and unnamed bindings
-
- While positional bindings need not be converted, resolving them here
- simplifies downstream conversions.
-}
module Convert.ResolveBindings (convert) where
import Control.Monad.Writer.Strict
import qualified Data.Map.Strict as Map
import Convert.Traverse
import Language.SystemVerilog.AST
type Ports = Map.Map Identifier ([Identifier], [Identifier])
convert :: [AST] -> [AST]
convert =
traverseFiles
(collectDescriptionsM collectPortsM)
(traverseDescriptions . traverseModuleItems . mapInstance)
collectPortsM :: Description -> Writer Ports ()
collectPortsM (Part _ _ _ _ name ports items) =
tell $ Map.singleton name (params, ports)
where params = parameterNames items
collectPortsM _ = return ()
-- given a list of module items, produces the parameter names in order
parameterNames :: [ModuleItem] -> [Identifier]
parameterNames =
execWriter . mapM (collectNestedModuleItemsM $ collectDeclsM collectDeclM)
where
collectDeclM :: Decl -> Writer [Identifier] ()
collectDeclM (Param Parameter _ x _) = tell [x]
collectDeclM (ParamType Parameter x _) = tell [x]
collectDeclM _ = return ()
mapInstance :: Ports -> ModuleItem -> ModuleItem
mapInstance modulePorts (Instance m paramBindings x rs portBindings) =
-- if we can't find it, just skip :(
if maybeModuleInfo == Nothing
then Instance m paramBindings x rs portBindings
else Instance m paramBindings' x rs portBindings'
where
maybeModuleInfo = Map.lookup m modulePorts
Just (paramNames, portNames) = maybeModuleInfo
msg :: String -> String
msg = flip (++) $ " in instance " ++ show x ++ " of " ++ show m
paramBindings' = resolveBindings (msg "parameter overrides") paramNames
paramBindings
portBindings' = resolveBindings (msg "port connections") portNames
$ concatMap expandStar portBindings
expandStar :: PortBinding -> [PortBinding]
expandStar ("*", Nil) =
map (\port -> (port, Ident port)) $
filter (flip notElem alreadyBound) portNames
where alreadyBound = map fst portBindings
expandStar other = [other]
mapInstance _ other = other
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
- Conversion for `.*` in module instantiation
-}
module Convert.StarPort (convert) where
import Control.Monad.Writer.Strict
import qualified Data.Map.Strict as Map
import Convert.Traverse
import Language.SystemVerilog.AST
type Ports = Map.Map Identifier [Identifier]
convert :: [AST] -> [AST]
convert =
traverseFiles
(collectDescriptionsM collectPortsM)
(traverseDescriptions . traverseModuleItems . mapInstance)
collectPortsM :: Description -> Writer Ports ()
collectPortsM (Part _ _ _ _ name ports _) = tell $ Map.singleton name ports
collectPortsM _ = return ()
mapInstance :: Ports -> ModuleItem -> ModuleItem
mapInstance modulePorts (Instance m p x rs bindings) =
Instance m p x rs $ concatMap expandBinding bindings
where
alreadyBound :: [Identifier]
alreadyBound = map fst bindings
expandBinding :: PortBinding -> [PortBinding]
expandBinding ("*", Nil) =
case Map.lookup m modulePorts of
Just l ->
map (\port -> (port, Ident port)) $
filter (\s -> not $ elem s alreadyBound) $ l
-- if we can't find it, just skip :(
Nothing -> [("*", Nil)]
expandBinding other = [other]
mapInstance _ other = other
...@@ -1109,7 +1109,7 @@ traverseNestedModuleItemsM mapper = fullMapper ...@@ -1109,7 +1109,7 @@ traverseNestedModuleItemsM mapper = fullMapper
Nothing -> return $ GenIf (Number n) s1 s2 Nothing -> return $ GenIf (Number n) s1 s2
Just 0 -> genItemMapper s2 Just 0 -> genItemMapper s2
Just _ -> genItemMapper s1 Just _ -> genItemMapper s1
genItemMapper (GenBlock "" [item]) = return item genItemMapper (GenBlock "" [item]) = genItemMapper item
genItemMapper (GenBlock _ []) = return GenNull genItemMapper (GenBlock _ []) = return GenNull
genItemMapper other = return other genItemMapper other = return other
......
...@@ -88,13 +88,12 @@ shortHash x = ...@@ -88,13 +88,12 @@ shortHash x =
type Binding t = (Identifier, t) type Binding t = (Identifier, t)
-- give a set of bindings explicit names -- give a set of bindings explicit names
resolveBindings :: Show t => [Identifier] -> [Binding t] -> [Binding t] resolveBindings :: String -> [Identifier] -> [Binding t] -> [Binding t]
resolveBindings available bindings = resolveBindings _ _ [] = []
zipWith resolveBinding bindings [0..] resolveBindings location available bindings =
where if length available < length bindings then
resolveBinding ("", e) idx = error $ "too many bindings specified for " ++ location
if idx < length available else if null $ fst $ head bindings then
then (available !! idx, e) zip available $ map snd bindings
else error $ "binding " ++ show e ++ " is out of range " else
++ show available bindings
resolveBinding other _ = other
...@@ -87,9 +87,9 @@ executable sv2v ...@@ -87,9 +87,9 @@ executable sv2v
Convert.ParamNoDefault Convert.ParamNoDefault
Convert.ParamType Convert.ParamType
Convert.RemoveComments Convert.RemoveComments
Convert.ResolveBindings
Convert.Scoper Convert.Scoper
Convert.Simplify Convert.Simplify
Convert.StarPort
Convert.Stream Convert.Stream
Convert.StringParam Convert.StringParam
Convert.Struct Convert.Struct
......
// pattern: too many bindings specified for parameters in class specialization of "example"
class example #(
parameter P = 1,
parameter Q = 1
);
typedef logic [P * Q:0] T;
endclass
module top;
example#(1, 2, 3)::T x;
endmodule
// pattern: too many bindings specified for parameter overrides in instance "e" of "example"
module example;
parameter P = 1;
parameter Q = 1;
endmodule
module top;
example #(1, 2, 3) e();
endmodule
// pattern: too many bindings specified for port connections in instance "e" of "example"
module example(
input x, y
);
endmodule
module top;
example e(1'b1, 1'b0, 1'b0);
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