From 0e1661f84e99f1d4a487e7a432b05a6cb2071714 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 7 Nov 2013 16:53:28 +0100 Subject: [PATCH] Fixed type of sign extension in opt_const $eq/$ne handling --- kernel/rtlil.cc | 16 ++++++++++++++++ kernel/rtlil.h | 1 + passes/opt/opt_const.cc | 18 +++++++++--------- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index d64a37bb8..4388acb1d 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -940,6 +940,22 @@ void RTLIL::SigSpec::extend(int width, bool is_signed) optimize(); } +void RTLIL::SigSpec::extend_un0(int width, bool is_signed) +{ + if (this->width > width) + remove(width, this->width - width); + + if (this->width < width) { + RTLIL::SigSpec padding = this->width > 0 ? extract(this->width - 1, 1) : RTLIL::SigSpec(RTLIL::State::S0); + if (!is_signed) + padding = RTLIL::SigSpec(RTLIL::State::S0); + while (this->width < width) + append(padding); + } + + optimize(); +} + void RTLIL::SigSpec::check() const { int w = 0; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 6cb471b58..376a09abf 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -342,6 +342,7 @@ struct RTLIL::SigSpec { void append(const RTLIL::SigSpec &signal); bool combine(RTLIL::SigSpec signal, RTLIL::State freeState = RTLIL::State::Sz, bool override = false); void extend(int width, bool is_signed = false); + void extend_un0(int width, bool is_signed = false); void check() const; bool operator <(const RTLIL::SigSpec &other) const; bool operator ==(const RTLIL::SigSpec &other) const; diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index b04ed9e72..f20181f1e 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -151,8 +151,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->parameters["\\A_WIDTH"].as_int() != cell->parameters["\\B_WIDTH"].as_int()) { int width = std::max(cell->parameters["\\A_WIDTH"].as_int(), cell->parameters["\\B_WIDTH"].as_int()); - a.extend(width, cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()); - b.extend(width, cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()); + a.extend_un0(width, cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()); + b.extend_un0(width, cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()); } RTLIL::SigSpec new_a, new_b; @@ -168,6 +168,13 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons new_b.append(b.chunks[i]); } + if (new_a.width == 0) { + RTLIL::SigSpec new_y = RTLIL::SigSpec(cell->type == "$eq" ? RTLIL::State::S1 : RTLIL::State::S0); + new_y.extend(cell->parameters["\\Y_WIDTH"].as_int(), false); + replace_cell(module, cell, "empty", "\\Y", new_y); + goto next_cell; + } + if (new_a.width != a.width) { new_a.optimize(); new_b.optimize(); @@ -176,13 +183,6 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cell->parameters["\\A_WIDTH"] = new_a.width; cell->parameters["\\B_WIDTH"] = new_b.width; } - - if (new_a.width == 0) { - RTLIL::SigSpec new_y = RTLIL::SigSpec(cell->type == "$eq" ? RTLIL::State::S1 : RTLIL::State::S0); - new_y.extend(cell->parameters["\\Y_WIDTH"].as_int(), false); - replace_cell(module, cell, "empty", "\\Y", new_y); - goto next_cell; - } } if ((cell->type == "$eq" || cell->type == "$ne") && cell->parameters["\\Y_WIDTH"].as_int() == 1 && -- 2.30.2