Commit d2c06b58 by Zachary Snow

initial work towards fleshing out package conversion

parent 91dd1441
...@@ -49,7 +49,7 @@ traverseDescriptionM (orig @ (Part extern kw lifetime name ports items)) = do ...@@ -49,7 +49,7 @@ traverseDescriptionM (orig @ (Part extern kw lifetime name ports items)) = do
existingPIs 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 (newItems ++ items)
where where
existingPIs = execWriter $ collectModuleItemsM collectPIsM orig existingPIs = execWriter $ collectModuleItemsM collectPIsM orig
runner f = execWriter $ collectModuleItemsM f orig runner f = execWriter $ collectModuleItemsM f orig
...@@ -97,4 +97,5 @@ piName (Decl (Variable _ _ ident _ _)) = Just ident ...@@ -97,4 +97,5 @@ 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 x y) = Just $ show $ Import x y piName (Import x y) = Just $ show $ Import x y
piName (Export _) = Nothing
piName (Comment _) = Nothing piName (Comment _) = Nothing
{- sv2v {- sv2v
- Author: Zachary Snow <zach@zachjs.com> - Author: Zachary Snow <zach@zachjs.com>
- -
- Conversion for packages and imports - Conversion for packages, exports, and imports
-
- TODO: We do not yet handle exports.
- TODO: The scoping rules are not being entirely followed yet.
- TODO: Explicit imports may introduce name conflicts because of carried items.
-
- The SystemVerilog scoping rules for exports and imports are not entirely
- trivial. We do not explicitly handle the "error" scenarios detailed Table
- 26-1 of Section 26-3 of IEEE 1800-2017. Users generally shouldn't be relying
- on this tool to catch and report such wild naming conflicts that are outlined
- there.
-
- Summary:
- * In scopes which have a local declaration of an identifier, that identifier
- refers to that local declaration.
- * If there is no local declaration, the identifier refers to the imported
- declaration.
- * If there is an explicit import of that identifier, the identifier refers to
- the imported declaration.
- * Usages of conflicting wildcard imports are not allowed.
-
- If a package cannot be found within a file that references it (including
- through files it imports), we fall back to an arbitrary package with the
- given name, if it exists. While this isn't foolproof, some projects do rely
- on their toolchain to locate their packages in other files, much like modules
- or interfaces.
-} -}
module Convert.Package (convert) where module Convert.Package (convert) where
...@@ -29,13 +54,23 @@ convert asts = ...@@ -29,13 +54,23 @@ convert asts =
where where
packages = execWriter $ packages = execWriter $
collectDescriptionsM collectDescriptionM $ concat curr collectDescriptionsM collectDescriptionM $ concat curr
next = map (convertFile packages) curr
convertFile :: Packages -> AST -> AST
convertFile globalPackages ast =
(++) globalItems $
filter (not . isCollected) $
traverseDescriptions (traverseDescription packages) $
ast
where
globalItems = map PackageItem $ globalItems = map PackageItem $
concatMap (uncurry globalPackageItems) $ Map.toList packages concatMap (uncurry globalPackageItems) $ Map.toList packages
next = map ((++) globalItems) $ map (filter shouldntRemove) $ map localPackages = execWriter $
(traverseDescriptions $ traverseDescription packages) curr collectDescriptionsM collectDescriptionM ast
shouldntRemove :: Description -> Bool packages = Map.union localPackages globalPackages
shouldntRemove (Package _ name _) = Map.notMember name packages isCollected :: Description -> Bool
shouldntRemove _ = True isCollected (Package _ name _) = Map.member name localPackages
isCollected _ = False
globalPackageItems :: Identifier -> PackageItems -> [PackageItem] globalPackageItems :: Identifier -> PackageItems -> [PackageItem]
globalPackageItems name items = globalPackageItems name items =
...@@ -86,20 +121,30 @@ collectDescriptionM _ = return () ...@@ -86,20 +121,30 @@ collectDescriptionM _ = return ()
traverseDescription :: Packages -> Description -> Description traverseDescription :: Packages -> Description -> Description
traverseDescription packages description = traverseDescription packages description =
traverseModuleItems (traverseModuleItem packages) description traverseModuleItems (traverseModuleItem existingItemNames packages)
description
where
existingItemNames = execWriter $
collectModuleItemsM writePIName description
writePIName :: ModuleItem -> Writer Idents ()
writePIName (MIPackageItem item) =
case piName item of
Nothing -> return ()
Just x -> tell $ Set.singleton x
writePIName _ = return ()
traverseModuleItem :: Packages -> ModuleItem -> ModuleItem traverseModuleItem :: Idents -> Packages -> ModuleItem -> ModuleItem
traverseModuleItem packages (MIPackageItem (Import x y)) = traverseModuleItem existingItemNames packages (MIPackageItem (Import x y)) =
if Map.member x packages if Map.member x packages
then Generate $ map (GenModuleItem . MIPackageItem) items then Generate $ map (GenModuleItem . MIPackageItem) items
else MIPackageItem $ Import x y else MIPackageItem $ Import x y
where where
packageItems = packages Map.! x packageItems = packages Map.! x
filterer = case y of filterer itemName = case y of
Nothing -> \_ -> True Nothing -> Set.notMember itemName existingItemNames
Just ident -> (==) ident Just ident -> ident == itemName
items = map snd $ filter (filterer . fst) $ Map.toList packageItems items = map snd $ filter (filterer . fst) $ Map.toList packageItems
traverseModuleItem _ item = traverseModuleItem _ _ item =
(traverseExprs $ traverseNestedExprs traverseExpr) $ (traverseExprs $ traverseNestedExprs traverseExpr) $
(traverseStmts traverseStmt) $ (traverseStmts traverseStmt) $
(traverseTypes traverseType) $ (traverseTypes traverseType) $
...@@ -131,4 +176,5 @@ piName (Decl (Variable _ _ ident _ _)) = Just ident ...@@ -131,4 +176,5 @@ 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 _ _) = Nothing
piName (Export _) = Nothing
piName (Comment _) = Nothing piName (Comment _) = Nothing
...@@ -564,6 +564,8 @@ traverseExprsM' strat exprMapper = moduleItemMapper ...@@ -564,6 +564,8 @@ traverseExprsM' strat exprMapper = moduleItemMapper
return $ MIPackageItem $ Comment c return $ MIPackageItem $ Comment c
moduleItemMapper (MIPackageItem (Import x y)) = moduleItemMapper (MIPackageItem (Import x y)) =
return $ MIPackageItem $ Import x y return $ MIPackageItem $ Import x y
moduleItemMapper (MIPackageItem (Export x)) =
return $ MIPackageItem $ Export x
moduleItemMapper (AssertionItem (mx, a)) = do moduleItemMapper (AssertionItem (mx, a)) = do
a' <- traverseAssertionStmtsM stmtMapper a a' <- traverseAssertionStmtsM stmtMapper a
a'' <- traverseAssertionExprsM exprMapper a' a'' <- traverseAssertionExprsM exprMapper a'
......
...@@ -57,6 +57,7 @@ data PackageItem ...@@ -57,6 +57,7 @@ data PackageItem
| Function (Maybe Lifetime) Type Identifier [Decl] [Stmt] | Function (Maybe Lifetime) Type Identifier [Decl] [Stmt]
| Task (Maybe Lifetime) Identifier [Decl] [Stmt] | Task (Maybe Lifetime) Identifier [Decl] [Stmt]
| Import Identifier (Maybe Identifier) | Import Identifier (Maybe Identifier)
| Export (Maybe (Identifier, Maybe Identifier))
| Decl Decl | Decl Decl
| Comment String | Comment String
deriving Eq deriving Eq
...@@ -72,6 +73,8 @@ instance Show PackageItem where ...@@ -72,6 +73,8 @@ instance Show PackageItem where
(showLifetime ml) x (indent $ show i) (showLifetime ml) x (indent $ show i)
(indent $ unlines' $ map show b) (indent $ unlines' $ map show b)
show (Import x y) = printf "import %s::%s;" x (fromMaybe "*" y) show (Import x y) = printf "import %s::%s;" x (fromMaybe "*" y)
show (Export Nothing) = "export *::*";
show (Export (Just (x, y))) = printf "export %s::%s;" x (fromMaybe "*" y)
show (Decl decl) = show decl show (Decl decl) = show decl
show (Comment c) = show (Comment c) =
if elem '\n' c if elem '\n' c
......
...@@ -578,6 +578,8 @@ NonDeclPackageItem :: { [PackageItem] } ...@@ -578,6 +578,8 @@ NonDeclPackageItem :: { [PackageItem] }
| "function" opt(Lifetime) FuncRetAndName TFItems DeclsAndStmts "endfunction" opt(Tag) { [Function $2 (fst $3) (snd $3) (map defaultFuncInput $ (map makeInput $4) ++ fst $5) (snd $5)] } | "function" opt(Lifetime) FuncRetAndName TFItems DeclsAndStmts "endfunction" opt(Tag) { [Function $2 (fst $3) (snd $3) (map defaultFuncInput $ (map makeInput $4) ++ fst $5) (snd $5)] }
| "task" opt(Lifetime) Identifier TFItems DeclsAndStmts "endtask" opt(Tag) { [Task $2 $3 (map defaultFuncInput $ $4 ++ fst $5) (snd $5)] } | "task" opt(Lifetime) Identifier TFItems DeclsAndStmts "endtask" opt(Tag) { [Task $2 $3 (map defaultFuncInput $ $4 ++ fst $5) (snd $5)] }
| "import" PackageImportItems ";" { map (uncurry Import) $2 } | "import" PackageImportItems ";" { map (uncurry Import) $2 }
| "export" PackageImportItems ";" { map (Export . Just) $2 }
| "export" "*" "::" "*" ";" { [Export Nothing] } -- "Nothing" being no restrictions
PackageImportItems :: { [(Identifier, Maybe Identifier)] } PackageImportItems :: { [(Identifier, Maybe Identifier)] }
: PackageImportItem { [$1] } : PackageImportItem { [$1] }
......
...@@ -17,6 +17,11 @@ package D; ...@@ -17,6 +17,11 @@ package D;
endpackage endpackage
package E; package E;
import D::*; import D::*;
export D::*;
endpackage
package F;
localparam MAGIC = -42;
localparam PIZZAZZ = -5;
endpackage endpackage
module top; module top;
import A::FOO; import A::FOO;
...@@ -33,4 +38,28 @@ module top; ...@@ -33,4 +38,28 @@ module top;
$display("%d", E::pack(0)); $display("%d", E::pack(0));
$display("%d", E::pack(1)); $display("%d", E::pack(1));
end end
import F::*;
initial begin
$display("imported MAGIC %d", MAGIC);
$display("imported MAGIC %d", F::MAGIC);
begin
localparam MAGIC = 42;
$display("local MAGIC %d", MAGIC);
$display("imported MAGIC %d", F::MAGIC);
end
$display("imported MAGIC %d", MAGIC);
$display("imported MAGIC %d", F::MAGIC);
end
localparam PIZZAZZ = -6;
initial begin
$display("local PIZZAZZ %d", PIZZAZZ);
$display("imported PIZZAZZ %d", F::PIZZAZZ);
begin
localparam PIZZAZZ = -7;
$display("shadowed local PIZZAZZ %d", PIZZAZZ);
$display("imported PIZZAZZ %d", F::PIZZAZZ);
end
$display("local PIZZAZZ %d", PIZZAZZ);
$display("imported PIZZAZZ %d", F::PIZZAZZ);
end
endmodule endmodule
...@@ -25,4 +25,20 @@ module top; ...@@ -25,4 +25,20 @@ module top;
$display("%d", E_pack(0)); $display("%d", E_pack(0));
$display("%d", E_pack(1)); $display("%d", E_pack(1));
end end
initial begin
$display("imported MAGIC %d", -42);
$display("imported MAGIC %d", -42);
$display("local MAGIC %d", +42);
$display("imported MAGIC %d", -42);
$display("imported MAGIC %d", -42);
$display("imported MAGIC %d", -42);
end
initial begin
$display("local PIZZAZZ %d", -6);
$display("imported PIZZAZZ %d", -5);
$display("shadowed local PIZZAZZ %d", -7);
$display("imported PIZZAZZ %d", -5);
$display("local PIZZAZZ %d", -6);
$display("imported PIZZAZZ %d", -5);
end
endmodule 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