3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-05-27 20:36:31 +00:00
This commit is contained in:
Lofty 2026-05-20 14:30:09 +01:00
parent 5f1d2297aa
commit 83ae8aa633
4 changed files with 98 additions and 16 deletions

View file

@ -23,6 +23,10 @@
// http://fmv.jku.at/papers/Biere-FMV-TR-07-1.pdf
// https://stackoverflow.com/a/46137633
#include "kernel/log.h"
#include "kernel/rtlil.h"
#include <cstdint>
#include <string>
#ifdef _MSC_VER
#include <stdlib.h>
#define __builtin_bswap32 _byteswap_ulong
@ -348,7 +352,7 @@ RTLIL::Wire* AigerReader::createWireIfNotExists(RTLIL::Module *module, unsigned
RTLIL::IdString wire_name(stringf("$aiger%d$%d%s", aiger_autoidx, variable, invert ? "b" : ""));
RTLIL::Wire *wire = module->wire(wire_name);
if (wire) return wire;
log_debug2("Creating %s\n", wire_name.c_str());
log_debug("Creating %s\n", wire_name.c_str());
wire = module->addWire(wire_name);
wire->port_input = wire->port_output = false;
if (!invert) return wire;
@ -358,12 +362,12 @@ RTLIL::Wire* AigerReader::createWireIfNotExists(RTLIL::Module *module, unsigned
if (module->cell(wire_inv_name)) return wire;
}
else {
log_debug2("Creating %s\n", wire_inv_name.c_str());
log_debug("Creating %s\n", wire_inv_name.c_str());
wire_inv = module->addWire(wire_inv_name);
wire_inv->port_input = wire_inv->port_output = false;
}
log_debug2("Creating %s = ~%s\n", wire_name.c_str(), wire_inv_name.c_str());
log_debug("Creating cell \"$not$aiger%d$%d\" to represent %s = ~%s\n", aiger_autoidx, variable, wire_name.c_str(), wire_inv_name.c_str());
module->addNotGate(stringf("$not$aiger%d$%d", aiger_autoidx, variable), wire_inv, wire);
return wire;
@ -406,7 +410,7 @@ void AigerReader::parse_xaiger()
module->connect(n0, State::S0);
int c = f.get();
if (c != 'c')
if (c != 'c') // 'c'omment section (used for extensions)
log_error("Line %u: cannot interpret first character '%c'!\n", line_count, c);
if (f.peek() == '\n')
f.get();
@ -415,7 +419,7 @@ void AigerReader::parse_xaiger()
std::string s;
for (int c = f.get(); c != EOF; c = f.get()) {
// XAIGER extensions
if (c == 'm') {
if (c == 'm') { // LUT 'm'apping
uint32_t dataSize = parse_xaiger_literal(f);
uint32_t lutNum = parse_xaiger_literal(f);
uint32_t lutSize = parse_xaiger_literal(f);
@ -461,7 +465,83 @@ void AigerReader::parse_xaiger()
module->addLut(stringf("$lut$aiger%d$%d", aiger_autoidx, rootNodeID), input_sig, output_sig, std::move(lut_mask));
}
}
else if (c == 'r') {
else if (c == 'M') { // cell 'M'apping
struct MappingCell {
RTLIL::IdString type;
RTLIL::IdString out;
std::vector<RTLIL::IdString> ins;
};
std::vector<MappingCell> mapping_cells;
uint32_t dataSize = parse_xaiger_literal(f);
uint32_t cellNum = parse_xaiger_literal(f);
uint32_t instanceNum = parse_xaiger_literal(f);
log_debug("M: dataSize=%u cellNum=%u instanceNum=%u\n", dataSize, cellNum, instanceNum);
for (unsigned i = 0; i < cellNum; ++i) {
MappingCell mapping_cell{};
auto cellName = std::string{}; // name of cell
auto outPinName = std::string{}; // name of cell output pin
std::getline(f, cellName, '\0');
std::getline(f, outPinName, '\0');
uint32_t inPinNum = parse_xaiger_literal(f);
log_debug("M: cellID=%u cellName=%s outPinName=%s inPinNum=%u\n", i, cellName, outPinName, inPinNum);
mapping_cell.type = RTLIL::escape_id(cellName);
mapping_cell.out = RTLIL::escape_id(outPinName);
auto module = design->addModule(RTLIL::escape_id(cellName));
module->set_bool_attribute(ID::blackbox);
module->addWire(RTLIL::escape_id(outPinName))->port_output = true;
for (unsigned j = 0; j < inPinNum; ++j) {
auto inPinName = std::string{};
std::getline(f, inPinName, '\0');
log_debug("M: inPinName=%s\n", inPinName);
mapping_cell.ins.push_back(RTLIL::escape_id(inPinName));
module->addWire(RTLIL::escape_id(inPinName))->port_input = true;
}
module->fixup_ports();
mapping_cells.push_back(std::move(mapping_cell));
}
for (unsigned i = 0; i < instanceNum; ++i) {
uint32_t cellID = parse_xaiger_literal(f);
uint32_t rootNodeID = parse_xaiger_literal(f);
log_assert(cellID < cellNum);
MappingCell &mapping_cell = mapping_cells.at(cellID);
log_debug("M: instanceID=%u cellID=%u outPort=%s rootNodeID=%u\n", i, cellID, RTLIL::unescape_id(mapping_cell.out), rootNodeID);
RTLIL::Wire *output_sig = createWireIfNotExists(module, rootNodeID);
log_assert(output_sig);
{
RTLIL::IdString output_cell_name;
if ((rootNodeID & 1) == 0) { // uninverted
output_cell_name = stringf("$and$aiger%d$%d", aiger_autoidx, rootNodeID >> 1);
} else { // inverted
output_cell_name = stringf("$not$aiger%d$%d", aiger_autoidx, rootNodeID >> 1);
}
RTLIL::Cell *output_cell = module->cell(output_cell_name);
log_assert(output_cell);
module->remove(output_cell);
}
RTLIL::Cell *cell = module->addCell(stringf("$sc$aiger%d$%d", aiger_autoidx, rootNodeID), mapping_cell.type);
cell->setPort(mapping_cell.out, output_sig);
for (unsigned j = 0; j < mapping_cell.ins.size(); ++j) {
auto nodeID = parse_xaiger_literal(f);
log_debug("M: inPort=%s nodeID=%u\n", RTLIL::unescape_id(mapping_cell.ins.at(j)), nodeID);
RTLIL::Wire *input_sig = createWireIfNotExists(module, nodeID);
cell->setPort(mapping_cell.ins.at(j), input_sig);
}
}
}
else if (c == 'r') { // 'r'egister classes
uint32_t dataSize = parse_xaiger_literal(f);
flopNum = parse_xaiger_literal(f);
log_debug("flopNum = %u\n", flopNum);
@ -470,7 +550,7 @@ void AigerReader::parse_xaiger()
for (unsigned i = 0; i < flopNum; i++)
mergeability.emplace_back(parse_xaiger_literal(f));
}
else if (c == 's') {
else if (c == 's') { // register initial 's'tates
uint32_t dataSize = parse_xaiger_literal(f);
flopNum = parse_xaiger_literal(f);
log_assert(dataSize == (flopNum+1) * sizeof(uint32_t));
@ -478,13 +558,13 @@ void AigerReader::parse_xaiger()
for (unsigned i = 0; i < flopNum; i++)
initial_state.emplace_back(parse_xaiger_literal(f));
}
else if (c == 'n') {
else if (c == 'n') { // 'n'ame
parse_xaiger_literal(f);
f >> s;
log_debug("n: '%s'\n", s);
}
else if (c == 'h') {
f.ignore(sizeof(uint32_t));
else if (c == 'h') { // 'h'ierarchy information
f.ignore(sizeof(uint32_t)); // length
uint32_t version = parse_xaiger_literal(f);
log_assert(version == 1);
uint32_t ciNum = parse_xaiger_literal(f);
@ -510,7 +590,7 @@ void AigerReader::parse_xaiger()
boxes.emplace_back(cell);
}
}
else if (c == 'a' || c == 'i' || c == 'o' || c == 's') {
else if (c == 'a' /* 'a'dditional AIG */ || c == 'i' /* 'i'nput arrival times */ || c == 'o' /* 'o'utput required times */) {
uint32_t dataSize = parse_xaiger_literal(f);
f.ignore(dataSize);
log_debug("ignoring '%c'\n", c);
@ -634,7 +714,7 @@ void AigerReader::parse_aiger_ascii()
log_error("Line %u cannot be interpreted as an AND!\n", line_count);
std::getline(f, line); // Ignore up to start of next line
log_debug2("%d %d %d is an AND\n", l1, l2, l3);
log_debug("%d %d %d is an AND\n", l1, l2, l3);
log_assert(!(l1 & 1));
RTLIL::Wire *o_wire = createWireIfNotExists(module, l1);
RTLIL::Wire *i1_wire = createWireIfNotExists(module, l2);

View file

@ -187,7 +187,7 @@ struct Xaiger2Frontend : public Frontend {
if (c == 'h') {
uint32_t len, ci_num, co_num, pi_num, po_num, no_boxes;
len = read_be32(*f);
read_be32(*f);
read_be32(*f); // version
ci_num = read_be32(*f);
co_num = read_be32(*f);
pi_num = read_be32(*f);

View file

@ -193,8 +193,10 @@ struct AbcNewPass : public ScriptPass {
run(stringf(" abc9_ops -write_box %s/input.box", tmpdir));
run(stringf(" write_xaiger2 -mapping_prep -map2 %s/input.map2 %s/input.xaig", tmpdir, tmpdir));
run(stringf(" abc9_exe %s -cwd %s -box %s/input.box", exe_options, tmpdir, tmpdir));
run(stringf(" read_xaiger2 -sc_mapping -module_name %s -map2 %s/input.map2 %s/output.aig",
modname.c_str(), tmpdir.c_str(), tmpdir.c_str()));
/*run(stringf(" read_xaiger2 -sc_mapping -module_name %s -map2 %s/input.map2 %s/output.aig",
modname.c_str(), tmpdir.c_str(), tmpdir.c_str()));*/
run(stringf(" read_aiger -xaiger -module_name %s$abc9 %s/output.aig", modname.c_str(), tmpdir.c_str()));
run(stringf("abc9_ops -reintegrate"));
if (!help_mode && mod->has_attribute(ID(abc9_script))) {
if (script_save.empty())
active_design->scratchpad_unset("abc9.script");

View file

@ -323,7 +323,7 @@ struct SynthGateMatePass : public ScriptPass
abc_args += " -dff";
}
if (abc_new) {
run("abc_new " + abc_args, "(with -luttree and -abc_new)");
run("abc_new -nocleanup " + abc_args, "(with -luttree and -abc_new)");
} else {
run("abc " + abc_args, "(with -luttree, without -abc_new)");
}