mirror of
https://github.com/YosysHQ/yosys
synced 2025-08-09 20:50:51 +00:00
Refactor common parts of SAT-using optimizations into a helper.
This also aligns the functionality: - in all cases, the onehot attribute is used to create appropriate constraints (previously, opt_dff didn't do it at all, and share created one-hot constraints based on $pmux presence alone, which is unsound) - in all cases, shift and mul/div/pow cells are now skipped when importing the SAT problem (previously only memory_share did this) — this avoids creating clauses for hard cells that are unlikely to help with proving the UNSATness needed for optimization
This commit is contained in:
parent
d8fcf1ab25
commit
d25b9088c8
7 changed files with 224 additions and 153 deletions
102
kernel/qcsat.cc
Normal file
102
kernel/qcsat.cc
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2021 Marcelina Kościelnicka <mwk@0x04.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "kernel/qcsat.h"
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
|
||||
std::vector<int> QuickConeSat::importSig(SigSpec sig)
|
||||
{
|
||||
sig = modwalker.sigmap(sig);
|
||||
for (auto bit : sig)
|
||||
bits_queue.insert(bit);
|
||||
return satgen.importSigSpec(sig);
|
||||
}
|
||||
|
||||
int QuickConeSat::importSigBit(SigBit bit)
|
||||
{
|
||||
bit = modwalker.sigmap(bit);
|
||||
bits_queue.insert(bit);
|
||||
return satgen.importSigBit(bit);
|
||||
}
|
||||
|
||||
void QuickConeSat::prepare()
|
||||
{
|
||||
while (!bits_queue.empty())
|
||||
{
|
||||
pool<ModWalker::PortBit> portbits;
|
||||
modwalker.get_drivers(portbits, bits_queue);
|
||||
|
||||
for (auto bit : bits_queue)
|
||||
if (bit.wire && bit.wire->get_bool_attribute(ID::onehot) && !imported_onehot.count(bit.wire))
|
||||
{
|
||||
std::vector<int> bits = satgen.importSigSpec(bit.wire);
|
||||
for (int i : bits)
|
||||
for (int j : bits)
|
||||
if (i != j)
|
||||
ez->assume(ez->NOT(i), j);
|
||||
imported_onehot.insert(bit.wire);
|
||||
}
|
||||
|
||||
bits_queue.clear();
|
||||
|
||||
for (auto &pbit : portbits)
|
||||
{
|
||||
if (imported_cells.count(pbit.cell))
|
||||
continue;
|
||||
if (cell_complexity(pbit.cell) > max_cell_complexity)
|
||||
continue;
|
||||
if (max_cell_outs && GetSize(modwalker.cell_outputs[pbit.cell]) > max_cell_outs)
|
||||
continue;
|
||||
auto &inputs = modwalker.cell_inputs[pbit.cell];
|
||||
bits_queue.insert(inputs.begin(), inputs.end());
|
||||
satgen.importCell(pbit.cell);
|
||||
imported_cells.insert(pbit.cell);
|
||||
}
|
||||
|
||||
if (max_cell_count && GetSize(imported_cells) > max_cell_count)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int QuickConeSat::cell_complexity(RTLIL::Cell *cell)
|
||||
{
|
||||
if (cell->type.in(ID($concat), ID($slice), ID($pos), ID($_BUF_)))
|
||||
return 0;
|
||||
if (cell->type.in(ID($not), ID($and), ID($or), ID($xor), ID($xnor),
|
||||
ID($reduce_and), ID($reduce_or), ID($reduce_xor),
|
||||
ID($reduce_xnor), ID($reduce_bool),
|
||||
ID($logic_not), ID($logic_and), ID($logic_or),
|
||||
ID($eq), ID($ne), ID($eqx), ID($nex), ID($fa),
|
||||
ID($mux), ID($pmux), ID($lut), ID($sop),
|
||||
ID($_NOT_), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_),
|
||||
ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_),
|
||||
ID($_MUX_), ID($_NMUX_), ID($_MUX4_), ID($_MUX8_), ID($_MUX16_),
|
||||
ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_)))
|
||||
return 1;
|
||||
if (cell->type.in(ID($neg), ID($add), ID($sub), ID($alu), ID($lcu),
|
||||
ID($lt), ID($le), ID($gt), ID($ge)))
|
||||
return 2;
|
||||
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)))
|
||||
return 3;
|
||||
if (cell->type.in(ID($mul), ID($macc), ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($pow)))
|
||||
return 4;
|
||||
// Unknown cell.
|
||||
return 5;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue