mirror of
https://github.com/YosysHQ/yosys
synced 2026-04-27 14:23:37 +00:00
equiv_simple, equiv_induct: fix config
This commit is contained in:
parent
c768e55983
commit
ed53ff2f49
3 changed files with 90 additions and 88 deletions
|
|
@ -23,54 +23,55 @@ static void report_missing_model(bool warn_only, RTLIL::Cell* cell)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct EquivBasicConfig {
|
||||||
|
bool model_undef = false;
|
||||||
|
int max_seq = 1;
|
||||||
|
bool set_assumes = false;
|
||||||
|
bool ignore_unknown_cells = false;
|
||||||
|
|
||||||
|
bool parse(const std::vector<std::string>& args, size_t& idx) {
|
||||||
|
if (args[idx] == "-undef") {
|
||||||
|
model_undef = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (args[idx] == "-seq" && idx+1 < args.size()) {
|
||||||
|
max_seq = atoi(args[++idx].c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (args[idx] == "-set-assumes") {
|
||||||
|
set_assumes = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (args[idx] == "-ignore-unknown-cells") {
|
||||||
|
ignore_unknown_cells = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
static std::string help(const char* default_seq) {
|
||||||
|
return stringf(
|
||||||
|
" -undef\n"
|
||||||
|
" enable modelling of undef states\n"
|
||||||
|
"\n"
|
||||||
|
" -seq <N>\n"
|
||||||
|
" the max. number of time steps to be considered (default = %s)\n"
|
||||||
|
"\n"
|
||||||
|
" -set-assumes\n"
|
||||||
|
" set all assumptions provided via $assume cells\n"
|
||||||
|
"\n"
|
||||||
|
" -ignore-unknown-cells\n"
|
||||||
|
" ignore all cells that can not be matched to a SAT model\n"
|
||||||
|
, default_seq);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Config = EquivBasicConfig>
|
||||||
struct EquivWorker {
|
struct EquivWorker {
|
||||||
RTLIL::Module *module;
|
RTLIL::Module *module;
|
||||||
|
|
||||||
ezSatPtr ez;
|
ezSatPtr ez;
|
||||||
SatGen satgen;
|
SatGen satgen;
|
||||||
|
Config cfg;
|
||||||
struct Config {
|
|
||||||
bool model_undef = false;
|
|
||||||
int max_seq = 1;
|
|
||||||
bool set_assumes = false;
|
|
||||||
bool ignore_unknown_cells = false;
|
|
||||||
|
|
||||||
bool parse(const std::vector<std::string>& args, size_t& idx) {
|
|
||||||
if (args[idx] == "-undef") {
|
|
||||||
model_undef = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (args[idx] == "-seq" && idx+1 < args.size()) {
|
|
||||||
max_seq = atoi(args[++idx].c_str());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (args[idx] == "-set-assumes") {
|
|
||||||
set_assumes = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (args[idx] == "-ignore-unknown-cells") {
|
|
||||||
ignore_unknown_cells = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
static std::string help(const char* default_seq) {
|
|
||||||
return stringf(
|
|
||||||
" -undef\n"
|
|
||||||
" enable modelling of undef states\n"
|
|
||||||
"\n"
|
|
||||||
" -seq <N>\n"
|
|
||||||
" the max. number of time steps to be considered (default = %s)\n"
|
|
||||||
"\n"
|
|
||||||
" -set-assumes\n"
|
|
||||||
" set all assumptions provided via $assume cells\n"
|
|
||||||
"\n"
|
|
||||||
" -ignore-unknown-cells\n"
|
|
||||||
" ignore all cells that can not be matched to a SAT model\n"
|
|
||||||
, default_seq);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Config cfg;
|
|
||||||
|
|
||||||
EquivWorker(RTLIL::Module *module, const SigMap *sigmap, Config cfg) : module(module), satgen(ez.get(), sigmap), cfg(cfg) {
|
EquivWorker(RTLIL::Module *module, const SigMap *sigmap, Config cfg) : module(module), satgen(ez.get(), sigmap), cfg(cfg) {
|
||||||
satgen.model_undef = cfg.model_undef;
|
satgen.model_undef = cfg.model_undef;
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct EquivInductWorker : public EquivWorker
|
struct EquivInductWorker : public EquivWorker<>
|
||||||
{
|
{
|
||||||
SigMap sigmap;
|
SigMap sigmap;
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ struct EquivInductWorker : public EquivWorker
|
||||||
dict<int, int> ez_step_is_consistent;
|
dict<int, int> ez_step_is_consistent;
|
||||||
SigPool undriven_signals;
|
SigPool undriven_signals;
|
||||||
|
|
||||||
EquivInductWorker(Module *module, const pool<Cell*> &unproven_equiv_cells, Config cfg) : EquivWorker(module, &sigmap, cfg), sigmap(module),
|
EquivInductWorker(Module *module, const pool<Cell*> &unproven_equiv_cells, EquivBasicConfig cfg) : EquivWorker<>(module, &sigmap, cfg), sigmap(module),
|
||||||
cells(module->selected_cells()), workset(unproven_equiv_cells),
|
cells(module->selected_cells()), workset(unproven_equiv_cells),
|
||||||
success_counter(0) {}
|
success_counter(0) {}
|
||||||
|
|
||||||
|
|
@ -174,7 +174,7 @@ struct EquivInductPass : public Pass {
|
||||||
log("Only selected $equiv cells are proven and only selected cells are used to\n");
|
log("Only selected $equiv cells are proven and only selected cells are used to\n");
|
||||||
log("perform the proof.\n");
|
log("perform the proof.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
EquivWorker::Config::help("4");
|
EquivBasicConfig::help("4");
|
||||||
log("\n");
|
log("\n");
|
||||||
log("This command is very effective in proving complex sequential circuits, when\n");
|
log("This command is very effective in proving complex sequential circuits, when\n");
|
||||||
log("the internal state of the circuit quickly propagates to $equiv cells.\n");
|
log("the internal state of the circuit quickly propagates to $equiv cells.\n");
|
||||||
|
|
@ -192,7 +192,7 @@ struct EquivInductPass : public Pass {
|
||||||
void execute(std::vector<std::string> args, Design *design) override
|
void execute(std::vector<std::string> args, Design *design) override
|
||||||
{
|
{
|
||||||
int success_counter = 0;
|
int success_counter = 0;
|
||||||
EquivWorker::Config cfg;
|
EquivBasicConfig cfg {};
|
||||||
cfg.max_seq = 4;
|
cfg.max_seq = 4;
|
||||||
|
|
||||||
log_header(design, "Executing EQUIV_INDUCT pass.\n");
|
log_header(design, "Executing EQUIV_INDUCT pass.\n");
|
||||||
|
|
|
||||||
|
|
@ -24,45 +24,44 @@
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct EquivSimpleWorker : public EquivWorker
|
struct EquivSimpleConfig : EquivBasicConfig {
|
||||||
{
|
bool verbose = false;
|
||||||
struct Config : EquivWorker::Config {
|
bool short_cones = false;
|
||||||
bool verbose = false;
|
bool group = true;
|
||||||
bool short_cones = false;
|
bool parse(const std::vector<std::string>& args, size_t& idx) {
|
||||||
bool group = true;
|
if (EquivBasicConfig::parse(args, idx))
|
||||||
bool parse(const std::vector<std::string>& args, size_t& idx) {
|
return true;
|
||||||
if (EquivWorker::Config::parse(args, idx))
|
if (args[idx] == "-v") {
|
||||||
return true;
|
verbose = true;
|
||||||
if (args[idx] == "-v") {
|
return true;
|
||||||
verbose = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (args[idx] == "-short") {
|
|
||||||
short_cones = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (args[idx] == "-nogroup") {
|
|
||||||
group = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
static std::string help(const char* default_seq) {
|
if (args[idx] == "-short") {
|
||||||
return EquivWorker::Config::help(default_seq) +
|
short_cones = true;
|
||||||
" -v\n"
|
return true;
|
||||||
" verbose output\n"
|
|
||||||
"\n"
|
|
||||||
" -short\n"
|
|
||||||
" create shorter input cones that stop at shared nodes. This yields\n"
|
|
||||||
" simpler SAT problems but sometimes fails to prove equivalence.\n"
|
|
||||||
"\n"
|
|
||||||
" -nogroup\n"
|
|
||||||
" disabling grouping of $equiv cells by output wire\n"
|
|
||||||
"\n";
|
|
||||||
}
|
}
|
||||||
};
|
if (args[idx] == "-nogroup") {
|
||||||
Config cfg;
|
group = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
static std::string help(const char* default_seq) {
|
||||||
|
return EquivBasicConfig::help(default_seq) +
|
||||||
|
" -v\n"
|
||||||
|
" verbose output\n"
|
||||||
|
"\n"
|
||||||
|
" -short\n"
|
||||||
|
" create shorter input cones that stop at shared nodes. This yields\n"
|
||||||
|
" simpler SAT problems but sometimes fails to prove equivalence.\n"
|
||||||
|
"\n"
|
||||||
|
" -nogroup\n"
|
||||||
|
" disabling grouping of $equiv cells by output wire\n"
|
||||||
|
"\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EquivSimpleWorker : public EquivWorker<EquivSimpleConfig>
|
||||||
|
{
|
||||||
const vector<Cell*> &equiv_cells;
|
const vector<Cell*> &equiv_cells;
|
||||||
const vector<Cell*> &assume_cells;
|
const vector<Cell*> &assume_cells;
|
||||||
struct Cone {
|
struct Cone {
|
||||||
|
|
@ -82,8 +81,8 @@ struct EquivSimpleWorker : public EquivWorker
|
||||||
|
|
||||||
pool<pair<Cell*, int>> imported_cells_cache;
|
pool<pair<Cell*, int>> imported_cells_cache;
|
||||||
|
|
||||||
EquivSimpleWorker(const vector<Cell*> &equiv_cells, const vector<Cell*> &assume_cells, DesignModel model, Config cfg) :
|
EquivSimpleWorker(const vector<Cell*> &equiv_cells, const vector<Cell*> &assume_cells, DesignModel model, EquivSimpleConfig cfg) :
|
||||||
EquivWorker(equiv_cells.front()->module, &model.sigmap, cfg), equiv_cells(equiv_cells), assume_cells(assume_cells),
|
EquivWorker<EquivSimpleConfig>(equiv_cells.front()->module, &model.sigmap, cfg), equiv_cells(equiv_cells), assume_cells(assume_cells),
|
||||||
model(model) {}
|
model(model) {}
|
||||||
|
|
||||||
struct ConeFinder {
|
struct ConeFinder {
|
||||||
|
|
@ -270,7 +269,9 @@ struct EquivSimpleWorker : public EquivWorker
|
||||||
}
|
}
|
||||||
void construct_ezsat(const pool<SigBit>& input_bits, int step)
|
void construct_ezsat(const pool<SigBit>& input_bits, int step)
|
||||||
{
|
{
|
||||||
|
log("ezsat\n");
|
||||||
if (cfg.set_assumes) {
|
if (cfg.set_assumes) {
|
||||||
|
log("yep assume\n");
|
||||||
if (cfg.verbose && step == cfg.max_seq) {
|
if (cfg.verbose && step == cfg.max_seq) {
|
||||||
RTLIL::SigSpec assumes_a, assumes_en;
|
RTLIL::SigSpec assumes_a, assumes_en;
|
||||||
satgen.getAssumes(assumes_a, assumes_en, step+1);
|
satgen.getAssumes(assumes_a, assumes_en, step+1);
|
||||||
|
|
@ -427,12 +428,12 @@ struct EquivSimplePass : public Pass {
|
||||||
log("\n");
|
log("\n");
|
||||||
log("This command tries to prove $equiv cells using a simple direct SAT approach.\n");
|
log("This command tries to prove $equiv cells using a simple direct SAT approach.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
EquivSimpleWorker::Config::help("1");
|
EquivSimpleConfig::help("1");
|
||||||
log("\n");
|
log("\n");
|
||||||
}
|
}
|
||||||
void execute(std::vector<std::string> args, Design *design) override
|
void execute(std::vector<std::string> args, Design *design) override
|
||||||
{
|
{
|
||||||
EquivSimpleWorker::Config cfg = {};
|
EquivSimpleConfig cfg {};
|
||||||
int success_counter = 0;
|
int success_counter = 0;
|
||||||
|
|
||||||
log_header(design, "Executing EQUIV_SIMPLE pass.\n");
|
log_header(design, "Executing EQUIV_SIMPLE pass.\n");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue