mirror of https://github.com/zachjs/sv2v.git
advanced typeof support
- most binary operators - ternary expressions - bitwise negation - number literals - size casts - concat and repeat expressions
This commit is contained in:
parent
d0a6b0f529
commit
2bc2eb59d8
|
|
@ -12,7 +12,9 @@
|
|||
module Convert.TypeOf (convert) where
|
||||
|
||||
import Control.Monad.State
|
||||
import Data.List (elemIndex)
|
||||
import Data.Maybe (fromMaybe, mapMaybe)
|
||||
import Data.Int (Int32)
|
||||
import qualified Data.Map.Strict as Map
|
||||
|
||||
import Convert.Traverse
|
||||
|
|
@ -71,6 +73,11 @@ traverseTypeM (TypeOf expr) = typeof expr
|
|||
traverseTypeM other = return other
|
||||
|
||||
typeof :: Expr -> State Info Type
|
||||
typeof (Number n) =
|
||||
return $ IntegerVector TLogic sg [r]
|
||||
where
|
||||
(size, sg) = parseNumber n
|
||||
r = (Number $ show (size - 1), Number "0")
|
||||
typeof (orig @ (Ident x)) = do
|
||||
res <- gets $ Map.lookup x
|
||||
return $ fromMaybe (TypeOf orig) res
|
||||
|
|
@ -93,9 +100,71 @@ typeof (orig @ (Range e mode r)) = do
|
|||
NonIndexed -> snd r
|
||||
IndexedPlus -> BinOp Sub (uncurry (BinOp Add) r) (Number "1")
|
||||
IndexedMinus -> BinOp Add (uncurry (BinOp Sub) r) (Number "1")
|
||||
typeof (BinOp Add e Number{}) = typeof e
|
||||
typeof (orig @ (Cast (Right (Ident x)) _)) = do
|
||||
typeMap <- get
|
||||
if Map.member x typeMap
|
||||
then return $ typeOfSize (Ident x)
|
||||
else return $ TypeOf orig
|
||||
typeof (Cast (Right s) _) = return $ typeOfSize s
|
||||
typeof (UniOp BitNot e ) = typeof e
|
||||
typeof (BinOp Pow e _) = typeof e
|
||||
typeof (BinOp ShiftL e _) = typeof e
|
||||
typeof (BinOp ShiftR e _) = typeof e
|
||||
typeof (BinOp ShiftAL e _) = typeof e
|
||||
typeof (BinOp ShiftAR e _) = typeof e
|
||||
typeof (BinOp Add a b) = return $ largerSizeType a b
|
||||
typeof (BinOp Sub a b) = return $ largerSizeType a b
|
||||
typeof (BinOp Mul a b) = return $ largerSizeType a b
|
||||
typeof (BinOp Div a b) = return $ largerSizeType a b
|
||||
typeof (BinOp Mod a b) = return $ largerSizeType a b
|
||||
typeof (BinOp BitAnd a b) = return $ largerSizeType a b
|
||||
typeof (BinOp BitXor a b) = return $ largerSizeType a b
|
||||
typeof (BinOp BitXnor a b) = return $ largerSizeType a b
|
||||
typeof (BinOp BitOr a b) = return $ largerSizeType a b
|
||||
typeof (Mux _ a b) = return $ largerSizeType a b
|
||||
typeof (Concat exprs) = return $ typeOfSize $ concatSize exprs
|
||||
typeof (Repeat reps exprs) = return $ typeOfSize size
|
||||
where size = BinOp Mul reps (concatSize exprs)
|
||||
typeof other = return $ TypeOf other
|
||||
|
||||
-- determines the size and sign of a number literal
|
||||
parseNumber :: String -> (Int32, 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
|
||||
largerSizeType :: Expr -> Expr -> Type
|
||||
largerSizeType a b =
|
||||
typeOfSize larger
|
||||
where
|
||||
sizeof = DimsFn FnBits . Right
|
||||
cond = BinOp Ge (sizeof a) (sizeof b)
|
||||
larger = Mux cond (sizeof a) (sizeof b)
|
||||
|
||||
-- returns the total size of concatenated list of expressions
|
||||
concatSize :: [Expr] -> Expr
|
||||
concatSize exprs =
|
||||
foldl (BinOp Add) (Number "0") $
|
||||
map sizeof exprs
|
||||
where
|
||||
sizeof = DimsFn FnBits . Right
|
||||
|
||||
-- produces a generic type of the given size
|
||||
typeOfSize :: Expr -> Type
|
||||
typeOfSize size =
|
||||
IntegerVector TLogic sg [(hi, Number "0")]
|
||||
where
|
||||
sg = Unspecified -- suitable for now
|
||||
hi = BinOp Sub size (Number "1")
|
||||
|
||||
-- combines a type with unpacked ranges
|
||||
injectRanges :: Type -> [Range] -> Type
|
||||
injectRanges t [] = t
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@ module top;
|
|||
|
||||
initial begin
|
||||
type(f(0)) x = f(0);
|
||||
type(x) y = ~x;
|
||||
$display("%b", x);
|
||||
$display("%b", y);
|
||||
$display("%b", $bits(x));
|
||||
$display("%b", $bits(type(x)));
|
||||
$display("%b", $bits(logic [0:1+$bits(type(x))]));
|
||||
|
|
@ -19,4 +21,43 @@ module top;
|
|||
void'(f(0));
|
||||
t(1);
|
||||
end
|
||||
|
||||
parameter FLAG = 1;
|
||||
initial begin
|
||||
logic [4:1] x = 4'b1011;
|
||||
type(x ^ 3'b111) y = x ^ 3'b111;
|
||||
type(x ^ 5'b11111) z = x ^ 5'b11111;
|
||||
type({8 {x}}) a = {8 {x}};
|
||||
type({x, y}) b = {x, y};
|
||||
type(FLAG ? x : y) c = FLAG ? x : y;
|
||||
type(!FLAG ? x : y) d = !FLAG ? x : y;
|
||||
$display("%b %d %d", x, $left(x), $right(x));
|
||||
$display("%b %d %d", y, $left(y), $right(y));
|
||||
$display("%b %d %d", z, $left(z), $right(z));
|
||||
$display("%b %d %d", a, $left(a), $right(a));
|
||||
$display("%b %d %d", b, $left(b), $right(b));
|
||||
$display("%b %d %d", c, $left(c), $right(c));
|
||||
$display("%b %d %d", d, $left(d), $right(d));
|
||||
end
|
||||
|
||||
parameter W = 4;
|
||||
initial begin
|
||||
logic [W-1:0] x = 4'hA;
|
||||
type(FLAG ? x : '1) y = FLAG ? x : '1;
|
||||
type(!FLAG ? y : '1) z = !FLAG ? y : '1;
|
||||
$display("%b %d %d", x, $left(x), $right(x));
|
||||
$display("%b %d %d", y, $left(y), $right(y));
|
||||
$display("%b %d %d", z, $left(z), $right(z));
|
||||
end
|
||||
|
||||
initial begin
|
||||
type(1) w = 1;
|
||||
type(-1) x = -1;
|
||||
type(32'hffff_ffff) y = 32'hffff_ffff;
|
||||
type(32'shffff_ffff) z = 32'shffff_ffff;
|
||||
$display("%b %d %d %d", w, w, $left(w), $right(w));
|
||||
$display("%b %d %d %d", x, x, $left(x), $right(x));
|
||||
$display("%b %d %d %d", y, y, $left(y), $right(y));
|
||||
$display("%b %d %d %d", z, z, $left(z), $right(z));
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -12,9 +12,11 @@ module top;
|
|||
endtask
|
||||
|
||||
initial begin : block
|
||||
reg x;
|
||||
reg x, y;
|
||||
x = f(0);
|
||||
y = ~x;
|
||||
$display("%b", x);
|
||||
$display("%b", y);
|
||||
$display("%b", 32'd1);
|
||||
$display("%b", 32'd1);
|
||||
$display("%b", 32'd3);
|
||||
|
|
@ -22,4 +24,52 @@ module top;
|
|||
x = f(0);
|
||||
t(1);
|
||||
end
|
||||
|
||||
parameter FLAG = 1;
|
||||
initial begin : block2
|
||||
reg [4:1] x;
|
||||
reg [3:0] y;
|
||||
reg [4:0] z;
|
||||
reg [31:0] a;
|
||||
reg [7:0] b;
|
||||
reg [3:0] c, d;
|
||||
x = 4'b1011;
|
||||
y = x ^ 3'b111;
|
||||
z = x ^ 5'b11111;
|
||||
a = {8 {x}};
|
||||
b = {x, y};
|
||||
c = FLAG ? x : y;
|
||||
d = !FLAG ? x : y;
|
||||
$display("%b %d %d", x, 4, 1);
|
||||
$display("%b %d %d", y, 3, 0);
|
||||
$display("%b %d %d", z, 4, 0);
|
||||
$display("%b %d %d", a, 31, 0);
|
||||
$display("%b %d %d", b, 7, 0);
|
||||
$display("%b %d %d", c, 3, 0);
|
||||
$display("%b %d %d", d, 3, 0);
|
||||
end
|
||||
|
||||
parameter W = 4;
|
||||
initial begin : block3
|
||||
reg [W-1:0] x, y, z;
|
||||
x = 4'hA;
|
||||
y = FLAG ? x : 4'hF;
|
||||
z = !FLAG ? y : 4'hF;
|
||||
$display("%b %d %d", x, W-1, 0);
|
||||
$display("%b %d %d", y, W-1, 0);
|
||||
$display("%b %d %d", z, W-1, 0);
|
||||
end
|
||||
|
||||
initial begin : block4
|
||||
integer w, x, z;
|
||||
reg [31:0] y;
|
||||
w = 1;
|
||||
x = -1;
|
||||
y = 32'hffff_ffff;
|
||||
z = 32'shffff_ffff;
|
||||
$display("%b %d %d %d", w, w, 31, 0);
|
||||
$display("%b %d %d %d", x, x, 31, 0);
|
||||
$display("%b %d %d %d", y, y, 31, 0);
|
||||
$display("%b %d %d %d", z, z, 31, 0);
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Reference in New Issue