mirror of https://github.com/zachjs/sv2v.git
unbased unsized literals are context-aware
This commit is contained in:
parent
cbe0071e43
commit
8cfd05de1a
|
|
@ -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 @@
|
||||||
-
|
-
|
||||||
- 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
|
||||||
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;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
`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;
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
`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;
|
||||||
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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue