mirror of https://github.com/YosysHQ/yosys.git
More fixes in ast expression sign/width handling
This commit is contained in:
parent
618b2ac994
commit
5dab327b30
|
@ -530,7 +530,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_TO_UNSIGNED:
|
case AST_TO_UNSIGNED:
|
||||||
children.at(0)->detectSignWidthWorker(width_hint, sign_hint);
|
children.at(0)->detectSignWidthWorker(width_hint, dummy_sign_hint);
|
||||||
sign_hint = false;
|
sign_hint = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -593,8 +593,8 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint)
|
||||||
case AST_LOGIC_AND:
|
case AST_LOGIC_AND:
|
||||||
case AST_LOGIC_OR:
|
case AST_LOGIC_OR:
|
||||||
case AST_LOGIC_NOT:
|
case AST_LOGIC_NOT:
|
||||||
for (auto child : children)
|
width_hint = std::max(width_hint, 1);
|
||||||
child->detectSignWidthWorker(width_hint, sign_hint);
|
sign_hint = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_TERNARY:
|
case AST_TERNARY:
|
||||||
|
@ -835,7 +835,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
// just pass thru the signal. the parent will evaluated the is_signed property and inperpret the SigSpec accordingly
|
// just pass thru the signal. the parent will evaluated the is_signed property and inperpret the SigSpec accordingly
|
||||||
case AST_TO_SIGNED:
|
case AST_TO_SIGNED:
|
||||||
case AST_TO_UNSIGNED: {
|
case AST_TO_UNSIGNED: {
|
||||||
RTLIL::SigSpec sig = children[0]->genRTLIL(width_hint, sign_hint);
|
RTLIL::SigSpec sig = children[0]->genRTLIL();
|
||||||
is_signed = type == AST_TO_SIGNED;
|
is_signed = type == AST_TO_SIGNED;
|
||||||
return sig;
|
return sig;
|
||||||
}
|
}
|
||||||
|
@ -889,6 +889,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
if (0) { case AST_BIT_XOR: type_name = "$xor"; }
|
if (0) { case AST_BIT_XOR: type_name = "$xor"; }
|
||||||
if (0) { case AST_BIT_XNOR: type_name = "$xnor"; }
|
if (0) { case AST_BIT_XNOR: type_name = "$xnor"; }
|
||||||
{
|
{
|
||||||
|
if (width_hint < 0)
|
||||||
|
detectSignWidth(width_hint, sign_hint);
|
||||||
RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint);
|
RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint);
|
||||||
RTLIL::SigSpec right = children[1]->genRTLIL(width_hint, sign_hint);
|
RTLIL::SigSpec right = children[1]->genRTLIL(width_hint, sign_hint);
|
||||||
int width = std::max(left.width, right.width);
|
int width = std::max(left.width, right.width);
|
||||||
|
@ -965,12 +967,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
if (width > width_hint && width_hint > 0)
|
if (width > width_hint && width_hint > 0)
|
||||||
width = width_hint;
|
width = width_hint;
|
||||||
if (width < width_hint) {
|
if (width < width_hint) {
|
||||||
if (type == AST_ADD || type == AST_SUB) {
|
if (type == AST_ADD || type == AST_SUB)
|
||||||
width++;
|
width++;
|
||||||
if (width < width_hint && children[0]->is_signed != children[1]->is_signed)
|
if (type == AST_SUB && (!children[0]->is_signed || !children[1]->is_signed))
|
||||||
width++;
|
|
||||||
}
|
|
||||||
if (type == AST_SUB && !children[0]->is_signed && !children[1]->is_signed)
|
|
||||||
width = width_hint;
|
width = width_hint;
|
||||||
if (type == AST_MUL)
|
if (type == AST_MUL)
|
||||||
width = std::min(left.width + right.width, width_hint);
|
width = std::min(left.width + right.width, width_hint);
|
||||||
|
|
|
@ -27,19 +27,21 @@ module test04(a, y);
|
||||||
assign y = ~(a - 1'b0);
|
assign y = ~(a - 1'b0);
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module test05(a, y);
|
// .. this test triggers a bug in xilinx isim.
|
||||||
input a;
|
// module test05(a, y);
|
||||||
output y;
|
// input a;
|
||||||
assign y = 12345 >> {a, 32'd0};
|
// output y;
|
||||||
endmodule
|
// assign y = 12345 >> {a, 32'd0};
|
||||||
|
// endmodule
|
||||||
|
|
||||||
module test06(a, b, c, y);
|
// .. this test triggers a bug in icarus verilog.
|
||||||
input signed [3:0] a;
|
// module test06(a, b, c, y);
|
||||||
input signed [1:0] b;
|
// input signed [3:0] a;
|
||||||
input signed [1:0] c;
|
// input signed [1:0] b;
|
||||||
output [5:0] y;
|
// input signed [1:0] c;
|
||||||
assign y = (a >> b) >>> c;
|
// output [5:0] y;
|
||||||
endmodule
|
// assign y = (a >> b) >>> c;
|
||||||
|
// endmodule
|
||||||
|
|
||||||
module test07(a, b, y);
|
module test07(a, b, y);
|
||||||
input signed [1:0] a;
|
input signed [1:0] a;
|
||||||
|
|
Loading…
Reference in New Issue