Commit c53b3931 by Zachary Snow

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.
parent 5ea2ec9d
......@@ -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
......
{- 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
......
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