mirror of https://github.com/zachjs/sv2v.git
disambiguate typenames and interface names
This commit is contained in:
parent
b09fdaf76a
commit
a209335c30
|
|
@ -8,6 +8,7 @@
|
|||
### New Features
|
||||
|
||||
* Added support for attributes in unary, binary, and ternary expressions
|
||||
* Added support for shadowing interface names with local typenames
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ initialPhases tops selectExclude =
|
|||
, Convert.FuncRoutine.convert
|
||||
, selectExclude Job.Assert Convert.Assertion.convert
|
||||
, selectExclude Job.Always Convert.AlwaysKW.convert
|
||||
, Convert.Interface.disambiguate
|
||||
, Convert.Package.convert
|
||||
, Convert.StructConst.convert
|
||||
, Convert.PortDecl.convert
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
- Conversion for interfaces
|
||||
-}
|
||||
|
||||
module Convert.Interface (convert) where
|
||||
module Convert.Interface (convert, disambiguate) where
|
||||
|
||||
import Data.List (intercalate, (\\))
|
||||
import Data.Maybe (isJust, isNothing, mapMaybe)
|
||||
|
|
@ -38,11 +38,6 @@ convert tops files =
|
|||
(map . convertDescription tops)
|
||||
files
|
||||
where
|
||||
-- we can only collect/map non-extern interfaces and modules
|
||||
collectPart :: Description -> Writer PartInfos ()
|
||||
collectPart (Part _ False kw _ name ports items) =
|
||||
tell $ Map.singleton name $ PartInfo kw ports items
|
||||
collectPart _ = return ()
|
||||
-- multidimensional instances need to be flattened before this
|
||||
-- conversion can proceed
|
||||
needsFlattening =
|
||||
|
|
@ -55,6 +50,67 @@ convert tops files =
|
|||
checkItem (Instance _ _ _ rs _) = when (length rs > 1) $ tell $ Any True
|
||||
checkItem _ = return ()
|
||||
|
||||
-- we can only collect/map non-extern interfaces and modules
|
||||
collectPart :: Description -> Writer PartInfos ()
|
||||
collectPart (Part _ False kw _ name ports items) =
|
||||
tell $ Map.singleton name $ PartInfo kw ports items
|
||||
collectPart _ = return ()
|
||||
|
||||
-- disambiguate typenames from interface names
|
||||
disambiguate :: [AST] -> [AST]
|
||||
disambiguate = traverseFiles
|
||||
(collectDescriptionsM collectPart)
|
||||
(map . disambiguateDescription)
|
||||
|
||||
-- disambiguate any typenames within a description
|
||||
disambiguateDescription :: PartInfos -> Description -> Description
|
||||
disambiguateDescription parts (Part att ext kw lif name ports items) =
|
||||
Part att ext kw lif name ports $ map traverseModuleItem items
|
||||
where
|
||||
typeNames = getTypeNames items
|
||||
|
||||
traverseModuleItem :: ModuleItem -> ModuleItem
|
||||
traverseModuleItem (MIAttr attr item) =
|
||||
MIAttr attr $ traverseModuleItem item
|
||||
traverseModuleItem (MIPackageItem (Decl (Variable d t x a e))) =
|
||||
MIPackageItem $ Decl $ Variable d (traverseType t) x a e
|
||||
traverseModuleItem other = other
|
||||
|
||||
traverseType :: Type -> Type
|
||||
traverseType (Alias interfaceName rs) =
|
||||
if isInterface interfaceName && not (elem interfaceName typeNames)
|
||||
then InterfaceT interfaceName "" rs
|
||||
else Alias interfaceName rs
|
||||
traverseType orig@(InterfaceT interfaceName _ _) =
|
||||
if null interfaceName || isInterface interfaceName
|
||||
then orig
|
||||
else error $ "declaration type " ++ show orig ++ " appears to "
|
||||
++ "refer to an interface that isn't defined"
|
||||
traverseType other = other
|
||||
|
||||
isInterface :: Identifier -> Bool
|
||||
isInterface partName =
|
||||
fmap pKind (Map.lookup partName parts) == Just Interface
|
||||
|
||||
disambiguateDescription _ other = other
|
||||
|
||||
-- get all of the typenames declared anywhere in the top-level module items
|
||||
getTypeNames :: [ModuleItem] -> [Identifier]
|
||||
getTypeNames (MIAttr _ item : rest) = getTypeNames $ item : rest
|
||||
getTypeNames (Generate genItems : rest) =
|
||||
getTypeNames $ genModuleItems genItems ++ rest
|
||||
getTypeNames (MIPackageItem (Decl (ParamType _ name _)) : rest) =
|
||||
name : getTypeNames rest
|
||||
getTypeNames (_ : rest) = getTypeNames rest
|
||||
getTypeNames [] = []
|
||||
|
||||
-- get the top-level (i.e., un-scoped) module items within a generate block
|
||||
genModuleItems :: [GenItem] -> [ModuleItem]
|
||||
genModuleItems (GenModuleItem item : rest) =
|
||||
item : genModuleItems rest
|
||||
genModuleItems (_ : rest) = genModuleItems rest
|
||||
genModuleItems [] = []
|
||||
|
||||
topInterfaceError :: String -> String -> a
|
||||
topInterfaceError name issue = error $
|
||||
"Specified top module " ++ name ++ " " ++ issue ++ ". Please " ++
|
||||
|
|
@ -307,7 +363,6 @@ convertDescription tops parts (Part att ext Module lif name ports items) =
|
|||
else if elem x (pPorts partInfo) then
|
||||
tell [(x, info)] >> return decl
|
||||
else
|
||||
-- TODO: This does not handle shadowed typenames.
|
||||
scopedErrorM $
|
||||
"Modport not in port list: " ++ show t ++ " " ++ x
|
||||
++ ". Is this an interface missing a port list?"
|
||||
|
|
@ -317,23 +372,10 @@ convertDescription tops parts (Part att ext Module lif name ports items) =
|
|||
checkDecl decl = return decl
|
||||
|
||||
extractModportInfo :: Type -> Maybe (Identifier, Identifier)
|
||||
extractModportInfo (InterfaceT "" "" _) = Just ("", "")
|
||||
extractModportInfo (InterfaceT interfaceName modportName _) =
|
||||
if isInterface interfaceName
|
||||
then Just (interfaceName, modportName)
|
||||
else Nothing
|
||||
extractModportInfo (Alias interfaceName _) =
|
||||
if isInterface interfaceName
|
||||
then Just (interfaceName, "")
|
||||
else Nothing
|
||||
Just (interfaceName, modportName)
|
||||
extractModportInfo _ = Nothing
|
||||
|
||||
isInterface :: Identifier -> Bool
|
||||
isInterface partName =
|
||||
case Map.lookup partName parts of
|
||||
Nothing -> False
|
||||
Just info -> pKind info == Interface
|
||||
|
||||
convertDescription _ _ other = other
|
||||
|
||||
isDecl :: ModuleItem -> Bool
|
||||
|
|
|
|||
|
|
@ -62,7 +62,8 @@ instance Show Type where
|
|||
show (IntegerVector kw sg rs) = printf "%s%s%s" (show kw) (showPadBefore sg) (showRanges rs)
|
||||
show (IntegerAtom kw sg ) = printf "%s%s" (show kw) (showPadBefore sg)
|
||||
show (NonInteger kw ) = printf "%s" (show kw)
|
||||
show (InterfaceT "" "" rs) = printf "interface%s" ( showRanges rs)
|
||||
show (InterfaceT "" "" rs) = printf "interface%s" (showRanges rs)
|
||||
show (InterfaceT xx "" rs) = printf "%s%s" xx (showRanges rs)
|
||||
show (InterfaceT xx yy rs) = printf "%s.%s%s" xx yy (showRanges rs)
|
||||
show (Enum t vals r) = printf "enum %s{%s}%s" tStr (commas $ map showVal vals) (showRanges r)
|
||||
where
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
interface I;
|
||||
logic [3:0] x;
|
||||
endinterface
|
||||
module A(I i);
|
||||
initial $display("A %b", i.x);
|
||||
endmodule
|
||||
module B #(localparam type I = logic [3:0]) (I i);
|
||||
initial $display("B %b", i);
|
||||
endmodule
|
||||
module top;
|
||||
I i();
|
||||
if (1) begin : blk
|
||||
|
|
@ -9,4 +15,7 @@ module top;
|
|||
assign i = 0;
|
||||
end
|
||||
initial $display("%b %b", i.x, blk.i);
|
||||
A a(i);
|
||||
B b(i.x);
|
||||
assign i.x = 1;
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
module A(input wire [3:0] i);
|
||||
initial $display("A %b", i);
|
||||
endmodule
|
||||
module B(input wire [3:0] i);
|
||||
initial $display("B %b", i);
|
||||
endmodule
|
||||
module top;
|
||||
generate
|
||||
if (1) begin : i
|
||||
|
|
@ -9,4 +15,7 @@ module top;
|
|||
end
|
||||
endgenerate
|
||||
initial $display("%b %b", i.x, blk.i);
|
||||
A a(i.x);
|
||||
B b(i.x);
|
||||
assign i.x = 1;
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
// pattern: declaration type I.J appears to refer to an interface that isn't defined
|
||||
module mod(I.J K);
|
||||
endmodule
|
||||
Loading…
Reference in New Issue