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