2019-09-14 22:42:54 +02:00
|
|
|
{- sv2v
|
|
|
|
|
- Author: Zachary Snow <zach@zachjs.com>
|
|
|
|
|
-
|
|
|
|
|
- Elaboration of the "expression size system function" ($bits) and the "array
|
|
|
|
|
- query functions" ($dimensions, $unpacked_dimensions, $left, $right, $low,
|
|
|
|
|
- $high, $increment, and $size).
|
|
|
|
|
-
|
|
|
|
|
- Some tools support $bits and some of the other functions in Verilog, but it
|
|
|
|
|
- is not part of the specification, so we have to convert them ourselves.
|
|
|
|
|
-
|
|
|
|
|
- Functions on types are trivially elaborated based on the dimensions of that
|
|
|
|
|
- type, so long as it has been resolved to a primitive type.
|
|
|
|
|
-
|
2020-01-12 02:35:51 +01:00
|
|
|
- Functions on expressions relies on the `type` operator and the `TypeOf`
|
|
|
|
|
- conversion to determine the underlying type of expression. The conversion of
|
|
|
|
|
- `$bits` on expressions recursively breaks the expression into its subtypes
|
|
|
|
|
- and finds their sizes.
|
2019-09-14 22:42:54 +02:00
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
module Convert.DimensionQuery (convert) where
|
|
|
|
|
|
|
|
|
|
import Data.List (elemIndex)
|
|
|
|
|
|
|
|
|
|
import Convert.Traverse
|
|
|
|
|
import Language.SystemVerilog.AST
|
|
|
|
|
|
|
|
|
|
convert :: [AST] -> [AST]
|
2020-06-14 15:20:30 +02:00
|
|
|
convert = map $ traverseDescriptions convertDescription
|
2019-09-14 22:42:54 +02:00
|
|
|
|
|
|
|
|
convertDescription :: Description -> Description
|
|
|
|
|
convertDescription =
|
2020-01-12 02:35:51 +01:00
|
|
|
traverseModuleItems $ traverseExprs $ traverseNestedExprs convertExpr
|
2019-09-14 22:42:54 +02:00
|
|
|
|
|
|
|
|
-- elaborate integer atom types to have explicit dimensions
|
|
|
|
|
elaborateType :: Type -> Type
|
|
|
|
|
elaborateType (IntegerAtom t sg) =
|
|
|
|
|
IntegerVector TLogic sg [(hi, lo)]
|
|
|
|
|
where
|
|
|
|
|
size = atomSize t
|
|
|
|
|
hi = Number $ show (size - 1)
|
|
|
|
|
lo = Number "0"
|
|
|
|
|
atomSize :: IntegerAtomType -> Int
|
|
|
|
|
atomSize TByte = 8
|
|
|
|
|
atomSize TShortint = 16
|
|
|
|
|
atomSize TInt = 32
|
|
|
|
|
atomSize TLongint = 64
|
|
|
|
|
atomSize TInteger = 32
|
|
|
|
|
atomSize TTime = 64
|
|
|
|
|
elaborateType other = other
|
|
|
|
|
|
2020-01-12 02:35:51 +01:00
|
|
|
convertExpr :: Expr -> Expr
|
2019-09-14 22:42:54 +02:00
|
|
|
|
|
|
|
|
-- conversion for array dimensions functions
|
2020-01-12 02:35:51 +01:00
|
|
|
convertExpr (DimsFn FnBits v) =
|
|
|
|
|
convertBits v
|
|
|
|
|
convertExpr (DimsFn fn (Right e)) =
|
|
|
|
|
DimsFn fn $ Left $ TypeOf e
|
|
|
|
|
convertExpr (DimFn fn (Right e) d) =
|
|
|
|
|
DimFn fn (Left $ TypeOf e) d
|
|
|
|
|
convertExpr (orig @ (DimsFn FnUnpackedDimensions (Left t))) =
|
2019-09-14 22:42:54 +02:00
|
|
|
case t of
|
2020-01-12 02:35:51 +01:00
|
|
|
UnpackedType _ rs -> Number $ show $ length rs
|
|
|
|
|
TypeOf{} -> orig
|
|
|
|
|
_ -> Number "0"
|
|
|
|
|
convertExpr (orig @ (DimsFn FnDimensions (Left t))) =
|
|
|
|
|
case t of
|
|
|
|
|
IntegerAtom{} -> Number "1"
|
2020-07-09 01:46:37 +02:00
|
|
|
CSAlias{} -> orig
|
2020-01-12 02:35:51 +01:00
|
|
|
TypeOf{} -> orig
|
|
|
|
|
UnpackedType t' rs ->
|
|
|
|
|
BinOp Add
|
|
|
|
|
(Number $ show $ length rs)
|
|
|
|
|
(DimsFn FnDimensions $ Left t')
|
|
|
|
|
_ -> Number $ show $ length $ snd $ typeRanges t
|
2019-09-14 22:42:54 +02:00
|
|
|
|
|
|
|
|
-- conversion for array dimension functions on types
|
2020-01-12 02:35:51 +01:00
|
|
|
convertExpr (DimFn f (Left t) (Number str)) =
|
|
|
|
|
if dm == Nothing || isUnresolved t then
|
2019-09-14 22:42:54 +02:00
|
|
|
DimFn f (Left t) (Number str)
|
2020-06-07 04:45:08 +02:00
|
|
|
else if d <= 0 || fromIntegral d > length rs then
|
2019-09-14 22:42:54 +02:00
|
|
|
Number "'x"
|
|
|
|
|
else case f of
|
|
|
|
|
FnLeft -> fst r
|
|
|
|
|
FnRight -> snd r
|
|
|
|
|
FnIncrement -> endianCondExpr r (Number "1") (Number "-1")
|
|
|
|
|
FnLow -> endianCondExpr r (snd r) (fst r)
|
|
|
|
|
FnHigh -> endianCondExpr r (fst r) (snd r)
|
|
|
|
|
FnSize -> rangeSize r
|
|
|
|
|
where
|
2020-01-12 02:35:51 +01:00
|
|
|
rs = case elaborateType t of
|
|
|
|
|
UnpackedType tInner rsOuter ->
|
|
|
|
|
rsOuter ++ (snd $ typeRanges $ elaborateType tInner)
|
|
|
|
|
_ -> snd $ typeRanges $ elaborateType t
|
2019-09-14 22:42:54 +02:00
|
|
|
dm = readNumber str
|
|
|
|
|
Just d = dm
|
2020-06-07 04:45:08 +02:00
|
|
|
r = rs !! (fromIntegral $ d - 1)
|
2020-01-12 02:35:51 +01:00
|
|
|
isUnresolved :: Type -> Bool
|
2020-07-09 01:46:37 +02:00
|
|
|
isUnresolved (CSAlias{}) = True
|
2020-01-12 02:35:51 +01:00
|
|
|
isUnresolved (TypeOf{}) = True
|
|
|
|
|
isUnresolved _ = False
|
|
|
|
|
convertExpr (DimFn f (Left t) d) =
|
2019-09-14 22:42:54 +02:00
|
|
|
DimFn f (Left t) d
|
|
|
|
|
|
2020-01-12 02:35:51 +01:00
|
|
|
convertExpr other = other
|
2019-09-14 22:42:54 +02:00
|
|
|
|
2020-01-12 02:35:51 +01:00
|
|
|
-- simplify a bits expression
|
|
|
|
|
convertBits :: TypeOrExpr -> Expr
|
|
|
|
|
convertBits (Left t) =
|
2019-09-14 22:42:54 +02:00
|
|
|
case elaborateType t of
|
|
|
|
|
IntegerVector _ _ rs -> dimensionsSize rs
|
|
|
|
|
Implicit _ rs -> dimensionsSize rs
|
2019-09-17 01:50:30 +02:00
|
|
|
Net _ _ rs -> dimensionsSize rs
|
2020-02-10 01:07:12 +01:00
|
|
|
Struct _ fields rs ->
|
|
|
|
|
BinOp Mul
|
|
|
|
|
(dimensionsSize rs)
|
|
|
|
|
(foldl (BinOp Add) (Number "0") fieldSizes)
|
|
|
|
|
where fieldSizes = map (DimsFn FnBits . Left . fst) fields
|
2020-01-12 02:35:51 +01:00
|
|
|
UnpackedType t' rs ->
|
|
|
|
|
BinOp Mul
|
|
|
|
|
(dimensionsSize rs)
|
|
|
|
|
(DimsFn FnBits $ Left t')
|
2019-09-14 22:42:54 +02:00
|
|
|
_ -> DimsFn FnBits $ Left t
|
2020-01-12 02:35:51 +01:00
|
|
|
convertBits (Right e) =
|
2019-09-14 22:42:54 +02:00
|
|
|
case e of
|
|
|
|
|
Concat exprs ->
|
|
|
|
|
foldl (BinOp Add) (Number "0") $
|
2020-01-12 02:35:51 +01:00
|
|
|
map (convertBits . Right) $
|
2019-09-14 22:42:54 +02:00
|
|
|
exprs
|
2020-01-12 02:35:51 +01:00
|
|
|
Stream _ _ exprs -> convertBits $ Right $ Concat exprs
|
2019-09-14 22:42:54 +02:00
|
|
|
Number n ->
|
|
|
|
|
case elemIndex '\'' n of
|
|
|
|
|
Nothing -> Number "32"
|
2020-06-05 02:19:21 +02:00
|
|
|
Just 0 -> Number "32"
|
2019-09-14 22:42:54 +02:00
|
|
|
Just idx -> Number $ take idx n
|
2020-06-07 03:28:37 +02:00
|
|
|
Range expr mode range ->
|
|
|
|
|
BinOp Mul size $ convertBits $ Right $ Bit expr (Number "0")
|
|
|
|
|
where
|
|
|
|
|
size = case mode of
|
|
|
|
|
NonIndexed -> rangeSize range
|
|
|
|
|
IndexedPlus -> snd range
|
|
|
|
|
IndexedMinus -> snd range
|
2020-01-12 02:35:51 +01:00
|
|
|
_ -> DimsFn FnBits $ Left $ TypeOf e
|