Commit 8cfd05de by Zachary Snow

unbased unsized literals are context-aware

parent cbe0071e
......@@ -106,6 +106,7 @@ typeof (orig @ (Cast (Right (Ident x)) _)) = do
then return $ typeOfSize (Ident x)
else return $ TypeOf orig
typeof (Cast (Right s) _) = return $ typeOfSize s
typeof (UniOp UniSub e ) = typeof e
typeof (UniOp BitNot e ) = typeof e
typeof (BinOp Pow e _) = typeof e
typeof (BinOp ShiftL e _) = typeof e
......
......@@ -3,13 +3,10 @@
-
- Conversion for unbased, unsized literals ('0, '1, 'z, 'x)
-
- The literals are given a binary base, a size of 1, and are made signed to
- allow sign extension. This enables the desired implicit casting in
- Verilog-2005.
-
- However, in a ternary expressions, these literals should take on the sign and
- size of their counterpart. To work around this, we explicitly size cast these
- literlas when they appear within a ternary expression.
- The literals are given a binary base and are made signed to allow sign
- extension. This enables the desired implicit casting in Verilog-2005.
- However, in self-determined contextes, the literals are given an explicit
- size of 1.
-}
module Convert.UnbasedUnsized (convert) where
......@@ -18,32 +15,60 @@ import Convert.Traverse
import Language.SystemVerilog.AST
convert :: [AST] -> [AST]
convert =
map $
traverseDescriptions $ traverseModuleItems $
traverseExprs $ traverseNestedExprs convertExpr
convert = map $ traverseDescriptions $ traverseModuleItems convertModuleItem
convertModuleItem :: ModuleItem -> ModuleItem
convertModuleItem =
traverseExprs (traverseNestedExprs convertExpr) .
traverseStmts (traverseNestedStmts convertStmt) .
traverseTypes (traverseNestedTypes convertType)
digits :: [Char]
digits = ['0', '1', 'x', 'z', 'X', 'Z']
literalFor :: Char -> Expr
literalFor ch =
literalFor :: String -> Char -> Expr
literalFor prefix ch =
if elem ch digits
then Number ("1'sb" ++ [ch])
then Number (prefix ++ [ch])
else error $ "unexpected unbased-unsized digit: " ++ [ch]
sizedLiteralFor :: Char -> Expr
sizedLiteralFor = literalFor "1'sb"
unsizedLiteralFor :: Char -> Expr
unsizedLiteralFor '1' = UniOp UniSub $ Number "'sd1"
unsizedLiteralFor ch = literalFor "'sd" ch
convertExpr :: Expr -> Expr
convertExpr (Mux cond left right) =
Mux cond (convertExprCast left right) (convertExprCast right left)
convertExpr (DimsFn fn (Right e)) =
DimsFn fn $ Right $ convertSizeExpr e
convertExpr (Concat exprs) =
Concat $ map convertSelfDeterminedExpr exprs
convertExpr (Repeat count exprs) =
Repeat count $ map convertSelfDeterminedExpr exprs
convertExpr (Number ['\'', ch]) =
literalFor ch
unsizedLiteralFor ch
convertExpr other = other
convertExprCast :: Expr -> Expr -> Expr
convertExprCast (Number ['\'', ch]) other =
Cast (Right size) (literalFor ch)
convertSelfDeterminedExpr :: Expr -> Expr
convertSelfDeterminedExpr (Number ['\'', ch]) =
sizedLiteralFor ch
convertSelfDeterminedExpr other = other
convertStmt :: Stmt -> Stmt
convertStmt (Subroutine (fn @ (Ident ('$' : _))) (Args args [])) =
Subroutine fn (Args args' [])
where args' = map convertSelfDeterminedExpr args
convertStmt other = other
convertType :: Type -> Type
convertType (TypeOf e) = TypeOf $ convertSizeExpr e
convertType other = other
convertSizeExpr :: Expr -> Expr
convertSizeExpr (Mux cond e1 e2) =
Mux cond e1' e2'
where
size = case other of
Number ['\'', _] -> Number "32"
_ -> DimsFn FnBits $ Right other
convertExprCast other _ = other
e1' = convertSelfDeterminedExpr e1
e2' = convertSelfDeterminedExpr e2
convertSizeExpr e = convertSelfDeterminedExpr e
......@@ -42,9 +42,11 @@ module top;
parameter W = 4;
initial begin
type('1) w = '1;
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", w, $left(w), $right(w));
$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));
......
......@@ -51,10 +51,13 @@ module top;
parameter W = 4;
initial begin : block3
reg w;
reg [W-1:0] x, y, z;
w = 1;
x = 4'hA;
y = FLAG ? x : 4'hF;
z = !FLAG ? y : 4'hF;
$display("%b %d %d", w, 0, 0);
$display("%b %d %d", x, W-1, 0);
$display("%b %d %d", y, W-1, 0);
$display("%b %d %d", z, W-1, 0);
......
`define TEST(value) \
logic [63:0] val_``value = 'value; \
initial $display(`"'value -> %b %b", val_``value, 'value);
initial $display(`"'value -> %b (%0d) %b (%0d)", \
val_``value, $bits(val_``value), \
'value, $bits('value) \
);
module top;
`TEST(1);
......@@ -13,14 +16,34 @@ module top;
logic [31:0] a;
logic [31:0] b;
logic [31:0] c;
logic [63:0] j;
logic [63:0] d;
logic [63:0] e;
initial begin
i = 42;
j = 42;
flag = 1;
a = (flag ? '1 : i);
b = (flag ? 'x : i);
c = (flag ? '1 : '0);
d = (flag ? '1 : j);
e = (flag ? 'x : j);
$display("%b", a);
$display("%b", b);
$display("%b", c);
$display("%b", d);
$display("%b", e);
end
initial begin
$display("%b", {'1, 'x, 'z, '0});
$display("%b", {2 {'1, 'x, 'z, '0}});
end
initial begin
$display($bits('1));
$display($bits(flag ? '1 : 'x));
$display($bits(type('1)));
$display($bits(type(flag ? '1 : 'x)));
end
endmodule
`define TEST(value) \
wire [63:0] val_``value = {64{1'b``value}}; \
initial $display(`"'value -> %b %b", val_``value, 1'b``value);
initial $display(`"'value -> %b (%0d) %b (%0d)", \
val_``value, $bits(val_``value), \
1'b``value, $bits(1'b``value) \
);
module top;
`TEST(1)
......@@ -13,14 +16,34 @@ module top;
reg [31:0] a;
reg [31:0] b;
reg [31:0] c;
reg [63:0] j;
reg [63:0] d;
reg [63:0] e;
initial begin
i = 42;
j = 42;
flag = 1;
a = (flag ? 32'hFFFFFFFF : i);
b = (flag ? 32'hXXXXXXXX : i);
c = (flag ? 32'hFFFFFFFF: i);
d = (flag ? 64'hFFFFFFFFFFFFFFFF : j);
e = (flag ? 64'hXXXXXXXXXXXXXXXX : j);
$display("%b", a);
$display("%b", b);
$display("%b", c);
$display("%b", d);
$display("%b", e);
end
initial begin
$display("%b", 4'b1xz0);
$display("%b", {4'b1xz0, 4'b1xz0});
end
initial begin
$display(1);
$display(1);
$display(1);
$display(1);
end
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