sv: fix some edge cases for unbased unsized literals

- Fix explicit size cast of unbased unsized literals
- Fix unbased unsized literal bound directly to port
- Output `is_unsized` flag in `dumpAst`
This commit is contained in:
Zachary Snow 2021-03-03 14:36:19 -05:00 committed by Zachary Snow
parent d245e2bae5
commit b1a8e73a60
4 changed files with 70 additions and 1 deletions

View File

@ -317,6 +317,8 @@ void AstNode::dumpAst(FILE *f, std::string indent) const
fprintf(f, " reg");
if (is_signed)
fprintf(f, " signed");
if (is_unsized)
fprintf(f, " unsized");
if (basic_prep)
fprintf(f, " basic_prep");
if (lookahead)

View File

@ -915,6 +915,22 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
}
}
if (type == AST_ARGUMENT)
{
if (children.size() == 1 && children[0]->type == AST_CONSTANT)
{
// HACK: For port bindings using unbased unsized literals, mark them
// signed so they sign-extend. The hierarchy will still incorrectly
// generate a warning complaining about resizing the expression.
// This also doesn't handle the complex of something like a ternary
// expression bound to a port, where the actual size of the port is
// needed to resolve the expression correctly.
AstNode *arg = children[0];
if (arg->is_unsized)
arg->is_signed = true;
}
}
int backup_width_hint = width_hint;
bool backup_sign_hint = sign_hint;
@ -3773,7 +3789,11 @@ replace_fcall_later:;
case AST_CAST_SIZE:
if (children.at(0)->type == AST_CONSTANT && children.at(1)->type == AST_CONSTANT) {
int width = children[0]->bitsAsConst().as_int();
RTLIL::Const val = children[1]->bitsAsConst(width);
RTLIL::Const val;
if (children[1]->is_unsized)
val = children[1]->bitsAsUnsizedConst(width);
else
val = children[1]->bitsAsConst(width);
newNode = mkconst_bits(val.bits, children[1]->is_signed);
}
break;

View File

@ -0,0 +1,40 @@
module pass_through(
input [63:0] inp,
output [63:0] out
);
assign out = inp;
endmodule
module top;
logic [63:0]
o01, o02, o03, o04,
o05, o06, o07, o08,
o09, o10, o11, o12,
o13, o14, o15, o16;
assign o01 = '0;
assign o02 = '1;
assign o03 = 'x;
assign o04 = 'z;
assign o05 = 3'('0);
assign o06 = 3'('1);
assign o07 = 3'('x);
assign o08 = 3'('z);
pass_through pt09('0, o09);
pass_through pt10('1, o10);
pass_through pt11('x, o11);
pass_through pt12('z, o12);
always @* begin
assert (o01 === {64 {1'b0}});
assert (o02 === {64 {1'b1}});
assert (o03 === {64 {1'bx}});
assert (o04 === {64 {1'bz}});
assert (o05 === {61'b0, 3'b000});
assert (o06 === {61'b0, 3'b111});
assert (o07 === {61'b0, 3'bxxx});
assert (o08 === {61'b0, 3'bzzz});
assert (o09 === {64 {1'b0}});
assert (o10 === {64 {1'b1}});
assert (o11 === {64 {1'bx}});
assert (o12 === {64 {1'bz}});
end
endmodule

View File

@ -0,0 +1,7 @@
read_verilog -sv unbased_unsized.sv
hierarchy
proc
flatten
opt -full
select -module top
sat -verify -seq 1 -tempinduct -prove-asserts -show-all