limited progress on typeof signedness

- ensure concats and repeats stay unsigned
- defer unbased-unsized conversion to enable cast semantics
- disable inaccurate folding of binary operations of based numbers
- fix typeof and size cast binop signedness logic
- fix typeof $unsigned and $signed
- test harness allows production of `integer unsigned`
This commit is contained in:
Zachary Snow
2021-02-01 10:17:50 -05:00
parent 275130e0b0
commit b8759776ca
9 changed files with 342 additions and 28 deletions
+3
View File
@@ -34,6 +34,9 @@ module top;
$display("args %b", $size(RamPair, 1'dx));
`EXHAUST(Ram);
`EXHAUST(Ram[0]);
`EXHAUST($unsigned(Ram[0]));
`EXHAUST($signed(Ram[0]));
`EXHAUST(Ram[0+:2]);
`EXHAUST(Ram[1+:2]);
`EXHAUST(Ram[0][2-:1]);
+30
View File
@@ -23,6 +23,36 @@ module top;
$display(1);
$display(160);
$display(16, 16, 1'bx);
$display(16, 16, 1'bx);
$display(1, 1, 1'bx);
$display(16, 16, 1'bx);
$display(1, 1, 1'bx);
$display(1, 1, 1'bx);
$display(1);
$display(0);
$display(16);
$display(16, 16, 1'bx);
$display(15, 15, 1'bx);
$display(0, 0, 1'bx);
$display(15, 15, 1'bx);
$display(0, 0, 1'bx);
$display(1, 1, 1'bx);
$display(1);
$display(0);
$display(16);
$display(16, 16, 1'bx);
$display(15, 15, 1'bx);
$display(0, 0, 1'bx);
$display(15, 15, 1'bx);
$display(0, 0, 1'bx);
$display(1, 1, 1'bx);
$display(1);
$display(0);
$display(16);
$display(2, 2, 16);
$display(0, 0, 16);
$display(1, 1, 1);
+195
View File
@@ -0,0 +1,195 @@
`define ASSERT_SIGNEDNESS(expr, signedness_str, signedness_val) \
initial begin \
type(expr) typeof; \
logic signed [$bits(expr):0] ones; \
logic [$bits(expr):0] extd; \
typeof = 1'sb1; \
ones = 1'sb1; \
extd = typeof; \
if (signedness_val != (extd == ones)) \
$display(`"FAIL: expected (expr) to be treated as signedness_str extd=%b`", extd); \
end
`define ASSERT_SIGNED(expr) `ASSERT_SIGNEDNESS(expr, signed, 1)
`define ASSERT_UNSIGNED(expr) `ASSERT_SIGNEDNESS(expr, unsigned, 0)
`define MAKE_PRIM(typ) \
typ typ``_unspecified = 1; \
typ unsigned typ``_unsigned = 1; \
typ signed typ``_signed = 1; \
`ASSERT_SIGNED(typ``_signed) \
`ASSERT_UNSIGNED(typ``_unsigned)
`define MAKE_PRIM_SIGNED(typ) \
`MAKE_PRIM(typ) \
`ASSERT_SIGNED(typ``_unspecified)
`define MAKE_PRIM_UNSIGNED(typ) \
`MAKE_PRIM(typ) \
`ASSERT_UNSIGNED(typ``_unspecified)
module top;
logic signed x;
logic signed [1:0] y;
assign x = 0;
assign y = 2;
type(x % y) z;
assign z = x % y;
logic [3:0] w;
assign w = z;
initial #1 $display("%b %b %b %b", x, y, z, w);
`MAKE_PRIM_SIGNED(byte)
`MAKE_PRIM_SIGNED(shortint)
`MAKE_PRIM_SIGNED(int)
`MAKE_PRIM_SIGNED(integer)
`MAKE_PRIM_SIGNED(longint)
`MAKE_PRIM_UNSIGNED(bit)
`MAKE_PRIM_UNSIGNED(reg)
`MAKE_PRIM_UNSIGNED(logic)
reg signed [5:0] arr;
`ASSERT_SIGNED(0)
`ASSERT_SIGNED('sb0)
`ASSERT_UNSIGNED('b0)
`ASSERT_UNSIGNED('o0)
`ASSERT_UNSIGNED('d0)
`ASSERT_UNSIGNED('h0)
`ASSERT_SIGNED('sb0)
`ASSERT_SIGNED('so0)
`ASSERT_SIGNED('sd0)
`ASSERT_SIGNED('sh0)
`ASSERT_UNSIGNED({1'b0})
`ASSERT_UNSIGNED({1'o0})
`ASSERT_UNSIGNED({1'd0})
`ASSERT_UNSIGNED({1'h0})
`ASSERT_UNSIGNED({1'sb0})
`ASSERT_UNSIGNED({1'so0})
`ASSERT_UNSIGNED({1'sd0})
`ASSERT_UNSIGNED({1'sh0})
`ASSERT_UNSIGNED({reg_unspecified})
`ASSERT_UNSIGNED({reg_unsigned})
`ASSERT_UNSIGNED({reg_signed})
`ASSERT_UNSIGNED({1 {1'b0}})
`ASSERT_UNSIGNED({1 {1'o0}})
`ASSERT_UNSIGNED({1 {1'd0}})
`ASSERT_UNSIGNED({1 {1'h0}})
`ASSERT_UNSIGNED({1 {1'sb0}})
`ASSERT_UNSIGNED({1 {1'so0}})
`ASSERT_UNSIGNED({1 {1'sd0}})
`ASSERT_UNSIGNED({1 {1'sh0}})
`ASSERT_UNSIGNED({1 {reg_unspecified}})
`ASSERT_UNSIGNED({1 {reg_unsigned}})
`ASSERT_UNSIGNED({1 {reg_signed}})
`ASSERT_SIGNED($signed(reg_unspecified))
`ASSERT_SIGNED($signed(reg_unsigned))
`ASSERT_SIGNED($signed(reg_signed))
`ASSERT_UNSIGNED($unsigned(reg_unspecified))
`ASSERT_UNSIGNED($unsigned(reg_unsigned))
`ASSERT_UNSIGNED($unsigned(reg_signed))
`define UNIOP_ALWAYS_UNSIGNED(op) \
`ASSERT_UNSIGNED(op 2'sb11) \
`ASSERT_UNSIGNED(op 2'b11) \
`ASSERT_UNSIGNED(op reg_signed) \
`ASSERT_UNSIGNED(op reg_unsigned)
`define UNIOP_SAME_SIGN(op) \
`ASSERT_SIGNED(op 2'sb11) \
`ASSERT_UNSIGNED(op 2'b11) \
`ASSERT_SIGNED(op reg_signed) \
`ASSERT_UNSIGNED(op reg_unsigned)
`UNIOP_ALWAYS_UNSIGNED(!)
`UNIOP_SAME_SIGN(~)
`UNIOP_SAME_SIGN(+)
`UNIOP_SAME_SIGN(-)
`UNIOP_ALWAYS_UNSIGNED(&)
`UNIOP_ALWAYS_UNSIGNED(~&)
`UNIOP_ALWAYS_UNSIGNED(|)
`UNIOP_ALWAYS_UNSIGNED(~|)
`UNIOP_ALWAYS_UNSIGNED(^)
`UNIOP_ALWAYS_UNSIGNED(~^)
`define BINOP_BOTH_SIGNED(op) \
`ASSERT_SIGNED(reg_signed op reg_signed) \
`ASSERT_UNSIGNED(reg_unsigned op reg_signed) \
`ASSERT_UNSIGNED(reg_signed op reg_unsigned) \
`ASSERT_UNSIGNED(reg_unsigned op reg_unsigned) \
`ASSERT_UNSIGNED(reg_unsigned op arr) \
`ASSERT_UNSIGNED(arr op reg_unsigned) \
`ASSERT_SIGNED(arr op arr) \
`ASSERT_SIGNED(arr op reg_signed) \
`ASSERT_SIGNED(reg_signed op arr) \
`ASSERT_SIGNED(1'sb1 op 2'sb11) \
`ASSERT_UNSIGNED(1'b1 op 2'sb11) \
`ASSERT_UNSIGNED(1'sb1 op 2'b11) \
`ASSERT_UNSIGNED(1'b1 op 2'b11)
`define BINOP_FIRST_SIGNED(op) \
`ASSERT_SIGNED(reg_signed op reg_signed) \
`ASSERT_UNSIGNED(reg_unsigned op reg_signed) \
`ASSERT_SIGNED(reg_signed op reg_unsigned) \
`ASSERT_UNSIGNED(reg_unsigned op reg_unsigned) \
`ASSERT_SIGNED(1'sb1 op 2'sb11) \
`ASSERT_UNSIGNED(1'b1 op 2'sb11) \
`ASSERT_SIGNED(1'sb1 op 2'b11) \
`ASSERT_UNSIGNED(1'b1 op 2'b11)
`define BINOP_NEVER_SIGNED(op) \
`ASSERT_UNSIGNED(reg_signed op reg_signed) \
`ASSERT_UNSIGNED(reg_unsigned op reg_signed) \
`ASSERT_UNSIGNED(reg_signed op reg_unsigned) \
`ASSERT_UNSIGNED(reg_unsigned op reg_unsigned) \
`ASSERT_UNSIGNED(1'sb1 op 2'sb11) \
`ASSERT_UNSIGNED(1'b1 op 2'sb11) \
`ASSERT_UNSIGNED(1'sb1 op 2'b11) \
`ASSERT_UNSIGNED(1'b1 op 2'b11)
`BINOP_NEVER_SIGNED(&& )
`BINOP_NEVER_SIGNED(|| )
`BINOP_NEVER_SIGNED(-> )
`BINOP_NEVER_SIGNED(<->)
`BINOP_BOTH_SIGNED( & )
`BINOP_BOTH_SIGNED( ^ )
`BINOP_BOTH_SIGNED( ~^ )
`BINOP_BOTH_SIGNED( | )
`BINOP_BOTH_SIGNED( * )
`BINOP_BOTH_SIGNED( / )
`BINOP_BOTH_SIGNED( + )
`BINOP_BOTH_SIGNED( - )
`BINOP_FIRST_SIGNED(** )
`BINOP_FIRST_SIGNED(<< )
`BINOP_FIRST_SIGNED(>> )
`BINOP_FIRST_SIGNED(<<<)
`BINOP_FIRST_SIGNED(>>>)
`BINOP_NEVER_SIGNED(== )
`BINOP_NEVER_SIGNED(!= )
`BINOP_NEVER_SIGNED(===)
`BINOP_NEVER_SIGNED(!==)
`BINOP_NEVER_SIGNED(==?)
`BINOP_NEVER_SIGNED(!=?)
`BINOP_NEVER_SIGNED(< )
`BINOP_NEVER_SIGNED(<= )
`BINOP_NEVER_SIGNED(> )
`BINOP_NEVER_SIGNED(>= )
`ASSERT_UNSIGNED(4'('0))
`ASSERT_UNSIGNED(3'('x))
`ASSERT_SIGNED(2'(1'sb1))
`ASSERT_SIGNED(10'(2'sb11))
`ASSERT_UNSIGNED(10'(2'b11))
`ASSERT_UNSIGNED(2'(1'b1))
`ASSERT_SIGNED(2'(reg_signed))
`ASSERT_UNSIGNED(2'(reg_unsigned))
`ASSERT_SIGNED(arr)
`ASSERT_UNSIGNED(arr[0])
`ASSERT_UNSIGNED(arr[5:0])
`ASSERT_UNSIGNED(arr[1+:2])
`ASSERT_UNSIGNED(arr[1-:2])
endmodule
+30
View File
@@ -0,0 +1,30 @@
`define MAKE_PRIM(typ, base, size) \
base [size-1:0] typ``_unspecified = 1; \
base unsigned [size-1:0] typ``_unsigned = 1; \
base signed [size-1:0] typ``_signed = 1;
module top;
wire signed x;
wire signed [1:0] y;
assign x = 0;
assign y = 2;
wire signed [1:0] z;
assign z = x % y;
wire [3:0] w;
assign w = z;
initial #1 $display("%b %b %b %b", x, y, z, w);
`MAKE_PRIM(byte, reg, 8)
`MAKE_PRIM(shortint, reg, 16)
`MAKE_PRIM(int, reg, 32)
integer integer_unspecified = 1;
integer unsigned integer_unsigned = 1;
integer signed integer_signed = 1;
`MAKE_PRIM(longint, reg, 64)
`MAKE_PRIM(bit, wire, 1)
`MAKE_PRIM(reg, reg, 1)
`MAKE_PRIM(logic, wire, 1)
reg signed [5:0] arr;
endmodule