Commit f5d66834 by Zachary Snow

generalization of array dimension(s) system functions

parent 10feedb1
......@@ -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
......
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