mirror of https://github.com/YosysHQ/yosys.git
satgen: Add support for dffe, sdff, sdffe, sdffce cells.
This commit is contained in:
parent
dafe04d559
commit
0c6d0d4b5d
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kernel/satgen.h"
|
#include "kernel/satgen.h"
|
||||||
|
#include "kernel/ff.h"
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
|
|
||||||
|
@ -1075,8 +1076,14 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timestep > 0 && cell->type.in(ID($ff), ID($dff), ID($_FF_), ID($_DFF_N_), ID($_DFF_P_)))
|
if (timestep > 0 && RTLIL::builtin_ff_cell_types().count(cell->type))
|
||||||
{
|
{
|
||||||
|
FfData ff(nullptr, cell);
|
||||||
|
|
||||||
|
// Latches and FFs with async inputs are not supported — use clk2fflogic or async2sync first.
|
||||||
|
if (!ff.has_d || ff.has_arst || ff.has_sr || (ff.has_en && !ff.has_clk))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (timestep == 1)
|
if (timestep == 1)
|
||||||
{
|
{
|
||||||
initial_state.add((*sigmap)(cell->getPort(ID::Q)));
|
initial_state.add((*sigmap)(cell->getPort(ID::Q)));
|
||||||
|
@ -1084,6 +1091,51 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::vector<int> d = importDefSigSpec(cell->getPort(ID::D), timestep-1);
|
std::vector<int> d = importDefSigSpec(cell->getPort(ID::D), timestep-1);
|
||||||
|
std::vector<int> undef_d;
|
||||||
|
if (model_undef)
|
||||||
|
undef_d = importUndefSigSpec(cell->getPort(ID::D), timestep-1);
|
||||||
|
if (ff.has_srst && ff.has_en && ff.ce_over_srst) {
|
||||||
|
int srst = importDefSigSpec(ff.sig_srst, timestep-1).at(0);
|
||||||
|
std::vector<int> rval = importDefSigSpec(ff.val_srst, timestep-1);
|
||||||
|
int undef_srst;
|
||||||
|
std::vector<int> undef_rval;
|
||||||
|
if (model_undef) {
|
||||||
|
undef_srst = importUndefSigSpec(ff.sig_srst, timestep-1).at(0);
|
||||||
|
undef_rval = importUndefSigSpec(ff.val_srst, timestep-1);
|
||||||
|
}
|
||||||
|
if (ff.pol_srst)
|
||||||
|
std::tie(d, undef_d) = mux(srst, undef_srst, d, undef_d, rval, undef_rval);
|
||||||
|
else
|
||||||
|
std::tie(d, undef_d) = mux(srst, undef_srst, rval, undef_rval, d, undef_d);
|
||||||
|
}
|
||||||
|
if (ff.has_en) {
|
||||||
|
int en = importDefSigSpec(ff.sig_en, timestep-1).at(0);
|
||||||
|
std::vector<int> old_q = importDefSigSpec(ff.sig_q, timestep-1);
|
||||||
|
int undef_en;
|
||||||
|
std::vector<int> undef_old_q;
|
||||||
|
if (model_undef) {
|
||||||
|
undef_en = importUndefSigSpec(ff.sig_en, timestep-1).at(0);
|
||||||
|
undef_old_q = importUndefSigSpec(ff.sig_q, timestep-1);
|
||||||
|
}
|
||||||
|
if (ff.pol_en)
|
||||||
|
std::tie(d, undef_d) = mux(en, undef_en, old_q, undef_old_q, d, undef_d);
|
||||||
|
else
|
||||||
|
std::tie(d, undef_d) = mux(en, undef_en, d, undef_d, old_q, undef_old_q);
|
||||||
|
}
|
||||||
|
if (ff.has_srst && !(ff.has_en && ff.ce_over_srst)) {
|
||||||
|
int srst = importDefSigSpec(ff.sig_srst, timestep-1).at(0);
|
||||||
|
std::vector<int> rval = importDefSigSpec(ff.val_srst, timestep-1);
|
||||||
|
int undef_srst;
|
||||||
|
std::vector<int> undef_rval;
|
||||||
|
if (model_undef) {
|
||||||
|
undef_srst = importUndefSigSpec(ff.sig_srst, timestep-1).at(0);
|
||||||
|
undef_rval = importUndefSigSpec(ff.val_srst, timestep-1);
|
||||||
|
}
|
||||||
|
if (ff.pol_srst)
|
||||||
|
std::tie(d, undef_d) = mux(srst, undef_srst, d, undef_d, rval, undef_rval);
|
||||||
|
else
|
||||||
|
std::tie(d, undef_d) = mux(srst, undef_srst, rval, undef_rval, d, undef_d);
|
||||||
|
}
|
||||||
std::vector<int> q = importDefSigSpec(cell->getPort(ID::Q), timestep);
|
std::vector<int> q = importDefSigSpec(cell->getPort(ID::Q), timestep);
|
||||||
|
|
||||||
std::vector<int> qq = model_undef ? ez->vec_var(q.size()) : q;
|
std::vector<int> qq = model_undef ? ez->vec_var(q.size()) : q;
|
||||||
|
@ -1091,7 +1143,6 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
||||||
|
|
||||||
if (model_undef)
|
if (model_undef)
|
||||||
{
|
{
|
||||||
std::vector<int> undef_d = importUndefSigSpec(cell->getPort(ID::D), timestep-1);
|
|
||||||
std::vector<int> undef_q = importUndefSigSpec(cell->getPort(ID::Q), timestep);
|
std::vector<int> undef_q = importUndefSigSpec(cell->getPort(ID::Q), timestep);
|
||||||
|
|
||||||
ez->assume(ez->vec_eq(undef_d, undef_q));
|
ez->assume(ez->vec_eq(undef_d, undef_q));
|
||||||
|
@ -1182,7 +1233,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unsupported internal cell types: $pow $lut
|
// Unsupported internal cell types: $pow $fsm $mem*
|
||||||
// .. and all sequential cells except $dff and $_DFF_[NP]_
|
// .. and all sequential cells with asynchronous inputs
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -262,6 +262,18 @@ struct SatGen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<std::vector<int>, std::vector<int>> mux(int s, int undef_s, const std::vector<int> &a, const std::vector<int> &undef_a, const std::vector<int> &b, const std::vector<int> &undef_b) {
|
||||||
|
std::vector<int> res;
|
||||||
|
std::vector<int> undef_res;
|
||||||
|
res = ez->vec_ite(s, b, a);
|
||||||
|
if (model_undef) {
|
||||||
|
std::vector<int> unequal_ab = ez->vec_not(ez->vec_iff(a, b));
|
||||||
|
std::vector<int> undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b));
|
||||||
|
undef_res = ez->vec_ite(undef_s, undef_ab, ez->vec_ite(s, undef_b, undef_a));
|
||||||
|
}
|
||||||
|
return std::make_pair(res, undef_res);
|
||||||
|
}
|
||||||
|
|
||||||
void undefGating(int y, int yy, int undef)
|
void undefGating(int y, int yy, int undef)
|
||||||
{
|
{
|
||||||
ez->assume(ez->OR(undef, ez->IFF(y, yy)));
|
ez->assume(ez->OR(undef, ez->IFF(y, yy)));
|
||||||
|
|
|
@ -35,7 +35,6 @@ design -stash gate
|
||||||
|
|
||||||
design -copy-from gold -as gold pmtest_xilinx_srl_pm_fixed
|
design -copy-from gold -as gold pmtest_xilinx_srl_pm_fixed
|
||||||
design -copy-from gate -as gate pmtest_xilinx_srl_pm_fixed
|
design -copy-from gate -as gate pmtest_xilinx_srl_pm_fixed
|
||||||
dff2dffe -unmap # sat does not support flops-with-enable yet
|
|
||||||
miter -equiv -flatten -make_assert gold gate miter
|
miter -equiv -flatten -make_assert gold gate miter
|
||||||
sat -set-init-zero -seq 5 -verify -prove-asserts miter
|
sat -set-init-zero -seq 5 -verify -prove-asserts miter
|
||||||
|
|
||||||
|
@ -52,6 +51,5 @@ design -stash gate
|
||||||
|
|
||||||
design -copy-from gold -as gold pmtest_xilinx_srl_pm_variable
|
design -copy-from gold -as gold pmtest_xilinx_srl_pm_variable
|
||||||
design -copy-from gate -as gate pmtest_xilinx_srl_pm_variable
|
design -copy-from gate -as gate pmtest_xilinx_srl_pm_variable
|
||||||
dff2dffe -unmap # sat does not support flops-with-enable yet
|
|
||||||
miter -equiv -flatten -make_assert gold gate miter
|
miter -equiv -flatten -make_assert gold gate miter
|
||||||
sat -set-init-zero -seq 5 -verify -prove-asserts miter
|
sat -set-init-zero -seq 5 -verify -prove-asserts miter
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Ensure all sync-only DFFs have usable SAT models.
|
||||||
|
|
||||||
|
read_verilog -icells <<EOT
|
||||||
|
|
||||||
|
module top(...);
|
||||||
|
|
||||||
|
input C, D, R, E;
|
||||||
|
output [4:0] Q;
|
||||||
|
|
||||||
|
\$dff #(.WIDTH(1), .CLK_POLARITY(1'b1)) ff0 (.CLK(C), .D(D), .Q(Q[0]));
|
||||||
|
\$dffe #(.WIDTH(1), .CLK_POLARITY(1'b1), .EN_POLARITY(1'b1)) ff1 (.CLK(C), .D(D), .EN(E), .Q(Q[1]));
|
||||||
|
\$sdff #(.WIDTH(1), .CLK_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(1'b0)) ff2 (.CLK(C), .D(D), .SRST(R), .Q(Q[2]));
|
||||||
|
\$sdffe #(.WIDTH(1), .CLK_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(1'b0), .EN_POLARITY(1'b1)) ff3 (.CLK(C), .D(D), .EN(E), .SRST(R), .Q(Q[3]));
|
||||||
|
\$sdffce #(.WIDTH(1), .CLK_POLARITY(1'b1), .SRST_POLARITY(1'b1), .SRST_VALUE(1'b0), .EN_POLARITY(1'b1)) ff4 (.CLK(C), .D(D), .EN(E), .SRST(R), .Q(Q[4]));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
EOT
|
||||||
|
|
||||||
|
# This ensures that 1) coarse cells have SAT models, 2) fine cells have SAT models, 3) they're equivalent
|
||||||
|
equiv_opt -assert simplemap
|
Loading…
Reference in New Issue