Commit 2bc2eb59 by Zachary Snow

advanced typeof support

- most binary operators
- ternary expressions
- bitwise negation
- number literals
- size casts
- concat and repeat expressions
parent d0a6b0f5
...@@ -12,7 +12,9 @@ ...@@ -12,7 +12,9 @@
module Convert.TypeOf (convert) where module Convert.TypeOf (convert) where
import Control.Monad.State import Control.Monad.State
import Data.List (elemIndex)
import Data.Maybe (fromMaybe, mapMaybe) import Data.Maybe (fromMaybe, mapMaybe)
import Data.Int (Int32)
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import Convert.Traverse import Convert.Traverse
...@@ -71,6 +73,11 @@ traverseTypeM (TypeOf expr) = typeof expr ...@@ -71,6 +73,11 @@ traverseTypeM (TypeOf expr) = typeof expr
traverseTypeM other = return other traverseTypeM other = return other
typeof :: Expr -> State Info Type 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 typeof (orig @ (Ident x)) = do
res <- gets $ Map.lookup x res <- gets $ Map.lookup x
return $ fromMaybe (TypeOf orig) res return $ fromMaybe (TypeOf orig) res
...@@ -93,9 +100,71 @@ typeof (orig @ (Range e mode r)) = do ...@@ -93,9 +100,71 @@ typeof (orig @ (Range e mode r)) = do
NonIndexed -> snd r NonIndexed -> snd r
IndexedPlus -> BinOp Sub (uncurry (BinOp Add) r) (Number "1") IndexedPlus -> BinOp Sub (uncurry (BinOp Add) r) (Number "1")
IndexedMinus -> BinOp Add (uncurry (BinOp Sub) 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 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 -- combines a type with unpacked ranges
injectRanges :: Type -> [Range] -> Type injectRanges :: Type -> [Range] -> Type
injectRanges t [] = t injectRanges t [] = t
......
...@@ -11,7 +11,9 @@ module top; ...@@ -11,7 +11,9 @@ module top;
initial begin initial begin
type(f(0)) x = f(0); type(f(0)) x = f(0);
type(x) y = ~x;
$display("%b", x); $display("%b", x);
$display("%b", y);
$display("%b", $bits(x)); $display("%b", $bits(x));
$display("%b", $bits(type(x))); $display("%b", $bits(type(x)));
$display("%b", $bits(logic [0:1+$bits(type(x))])); $display("%b", $bits(logic [0:1+$bits(type(x))]));
...@@ -19,4 +21,43 @@ module top; ...@@ -19,4 +21,43 @@ module top;
void'(f(0)); void'(f(0));
t(1); t(1);
end 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 endmodule
...@@ -12,9 +12,11 @@ module top; ...@@ -12,9 +12,11 @@ module top;
endtask endtask
initial begin : block initial begin : block
reg x; reg x, y;
x = f(0); x = f(0);
y = ~x;
$display("%b", x); $display("%b", x);
$display("%b", y);
$display("%b", 32'd1); $display("%b", 32'd1);
$display("%b", 32'd1); $display("%b", 32'd1);
$display("%b", 32'd3); $display("%b", 32'd3);
...@@ -22,4 +24,52 @@ module top; ...@@ -22,4 +24,52 @@ module top;
x = f(0); x = f(0);
t(1); t(1);
end 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 endmodule
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