conversion to create declarations for implicit nets

This commit is contained in:
Zachary Snow 2020-09-13 23:27:22 -04:00
parent eb908b8db7
commit 7e2450ea5e
5 changed files with 192 additions and 0 deletions

View File

@ -21,6 +21,7 @@ import qualified Convert.ForDecl
import qualified Convert.Foreach import qualified Convert.Foreach
import qualified Convert.FuncRet import qualified Convert.FuncRet
import qualified Convert.FuncRoutine import qualified Convert.FuncRoutine
import qualified Convert.ImplicitNet
import qualified Convert.Inside import qualified Convert.Inside
import qualified Convert.Interface import qualified Convert.Interface
import qualified Convert.IntTypes import qualified Convert.IntTypes
@ -63,6 +64,7 @@ phases excludes =
, Convert.FuncRet.convert , Convert.FuncRet.convert
, Convert.FuncRoutine.convert , Convert.FuncRoutine.convert
, Convert.EmptyArgs.convert , Convert.EmptyArgs.convert
, Convert.ImplicitNet.convert
, Convert.Inside.convert , Convert.Inside.convert
, Convert.IntTypes.convert , Convert.IntTypes.convert
, Convert.KWArgs.convert , Convert.KWArgs.convert

107
src/Convert/ImplicitNet.hs Normal file
View File

