mirror of https://github.com/zachjs/sv2v.git
generalization of array dimension(s) system functions
This commit is contained in:
parent
10feedb1af
commit
f5d6683422
|
|
@ -26,7 +26,11 @@ import Language.SystemVerilog.AST
|
|||
type Info = Map.Map Identifier (Type, [Range])
|
||||
|
||||
convert :: [AST] -> [AST]
|
||||
convert = map $ traverseDescriptions convertDescription
|
||||
convert files =
|
||||
if files == files'
|
||||
then files
|
||||
else convert files'
|
||||
where files' = map (traverseDescriptions convertDescription) files
|
||||
|
||||
convertDescription :: Description -> Description
|
||||
convertDescription =
|
||||
|
|
@ -54,28 +58,28 @@ traverseExprM = traverseNestedExprsM $ stately converter
|
|||
|
||||
-- simplify a bits expression given scoped type information
|
||||
convertExpr :: Info -> Expr -> Expr
|
||||
convertExpr _ (Bits (Left t)) =
|
||||
convertExpr _ (DimsFn FnBits (Left t)) =
|
||||
case t of
|
||||
IntegerVector _ _ rs -> dimensionsSize rs
|
||||
Implicit _ rs -> dimensionsSize rs
|
||||
Net _ rs -> dimensionsSize rs
|
||||
_ -> Bits $ Left t
|
||||
convertExpr info (Bits (Right e)) =
|
||||
_ -> DimsFn FnBits $ Left t
|
||||
convertExpr info (DimsFn FnBits (Right e)) =
|
||||
case e of
|
||||
Ident x ->
|
||||
case Map.lookup x info of
|
||||
Nothing -> Bits $ Right e
|
||||
Nothing -> DimsFn FnBits $ Right e
|
||||
Just (t, rs) -> simplify $ BinOp Mul
|
||||
(dimensionsSize rs)
|
||||
(convertExpr info $ Bits $ Left t)
|
||||
(convertExpr info $ DimsFn FnBits $ Left t)
|
||||
Concat exprs ->
|
||||
foldl (BinOp Add) (Number "0") $
|
||||
map (convertExpr info) $
|
||||
map (Bits . Right) $
|
||||
map (DimsFn FnBits . Right) $
|
||||
exprs
|
||||
Range expr mode range ->
|
||||
simplify $ BinOp Mul size
|
||||
(convertExpr info $ Bits $ Right $ Bit expr (Number "0"))
|
||||
(convertExpr info $ DimsFn FnBits $ Right $ Bit expr (Number "0"))
|
||||
where
|
||||
size = case mode of
|
||||
NonIndexed -> rangeSize range
|
||||
|
|
@ -83,16 +87,16 @@ convertExpr info (Bits (Right e)) =
|
|||
IndexedMinus -> snd range
|
||||
Bit (Ident x) idx ->
|
||||
case Map.lookup x info of
|
||||
Nothing -> Bits $ Right $ Bit (Ident x) idx
|
||||
Nothing -> DimsFn FnBits $ Right $ Bit (Ident x) idx
|
||||
Just (t, rs) ->
|
||||
convertExpr info $ Bits $ Left t'
|
||||
convertExpr info $ DimsFn FnBits $ Left t'
|
||||
where t' = popRange t rs
|
||||
Stream _ _ exprs -> convertExpr info $ Bits $ Right $ Concat exprs
|
||||
Stream _ _ exprs -> convertExpr info $ DimsFn FnBits $ Right $ Concat exprs
|
||||
Number n ->
|
||||
case elemIndex '\'' n of
|
||||
Nothing -> Number "32"
|
||||
Just idx -> Number $ take idx n
|
||||
_ -> Bits $ Right e
|
||||
_ -> DimsFn FnBits $ Right e
|
||||
convertExpr _ other = other
|
||||
|
||||
-- combines the given type and dimensions and returns a new type with the
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ convertDescription ports orig =
|
|||
collectNestedExprsM exprIdents expr
|
||||
tmp = "sv2v_tmp_" ++ instanceName ++ "_" ++ portName
|
||||
tmpExpr = Ident tmp
|
||||
t = Net TWire [(Bits $ Right expr, Number "1")]
|
||||
t = Net TWire [(DimsFn FnBits $ Right expr, Number "1")]
|
||||
items =
|
||||
[ MIPackageItem $ Decl $ Variable Local t tmp [] Nothing
|
||||
, AlwaysC AlwaysComb $ AsgnBlk AsgnOpEq lhs tmpExpr]
|
||||
|
|
|
|||
|
|
@ -79,8 +79,8 @@ traverseAsgnM (lhs, Stream StreamR _ exprs) constructor =
|
|||
return $ constructor lhs expr
|
||||
where
|
||||
expr = Concat $ exprs ++ [Repeat delta [Number "1'b0"]]
|
||||
size = Bits $ Right $ lhsToExpr lhs
|
||||
exprSize = Bits $ Right (Concat exprs)
|
||||
size = DimsFn FnBits $ Right $ lhsToExpr lhs
|
||||
exprSize = DimsFn FnBits $ Right (Concat exprs)
|
||||
delta = BinOp Sub size exprSize
|
||||
traverseAsgnM (LHSStream StreamR _ lhss, expr) constructor =
|
||||
return $ constructor (LHSConcat lhss) expr
|
||||
|
|
@ -88,13 +88,13 @@ traverseAsgnM (lhs, Stream StreamL chunk exprs) constructor = do
|
|||
return $ streamerBlock chunk size constructor lhs expr
|
||||
where
|
||||
expr = Concat $ Repeat delta [Number "1'b0"] : exprs
|
||||
size = Bits $ Right $ lhsToExpr lhs
|
||||
exprSize = Bits $ Right (Concat exprs)
|
||||
size = DimsFn FnBits $ Right $ lhsToExpr lhs
|
||||
exprSize = DimsFn FnBits $ Right (Concat exprs)
|
||||
delta = BinOp Sub size exprSize
|
||||
traverseAsgnM (LHSStream StreamL chunk lhss, expr) constructor = do
|
||||
return $ streamerBlock chunk size constructor lhs expr
|
||||
where
|
||||
lhs = LHSConcat lhss
|
||||
size = Bits $ Right expr
|
||||
size = DimsFn FnBits $ Right expr
|
||||
traverseAsgnM (lhs, expr) constructor =
|
||||
return $ constructor lhs expr
|
||||
|
|
|
|||
|
|
@ -446,10 +446,14 @@ convertAsgn structs types (lhs, expr) =
|
|||
(t, Cast (Left t) (snd $ convertSubExpr sub))
|
||||
convertSubExpr (Cast (Right e) sub) =
|
||||
(Implicit Unspecified [], Cast (Right e) (snd $ convertSubExpr sub))
|
||||
convertSubExpr (Bits (Left t)) = (Implicit Unspecified [], Bits (Left t))
|
||||
convertSubExpr (Bits (Right e)) =
|
||||
(Implicit Unspecified [], Bits (Right e'))
|
||||
where e' = snd $ convertSubExpr e
|
||||
convertSubExpr (DimsFn f tore) =
|
||||
(Implicit Unspecified [], DimsFn f tore')
|
||||
where tore' = convertTypeOrExpr tore
|
||||
convertSubExpr (DimFn f tore e) =
|
||||
(Implicit Unspecified [], DimFn f tore' e')
|
||||
where
|
||||
tore' = convertTypeOrExpr tore
|
||||
e' = snd $ convertSubExpr e
|
||||
convertSubExpr (Pattern items) =
|
||||
if all (== Nothing) $ map fst items'
|
||||
then (Implicit Unspecified [], Concat $ map snd items')
|
||||
|
|
@ -459,6 +463,10 @@ convertAsgn structs types (lhs, expr) =
|
|||
mapItem (mx, e) = (mx, snd $ convertSubExpr e)
|
||||
convertSubExpr Nil = (Implicit Unspecified [], Nil)
|
||||
|
||||
convertTypeOrExpr :: TypeOrExpr -> TypeOrExpr
|
||||
convertTypeOrExpr (Left t) = Left t
|
||||
convertTypeOrExpr (Right e) = Right $ snd $ convertSubExpr e
|
||||
|
||||
-- lookup the range of a field in its unstructured type
|
||||
lookupUnstructRange :: TypeFunc -> Identifier -> Range
|
||||
lookupUnstructRange structTf fieldName =
|
||||
|
|
|
|||
|
|
@ -411,6 +411,9 @@ traverseNestedExprsM mapper = exprMapper
|
|||
maybeExprMapper Nothing = return Nothing
|
||||
maybeExprMapper (Just e) =
|
||||
exprMapper e >>= return . Just
|
||||
typeOrExprMapper (Left t) = return $ Left t
|
||||
typeOrExprMapper (Right e) =
|
||||
exprMapper e >>= return . Right
|
||||
em (String s) = return $ String s
|
||||
em (Number s) = return $ Number s
|
||||
em (Ident i) = return $ Ident i
|
||||
|
|
@ -456,9 +459,12 @@ 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 (DimsFn f tore) =
|
||||
typeOrExprMapper tore >>= return . DimsFn f
|
||||
em (DimFn f tore e) = do
|
||||
tore' <- typeOrExprMapper tore
|
||||
e' <- exprMapper e
|
||||
return $ DimFn f tore' e'
|
||||
em (Dot e x) =
|
||||
exprMapper e >>= \e' -> return $ Dot e' x
|
||||
em (Pattern l) = do
|
||||
|
|
@ -832,10 +838,16 @@ traverseTypesM mapper item =
|
|||
fullMapper = traverseNestedTypesM mapper
|
||||
maybeMapper Nothing = return Nothing
|
||||
maybeMapper (Just t) = fullMapper t >>= return . Just
|
||||
typeOrExprMapper (Right e) = return $ Right e
|
||||
typeOrExprMapper (Left t) =
|
||||
fullMapper t >>= return . Left
|
||||
exprMapper (Cast (Left t) e) =
|
||||
fullMapper t >>= \t' -> return $ Cast (Left t') e
|
||||
exprMapper (Bits (Left t)) =
|
||||
fullMapper t >>= return . Bits . Left
|
||||
exprMapper (DimsFn f tore) =
|
||||
typeOrExprMapper tore >>= return . DimsFn f
|
||||
exprMapper (DimFn f tore e) = do
|
||||
tore' <- typeOrExprMapper tore
|
||||
return $ DimFn f tore' e
|
||||
exprMapper other = return other
|
||||
declMapper (Param s t x e) =
|
||||
fullMapper t >>= \t' -> return $ Param s t' x e
|
||||
|
|
|
|||
|
|
@ -58,7 +58,8 @@ convertDescription globalTypes description =
|
|||
convertTypeOrExpr other = other
|
||||
convertExpr :: Expr -> Expr
|
||||
convertExpr (Cast v e) = Cast (convertTypeOrExpr v) e
|
||||
convertExpr (Bits v) = Bits $ convertTypeOrExpr v
|
||||
convertExpr (DimsFn f v) = DimsFn f (convertTypeOrExpr v)
|
||||
convertExpr (DimFn f v e) = DimFn f (convertTypeOrExpr v) e
|
||||
convertExpr other = other
|
||||
convertModuleItem :: ModuleItem -> ModuleItem
|
||||
convertModuleItem (Instance m params x r p) =
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ module Language.SystemVerilog.AST.Expr
|
|||
, TypeOrExpr
|
||||
, Args (..)
|
||||
, PartSelectMode (..)
|
||||
, DimsFn (..)
|
||||
, DimFn (..)
|
||||
, showAssignment
|
||||
, showRanges
|
||||
, simplify
|
||||
|
|
@ -48,7 +50,8 @@ data Expr
|
|||
| BinOp BinOp Expr Expr
|
||||
| Mux Expr Expr Expr
|
||||
| Cast TypeOrExpr Expr
|
||||
| Bits TypeOrExpr
|
||||
| DimsFn DimsFn TypeOrExpr
|
||||
| DimFn DimFn TypeOrExpr Expr
|
||||
| Dot Expr Identifier
|
||||
| Pattern [(Maybe Identifier, Expr)]
|
||||
| Nil
|
||||
|
|
@ -69,9 +72,10 @@ instance Show Expr where
|
|||
show (BinOp o a b) = printf "(%s %s %s)" (show a) (show o) (show b)
|
||||
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 ps f l) = printf "%s%s(%s)" (maybe "" (++ "::") ps) f (show l)
|
||||
show (Cast tore e ) = printf "%s'(%s)" (showEither tore) (show e)
|
||||
show (Bits tore ) = printf "$bits(%s)" (showEither tore)
|
||||
show (Call ps f l) = printf "%s%s(%s)" (maybe "" (++ "::") ps) f (show l)
|
||||
show (Cast tore e ) = printf "%s'(%s)" (showEither tore) (show e)
|
||||
show (DimsFn f v ) = printf "%s(%s)" (show f) (showEither v)
|
||||
show (DimFn f v e) = printf "%s(%s, %s)" (show f) (showEither v) (show e)
|
||||
show (Pattern l ) =
|
||||
printf "'{\n%s\n}" (indent $ intercalate ",\n" $ map showPatternItem l)
|
||||
where
|
||||
|
|
@ -101,6 +105,35 @@ instance Show PartSelectMode where
|
|||
show IndexedPlus = "+:"
|
||||
show IndexedMinus = "-:"
|
||||
|
||||
data DimsFn
|
||||
= FnBits
|
||||
| FnDimensions
|
||||
| FnUnpackedDimensions
|
||||
deriving (Eq, Ord)
|
||||
|
||||
data DimFn
|
||||
= FnLeft
|
||||
| FnRight
|
||||
| FnLow
|
||||
| FnHigh
|
||||
| FnIncrement
|
||||
| FnSize
|
||||
deriving (Eq, Ord)
|
||||
|
||||
instance Show DimsFn where
|
||||
show FnBits = "$bits"
|
||||
show FnDimensions = "$dimensions"
|
||||
show FnUnpackedDimensions = "$unpacked_dimensions"
|
||||
|
||||
instance Show DimFn where
|
||||
show FnLeft = "$left"
|
||||
show FnRight = "$right"
|
||||
show FnLow = "$low"
|
||||
show FnHigh = "$high"
|
||||
show FnIncrement = "$increment"
|
||||
show FnSize = "$size"
|
||||
|
||||
|
||||
showAssignment :: Show a => Maybe a -> String
|
||||
showAssignment Nothing = ""
|
||||
showAssignment (Just val) = " = " ++ show val
|
||||
|
|
|
|||
|
|
@ -115,7 +115,16 @@ $decimalDigit = [0-9]
|
|||
|
||||
tokens :-
|
||||
|
||||
"$bits" { tok KW_dollar_bits }
|
||||
"$bits" { tok KW_dollar_bits }
|
||||
"$dimensions" { tok KW_dollar_dimensions }
|
||||
"$unpacked_dimensions" { tok KW_dollar_unpacked_dimensions }
|
||||
"$left" { tok KW_dollar_left }
|
||||
"$right" { tok KW_dollar_right }
|
||||
"$low" { tok KW_dollar_low }
|
||||
"$high" { tok KW_dollar_high }
|
||||
"$increment" { tok KW_dollar_increment }
|
||||
"$size" { tok KW_dollar_size }
|
||||
|
||||
"accept_on" { tok KW_accept_on }
|
||||
"alias" { tok KW_alias }
|
||||
"always" { tok KW_always }
|
||||
|
|
|
|||
|
|
@ -26,7 +26,16 @@ import Language.SystemVerilog.Parser.Tokens
|
|||
|
||||
%token
|
||||
|
||||
"$bits" { Token KW_dollar_bits _ _ }
|
||||
"$bits" { Token KW_dollar_bits _ _ }
|
||||
"$dimensions" { Token KW_dollar_dimensions _ _ }
|
||||
"$unpacked_dimensions" { Token KW_dollar_unpacked_dimensions _ _ }
|
||||
"$left" { Token KW_dollar_left _ _ }
|
||||
"$right" { Token KW_dollar_right _ _ }
|
||||
"$low" { Token KW_dollar_low _ _ }
|
||||
"$high" { Token KW_dollar_high _ _ }
|
||||
"$increment" { Token KW_dollar_increment _ _ }
|
||||
"$size" { Token KW_dollar_size _ _ }
|
||||
|
||||
"accept_on" { Token KW_accept_on _ _ }
|
||||
"alias" { Token KW_alias _ _ }
|
||||
"always" { Token KW_always _ _ }
|
||||
|
|
@ -1011,7 +1020,9 @@ Expr :: { Expr }
|
|||
| Number { Number $1 }
|
||||
| Identifier "(" CallArgs ")" { Call (Nothing) $1 $3 }
|
||||
| Identifier "::" Identifier "(" CallArgs ")" { Call (Just $1) $3 $5 }
|
||||
| "$bits" "(" TypeOrExpr ")" { Bits $3 }
|
||||
| DimsFn "(" TypeOrExpr ")" { DimsFn $1 $3 }
|
||||
| DimFn "(" TypeOrExpr ")" { DimFn $1 $3 (Number "1") }
|
||||
| DimFn "(" TypeOrExpr "," Expr ")" { DimFn $1 $3 $5 }
|
||||
| Identifier { Ident $1 }
|
||||
| Identifier "::" Identifier { PSIdent $1 $3 }
|
||||
| Expr PartSelect { Range $1 (fst $2) (snd $2) }
|
||||
|
|
@ -1088,7 +1099,7 @@ StreamOp :: { StreamOp }
|
|||
: "<<" { StreamL }
|
||||
| ">>" { StreamR }
|
||||
StreamSize :: { Expr }
|
||||
: TypeNonIdent { Bits $ Left $1 }
|
||||
: TypeNonIdent { DimsFn FnBits (Left $1) }
|
||||
| Expr { $1 }
|
||||
|
||||
GenItemOrNull :: { GenItem }
|
||||
|
|
@ -1152,6 +1163,18 @@ IncOrDecOperator :: { BinOp }
|
|||
: "++" { Add }
|
||||
| "--" { Sub }
|
||||
|
||||
DimsFn :: { DimsFn }
|
||||
: "$bits" { FnBits }
|
||||
| "$dimensions" { FnDimensions }
|
||||
| "$unpacked_dimensions" { FnUnpackedDimensions }
|
||||
DimFn :: { DimFn }
|
||||
: "$left" { FnLeft }
|
||||
| "$right" { FnRight }
|
||||
| "$low" { FnLow }
|
||||
| "$high" { FnHigh }
|
||||
| "$increment" { FnIncrement }
|
||||
| "$size" { FnSize }
|
||||
|
||||
{
|
||||
|
||||
parseError :: [Token] -> a
|
||||
|
|
|
|||
|
|
@ -30,6 +30,14 @@ data Token
|
|||
|
||||
data TokenName
|
||||
= KW_dollar_bits
|
||||
| KW_dollar_dimensions
|
||||
| KW_dollar_unpacked_dimensions
|
||||
| KW_dollar_left
|
||||
| KW_dollar_right
|
||||
| KW_dollar_low
|
||||
| KW_dollar_high
|
||||
| KW_dollar_increment
|
||||
| KW_dollar_size
|
||||
| KW_accept_on
|
||||
| KW_alias
|
||||
| KW_always
|
||||
|
|
|
|||
Loading…
Reference in New Issue