Commit 2aa39289 by Zachary Snow

added preliminary package conversion

parent 33dc4b3f
......@@ -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
{- 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
......
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