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)
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
`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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
`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
|
||||
|
|
|
|||
Loading…
Reference in New Issue