Commit 2aa39289 by Zachary Snow

added preliminary package conversion

parent 33dc4b3f
...@@ -20,6 +20,7 @@ import qualified Convert.KWArgs ...@@ -20,6 +20,7 @@ import qualified Convert.KWArgs
import qualified Convert.Logic import qualified Convert.Logic
import qualified Convert.NamedBlock import qualified Convert.NamedBlock
import qualified Convert.NestPI import qualified Convert.NestPI
import qualified Convert.Package
import qualified Convert.PackedArray import qualified Convert.PackedArray
import qualified Convert.Return import qualified Convert.Return
import qualified Convert.StarPort import qualified Convert.StarPort
...@@ -49,6 +50,7 @@ phases excludes = ...@@ -49,6 +50,7 @@ phases excludes =
, Convert.Typedef.convert , Convert.Typedef.convert
, Convert.UnbasedUnsized.convert , Convert.UnbasedUnsized.convert
, Convert.Unique.convert , Convert.Unique.convert
, Convert.Package.convert
, Convert.NestPI.convert , Convert.NestPI.convert
, selectExclude (Job.Interface, Convert.Interface.convert) , selectExclude (Job.Interface, Convert.Interface.convert)
, selectExclude (Job.Always , Convert.AlwaysKW.convert) , selectExclude (Job.Always , Convert.AlwaysKW.convert)
......
...@@ -8,6 +8,7 @@ module Convert.NestPI (convert) where ...@@ -8,6 +8,7 @@ module Convert.NestPI (convert) where
import Control.Monad.State import Control.Monad.State
import Control.Monad.Writer import Control.Monad.Writer
import Data.List (isPrefixOf)
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
...@@ -42,6 +43,10 @@ traverseDescriptionM (PackageItem item) = do ...@@ -42,6 +43,10 @@ traverseDescriptionM (PackageItem item) = do
return $ PackageItem item return $ PackageItem item
traverseDescriptionM (orig @ (Part extern kw lifetime name ports items)) = do traverseDescriptionM (orig @ (Part extern kw lifetime name ports items)) = do
tfs <- get tfs <- get
let neededPIs = Set.difference
(Set.union usedPIs $
Set.filter (isPrefixOf "import ") $ Map.keysSet tfs)
existingPIs
let newItems = map MIPackageItem $ Map.elems $ let newItems = map MIPackageItem $ Map.elems $
Map.restrictKeys tfs neededPIs Map.restrictKeys tfs neededPIs
return $ Part extern kw lifetime name ports (items ++ newItems) return $ Part extern kw lifetime name ports (items ++ newItems)
...@@ -53,7 +58,6 @@ traverseDescriptionM (orig @ (Part extern kw lifetime name ports items)) = do ...@@ -53,7 +58,6 @@ traverseDescriptionM (orig @ (Part extern kw lifetime name ports items)) = do
, collectTypesM collectTypenamesM , collectTypesM collectTypenamesM
, collectExprsM $ collectNestedExprsM collectIdentsM , collectExprsM $ collectNestedExprsM collectIdentsM
] ]
neededPIs = Set.difference usedPIs existingPIs
traverseDescriptionM other = return other traverseDescriptionM other = return other
-- writes down the names of package items -- writes down the names of package items
...@@ -92,5 +96,5 @@ piName (Typedef _ ident ) = Just ident ...@@ -92,5 +96,5 @@ piName (Typedef _ ident ) = Just ident
piName (Decl (Variable _ _ ident _ _)) = Just ident piName (Decl (Variable _ _ ident _ _)) = Just ident
piName (Decl (Parameter _ ident _)) = Just ident piName (Decl (Parameter _ ident _)) = Just ident
piName (Decl (Localparam _ ident _)) = Just ident piName (Decl (Localparam _ ident _)) = Just ident
piName (Import _ _) = Nothing piName (Import x y) = Just $ show $ Import x y
piName (Comment _) = Nothing piName (Comment _) = Nothing
{- 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 ...@@ -64,6 +64,7 @@ executable sv2v
Convert.Logic Convert.Logic
Convert.NamedBlock Convert.NamedBlock
Convert.NestPI Convert.NestPI
Convert.Package
Convert.PackedArray Convert.PackedArray
Convert.Return Convert.Return
Convert.StarPort Convert.StarPort
......
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
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
// intentionally empty
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