Commit d88c516d by Zachary Snow

enhanced handling of number literals

- number literals are parsed rather than stored as strings
- fix array query functions used on non-trivial number literals
- more efficient expression simplification recursion
- expanded constant folding scenarios
parent 737c66a6
...@@ -19,8 +19,7 @@ ...@@ -19,8 +19,7 @@
module Convert.DimensionQuery (convert) where module Convert.DimensionQuery (convert) where
import Data.List (elemIndex) import Convert.ExprUtils
import Convert.Traverse import Convert.Traverse
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
...@@ -37,9 +36,9 @@ elaborateType (IntegerAtom t sg) = ...@@ -37,9 +36,9 @@ elaborateType (IntegerAtom t sg) =
IntegerVector TLogic sg [(hi, lo)] IntegerVector TLogic sg [(hi, lo)]
where where
size = atomSize t size = atomSize t
hi = Number $ show (size - 1) hi = RawNum $ size - 1
lo = Number "0" lo = RawNum 0
atomSize :: IntegerAtomType -> Int atomSize :: IntegerAtomType -> Integer
atomSize TByte = 8 atomSize TByte = 8
atomSize TShortint = 16 atomSize TShortint = 16
atomSize TInt = 32 atomSize TInt = 32
...@@ -59,32 +58,32 @@ convertExpr (DimFn fn (Right e) d) = ...@@ -59,32 +58,32 @@ convertExpr (DimFn fn (Right e) d) =
DimFn fn (Left $ TypeOf e) d DimFn fn (Left $ TypeOf e) d
convertExpr (orig @ (DimsFn FnUnpackedDimensions (Left t))) = convertExpr (orig @ (DimsFn FnUnpackedDimensions (Left t))) =
case t of case t of
UnpackedType _ rs -> Number $ show $ length rs UnpackedType _ rs -> RawNum $ fromIntegral $ length rs
TypeOf{} -> orig TypeOf{} -> orig
_ -> Number "0" _ -> RawNum 0
convertExpr (orig @ (DimsFn FnDimensions (Left t))) = convertExpr (orig @ (DimsFn FnDimensions (Left t))) =
case t of case t of
IntegerAtom{} -> Number "1" IntegerAtom{} -> RawNum 1
Alias{} -> orig Alias{} -> orig
PSAlias{} -> orig PSAlias{} -> orig
CSAlias{} -> orig CSAlias{} -> orig
TypeOf{} -> orig TypeOf{} -> orig
UnpackedType t' rs -> UnpackedType t' rs ->
BinOp Add BinOp Add
(Number $ show $ length rs) (RawNum $ fromIntegral $ length rs)
(DimsFn FnDimensions $ Left t') (DimsFn FnDimensions $ Left t')
_ -> Number $ show $ length $ snd $ typeRanges t _ -> RawNum $ fromIntegral $ length $ snd $ typeRanges t
-- conversion for array dimension functions on types -- conversion for array dimension functions on types
convertExpr (DimFn f (Left t) (Number str)) = convertExpr (DimFn f (Left t) (Number n)) =
if dm == Nothing || isUnresolved t then if isUnresolved t then
DimFn f (Left t) (Number str) DimFn f (Left t) (Number n)
else if d <= 0 || fromIntegral d > length rs then else if d <= 0 || d > length rs then
Number "'x" Number $ UnbasedUnsized 'x'
else case f of else case f of
FnLeft -> fst r FnLeft -> fst r
FnRight -> snd r FnRight -> snd r
FnIncrement -> endianCondExpr r (Number "1") (UniOp UniSub $ Number "1") FnIncrement -> endianCondExpr r (RawNum 1) (UniOp UniSub $ RawNum 1)
FnLow -> endianCondExpr r (snd r) (fst r) FnLow -> endianCondExpr r (snd r) (fst r)
FnHigh -> endianCondExpr r (fst r) (snd r) FnHigh -> endianCondExpr r (fst r) (snd r)
FnSize -> rangeSize r FnSize -> rangeSize r
...@@ -93,9 +92,10 @@ convertExpr (DimFn f (Left t) (Number str)) = ...@@ -93,9 +92,10 @@ convertExpr (DimFn f (Left t) (Number str)) =
UnpackedType tInner rsOuter -> UnpackedType tInner rsOuter ->
rsOuter ++ (snd $ typeRanges $ elaborateType tInner) rsOuter ++ (snd $ typeRanges $ elaborateType tInner)
_ -> snd $ typeRanges $ elaborateType t _ -> snd $ typeRanges $ elaborateType t
dm = readNumber str d = case numberToInteger n of
Just d = dm Just value -> fromIntegral value
r = rs !! (fromIntegral $ d - 1) Nothing -> 0
r = rs !! (d - 1)
isUnresolved :: Type -> Bool isUnresolved :: Type -> Bool
isUnresolved Alias{} = True isUnresolved Alias{} = True
isUnresolved PSAlias{} = True isUnresolved PSAlias{} = True
...@@ -117,7 +117,7 @@ convertBits (Left t) = ...@@ -117,7 +117,7 @@ convertBits (Left t) =
Struct _ fields rs -> Struct _ fields rs ->
BinOp Mul BinOp Mul
(dimensionsSize rs) (dimensionsSize rs)
(foldl (BinOp Add) (Number "0") fieldSizes) (foldl (BinOp Add) (RawNum 0) fieldSizes)
where fieldSizes = map (DimsFn FnBits . Left . fst) fields where fieldSizes = map (DimsFn FnBits . Left . fst) fields
UnpackedType t' rs -> UnpackedType t' rs ->
BinOp Mul BinOp Mul
...@@ -127,17 +127,13 @@ convertBits (Left t) = ...@@ -127,17 +127,13 @@ convertBits (Left t) =
convertBits (Right e) = convertBits (Right e) =
case e of case e of
Concat exprs -> Concat exprs ->
foldl (BinOp Add) (Number "0") $ foldl (BinOp Add) (RawNum 0) $
map (convertBits . Right) $ map (convertBits . Right) $
exprs exprs
Stream _ _ exprs -> convertBits $ Right $ Concat exprs Stream _ _ exprs -> convertBits $ Right $ Concat exprs
Number n -> Number n -> RawNum $ numberBitLength n
case elemIndex '\'' n of
Nothing -> Number "32"
Just 0 -> Number "32"
Just idx -> Number $ take idx n
Range expr mode range -> Range expr mode range ->
BinOp Mul size $ convertBits $ Right $ Bit expr (Number "0") BinOp Mul size $ convertBits $ Right $ Bit expr (RawNum 0)
where where
size = case mode of size = case mode of
NonIndexed -> rangeSize range NonIndexed -> rangeSize range
......
...@@ -49,6 +49,6 @@ convertExpr :: Idents -> Expr -> Expr ...@@ -49,6 +49,6 @@ convertExpr :: Idents -> Expr -> Expr
convertExpr functions (Call (Ident func) (Args [] [])) = convertExpr functions (Call (Ident func) (Args [] [])) =
Call (Ident func) (Args args []) Call (Ident func) (Args args [])
where args = if Set.member func functions where args = if Set.member func functions
then [Number "0"] then [RawNum 0]
else [] else []
convertExpr _ other = other convertExpr _ other = other
...@@ -23,6 +23,7 @@ import Control.Monad.Writer ...@@ -23,6 +23,7 @@ import Control.Monad.Writer
import Data.List (elemIndices) import Data.List (elemIndices)
import qualified Data.Set as Set import qualified Data.Set as Set
import Convert.ExprUtils
import Convert.Traverse import Convert.Traverse
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
...@@ -72,12 +73,12 @@ traverseType (Enum (Implicit sg rl) v rs) = ...@@ -72,12 +73,12 @@ traverseType (Enum (Implicit sg rl) v rs) =
-- default to a 32 bit logic -- default to a 32 bit logic
t' = IntegerVector TLogic sg rl' t' = IntegerVector TLogic sg rl'
rl' = if null rl rl' = if null rl
then [(Number "31", Number "0")] then [(RawNum 31, RawNum 0)]
else rl else rl
traverseType (Enum t v rs) = do traverseType (Enum t v rs) = do
let (tf, rl) = typeRanges t let (tf, rl) = typeRanges t
rlParam <- case rl of rlParam <- case rl of
[ ] -> return [(Number "0", Number "0")] [ ] -> return [(RawNum 0, RawNum 0)]
[_] -> return rl [_] -> return rl
_ -> error $ "unexpected multi-dim enum type: " ++ show (Enum t v rs) _ -> error $ "unexpected multi-dim enum type: " ++ show (Enum t v rs)
tell $ Set.singleton (tf rlParam, v) -- type of localparams tell $ Set.singleton (tf rlParam, v) -- type of localparams
...@@ -93,10 +94,10 @@ makeEnumItems (itemType, l) = ...@@ -93,10 +94,10 @@ makeEnumItems (itemType, l) =
++ show (zip keys vals) ++ show (zip keys vals)
where where
keys = map fst l keys = map fst l
vals = tail $ scanl step (UniOp UniSub $ Number "1") (map snd l) vals = tail $ scanl step (UniOp UniSub $ RawNum 1) (map snd l)
noDuplicates = all (null . tail . flip elemIndices vals) vals noDuplicates = all (null . tail . flip elemIndices vals) vals
step :: Expr -> Expr -> Expr step :: Expr -> Expr -> Expr
step expr Nil = simplify $ BinOp Add expr (Number "1") step expr Nil = simplify $ BinOp Add expr (RawNum 1)
step _ expr = expr step _ expr = expr
toPackageItem :: Identifier -> Expr -> PackageItem toPackageItem :: Identifier -> Expr -> PackageItem
toPackageItem x v = toPackageItem x v =
......
{-# LANGUAGE PatternSynonyms #-}
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
- Utilities for expressions and ranges
-}
module Convert.ExprUtils
( simplify
, simplifyStep
, rangeSize
, rangeSizeHiLo
, endianCondExpr
, endianCondRange
, dimensionsSize
) where
import Data.Bits (shiftL, shiftR)
import Convert.Traverse
import Language.SystemVerilog.AST
simplify :: Expr -> Expr
simplify = simplifyStep . traverseSinglyNestedExprs simplify . simplifyStep
simplifyStep :: Expr -> Expr
simplifyStep (UniOp LogNot (Number n)) =
case numberToInteger n of
Just 0 -> bool True
Just _ -> bool False
Nothing -> UniOp LogNot $ Number n
simplifyStep (UniOp LogNot (BinOp Eq a b)) = BinOp Ne a b
simplifyStep (UniOp LogNot (BinOp Ne a b)) = BinOp Eq a b
simplifyStep (UniOp UniSub (UniOp UniSub e)) = e
simplifyStep (UniOp UniSub (BinOp Sub e1 e2)) = BinOp Sub e2 e1
simplifyStep (Concat [e]) = e
simplifyStep (Concat es) = Concat $ filter (/= Concat []) es
simplifyStep (Repeat (Dec 0) _) = Concat []
simplifyStep (Repeat (Dec 1) es) = Concat es
simplifyStep (Mux (Number n) e1 e2) =
case numberToInteger n of
Just 0 -> e2
Just _ -> e1
Nothing -> Mux (Number n) e1 e2
simplifyStep (Call (Ident "$clog2") (Args [Dec k] [])) =
toDec $ clog2 k
where
clog2Help :: Integer -> Integer -> Integer
clog2Help p n = if p >= n then 0 else 1 + clog2Help (p*2) n
clog2 :: Integer -> Integer
clog2 n = if n < 2 then 0 else clog2Help 1 n
simplifyStep (BinOp op e1 e2) = simplifyBinOp op e1 e2
simplifyStep other = other
simplifyBinOp :: BinOp -> Expr -> Expr -> Expr
simplifyBinOp Add (Dec 0) e = e
simplifyBinOp Add e (Dec 0) = e
simplifyBinOp Sub e (Dec 0) = e
simplifyBinOp Sub (Dec 0) e = UniOp UniSub e
simplifyBinOp Mul (Dec 0) _ = toDec 0
simplifyBinOp Mul (Dec 1) e = e
simplifyBinOp Mul _ (Dec 0) = toDec 0
simplifyBinOp Mul e (Dec 1) = e
simplifyBinOp Add e1 (UniOp UniSub e2) = BinOp Sub e1 e2
simplifyBinOp Add (UniOp UniSub e1) e2 = BinOp Sub e2 e1
simplifyBinOp Sub e1 (UniOp UniSub e2) = BinOp Add e1 e2
simplifyBinOp Sub (UniOp UniSub e1) e2 = UniOp UniSub $ BinOp Add e1 e2
simplifyBinOp Sub (n1 @ Number{}) (BinOp Sub (n2 @ Number{}) e) =
BinOp Add (BinOp Sub n1 n2) e
simplifyBinOp Sub (n1 @ Number{}) (BinOp Sub e (n2 @ Number{})) =
BinOp Sub (BinOp Add n1 n2) e
simplifyBinOp Sub (BinOp Add e (n1 @ Number{})) (n2 @ Number{}) =
BinOp Add e (BinOp Sub n1 n2)
simplifyBinOp Add (n1 @ Number{}) (BinOp Add (n2 @ Number{}) e) =
BinOp Add (BinOp Add n1 n2) e
simplifyBinOp Add (n1 @ Number{}) (BinOp Sub e (n2 @ Number{})) =
BinOp Add e (BinOp Sub n1 n2)
simplifyBinOp Sub (BinOp Sub e (n1 @ Number{})) (n2 @ Number{}) =
BinOp Sub e (BinOp Add n1 n2)
simplifyBinOp Add (BinOp Sub e (n1 @ Number{})) (n2 @ Number{}) =
BinOp Sub e (BinOp Sub n1 n2)
simplifyBinOp Add (BinOp Sub (n1 @ Number{}) e) (n2 @ Number{}) =
BinOp Sub (BinOp Add n1 n2) e
simplifyBinOp Ge (BinOp Sub e (Dec 1)) (Dec 0) = BinOp Ge e (toDec 1)
simplifyBinOp ShiftAL (Dec x) (Dec y) = toDec $ shiftL x (fromIntegral y)
simplifyBinOp ShiftAR (Dec x) (Dec y) = toDec $ shiftR x (fromIntegral y)
simplifyBinOp ShiftL (Dec x) (Dec y) = toDec $ shiftL x (fromIntegral y)
simplifyBinOp ShiftR (Dec x) (Dec y) = toDec $ shiftR x (fromIntegral y)
simplifyBinOp op e1 e2 =
case (e1, e2) of
(Dec x, Dec y) -> constantFold orig op x y
(SizDec x, Dec y) -> constantFold orig op x y
(Dec x, SizDec y) -> constantFold orig op x y
(Bas x, Dec y) -> constantFold orig op x y
(Dec x, Bas y) -> constantFold orig op x y
(Bas x, Bas y) -> constantFold orig op x y
(NegDec x, Dec y) -> constantFold orig op (-x) y
(Dec x, NegDec y) -> constantFold orig op x (-y)
(NegDec x, NegDec y) -> constantFold orig op (-x) (-y)
_ -> orig
where orig = BinOp op e1 e2
-- attempt to constant fold a binary operation on integers
constantFold :: Expr -> BinOp -> Integer -> Integer -> Expr
constantFold _ Add x y = toDec (x + y)
constantFold _ Sub x y = toDec (x - y)
constantFold _ Mul x y = toDec (x * y)
constantFold _ Div _ 0 = Number $ Based (-32) True Hex 0 bits
where bits = 2 ^ (32 :: Integer) - 1
constantFold _ Div x y = toDec (x `quot` y)
constantFold _ Mod x y = toDec (x `rem` y)
constantFold _ Pow x y = toDec (x ^ y)
constantFold _ Eq x y = bool $ x == y
constantFold _ Ne x y = bool $ x /= y
constantFold _ Gt x y = bool $ x > y
constantFold _ Ge x y = bool $ x >= y
constantFold _ Lt x y = bool $ x < y
constantFold _ Le x y = bool $ x <= y
constantFold fallback _ _ _ = fallback
bool :: Bool -> Expr
bool True = Number $ Decimal 1 False 1
bool False = Number $ Decimal 1 False 0
toDec :: Integer -> Expr
toDec n =
if n < 0 then
UniOp UniSub $ toDec (-n)
else if n >= 4294967296 `div` 2 then
let size = fromIntegral $ bits $ n * 2
in Number $ Decimal (negate size) True n
else
RawNum n
where
bits :: Integer -> Integer
bits 0 = 0
bits v = 1 + bits (quot v 2)
pattern Dec :: Integer -> Expr
pattern Dec n <- Number (Decimal (-32) _ n)
pattern SizDec :: Integer -> Expr
pattern SizDec n <- Number (Decimal 32 _ n)
pattern NegDec :: Integer -> Expr
pattern NegDec n <- UniOp UniSub (Dec n)
pattern Bas :: Integer -> Expr
pattern Bas n <- Number (Based _ _ _ n 0)
-- returns the size of a range
rangeSize :: Range -> Expr
rangeSize (s, e) =
endianCondExpr (s, e) a b
where
a = rangeSizeHiLo (s, e)
b = rangeSizeHiLo (e, s)
-- returns the size of a range known to be ordered
rangeSizeHiLo :: Range -> Expr
rangeSizeHiLo (hi, lo) =
simplify $ BinOp Add (BinOp Sub hi lo) (RawNum 1)
-- chooses one or the other expression based on the endianness of the given
-- range; [hi:lo] chooses the first expression
endianCondExpr :: Range -> Expr -> Expr -> Expr
endianCondExpr r e1 e2 = simplify $ Mux (uncurry (BinOp Ge) r) e1 e2
-- chooses one or the other range based on the endianness of the given range,
-- but in such a way that the result is itself also usable as a range even if
-- the endianness cannot be resolved during conversion, i.e. if it's dependent
-- on a parameter value; [hi:lo] chooses the first range
endianCondRange :: Range -> Range -> Range -> Range
endianCondRange r r1 r2 =
( endianCondExpr r (fst r1) (fst r2)
, endianCondExpr r (snd r1) (snd r2)
)
-- returns the total size of a set of dimensions
dimensionsSize :: [Range] -> Expr
dimensionsSize ranges =
simplify $
foldl (BinOp Mul) (RawNum 1) $
map rangeSize $
ranges
...@@ -23,7 +23,7 @@ convertStmt (For (Left []) cc asgns stmt) = ...@@ -23,7 +23,7 @@ convertStmt (For (Left []) cc asgns stmt) =
convertStmt $ For (Right []) cc asgns stmt convertStmt $ For (Right []) cc asgns stmt
convertStmt (For (Right []) cc asgns stmt) = convertStmt (For (Right []) cc asgns stmt) =
convertStmt $ For inits cc asgns stmt convertStmt $ For inits cc asgns stmt
where inits = Left [dummyDecl $ Number "0"] where inits = Left [dummyDecl $ RawNum 0]
convertStmt (orig @ (For (Right [_]) _ _ _)) = orig convertStmt (orig @ (For (Right [_]) _ _ _)) = orig
convertStmt (For (Left inits) cc asgns stmt) = convertStmt (For (Left inits) cc asgns stmt) =
......
...@@ -22,16 +22,16 @@ convertStmt :: Stmt -> Stmt ...@@ -22,16 +22,16 @@ convertStmt :: Stmt -> Stmt
convertStmt (Foreach x idxs stmt) = convertStmt (Foreach x idxs stmt) =
(foldl (.) id $ map toLoop $ zip [1..] idxs) stmt (foldl (.) id $ map toLoop $ zip [1..] idxs) stmt
where where
toLoop :: (Int, Identifier) -> (Stmt -> Stmt) toLoop :: (Integer, Identifier) -> (Stmt -> Stmt)
toLoop (_, "") = id toLoop (_, "") = id
toLoop (d, i) = toLoop (d, i) =
For (Left [idxDecl]) cmp [incr] For (Left [idxDecl]) cmp [incr]
where where
queryFn f = DimFn f (Right $ Ident x) (Number $ show d) queryFn f = DimFn f (Right $ Ident x) (RawNum d)
idxDecl = Variable Local (IntegerAtom TInteger Unspecified) i [] idxDecl = Variable Local (IntegerAtom TInteger Unspecified) i []
(queryFn FnLeft) (queryFn FnLeft)
cmp = cmp =
Mux (BinOp Eq (queryFn FnIncrement) (Number "1")) Mux (BinOp Eq (queryFn FnIncrement) (RawNum 1))
(BinOp Ge (Ident i) (queryFn FnRight)) (BinOp Ge (Ident i) (queryFn FnRight))
(BinOp Le (Ident i) (queryFn FnRight)) (BinOp Le (Ident i) (queryFn FnRight))
incr = (LHSIdent i, AsgnOp Sub, queryFn FnIncrement) incr = (LHSIdent i, AsgnOp Sub, queryFn FnIncrement)
......
...@@ -276,23 +276,26 @@ convertLoop loop comp stmt = do ...@@ -276,23 +276,26 @@ convertLoop loop comp stmt = do
] ]
jumpStateType :: Type jumpStateType :: Type
jumpStateType = IntegerVector TBit Unspecified [(Number "0", Number "1")] jumpStateType = IntegerVector TBit Unspecified [(RawNum 0, RawNum 1)]
jumpState :: String jumpState :: String
jumpState = "_sv2v_jump" jumpState = "_sv2v_jump"
jsVal :: Integer -> Expr
jsVal n = Number $ Based 2 False Binary n 0
-- keep running the loop/function normally -- keep running the loop/function normally
jsNone :: Expr jsNone :: Expr
jsNone = Number "2'b00" jsNone = jsVal 0
-- skip to the next iteration of the loop (continue) -- skip to the next iteration of the loop (continue)
jsContinue :: Expr jsContinue :: Expr
jsContinue = Number "2'b01" jsContinue = jsVal 1
-- stop running the loop immediately (break) -- stop running the loop immediately (break)
jsBreak :: Expr jsBreak :: Expr
jsBreak = Number "2'b10" jsBreak = jsVal 2
-- stop running the function immediately (return) -- stop running the function immediately (return)
jsReturn :: Expr jsReturn :: Expr
jsReturn = Number "2'b11" jsReturn = jsVal 3
assertMsg :: Bool -> String -> State Info () assertMsg :: Bool -> String -> State Info ()
......
...@@ -134,7 +134,7 @@ traverseModuleItem ports scopes = ...@@ -134,7 +134,7 @@ traverseModuleItem ports scopes =
tmp = "sv2v_tmp_" ++ instanceName ++ "_" ++ portName tmp = "sv2v_tmp_" ++ instanceName ++ "_" ++ portName
tmpExpr = Ident tmp tmpExpr = Ident tmp
t = Net (NetType TWire) Unspecified t = Net (NetType TWire) Unspecified
[(DimsFn FnBits $ Right expr, Number "1")] [(DimsFn FnBits $ Right expr, RawNum 1)]
items = items =
[ MIPackageItem $ Decl $ Variable Local t tmp [] Nil [ MIPackageItem $ Decl $ Variable Local t tmp [] Nil
, AlwaysC AlwaysComb $ Asgn AsgnOpEq Nothing lhs tmpExpr] , AlwaysC AlwaysComb $ Asgn AsgnOpEq Nothing lhs tmpExpr]
...@@ -182,7 +182,7 @@ rewriteDeclM (Variable d t x a e) = do ...@@ -182,7 +182,7 @@ rewriteDeclM (Variable d t x a e) = do
return $ Variable d' t' x a e return $ Variable d' t' x a e
rewriteDeclM (Param s (IntegerVector _ sg []) x e) = rewriteDeclM (Param s (IntegerVector _ sg []) x e) =
return $ Param s (Implicit sg [(zero, zero)]) x e return $ Param s (Implicit sg [(zero, zero)]) x e
where zero = Number "0" where zero = RawNum 0
rewriteDeclM (Param s (IntegerVector _ sg rs) x e) = rewriteDeclM (Param s (IntegerVector _ sg rs) x e) =
return $ Param s (Implicit sg rs) x e return $ Param s (Implicit sg rs) x e
rewriteDeclM decl = return decl rewriteDeclM decl = return decl
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
module Convert.MultiplePacked (convert) where module Convert.MultiplePacked (convert) where
import Convert.ExprUtils
import Control.Monad ((>=>)) import Control.Monad ((>=>))
import Data.Tuple (swap) import Data.Tuple (swap)
import Data.Maybe (isJust) import Data.Maybe (isJust)
...@@ -110,7 +111,7 @@ combineRanges r1 r2 = r ...@@ -110,7 +111,7 @@ combineRanges r1 r2 = r
size2 = rangeSizeHiLo (s2, e2) size2 = rangeSizeHiLo (s2, e2)
lower = BinOp Add e2 (BinOp Mul e1 size2) lower = BinOp Add e2 (BinOp Mul e1 size2)
upper = BinOp Add (BinOp Mul size1 size2) upper = BinOp Add (BinOp Mul size1 size2)
(BinOp Sub lower (Number "1")) (BinOp Sub lower (RawNum 1))
traverseStmtM :: Stmt -> Scoper TypeInfo Stmt traverseStmtM :: Stmt -> Scoper TypeInfo Stmt
traverseStmtM = traverseStmtM =
...@@ -254,7 +255,7 @@ convertExpr scopes = ...@@ -254,7 +255,7 @@ convertExpr scopes =
maybeDims = dims expr maybeDims = dims expr
exprOuter = Bit expr idxInner exprOuter = Bit expr idxInner
baseDec = fst rangeOuter baseDec = fst rangeOuter
baseInc = BinOp Sub (BinOp Add baseDec len) (Number "1") baseInc = BinOp Sub (BinOp Add baseDec len) (RawNum 1)
base = endianCondExpr rangeOuter baseDec baseInc base = endianCondExpr rangeOuter baseDec baseInc
len = rangeSize rangeOuter len = rangeSize rangeOuter
range = (base, len) range = (base, len)
...@@ -277,7 +278,7 @@ convertExpr scopes = ...@@ -277,7 +278,7 @@ convertExpr scopes =
base = endianCondExpr dimOuter baseDec baseInc base = endianCondExpr dimOuter baseDec baseInc
len = lenOuter len = lenOuter
range' = (base, len) range' = (base, len)
one = Number "1" one = RawNum 1
rewriteExpr (orig @ (Range expr NonIndexed range)) = rewriteExpr (orig @ (Range expr NonIndexed range)) =
if isJust maybeDims && expr == rewriteExpr expr if isJust maybeDims && expr == rewriteExpr expr
then rewriteExpr $ Range expr IndexedMinus range' then rewriteExpr $ Range expr IndexedMinus range'
...@@ -285,7 +286,7 @@ convertExpr scopes = ...@@ -285,7 +286,7 @@ convertExpr scopes =
where where
maybeDims = dims expr maybeDims = dims expr
baseDec = fst range baseDec = fst range
baseInc = BinOp Sub (BinOp Add baseDec len) (Number "1") baseInc = BinOp Sub (BinOp Add baseDec len) (RawNum 1)
base = endianCondExpr range baseDec baseInc base = endianCondExpr range baseDec baseInc
len = rangeSize range len = rangeSize range
range' = (base, len) range' = (base, len)
...@@ -299,7 +300,7 @@ convertExpr scopes = ...@@ -299,7 +300,7 @@ convertExpr scopes =
sizeOuter = rangeSize dimOuter sizeOuter = rangeSize dimOuter
offsetOuter = uncurry (endianCondExpr dimOuter) $ swap dimOuter offsetOuter = uncurry (endianCondExpr dimOuter) $ swap dimOuter
(baseOrig, lenOrig) = range (baseOrig, lenOrig) = range
lenOrigMinusOne = BinOp Sub lenOrig (Number "1") lenOrigMinusOne = BinOp Sub lenOrig (RawNum 1)
baseSwapped = baseSwapped =
orientIdx dimInner $ orientIdx dimInner $
case mode of case mode of
......
...@@ -13,6 +13,7 @@ import Data.Maybe (isJust, isNothing, fromJust) ...@@ -13,6 +13,7 @@ import Data.Maybe (isJust, isNothing, fromJust)
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import qualified Data.Set as Set import qualified Data.Set as Set
import Convert.ExprUtils
import Convert.Traverse import Convert.Traverse
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
...@@ -164,7 +165,7 @@ convert files = ...@@ -164,7 +165,7 @@ convert files =
idents = Set.toList identSet idents = Set.toList identSet
toParam :: Identifier -> Decl toParam :: Identifier -> Decl
toParam ident = toParam ident =
Param Parameter typ name (Number "0") Param Parameter typ name (RawNum 0)
where where
typ = Alias (addedParamTypeName paramName ident) [] typ = Alias (addedParamTypeName paramName ident) []
name = addedParamName paramName ident name = addedParamName paramName ident
...@@ -225,7 +226,7 @@ exprToType (Bit e i) = ...@@ -225,7 +226,7 @@ exprToType (Bit e i) =
Just t -> Just $ tf (rs ++ [r]) Just t -> Just $ tf (rs ++ [r])
where where
(tf, rs) = typeRanges t (tf, rs) = typeRanges t
r = (simplify $ BinOp Sub i (Number "1"), Number "0") r = (simplify $ BinOp Sub i (RawNum 1), RawNum 0)
exprToType _ = Nothing exprToType _ = Nothing
-- checks where a type is sufficiently resolved to be substituted -- checks where a type is sufficiently resolved to be substituted
......
...@@ -19,6 +19,7 @@ module Convert.Simplify (convert) where ...@@ -19,6 +19,7 @@ module Convert.Simplify (convert) where
import Control.Monad.State import Control.Monad.State
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import Convert.ExprUtils
import Convert.Traverse import Convert.Traverse
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
...@@ -66,44 +67,56 @@ traverseStmtM :: Stmt -> State Info Stmt ...@@ -66,44 +67,56 @@ traverseStmtM :: Stmt -> State Info Stmt
traverseStmtM stmt = traverseStmtExprsM traverseExprM stmt traverseStmtM stmt = traverseStmtExprsM traverseExprM stmt
traverseExprM :: Expr -> State Info Expr traverseExprM :: Expr -> State Info Expr
traverseExprM = traverseNestedExprsM $ stately convertExpr traverseExprM = stately convertExpr
substituteExprM :: Expr -> State Info Expr substituteExprM :: Expr -> State Info Expr
substituteExprM = traverseNestedExprsM $ stately substitute substituteExprM = stately substitute
convertExpr :: Info -> Expr -> Expr convertExpr :: Info -> Expr -> Expr
convertExpr info (Cast (Right c) e) = convertExpr info (Cast (Right c) e) =
Cast (Right c') e Cast (Right c') e'
where where
c' = simplify $ substitute info c c' = convertExpr info $ substitute info c
e' = convertExpr info e
convertExpr info (DimFn f v e) = convertExpr info (DimFn f v e) =
DimFn f v e' DimFn f v e'
where where e' = convertExpr info $ substitute info e
e' = simplify $ substitute info e
convertExpr info (Call (Ident "$clog2") (Args [e] [])) = convertExpr info (Call (Ident "$clog2") (Args [e] [])) =
if clog2' == clog2 if val' == val
then clog2 then val
else clog2' else val'
where where
e' = simplify $ substitute info e e' = convertExpr info $ substitute info e
clog2 = Call (Ident "$clog2") (Args [e'] []) val = Call (Ident "$clog2") (Args [e'] [])
clog2' = simplify clog2 val' = simplifyStep val
convertExpr info (Mux cc aa bb) = convertExpr info (Mux cc aa bb) =
if before == after if before == after
then simplify $ Mux cc aa bb then simplifyStep $ Mux cc' aa' bb'
else simplify $ Mux after aa bb else simplifyStep $ Mux after aa' bb'
where where
before = substitute info cc before = substitute info cc'
after = simplify before after = convertExpr info before
convertExpr _ (other @ Repeat{}) = traverseNestedExprs simplify other aa' = convertExpr info aa
convertExpr _ (other @ Concat{}) = simplify other bb' = convertExpr info bb
convertExpr _ (other @ BinOp{}) = simplify other cc' = convertExpr info cc
convertExpr _ (other @ UniOp{}) = simplify other convertExpr info (BinOp op e1 e2) =
convertExpr _ other = other simplifyStep $ BinOp op
(convertExpr info e1)
(convertExpr info e2)
convertExpr info (UniOp op expr) =
simplifyStep $ UniOp op $ convertExpr info expr
convertExpr info (Repeat expr exprs) =
simplifyStep $ Repeat
(convertExpr info expr)
(map (convertExpr info) exprs)
convertExpr info (Concat exprs) =
simplifyStep $ Concat (map (convertExpr info) exprs)
convertExpr info expr =
traverseSinglyNestedExprs (convertExpr info) expr
substitute :: Info -> Expr -> Expr substitute :: Info -> Expr -> Expr
substitute info expr = substitute info expr =
traverseNestedExprs substitute' $ simplify expr traverseNestedExprs substitute' expr
where where
substitute' :: Expr -> Expr substitute' :: Expr -> Expr
substitute' (Ident x) = substitute' (Ident x) =
......
...@@ -12,6 +12,7 @@ import Control.Monad.Writer ...@@ -12,6 +12,7 @@ import Control.Monad.Writer
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import qualified Data.Set as Set import qualified Data.Set as Set
import Convert.ExprUtils
import Convert.Traverse import Convert.Traverse
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
...@@ -55,8 +56,8 @@ traverseModuleItemM item = traverseExprsM traverseExprM item ...@@ -55,8 +56,8 @@ traverseModuleItemM item = traverseExprsM traverseExprM item
traverseStmtM :: Stmt -> ST Stmt traverseStmtM :: Stmt -> ST Stmt
traverseStmtM stmt = traverseStmtExprsM traverseExprM stmt traverseStmtM stmt = traverseStmtExprsM traverseExprM stmt
pattern ConvertedUU :: Char -> Expr pattern ConvertedUU :: Integer -> Integer -> Expr
pattern ConvertedUU ch = Number ['1', '\'', 's', 'b', ch] pattern ConvertedUU a b = Number (Based 1 True Binary a b)
traverseExprM :: Expr -> ST Expr traverseExprM :: Expr -> ST Expr
traverseExprM = traverseExprM =
...@@ -64,16 +65,25 @@ traverseExprM = ...@@ -64,16 +65,25 @@ traverseExprM =
where where
convertExprM :: Expr -> ST Expr convertExprM :: Expr -> ST Expr
convertExprM (Cast (Right (Number s)) (Number n)) = convertExprM (Cast (Right (Number s)) (Number n)) =
if elem '\'' n && s == takeWhile (/= '\'') n case n of
then return $ Number n UnbasedUnsized{} -> fallback
else case (readNumber s, readNumber n) of Decimal (-32) True val ->
(Just s', Just n') -> num $ Decimal (fromIntegral size) False val'
return $ Number str
where where
str = (show size) ++ "'d" ++ (show num) Just size = numberToInteger s
size = s' val' = val `mod` (2 ^ size)
num = n' `mod` (2 ^ s') Decimal size signed val ->
_ -> convertCastM (Number s) (Number n) if sizesMatch
then num $ Decimal (abs size) signed val
else fallback
Based size signed base vals knds ->
if sizesMatch
then num $ Based (abs size) signed base vals knds
else fallback
where
sizesMatch = numberToInteger s == Just (numberBitLength n)
fallback = convertCastM (Number s) (Number n)
num = return . Number
convertExprM (orig @ (Cast (Right DimsFn{}) _)) = convertExprM (orig @ (Cast (Right DimsFn{}) _)) =
return orig return orig
convertExprM (Cast (Right (Ident x)) e) = do convertExprM (Cast (Right (Ident x)) e) = do
...@@ -91,13 +101,13 @@ traverseExprM = ...@@ -91,13 +101,13 @@ traverseExprM =
convertExprM other = return other convertExprM other = return other
convertCastM :: Expr -> Expr -> ST Expr convertCastM :: Expr -> Expr -> ST Expr
convertCastM (s @ (Number str)) (e @ (ConvertedUU ch)) = do convertCastM (RawNum n) (ConvertedUU a b) =
typeMap <- get return $ Number $ Based (fromIntegral n) False Binary
case (exprSigning typeMap e, readNumber str) of (extend a) (extend b)
(Just Unspecified, Just n) -> return $ Number $ where
show n ++ "'b" ++ take (fromIntegral n) (repeat ch) extend 0 = 0
(Just sg, _) -> convertCastWithSigningM s e sg extend 1 = (2 ^ n) - 1
_ -> return $ Cast (Right s) e extend _ = error "not possible"
convertCastM s e = do convertCastM s e = do
typeMap <- get typeMap <- get
case exprSigning typeMap e of case exprSigning typeMap e of
...@@ -117,7 +127,7 @@ castFn e sg = ...@@ -117,7 +127,7 @@ castFn e sg =
Function Automatic t fnName [decl] [Return $ Ident inp] Function Automatic t fnName [decl] [Return $ Ident inp]
where where
inp = "inp" inp = "inp"
r = (simplify $ BinOp Sub e (Number "1"), Number "0") r = (simplify $ BinOp Sub e (RawNum 1), RawNum 0)
t = IntegerVector TLogic sg [r] t = IntegerVector TLogic sg [r]
fnName = castFnName e sg fnName = castFnName e sg
decl = Variable Input t inp [] Nil decl = Variable Input t inp [] Nil
...@@ -130,7 +140,7 @@ castFnName e sg = ...@@ -130,7 +140,7 @@ castFnName e sg =
where where
sizeStr = case e of sizeStr = case e of
Number n -> Number n ->
case readNumber n of case numberToInteger n of
Just v -> show v Just v -> show v
_ -> shortHash e _ -> shortHash e
_ -> shortHash e _ -> shortHash e
......
...@@ -29,8 +29,8 @@ streamerBlock chunk size asgn output input = ...@@ -29,8 +29,8 @@ streamerBlock chunk size asgn output input =
, asgn output (Ident out) , asgn output (Ident out)
] ]
where where
lo = Number "0" lo = RawNum 0
hi = BinOp Sub size (Number "1") hi = BinOp Sub size (RawNum 1)
t = IntegerVector TLogic Unspecified [(hi, lo)] t = IntegerVector TLogic Unspecified [(hi, lo)]
name = streamerBlockName chunk size name = streamerBlockName chunk size
inp = name ++ "_inp" inp = name ++ "_inp"
...@@ -49,7 +49,7 @@ streamerBlock chunk size asgn output input = ...@@ -49,7 +49,7 @@ streamerBlock chunk size asgn output input =
lhs2 = LHSRange (LHSIdent out) IndexedMinus (BinOp Sub hi base, left) lhs2 = LHSRange (LHSIdent out) IndexedMinus (BinOp Sub hi base, left)
expr2 = Range (Ident inp) IndexedPlus (base, left) expr2 = Range (Ident inp) IndexedPlus (base, left)
stmt2 = Asgn AsgnOpEq Nothing lhs2 expr2 stmt2 = Asgn AsgnOpEq Nothing lhs2 expr2
cmp2 = BinOp Gt left (Number "0") cmp2 = BinOp Gt left (RawNum 0)
streamerBlockName :: Expr -> Expr -> Identifier streamerBlockName :: Expr -> Expr -> Identifier
streamerBlockName chunk size = streamerBlockName chunk size =
...@@ -60,11 +60,14 @@ traverseStmt (Asgn op mt lhs expr) = ...@@ -60,11 +60,14 @@ traverseStmt (Asgn op mt lhs expr) =
traverseAsgn (lhs, expr) (Asgn op mt) traverseAsgn (lhs, expr) (Asgn op mt)
traverseStmt other = other traverseStmt other = other
zeroBit :: Expr
zeroBit = Number $ Based 1 False Binary 0 0
traverseAsgn :: (LHS, Expr) -> (LHS -> Expr -> Stmt) -> Stmt traverseAsgn :: (LHS, Expr) -> (LHS -> Expr -> Stmt) -> Stmt
traverseAsgn (lhs, Stream StreamR _ exprs) constructor = traverseAsgn (lhs, Stream StreamR _ exprs) constructor =
constructor lhs expr constructor lhs expr
where where
expr = Concat $ exprs ++ [Repeat delta [Number "1'b0"]] expr = Concat $ exprs ++ [Repeat delta [zeroBit]]
size = DimsFn FnBits $ Right $ lhsToExpr lhs size = DimsFn FnBits $ Right $ lhsToExpr lhs
exprSize = DimsFn FnBits $ Right (Concat exprs) exprSize = DimsFn FnBits $ Right (Concat exprs)
delta = BinOp Sub size exprSize delta = BinOp Sub size exprSize
...@@ -73,7 +76,7 @@ traverseAsgn (LHSStream StreamR _ lhss, expr) constructor = ...@@ -73,7 +76,7 @@ traverseAsgn (LHSStream StreamR _ lhss, expr) constructor =
traverseAsgn (lhs, Stream StreamL chunk exprs) constructor = do traverseAsgn (lhs, Stream StreamL chunk exprs) constructor = do
streamerBlock chunk size constructor lhs expr streamerBlock chunk size constructor lhs expr
where where
expr = Concat $ Repeat delta [Number "1'b0"] : exprs expr = Concat $ Repeat delta [zeroBit] : exprs
size = DimsFn FnBits $ Right $ lhsToExpr lhs size = DimsFn FnBits $ Right $ lhsToExpr lhs
exprSize = DimsFn FnBits $ Right (Concat exprs) exprSize = DimsFn FnBits $ Right (Concat exprs)
delta = BinOp Sub size exprSize delta = BinOp Sub size exprSize
......
...@@ -12,6 +12,7 @@ import Data.Tuple (swap) ...@@ -12,6 +12,7 @@ import Data.Tuple (swap)
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import qualified Data.Set as Set import qualified Data.Set as Set
import Convert.ExprUtils
import Convert.Scoper import Convert.Scoper
import Convert.Traverse import Convert.Traverse
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
...@@ -43,7 +44,7 @@ convertStruct' isStruct sg fields = ...@@ -43,7 +44,7 @@ convertStruct' isStruct sg fields =
then Just (unstructType, unstructFields) then Just (unstructType, unstructFields)
else Nothing else Nothing
where where
zero = Number "0" zero = RawNum 0
typeRange :: Type -> Range typeRange :: Type -> Range
typeRange t = typeRange t =
case ranges of case ranges of
...@@ -61,13 +62,13 @@ convertStruct' isStruct sg fields = ...@@ -61,13 +62,13 @@ convertStruct' isStruct sg fields =
-- used here because SystemVerilog structs are laid out backwards -- used here because SystemVerilog structs are laid out backwards
fieldLos = fieldLos =
if isStruct if isStruct
then map simplify $ tail $ scanr (BinOp Add) (Number "0") fieldSizes then map simplify $ tail $ scanr (BinOp Add) (RawNum 0) fieldSizes
else map simplify $ repeat (Number "0") else map simplify $ repeat (RawNum 0)
fieldHis = fieldHis =
if isStruct if isStruct
then map simplify $ init $ scanr (BinOp Add) minusOne fieldSizes then map simplify $ init $ scanr (BinOp Add) minusOne fieldSizes
else map simplify $ map (BinOp Add minusOne) fieldSizes else map simplify $ map (BinOp Add minusOne) fieldSizes
minusOne = UniOp UniSub $ Number "1" minusOne = UniOp UniSub $ RawNum 1
-- create the mapping structure for the unstructured fields -- create the mapping structure for the unstructured fields
keys = map snd fields keys = map snd fields
...@@ -80,7 +81,7 @@ convertStruct' isStruct sg fields = ...@@ -80,7 +81,7 @@ convertStruct' isStruct sg fields =
if isStruct if isStruct
then foldl1 (BinOp Add) fieldSizes then foldl1 (BinOp Add) fieldSizes
else head fieldSizes else head fieldSizes
packedRange = (simplify $ BinOp Sub structSize (Number "1"), zero) packedRange = (simplify $ BinOp Sub structSize (RawNum 1), zero)
unstructType = IntegerVector TLogic sg [packedRange] unstructType = IntegerVector TLogic sg [packedRange]
-- check if this struct can be packed into an integer vector; we only -- check if this struct can be packed into an integer vector; we only
...@@ -208,20 +209,20 @@ convertExpr (t @ IntegerVector{}) (Concat exprs) = ...@@ -208,20 +209,20 @@ convertExpr (t @ IntegerVector{}) (Concat exprs) =
caster = Cast (Left $ dropInnerTypeRange t) caster = Cast (Left $ dropInnerTypeRange t)
exprs' = map caster exprs exprs' = map caster exprs
isUnsizedNumber :: Expr -> Bool isUnsizedNumber :: Expr -> Bool
isUnsizedNumber (Number n) = not $ elem '\'' n isUnsizedNumber (Number n) = not $ numberIsSized n
isUnsizedNumber (UniOp UniSub e) = isUnsizedNumber e isUnsizedNumber (UniOp UniSub e) = isUnsizedNumber e
isUnsizedNumber _ = False isUnsizedNumber _ = False
convertExpr (Struct packing fields (_:rs)) (Concat exprs) = convertExpr (Struct packing fields (_:rs)) (Concat exprs) =
Concat $ map (convertExpr (Struct packing fields rs)) exprs Concat $ map (convertExpr (Struct packing fields rs)) exprs
convertExpr (Struct packing fields (_:rs)) (Bit e _) = convertExpr (Struct packing fields (_:rs)) (Bit e _) =
convertExpr (Struct packing fields rs) e convertExpr (Struct packing fields rs) e
convertExpr (Struct packing fields []) (Pattern [("", Repeat (Number nStr) exprs)]) = convertExpr (Struct packing fields []) (Pattern [("", Repeat (Number n) exprs)]) =
case fmap fromIntegral (readNumber nStr) of case fmap fromIntegral (numberToInteger n) of
Just n -> convertExpr (Struct packing fields []) $ Pattern $ Just val -> convertExpr (Struct packing fields []) $ Pattern $
zip (repeat "") (concat $ take n $ repeat exprs) zip (repeat "") (concat $ replicate val exprs)
Nothing -> Nothing ->
error $ "unable to handle repeat in pattern: " ++ error $ "unable to handle repeat in pattern: " ++
(show $ Repeat (Number nStr) exprs) (show $ Repeat (Number n) exprs)
convertExpr (struct @ (Struct _ fields [])) (Pattern itemsOrig) = convertExpr (struct @ (Struct _ fields [])) (Pattern itemsOrig) =
if extraNames /= Set.empty then if extraNames /= Set.empty then
error $ "pattern " ++ show (Pattern itemsOrig) ++ error $ "pattern " ++ show (Pattern itemsOrig) ++
...@@ -332,7 +333,7 @@ convertSubExpr scopes (Dot e x) = ...@@ -332,7 +333,7 @@ convertSubExpr scopes (Dot e x) =
(fieldType, bounds, dims) = lookupFieldInfo subExprType x (fieldType, bounds, dims) = lookupFieldInfo subExprType x
base = fst bounds base = fst bounds
len = rangeSize bounds len = rangeSize bounds
undotted = if null dims || rangeSize (head dims) == Number "1" undotted = if null dims || rangeSize (head dims) == RawNum 1
then Bit e' (fst bounds) then Bit e' (fst bounds)
else Range e' IndexedMinus (base, len) else Range e' IndexedMinus (base, len)
convertSubExpr scopes (Range (Dot e x) NonIndexed rOuter) = convertSubExpr scopes (Range (Dot e x) NonIndexed rOuter) =
...@@ -374,7 +375,7 @@ convertSubExpr scopes (Range (Dot e x) mode (baseO, lenO)) = ...@@ -374,7 +375,7 @@ convertSubExpr scopes (Range (Dot e x) mode (baseO, lenO)) =
NonIndexed -> error "invariant violated" NonIndexed -> error "invariant violated"
base = endianCondExpr dim baseDec baseInc base = endianCondExpr dim baseDec baseInc
undotted = Range e' mode (base, lenO) undotted = Range e' mode (base, lenO)
one = Number "1" one = RawNum 1
convertSubExpr scopes (Range e mode r) = convertSubExpr scopes (Range e mode r) =
(dropInnerTypeRange t, Range e' mode r) (dropInnerTypeRange t, Range e' mode r)
where (t, e') = convertSubExpr scopes e where (t, e') = convertSubExpr scopes e
......
...@@ -78,6 +78,9 @@ module Convert.Traverse ...@@ -78,6 +78,9 @@ module Convert.Traverse
, traverseNestedExprsM , traverseNestedExprsM
, traverseNestedExprs , traverseNestedExprs
, collectNestedExprsM , collectNestedExprsM
, traverseSinglyNestedExprsM
, traverseSinglyNestedExprs
, collectSinglyNestedExprsM
, traverseNestedLHSsM , traverseNestedLHSsM
, traverseNestedLHSs , traverseNestedLHSs
, collectNestedLHSsM , collectNestedLHSsM
...@@ -211,8 +214,13 @@ traverseSinglyNestedStmtsM fullMapper = cs ...@@ -211,8 +214,13 @@ traverseSinglyNestedStmtsM fullMapper = cs
cs (DoWhile e stmt) = fullMapper stmt >>= return . DoWhile e cs (DoWhile e stmt) = fullMapper stmt >>= return . DoWhile e
cs (Forever stmt) = fullMapper stmt >>= return . Forever cs (Forever stmt) = fullMapper stmt >>= return . Forever
cs (Foreach x vars stmt) = fullMapper stmt >>= return . Foreach x vars cs (Foreach x vars stmt) = fullMapper stmt >>= return . Foreach x vars
cs (If NoCheck (Number "1") s _) = fullMapper s cs (If NoCheck (Number n) s1 s2) = do
cs (If NoCheck (Number "0") _ s) = fullMapper s s1' <- fullMapper s1
s2' <- fullMapper s2
return $ case numberToInteger n of
Nothing -> If NoCheck (Number n) s1' s2'
Just 0 -> s2'
Just _ -> s1'
cs (If u e s1 s2) = do cs (If u e s1 s2) = do
s1' <- fullMapper s1 s1' <- fullMapper s1
s2' <- fullMapper s2 s2' <- fullMapper s2
...@@ -379,8 +387,16 @@ collectStmtLHSsM = collectify traverseStmtLHSsM ...@@ -379,8 +387,16 @@ collectStmtLHSsM = collectify traverseStmtLHSsM
traverseNestedExprsM :: Monad m => MapperM m Expr -> MapperM m Expr traverseNestedExprsM :: Monad m => MapperM m Expr -> MapperM m Expr
traverseNestedExprsM mapper = exprMapper traverseNestedExprsM mapper = exprMapper
where exprMapper = mapper >=> traverseSinglyNestedExprsM exprMapper
traverseNestedExprs :: Mapper Expr -> Mapper Expr
traverseNestedExprs = unmonad traverseNestedExprsM
collectNestedExprsM :: Monad m => CollectorM m Expr -> CollectorM m Expr
collectNestedExprsM = collectify traverseNestedExprsM
traverseSinglyNestedExprsM :: Monad m => MapperM m Expr -> MapperM m Expr
traverseSinglyNestedExprsM exprMapper = em
where where
exprMapper = mapper >=> em
(_, _, _, typeMapper, _) = exprMapperHelpers exprMapper (_, _, _, typeMapper, _) = exprMapperHelpers exprMapper
typeOrExprMapper (Left t) = typeOrExprMapper (Left t) =
typeMapper t >>= return . Left typeMapper t >>= return . Left
...@@ -393,7 +409,8 @@ traverseNestedExprsM mapper = exprMapper ...@@ -393,7 +409,8 @@ traverseNestedExprsM mapper = exprMapper
e2' <- exprMapper e2 e2' <- exprMapper e2
return $ Right (e1', e2') return $ Right (e1', e2')
em (String s) = return $ String s em (String s) = return $ String s
em (Number s) = return $ Number s em (Real s) = return $ Real s
em (Number n) = return $ Number n
em (Time s) = return $ Time s em (Time s) = return $ Time s
em (Ident i) = return $ Ident i em (Ident i) = return $ Ident i
em (PSIdent x y) = return $ PSIdent x y em (PSIdent x y) = return $ PSIdent x y
...@@ -466,6 +483,11 @@ traverseNestedExprsM mapper = exprMapper ...@@ -466,6 +483,11 @@ traverseNestedExprsM mapper = exprMapper
return $ MinTypMax e1' e2' e3' return $ MinTypMax e1' e2' e3'
em (Nil) = return Nil em (Nil) = return Nil
traverseSinglyNestedExprs :: Mapper Expr -> Mapper Expr
traverseSinglyNestedExprs = unmonad traverseSinglyNestedExprsM
collectSinglyNestedExprsM :: Monad m => CollectorM m Expr -> CollectorM m Expr
collectSinglyNestedExprsM = collectify traverseSinglyNestedExprsM
exprMapperHelpers :: Monad m => MapperM m Expr -> exprMapperHelpers :: Monad m => MapperM m Expr ->
( MapperM m Range ( MapperM m Range
, MapperM m Decl , MapperM m Decl
...@@ -1033,8 +1055,11 @@ traverseNestedModuleItemsM mapper = fullMapper ...@@ -1033,8 +1055,11 @@ traverseNestedModuleItemsM mapper = fullMapper
Generate subItems -> GenBlock "" subItems Generate subItems -> GenBlock "" subItems
_ -> GenModuleItem moduleItem' _ -> GenModuleItem moduleItem'
genItemMapper (GenIf _ GenNull GenNull) = return GenNull genItemMapper (GenIf _ GenNull GenNull) = return GenNull
genItemMapper (GenIf (Number "1") s _) = return s genItemMapper (GenIf (Number n) s1 s2) = do
genItemMapper (GenIf (Number "0") _ s) = return s case numberToInteger n of
Nothing -> return $ GenIf (Number n) s1 s2
Just 0 -> genItemMapper s2
Just _ -> genItemMapper s1
genItemMapper (GenBlock "" [item]) = return item genItemMapper (GenBlock "" [item]) = return item
genItemMapper (GenBlock _ []) = return GenNull genItemMapper (GenBlock _ []) = return GenNull
genItemMapper other = return other genItemMapper other = return other
...@@ -1049,11 +1074,6 @@ traverseNestedStmts = unmonad traverseNestedStmtsM ...@@ -1049,11 +1074,6 @@ traverseNestedStmts = unmonad traverseNestedStmtsM
collectNestedStmtsM :: Monad m => CollectorM m Stmt -> CollectorM m Stmt collectNestedStmtsM :: Monad m => CollectorM m Stmt -> CollectorM m Stmt
collectNestedStmtsM = collectify traverseNestedStmtsM collectNestedStmtsM = collectify traverseNestedStmtsM
traverseNestedExprs :: Mapper Expr -> Mapper Expr
traverseNestedExprs = unmonad traverseNestedExprsM
collectNestedExprsM :: Monad m => CollectorM m Expr -> CollectorM m Expr
collectNestedExprsM = collectify traverseNestedExprsM
-- Traverse all the declaration scopes within a ModuleItem. Note that Functions, -- Traverse all the declaration scopes within a ModuleItem. Note that Functions,
-- Tasks, Always/Initial/Final blocks are all NOT passed through ModuleItem -- Tasks, Always/Initial/Final blocks are all NOT passed through ModuleItem
-- mapper, and Decl ModuleItems are NOT passed through the Decl mapper. The -- mapper, and Decl ModuleItems are NOT passed through the Decl mapper. The
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
module Convert.TypeOf (convert) where module Convert.TypeOf (convert) where
import Data.List (elemIndex)
import Data.Tuple (swap) import Data.Tuple (swap)
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
...@@ -76,8 +75,9 @@ typeof :: Expr -> Scoper Type Type ...@@ -76,8 +75,9 @@ typeof :: Expr -> Scoper Type Type
typeof (Number n) = typeof (Number n) =
return $ IntegerVector TLogic sg [r] return $ IntegerVector TLogic sg [r]
where where
(size, sg) = parseNumber n r = (RawNum $ size - 1, RawNum 0)
r = (Number $ show (size - 1), Number "0") size = numberBitLength n
sg = if numberIsSigned n then Signed else Unspecified
typeof (Call (Ident x) _) = typeof (Call (Ident x) _) =
typeof $ Ident x typeof $ Ident x
typeof (orig @ (Bit e _)) = do typeof (orig @ (Bit e _)) = do
...@@ -94,8 +94,8 @@ typeof (orig @ (Range e mode r)) = do ...@@ -94,8 +94,8 @@ typeof (orig @ (Range e mode r)) = do
lo = fst r lo = fst r
hi = case mode of hi = case mode of
NonIndexed -> snd r NonIndexed -> snd r
IndexedPlus -> BinOp Sub (uncurry (BinOp Add) r) (Number "1") IndexedPlus -> BinOp Sub (uncurry (BinOp Add) r) (RawNum 1)
IndexedMinus -> BinOp Add (uncurry (BinOp Sub) r) (Number "1") IndexedMinus -> BinOp Add (uncurry (BinOp Sub) r) (RawNum 1)
typeof (orig @ (Dot e x)) = do typeof (orig @ (Dot e x)) = do
t <- typeof e t <- typeof e
case t of case t of
...@@ -133,19 +133,6 @@ typeof (Repeat reps exprs) = return $ typeOfSize size ...@@ -133,19 +133,6 @@ typeof (Repeat reps exprs) = return $ typeOfSize size
where size = BinOp Mul reps (concatSize exprs) where size = BinOp Mul reps (concatSize exprs)
typeof other = lookupTypeOf other typeof other = lookupTypeOf other
-- determines the size and sign of a number literal
parseNumber :: String -> (Integer, Signing)
parseNumber s =
case elemIndex '\'' s of
Nothing -> (32, Signed)
Just 0 -> parseNumber $ '3' : '2' : s
Just idx -> (size, signing)
where
Just size = readNumber $ take idx s
signing = case drop (idx + 1) s of
's' : _ -> Signed
_ -> Unsigned
-- produces a type large enough to hold either expression -- produces a type large enough to hold either expression
largerSizeType :: Expr -> Expr -> Type largerSizeType :: Expr -> Expr -> Type
largerSizeType a b = largerSizeType a b =
...@@ -158,7 +145,7 @@ largerSizeType a b = ...@@ -158,7 +145,7 @@ largerSizeType a b =
-- returns the total size of concatenated list of expressions -- returns the total size of concatenated list of expressions
concatSize :: [Expr] -> Expr concatSize :: [Expr] -> Expr
concatSize exprs = concatSize exprs =
foldl (BinOp Add) (Number "0") $ foldl (BinOp Add) (RawNum 0) $
map sizeof exprs map sizeof exprs
where where
sizeof = DimsFn FnBits . Right sizeof = DimsFn FnBits . Right
...@@ -166,10 +153,10 @@ concatSize exprs = ...@@ -166,10 +153,10 @@ concatSize exprs =
-- produces a generic type of the given size -- produces a generic type of the given size
typeOfSize :: Expr -> Type typeOfSize :: Expr -> Type
typeOfSize size = typeOfSize size =
IntegerVector TLogic sg [(hi, Number "0")] IntegerVector TLogic sg [(hi, RawNum 0)]
where where
sg = Unspecified -- suitable for now sg = Unspecified -- suitable for now
hi = BinOp Sub size (Number "1") hi = BinOp Sub size (RawNum 1)
-- combines a type with unpacked ranges -- combines a type with unpacked ranges
injectRanges :: Type -> [Range] -> Type injectRanges :: Type -> [Range] -> Type
......
...@@ -76,7 +76,7 @@ bindItem ports bind = ...@@ -76,7 +76,7 @@ bindItem ports bind =
where where
portName = lookupPort ports (bPort bind) portName = lookupPort ports (bPort bind)
size = DimsFn FnBits $ Right $ Ident portName size = DimsFn FnBits $ Right $ Ident portName
rng = (BinOp Sub size (Number "1"), Number "0") rng = (BinOp Sub size (RawNum 1), RawNum 0)
typ = Implicit Unspecified [rng] typ = Implicit Unspecified [rng]
name = bindName bind name = bindName bind
expr = literalFor $ bBit bind expr = literalFor $ bBit bind
...@@ -102,8 +102,8 @@ convertModuleItemM (Instance moduleName params instanceName [] bindings) = do ...@@ -102,8 +102,8 @@ convertModuleItemM (Instance moduleName params instanceName [] bindings) = do
expr'' <- traverseNestedExprsM (replaceBindingExpr port) expr' expr'' <- traverseNestedExprsM (replaceBindingExpr port) expr'
return (portName, expr'') return (portName, expr'')
replaceBindingExpr :: Port -> Expr -> Writer Binds Expr replaceBindingExpr :: Port -> Expr -> Writer Binds Expr
replaceBindingExpr port (orig @ (Cast Right{} (Number num))) = do replaceBindingExpr port (orig @ (Cast Right{} (ConvertedUU a b))) = do
let ch = last num let ch = charForBit a b
if orig == sizedLiteralFor tag ch if orig == sizedLiteralFor tag ch
then do then do
let bind = Bind moduleName ch port let bind = Bind moduleName ch port
...@@ -120,14 +120,24 @@ convertModuleItem = ...@@ -120,14 +120,24 @@ convertModuleItem =
traverseTypes (traverseNestedTypes convertType) . traverseTypes (traverseNestedTypes convertType) .
traverseAsgns convertAsgn traverseAsgns convertAsgn
digits :: [Char]
digits = ['0', '1', 'x', 'z', 'X', 'Z']
literalFor :: Char -> Expr literalFor :: Char -> Expr
literalFor ch = literalFor 'Z' = literalFor 'z'
if elem ch digits literalFor 'X' = literalFor 'x'
then Number ("1'sb" ++ [ch]) literalFor '0' = Number $ Based 1 True Binary 0 0
else error $ "unexpected unbased-unsized digit: " ++ [ch] literalFor '1' = Number $ Based 1 True Binary 1 0
literalFor 'x' = Number $ Based 1 True Binary 0 1
literalFor 'z' = Number $ Based 1 True Binary 1 1
literalFor ch = error $ "unexpected unbased-unsized digit: " ++ [ch]
pattern ConvertedUU :: Integer -> Integer -> Expr
pattern ConvertedUU a b = Number (Based 1 True Binary a b)
charForBit :: Integer -> Integer -> Char
charForBit 0 0 = '0'
charForBit 1 0 = '1'
charForBit 0 1 = 'x'
charForBit 1 1 = 'z'
charForBit _ _ = error "charForBit invariant violated"
sizedLiteralFor :: Expr -> Char -> Expr sizedLiteralFor :: Expr -> Char -> Expr
sizedLiteralFor expr ch = sizedLiteralFor expr ch =
...@@ -206,7 +216,7 @@ convertExpr (ContextDetermined expr) (UU ch) = ...@@ -206,7 +216,7 @@ convertExpr (ContextDetermined expr) (UU ch) =
convertExpr _ other = other convertExpr _ other = other
pattern UU :: Char -> Expr pattern UU :: Char -> Expr
pattern UU ch = Number ['\'', ch] pattern UU ch = Number (UnbasedUnsized ch)
convertType :: Type -> Type convertType :: Type -> Type
convertType (TypeOf e) = TypeOf $ convertExpr SelfDetermined e convertType (TypeOf e) = TypeOf $ convertExpr SelfDetermined e
......
...@@ -34,7 +34,7 @@ import qualified Data.Map.Strict as Map ...@@ -34,7 +34,7 @@ import qualified Data.Map.Strict as Map
import Convert.Traverse import Convert.Traverse
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
type Patterns = Map.Map Identifier String type Patterns = Map.Map Identifier Number
convert :: [AST] -> [AST] convert :: [AST] -> [AST]
convert = map $ traverseDescriptions convertDescription convert = map $ traverseDescriptions convertDescription
...@@ -64,10 +64,7 @@ traverseExprM = traverseNestedExprsM $ stately convertExpr ...@@ -64,10 +64,7 @@ traverseExprM = traverseNestedExprsM $ stately convertExpr
isPlainPattern :: Patterns -> Expr -> Bool isPlainPattern :: Patterns -> Expr -> Bool
isPlainPattern _ (Number n) = isPlainPattern _ (Number n) =
not $ any isWildcardChar n numberToInteger n /= Nothing
where
isWildcardChar :: Char -> Bool
isWildcardChar = flip elem "xzXZ?"
isPlainPattern patterns (Ident x) = isPlainPattern patterns (Ident x) =
case Map.lookup x patterns of case Map.lookup x patterns of
Nothing -> False Nothing -> False
...@@ -81,7 +78,7 @@ convertExpr patterns (BinOp WEq l r) = ...@@ -81,7 +78,7 @@ convertExpr patterns (BinOp WEq l r) =
else else
BinOp BitAnd couldMatch $ BinOp BitAnd couldMatch $
BinOp BitOr noExtraXZs $ BinOp BitOr noExtraXZs $
Number "1'bx" Number (Based 1 False Binary 0 1)
where where
lxl = BinOp BitXor l l lxl = BinOp BitXor l l
rxr = BinOp BitXor r r rxr = BinOp BitXor r r
......
...@@ -22,6 +22,7 @@ module Language.SystemVerilog.AST ...@@ -22,6 +22,7 @@ module Language.SystemVerilog.AST
, module GenItem , module GenItem
, module LHS , module LHS
, module ModuleItem , module ModuleItem
, module Number
, module Op , module Op
, module Stmt , module Stmt
, module Type , module Type
...@@ -40,6 +41,7 @@ import Language.SystemVerilog.AST.Expr as Expr ...@@ -40,6 +41,7 @@ import Language.SystemVerilog.AST.Expr as Expr
import Language.SystemVerilog.AST.GenItem as GenItem import Language.SystemVerilog.AST.GenItem as GenItem
import Language.SystemVerilog.AST.LHS as LHS import Language.SystemVerilog.AST.LHS as LHS
import Language.SystemVerilog.AST.ModuleItem as ModuleItem import Language.SystemVerilog.AST.ModuleItem as ModuleItem
import Language.SystemVerilog.AST.Number as Number
import Language.SystemVerilog.AST.Op as Op import Language.SystemVerilog.AST.Op as Op
import Language.SystemVerilog.AST.Stmt as Stmt import Language.SystemVerilog.AST.Stmt as Stmt
import Language.SystemVerilog.AST.Type as Type import Language.SystemVerilog.AST.Type as Type
......
{-# LANGUAGE PatternSynonyms #-}
{- sv2v {- sv2v
- Author: Zachary Snow <zach@zachjs.com> - Author: Zachary Snow <zach@zachjs.com>
- Initial Verilog AST Author: Tom Hawkins <tomahawkins@gmail.com> - Initial Verilog AST Author: Tom Hawkins <tomahawkins@gmail.com>
...@@ -17,23 +18,15 @@ module Language.SystemVerilog.AST.Expr ...@@ -17,23 +18,15 @@ module Language.SystemVerilog.AST.Expr
, showAssignment , showAssignment
, showRanges , showRanges
, showExprOrRange , showExprOrRange
, simplify
, rangeSize
, rangeSizeHiLo
, endianCondExpr
, endianCondRange
, dimensionsSize
, readNumber
, ParamBinding , ParamBinding
, showParams , showParams
, pattern RawNum
) where ) where
import Data.Bits (shiftL, shiftR)
import Data.List (intercalate) import Data.List (intercalate)
import Numeric (readHex)
import Text.Printf (printf) import Text.Printf (printf)
import Text.Read (readMaybe)
import Language.SystemVerilog.AST.Number (Number(..))
import Language.SystemVerilog.AST.Op import Language.SystemVerilog.AST.Op
import Language.SystemVerilog.AST.ShowHelp import Language.SystemVerilog.AST.ShowHelp
import {-# SOURCE #-} Language.SystemVerilog.AST.Type import {-# SOURCE #-} Language.SystemVerilog.AST.Type
...@@ -43,9 +36,13 @@ type Range = (Expr, Expr) ...@@ -43,9 +36,13 @@ type Range = (Expr, Expr)
type TypeOrExpr = Either Type Expr type TypeOrExpr = Either Type Expr
type ExprOrRange = Either Expr Range type ExprOrRange = Either Expr Range
pattern RawNum :: Integer -> Expr
pattern RawNum n = Number (Decimal (-32) True n)
data Expr data Expr
= String String = String String
| Number String | Real String
| Number Number
| Time String | Time String
| Ident Identifier | Ident Identifier
| PSIdent Identifier Identifier | PSIdent Identifier Identifier
...@@ -71,9 +68,10 @@ data Expr ...@@ -71,9 +68,10 @@ data Expr
instance Show Expr where instance Show Expr where
show (Nil ) = "" show (Nil ) = ""
show (Number str ) = str
show (Time str ) = str show (Time str ) = str
show (Ident str ) = str show (Ident str ) = str
show (Real str ) = str
show (Number n ) = show n
show (PSIdent x y ) = printf "%s::%s" x y show (PSIdent x y ) = printf "%s::%s" x y
show (CSIdent x p y) = printf "%s#%s::%s" x (showParams p) y show (CSIdent x p y) = printf "%s#%s::%s" x (showParams p) y
show (String str ) = printf "\"%s\"" str show (String str ) = printf "\"%s\"" str
...@@ -193,24 +191,6 @@ showExprOrRange :: ExprOrRange -> String ...@@ -193,24 +191,6 @@ showExprOrRange :: ExprOrRange -> String
showExprOrRange (Left x) = show x showExprOrRange (Left x) = show x
showExprOrRange (Right x) = show x showExprOrRange (Right x) = show x
clog2Help :: Integer -> Integer -> Integer
clog2Help p n = if p >= n then 0 else 1 + clog2Help (p*2) n
clog2 :: Integer -> Integer
clog2 n = if n < 2 then 0 else clog2Help 1 n
readNumber :: String -> Maybe Integer
readNumber ('3' : '2' : '\'' : 'd' : rest) = readMaybe rest
readNumber ( '\'' : 'd' : rest) = readMaybe rest
readNumber ('3' : '2' : '\'' : 'h' : rest) =
case readHex rest of
[(v, _)] -> Just v
_ -> Nothing
readNumber ('\'' : 'h' : rest) =
case readHex rest of
[(v, _)] -> Just v
_ -> Nothing
readNumber n = readMaybe n
showUniOpPrec :: Expr -> ShowS showUniOpPrec :: Expr -> ShowS
showUniOpPrec (e @ UniOp{}) = (showParen True . shows) e showUniOpPrec (e @ UniOp{}) = (showParen True . shows) e
showUniOpPrec (e @ BinOp{}) = (showParen True . shows) e showUniOpPrec (e @ BinOp{}) = (showParen True . shows) e
...@@ -220,154 +200,6 @@ showBinOpPrec :: Expr -> ShowS ...@@ -220,154 +200,6 @@ showBinOpPrec :: Expr -> ShowS
showBinOpPrec (e @ BinOp{}) = (showParen True . shows) e showBinOpPrec (e @ BinOp{}) = (showParen True . shows) e
showBinOpPrec e = shows e showBinOpPrec e = shows e
-- basic expression simplfication utility to help us generate nicer code in the
-- common case of ranges like `[FOO-1:0]`
simplify :: Expr -> Expr
simplify (UniOp LogNot (Number "1")) = Number "0"
simplify (UniOp LogNot (Number "0")) = Number "1"
simplify (UniOp LogNot (BinOp Eq a b)) = BinOp Ne a b
simplify (orig @ (Repeat (Number n) exprs)) =
case readNumber n of
Nothing -> orig
Just 0 -> Concat []
Just 1 -> Concat exprs
Just x ->
if x < 0
then error $ "negative repeat count: " ++ show orig
else orig
simplify (Concat [expr]) = expr
simplify (Concat exprs) =
Concat $ filter (/= Concat []) exprs
simplify (orig @ (Call (Ident "$clog2") (Args [Number n] []))) =
case readNumber n of
Nothing -> orig
Just x -> toLiteral $ clog2 x
simplify (Mux cc e1 e2) =
case cc' of
Number "1" -> e1'
Number "0" -> e2'
_ -> Mux cc' e1' e2'
where
cc' = simplify cc
e1' = simplify e1
e2' = simplify e2
simplify (Range e NonIndexed r) = Range e NonIndexed r
simplify (Range e _ (i, Number "0")) = Bit e i
simplify (BinOp Sub (Number n1) (BinOp Sub (Number n2) e)) =
simplify $ BinOp Add (BinOp Sub (Number n1) (Number n2)) e
simplify (BinOp Sub (Number n1) (BinOp Sub e (Number n2))) =
simplify $ BinOp Sub (BinOp Add (Number n1) (Number n2)) e
simplify (BinOp Sub (BinOp Add e (Number n1)) (Number n2)) =
simplify $ BinOp Add e (BinOp Sub (Number n1) (Number n2))
simplify (BinOp Add (Number n1) (BinOp Add (Number n2) e)) =
simplify $ BinOp Add (BinOp Add (Number n1) (Number n2)) e
simplify (BinOp Ge (BinOp Sub e (Number "1")) (Number "0")) =
simplify $ BinOp Ge e (Number "1")
simplify (BinOp Add e1 (UniOp UniSub e2)) =
simplify $ BinOp Sub e1 e2
simplify (BinOp Add (UniOp UniSub e2) e1) =
simplify $ BinOp Sub e1 e2
simplify (BinOp Add (BinOp Sub (Number n1) e) (Number n2)) =
case (readNumber n1, readNumber n2) of
(Just x, Just y) ->
simplify $ BinOp Sub (toLiteral (x + y)) e'
_ -> nochange
where
e' = simplify e
nochange = BinOp Add (BinOp Sub (Number n1) e') (Number n2)
simplify (BinOp op e1 e2) =
case (op, e1', e2') of
(Add, Number "0", e) -> e
(Add, e, Number "0") -> e
(Mul, _, Number "0") -> Number "0"
(Mul, Number "0", _) -> Number "0"
(Mul, e, Number "1") -> e
(Mul, Number "1", e) -> e
(Sub, e, Number "0") -> e
(Add, BinOp Sub e (Number "1"), Number "1") -> e
(Add, e, BinOp Sub (Number "0") (Number "1")) -> BinOp Sub e (Number "1")
(_ , Number a, Number b) ->
case (op, readNumber a, readNumber b) of
(Add, Just x, Just y) -> toLiteral (x + y)
(Sub, Just x, Just y) -> toLiteral (x - y)
(Mul, Just x, Just y) -> toLiteral (x * y)
(Div, Just _, Just 0) -> Number "x"
(Div, Just x, Just y) -> toLiteral (x `quot` y)
(Mod, Just x, Just y) -> toLiteral (x `rem` y)
(Pow, Just x, Just y) -> toLiteral (x ^ y)
(Eq , Just x, Just y) -> bool $ x == y
(Ne , Just x, Just y) -> bool $ x /= y
(Gt , Just x, Just y) -> bool $ x > y
(Ge , Just x, Just y) -> bool $ x >= y
(Lt , Just x, Just y) -> bool $ x < y
(Le , Just x, Just y) -> bool $ x <= y
(ShiftAL, Just x, Just y) -> toLiteral $ shiftL x (toInt y)
(ShiftAR, Just x, Just y) -> toLiteral $ shiftR x (toInt y)
(ShiftL , Just x, Just y) -> toLiteral $ shiftL x (toInt y)
(ShiftR , Just x, Just y) ->
if x < 0 && y > 0
then BinOp ShiftR (Number a) (Number b)
else toLiteral $ shiftR x (toInt y)
_ -> BinOp op e1' e2'
where
toInt :: Integer -> Int
toInt = fromIntegral
(Add, BinOp Add e (Number a), Number b) ->
case (readNumber a, readNumber b) of
(Just x, Just y) -> BinOp Add e $ toLiteral (x + y)
_ -> BinOp op e1' e2'
(Sub, e, Number "-1") -> BinOp Add e (Number "1")
_ -> BinOp op e1' e2'
where
e1' = simplify e1
e2' = simplify e2
bool True = Number "1"
bool False = Number "0"
simplify other = other
toLiteral :: Integer -> Expr
toLiteral n =
if n >= 4294967296
then Number $ show (bits n) ++ "'d" ++ show n
else Number $ show n
bits :: Integer -> Integer
bits 0 = 0
bits n = 1 + bits (quot n 2)
rangeSize :: Range -> Expr
rangeSize (s, e) =
endianCondExpr (s, e) a b
where
a = rangeSizeHiLo (s, e)
b = rangeSizeHiLo (e, s)
rangeSizeHiLo :: Range -> Expr
rangeSizeHiLo (hi, lo) =
simplify $ BinOp Add (BinOp Sub hi lo) (Number "1")
-- chooses one or the other expression based on the endianness of the given
-- range; [hi:lo] chooses the first expression
endianCondExpr :: Range -> Expr -> Expr -> Expr
endianCondExpr r e1 e2 = simplify $ Mux (uncurry (BinOp Ge) r) e1 e2
-- chooses one or the other range based on the endianness of the given range,
-- but in such a way that the result is itself also usable as a range even if
-- the endianness cannot be resolved during conversion, i.e. if it's dependent
-- on a parameter value; [hi:lo] chooses the first range
endianCondRange :: Range -> Range -> Range -> Range
endianCondRange r r1 r2 =
( endianCondExpr r (fst r1) (fst r2)
, endianCondExpr r (snd r1) (snd r2)
)
dimensionsSize :: [Range] -> Expr
dimensionsSize ranges =
simplify $
foldl (BinOp Mul) (Number "1") $
map rangeSize $
ranges
type ParamBinding = (Identifier, TypeOrExpr) type ParamBinding = (Identifier, TypeOrExpr)
showParams :: [ParamBinding] -> String showParams :: [ParamBinding] -> String
......
...@@ -112,10 +112,10 @@ typeRanges (UnpackedType t rs) = (UnpackedType t, rs) ...@@ -112,10 +112,10 @@ typeRanges (UnpackedType t rs) = (UnpackedType t, rs)
nullRange :: Type -> ([Range] -> Type) nullRange :: Type -> ([Range] -> Type)
nullRange t [] = t nullRange t [] = t
nullRange t [(Number "0", Number "0")] = t nullRange t [(RawNum 0, RawNum 0)] = t
nullRange (IntegerAtom TInteger sg) rs = nullRange (IntegerAtom TInteger sg) rs =
-- integer arrays are allowed in SystemVerilog but not in Verilog -- integer arrays are allowed in SystemVerilog but not in Verilog
IntegerVector TBit sg (rs ++ [(Number "31", Number "0")]) IntegerVector TBit sg (rs ++ [(RawNum 31, RawNum 0)])
nullRange t rs1 = nullRange t rs1 =
if t == t' if t == t'
then error $ "non-vector type " ++ show t ++ then error $ "non-vector type " ++ show t ++
...@@ -136,9 +136,9 @@ elaborateIntegerAtom other = other ...@@ -136,9 +136,9 @@ elaborateIntegerAtom other = other
-- size; if not unspecified, the first signing overrides the second -- size; if not unspecified, the first signing overrides the second
baseIntType :: Signing -> Signing -> Int -> Type baseIntType :: Signing -> Signing -> Int -> Type
baseIntType sgOverride sgBase size = baseIntType sgOverride sgBase size =
IntegerVector TReg sg [(Number hi, Number "0")] IntegerVector TReg sg [(RawNum hi, RawNum 0)]
where where
hi = show (size - 1) hi = fromIntegral $ size - 1
sg = if sgOverride /= Unspecified sg = if sgOverride /= Unspecified
then sgOverride then sgOverride
else sgBase else sgBase
......
...@@ -74,9 +74,6 @@ import Language.SystemVerilog.Parser.Tokens ...@@ -74,9 +74,6 @@ import Language.SystemVerilog.Parser.Tokens
| @binaryNumber | @binaryNumber
| @hexNumber | @hexNumber
| @unbasedUnsizedLiteral | @unbasedUnsizedLiteral
@number
= @integralNumber
| @realNumber
-- Strings -- Strings
...@@ -366,7 +363,8 @@ tokens :- ...@@ -366,7 +363,8 @@ tokens :-
@escapedIdentifier { tok Id_escaped } @escapedIdentifier { tok Id_escaped }
@systemIdentifier { tok Id_system } @systemIdentifier { tok Id_system }
@number { tok Lit_number } @realNumber { tok Lit_real }
@integralNumber { tok Lit_number }
@string { tok Lit_string } @string { tok Lit_string }
@time { tok Lit_time } @time { tok Lit_time }
......
...@@ -295,6 +295,7 @@ import Language.SystemVerilog.Parser.Tokens ...@@ -295,6 +295,7 @@ import Language.SystemVerilog.Parser.Tokens
simpleIdentifier { Token Id_simple _ _ } simpleIdentifier { Token Id_simple _ _ }
escapedIdentifier { Token Id_escaped _ _ } escapedIdentifier { Token Id_escaped _ _ }
systemIdentifier { Token Id_system _ _ } systemIdentifier { Token Id_system _ _ }
real { Token Lit_real _ _ }
number { Token Lit_number _ _ } number { Token Lit_number _ _ }
string { Token Lit_string _ _ } string { Token Lit_string _ _ }
time { Token Lit_time _ _ } time { Token Lit_time _ _ }
...@@ -630,10 +631,10 @@ DeclToken :: { DeclToken } ...@@ -630,10 +631,10 @@ DeclToken :: { DeclToken }
| ExplicitLifetime {% posInject \p -> DTLifetime p $1 } | ExplicitLifetime {% posInject \p -> DTLifetime p $1 }
| "const" PartialType {% posInject \p -> DTType p $2 } | "const" PartialType {% posInject \p -> DTType p $2 }
| "{" StreamOp StreamSize Concat "}" {% posInject \p -> DTStream p $2 $3 (map toLHS $4) } | "{" StreamOp StreamSize Concat "}" {% posInject \p -> DTStream p $2 $3 (map toLHS $4) }
| "{" StreamOp Concat "}" {% posInject \p -> DTStream p $2 (Number "1") (map toLHS $3) } | "{" StreamOp Concat "}" {% posInject \p -> DTStream p $2 (RawNum 1) (map toLHS $3) }
| opt("var") "type" "(" Expr ")" {% posInject \p -> DTType p (\Unspecified -> \[] -> TypeOf $4) } | opt("var") "type" "(" Expr ")" {% posInject \p -> DTType p (\Unspecified -> \[] -> TypeOf $4) }
| "<=" opt(DelayOrEvent) Expr {% posInject \p -> DTAsgn p AsgnOpNonBlocking $2 $3 } | "<=" opt(DelayOrEvent) Expr {% posInject \p -> DTAsgn p AsgnOpNonBlocking $2 $3 }
| IncOrDecOperator {% posInject \p -> DTAsgn p (AsgnOp $1) Nothing (Number "1") } | IncOrDecOperator {% posInject \p -> DTAsgn p (AsgnOp $1) Nothing (RawNum 1) }
| Identifier "::" Identifier {% posInject \p -> DTPSIdent p $1 $3 } | Identifier "::" Identifier {% posInject \p -> DTPSIdent p $1 $3 }
| Identifier ParamBindings "::" Identifier {% posInject \p -> DTCSIdent p $1 $2 $4 } | Identifier ParamBindings "::" Identifier {% posInject \p -> DTCSIdent p $1 $2 $4 }
DeclTokenAsgn :: { DeclToken } DeclTokenAsgn :: { DeclToken }
...@@ -905,7 +906,7 @@ DimensionsNonEmpty :: { [Range] } ...@@ -905,7 +906,7 @@ DimensionsNonEmpty :: { [Range] }
| DimensionsNonEmpty Dimension { $1 ++ [$2] } | DimensionsNonEmpty Dimension { $1 ++ [$2] }
Dimension :: { Range } Dimension :: { Range }
: Range { $1 } : Range { $1 }
| "[" Expr "]" { (Number "0", BinOp Sub $2 (Number "1")) } | "[" Expr "]" { (RawNum 0, BinOp Sub $2 (RawNum 1)) }
DeclAsgns :: { [(Identifier, Expr, [Range])] } DeclAsgns :: { [(Identifier, Expr, [Range])] }
: DeclAsgn { [$1] } : DeclAsgn { [$1] }
...@@ -928,8 +929,8 @@ LHS :: { LHS } ...@@ -928,8 +929,8 @@ LHS :: { LHS }
| LHS "[" Expr "]" { LHSBit $1 $3 } | LHS "[" Expr "]" { LHSBit $1 $3 }
| LHS "." Identifier { LHSDot $1 $3 } | LHS "." Identifier { LHSDot $1 $3 }
| LHSConcat { LHSConcat $1 } | LHSConcat { LHSConcat $1 }
| "{" StreamOp StreamSize Concat "}" { LHSStream $2 $3 (map toLHS $4) } | "{" StreamOp StreamSize Concat "}" { LHSStream $2 $3 (map toLHS $4) }
| "{" StreamOp Concat "}" { LHSStream $2 (Number "1") (map toLHS $3) } | "{" StreamOp Concat "}" { LHSStream $2 (RawNum 1) (map toLHS $3) }
LHSConcat :: { [LHS] } LHSConcat :: { [LHS] }
: "{" LHSs "}" { $2 } : "{" LHSs "}" { $2 }
...@@ -972,8 +973,8 @@ StmtAsgn :: { Stmt } ...@@ -972,8 +973,8 @@ StmtAsgn :: { Stmt }
: LHS "=" opt(DelayOrEvent) Expr ";" { Asgn AsgnOpEq $3 $1 $4 } : LHS "=" opt(DelayOrEvent) Expr ";" { Asgn AsgnOpEq $3 $1 $4 }
| LHS "<=" opt(DelayOrEvent) Expr ";" { Asgn AsgnOpNonBlocking $3 $1 $4 } | LHS "<=" opt(DelayOrEvent) Expr ";" { Asgn AsgnOpNonBlocking $3 $1 $4 }
| LHS AsgnBinOp Expr ";" { Asgn $2 Nothing $1 $3 } | LHS AsgnBinOp Expr ";" { Asgn $2 Nothing $1 $3 }
| LHS IncOrDecOperator ";" { Asgn (AsgnOp $2) Nothing $1 (Number "1") } | LHS IncOrDecOperator ";" { Asgn (AsgnOp $2) Nothing $1 (RawNum 1) }
| IncOrDecOperator LHS ";" { Asgn (AsgnOp $1) Nothing $2 (Number "1") } | IncOrDecOperator LHS ";" { Asgn (AsgnOp $1) Nothing $2 (RawNum 1) }
| LHS ";" { Subroutine (lhsToExpr $1) (Args [] []) } | LHS ";" { Subroutine (lhsToExpr $1) (Args [] []) }
| LHS CallArgs ";" { Subroutine (lhsToExpr $1) $2 } | LHS CallArgs ";" { Subroutine (lhsToExpr $1) $2 }
StmtNonAsgn :: { Stmt } StmtNonAsgn :: { Stmt }
...@@ -1021,7 +1022,7 @@ ForInit :: { Either [Decl] [(LHS, Expr)] } ...@@ -1021,7 +1022,7 @@ ForInit :: { Either [Decl] [(LHS, Expr)] }
| DeclTokens(";") { parseDTsAsDeclsOrAsgns $1 } | DeclTokens(";") { parseDTsAsDeclsOrAsgns $1 }
ForCond :: { Expr } ForCond :: { Expr }
: ";" { Number "1" } : ";" { RawNum 1 }
| Expr ";" { $1 } | Expr ";" { $1 }
ForStep :: { [(LHS, AsgnOp, Expr)] } ForStep :: { [(LHS, AsgnOp, Expr)] }
...@@ -1032,8 +1033,8 @@ ForStepNonEmpty :: { [(LHS, AsgnOp, Expr)] } ...@@ -1032,8 +1033,8 @@ ForStepNonEmpty :: { [(LHS, AsgnOp, Expr)] }
| ForStepNonEmpty "," ForStepAssignment { $1 ++ [$3] } | ForStepNonEmpty "," ForStepAssignment { $1 ++ [$3] }
ForStepAssignment :: { (LHS, AsgnOp, Expr) } ForStepAssignment :: { (LHS, AsgnOp, Expr) }
: LHS AsgnOp Expr { ($1, $2, $3) } : LHS AsgnOp Expr { ($1, $2, $3) }
| IncOrDecOperator LHS { ($2, AsgnOp $1, Number "1") } | IncOrDecOperator LHS { ($2, AsgnOp $1, RawNum 1) }
| LHS IncOrDecOperator { ($1, AsgnOp $2, Number "1") } | LHS IncOrDecOperator { ($1, AsgnOp $2, RawNum 1) }
IdxVars :: { [Identifier] } IdxVars :: { [Identifier] }
: "[" IdxVarsInside "]" { $2 } : "[" IdxVarsInside "]" { $2 }
...@@ -1122,8 +1123,11 @@ InsideCase :: { ([ExprOrRange], Stmt) } ...@@ -1122,8 +1123,11 @@ InsideCase :: { ([ExprOrRange], Stmt) }
: OpenRangeList ":" Stmt { ($1, $3) } : OpenRangeList ":" Stmt { ($1, $3) }
| "default" opt(":") Stmt { ([], $3) } | "default" opt(":") Stmt { ([], $3) }
Number :: { String } Real :: { String }
: number { tokenString $1 } : real { tokenString $1 }
Number :: { Number }
: number { parseNumber $ tokenString $1 }
String :: { String } String :: { String }
: string { tail $ init $ tokenString $1 } : string { tail $ init $ tokenString $1 }
...@@ -1169,11 +1173,12 @@ ValueRange :: { ExprOrRange } ...@@ -1169,11 +1173,12 @@ ValueRange :: { ExprOrRange }
Expr :: { Expr } Expr :: { Expr }
: "(" Expr ")" { $2 } : "(" Expr ")" { $2 }
| String { String $1 } | String { String $1 }
| Real { Real $1 }
| Number { Number $1 } | Number { Number $1 }
| Time { Time $1 } | Time { Time $1 }
| Expr CallArgs { Call $1 $2 } | Expr CallArgs { Call $1 $2 }
| DimsFn "(" TypeOrExpr ")" { DimsFn $1 $3 } | DimsFn "(" TypeOrExpr ")" { DimsFn $1 $3 }
| DimFn "(" TypeOrExpr ")" { DimFn $1 $3 (Number "1") } | DimFn "(" TypeOrExpr ")" { DimFn $1 $3 (RawNum 1) }
| DimFn "(" TypeOrExpr "," Expr ")" { DimFn $1 $3 $5 } | DimFn "(" TypeOrExpr "," Expr ")" { DimFn $1 $3 $5 }
| Expr PartSelect { Range $1 (fst $2) (snd $2) } | Expr PartSelect { Range $1 (fst $2) (snd $2) }
| Expr "[" Expr "]" { Bit $1 $3 } | Expr "[" Expr "]" { Bit $1 $3 }
...@@ -1184,8 +1189,8 @@ Expr :: { Expr } ...@@ -1184,8 +1189,8 @@ Expr :: { Expr }
| "'" "{" PatternItems "}" { Pattern $3 } | "'" "{" PatternItems "}" { Pattern $3 }
| CastingType "'" "(" Expr ")" { Cast (Left $1) $4 } | CastingType "'" "(" Expr ")" { Cast (Left $1) $4 }
| Expr "'" "(" Expr ")" { Cast (Right $1) $4 } | Expr "'" "(" Expr ")" { Cast (Right $1) $4 }
| "{" StreamOp StreamSize Concat "}" { Stream $2 $3 $4 } | "{" StreamOp StreamSize Concat "}" { Stream $2 $3 $4 }
| "{" StreamOp Concat "}" { Stream $2 (Number "1") $3 } | "{" StreamOp Concat "}" { Stream $2 (RawNum 1) $3 }
| Expr "inside" "{" OpenRangeList "}" { Inside $1 $4 } | Expr "inside" "{" OpenRangeList "}" { Inside $1 $4 }
| "(" Expr ":" Expr ":" Expr ")" { MinTypMax $2 $4 $6 } | "(" Expr ":" Expr ":" Expr ")" { MinTypMax $2 $4 $6 }
| Identifier %prec REDUCE_OP {- defer -} { Ident $1 } | Identifier %prec REDUCE_OP {- defer -} { Ident $1 }
...@@ -1302,8 +1307,8 @@ GenvarInitialization :: { Expr -> (Identifier, AsgnOp, Expr) -> GenItem -> GenIt ...@@ -1302,8 +1307,8 @@ GenvarInitialization :: { Expr -> (Identifier, AsgnOp, Expr) -> GenItem -> GenIt
GenvarIteration :: { (Identifier, AsgnOp, Expr) } GenvarIteration :: { (Identifier, AsgnOp, Expr) }
: Identifier AsgnOp Expr { ($1, $2, $3) } : Identifier AsgnOp Expr { ($1, $2, $3) }
| IncOrDecOperator Identifier { ($2, AsgnOp $1, Number "1") } | IncOrDecOperator Identifier { ($2, AsgnOp $1, RawNum 1) }
| Identifier IncOrDecOperator { ($1, AsgnOp $2, Number "1") } | Identifier IncOrDecOperator { ($1, AsgnOp $2, RawNum 1) }
AsgnOp :: { AsgnOp } AsgnOp :: { AsgnOp }
: "=" { AsgnOpEq } : "=" { AsgnOpEq }
......
...@@ -183,7 +183,7 @@ parseDTsAsIntantiations (DTIdent _ name : tokens) = ...@@ -183,7 +183,7 @@ parseDTsAsIntantiations (DTIdent _ name : tokens) =
follow = if null toks' then [] else step (tail toks') follow = if null toks' then [] else step (tail toks')
asRange :: DeclToken -> Range asRange :: DeclToken -> Range
asRange (DTRange _ (NonIndexed, s)) = s asRange (DTRange _ (NonIndexed, s)) = s
asRange (DTBit _ s) = (Number "0", BinOp Sub s (Number "1")) asRange (DTBit _ s) = (RawNum 0, BinOp Sub s (RawNum 1))
asRange _ = failure asRange _ = failure
failure = error $ "unrecognized instantiation of " ++ name failure = error $ "unrecognized instantiation of " ++ name
++ ": " ++ show inst ++ ": " ++ show inst
...@@ -439,14 +439,14 @@ takeRanges (token : tokens) = ...@@ -439,14 +439,14 @@ takeRanges (token : tokens) =
_ -> ([] , token : tokens) _ -> ([] , token : tokens)
where where
(rs, rest) = takeRanges tokens (rs, rest) = takeRanges tokens
asRange s = (Number "0", BinOp Sub s (Number "1")) asRange s = (RawNum 0, BinOp Sub s (RawNum 1))
autoDim :: [a] -> ([Range], [DeclToken]) autoDim :: [a] -> ([Range], [DeclToken])
autoDim l = autoDim l =
((lo, hi) : rs, rest) ((lo, hi) : rs, rest)
where where
n = length l n = length l
lo = Number "0" lo = RawNum 0
hi = Number $ show (n - 1) hi = RawNum $ fromIntegral $ n - 1
-- Matching `AsgnOpEq` and `AsgnOpNonBlocking` here allows tripLookahead to work -- Matching `AsgnOpEq` and `AsgnOpNonBlocking` here allows tripLookahead to work
-- both for standard declarations and in `parseDTsAsDeclOrStmt`, where we're -- both for standard declarations and in `parseDTsAsDeclOrStmt`, where we're
......
...@@ -302,6 +302,7 @@ data TokenName ...@@ -302,6 +302,7 @@ data TokenName
| Id_simple | Id_simple
| Id_escaped | Id_escaped
| Id_system | Id_system
| Lit_real
| Lit_number | Lit_number
| Lit_string | Lit_string
| Lit_time | Lit_time
......
...@@ -43,6 +43,7 @@ executable sv2v ...@@ -43,6 +43,7 @@ executable sv2v
Language.SystemVerilog.AST.GenItem Language.SystemVerilog.AST.GenItem
Language.SystemVerilog.AST.LHS Language.SystemVerilog.AST.LHS
Language.SystemVerilog.AST.ModuleItem Language.SystemVerilog.AST.ModuleItem
Language.SystemVerilog.AST.Number
Language.SystemVerilog.AST.Op Language.SystemVerilog.AST.Op
Language.SystemVerilog.AST.ShowHelp Language.SystemVerilog.AST.ShowHelp
Language.SystemVerilog.AST.Stmt Language.SystemVerilog.AST.Stmt
...@@ -64,6 +65,7 @@ executable sv2v ...@@ -64,6 +65,7 @@ executable sv2v
Convert.DuplicateGenvar Convert.DuplicateGenvar
Convert.EmptyArgs Convert.EmptyArgs
Convert.Enum Convert.Enum
Convert.ExprUtils
Convert.ForDecl Convert.ForDecl
Convert.Foreach Convert.Foreach
Convert.FuncRet Convert.FuncRet
......
...@@ -25,6 +25,14 @@ module top; ...@@ -25,6 +25,14 @@ module top;
$display($size(Ram[0])); $display($size(Ram[0]));
$display($bits(foo)); $display($bits(foo));
$display("args %b", $size(RamPair, 1));
$display("args %b", $size(RamPair, 1'b1));
$display("args %b", $size(RamPair, '1));
$display("args %b", $size(RamPair, 'o1));
$display("args %b", $size(RamPair, 1'h1));
$display("args %b", $size(RamPair, 1'd1));
$display("args %b", $size(RamPair, 1'dx));
`EXHAUST(Ram); `EXHAUST(Ram);
`EXHAUST(Ram[0+:2]); `EXHAUST(Ram[0+:2]);
`EXHAUST(Ram[1+:2]); `EXHAUST(Ram[1+:2]);
......
...@@ -5,6 +5,14 @@ module top; ...@@ -5,6 +5,14 @@ module top;
$display(16); $display(16);
$display(3); $display(3);
$display("args %b", 2);
$display("args %b", 2);
$display("args %b", 2);
$display("args %b", 2);
$display("args %b", 2);
$display("args %b", 2);
$display("args %b", 1'bx);
$display(10, 10, 16); $display(10, 10, 16);
$display(0, 0, 16); $display(0, 0, 16);
$display(9, 9, 1); $display(9, 9, 1);
......
module top;
localparam X = 1 / 0;
localparam Y = 'dx;
localparam Z = 40'dx____;
initial $display("%b", X);
initial $display("%b", Y);
initial $display("%b", Z);
endmodule
`include "div.sv"
`define TEST(N) \
$display(`"N -> %0d %b`", N, N); \
$display(`"$bits(N) -> %0d`", $bits(N));
module top;
initial begin
`TEST(0) `TEST(1) `TEST(2)
`TEST(-0) `TEST(-1) `TEST(-2)
`TEST('d0) `TEST('d1) `TEST('d2)
`TEST('sd0) `TEST('sd1) `TEST('sd2)
`TEST('b0) `TEST('b1) `TEST('b10)
`TEST('sd0) `TEST('sd1) `TEST('sd2)
`TEST(1'sox) `TEST(2'sox) `TEST(3'sox) `TEST(7'sox) `TEST(8'sox) `TEST(9'sox) `TEST(9'soxx) `TEST(10'soxx)
`TEST(1'soz) `TEST(2'soz) `TEST(3'soz) `TEST(7'soz) `TEST(8'soz) `TEST(9'soz) `TEST(9'sozz) `TEST(10'sozz)
`TEST(1'SOZ) `TEST(2'SOZ) `TEST(3'SOZ) `TEST(7'SOZ) `TEST(8'SOZ) `TEST(9'SOZ) `TEST(9'SOZZ) `TEST(10'SOZZ)
`TEST(1234_5678) `TEST('h1234_5678) `TEST('o1234_5677) `TEST('b0101_1100)
`TEST('d4294967295) `TEST('d4294967296) `TEST('d4294967297) `TEST('d4294967298) `TEST('d4294967299)
`TEST('d004294967295) `TEST('d004294967296) `TEST('d004294967297) `TEST('d004294967298) `TEST('d004294967299)
`TEST(4294967295) `TEST(4294967296) `TEST(4294967297) `TEST(4294967298) `TEST(4294967299)
`TEST(-4294967295) `TEST(-4294967297) `TEST(-4294967298) `TEST(-4294967299)
`TEST(-8589934593) `TEST(8589934592) `TEST(8589934593)
// iverlog does weird things with these: `TEST(-4294967296) `TEST(-8589934592)
`TEST(659) `TEST('h 837FF) `TEST('o7460)
`TEST(4'b1001) `TEST(5 'D 3) `TEST(3'b01x) `TEST(12'hx) `TEST(16'hz)
`TEST(-8 'd 6) `TEST(4 'shf) `TEST(-4 'sd15) `TEST(16'sd?)
`TEST('bx) `TEST('bz) `TEST('bzx) `TEST('bxz)
`TEST(3'bx) `TEST(3'b1x) `TEST(3'bx1) `TEST('b1x) `TEST('bx1) `TEST(3'b0x1) `TEST(3'b0z1)
`TEST('hf & 10'hf) `TEST(7'hf & 10'hf)
`TEST('b01xz01xz01xz01xz01xz01xz01xz01xz01xz) `TEST('b101xz01xz01xz01xz01xz01xz01xz01xz01xz)
`TEST(36'b01xz01xz01xz01xz01xz01xz01xz01xz01xz) `TEST(37'b01xz01xz01xz01xz01xz01xz01xz01xz01xz)
`TEST(36'sb01xz01xz01xz01xz01xz01xz01xz01xz01xz) `TEST(37'sb01xz01xz01xz01xz01xz01xz01xz01xz01xz)
`TEST('h01xz01xz) `TEST('h101xz01xz)
`TEST(36'h01xz01xz) `TEST(37'h01xz01xz)
`TEST(36'hb01xz01xz) `TEST(37'hb01xz01xz)
end
endmodule
`include "number.sv"
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