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(..)) ...@@ -11,6 +11,7 @@ import qualified Job (Exclude(..))
import qualified Convert.AlwaysKW import qualified Convert.AlwaysKW
import qualified Convert.AsgnOp import qualified Convert.AsgnOp
import qualified Convert.Bits
import qualified Convert.Enum import qualified Convert.Enum
import qualified Convert.FuncRet import qualified Convert.FuncRet
import qualified Convert.Interface import qualified Convert.Interface
...@@ -30,6 +31,7 @@ type Phase = AST -> AST ...@@ -30,6 +31,7 @@ type Phase = AST -> AST
phases :: [Job.Exclude] -> [Phase] phases :: [Job.Exclude] -> [Phase]
phases excludes = phases excludes =
[ Convert.AsgnOp.convert [ Convert.AsgnOp.convert
, Convert.Bits.convert
, selectExclude (Job.Logic , Convert.Logic.convert) , selectExclude (Job.Logic , Convert.Logic.convert)
, Convert.FuncRet.convert , Convert.FuncRet.convert
, Convert.Enum.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 ...@@ -235,6 +235,9 @@ traverseNestedExprsM mapper = exprMapper
e1' <- exprMapper e1 e1' <- exprMapper e1
e2' <- exprMapper e2 e2' <- exprMapper e2
return $ Cast (Right e1') 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) = em (Dot e x) =
exprMapper e >>= \e' -> return $ Dot e' x exprMapper e >>= \e' -> return $ Dot e' x
em (Pattern l) = do em (Pattern l) = do
...@@ -341,10 +344,11 @@ traverseExprsM mapper = moduleItemMapper ...@@ -341,10 +344,11 @@ traverseExprsM mapper = moduleItemMapper
decls' <- mapM declMapper decls decls' <- mapM declMapper decls
stmts' <- mapM stmtMapper stmts stmts' <- mapM stmtMapper stmts
return $ MIPackageItem $ Task lifetime f decls' 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 l' <- mapM portBindingMapper l
r' <- mapM rangeMapper r r' <- mapM rangeMapper r
return $ Instance m params x r' l' return $ Instance m p' x r' l'
moduleItemMapper (Modport x l) = moduleItemMapper (Modport x l) =
mapM modportDeclMapper l >>= return . Modport x mapM modportDeclMapper l >>= return . Modport x
moduleItemMapper (NInputGate kw x lhs exprs) = do moduleItemMapper (NInputGate kw x lhs exprs) = do
...@@ -353,12 +357,29 @@ traverseExprsM mapper = moduleItemMapper ...@@ -353,12 +357,29 @@ traverseExprsM mapper = moduleItemMapper
moduleItemMapper (NOutputGate kw x lhss expr) = moduleItemMapper (NOutputGate kw x lhss expr) =
exprMapper expr >>= return . NOutputGate kw x lhss exprMapper expr >>= return . NOutputGate kw x lhss
moduleItemMapper (Genvar x) = return $ Genvar x 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)) = moduleItemMapper (MIPackageItem (Typedef t x)) =
return $ MIPackageItem $ Typedef t x return $ MIPackageItem $ Typedef t x
moduleItemMapper (MIPackageItem (Comment c)) = moduleItemMapper (MIPackageItem (Comment c)) =
return $ 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 modportDeclMapper (dir, ident, Just e) = do
e' <- exprMapper e e' <- exprMapper e
return (dir, ident, Just e') return (dir, ident, Just e')
...@@ -456,8 +477,8 @@ traverseTypesM mapper item = ...@@ -456,8 +477,8 @@ traverseTypesM mapper item =
return $ Struct p (zip types idents) r return $ Struct p (zip types idents) r
exprMapper (Cast (Left t) e) = exprMapper (Cast (Left t) e) =
fullMapper t >>= \t' -> return $ Cast (Left t') e fullMapper t >>= \t' -> return $ Cast (Left t') e
exprMapper (Cast (Right e1) e2) = exprMapper (Bits (Left t)) =
return $ Cast (Right e1) e2 fullMapper t >>= return . Bits . Left
exprMapper other = return other exprMapper other = return other
declMapper (Parameter t x e) = declMapper (Parameter t x e) =
fullMapper t >>= \t' -> return $ Parameter t' x e fullMapper t >>= \t' -> return $ Parameter t' x e
......
...@@ -35,6 +35,7 @@ convert descriptions = ...@@ -35,6 +35,7 @@ convert descriptions =
convertDescription :: Types -> Description -> Description convertDescription :: Types -> Description -> Description
convertDescription globalTypes description = convertDescription globalTypes description =
traverseModuleItems removeTypedef $ traverseModuleItems removeTypedef $
traverseModuleItems (traverseExprs $ traverseNestedExprs $ convertExpr) $
traverseModuleItems (traverseTypes $ resolveType types) $ traverseModuleItems (traverseTypes $ resolveType types) $
description description
where where
...@@ -47,6 +48,12 @@ convertDescription globalTypes description = ...@@ -47,6 +48,12 @@ convertDescription globalTypes description =
removeTypedef (MIPackageItem (Typedef _ x)) = removeTypedef (MIPackageItem (Typedef _ x)) =
MIPackageItem $ Comment $ "removed typedef: " ++ x MIPackageItem $ Comment $ "removed typedef: " ++ x
removeTypedef other = other 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 :: Types -> Type -> Type
resolveType _ (Net kw rs) = Net kw rs resolveType _ (Net kw rs) = Net kw rs
......
...@@ -35,6 +35,7 @@ data Expr ...@@ -35,6 +35,7 @@ data Expr
| BinOp BinOp Expr Expr | BinOp BinOp Expr Expr
| Mux Expr Expr Expr | Mux Expr Expr Expr
| Cast (Either Type Expr) Expr | Cast (Either Type Expr) Expr
| Bits (Either Type Expr)
| Dot Expr Identifier | Dot Expr Identifier
| Pattern [(Maybe Identifier, Expr)] | Pattern [(Maybe Identifier, Expr)]
deriving (Eq, Ord) deriving (Eq, Ord)
...@@ -52,11 +53,8 @@ instance Show Expr where ...@@ -52,11 +53,8 @@ instance Show Expr where
show (Dot e n ) = printf "%s.%s" (show e) n 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 (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 (Call f l ) = printf "%s(%s)" f (show l)
show (Cast tore e ) = printf "%s'(%s)" tStr (show e) show (Cast tore e ) = printf "%s'(%s)" (showEither tore) (show e)
where show (Bits tore ) = printf "$bits(%s)" (showEither tore)
tStr = case tore of
Left a -> show a
Right a -> show a
show (Pattern l ) = show (Pattern l ) =
printf "'{\n%s\n}" (indent $ intercalate ",\n" $ map showPatternItem l) printf "'{\n%s\n}" (indent $ intercalate ",\n" $ map showPatternItem l)
where where
......
...@@ -13,6 +13,7 @@ module Language.SystemVerilog.AST.ShowHelp ...@@ -13,6 +13,7 @@ module Language.SystemVerilog.AST.ShowHelp
, commas , commas
, indentedParenList , indentedParenList
, showCase , showCase
, showEither
) where ) where
import Data.List (intercalate) import Data.List (intercalate)
...@@ -52,3 +53,7 @@ indentedParenList l = "(\n" ++ (indent $ intercalate ",\n" l) ++ "\n)" ...@@ -52,3 +53,7 @@ indentedParenList l = "(\n" ++ (indent $ intercalate ",\n" l) ++ "\n)"
showCase :: (Show x, Show y) => ([x], y) -> String showCase :: (Show x, Show y) => ([x], y) -> String
showCase (a, b) = printf "%s: %s" (commas $ map show a) (show b) 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] ...@@ -102,6 +102,7 @@ $decimalDigit = [0-9]
tokens :- tokens :-
"$bits" { tok KW_dollar_bits }
"always" { tok KW_always } "always" { tok KW_always }
"always_comb" { tok KW_always_comb } "always_comb" { tok KW_always_comb }
"always_ff" { tok KW_always_ff } "always_ff" { tok KW_always_ff }
......
...@@ -17,6 +17,7 @@ import Language.SystemVerilog.Parser.Tokens ...@@ -17,6 +17,7 @@ import Language.SystemVerilog.Parser.Tokens
%token %token
"$bits" { Token KW_dollar_bits _ _ }
"always" { Token KW_always _ _ } "always" { Token KW_always _ _ }
"always_comb" { Token KW_always_comb _ _ } "always_comb" { Token KW_always_comb _ _ }
"always_ff" { Token KW_always_ff _ _ } "always_ff" { Token KW_always_ff _ _ }
...@@ -264,6 +265,9 @@ PartialType :: { Signing -> [Range] -> Type } ...@@ -264,6 +265,9 @@ PartialType :: { Signing -> [Range] -> Type }
| NonIntegerType { \Unspecified -> \[] -> NonInteger $1 } | NonIntegerType { \Unspecified -> \[] -> NonInteger $1 }
| "enum" opt(Type) "{" EnumItems "}" { \Unspecified -> Enum $2 $4 } | "enum" opt(Type) "{" EnumItems "}" { \Unspecified -> Enum $2 $4 }
| "struct" Packing "{" StructItems "}" { \Unspecified -> Struct $2 $4 } | "struct" Packing "{" StructItems "}" { \Unspecified -> Struct $2 $4 }
TypeNonIdent :: { Type }
: PartialType Dimensions { $1 Unspecified $2 }
| PartialType Signing Dimensions { $1 $2 $3 }
CastingType :: { Type } CastingType :: { Type }
: IntegerVectorType { IntegerVector $1 Unspecified [] } : IntegerVectorType { IntegerVector $1 Unspecified [] }
...@@ -762,11 +766,15 @@ Exprs :: { [Expr] } ...@@ -762,11 +766,15 @@ Exprs :: { [Expr] }
: Expr { [$1] } : Expr { [$1] }
| Exprs "," Expr { $1 ++ [$3] } | Exprs "," Expr { $1 ++ [$3] }
BitsArg :: { Either Type Expr }
: TypeNonIdent { Left $1 }
| Expr { Right $1 }
Expr :: { Expr } Expr :: { Expr }
: "(" Expr ")" { $2 } : "(" Expr ")" { $2 }
| String { String $1 } | String { String $1 }
| Number { Number $1 } | Number { Number $1 }
| Identifier "(" CallArgs ")" { Call $1 $3 } | Identifier "(" CallArgs ")" { Call $1 $3 }
| "$bits" "(" BitsArg ")" { Bits $3 }
| Identifier { Ident $1 } | Identifier { Ident $1 }
| Expr Range { Range $1 $2 } | Expr Range { Range $1 $2 }
| Expr "[" Expr "]" { Bit $1 $3 } | Expr "[" Expr "]" { Bit $1 $3 }
......
...@@ -63,6 +63,7 @@ data TokenName ...@@ -63,6 +63,7 @@ data TokenName
| KW_disable | KW_disable
| KW_dist | KW_dist
| KW_do | KW_do
| KW_dollar_bits
| KW_edge | KW_edge
| KW_else | KW_else
| KW_end | KW_end
......
...@@ -51,6 +51,7 @@ executable sv2v ...@@ -51,6 +51,7 @@ executable sv2v
Convert Convert
Convert.AlwaysKW Convert.AlwaysKW
Convert.AsgnOp Convert.AsgnOp
Convert.Bits
Convert.Enum Convert.Enum
Convert.FuncRet Convert.FuncRet
Convert.Interface 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