@ -0,0 +1,107 @@
{-# LANGUAGE PatternSynonyms #-}
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
- Create declarations for implicit nets
-}
module Convert.ImplicitNet (convert) where
import Control.Monad (when)
import Data.List (isPrefixOf, mapAccumL)
import Convert.Scoper
import Language.SystemVerilog.AST
type DefaultNetType = Maybe NetType
convert :: [AST] -> [AST]
convert =
snd . mapAccumL
(mapAccumL traverseDescription)
(Just TWire)
traverseDescription :: DefaultNetType -> Description
-> (DefaultNetType, Description)
traverseDescription defaultNetType (PackageItem (Directive str)) =
(defaultNetType', PackageItem $ Directive str)
where
prefix = "`default_nettype "
defaultNetType' =
if isPrefixOf prefix str
then parseDefaultNetType $ drop (length prefix) str
else defaultNetType
traverseDescription defaultNetType (part @ Part{}) =
(defaultNetType, partScoper traverseDeclM
(traverseModuleItemM defaultNetType)
return return part)
traverseDescription defaultNetType other = (defaultNetType, other)
traverseDeclM :: Decl -> Scoper () Decl
traverseDeclM decl = do
case decl of
Variable _ t x _ _ -> when (t /= unknownType) $ insertElem x ()
Param _ _ x _ -> insertElem x ()
ParamType{} -> return ()
CommentDecl{} -> return ()
return decl
where unknownType = Implicit Unspecified []
traverseModuleItemM :: DefaultNetType -> ModuleItem -> Scoper () ModuleItem
traverseModuleItemM _ (Genvar x) =
insertElem x () >> return (Genvar x)
traverseModuleItemM defaultNetType (orig @ (Assign _ x _)) = do
needsLHS defaultNetType x
return orig
traverseModuleItemM defaultNetType (orig @ (NInputGate _ _ x lhs exprs)) = do
insertElem x ()
needsLHS defaultNetType lhs
_ <- mapM (needsExpr defaultNetType) exprs
return orig
traverseModuleItemM defaultNetType (orig @ (NOutputGate _ _ x lhss expr)) = do
insertElem x ()
_ <- mapM (needsLHS defaultNetType) lhss
needsExpr defaultNetType expr
return orig
traverseModuleItemM defaultNetType (orig @ (Instance _ _ _ _ ports)) = do
_ <- mapM (needsExpr defaultNetType . snd) ports
return orig
traverseModuleItemM _ item = return item
needsExpr :: DefaultNetType -> Expr -> Scoper () ()
needsExpr defaultNetType (Ident x) = needsIdent defaultNetType x
needsExpr _ _ = return ()
needsLHS :: DefaultNetType -> LHS -> Scoper () ()
needsLHS defaultNetType (LHSIdent x) = needsIdent defaultNetType x
needsLHS _ _ = return ()
needsIdent :: DefaultNetType -> Identifier -> Scoper () ()
needsIdent defaultNetType x = do
details <- lookupElemM x
when (details == Nothing) $ do
insertElem x ()
injectItem decl
where
t = impliedNetType x defaultNetType Unspecified []
decl = MIPackageItem $ Decl $ Variable Local t x [] Nil
impliedNetType :: String -> DefaultNetType -> Signing -> [Range] -> Type
impliedNetType var Nothing =
error $ "implicit declaration of " ++
show var ++ " but default_nettype is none"
impliedNetType _ (Just netType) = Net (NetType netType)
parseDefaultNetType :: String -> DefaultNetType
parseDefaultNetType "tri" = Just TTri
parseDefaultNetType "triand" = Just TTriand
parseDefaultNetType "trior" = Just TTrior
parseDefaultNetType "trireg" = Just TTrireg
parseDefaultNetType "tri0" = Just TTri0
parseDefaultNetType "tri1" = Just TTri1
parseDefaultNetType "uwire" = Just TUwire
parseDefaultNetType "wire" = Just TWire
parseDefaultNetType "wand" = Just TWand
parseDefaultNetType "wor" = Just TWor
parseDefaultNetType "none" = Nothing
parseDefaultNetType str = error $ "bad default_nettype: " ++ show str

View File

@ -70,6 +70,7 @@ executable sv2v
Convert.Foreach Convert.Foreach
Convert.FuncRet Convert.FuncRet
Convert.FuncRoutine Convert.FuncRoutine
Convert.ImplicitNet
Convert.Inside Convert.Inside
Convert.Interface Convert.Interface
Convert.IntTypes Convert.IntTypes

View File

@ -0,0 +1,39 @@
`define DISPLAY(expr) \
$display(`"expr = %b; $bits(expr) = %0d`", expr, $bits(expr));
`default_nettype wor
module Example(a, b, c);
input a, b, c;
initial begin
`DISPLAY(a)
`DISPLAY(b)
`DISPLAY(c)
end
endmodule
module top;
assign foo = 0;
type(foo) bar;
assign bar = 1;
and (o1, foo, bar);
not (o2, o3, foo);
not (u1, u2, u3);
Example e (a, b, c);
initial begin
`DISPLAY(foo)
`DISPLAY(bar)
`DISPLAY(o1)
`DISPLAY(o2)
`DISPLAY(o3)
`DISPLAY(u1)
`DISPLAY(u2)
`DISPLAY(u3)
`DISPLAY(a)
`DISPLAY(b)
`DISPLAY(c)
end
endmodule

43
test/basic/implicit_net.v Normal file
View File

@ -0,0 +1,43 @@
`define DISPLAY(expr) \
$display(`"expr = %b; $bits(expr) = %0d`", expr, $bits(expr));
`default_nettype wor
module Example(a, b, c);
input a, b, c;
initial begin
`DISPLAY(a)
`DISPLAY(b)
`DISPLAY(c)
end
endmodule
module top;
wor foo;
assign foo = 0;
wor bar;
assign bar = 1;
wor o1, o2, o3;
wor u1, u2, u3;
and (o1, foo, bar);
not (o2, o3, foo);
not (u1, u2, u3);
wor a, b, c;
Example e (a, b, c);
initial begin
`DISPLAY(foo)
`DISPLAY(bar)
`DISPLAY(o1)
`DISPLAY(o2)
`DISPLAY(o3)
`DISPLAY(u1)
`DISPLAY(u2)
`DISPLAY(u3)
`DISPLAY(a)
`DISPLAY(b)
`DISPLAY(c)
end
endmodule