Commit 8eb3a251 by Zachary Snow

package conversion overhaul

- full import and export support
- simplify AST representation of import and export
- allow package-scoped identifiers invoked as subroutines
- use scoped name resolution for identifiers in packages
- merge package item nesting conversion into package conversion
- fix handling of colliding enum items in separate modules
- fix visiting enum item exprs in types
parent 40df9028
...@@ -102,8 +102,9 @@ Other: ...@@ -102,8 +102,9 @@ Other:
## Supported Features ## Supported Features
sv2v supports most synthesizable SystemVerilog features. Current notable sv2v supports most synthesizable SystemVerilog features. Current notable
exceptions include `export` and interface arrays. Assertions are also supported, exceptions include `defparam` on interface instances and references to typedefs
but are simply dropped during conversion. within interface instances. Assertions are also supported, but are simply
dropped during conversion.
If you find a bug or have a feature request, please create an issue. Preference If you find a bug or have a feature request, please create an issue. Preference
will be given to issues which include examples or test cases. will be given to issues which include examples or test cases.
......
...@@ -31,7 +31,6 @@ import qualified Convert.Logic ...@@ -31,7 +31,6 @@ import qualified Convert.Logic
import qualified Convert.LogOp import qualified Convert.LogOp
import qualified Convert.MultiplePacked import qualified Convert.MultiplePacked
import qualified Convert.NamedBlock import qualified Convert.NamedBlock
import qualified Convert.NestPI
import qualified Convert.Package import qualified Convert.Package
import qualified Convert.ParamNoDefault import qualified Convert.ParamNoDefault
import qualified Convert.ParamType import qualified Convert.ParamType
...@@ -86,9 +85,7 @@ phases excludes = ...@@ -86,9 +85,7 @@ phases excludes =
, Convert.Unsigned.convert , Convert.Unsigned.convert
, Convert.SignCast.convert , Convert.SignCast.convert
, Convert.Wildcard.convert , Convert.Wildcard.convert
, Convert.Package.convert
, Convert.Enum.convert , Convert.Enum.convert
, Convert.NestPI.convert
, Convert.ForDecl.convert , Convert.ForDecl.convert
, Convert.Jump.convert , Convert.Jump.convert
, Convert.Foreach.convert , Convert.Foreach.convert
...@@ -111,7 +108,7 @@ run excludes = foldr (.) id $ phases excludes ...@@ -111,7 +108,7 @@ run excludes = foldr (.) id $ phases excludes
convert :: [Job.Exclude] -> Phase convert :: [Job.Exclude] -> Phase
convert excludes = convert excludes =
convert' convert'
. Convert.NestPI.reorder . Convert.Package.convert
. Convert.ParamNoDefault.convert . Convert.ParamNoDefault.convert
where where
convert' :: Phase convert' :: Phase
......
...@@ -3,10 +3,11 @@ ...@@ -3,10 +3,11 @@
- -
- Conversion for `enum` - Conversion for `enum`
- -
- This conversion replaces the enum items with localparams declared at the - This conversion replaces the enum items with localparams. The localparams are
- global scope. We leave it to the package item nesting conversion to determine - explicitly sized to match the size of the converted enum type. For packages
- where the generated localparams are needed. The localparams are explicitly - and enums used in the global scope, these localparams are inserted in place.
- sized to match the size of the converted enum type. - For enums used within a module or interface, the localparams are injected as
- needed using a nesting procedure from the package conversion.
- -
- SystemVerilog allows for enums to have any number of the items' values - SystemVerilog allows for enums to have any number of the items' values
- specified or unspecified. If the first one is unspecified, it is 0. All other - specified or unspecified. If the first one is unspecified, it is 0. All other
...@@ -24,6 +25,7 @@ import Data.List (elemIndices) ...@@ -24,6 +25,7 @@ import Data.List (elemIndices)
import qualified Data.Set as Set import qualified Data.Set as Set
import Convert.ExprUtils import Convert.ExprUtils
import Convert.Package (inject)
import Convert.Traverse import Convert.Traverse
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
...@@ -36,9 +38,14 @@ convert = map $ concatMap convertDescription ...@@ -36,9 +38,14 @@ convert = map $ concatMap convertDescription
convertDescription :: Description -> [Description] convertDescription :: Description -> [Description]
convertDescription (Package ml name items) = convertDescription (Package ml name items) =
[Package ml name $ concatMap convertPackageItem items] [Package ml name $ concatMap convertPackageItem items]
convertDescription description = convertDescription (description @ Part{}) =
(map PackageItem enumItems) ++ [description'] [Part attrs extern kw lifetime name ports items']
where (description', enumItems) = convertDescription' description where
items' = inject enumItems items -- only keep what's used
Part attrs extern kw lifetime name ports items = description'
(description', enumItems) = convertDescription' description
convertDescription (PackageItem item) =
map PackageItem $ convertPackageItem item
-- explode a package item with its corresponding enum items -- explode a package item with its corresponding enum items
convertPackageItem :: PackageItem -> [PackageItem] convertPackageItem :: PackageItem -> [PackageItem]
......
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
- Conversion for moving top-level package items into modules
-}
module Convert.NestPI (convert, reorder) where
import Control.Monad.Writer.Strict
import Data.Maybe (mapMaybe)
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
import Convert.Traverse
import Language.SystemVerilog.AST
type PIs = Map.Map Identifier PackageItem
type Idents = Set.Set Identifier
convert :: [AST] -> [AST]
convert =
map (filter (not . isPI)) . nest
where
nest :: [AST] -> [AST]
nest = traverseFiles
(collectDescriptionsM collectDescriptionM)
(traverseDescriptions . convertDescription)
isPI :: Description -> Bool
isPI (PackageItem Import{}) = False
isPI (PackageItem item) = piName item /= ""
isPI _ = False
reorder :: [AST] -> [AST]
reorder = map $ traverseDescriptions reorderDescription
-- collects packages items missing
collectDescriptionM :: Description -> Writer PIs ()
collectDescriptionM (PackageItem item) = do
case piName item of
"" -> return ()
ident -> tell $ Map.singleton ident item
collectDescriptionM _ = return ()
-- nests packages items missing from modules
convertDescription :: PIs -> Description -> Description
convertDescription pis (orig @ Part{}) =
if Map.null pis
then orig
else Part attrs extern kw lifetime name ports items'
where
Part attrs extern kw lifetime name ports items = orig
items' = addItems pis Set.empty (map addUsedPIs items)
convertDescription _ other = other
-- attempt to fix simple declaration order issues
reorderDescription :: Description -> Description
reorderDescription (Part attrs extern kw lifetime name ports items) =
Part attrs extern kw lifetime name ports items'
where
items' = addItems localPIs Set.empty (map addUsedPIs items)
localPIs = Map.fromList $ mapMaybe toPIElem items
toPIElem :: ModuleItem -> Maybe (Identifier, PackageItem)
toPIElem (MIPackageItem item) = Just (piName item, item)
toPIElem _ = Nothing
reorderDescription other = other
-- iteratively inserts missing package items exactly where they are needed
addItems :: PIs -> Idents -> [(ModuleItem, Idents)] -> [ModuleItem]
addItems pis existingPIs ((item, usedPIs) : items) =
if not $ Set.disjoint existingPIs thisPI then
-- this item was re-imported earlier in the module
addItems pis existingPIs items
else if null itemsToAdd then
-- this item has no additional dependencies
item : addItems pis (Set.union existingPIs thisPI) items
else
-- this item has at least one un-met dependency
addItems pis existingPIs (addUsedPIs chosen : (item, usedPIs) : items)
where
thisPI = execWriter $ collectPIsM item
neededPIs = Set.difference (Set.difference usedPIs existingPIs) thisPI
itemsToAdd = map MIPackageItem $ Map.elems $
Map.restrictKeys pis neededPIs
chosen = head itemsToAdd
addItems _ _ [] = []
-- augment a module item with the set of identifiers it uses
addUsedPIs :: ModuleItem -> (ModuleItem, Idents)
addUsedPIs item =
(item, usedPIs)
where
usedPIs = execWriter $
traverseNestedModuleItemsM (traverseIdentsM writeIdent) item
writeIdent :: Identifier -> Writer Idents Identifier
writeIdent x = tell (Set.singleton x) >> return x
-- writes down the names of package items
collectPIsM :: ModuleItem -> Writer Idents ()
collectPIsM (MIPackageItem item) =
case piName item of
"" -> return ()
ident -> tell $ Set.singleton ident
collectPIsM _ = return ()
-- visits all identifiers in a module item
traverseIdentsM :: Monad m => MapperM m Identifier -> MapperM m ModuleItem
traverseIdentsM identMapper = traverseNodesM
(traverseExprIdentsM identMapper)
(traverseDeclIdentsM identMapper)
(traverseTypeIdentsM identMapper)
(traverseLHSIdentsM identMapper)
(traverseStmtIdentsM identMapper)
-- visits all identifiers in an expression
traverseExprIdentsM :: Monad m => MapperM m Identifier -> MapperM m Expr
traverseExprIdentsM identMapper = fullMapper
where
fullMapper = exprMapper >=> traverseSinglyNestedExprsM fullMapper
exprMapper (Call (Ident x) args) =
identMapper x >>= \x' -> return $ Call (Ident x') args
exprMapper (Ident x) = identMapper x >>= return . Ident
exprMapper other = return other
-- visits all identifiers in a type
traverseTypeIdentsM :: Monad m => MapperM m Identifier -> MapperM m Type
traverseTypeIdentsM identMapper = fullMapper
where
fullMapper = typeMapper
>=> traverseTypeExprsM (traverseExprIdentsM identMapper)
>=> traverseSinglyNestedTypesM fullMapper
typeMapper (Alias x t) = aliasHelper (Alias ) x t
typeMapper (PSAlias p x t) = aliasHelper (PSAlias p ) x t
typeMapper (CSAlias c p x t) = aliasHelper (CSAlias c p) x t
typeMapper other = return other
aliasHelper constructor x t =
identMapper x >>= \x' -> return $ constructor x' t
-- visits all identifiers in an LHS
traverseLHSIdentsM :: Monad m => MapperM m Identifier -> MapperM m LHS
traverseLHSIdentsM identMapper = fullMapper
where
fullMapper = lhsMapper
>=> traverseLHSExprsM (traverseExprIdentsM identMapper)
>=> traverseSinglyNestedLHSsM fullMapper
lhsMapper (LHSIdent x) = identMapper x >>= return . LHSIdent
lhsMapper other = return other
-- visits all identifiers in a statement
traverseStmtIdentsM :: Monad m => MapperM m Identifier -> MapperM m Stmt
traverseStmtIdentsM identMapper = fullMapper
where
fullMapper = stmtMapper
>=> traverseStmtExprsM (traverseExprIdentsM identMapper)
>=> traverseStmtLHSsM (traverseLHSIdentsM identMapper)
>=> traverseSinglyNestedStmtsM fullMapper
stmtMapper (Subroutine (Ident x) args) =
identMapper x >>= \x' -> return $ Subroutine (Ident x') args
stmtMapper other = return other
-- visits all identifiers in a declaration
traverseDeclIdentsM :: Monad m => MapperM m Identifier -> MapperM m Decl
traverseDeclIdentsM identMapper =
traverseDeclExprsM (traverseExprIdentsM identMapper) >=>
traverseDeclTypesM (traverseTypeIdentsM identMapper)
-- returns the "name" of a package item, if it has one
piName :: PackageItem -> Identifier
piName (Function _ _ ident _ _) = ident
piName (Task _ ident _ _) = ident
piName (Typedef _ ident ) = ident
piName (Decl (Variable _ _ ident _ _)) = ident
piName (Decl (Param _ _ ident _)) = ident
piName (Decl (ParamType _ ident _)) = ident
piName (Decl (CommentDecl _)) = ""
piName (Import x y) = show $ Import x y
piName (Export _) = ""
piName (Directive _) = ""
...@@ -27,6 +27,7 @@ module Convert.Scoper ...@@ -27,6 +27,7 @@ module Convert.Scoper
, ScoperT , ScoperT
, evalScoper , evalScoper
, evalScoperT , evalScoperT
, runScoperT
, partScoper , partScoper
, partScoperT , partScoperT
, insertElem , insertElem
...@@ -36,9 +37,12 @@ module Convert.Scoper ...@@ -36,9 +37,12 @@ module Convert.Scoper
, Access(..) , Access(..)
, ScopeKey , ScopeKey
, Scopes , Scopes
, extractMapping
, embedScopes , embedScopes
, withinProcedure , withinProcedure
, withinProcedureM , withinProcedureM
, lookupLocalIdent
, lookupLocalIdentM
, scopeModuleItemT , scopeModuleItemT
, Replacements , Replacements
) where ) where
...@@ -82,6 +86,12 @@ data Scopes a = Scopes ...@@ -82,6 +86,12 @@ data Scopes a = Scopes
, sInjected :: [ModuleItem] , sInjected :: [ModuleItem]
} deriving Show } deriving Show
extractMapping :: Scopes a -> Map.Map Identifier a
extractMapping =
Map.mapMaybe eElement .
eMapping . snd .
Map.findMin . sMapping
embedScopes :: Monad m => (Scopes a -> b -> c) -> b -> ScoperT a m c embedScopes :: Monad m => (Scopes a -> b -> c) -> b -> ScoperT a m c
embedScopes func x = do embedScopes func x = do
scopes <- get scopes <- get
...@@ -142,13 +152,26 @@ exprToAccesses (Dot e x) = do ...@@ -142,13 +152,26 @@ exprToAccesses (Dot e x) = do
Just $ accesses ++ [Access x Nil] Just $ accesses ++ [Access x Nil]
exprToAccesses _ = Nothing exprToAccesses _ = Nothing
insertElem :: Monad m => Identifier -> a -> ScoperT a m () class ScopePath k where
insertElem name element = do toTiers :: Scopes a -> k -> [Tier]
instance ScopePath Identifier where
toTiers scopes name = sCurrent scopes ++ [Tier name ""]
instance ScopePath [Access] where
toTiers _ = map toTier
where
toTier :: Access -> Tier
toTier (Access x Nil) = Tier x ""
toTier (Access x iy) = Tier x y
where Ident y = iy
insertElem :: Monad m => ScopePath k => k -> a -> ScoperT a m ()
insertElem key element = do
s <- get s <- get
let current = sCurrent s
let mapping = sMapping s let mapping = sMapping s
let entry = Entry (Just element) "" Map.empty let entry = Entry (Just element) "" Map.empty
let mapping' = setScope (current ++ [Tier name ""]) entry mapping let mapping' = setScope (toTiers s key) entry mapping
put $ s { sMapping = mapping' } put $ s { sMapping = mapping' }
injectItem :: Monad m => ModuleItem -> ScoperT a m () injectItem :: Monad m => ModuleItem -> ScoperT a m ()
...@@ -218,6 +241,19 @@ lookupAccesses scopes accesses = do ...@@ -218,6 +241,19 @@ lookupAccesses scopes accesses = do
let side = resolveInScope (sMapping scopes) [] accesses let side = resolveInScope (sMapping scopes) [] accesses
if isNothing deep then side else deep if isNothing deep then side else deep
lookupLocalIdent :: Scopes a -> Identifier -> LookupResult a
lookupLocalIdent scopes ident = do
(replacements, element) <- directResolve (sMapping scopes) accesses
Just (accesses, replacements, element)
where
accesses = map toAccess (sCurrent scopes) ++ [Access ident Nil]
toAccess :: Tier -> Access
toAccess (Tier x "") = Access x Nil
toAccess (Tier x y) = Access x (Ident y)
lookupLocalIdentM :: Monad m => Identifier -> ScoperT a m (LookupResult a)
lookupLocalIdentM = embedScopes lookupLocalIdent
withinProcedureM :: Monad m => ScoperT a m Bool withinProcedureM :: Monad m => ScoperT a m Bool
withinProcedureM = gets sProcedure withinProcedureM = gets sProcedure
...@@ -245,8 +281,23 @@ evalScoperT ...@@ -245,8 +281,23 @@ evalScoperT
-> Identifier -> Identifier
-> [ModuleItem] -> [ModuleItem]
-> m [ModuleItem] -> m [ModuleItem]
evalScoperT declMapper moduleItemMapper genItemMapper stmtMapper topName items = evalScoperT declMapper moduleItemMapper genItemMapper stmtMapper topName items = do
evalStateT operation initialState (items', _) <- runScoperT
declMapper moduleItemMapper genItemMapper stmtMapper
topName items
return items'
runScoperT
:: forall a m. Monad m
=> MapperM (ScoperT a m) Decl
-> MapperM (ScoperT a m) ModuleItem
-> MapperM (ScoperT a m) GenItem
-> MapperM (ScoperT a m) Stmt
-> Identifier
-> [ModuleItem]
-> m ([ModuleItem], Scopes a)
runScoperT declMapper moduleItemMapper genItemMapper stmtMapper topName items =
runStateT operation initialState
where where
operation :: ScoperT a m [ModuleItem] operation :: ScoperT a m [ModuleItem]
operation = do operation = do
......
...@@ -613,8 +613,8 @@ traverseNodesM exprMapper declMapper typeMapper lhsMapper stmtMapper = ...@@ -613,8 +613,8 @@ traverseNodesM exprMapper declMapper typeMapper lhsMapper stmtMapper =
return $ MIPackageItem $ Directive c return $ MIPackageItem $ Directive 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)) = moduleItemMapper (MIPackageItem (Export x y)) =
return $ MIPackageItem $ Export x return $ MIPackageItem $ Export x y
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'
...@@ -864,6 +864,11 @@ traverseTypeExprsM exprMapper = ...@@ -864,6 +864,11 @@ traverseTypeExprsM exprMapper =
let pm' = zip (map fst pm) vals' let pm' = zip (map fst pm) vals'
rs' <- mapM (mapBothM exprMapper) rs rs' <- mapM (mapBothM exprMapper) rs
return $ CSAlias ps pm' xx rs' return $ CSAlias ps pm' xx rs'
typeMapper (Enum t enumItems rs) = do
enumItems' <- mapM enumItemMapper enumItems
rs' <- mapM (mapBothM exprMapper) rs
return $ Enum t enumItems' rs'
where enumItemMapper (x, e) = exprMapper e >>= \e' -> return (x, e')
typeMapper t = do typeMapper t = do
let (tf, rs) = typeRanges t let (tf, rs) = typeRanges t
rs' <- mapM (mapBothM exprMapper) rs rs' <- mapM (mapBothM exprMapper) rs
......
...@@ -12,7 +12,6 @@ module Language.SystemVerilog.AST.Description ...@@ -12,7 +12,6 @@ module Language.SystemVerilog.AST.Description
, Lifetime (..) , Lifetime (..)
) where ) where
import Data.Maybe (fromMaybe)
import Text.Printf (printf) import Text.Printf (printf)
import Language.SystemVerilog.AST.ShowHelp import Language.SystemVerilog.AST.ShowHelp
...@@ -56,8 +55,8 @@ data PackageItem ...@@ -56,8 +55,8 @@ data PackageItem
= Typedef Type Identifier = Typedef Type Identifier
| Function Lifetime Type Identifier [Decl] [Stmt] | Function Lifetime Type Identifier [Decl] [Stmt]
| Task Lifetime Identifier [Decl] [Stmt] | Task Lifetime Identifier [Decl] [Stmt]
| Import Identifier (Maybe Identifier) | Import Identifier Identifier
| Export (Maybe (Identifier, Maybe Identifier)) | Export Identifier Identifier
| Decl Decl | Decl Decl
| Directive String | Directive String
deriving Eq deriving Eq
...@@ -70,12 +69,15 @@ instance Show PackageItem where ...@@ -70,12 +69,15 @@ instance Show PackageItem where
show (Task ml x i b) = show (Task ml x i b) =
printf "task %s%s;\n%s\nendtask" printf "task %s%s;\n%s\nendtask"
(showPad ml) x (showBlock i b) (showPad ml) x (showBlock i b)
show (Import x y) = printf "import %s::%s;" x (fromMaybe "*" y) show (Import x y) = printf "import %s::%s;" x (showWildcard y)
show (Export Nothing) = "export *::*"; show (Export x y) = printf "export %s::%s;" (showWildcard x) (showWildcard y)
show (Export (Just (x, y))) = printf "export %s::%s;" x (fromMaybe "*" y)
show (Decl decl) = show decl show (Decl decl) = show decl
show (Directive str) = str show (Directive str) = str
showWildcard :: Identifier -> String
showWildcard "" = "*"
showWildcard x = x
data PartKW data PartKW
= Module = Module
| Interface | Interface
......
...@@ -843,8 +843,8 @@ NonDeclPackageItem :: { [PackageItem] } ...@@ -843,8 +843,8 @@ NonDeclPackageItem :: { [PackageItem] }
| "function" Lifetime "void" Identifier TFItems DeclsAndStmts "endfunction" opt(Tag) { [Task $2 $4 (map defaultFuncInput $ $5 ++ fst $6) (snd $6)] } | "function" Lifetime "void" Identifier TFItems DeclsAndStmts "endfunction" opt(Tag) { [Task $2 $4 (map defaultFuncInput $ $5 ++ fst $6) (snd $6)] }
| "task" Lifetime Identifier TFItems DeclsAndStmts "endtask" opt(Tag) { [Task $2 $3 (map defaultFuncInput $ $4 ++ fst $5) (snd $5)] } | "task" 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" PackageImportItems ";" { map (uncurry Export) $2 }
| "export" "*" "::" "*" ";" { [Export Nothing] } -- "Nothing" being no restrictions | "export" "*" "::" "*" ";" { [Export "" ""] }
| ForwardTypedef ";" { $1 } | ForwardTypedef ";" { $1 }
| TimeunitsDeclaration { $1 } | TimeunitsDeclaration { $1 }
| Directive { [Directive $1] } | Directive { [Directive $1] }
...@@ -872,12 +872,12 @@ DefaultNetType :: { String } ...@@ -872,12 +872,12 @@ DefaultNetType :: { String }
: NetType { show $1 } : NetType { show $1 }
| Identifier { $1 } | Identifier { $1 }
PackageImportItems :: { [(Identifier, Maybe Identifier)] } PackageImportItems :: { [(Identifier, Identifier)] }
: PackageImportItem { [$1] } : PackageImportItem { [$1] }
| PackageImportItems "," PackageImportItem { $1 ++ [$3] } | PackageImportItems "," PackageImportItem { $1 ++ [$3] }
PackageImportItem :: { (Identifier, Maybe Identifier) } PackageImportItem :: { (Identifier, Identifier) }
: Identifier "::" Identifier { ($1, Just $3) } : Identifier "::" Identifier { ($1, $3) }
| Identifier "::" "*" { ($1, Nothing) } | Identifier "::" "*" { ($1, "") }
FuncRetAndName :: { (Type, Identifier) } FuncRetAndName :: { (Type, Identifier) }
: Type Identifier { ($1 , $2) } : Type Identifier { ($1 , $2) }
...@@ -987,6 +987,8 @@ StmtAsgn :: { Stmt } ...@@ -987,6 +987,8 @@ StmtAsgn :: { Stmt }
| IncOrDecOperator LHS ";" { Asgn (AsgnOp $1) Nothing $2 (RawNum 1) } | IncOrDecOperator LHS ";" { Asgn (AsgnOp $1) Nothing $2 (RawNum 1) }
| LHS ";" { Subroutine (lhsToExpr $1) (Args [] []) } | LHS ";" { Subroutine (lhsToExpr $1) (Args [] []) }
| LHS CallArgs ";" { Subroutine (lhsToExpr $1) $2 } | LHS CallArgs ";" { Subroutine (lhsToExpr $1) $2 }
| Identifier "::" Identifier ";" { Subroutine (PSIdent $1 $3) (Args [] []) }
| Identifier "::" Identifier CallArgs ";" { Subroutine (PSIdent $1 $3) $4 }
StmtNonAsgn :: { Stmt } StmtNonAsgn :: { Stmt }
: StmtBlock(BlockKWSeq, "end" ) { $1 } : StmtBlock(BlockKWSeq, "end" ) { $1 }
| StmtBlock(BlockKWPar, "join") { $1 } | StmtBlock(BlockKWPar, "join") { $1 }
......
...@@ -81,7 +81,6 @@ executable sv2v ...@@ -81,7 +81,6 @@ executable sv2v
Convert.LogOp Convert.LogOp
Convert.MultiplePacked Convert.MultiplePacked
Convert.NamedBlock Convert.NamedBlock
Convert.NestPI
Convert.Package Convert.Package
Convert.ParamNoDefault Convert.ParamNoDefault
Convert.ParamType Convert.ParamType
......
module ExampleA;
typedef enum logic {
A = 1,
B = 0,
C = 2
} Enum;
Enum x = A;
initial $display("ExampleA: x=%b, A=%b, B=%b", x, A, B);
endmodule
module ExampleB;
typedef enum logic {
A = 0,
B = 1
} Enum;
Enum x = A;
initial $display("ExampleB: x=%b, A=%b, B=%b", x, A, B);
endmodule
module ExampleA;
localparam [0:0] A = 1;
localparam [0:0] B = 0;
reg x = A;
initial $display("ExampleA: x=%b, A=%b, B=%b", x, A, B);
endmodule
module ExampleB;
localparam [0:0] A = 0;
localparam [0:0] B = 1;
reg x = A;
initial $display("ExampleB: x=%b, A=%b, B=%b", x, A, B);
endmodule
module top;
ExampleA a();
ExampleB b();
endmodule
package Q;
localparam W = 5;
localparam unrelated = 1;
endpackage
package P;
import Q::*;
export Q::W;
endpackage
module Example
import P::*;
(
input logic [W - 1:0] inp
);
import Q::unrelated;
initial $display("%b %0d %0d", inp, $bits(inp), unrelated);
endmodule
module Example(inp);
localparam W = 5;
localparam unrelated = 1;
input wire [W - 1:0] inp;
initial $display("%b %0d %0d", inp, $bits(inp), unrelated);
endmodule
module top;
Example e(5'b00000);
endmodule
package Pkg;
localparam integer X = func(1);
function automatic integer func;
input integer inp;
func = inp * 2;
endfunction
endpackage
module top;
initial $display(Pkg::X);
endmodule
module top;
function automatic integer func;
input integer inp;
func = inp * 2;
endfunction
localparam integer X = func(1);
initial $display(X);
endmodule
package P;
localparam X = 1;
localparam Y = 2;
typedef enum {
A = X,
B = Y
} Enum;
endpackage
module top;
import P::*;
initial $display("%0d %0d %0d", X, A, B);
endmodule
module top;
localparam X = 1;
localparam Y = 2;
localparam A = X;
localparam B = Y;
initial $display("%0d %0d %0d", X, A, B);
endmodule
package PkgA;
localparam Foo = 1;
endpackage
package PkgB;
export PkgA::*;
localparam Bar = 2;
endpackage
module top;
initial $display(PkgB::Bar);
endmodule
module top;
localparam Bar = 2;
initial $display(Bar);
endmodule
package P;
localparam X = 1;
endpackage
package Q;
import P::X;
export P::*;
localparam Y = 2;
endpackage
package R;
import Q::X;
export Q::*;
localparam Z = 3;
endpackage
package S;
import P::X;
import Q::Y;
import R::Z;
export *::*;
endpackage
module top;
import S::*;
initial $display(X, Y, Z);
endmodule
module top;
localparam X = 1;
localparam Y = 2;
localparam Z = 3;
initial $display(X, Y, Z);
endmodule
package PkgA;
localparam X = 1;
localparam Y = 2;
endpackage
package PkgB;
localparam X = 3;
localparam Z = 4;
endpackage
import PkgA::*;
import PkgB::*;
localparam X = 5;
module top;
initial $display(X, Y, Z);
endmodule
module top;
localparam X = 5;
localparam Y = 2;
localparam Z = 4;
initial $display(X, Y, Z);
endmodule
`define DUMP(key) initial $display(`"key %0d`", X);
package P;
localparam X = 1;
endpackage
package Q;
localparam X = 2;
endpackage
module ExampleA;
import P::*;
localparam X = 3;
`DUMP(A)
endmodule
module ExampleB;
localparam X = 3;
import P::*;
`DUMP(B)
endmodule
module ExampleC;
import P::*;
`DUMP(C)
endmodule
module ExampleD;
import Q::*;
`DUMP(D)
endmodule
module ExampleE;
import P::*;
import Q::X;
`DUMP(E)
endmodule
module ExampleF;
import Q::X;
import P::*;
`DUMP(F)
endmodule
module ExampleG;
import P::*;
import Q::*;
// allowed but can't reference C
endmodule
package R;
import P::X;
export P::X;
endpackage
package S;
import P::X;
export R::X; // oof but it's allowed
endpackage
module ExampleH;
import R::*;
import S::*;
`DUMP(H)
endmodule
module ExampleI;
import R::X;
import S::X;
`DUMP(I)
endmodule
module ExampleJ;
import R::*;
`DUMP(J)
import S::X;
endmodule
module ExampleK;
import P::X;
if (1) begin : blk1
import P::X;
`DUMP(K1)
end
if (1) begin : blk2
import Q::X;
`DUMP(K2)
end
if (1) begin : blk3
localparam X = 3;
`DUMP(K3)
end
if (1) begin : blk4
import Q::*;
`DUMP(K4)
end
`DUMP(K0)
endmodule
module ExampleL;
import P::X;
import R::X;
`DUMP(L)
endmodule
package T;
import P::X;
export P::*;
endpackage
package U;
import P::*;
export P::X;
endpackage
package V;
import P::*;
export P::*;
localparam Y = X;
endpackage
package W;
import P::*;
export P::*;
task help;
$display("W::help() %0d", X);
endtask
endpackage
module ExampleM;
if (1) begin : blk1
import T::X;
`DUMP(M1)
end
if (1) begin : blk2
import U::X;
`DUMP(M2)
end
if (1) begin : blk3
import V::X;
`DUMP(M3)
end
if (1) begin : blk4
import W::X;
`DUMP(M4)
initial W::help;
initial W::help();
end
endmodule
module ExampleN;
import P::*;
if (1) begin : blk1
import P::X;
`DUMP(N1)
end
import Q::X;
`DUMP(N2)
endmodule
module ExampleO;
import P::*;
if (1) begin : blk1
import P::*;
`DUMP(O1)
end
import Q::X;
`DUMP(O2)
endmodule
module top;
endmodule
module top;
initial begin
$display("A 3");
$display("B 3");
$display("C 1");
$display("D 2");
$display("E 2");
$display("F 2");
// G doesn't print
$display("H 1");
$display("I 1");
$display("J 1");
$display("K1 1");
$display("K2 2");
$display("K3 3");
$display("K4 2");
$display("K0 1");
$display("L 1");
$display("M1 1");
$display("M2 1");
$display("M3 1");
$display("M4 1");
$display("W::help() 1");
$display("W::help() 1");
$display("N1 1");
$display("N2 2");
$display("O1 1");
$display("O2 2");
end
endmodule
// pattern: invalid export Pkg::Foo outside of package
package Pkg;
localparam Foo = 1;
endpackage
import Pkg::Foo;
export Pkg::Foo;
module top;
initial $display(Foo);
endmodule
// pattern: invalid export Pkg::Foo outside of package
package Pkg;
localparam Foo = 1;
endpackage
module top;
import Pkg::Foo;
export Pkg::Foo;
initial $display(Foo);
endmodule
// pattern: invalid export \*::\* outside of package
package Pkg;
localparam Foo = 1;
endpackage
import Pkg::Foo;
export *::*;
module top;
initial $display(Foo);
endmodule
// pattern: could not find package "PackageThatDoesNotExist"
module top;
import PackageThatDoesNotExist::*;
endmodule
// pattern: could not find "ItemThatDoesNotExist" in package "Pkg"
package Pkg;
localparam Foo = 1;
endpackage
module top;
import Pkg::ItemThatDoesNotExist;
endmodule
// pattern: could not find "X" in package "Q"
package P;
localparam X = 1;
endpackage
package Q;
import P::*;
export P::*;
localparam Y = P::X;
endpackage
module top;
initial $display(Q::X);
endmodule
// pattern: could not find "X" in package "Q"
package P;
localparam X = 1;
localparam Y = 2;
endpackage
package Q;
import P::*;
export *::*;
localparam Z = P::Y;
endpackage
module top;
initial $display(Q::X);
endmodule
// pattern: export of PkgA::Bar, but Bar was never imported
package PkgA;
localparam Bar = 2;
endpackage
package PkgB;
export PkgA::Bar;
localparam Foo = 1;
endpackage
module top;
initial $display(PkgB::Foo);
endmodule
// pattern: export of Bar::Foo differs from import of Foo::Foo
package Bar;
localparam Bar = 1;
localparam Foo = 3;
endpackage
package Foo;
localparam Foo = 2;
endpackage
package Pkg;
import Foo::Foo;
import Bar::Bar;
export Bar::Foo;
endpackage
module top;
initial $display(Pkg::Foo);
endmodule
// pattern: could not find "Foo" in package "Bar"
package Bar;
localparam Bar = 1;
endpackage
package Pkg;
import Bar::*;
export Bar::Foo;
endpackage
module top;
initial $display(Pkg::Foo);
endmodule
// pattern: could not find package "PackageThatDoesNotExist"
package Wrap;
import PackageThatDoesNotExist::*;
localparam Foo = Bar;
endpackage
module top;
import Wrap::*;
endmodule
// pattern: could not find "ItemThatDoesNotExist" in package "Pkg"
package Pkg;
localparam Foo = 1;
endpackage
package Wrap;
localparam Foo = Pkg::ItemThatDoesNotExist;
endpackage
module top;
import Wrap::*;
endmodule
// pattern: package dependency loop: "PkgA" depends on "PkgB", which depends on "PkgA"
package PkgA;
import PkgB::Foo;
export PkgB::Foo;
endpackage
package PkgB;
import PkgA::Foo;
export PkgA::Foo;
endpackage
module top;
initial $display(PkgA::Foo);
endmodule
// pattern: package dependency loop: "PkgA" depends on "PkgC", which depends on "PkgB", which depends on "PkgA"
package PkgA;
import PkgC::Foo;
export PkgC::Foo;
endpackage
package PkgB;
import PkgA::Foo;
export PkgA::Foo;
endpackage
package PkgC;
import PkgB::Foo;
export PkgB::Foo;
endpackage
module top;
initial $display(PkgA::Foo);
endmodule
// pattern: identifier "X" ambiguously refers to the definitions in any of P, Q
package P;
localparam X = 1;
endpackage
package Q;
localparam X = 2;
endpackage
module top;
import P::*;
import Q::*;
initial $display(X);
endmodule
// pattern: import of Q::X conflicts with prior import of P::X
package P;
localparam X = 1;
endpackage
package Q;
localparam X = 2;
endpackage
module top;
import P::X;
import Q::X;
endmodule
// pattern: declaration of X conflicts with prior import of P::X
package P;
localparam X = 1;
endpackage
module top;
import P::X;
localparam X = 2;
endmodule
// pattern: import of P::X conflicts with prior declaration of X
package P;
localparam X = 1;
endpackage
module top;
localparam X = 2;
import P::X;
endmodule
// pattern: import of P::X conflicts with prior import of Q::X
package P;
localparam X = 1;
endpackage
package Q;
localparam X = 2;
endpackage
module top;
import Q::*;
initial $display(X); // imports Q::X
import P::X; // illegal
endmodule
// pattern: import of Q::X conflicts with prior import of P::X
package P;
localparam X = 1;
endpackage
package Q;
localparam X = 2;
endpackage
package W;
import P::*;
export P::*;
task help;
$display("W::help() %0d", X);
endtask
import Q::X;
endpackage
module top;
import W::*;
initial $display(X);
endmodule
// pattern: import of Q::X conflicts with prior import of P::X
package P;
localparam X = 1;
endpackage
package Q;
localparam X = 2;
endpackage
module top;
import P::*;
if (1) begin : blk1
// forces import of P::X at the top level
initial $display(X);
end
import Q::X; // illegal
endmodule
// pattern: identifier "X" ambiguously refers to the definitions in any of PkgA, PkgB
package PkgA;
localparam X = 1;
endpackage
package PkgB;
localparam X = 3;
endpackage
import PkgA::*;
import PkgB::*;
module top;
initial $display(X);
endmodule
// pattern: package dependency loop: "Pkg" depends on "Pkg"
package Pkg;
localparam Foo = 1;
export Pkg::Foo;
endpackage
module top;
initial $display(Pkg::Foo);
endmodule
// pattern: package dependency loop: "P" depends on "P"
package P;
import P::*;
localparam Foo = 1;
endpackage
module top;
import P::*;
initial $display(Foo);
endmodule
// pattern: package dependency loop: "P" depends on "P"
package P;
localparam Foo = P::Foo;
endpackage
module top;
import P::*;
initial $display(Foo);
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