mirror of
https://github.com/YosysHQ/yosys
synced 2026-02-12 20:04:11 +00:00
Widen $polarity cell to multiple ports
This commit is contained in:
parent
7f19cf8849
commit
0c7afe8e31
8 changed files with 74 additions and 58 deletions
|
|
@ -658,22 +658,25 @@ RTLIL::Const RTLIL::const_bmux(const RTLIL::Const &arg1, const RTLIL::Const &arg
|
|||
return t;
|
||||
}
|
||||
|
||||
RTLIL::Const RTLIL::const_priority(const RTLIL::Const &arg, const RTLIL::Const &polarity)
|
||||
RTLIL::Const RTLIL::const_priority(const RTLIL::Const &arg, int p_width, const RTLIL::Const &polarity)
|
||||
{
|
||||
std::vector<State> t;
|
||||
std::optional<State> first_non_zero = std::nullopt;
|
||||
for (int i = 0; i < GetSize(arg); i++)
|
||||
for (int offset = 0; offset < GetSize(arg); offset += p_width)
|
||||
{
|
||||
RTLIL::State s = arg.at(i);
|
||||
if (first_non_zero && s != State::Sx) {
|
||||
auto inactive = polarity[i] == State::S0 ? State::S1 : State::S0;
|
||||
auto val = *first_non_zero == State::Sx ? State::Sx : inactive;
|
||||
t.push_back(val);
|
||||
} else {
|
||||
t.push_back(s);
|
||||
}
|
||||
if ((!first_non_zero && s == polarity[i]) || s == State::Sx) {
|
||||
first_non_zero = s;
|
||||
std::optional<State> first_non_zero = std::nullopt;
|
||||
for (int i = offset; i < offset + p_width; i++)
|
||||
{
|
||||
RTLIL::State s = arg.at(i);
|
||||
if (first_non_zero && s != State::Sx) {
|
||||
auto inactive = polarity[i] == State::S0 ? State::S1 : State::S0;
|
||||
auto val = *first_non_zero == State::Sx ? State::Sx : inactive;
|
||||
t.push_back(val);
|
||||
} else {
|
||||
t.push_back(s);
|
||||
}
|
||||
if ((!first_non_zero && s == polarity[i]) || s == State::Sx) {
|
||||
first_non_zero = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
return t;
|
||||
|
|
|
|||
|
|
@ -511,7 +511,7 @@ struct CellTypes
|
|||
|
||||
if (cell->type == ID($priority))
|
||||
{
|
||||
return const_priority(arg1, cell->getParam(ID::POLARITY));
|
||||
return const_priority(arg1, cell->getParam(ID::P_WIDTH).as_int(), cell->getParam(ID::POLARITY));
|
||||
}
|
||||
|
||||
bool signed_a = cell->parameters.count(ID::A_SIGNED) > 0 && cell->parameters[ID::A_SIGNED].as_bool();
|
||||
|
|
|
|||
|
|
@ -680,6 +680,7 @@ X(PRODUCT_NEGATED)
|
|||
X(P_BYPASS)
|
||||
X(P_EN)
|
||||
X(P_SRST_N)
|
||||
X(P_WIDTH)
|
||||
X(Q)
|
||||
X(QL_DSP2)
|
||||
X(R)
|
||||
|
|
|
|||
|
|
@ -2648,9 +2648,10 @@ namespace {
|
|||
}
|
||||
if (cell->type.in(ID($priority))) {
|
||||
param(ID::WIDTH);
|
||||
param(ID::P_WIDTH);
|
||||
param(ID::POLARITY);
|
||||
port(ID::A, param(ID::WIDTH));
|
||||
port(ID::Y, param(ID::WIDTH));
|
||||
port(ID::A, param(ID::P_WIDTH)*param(ID::WIDTH));
|
||||
port(ID::Y, param(ID::P_WIDTH)*param(ID::WIDTH));
|
||||
check_expected();
|
||||
return;
|
||||
}
|
||||
|
|
@ -4501,7 +4502,8 @@ void RTLIL::Cell::check()
|
|||
void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
|
||||
{
|
||||
if (!type.begins_with("$") || type.begins_with("$_") || type.begins_with("$paramod") || type.begins_with("$fmcombine") ||
|
||||
type.begins_with("$verific$") || type.begins_with("$array:") || type.begins_with("$extern:"))
|
||||
type.begins_with("$verific$") || type.begins_with("$array:") || type.begins_with("$extern:")||
|
||||
type.begins_with("$priority"))
|
||||
return;
|
||||
|
||||
if (type == ID($buf) || type == ID($mux) || type == ID($pmux) || type == ID($bmux) || type == ID($bwmux) || type == ID($bweqx)) {
|
||||
|
|
@ -4519,7 +4521,7 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
|
|||
return;
|
||||
}
|
||||
|
||||
if (type == ID($lut) || type == ID($sop) || type == ID($priority)) {
|
||||
if (type == ID($lut) || type == ID($sop)) {
|
||||
parameters[ID::WIDTH] = GetSize(connections_[ID::A]);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -848,7 +848,7 @@ namespace RTLIL {
|
|||
RTLIL::Const const_pmux (const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3);
|
||||
RTLIL::Const const_bmux (const RTLIL::Const &arg1, const RTLIL::Const &arg2);
|
||||
RTLIL::Const const_demux (const RTLIL::Const &arg1, const RTLIL::Const &arg2);
|
||||
RTLIL::Const const_priority (const RTLIL::Const &arg, const RTLIL::Const &polarity);
|
||||
RTLIL::Const const_priority (const RTLIL::Const &arg, int p_width, const RTLIL::Const &polarity);
|
||||
|
||||
RTLIL::Const const_bweqx (const RTLIL::Const &arg1, const RTLIL::Const &arg2);
|
||||
RTLIL::Const const_bwmux (const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3);
|
||||
|
|
|
|||
|
|
@ -437,32 +437,35 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
|
||||
|
||||
const Const& polarity = cell->getParam(ID::POLARITY);
|
||||
int p_width = cell->getParam(ID::P_WIDTH).as_int();
|
||||
|
||||
int any_previous_active;
|
||||
if (a.size()) {
|
||||
any_previous_active = polarity[0] ? a[0] : ez->NOT(a[0]);
|
||||
ez->assume(ez->IFF(yy[0], a[0]));
|
||||
}
|
||||
for (size_t i = 1; i < a.size(); i++) {
|
||||
int inactive_val = !polarity[i] ? ez->CONST_TRUE : ez->CONST_FALSE;
|
||||
int active_val = polarity[i] ? ez->CONST_TRUE : ez->CONST_FALSE;
|
||||
ez->assume(ez->IFF(yy[i], ez->ITE(any_previous_active, inactive_val, a[i])));
|
||||
any_previous_active = ez->OR(any_previous_active, ez->IFF(a[i], active_val));
|
||||
}
|
||||
if (model_undef) {
|
||||
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
|
||||
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
|
||||
for (size_t offset = 0; offset < a.size(); offset += p_width) {
|
||||
int any_previous_active;
|
||||
if (p_width) {
|
||||
any_previous_active = polarity[offset] ? a[offset] : ez->NOT(a[offset]);
|
||||
ez->assume(ez->IFF(yy[offset], a[offset]));
|
||||
}
|
||||
for (size_t i = offset + 1; i < offset + p_width; i++) {
|
||||
int inactive_val = !polarity[i] ? ez->CONST_TRUE : ez->CONST_FALSE;
|
||||
int active_val = polarity[i] ? ez->CONST_TRUE : ez->CONST_FALSE;
|
||||
ez->assume(ez->IFF(yy[i], ez->ITE(any_previous_active, inactive_val, a[i])));
|
||||
any_previous_active = ez->OR(any_previous_active, ez->IFF(a[i], active_val));
|
||||
}
|
||||
if (model_undef) {
|
||||
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
|
||||
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
|
||||
|
||||
int any_previous_undef;
|
||||
if (a.size()) {
|
||||
any_previous_undef = undef_a[0];
|
||||
ez->assume(ez->IFF(undef_y[0], undef_a[0]));
|
||||
int any_previous_undef;
|
||||
if (p_width) {
|
||||
any_previous_undef = undef_a[offset];
|
||||
ez->assume(ez->IFF(undef_y[offset], undef_a[offset]));
|
||||
}
|
||||
for (size_t i = offset + 1; i < offset + p_width; i++) {
|
||||
any_previous_undef = ez->OR(any_previous_undef, undef_a[i]);
|
||||
ez->assume(ez->IFF(undef_y[i], any_previous_undef));
|
||||
}
|
||||
undefGating(y, yy, undef_y);
|
||||
}
|
||||
for (size_t i = 1; i < a.size(); i++) {
|
||||
any_previous_undef = ez->OR(any_previous_undef, undef_a[i]);
|
||||
ez->assume(ez->IFF(undef_y[i], any_previous_undef));
|
||||
}
|
||||
undefGating(y, yy, undef_y);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue