mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-13 04:28:18 +00:00
Added SAT support for $div and $mod cells
This commit is contained in:
parent
a5836af172
commit
ccf36cb7d8
|
@ -267,6 +267,52 @@ struct SatGen
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cell->type == "$div" || cell->type == "$mod")
|
||||||
|
{
|
||||||
|
std::vector<int> a = importSigSpec(cell->connections.at("\\A"), timestep);
|
||||||
|
std::vector<int> b = importSigSpec(cell->connections.at("\\B"), timestep);
|
||||||
|
std::vector<int> y = importSigSpec(cell->connections.at("\\Y"), timestep);
|
||||||
|
extendSignalWidth(a, b, y, cell);
|
||||||
|
|
||||||
|
std::vector<int> a_u, b_u;
|
||||||
|
if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) {
|
||||||
|
a_u = ez->vec_ite(a.back(), ez->vec_neg(a), a);
|
||||||
|
b_u = ez->vec_ite(b.back(), ez->vec_neg(b), b);
|
||||||
|
} else {
|
||||||
|
a_u = a;
|
||||||
|
b_u = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> chain_buf = a_u;
|
||||||
|
std::vector<int> y_u(a_u.size(), ez->FALSE);
|
||||||
|
for (int i = int(a.size())-1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
chain_buf.insert(chain_buf.end(), chain_buf.size(), ez->FALSE);
|
||||||
|
|
||||||
|
std::vector<int> b_shl(i, ez->FALSE);
|
||||||
|
b_shl.insert(b_shl.end(), b_u.begin(), b_u.end());
|
||||||
|
b_shl.insert(b_shl.end(), chain_buf.size()-b_shl.size(), ez->FALSE);
|
||||||
|
|
||||||
|
y_u.at(i) = ez->vec_ge_unsigned(chain_buf, b_shl);
|
||||||
|
chain_buf = ez->vec_ite(y_u.at(i), ez->vec_sub(chain_buf, b_shl), chain_buf);
|
||||||
|
|
||||||
|
chain_buf.erase(chain_buf.begin() + a_u.size(), chain_buf.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cell->type == "$div") {
|
||||||
|
if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool())
|
||||||
|
ez->assume(ez->vec_eq(y, ez->vec_ite(ez->XOR(a.back(), b.back()), ez->vec_neg(y_u), y_u)));
|
||||||
|
else
|
||||||
|
ez->assume(ez->vec_eq(y, y_u));
|
||||||
|
} else {
|
||||||
|
if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool())
|
||||||
|
ez->assume(ez->vec_eq(y, ez->vec_ite(a.back(), ez->vec_neg(chain_buf), chain_buf)));
|
||||||
|
else
|
||||||
|
ez->assume(ez->vec_eq(y, chain_buf));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (timestep > 0 && (cell->type == "$dff" || cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_")) {
|
if (timestep > 0 && (cell->type == "$dff" || cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_")) {
|
||||||
if (timestep == 1) {
|
if (timestep == 1) {
|
||||||
initial_state.add((*sigmap)(cell->connections.at("\\Q")));
|
initial_state.add((*sigmap)(cell->connections.at("\\Q")));
|
||||||
|
|
|
@ -852,6 +852,12 @@ std::vector<int> ezSAT::vec_sub(const std::vector<int> &vec1, const std::vector<
|
||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<int> ezSAT::vec_neg(const std::vector<int> &vec)
|
||||||
|
{
|
||||||
|
std::vector<int> zero(vec.size(), FALSE);
|
||||||
|
return vec_sub(zero, vec);
|
||||||
|
}
|
||||||
|
|
||||||
void ezSAT::vec_cmp(const std::vector<int> &vec1, const std::vector<int> &vec2, int &carry, int &overflow, int &sign, int &zero)
|
void ezSAT::vec_cmp(const std::vector<int> &vec1, const std::vector<int> &vec2, int &carry, int &overflow, int &sign, int &zero)
|
||||||
{
|
{
|
||||||
assert(vec1.size() == vec2.size());
|
assert(vec1.size() == vec2.size());
|
||||||
|
|
|
@ -223,6 +223,7 @@ public:
|
||||||
std::vector<int> vec_count(const std::vector<int> &vec, int bits, bool clip = true);
|
std::vector<int> vec_count(const std::vector<int> &vec, int bits, bool clip = true);
|
||||||
std::vector<int> vec_add(const std::vector<int> &vec1, const std::vector<int> &vec2);
|
std::vector<int> vec_add(const std::vector<int> &vec1, const std::vector<int> &vec2);
|
||||||
std::vector<int> vec_sub(const std::vector<int> &vec1, const std::vector<int> &vec2);
|
std::vector<int> vec_sub(const std::vector<int> &vec1, const std::vector<int> &vec2);
|
||||||
|
std::vector<int> vec_neg(const std::vector<int> &vec);
|
||||||
|
|
||||||
void vec_cmp(const std::vector<int> &vec1, const std::vector<int> &vec2, int &carry, int &overflow, int &sign, int &zero);
|
void vec_cmp(const std::vector<int> &vec1, const std::vector<int> &vec2, int &carry, int &overflow, int &sign, int &zero);
|
||||||
|
|
||||||
|
@ -305,6 +306,8 @@ struct ezSATvec
|
||||||
ezSATvec(ezSAT &sat, const std::vector<int> &vec) : sat(sat), vec(vec) { }
|
ezSATvec(ezSAT &sat, const std::vector<int> &vec) : sat(sat), vec(vec) { }
|
||||||
|
|
||||||
ezSATvec operator ~() { return ezSATvec(sat, sat.vec_not(vec)); }
|
ezSATvec operator ~() { return ezSATvec(sat, sat.vec_not(vec)); }
|
||||||
|
ezSATvec operator -() { return ezSATvec(sat, sat.vec_neg(vec)); }
|
||||||
|
|
||||||
ezSATvec operator &(const ezSATvec &other) { return ezSATvec(sat, sat.vec_and(vec, other.vec)); }
|
ezSATvec operator &(const ezSATvec &other) { return ezSATvec(sat, sat.vec_and(vec, other.vec)); }
|
||||||
ezSATvec operator |(const ezSATvec &other) { return ezSATvec(sat, sat.vec_or(vec, other.vec)); }
|
ezSATvec operator |(const ezSATvec &other) { return ezSATvec(sat, sat.vec_or(vec, other.vec)); }
|
||||||
ezSATvec operator ^(const ezSATvec &other) { return ezSATvec(sat, sat.vec_xor(vec, other.vec)); }
|
ezSATvec operator ^(const ezSATvec &other) { return ezSATvec(sat, sat.vec_xor(vec, other.vec)); }
|
||||||
|
|
Loading…
Reference in a new issue