mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-19 07:09:05 +00:00
read_verilog: simplify ternary condition early, ignore unreach children
This commit is contained in:
parent
5791c52e1b
commit
dd3c3c0bdc
|
@ -769,8 +769,10 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
|
|||
break;
|
||||
|
||||
case AST_TERNARY:
|
||||
children.at(1)->detectSignWidthWorker(width_hint, sign_hint, found_real);
|
||||
children.at(2)->detectSignWidthWorker(width_hint, sign_hint, found_real);
|
||||
if (children.at(0)->type != AST_CONSTANT || children.at(0)->asBool())
|
||||
children.at(1)->detectSignWidthWorker(width_hint, sign_hint, found_real);
|
||||
if (children.at(0)->type != AST_CONSTANT || !children.at(0)->asBool())
|
||||
children.at(2)->detectSignWidthWorker(width_hint, sign_hint, found_real);
|
||||
break;
|
||||
|
||||
case AST_MEMRD:
|
||||
|
@ -1334,18 +1336,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);
|
||||
|
|
|
@ -572,6 +572,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
|||
case AST_TERNARY:
|
||||
detect_width_simple = true;
|
||||
child_0_is_self_determined = true;
|
||||
while (children[0]->simplify(true, false, false, 1, -1, false, false)) { }
|
||||
break;
|
||||
|
||||
case AST_MEMRD:
|
||||
|
@ -605,9 +606,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
|||
if (type == AST_TERNARY) {
|
||||
int width_hint_left, width_hint_right;
|
||||
bool sign_hint_left, sign_hint_right;
|
||||
bool found_real_left, found_real_right;
|
||||
children[1]->detectSignWidth(width_hint_left, sign_hint_left, &found_real_left);
|
||||
children[2]->detectSignWidth(width_hint_right, sign_hint_right, &found_real_right);
|
||||
bool found_real_left = false, found_real_right = false;
|
||||
if (children[0]->type != AST_CONSTANT || children[0]->asBool())
|
||||
children[1]->detectSignWidth(width_hint_left, sign_hint_left, &found_real_left);
|
||||
if (children[0]->type != AST_CONSTANT || !children[0]->asBool())
|
||||
children[2]->detectSignWidth(width_hint_right, sign_hint_right, &found_real_right);
|
||||
if (found_real_left || found_real_right) {
|
||||
child_1_is_self_determined = true;
|
||||
child_2_is_self_determined = true;
|
||||
|
|
Loading…
Reference in a new issue