diff options
author | Eddie Hung <eddie@fpgeh.com> | 2020-02-27 16:55:55 -0800 |
---|---|---|
committer | Eddie Hung <eddie@fpgeh.com> | 2020-02-27 16:55:55 -0800 |
commit | 5bba9c3640971e25544f2053b31eb152c138c3af (patch) | |
tree | ada4dabc8e3326edeecf9c133589085fb5bdbdc4 | |
parent | 825b96fdcffedec02b4eaaa5f9c4aee5bfc6942a (diff) | |
download | yosys-5bba9c3640971e25544f2053b31eb152c138c3af.tar.gz yosys-5bba9c3640971e25544f2053b31eb152c138c3af.tar.bz2 yosys-5bba9c3640971e25544f2053b31eb152c138c3af.zip |
ast: fixes #1710; do not generate RTLIL for unreachable ternary
-rw-r--r-- | frontends/ast/genrtlil.cc | 31 | ||||
-rw-r--r-- | tests/various/bug1710.ys | 30 |
2 files changed, 52 insertions, 9 deletions
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 3fb6b3e5c..1dfcf3e0e 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1338,18 +1338,31 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) detectSignWidth(width_hint, sign_hint); RTLIL::SigSpec cond = children[0]->genRTLIL(); - RTLIL::SigSpec val1 = children[1]->genRTLIL(width_hint, sign_hint); - RTLIL::SigSpec val2 = children[2]->genRTLIL(width_hint, sign_hint); + RTLIL::SigSpec sig; + if (cond.is_fully_const()) { + if (cond.as_bool()) { + sig = children[1]->genRTLIL(width_hint, sign_hint); + widthExtend(this, sig, sig.size(), children[1]->is_signed); + } + else { + sig = children[2]->genRTLIL(width_hint, sign_hint); + widthExtend(this, sig, sig.size(), children[2]->is_signed); + } + } + else { + RTLIL::SigSpec val1 = children[1]->genRTLIL(width_hint, sign_hint); + RTLIL::SigSpec val2 = children[2]->genRTLIL(width_hint, sign_hint); - if (cond.size() > 1) - cond = uniop2rtlil(this, "$reduce_bool", 1, cond, false); + if (cond.size() > 1) + cond = uniop2rtlil(this, "$reduce_bool", 1, cond, false); - int width = max(val1.size(), val2.size()); - is_signed = children[1]->is_signed && children[2]->is_signed; - widthExtend(this, val1, width, is_signed); - widthExtend(this, val2, width, is_signed); + int width = max(val1.size(), val2.size()); + is_signed = children[1]->is_signed && children[2]->is_signed; + widthExtend(this, val1, width, is_signed); + widthExtend(this, val2, width, is_signed); - RTLIL::SigSpec sig = mux2rtlil(this, cond, val1, val2); + sig = mux2rtlil(this, cond, val1, val2); + } if (sig.size() < width_hint) sig.extend_u0(width_hint, sign_hint); diff --git a/tests/various/bug1710.ys b/tests/various/bug1710.ys new file mode 100644 index 000000000..c2ecf3c90 --- /dev/null +++ b/tests/various/bug1710.ys @@ -0,0 +1,30 @@ +logger -werror "out of bounds" +read_verilog <<EOT +module Example; + + parameter FLAG = 1; + wire [3:0] inp; + + reg out1; + initial out1 = FLAG ? &inp[2:0] : &inp[4:0]; + + reg out2; + initial + if (FLAG) + out2 = &inp[2:0]; + else + out2 = &inp[4:0]; + + wire out3; + assign out3 = FLAG ? &inp[2:0] : &inp[4:0]; + + wire out4; + generate + if (FLAG) + assign out4 = &inp[2:0]; + else + assign out4 = &inp[4:0]; + endgenerate + +endmodule +EOT |