Commit 8cfd05de by Zachary Snow

unbased unsized literals are context-aware

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