mirror of https://github.com/zachjs/sv2v.git
fix conversion of signed struct fields accessed directly
This commit is contained in:
parent
effeded6d1
commit
336812ff21
|
|
@ -33,6 +33,8 @@
|
|||
procedural assignment
|
||||
* `always_comb` and `always_latch` now generate explicit sensitivity lists where
|
||||
necessary because of calls to functions which reference non-local data
|
||||
* Fixed signed `struct` fields being converted to unsigned expressions when
|
||||
accessed directly
|
||||
|
||||
## v0.0.9
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
{-# LANGUAGE PatternSynonyms #-}
|
||||
{-# LANGUAGE TupleSections #-}
|
||||
{- sv2v
|
||||
- Author: Zachary Snow <zach@zachjs.com>
|
||||
|
|
@ -363,12 +364,19 @@ fallbackType scopes e =
|
|||
Nothing -> UnknownType
|
||||
Just (_, _, typ) -> typ
|
||||
|
||||
pattern MakeSigned :: Expr -> Expr
|
||||
pattern MakeSigned e = Call (Ident "$signed") (Args [e] [])
|
||||
|
||||
-- converting LHSs by looking at the innermost types first
|
||||
convertLHS :: LHS -> Scoper Type (Type, LHS)
|
||||
convertLHS l = do
|
||||
let e = lhsToExpr l
|
||||
(t, e') <- embedScopes convertSubExpr e
|
||||
let Just l' = exprToLHS e'
|
||||
-- per IEEE 1800-2017 sections 10.7 and 11.8, the signedness of the LHS does
|
||||
-- not affect the evaluation and sign-extension of the RHS
|
||||
let Just l' = exprToLHS $ case e' of
|
||||
MakeSigned e'' -> e''
|
||||
_ -> e'
|
||||
return (t, l')
|
||||
|
||||
-- try expression conversion by looking at the *innermost* type first
|
||||
|
|
@ -379,7 +387,7 @@ convertSubExpr scopes (Dot e x) =
|
|||
else if structIsntReady subExprType then
|
||||
(fieldType, Dot e' x)
|
||||
else
|
||||
(fieldType, undotted)
|
||||
(fieldType, undottedWithSign)
|
||||
where
|
||||
(subExprType, e') = convertSubExpr scopes e
|
||||
(fieldType, bounds, dims) = lookupFieldInfo scopes subExprType e' x
|
||||
|
|
@ -388,6 +396,14 @@ convertSubExpr scopes (Dot e x) =
|
|||
undotted = if null dims || rangeSize (head dims) == RawNum 1
|
||||
then Bit e' (fst bounds)
|
||||
else Range e' IndexedMinus (base, len)
|
||||
-- retain signedness of fields which would otherwise be lost via the
|
||||
-- resulting bit or range selection
|
||||
IntegerVector _ fieldSg _ = fieldType
|
||||
undottedWithSign =
|
||||
if fieldSg == Signed
|
||||
then MakeSigned undotted
|
||||
else undotted
|
||||
|
||||
convertSubExpr scopes (Range (Dot e x) NonIndexed rOuter) =
|
||||
if isntStruct subExprType then
|
||||
(UnknownType, orig')
|
||||
|
|
|
|||
|
|
@ -5,8 +5,15 @@ module test;
|
|||
logic z;
|
||||
} struct_a;
|
||||
struct_a a;
|
||||
wire signed [31:0] a_w, a_x;
|
||||
wire signed [7:0] a_y;
|
||||
assign a_w = a.w;
|
||||
assign a_x = a.x;
|
||||
assign a_y = a.y;
|
||||
initial begin
|
||||
$monitor("%2d: %b %b %b %b %b", $time, a, a.w, a.x, a.y, a.z);
|
||||
// TODO: The signed fields should not have to be indirected here, but
|
||||
// iverilog does not currently support complex arguments to $monitor.
|
||||
$monitor("%2d: %b %b %b %b %b", $time, a, a_w, a_x, a_y, a.z);
|
||||
|
||||
#1 a.w = 0;
|
||||
#1 a.x = 0;
|
||||
|
|
@ -41,9 +48,13 @@ module test;
|
|||
logic z;
|
||||
} struct_b;
|
||||
struct_b b;
|
||||
wire signed [31:0] b_x;
|
||||
assign b_x = b.x;
|
||||
initial begin
|
||||
#100;
|
||||
$monitor("%2d: %b %b %b %b", $time, b, b.x, b.y, b.z);
|
||||
// TODO: The signed fields should not have to be indirected here, but
|
||||
// iverilog does not currently support complex arguments to $monitor.
|
||||
$monitor("%2d: %b %b %b %b", $time, b, b_x, b.y, b.z);
|
||||
|
||||
#1 b.x = 0;
|
||||
#1 b.y = 0;
|
||||
|
|
|
|||
|
|
@ -206,4 +206,34 @@ module top;
|
|||
`ASSERT_UNSIGNED(STR_L)
|
||||
`ASSERT_UNSIGNED(64'(STR_P))
|
||||
`ASSERT_UNSIGNED(64'(STR_L))
|
||||
|
||||
struct packed {
|
||||
logic w;
|
||||
logic signed x;
|
||||
logic [1:0] y;
|
||||
logic signed [1:0] z;
|
||||
struct packed {
|
||||
logic w;
|
||||
logic signed x;
|
||||
logic [1:0] y;
|
||||
logic signed [1:0] z;
|
||||
} i;
|
||||
} s = '1;
|
||||
struct packed signed {
|
||||
logic w;
|
||||
logic signed x;
|
||||
logic [1:0] y;
|
||||
logic signed [1:0] z;
|
||||
} t = '1;
|
||||
`ASSERT_UNSIGNED(s)
|
||||
`ASSERT_UNSIGNED(s.w)
|
||||
`ASSERT_UNSIGNED(s.y)
|
||||
`ASSERT_SIGNED(s.x)
|
||||
`ASSERT_SIGNED(s.z)
|
||||
`ASSERT_UNSIGNED(s.i)
|
||||
`ASSERT_UNSIGNED(s.i.w)
|
||||
`ASSERT_UNSIGNED(s.i.y)
|
||||
`ASSERT_SIGNED(s.i.x)
|
||||
`ASSERT_SIGNED(s.i.z)
|
||||
`ASSERT_SIGNED(t)
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -27,4 +27,9 @@ module top;
|
|||
`MAKE_PRIM(logic, 1)
|
||||
|
||||
reg signed [5:0] arr;
|
||||
|
||||
reg signed [11:0] s;
|
||||
initial s = 1'sb1;
|
||||
reg [5:0] t;
|
||||
initial t = 1'sb1;
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Reference in New Issue