mirror of https://github.com/zachjs/sv2v.git
added support and conversion handling of the $bits system function
This also entailed further fleshing out the expression traversal helper to cover expressions in generate blocks, which could, of course, use $bits.
This commit is contained in:
parent
5ea2ec9ddf
commit
c53b39319d
|
|
@ -11,6 +11,7 @@ import qualified Job (Exclude(..))
|
|||
|
||||
import qualified Convert.AlwaysKW
|
||||
import qualified Convert.AsgnOp
|
||||
import qualified Convert.Bits
|
||||
import qualified Convert.Enum
|
||||
import qualified Convert.FuncRet
|
||||
import qualified Convert.Interface
|
||||
|
|
@ -30,6 +31,7 @@ type Phase = AST -> AST
|
|||
phases :: [Job.Exclude] -> [Phase]
|
||||
phases excludes =
|
||||
[ Convert.AsgnOp.convert
|
||||
, Convert.Bits.convert
|
||||
, selectExclude (Job.Logic , Convert.Logic.convert)
|
||||
, Convert.FuncRet.convert
|
||||
, Convert.Enum.convert
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
{- sv2v
|
||||
- Author: Zachary Snow <zach@zachjs.com>
|
||||
-
|
||||
- Elaboration of `$bits`, where possible
|
||||
-}
|
||||
|
||||
module Convert.Bits (convert) where
|
||||
|
||||
import Convert.Traverse
|
||||
import Language.SystemVerilog.AST
|
||||
|
||||
convert :: AST -> AST
|
||||
convert =
|
||||
traverseDescriptions $
|
||||
traverseModuleItems $
|
||||
traverseExprs $
|
||||
traverseNestedExprs $
|
||||
convertExpr
|
||||
|
||||
convertExpr :: Expr -> Expr
|
||||
convertExpr (Bits (Left (IntegerVector _ _ [r]))) = rangeSize r
|
||||
convertExpr (Bits (Left (Implicit _ [r]))) = rangeSize r
|
||||
convertExpr other = other
|
||||
|
|
@ -235,6 +235,9 @@ traverseNestedExprsM mapper = exprMapper
|
|||
e1' <- exprMapper e1
|
||||
e2' <- exprMapper e2
|
||||
return $ Cast (Right e1') e2'
|
||||
em (Bits (Right e)) =
|
||||
exprMapper e >>= return . Bits . Right
|
||||
em (Bits (Left t)) = return $ Bits (Left t)
|
||||
em (Dot e x) =
|
||||
exprMapper e >>= \e' -> return $ Dot e' x
|
||||
em (Pattern l) = do
|
||||
|
|
@ -341,10 +344,11 @@ traverseExprsM mapper = moduleItemMapper
|
|||
decls' <- mapM declMapper decls
|
||||
stmts' <- mapM stmtMapper stmts
|
||||
return $ MIPackageItem $ Task lifetime f decls' stmts'
|
||||
moduleItemMapper (Instance m params x r l) = do
|
||||
moduleItemMapper (Instance m p x r l) = do
|
||||
p' <- mapM portBindingMapper p
|
||||
l' <- mapM portBindingMapper l
|
||||
r' <- mapM rangeMapper r
|
||||
return $ Instance m params x r' l'
|
||||
return $ Instance m p' x r' l'
|
||||
moduleItemMapper (Modport x l) =
|
||||
mapM modportDeclMapper l >>= return . Modport x
|
||||
moduleItemMapper (NInputGate kw x lhs exprs) = do
|
||||
|
|
@ -353,12 +357,29 @@ traverseExprsM mapper = moduleItemMapper
|
|||
moduleItemMapper (NOutputGate kw x lhss expr) =
|
||||
exprMapper expr >>= return . NOutputGate kw x lhss
|
||||
moduleItemMapper (Genvar x) = return $ Genvar x
|
||||
moduleItemMapper (Generate x) = return $ Generate x
|
||||
moduleItemMapper (Generate items) = do
|
||||
items' <- mapM (traverseNestedGenItemsM genItemMapper) items
|
||||
return $ Generate items'
|
||||
moduleItemMapper (MIPackageItem (Typedef t x)) =
|
||||
return $ MIPackageItem $ Typedef t x
|
||||
moduleItemMapper (MIPackageItem (Comment c)) =
|
||||
return $ MIPackageItem $ Comment c
|
||||
|
||||
genItemMapper (GenFor (x1, e1) cc (x2, op2, e2) mn subItems) = do
|
||||
e1' <- exprMapper e1
|
||||
e2' <- exprMapper e2
|
||||
cc' <- exprMapper cc
|
||||
return $ GenFor (x1, e1') cc' (x2, op2, e2') mn subItems
|
||||
genItemMapper (GenIf e i1 i2) = do
|
||||
e' <- exprMapper e
|
||||
return $ GenIf e' i1 i2
|
||||
genItemMapper (GenCase e cases def) = do
|
||||
e' <- exprMapper e
|
||||
caseExprs <- mapM (mapM exprMapper . fst) cases
|
||||
let cases' = zip caseExprs (map snd cases)
|
||||
return $ GenCase e' cases' def
|
||||
genItemMapper other = return other
|
||||
|
||||
modportDeclMapper (dir, ident, Just e) = do
|
||||
e' <- exprMapper e
|
||||
return (dir, ident, Just e')
|
||||
|
|
@ -456,8 +477,8 @@ traverseTypesM mapper item =
|
|||
return $ Struct p (zip types idents) r
|
||||
exprMapper (Cast (Left t) e) =
|
||||
fullMapper t >>= \t' -> return $ Cast (Left t') e
|
||||
exprMapper (Cast (Right e1) e2) =
|
||||
return $ Cast (Right e1) e2
|
||||
exprMapper (Bits (Left t)) =
|
||||
fullMapper t >>= return . Bits . Left
|
||||
exprMapper other = return other
|
||||
declMapper (Parameter t x e) =
|
||||
fullMapper t >>= \t' -> return $ Parameter t' x e
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ convert descriptions =
|
|||
convertDescription :: Types -> Description -> Description
|
||||
convertDescription globalTypes description =
|
||||
traverseModuleItems removeTypedef $
|
||||
traverseModuleItems (traverseExprs $ traverseNestedExprs $ convertExpr) $
|
||||
traverseModuleItems (traverseTypes $ resolveType types) $
|
||||
description
|
||||
where
|
||||
|
|
@ -47,6 +48,12 @@ convertDescription globalTypes description =
|
|||
removeTypedef (MIPackageItem (Typedef _ x)) =
|
||||
MIPackageItem $ Comment $ "removed typedef: " ++ x
|
||||
removeTypedef other = other
|
||||
convertExpr :: Expr -> Expr
|
||||
convertExpr (Bits (Right (Ident x))) =
|
||||
if Map.member x types
|
||||
then Bits $ Left $ resolveType types (Alias x [])
|
||||
else Bits $ Right $ Ident x
|
||||
convertExpr other = other
|
||||
|
||||
resolveType :: Types -> Type -> Type
|
||||
resolveType _ (Net kw rs) = Net kw rs
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ data Expr
|
|||
| BinOp BinOp Expr Expr
|
||||
| Mux Expr Expr Expr
|
||||
| Cast (Either Type Expr) Expr
|
||||
| Bits (Either Type Expr)
|
||||
| Dot Expr Identifier
|
||||
| Pattern [(Maybe Identifier, Expr)]
|
||||
deriving (Eq, Ord)
|
||||
|
|
@ -52,11 +53,8 @@ instance Show Expr where
|
|||
show (Dot e n ) = printf "%s.%s" (show e) n
|
||||
show (Mux c a b) = printf "(%s ? %s : %s)" (show c) (show a) (show b)
|
||||
show (Call f l ) = printf "%s(%s)" f (show l)
|
||||
show (Cast tore e ) = printf "%s'(%s)" tStr (show e)
|
||||
where
|
||||
tStr = case tore of
|
||||
Left a -> show a
|
||||
Right a -> show a
|
||||
show (Cast tore e ) = printf "%s'(%s)" (showEither tore) (show e)
|
||||
show (Bits tore ) = printf "$bits(%s)" (showEither tore)
|
||||
show (Pattern l ) =
|
||||
printf "'{\n%s\n}" (indent $ intercalate ",\n" $ map showPatternItem l)
|
||||
where
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ module Language.SystemVerilog.AST.ShowHelp
|
|||
, commas
|
||||
, indentedParenList
|
||||
, showCase
|
||||
, showEither
|
||||
) where
|
||||
|
||||
import Data.List (intercalate)
|
||||
|
|
@ -52,3 +53,7 @@ indentedParenList l = "(\n" ++ (indent $ intercalate ",\n" l) ++ "\n)"
|
|||
|
||||
showCase :: (Show x, Show y) => ([x], y) -> String
|
||||
showCase (a, b) = printf "%s: %s" (commas $ map show a) (show b)
|
||||
|
||||
showEither :: (Show a, Show b) => Either a b -> String
|
||||
showEither (Left v) = show v
|
||||
showEither (Right v) = show v
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ $decimalDigit = [0-9]
|
|||
|
||||
tokens :-
|
||||
|
||||
"$bits" { tok KW_dollar_bits }
|
||||
"always" { tok KW_always }
|
||||
"always_comb" { tok KW_always_comb }
|
||||
"always_ff" { tok KW_always_ff }
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import Language.SystemVerilog.Parser.Tokens
|
|||
|
||||
%token
|
||||
|
||||
"$bits" { Token KW_dollar_bits _ _ }
|
||||
"always" { Token KW_always _ _ }
|
||||
"always_comb" { Token KW_always_comb _ _ }
|
||||
"always_ff" { Token KW_always_ff _ _ }
|
||||
|
|
@ -264,6 +265,9 @@ PartialType :: { Signing -> [Range] -> Type }
|
|||
| NonIntegerType { \Unspecified -> \[] -> NonInteger $1 }
|
||||
| "enum" opt(Type) "{" EnumItems "}" { \Unspecified -> Enum $2 $4 }
|
||||
| "struct" Packing "{" StructItems "}" { \Unspecified -> Struct $2 $4 }
|
||||
TypeNonIdent :: { Type }
|
||||
: PartialType Dimensions { $1 Unspecified $2 }
|
||||
| PartialType Signing Dimensions { $1 $2 $3 }
|
||||
|
||||
CastingType :: { Type }
|
||||
: IntegerVectorType { IntegerVector $1 Unspecified [] }
|
||||
|
|
@ -762,11 +766,15 @@ Exprs :: { [Expr] }
|
|||
: Expr { [$1] }
|
||||
| Exprs "," Expr { $1 ++ [$3] }
|
||||
|
||||
BitsArg :: { Either Type Expr }
|
||||
: TypeNonIdent { Left $1 }
|
||||
| Expr { Right $1 }
|
||||
Expr :: { Expr }
|
||||
: "(" Expr ")" { $2 }
|
||||
| String { String $1 }
|
||||
| Number { Number $1 }
|
||||
| Identifier "(" CallArgs ")" { Call $1 $3 }
|
||||
| "$bits" "(" BitsArg ")" { Bits $3 }
|
||||
| Identifier { Ident $1 }
|
||||
| Expr Range { Range $1 $2 }
|
||||
| Expr "[" Expr "]" { Bit $1 $3 }
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ data TokenName
|
|||
| KW_disable
|
||||
| KW_dist
|
||||
| KW_do
|
||||
| KW_dollar_bits
|
||||
| KW_edge
|
||||
| KW_else
|
||||
| KW_end
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ executable sv2v
|
|||
Convert
|
||||
Convert.AlwaysKW
|
||||
Convert.AsgnOp
|
||||
Convert.Bits
|
||||
Convert.Enum
|
||||
Convert.FuncRet
|
||||
Convert.Interface
|
||||
|
|
|
|||
Loading…
Reference in New Issue