mirror of https://github.com/zachjs/sv2v.git
added preliminary package conversion
This commit is contained in:
parent
33dc4b3f88
commit
2aa39289a3
|
|
@ -20,6 +20,7 @@ import qualified Convert.KWArgs
|
|||
import qualified Convert.Logic
|
||||
import qualified Convert.NamedBlock
|
||||
import qualified Convert.NestPI
|
||||
import qualified Convert.Package
|
||||
import qualified Convert.PackedArray
|
||||
import qualified Convert.Return
|
||||
import qualified Convert.StarPort
|
||||
|
|
@ -49,6 +50,7 @@ phases excludes =
|
|||
, Convert.Typedef.convert
|
||||
, Convert.UnbasedUnsized.convert
|
||||
, Convert.Unique.convert
|
||||
, Convert.Package.convert
|
||||
, Convert.NestPI.convert
|
||||
, selectExclude (Job.Interface, Convert.Interface.convert)
|
||||
, selectExclude (Job.Always , Convert.AlwaysKW.convert)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ module Convert.NestPI (convert) where
|
|||
|
||||
import Control.Monad.State
|
||||
import Control.Monad.Writer
|
||||
import Data.List (isPrefixOf)
|
||||
import qualified Data.Map.Strict as Map
|
||||
import qualified Data.Set as Set
|
||||
|
||||
|
|
@ -42,6 +43,10 @@ traverseDescriptionM (PackageItem item) = do
|
|||
return $ PackageItem item
|
||||
traverseDescriptionM (orig @ (Part extern kw lifetime name ports items)) = do
|
||||
tfs <- get
|
||||
let neededPIs = Set.difference
|
||||
(Set.union usedPIs $
|
||||
Set.filter (isPrefixOf "import ") $ Map.keysSet tfs)
|
||||
existingPIs
|
||||
let newItems = map MIPackageItem $ Map.elems $
|
||||
Map.restrictKeys tfs neededPIs
|
||||
return $ Part extern kw lifetime name ports (items ++ newItems)
|
||||
|
|
@ -53,7 +58,6 @@ traverseDescriptionM (orig @ (Part extern kw lifetime name ports items)) = do
|
|||
, collectTypesM collectTypenamesM
|
||||
, collectExprsM $ collectNestedExprsM collectIdentsM
|
||||
]
|
||||
neededPIs = Set.difference usedPIs existingPIs
|
||||
traverseDescriptionM other = return other
|
||||
|
||||
-- writes down the names of package items
|
||||
|
|
@ -92,5 +96,5 @@ piName (Typedef _ ident ) = Just ident
|
|||
piName (Decl (Variable _ _ ident _ _)) = Just ident
|
||||
piName (Decl (Parameter _ ident _)) = Just ident
|
||||
piName (Decl (Localparam _ ident _)) = Just ident
|
||||
piName (Import _ _) = Nothing
|
||||
piName (Import x y) = Just $ show $ Import x y
|
||||
piName (Comment _) = Nothing
|
||||
|
|
|
|||
|
|
@ -0,0 +1,116 @@
|
|||
{- sv2v
|
||||
- Author: Zachary Snow <zach@zachjs.com>
|
||||
-
|
||||
- Conversion for packages and imports
|
||||
-}
|
||||
|
||||
module Convert.Package (convert) where
|
||||
|
||||
import Control.Monad.Writer
|
||||
import qualified Data.Map.Strict as Map
|
||||
import qualified Data.Set as Set
|
||||
|
||||
import Convert.Traverse
|
||||
import Language.SystemVerilog.AST
|
||||
|
||||
type Packages = Map.Map Identifier PackageItems
|
||||
type PackageItems = Map.Map Identifier PackageItem
|
||||
type Idents = Set.Set Identifier
|
||||
|
||||
convert :: [AST] -> [AST]
|
||||
convert asts =
|
||||
step asts
|
||||
where
|
||||
step :: [AST] -> [AST]
|
||||
step curr =
|
||||
if next == curr
|
||||
then curr
|
||||
else step next
|
||||
where
|
||||
packages = execWriter $
|
||||
collectDescriptionsM collectDescriptionM $ concat curr
|
||||
globalItems = map PackageItem $
|
||||
concatMap (uncurry globalPackageItems) $ Map.toList packages
|
||||
next = map ((++) globalItems) $ map (filter shouldntRemove) $ map
|
||||
(traverseDescriptions $ traverseDescription packages) curr
|
||||
shouldntRemove :: Description -> Bool
|
||||
shouldntRemove (Package _ name _) = Map.notMember name packages
|
||||
shouldntRemove _ = True
|
||||
|
||||
globalPackageItems :: Identifier -> PackageItems -> [PackageItem]
|
||||
globalPackageItems name items =
|
||||
map (prefixPackageItem name (Map.keysSet items)) (Map.elems items)
|
||||
|
||||
prefixPackageItem :: Identifier -> Idents -> PackageItem -> PackageItem
|
||||
prefixPackageItem packageName idents item =
|
||||
item''
|
||||
where
|
||||
prefix :: Identifier -> Identifier
|
||||
prefix x =
|
||||
if Set.member x idents
|
||||
then packageName ++ "_" ++ x
|
||||
else x
|
||||
item' = case item of
|
||||
Function a b x c d -> Function a b (prefix x) c d
|
||||
Task a x c d -> Task a (prefix x) c d
|
||||
Typedef a x -> Typedef a (prefix x)
|
||||
Decl (Variable a b x c d) -> Decl (Variable a b (prefix x) c d)
|
||||
Decl (Parameter a x b) -> Decl (Parameter a (prefix x) b)
|
||||
Decl (Localparam a x b) -> Decl (Localparam a (prefix x) b)
|
||||
other -> other
|
||||
convertExpr (Ident x) = Ident $ prefix x
|
||||
convertExpr other = other
|
||||
converter =
|
||||
(traverseExprs $ traverseNestedExprs convertExpr)
|
||||
MIPackageItem item'' = converter $ MIPackageItem item'
|
||||
|
||||
collectDescriptionM :: Description -> Writer Packages ()
|
||||
collectDescriptionM (Package _ name items) =
|
||||
if any isImport items
|
||||
then return ()
|
||||
else tell $ Map.singleton name itemMap
|
||||
where
|
||||
itemMap = Map.unions $ map toMap items
|
||||
toMap :: PackageItem -> PackageItems
|
||||
toMap item =
|
||||
case piName item of
|
||||
Nothing -> Map.empty
|
||||
Just x -> Map.singleton x item
|
||||
isImport :: PackageItem -> Bool
|
||||
isImport (Import _ _) = True
|
||||
isImport _ = False
|
||||
collectDescriptionM _ = return ()
|
||||
|
||||
traverseDescription :: Packages -> Description -> Description
|
||||
traverseDescription packages description =
|
||||
traverseModuleItems (traverseModuleItem packages) description
|
||||
|
||||
traverseModuleItem :: Packages -> ModuleItem -> ModuleItem
|
||||
traverseModuleItem packages (MIPackageItem (Import x y)) =
|
||||
if Map.member x packages
|
||||
then Generate $ map (GenModuleItem . MIPackageItem) items
|
||||
else MIPackageItem $ Import x y
|
||||
where
|
||||
packageItems = packages Map.! x
|
||||
filterer = case y of
|
||||
Nothing -> \_ -> True
|
||||
Just ident -> (==) ident
|
||||
items = map snd $ filter (filterer . fst) $ Map.toList packageItems
|
||||
traverseModuleItem _ item =
|
||||
(traverseExprs $ traverseNestedExprs traverseExpr) $
|
||||
item
|
||||
|
||||
traverseExpr :: Expr -> Expr
|
||||
traverseExpr (PSIdent x y) = Ident $ x ++ "_" ++ y
|
||||
traverseExpr other = other
|
||||
|
||||
-- returns the "name" of a package item, if it has one
|
||||
piName :: PackageItem -> Maybe Identifier
|
||||
piName (Function _ _ ident _ _) = Just ident
|
||||
piName (Task _ ident _ _) = Just ident
|
||||
piName (Typedef _ ident ) = Just ident
|
||||
piName (Decl (Variable _ _ ident _ _)) = Just ident
|
||||
piName (Decl (Parameter _ ident _)) = Just ident
|
||||
piName (Decl (Localparam _ ident _)) = Just ident
|
||||
piName (Import _ _) = Nothing
|
||||
piName (Comment _) = Nothing
|
||||
|
|
@ -64,6 +64,7 @@ executable sv2v
|
|||
Convert.Logic
|
||||
Convert.NamedBlock
|
||||
Convert.NestPI
|
||||
Convert.Package
|
||||
Convert.PackedArray
|
||||
Convert.Return
|
||||
Convert.StarPort
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
package A;
|
||||
localparam FOO = 37;
|
||||
localparam BAR = 97;
|
||||
endpackage
|
||||
package B;
|
||||
localparam FOO = -37;
|
||||
localparam BAR = -97;
|
||||
endpackage
|
||||
module top;
|
||||
import A::FOO;
|
||||
import B::BAR;
|
||||
initial begin
|
||||
$display(A::FOO);
|
||||
$display(A::BAR);
|
||||
$display(B::FOO);
|
||||
$display(B::BAR);
|
||||
$display(FOO);
|
||||
$display(BAR);
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
module top;
|
||||
localparam A_FOO = 37;
|
||||
localparam A_BAR = 97;
|
||||
localparam B_FOO = -37;
|
||||
localparam B_BAR = -97;
|
||||
localparam FOO = 37;
|
||||
localparam BAR = -97;
|
||||
initial begin
|
||||
$display(A_FOO);
|
||||
$display(A_BAR);
|
||||
$display(B_FOO);
|
||||
$display(B_BAR);
|
||||
$display(FOO);
|
||||
$display(BAR);
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1 @@
|
|||
// intentionally empty
|
||||
Loading…
Reference in New Issue