mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-06 22:23:23 +00:00
Add $bmux and $demux cells.
This commit is contained in:
parent
db33b1e535
commit
93508d58da
25 changed files with 694 additions and 49 deletions
100
kernel/satgen.cc
100
kernel/satgen.cc
|
@ -252,6 +252,106 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($bmux))
|
||||
{
|
||||
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
|
||||
std::vector<int> s = importDefSigSpec(cell->getPort(ID::S), timestep);
|
||||
std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
|
||||
std::vector<int> undef_a, undef_s, undef_y;
|
||||
|
||||
if (model_undef)
|
||||
{
|
||||
undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
|
||||
undef_s = importUndefSigSpec(cell->getPort(ID::S), timestep);
|
||||
undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
|
||||
}
|
||||
|
||||
if (GetSize(s) == 0) {
|
||||
ez->vec_set(a, y);
|
||||
if (model_undef)
|
||||
ez->vec_set(undef_a, undef_y);
|
||||
} else {
|
||||
for (int i = GetSize(s)-1; i >= 0; i--)
|
||||
{
|
||||
std::vector<int> out = (i == 0) ? y : ez->vec_var(a.size() / 2);
|
||||
std::vector<int> yy = model_undef ? ez->vec_var(out.size()) : out;
|
||||
|
||||
std::vector<int> a0(a.begin(), a.begin() + a.size() / 2);
|
||||
std::vector<int> a1(a.begin() + a.size() / 2, a.end());
|
||||
ez->assume(ez->vec_eq(ez->vec_ite(s.at(i), a1, a0), yy));
|
||||
|
||||
if (model_undef)
|
||||
{
|
||||
std::vector<int> undef_out = (i == 0) ? undef_y : ez->vec_var(a.size() / 2);
|
||||
std::vector<int> undef_a0(undef_a.begin(), undef_a.begin() + a.size() / 2);
|
||||
std::vector<int> undef_a1(undef_a.begin() + a.size() / 2, undef_a.end());
|
||||
std::vector<int> unequal_ab = ez->vec_not(ez->vec_iff(a0, a1));
|
||||
std::vector<int> undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a0, undef_a1));
|
||||
std::vector<int> yX = ez->vec_ite(undef_s.at(i), undef_ab, ez->vec_ite(s.at(i), undef_a1, undef_a0));
|
||||
ez->assume(ez->vec_eq(yX, undef_out));
|
||||
undefGating(out, yy, undef_out);
|
||||
|
||||
undef_a = undef_out;
|
||||
}
|
||||
|
||||
a = out;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($demux))
|
||||
{
|
||||
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
|
||||
std::vector<int> s = importDefSigSpec(cell->getPort(ID::S), timestep);
|
||||
std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
|
||||
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
|
||||
std::vector<int> undef_a, undef_s, undef_y;
|
||||
|
||||
if (model_undef)
|
||||
{
|
||||
undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
|
||||
undef_s = importUndefSigSpec(cell->getPort(ID::S), timestep);
|
||||
undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
|
||||
}
|
||||
|
||||
if (GetSize(s) == 0) {
|
||||
ez->vec_set(a, y);
|
||||
if (model_undef)
|
||||
ez->vec_set(undef_a, undef_y);
|
||||
} else {
|
||||
for (int i = 0; i < (1 << GetSize(s)); i++)
|
||||
{
|
||||
std::vector<int> ss;
|
||||
for (int j = 0; j < GetSize(s); j++) {
|
||||
if (i & 1 << j)
|
||||
ss.push_back(s[j]);
|
||||
else
|
||||
ss.push_back(ez->NOT(s[j]));
|
||||
}
|
||||
int sss = ez->expression(ezSAT::OpAnd, ss);
|
||||
|
||||
for (int j = 0; j < GetSize(a); j++) {
|
||||
ez->SET(ez->AND(sss, a[j]), yy.at(i * GetSize(a) + j));
|
||||
}
|
||||
|
||||
if (model_undef)
|
||||
{
|
||||
int s0 = ez->expression(ezSAT::OpOr, ez->vec_and(ez->vec_not(ss), ez->vec_not(undef_s)));
|
||||
int us = ez->AND(ez->NOT(s0), ez->expression(ezSAT::OpOr, undef_s));
|
||||
for (int j = 0; j < GetSize(a); j++) {
|
||||
int a0 = ez->AND(ez->NOT(a[j]), ez->NOT(undef_a[j]));
|
||||
int yX = ez->AND(ez->OR(us, undef_a[j]), ez->NOT(ez->OR(s0, a0)));
|
||||
ez->SET(yX, undef_y.at(i * GetSize(a) + j));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (model_undef)
|
||||
undefGating(y, yy, undef_y);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == ID($pmux))
|
||||
{
|
||||
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue