Commit 18358063 by Zachary Snow

restrict unbased unsized bit representation

parent 52ccd3d3
......@@ -116,16 +116,15 @@ convertCastM (RawNum size) (Number (Based 1 True Binary a b)) signed =
return $ Number $ Based (fromIntegral size) signed Binary
(val * a) (val * b)
where val = (2 ^ size) - 1
convertCastM (RawNum size) (Number (UnbasedUnsized ch)) signed =
convertCastM (RawNum size) (Number (UnbasedUnsized bit)) signed =
convertCastM (RawNum size) (Number num) signed
where
num = Based 1 True Binary a b
(a, b) = case ch of
'0' -> (0, 0)
'1' -> (1, 0)
'x' -> (0, 1)
'z' -> (1, 1)
_ -> error $ "unexpected unbased-unsized digit: " ++ [ch]
(a, b) = case bit of
Bit0 -> (0, 0)
Bit1 -> (1, 0)
BitX -> (0, 1)
BitZ -> (1, 1)
convertCastM size value signed = do
value' <- traverseExprM value
useFn <- embedScopes canUseCastFn size
......
......@@ -79,7 +79,7 @@ convertExpr (DimFn f (Left t) (Number n)) =
if isUnresolved t then
DimFn f (Left t) (Number n)
else if d <= 0 || d > length rs then
Number $ UnbasedUnsized 'x'
Number $ UnbasedUnsized BitX
else case f of
FnLeft -> fst r
FnRight -> snd r
......
......@@ -96,9 +96,9 @@ traverseExprM (Cast (Left (Implicit sg [])) expr) =
-- and `$unsigned` system functions present in Verilog-2005
traverseExprM $ Call (Ident fn) $ Args [expr] []
where fn = if sg == Signed then "$signed" else "$unsigned"
traverseExprM (Cast (Left t) (Number (UnbasedUnsized ch))) =
traverseExprM (Cast (Left t) (Number (UnbasedUnsized bit))) =
-- defer until this expression becomes explicit
return $ Cast (Left t) (Number (UnbasedUnsized ch))
return $ Cast (Left t) (Number (UnbasedUnsized bit))
traverseExprM (Cast (Left (t @ (IntegerAtom TInteger _))) expr) =
-- convert to cast to an integer vector type
traverseExprM $ Cast (Left t') expr
......
......@@ -68,11 +68,11 @@ convertModuleItem parts (Instance moduleName params instanceName [] bindings) =
convertExpr (ContextDetermined tag) expr
replaceBindingExpr :: Identifier -> Int -> Expr -> Expr
replaceBindingExpr portName idx (orig @ (Repeat _ [ConvertedUU a b])) =
if orig == sizedLiteralFor tag ch
if orig == sizedLiteralFor tag bit
then Repeat portSize [ConvertedUU a b]
else orig
where
ch = charForBit a b
bit = bitForBased a b
portName' =
if null portName
then lookupBindingName portNames idx
......@@ -159,28 +159,21 @@ convertModuleItem' =
traverseTypes (traverseNestedTypes convertType) .
traverseAsgns convertAsgn
literalFor :: Char -> Expr
literalFor 'Z' = literalFor 'z'
literalFor 'X' = literalFor 'x'
literalFor '0' = Number $ Based 1 True Binary 0 0
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]
literalFor :: Bit -> Expr
literalFor = Number . (uncurry $ Based 1 True Binary) . bitToVK
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"
bitForBased :: Integer -> Integer -> Bit
bitForBased 0 0 = Bit0
bitForBased 1 0 = Bit1
bitForBased 0 1 = BitX
bitForBased _ _ = BitZ
sizedLiteralFor :: Expr -> Char -> Expr
sizedLiteralFor expr ch =
Repeat size [literalFor ch]
sizedLiteralFor :: Expr -> Bit -> Expr
sizedLiteralFor expr bit =
Repeat size [literalFor bit]
where size = DimsFn FnBits $ Right expr
convertAsgn :: (LHS, Expr) -> (LHS, Expr)
......@@ -251,14 +244,14 @@ convertExpr context (UniOp op expr) =
if isSizedUniOp op
then UniOp op (convertExpr context expr)
else UniOp op (convertExpr SelfDetermined expr)
convertExpr SelfDetermined (UU ch) =
literalFor ch
convertExpr (ContextDetermined expr) (UU ch) =
sizedLiteralFor expr ch
convertExpr SelfDetermined (UU bit) =
literalFor bit
convertExpr (ContextDetermined expr) (UU bit) =
sizedLiteralFor expr bit
convertExpr _ other = other
pattern UU :: Char -> Expr
pattern UU ch = Number (UnbasedUnsized ch)
pattern UU :: Bit -> Expr
pattern UU bit = Number (UnbasedUnsized bit)
convertType :: Type -> Type
convertType (TypeOf e) = TypeOf $ convertExpr SelfDetermined e
......
......@@ -7,11 +7,13 @@
module Language.SystemVerilog.AST.Number
( Number (..)
, Base (..)
, Bit (..)
, parseNumber
, numberBitLength
, numberIsSigned
, numberIsSized
, numberToInteger
, bitToVK
) where
import Data.Bits (shiftL)
......@@ -26,7 +28,10 @@ parseNumber = parseNumber' . map toLower . filter (not . isPad)
where isPad = flip elem "_ \n\t"
parseNumber' :: String -> Number
parseNumber' ['\'', ch] = UnbasedUnsized ch
parseNumber' "'0" = UnbasedUnsized Bit0
parseNumber' "'1" = UnbasedUnsized Bit1
parseNumber' "'x" = UnbasedUnsized BitX
parseNumber' "'z" = UnbasedUnsized BitZ
parseNumber' str =
-- simple decimal number
if maybeIdx == Nothing then
......@@ -145,6 +150,26 @@ zDigits = ['z', '?']
xzDigits :: [Char]
xzDigits = xDigits ++ zDigits
data Bit
= Bit0
| Bit1
| BitX
| BitZ
deriving (Eq, Ord)
instance Show Bit where
show Bit0 = "0"
show Bit1 = "1"
show BitX = "x"
show BitZ = "z"
-- convet an unbased unsized bit to its (values, kinds) pair
bitToVK :: Bit -> (Integer, Integer)
bitToVK Bit0 = (0, 0)
bitToVK Bit1 = (1, 0)
bitToVK BitX = (0, 1)
bitToVK BitZ = (1, 1)
data Base
= Binary
| Octal
......@@ -157,7 +182,7 @@ instance Show Base where
show Hex = "h"
data Number
= UnbasedUnsized Char
= UnbasedUnsized Bit
| Decimal Int Bool Integer
| Based Int Bool Base Integer Integer
deriving (Eq, Ord)
......@@ -191,8 +216,8 @@ numberIsSigned (Based _ signed _ _ _) = signed
-- get the integer value of a number, provided it has not X or Z bits
numberToInteger :: Number -> Maybe Integer
numberToInteger (UnbasedUnsized '1') = Just 1
numberToInteger (UnbasedUnsized '0') = Just 0
numberToInteger (UnbasedUnsized Bit1) = Just 1
numberToInteger (UnbasedUnsized Bit0) = Just 0
numberToInteger UnbasedUnsized{} = Nothing
numberToInteger (Decimal _ _ num) = Just num
numberToInteger (Based _ _ _ num 0) = Just num
......@@ -205,10 +230,8 @@ bits n = 1 + bits (quot n 2)
-- number to string conversion
instance Show Number where
show (UnbasedUnsized ch) =
if elem ch "01xzXZ"
then ['\'', ch]
else error $ "illegal unbased-unsized char: " ++ show ch
show (UnbasedUnsized bit) =
'\'' : show bit
show (Decimal (-32) True value) =
if value < 0
then error $ "illegal decimal: " ++ show value
......@@ -326,11 +349,5 @@ instance Semigroup Number where
toBased (n @ Based{}) = n
toBased (Decimal size signed num) =
Based size signed Hex num 0
toBased (UnbasedUnsized ch) =
case ch of
'0' -> based 0 0
'1' -> based 1 0
'x' -> based 0 1
'z' -> based 1 1
_ -> error $ "invalid unbased unsized char: " ++ show ch
where based = Based 1 False Binary
toBased (UnbasedUnsized bit) =
uncurry (Based 1 False Binary) (bitToVK bit)
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