3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-01-06 02:52:44 +00:00

Merge remote-tracking branch 'origin/main' into gussmith23-rosette-backend-updates

This commit is contained in:
Gus Smith 2025-11-29 14:20:36 -08:00
commit 6fe35fa46c
694 changed files with 33466 additions and 17901 deletions

View file

@ -132,7 +132,7 @@ struct AigerWriter
return a;
}
AigerWriter(Module *module, bool zinit_mode, bool imode, bool omode, bool bmode, bool lmode) : module(module), zinit_mode(zinit_mode), sigmap(module)
AigerWriter(Module *module, bool no_sort, bool zinit_mode, bool imode, bool omode, bool bmode, bool lmode) : module(module), zinit_mode(zinit_mode), sigmap(module)
{
pool<SigBit> undriven_bits;
pool<SigBit> unused_bits;
@ -152,6 +152,37 @@ struct AigerWriter
if (wire->port_input)
sigmap.add(wire);
// handle ports
// provided the input_bits and output_bits don't get sorted they
// will be returned in reverse order, so add them in reverse to
// match
for (auto riter = module->ports.rbegin(); riter != module->ports.rend(); ++riter) {
auto *wire = module->wire(*riter);
for (int i = 0; i < GetSize(wire); i++)
{
SigBit wirebit(wire, i);
SigBit bit = sigmap(wirebit);
if (bit.wire == nullptr) {
if (wire->port_output) {
aig_map[wirebit] = (bit == State::S1) ? 1 : 0;
output_bits.insert(wirebit);
}
continue;
}
if (wire->port_input)
input_bits.insert(bit);
if (wire->port_output) {
if (bit != wirebit)
alias_map[wirebit] = bit;
output_bits.insert(wirebit);
}
}
}
// handle wires
for (auto wire : module->wires())
{
if (wire->attributes.count(ID::init)) {
@ -167,25 +198,13 @@ struct AigerWriter
SigBit wirebit(wire, i);
SigBit bit = sigmap(wirebit);
if (bit.wire == nullptr) {
if (wire->port_output) {
aig_map[wirebit] = (bit == State::S1) ? 1 : 0;
output_bits.insert(wirebit);
}
if (bit.wire == nullptr)
continue;
if (wire->port_input || wire->port_output)
continue;
}
undriven_bits.insert(bit);
unused_bits.insert(bit);
if (wire->port_input)
input_bits.insert(bit);
if (wire->port_output) {
if (bit != wirebit)
alias_map[wirebit] = bit;
output_bits.insert(wirebit);
}
}
if (wire->width == 1) {
@ -200,12 +219,6 @@ struct AigerWriter
}
}
for (auto bit : input_bits)
undriven_bits.erase(bit);
for (auto bit : output_bits)
unused_bits.erase(bit);
for (auto cell : module->cells())
{
if (cell->type == ID($_NOT_))
@ -343,8 +356,11 @@ struct AigerWriter
}
init_map.sort();
input_bits.sort();
output_bits.sort();
// we are relying here on unsorted pools iterating last-in-first-out
if (!no_sort) {
input_bits.sort();
output_bits.sort();
}
not_map.sort();
ff_map.sort();
and_map.sort();
@ -697,7 +713,7 @@ struct AigerWriter
}
if (wire->port_output) {
int o = ordered_outputs.at(sig[i]);
int o = ordered_outputs.at(SigSpec(wire, i));
output_lines[o] += stringf("output %d %d %s\n", o, index, log_id(wire));
}
@ -901,6 +917,9 @@ struct AigerBackend : public Backend {
log(" -symbols\n");
log(" include a symbol table in the generated AIGER file\n");
log("\n");
log(" -no-sort\n");
log(" don't sort input/output ports\n");
log("\n");
log(" -map <filename>\n");
log(" write an extra file with port and latch symbols\n");
log("\n");
@ -925,6 +944,7 @@ struct AigerBackend : public Backend {
bool zinit_mode = false;
bool miter_mode = false;
bool symbols_mode = false;
bool no_sort = false;
bool verbose_map = false;
bool imode = false;
bool omode = false;
@ -955,6 +975,10 @@ struct AigerBackend : public Backend {
symbols_mode = true;
continue;
}
if (args[argidx] == "-no-sort") {
no_sort = true;
continue;
}
if (map_filename.empty() && args[argidx] == "-map" && argidx+1 < args.size()) {
map_filename = args[++argidx];
continue;
@ -1008,7 +1032,7 @@ struct AigerBackend : public Backend {
if (!top_module->memories.empty())
log_error("Found unmapped memories in module %s: unmapped memories are not supported in AIGER backend!\n", log_id(top_module));
AigerWriter writer(top_module, zinit_mode, imode, omode, bmode, lmode);
AigerWriter writer(top_module, no_sort, zinit_mode, imode, omode, bmode, lmode);
writer.write_aiger(*f, ascii_mode, miter_mode, symbols_mode);
if (!map_filename.empty()) {
@ -1016,7 +1040,7 @@ struct AigerBackend : public Backend {
std::ofstream mapf;
mapf.open(map_filename.c_str(), std::ofstream::trunc);
if (mapf.fail())
log_error("Can't open file `%s' for writing: %s\n", map_filename.c_str(), strerror(errno));
log_error("Can't open file `%s' for writing: %s\n", map_filename, strerror(errno));
writer.write_map(mapf, verbose_map, no_startoffset);
}
@ -1027,7 +1051,7 @@ struct AigerBackend : public Backend {
PrettyJson json;
if (!json.write_to_file(yw_map_filename))
log_error("Can't open file `%s' for writing: %s\n", yw_map_filename.c_str(), strerror(errno));
log_error("Can't open file `%s' for writing: %s\n", yw_map_filename, strerror(errno));
writer.write_ywmap(json);
}
}

View file

@ -788,7 +788,7 @@ struct XAigerBackend : public Backend {
std::ofstream mapf;
mapf.open(map_filename.c_str(), std::ofstream::trunc);
if (mapf.fail())
log_error("Can't open file `%s' for writing: %s\n", map_filename.c_str(), strerror(errno));
log_error("Can't open file `%s' for writing: %s\n", map_filename, strerror(errno));
writer.write_map(mapf);
}
}

View file

@ -91,7 +91,7 @@ struct Index {
int pos = index_wires(info, m);
for (auto cell : m->cells()) {
if (cell->type.in(KNOWN_OPS) || cell->type.in(ID($scopeinfo), ID($specify2), ID($specify3)))
if (cell->type.in(KNOWN_OPS) || cell->type.in(ID($scopeinfo), ID($specify2), ID($specify3), ID($input_port)))
continue;
Module *submodule = m->design->module(cell->type);
@ -105,6 +105,13 @@ struct Index {
if (allow_blackboxes) {
info.found_blackboxes.insert(cell);
} else {
// Even if we don't allow blackboxes these might still be
// present outside of any traversed input cones, so we
// can't bail at this point. If they are hit by a traversal
// (which can only really happen with $tribuf not
// $connect), we can still detect this as an error later.
if (cell->type == ID($connect) || (cell->type == ID($tribuf) && cell->has_attribute(ID(aiger2_zbuf))))
continue;
if (!submodule || submodule->get_blackbox_attribute())
log_error("Unsupported cell type: %s (%s in %s)\n",
log_id(cell->type), log_id(cell), log_id(m));
@ -483,7 +490,8 @@ struct Index {
{
Design *design = index.design;
auto &minfo = leaf_minfo(index);
log_assert(minfo.suboffsets.count(cell));
if (!minfo.suboffsets.count(cell))
log_error("Reached unsupport cell %s (%s in %s)\n", log_id(cell->type), log_id(cell), log_id(cell->module));
Module *def = design->module(cell->type);
log_assert(def);
levels.push_back(Level(index.modules.at(def), cell));
@ -566,7 +574,7 @@ struct Index {
}
Lit ret;
if (!bit.wire->port_input) {
if (!bit.wire->port_input || bit.wire->port_output) {
// an output of a cell
Cell *driver = bit.wire->driverCell();
@ -618,7 +626,7 @@ struct Index {
if (!cursor) {
log_assert(bit.wire->module == top);
log_assert(bit.wire->port_input);
log_assert(bit.wire->port_input && !bit.wire->port_output);
return lits[top_minfo->windices[bit.wire] + bit.offset];
} else {
log_assert(bit.wire->module == cursor->leaf_module(*this));
@ -723,7 +731,7 @@ struct AigerWriter : Index<AigerWriter, unsigned int, 0, 1> {
for (auto id : top->ports) {
Wire *w = top->wire(id);
log_assert(w);
if (w->port_input)
if (w->port_input && !w->port_output)
for (int i = 0; i < w->width; i++) {
pi_literal(SigBit(w, i)) = lit_counter;
inputs.push_back(SigBit(w, i));
@ -828,7 +836,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
{
log_assert(cursor.is_top()); // TOOD: fix analyzer to work with hierarchy
if (bit.wire->port_input)
if (bit.wire->port_input && !bit.wire->port_output)
return false;
Cell *driver = bit.wire->driverCell();
@ -838,7 +846,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
int max = 1;
for (auto wire : mod->wires())
if (wire->port_input)
if (wire->port_input && !wire->port_output)
for (int i = 0; i < wire->width; i++) {
int ilevel = visit(cursor, driver->getPort(wire->name)[i]);
max = std::max(max, ilevel + 1);
@ -858,7 +866,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
for (auto id : top->ports) {
Wire *w = top->wire(id);
log_assert(w);
if (w->port_input)
if (w->port_input && !w->port_output)
for (int i = 0; i < w->width; i++)
pi_literal(SigBit(w, i)) = 0;
}
@ -868,7 +876,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
Module *def = design->module(box->type);
if (!(def && def->has_attribute(ID::abc9_box_id)))
for (auto &conn : box->connections_)
if (box->output(conn.first))
if (box->port_dir(conn.first) != RTLIL::PD_INPUT)
for (auto bit : conn.second)
pi_literal(bit, &cursor) = 0;
}
@ -883,7 +891,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
Module *def = design->module(box->type);
if (!(def && def->has_attribute(ID::abc9_box_id)))
for (auto &conn : box->connections_)
if (box->input(conn.first))
if (box->port_dir(conn.first) == RTLIL::PD_INPUT)
for (auto bit : conn.second)
(void) eval_po(bit);
}
@ -903,6 +911,16 @@ struct XAigerWriter : AigerWriter {
typedef std::pair<SigBit, HierCursor> HierBit;
std::vector<HierBit> pos;
std::vector<HierBit> pis;
// * The aiger output port sequence is COs (inputs to modeled boxes),
// inputs to opaque boxes, then module outputs. COs going first is
// required by abc.
// * proper_pos_counter counts ports which follow after COs
// * The mapping file `pseudopo` and `po` statements use indexing relative
// to the first port following COs.
// * If a module output is directly driven by an opaque box, the emission
// of the po statement in the mapping file is skipped. This is done to
// aid re-integration of the mapped result.
int proper_pos_counter = 0;
pool<SigBit> driven_by_opaque_box;
@ -937,15 +955,10 @@ struct XAigerWriter : AigerWriter {
lit_counter += 2;
}
void append_box_ports(Cell *box, HierCursor &cursor, bool inputs)
void append_opaque_box_ports(Cell *box, HierCursor &cursor, bool inputs)
{
for (auto &conn : box->connections_) {
bool is_input = box->input(conn.first);
bool is_output = box->output(conn.first);
if (!(is_input || is_output) || (is_input && is_output))
log_error("Ambiguous port direction on %s/%s\n",
log_id(box->type), log_id(conn.first));
bool is_input = box->port_dir(conn.first) == RTLIL::PD_INPUT;
if (is_input && inputs) {
int bitp = 0;
@ -955,13 +968,14 @@ struct XAigerWriter : AigerWriter {
continue;
}
// Inputs to opaque boxes are proper POs as far as abc is concerned
if (map_file.is_open()) {
log_assert(cursor.is_top());
map_file << "pseudopo " << proper_pos_counter++ << " " << bitp
map_file << "pseudopo " << proper_pos_counter << " " << bitp
<< " " << box->name.c_str()
<< " " << conn.first.c_str() << "\n";
}
proper_pos_counter++;
pos.push_back(std::make_pair(bit, cursor));
if (mapping_prep)
@ -969,10 +983,10 @@ struct XAigerWriter : AigerWriter {
bitp++;
}
} else if (is_output && !inputs) {
} else if (!is_input && !inputs) {
for (auto &bit : conn.second) {
if (!bit.wire || bit.wire->port_input)
log_error("Bad connection");
if (!bit.wire || (bit.wire->port_input && !bit.wire->port_output))
log_error("Bad connection %s/%s ~ %s\n", log_id(box), log_id(conn.first), log_signal(conn.second));
ensure_pi(bit, cursor);
@ -1011,8 +1025,8 @@ struct XAigerWriter : AigerWriter {
auto &minfo = cursor.leaf_minfo(*this);
for (auto box : minfo.found_blackboxes) {
log_debug(" - %s.%s (type %s): ", cursor.path().c_str(),
RTLIL::unescape_id(box->name).c_str(),
log_debug(" - %s.%s (type %s): ", cursor.path(),
RTLIL::unescape_id(box->name),
log_id(box->type));
Module *box_module = design->module(box->type), *box_derived;
@ -1038,7 +1052,7 @@ struct XAigerWriter : AigerWriter {
});
for (auto [cursor, box, def] : opaque_boxes)
append_box_ports(box, cursor, false);
append_opaque_box_ports(box, cursor, false);
holes_module = design->addModule(NEW_ID);
std::vector<RTLIL::Wire *> holes_pis;
@ -1086,6 +1100,8 @@ struct XAigerWriter : AigerWriter {
bit = RTLIL::Sx;
}
// Nonopaque box inputs come first and are not part of
// the PO numbering used by the mapping file.
pos.push_back(std::make_pair(bit, cursor));
}
boxes_co_num += port->width;
@ -1106,7 +1122,7 @@ struct XAigerWriter : AigerWriter {
holes_pi_idx++;
}
holes_wb->setPort(port_id, in_conn);
} else if (port->port_output && !port->port_input) {
} else if (port->port_output) {
// primary
for (int i = 0; i < port->width; i++) {
SigBit bit;
@ -1138,7 +1154,7 @@ struct XAigerWriter : AigerWriter {
}
for (auto [cursor, box, def] : opaque_boxes)
append_box_ports(box, cursor, true);
append_opaque_box_ports(box, cursor, true);
write_be32(h_buffer, 1);
write_be32(h_buffer, pis.size());
@ -1159,7 +1175,7 @@ struct XAigerWriter : AigerWriter {
log_assert(port);
if (port->port_input && !port->port_output) {
box_co_num += port->width;
} else if (port->port_output && !port->port_input) {
} else if (port->port_output) {
box_ci_num += port->width;
} else {
log_abort();
@ -1182,7 +1198,7 @@ struct XAigerWriter : AigerWriter {
reset_counters();
for (auto w : top->wires())
if (w->port_input)
if (w->port_input && !w->port_output)
for (int i = 0; i < w->width; i++)
ensure_pi(SigBit(w, i));
@ -1195,10 +1211,14 @@ struct XAigerWriter : AigerWriter {
for (auto w : top->wires())
if (w->port_output)
for (int i = 0; i < w->width; i++) {
// When a module output is directly driven by an opaque box, we
// don't emit it to the mapping file to aid re-integration, but we
// do emit a proper PO.
if (map_file.is_open() && !driven_by_opaque_box.count(SigBit(w, i))) {
map_file << "po " << proper_pos_counter++ << " " << i
map_file << "po " << proper_pos_counter << " " << i
<< " " << w->name.c_str() << "\n";
}
proper_pos_counter++;
pos.push_back(std::make_pair(SigBit(w, i), HierCursor{}));
}
@ -1446,7 +1466,7 @@ struct XAiger2Backend : Backend {
if (!map_filename.empty()) {
writer.map_file.open(map_filename);
if (!writer.map_file)
log_cmd_error("Failed to open '%s' for writing\n", map_filename.c_str());
log_cmd_error("Failed to open '%s' for writing\n", map_filename);
}
design->bufNormalize(true);

View file

@ -157,14 +157,14 @@ struct BlifDumper
f << stringf("%c", ch);
f << stringf("\"\n");
} else
f << stringf("%s\n", param.second.as_string().c_str());
f << stringf("%s\n", param.second.as_string());
}
}
void dump()
{
f << stringf("\n");
f << stringf(".model %s\n", str(module->name).c_str());
f << stringf(".model %s\n", str(module->name));
std::map<int, RTLIL::Wire*> inputs, outputs;
@ -179,7 +179,7 @@ struct BlifDumper
for (auto &it : inputs) {
RTLIL::Wire *wire = it.second;
for (int i = 0; i < wire->width; i++)
f << stringf(" %s", str(RTLIL::SigSpec(wire, i)).c_str());
f << stringf(" %s", str(RTLIL::SigSpec(wire, i)));
}
f << stringf("\n");
@ -187,7 +187,7 @@ struct BlifDumper
for (auto &it : outputs) {
RTLIL::Wire *wire = it.second;
for (int i = 0; i < wire->width; i++)
f << stringf(" %s", str(RTLIL::SigSpec(wire, i)).c_str());
f << stringf(" %s", str(RTLIL::SigSpec(wire, i)));
}
f << stringf("\n");
@ -200,7 +200,7 @@ struct BlifDumper
if (!config->impltf_mode) {
if (!config->false_type.empty()) {
if (config->false_type == "+")
f << stringf(".names %s\n", config->false_out.c_str());
f << stringf(".names %s\n", config->false_out);
else if (config->false_type != "-")
f << stringf(".%s %s %s=$false\n", subckt_or_gate(config->false_type),
config->false_type.c_str(), config->false_out.c_str());
@ -208,7 +208,7 @@ struct BlifDumper
f << stringf(".names $false\n");
if (!config->true_type.empty()) {
if (config->true_type == "+")
f << stringf(".names %s\n1\n", config->true_out.c_str());
f << stringf(".names %s\n1\n", config->true_out);
else if (config->true_type != "-")
f << stringf(".%s %s %s=$true\n", subckt_or_gate(config->true_type),
config->true_type.c_str(), config->true_out.c_str());
@ -216,7 +216,7 @@ struct BlifDumper
f << stringf(".names $true\n1\n");
if (!config->undef_type.empty()) {
if (config->undef_type == "+")
f << stringf(".names %s\n", config->undef_out.c_str());
f << stringf(".names %s\n", config->undef_out);
else if (config->undef_type != "-")
f << stringf(".%s %s %s=$undef\n", subckt_or_gate(config->undef_type),
config->undef_type.c_str(), config->undef_out.c_str());
@ -331,31 +331,31 @@ struct BlifDumper
}
if (!config->icells_mode && cell->type == ID($_FF_)) {
f << stringf(".latch %s %s%s\n", str(cell->getPort(ID::D)).c_str(), str(cell->getPort(ID::Q)).c_str(),
f << stringf(".latch %s %s%s\n", str(cell->getPort(ID::D)), str(cell->getPort(ID::Q)),
str_init(cell->getPort(ID::Q)).c_str());
goto internal_cell;
}
if (!config->icells_mode && cell->type == ID($_DFF_N_)) {
f << stringf(".latch %s %s fe %s%s\n", str(cell->getPort(ID::D)).c_str(), str(cell->getPort(ID::Q)).c_str(),
f << stringf(".latch %s %s fe %s%s\n", str(cell->getPort(ID::D)), str(cell->getPort(ID::Q)),
str(cell->getPort(ID::C)).c_str(), str_init(cell->getPort(ID::Q)).c_str());
goto internal_cell;
}
if (!config->icells_mode && cell->type == ID($_DFF_P_)) {
f << stringf(".latch %s %s re %s%s\n", str(cell->getPort(ID::D)).c_str(), str(cell->getPort(ID::Q)).c_str(),
f << stringf(".latch %s %s re %s%s\n", str(cell->getPort(ID::D)), str(cell->getPort(ID::Q)),
str(cell->getPort(ID::C)).c_str(), str_init(cell->getPort(ID::Q)).c_str());
goto internal_cell;
}
if (!config->icells_mode && cell->type == ID($_DLATCH_N_)) {
f << stringf(".latch %s %s al %s%s\n", str(cell->getPort(ID::D)).c_str(), str(cell->getPort(ID::Q)).c_str(),
f << stringf(".latch %s %s al %s%s\n", str(cell->getPort(ID::D)), str(cell->getPort(ID::Q)),
str(cell->getPort(ID::E)).c_str(), str_init(cell->getPort(ID::Q)).c_str());
goto internal_cell;
}
if (!config->icells_mode && cell->type == ID($_DLATCH_P_)) {
f << stringf(".latch %s %s ah %s%s\n", str(cell->getPort(ID::D)).c_str(), str(cell->getPort(ID::Q)).c_str(),
f << stringf(".latch %s %s ah %s%s\n", str(cell->getPort(ID::D)), str(cell->getPort(ID::Q)),
str(cell->getPort(ID::E)).c_str(), str_init(cell->getPort(ID::Q)).c_str());
goto internal_cell;
}
@ -366,10 +366,10 @@ struct BlifDumper
auto width = cell->parameters.at(ID::WIDTH).as_int();
log_assert(inputs.size() == width);
for (int i = width-1; i >= 0; i--)
f << stringf(" %s", str(inputs.extract(i, 1)).c_str());
f << stringf(" %s", str(inputs.extract(i, 1)));
auto &output = cell->getPort(ID::Y);
log_assert(output.size() == 1);
f << stringf(" %s", str(output).c_str());
f << stringf(" %s", str(output));
f << stringf("\n");
RTLIL::SigSpec mask = cell->parameters.at(ID::LUT);
for (int i = 0; i < (1 << width); i++)
@ -392,10 +392,10 @@ struct BlifDumper
table.push_back(State::S0);
log_assert(inputs.size() == width);
for (int i = 0; i < width; i++)
f << stringf(" %s", str(inputs.extract(i, 1)).c_str());
f << stringf(" %s", str(inputs.extract(i, 1)));
auto &output = cell->getPort(ID::Y);
log_assert(output.size() == 1);
f << stringf(" %s", str(output).c_str());
f << stringf(" %s", str(output));
f << stringf("\n");
for (int i = 0; i < depth; i++) {
for (int j = 0; j < width; j++) {
@ -410,11 +410,11 @@ struct BlifDumper
goto internal_cell;
}
f << stringf(".%s %s", subckt_or_gate(cell->type.str()), str(cell->type).c_str());
f << stringf(".%s %s", subckt_or_gate(cell->type.str()), str(cell->type));
for (auto &conn : cell->connections())
{
if (conn.second.size() == 1) {
f << stringf(" %s=%s", str(conn.first).c_str(), str(conn.second[0]).c_str());
f << stringf(" %s=%s", str(conn.first), str(conn.second[0]));
continue;
}
@ -423,11 +423,11 @@ struct BlifDumper
if (w == nullptr) {
for (int i = 0; i < GetSize(conn.second); i++)
f << stringf(" %s[%d]=%s", str(conn.first).c_str(), i, str(conn.second[i]).c_str());
f << stringf(" %s[%d]=%s", str(conn.first), i, str(conn.second[i]));
} else {
for (int i = 0; i < std::min(GetSize(conn.second), GetSize(w)); i++) {
SigBit sig(w, i);
f << stringf(" %s[%d]=%s", str(conn.first).c_str(), sig.wire->upto ?
f << stringf(" %s[%d]=%s", str(conn.first), sig.wire->upto ?
sig.wire->start_offset+sig.wire->width-sig.offset-1 :
sig.wire->start_offset+sig.offset, str(conn.second[i]).c_str());
}
@ -436,7 +436,7 @@ struct BlifDumper
f << stringf("\n");
if (config->cname_mode)
f << stringf(".cname %s\n", str(cell->name).c_str());
f << stringf(".cname %s\n", str(cell->name));
if (config->attr_mode)
dump_params(".attr", cell->attributes);
if (config->param_mode)
@ -445,7 +445,7 @@ struct BlifDumper
if (0) {
internal_cell:
if (config->iname_mode)
f << stringf(".cname %s\n", str(cell->name).c_str());
f << stringf(".cname %s\n", str(cell->name));
if (config->iattr_mode)
dump_params(".attr", cell->attributes);
}
@ -461,12 +461,12 @@ struct BlifDumper
continue;
if (config->conn_mode)
f << stringf(".conn %s %s\n", str(rhs_bit).c_str(), str(lhs_bit).c_str());
f << stringf(".conn %s %s\n", str(rhs_bit), str(lhs_bit));
else if (!config->buf_type.empty())
f << stringf(".%s %s %s=%s %s=%s\n", subckt_or_gate(config->buf_type), config->buf_type.c_str(),
f << stringf(".%s %s %s=%s %s=%s\n", subckt_or_gate(config->buf_type), config->buf_type,
config->buf_in.c_str(), str(rhs_bit).c_str(), config->buf_out.c_str(), str(lhs_bit).c_str());
else
f << stringf(".names %s %s\n1 1\n", str(rhs_bit).c_str(), str(lhs_bit).c_str());
f << stringf(".names %s %s\n1 1\n", str(rhs_bit), str(lhs_bit));
}
f << stringf(".end\n");
@ -674,7 +674,7 @@ struct BlifBackend : public Backend {
}
if (!top_module_name.empty())
log_error("Can't find top module `%s'!\n", top_module_name.c_str());
log_error("Can't find top module `%s'!\n", top_module_name);
for (auto module : mod_list)
BlifDumper::dump(*f, module, design, config);

View file

@ -98,24 +98,22 @@ struct BtorWorker
vector<ywmap_btor_sig> ywmap_states;
dict<SigBit, int> ywmap_clock_bits;
dict<SigBit, int> ywmap_clock_inputs;
vector<Cell *> ywmap_asserts;
vector<Cell *> ywmap_assumes;
PrettyJson ywmap_json;
void btorf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 2, 3))
template <typename... Args>
void btorf(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
{
va_list ap;
va_start(ap, fmt);
f << indent << vstringf(fmt, ap);
va_end(ap);
f << indent << fmt.format(args...);
}
void infof(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 2, 3))
template <typename... Args>
void infof(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
{
va_list ap;
va_start(ap, fmt);
info_lines.push_back(vstringf(fmt, ap));
va_end(ap);
info_lines.push_back(fmt.format(args...));
}
template<typename T>
@ -129,7 +127,7 @@ struct BtorWorker
std::replace(src.begin(), src.end(), ' ', '_');
if (srcsymbols.count(src) || module->count_id("\\" + src)) {
for (int i = 1;; i++) {
string s = stringf("%s-%d", src.c_str(), i);
string s = stringf("%s-%d", src, i);
if (!srcsymbols.count(s) && !module->count_id("\\" + s)) {
src = s;
break;
@ -192,7 +190,7 @@ struct BtorWorker
void btorf_push(const string &id)
{
if (verbose) {
f << indent << stringf(" ; begin %s\n", id.c_str());
f << indent << stringf(" ; begin %s\n", id);
indent += " ";
}
}
@ -201,7 +199,7 @@ struct BtorWorker
{
if (verbose) {
indent = indent.substr(4);
f << indent << stringf(" ; end %s\n", id.c_str());
f << indent << stringf(" ; end %s\n", id);
}
}
@ -246,7 +244,7 @@ struct BtorWorker
string cell_list;
for (auto c : cell_recursion_guard)
cell_list += stringf("\n %s", log_id(c));
log_error("Found topological loop while processing cell %s. Active cells:%s\n", log_id(cell), cell_list.c_str());
log_error("Found topological loop while processing cell %s. Active cells:%s\n", log_id(cell), cell_list);
}
cell_recursion_guard.insert(cell);
@ -322,12 +320,12 @@ struct BtorWorker
btorf("%d slt %d %d %d\n", nid_b_ltz, sid_bit, nid_b, nid_zero);
nid = next_nid++;
btorf("%d ite %d %d %d %d%s\n", nid, sid, nid_b_ltz, nid_l, nid_r, getinfo(cell).c_str());
btorf("%d ite %d %d %d %d%s\n", nid, sid, nid_b_ltz, nid_l, nid_r, getinfo(cell));
}
else
{
nid = next_nid++;
btorf("%d %s %d %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
btorf("%d %s %d %d %d%s\n", nid, btor_op, sid, nid_a, nid_b, getinfo(cell));
}
SigSpec sig = sigmap(cell->getPort(ID::Y));
@ -368,7 +366,7 @@ struct BtorWorker
int sid = get_bv_sid(width);
int nid = next_nid++;
btorf("%d %c%s %d %d %d%s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
btorf("%d %c%s %d %d %d%s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op, sid, nid_a, nid_b, getinfo(cell));
SigSpec sig = sigmap(cell->getPort(ID::Y));
@ -394,12 +392,12 @@ struct BtorWorker
if (cell->type == ID($_ANDNOT_)) {
btorf("%d not %d %d\n", nid1, sid, nid_b);
btorf("%d and %d %d %d%s\n", nid2, sid, nid_a, nid1, getinfo(cell).c_str());
btorf("%d and %d %d %d%s\n", nid2, sid, nid_a, nid1, getinfo(cell));
}
if (cell->type == ID($_ORNOT_)) {
btorf("%d not %d %d\n", nid1, sid, nid_b);
btorf("%d or %d %d %d%s\n", nid2, sid, nid_a, nid1, getinfo(cell).c_str());
btorf("%d or %d %d %d%s\n", nid2, sid, nid_a, nid1, getinfo(cell));
}
SigSpec sig = sigmap(cell->getPort(ID::Y));
@ -421,13 +419,13 @@ struct BtorWorker
if (cell->type == ID($_OAI3_)) {
btorf("%d or %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d and %d %d %d\n", nid2, sid, nid1, nid_c);
btorf("%d not %d %d%s\n", nid3, sid, nid2, getinfo(cell).c_str());
btorf("%d not %d %d%s\n", nid3, sid, nid2, getinfo(cell));
}
if (cell->type == ID($_AOI3_)) {
btorf("%d and %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d or %d %d %d\n", nid2, sid, nid1, nid_c);
btorf("%d not %d %d%s\n", nid3, sid, nid2, getinfo(cell).c_str());
btorf("%d not %d %d%s\n", nid3, sid, nid2, getinfo(cell));
}
SigSpec sig = sigmap(cell->getPort(ID::Y));
@ -452,14 +450,14 @@ struct BtorWorker
btorf("%d or %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d or %d %d %d\n", nid2, sid, nid_c, nid_d);
btorf("%d and %d %d %d\n", nid3, sid, nid1, nid2);
btorf("%d not %d %d%s\n", nid4, sid, nid3, getinfo(cell).c_str());
btorf("%d not %d %d%s\n", nid4, sid, nid3, getinfo(cell));
}
if (cell->type == ID($_AOI4_)) {
btorf("%d and %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d and %d %d %d\n", nid2, sid, nid_c, nid_d);
btorf("%d or %d %d %d\n", nid3, sid, nid1, nid2);
btorf("%d not %d %d%s\n", nid4, sid, nid3, getinfo(cell).c_str());
btorf("%d not %d %d%s\n", nid4, sid, nid3, getinfo(cell));
}
SigSpec sig = sigmap(cell->getPort(ID::Y));
@ -491,9 +489,9 @@ struct BtorWorker
int nid = next_nid++;
if (cell->type.in(ID($lt), ID($le), ID($ge), ID($gt))) {
btorf("%d %c%s %d %d %d%s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
btorf("%d %c%s %d %d %d%s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op, sid, nid_a, nid_b, getinfo(cell));
} else {
btorf("%d %s %d %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
btorf("%d %s %d %d %d%s\n", nid, btor_op, sid, nid_a, nid_b, getinfo(cell));
}
SigSpec sig = sigmap(cell->getPort(ID::Y));
@ -509,7 +507,7 @@ struct BtorWorker
goto okay;
}
if (cell->type.in(ID($not), ID($neg), ID($_NOT_), ID($pos)))
if (cell->type.in(ID($not), ID($neg), ID($_NOT_), ID($pos), ID($buf), ID($_BUF_)))
{
string btor_op;
if (cell->type.in(ID($not), ID($_NOT_))) btor_op = "not";
@ -521,14 +519,14 @@ struct BtorWorker
int nid_a = get_sig_nid(cell->getPort(ID::A), width, a_signed);
SigSpec sig = sigmap(cell->getPort(ID::Y));
// the $pos cell just passes through, all other cells need an actual operation applied
// the $pos/$buf cells just pass through, all other cells need an actual operation applied
int nid = nid_a;
if (cell->type != ID($pos))
if (!cell->type.in(ID($pos), ID($buf), ID($_BUF_)))
{
log_assert(!btor_op.empty());
int sid = get_bv_sid(width);
nid = next_nid++;
btorf("%d %s %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
btorf("%d %s %d %d%s\n", nid, btor_op, sid, nid_a, getinfo(cell));
}
if (GetSize(sig) < width) {
@ -568,9 +566,9 @@ struct BtorWorker
int nid = next_nid++;
if (btor_op != "not")
btorf("%d %s %d %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
btorf("%d %s %d %d %d%s\n", nid, btor_op, sid, nid_a, nid_b, getinfo(cell));
else
btorf("%d %s %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
btorf("%d %s %d %d%s\n", nid, btor_op, sid, nid_a, getinfo(cell));
SigSpec sig = sigmap(cell->getPort(ID::Y));
@ -601,11 +599,11 @@ struct BtorWorker
if (cell->type == ID($reduce_xnor)) {
int nid2 = next_nid++;
btorf("%d %s %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
btorf("%d %s %d %d%s\n", nid, btor_op, sid, nid_a, getinfo(cell));
btorf("%d not %d %d\n", nid2, sid, nid);
nid = nid2;
} else {
btorf("%d %s %d %d%s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
btorf("%d %s %d %d%s\n", nid, btor_op, sid, nid_a, getinfo(cell));
}
SigSpec sig = sigmap(cell->getPort(ID::Y));
@ -640,9 +638,9 @@ struct BtorWorker
int tmp = nid;
nid = next_nid++;
btorf("%d ite %d %d %d %d\n", tmp, sid, nid_s, nid_b, nid_a);
btorf("%d not %d %d%s\n", nid, sid, tmp, getinfo(cell).c_str());
btorf("%d not %d %d%s\n", nid, sid, tmp, getinfo(cell));
} else {
btorf("%d ite %d %d %d %d%s\n", nid, sid, nid_s, nid_b, nid_a, getinfo(cell).c_str());
btorf("%d ite %d %d %d %d%s\n", nid, sid, nid_s, nid_b, nid_a, getinfo(cell));
}
add_nid_sig(nid, sig_y);
@ -665,7 +663,7 @@ struct BtorWorker
int nid_s = get_sig_nid(sig_s.extract(i));
int nid2 = next_nid++;
if (i == GetSize(sig_s)-1)
btorf("%d ite %d %d %d %d%s\n", nid2, sid, nid_s, nid_b, nid, getinfo(cell).c_str());
btorf("%d ite %d %d %d %d%s\n", nid2, sid, nid_s, nid_b, nid, getinfo(cell));
else
btorf("%d ite %d %d %d %d\n", nid2, sid, nid_s, nid_b, nid);
nid = nid2;
@ -709,12 +707,13 @@ struct BtorWorker
}
}
Const initval;
Const::Builder initval_bits(GetSize(sig_q));
for (int i = 0; i < GetSize(sig_q); i++)
if (initbits.count(sig_q[i]))
initval.bits().push_back(initbits.at(sig_q[i]) ? State::S1 : State::S0);
initval_bits.push_back(initbits.at(sig_q[i]) ? State::S1 : State::S0);
else
initval.bits().push_back(State::Sx);
initval_bits.push_back(State::Sx);
Const initval = initval_bits.build();
int nid_init_val = -1;
@ -753,7 +752,7 @@ struct BtorWorker
int sid = get_bv_sid(GetSize(sig_y));
int nid = next_nid++;
btorf("%d state %d%s\n", nid, sid, getinfo(cell).c_str());
btorf("%d state %d%s\n", nid, sid, getinfo(cell));
ywmap_state(sig_y);
@ -776,7 +775,7 @@ struct BtorWorker
int one_nid = get_sig_nid(State::S1);
int zero_nid = get_sig_nid(State::S0);
initstate_nid = next_nid++;
btorf("%d state %d%s\n", initstate_nid, sid, getinfo(cell).c_str());
btorf("%d state %d%s\n", initstate_nid, sid, getinfo(cell));
btorf("%d init %d %d %d\n", next_nid++, sid, initstate_nid, one_nid);
btorf("%d next %d %d %d\n", next_nid++, sid, initstate_nid, zero_nid);
@ -1043,15 +1042,16 @@ struct BtorWorker
{
if (bit.wire == nullptr)
{
Const c(bit.data);
while (i+GetSize(c) < GetSize(sig) && sig[i+GetSize(c)].wire == nullptr)
c.bits().push_back(sig[i+GetSize(c)].data);
Const::Builder c_bits;
c_bits.push_back(bit.data);
while (i + GetSize(c_bits) < GetSize(sig) && sig[i + GetSize(c_bits)].wire == nullptr)
c_bits.push_back(sig[i + GetSize(c_bits)].data);
Const c = c_bits.build();
if (consts.count(c) == 0) {
int sid = get_bv_sid(GetSize(c));
int nid = next_nid++;
btorf("%d const %d %s\n", nid, sid, c.as_string().c_str());
btorf("%d const %d %s\n", nid, sid, c.as_string());
consts[c] = nid;
nid_width[nid] = GetSize(c);
}
@ -1215,7 +1215,7 @@ struct BtorWorker
int sid = get_bv_sid(GetSize(sig));
int nid = next_nid++;
btorf("%d input %d%s\n", nid, sid, getinfo(wire).c_str());
btorf("%d input %d%s\n", nid, sid, getinfo(wire));
ywmap_input(wire);
add_nid_sig(nid, sig);
@ -1260,7 +1260,7 @@ struct BtorWorker
btorf_push(stringf("output %s", log_id(wire)));
int nid = get_sig_nid(wire);
btorf("%d output %d%s\n", next_nid++, nid, getinfo(wire).c_str());
btorf("%d output %d%s\n", next_nid++, nid, getinfo(wire));
btorf_pop(stringf("output %s", log_id(wire)));
}
@ -1282,6 +1282,8 @@ struct BtorWorker
btorf("%d or %d %d %d\n", nid_a_or_not_en, sid, nid_a, nid_not_en);
btorf("%d constraint %d\n", nid, nid_a_or_not_en);
if (ywmap_json.active()) ywmap_assumes.emplace_back(cell);
btorf_pop(log_id(cell));
}
@ -1302,10 +1304,12 @@ struct BtorWorker
bad_properties.push_back(nid_en_and_not_a);
} else {
if (cover_mode) {
infof("bad %d%s\n", nid_en_and_not_a, getinfo(cell, true).c_str());
infof("bad %d%s\n", nid_en_and_not_a, getinfo(cell, true));
} else {
int nid = next_nid++;
btorf("%d bad %d%s\n", nid, nid_en_and_not_a, getinfo(cell, true).c_str());
btorf("%d bad %d%s\n", nid, nid_en_and_not_a, getinfo(cell, true));
if (ywmap_json.active()) ywmap_asserts.emplace_back(cell);
}
}
@ -1327,7 +1331,7 @@ struct BtorWorker
bad_properties.push_back(nid_en_and_a);
} else {
int nid = next_nid++;
btorf("%d bad %d%s\n", nid, nid_en_and_a, getinfo(cell, true).c_str());
btorf("%d bad %d%s\n", nid, nid_en_and_a, getinfo(cell, true));
}
btorf_pop(log_id(cell));
@ -1348,7 +1352,7 @@ struct BtorWorker
continue;
int this_nid = next_nid++;
btorf("%d uext %d %d %d%s\n", this_nid, sid, nid, 0, getinfo(wire).c_str());
btorf("%d uext %d %d %d%s\n", this_nid, sid, nid, 0, getinfo(wire));
if (info_clocks.count(nid))
info_clocks[this_nid] |= info_clocks[nid];
@ -1371,7 +1375,7 @@ struct BtorWorker
SigSpec sig = sigmap(cell->getPort(ID::D));
int nid_q = get_sig_nid(sig);
int sid = get_bv_sid(GetSize(sig));
btorf("%d next %d %d %d%s\n", next_nid++, sid, nid, nid_q, getinfo(cell).c_str());
btorf("%d next %d %d %d%s\n", next_nid++, sid, nid, nid_q, getinfo(cell));
btorf_pop(stringf("next %s", log_id(cell)));
}
@ -1430,7 +1434,7 @@ struct BtorWorker
}
int nid2 = next_nid++;
btorf("%d next %d %d %d%s\n", nid2, sid, nid, nid_head, (mem->cell ? getinfo(mem->cell) : getinfo(mem->mem)).c_str());
btorf("%d next %d %d %d%s\n", nid2, sid, nid, nid_head, (mem->cell ? getinfo(mem->cell) : getinfo(mem->mem)));
btorf_pop(stringf("next %s", log_id(mem->memid)));
}
@ -1463,6 +1467,7 @@ struct BtorWorker
log_assert(cursor == 0);
log_assert(GetSize(todo) == 1);
btorf("%d bad %d\n", nid, todo[cursor]);
// What do we do with ywmap_asserts when using single_bad?
}
}
@ -1489,7 +1494,7 @@ struct BtorWorker
std::ofstream f;
f.open(info_filename.c_str(), std::ofstream::trunc);
if (f.fail())
log_error("Can't open file `%s' for writing: %s\n", info_filename.c_str(), strerror(errno));
log_error("Can't open file `%s' for writing: %s\n", info_filename, strerror(errno));
for (auto &it : info_lines)
f << it;
f.close();
@ -1528,6 +1533,18 @@ struct BtorWorker
emit_ywmap_btor_sig(entry);
ywmap_json.end_array();
ywmap_json.name("asserts");
ywmap_json.begin_array();
for (Cell *cell : ywmap_asserts)
ywmap_json.value(witness_path(cell));
ywmap_json.end_array();
ywmap_json.name("assumes");
ywmap_json.begin_array();
for (Cell *cell : ywmap_assumes)
ywmap_json.value(witness_path(cell));
ywmap_json.end_array();
ywmap_json.end_object();
}
}

View file

@ -637,20 +637,6 @@ std::string escape_cxx_string(const std::string &input)
return output;
}
std::string basename(const std::string &filepath)
{
#ifdef _WIN32
const std::string dir_seps = "\\/";
#else
const std::string dir_seps = "/";
#endif
size_t sep_pos = filepath.find_last_of(dir_seps);
if (sep_pos != std::string::npos)
return filepath.substr(sep_pos + 1);
else
return filepath;
}
template<class T>
std::string get_hdl_name(T *object)
{
@ -1533,7 +1519,7 @@ struct CxxrtlWorker {
}
// Internal cells
} else if (is_internal_cell(cell->type)) {
log_cmd_error("Unsupported internal cell `%s'.\n", cell->type.c_str());
log_cmd_error("Unsupported internal cell `%s'.\n", cell->type);
// User cells
} else if (for_debug) {
// Outlines are called on demand when computing the value of a debug item. Nothing to do here.
@ -1668,26 +1654,29 @@ struct CxxrtlWorker {
f << signal_temp << " == ";
dump_sigspec(compare, /*is_lhs=*/false, for_debug);
} else if (compare.is_fully_const()) {
RTLIL::Const compare_mask, compare_value;
RTLIL::Const::Builder compare_mask_builder(compare.size());
RTLIL::Const::Builder compare_value_builder(compare.size());
for (auto bit : compare.as_const()) {
switch (bit) {
case RTLIL::S0:
case RTLIL::S1:
compare_mask.bits().push_back(RTLIL::S1);
compare_value.bits().push_back(bit);
compare_mask_builder.push_back(RTLIL::S1);
compare_value_builder.push_back(bit);
break;
case RTLIL::Sx:
case RTLIL::Sz:
case RTLIL::Sa:
compare_mask.bits().push_back(RTLIL::S0);
compare_value.bits().push_back(RTLIL::S0);
compare_mask_builder.push_back(RTLIL::S0);
compare_value_builder.push_back(RTLIL::S0);
break;
default:
log_assert(false);
}
}
RTLIL::Const compare_mask = compare_mask_builder.build();
RTLIL::Const compare_value = compare_value_builder.build();
f << "and_uu<" << compare.size() << ">(" << signal_temp << ", ";
dump_const(compare_mask);
f << ") == ";
@ -2429,8 +2418,6 @@ struct CxxrtlWorker {
inc_indent();
for (auto wire : module->wires()) {
const auto &debug_wire_type = debug_wire_types[wire];
if (!wire->name.isPublic())
continue;
count_public_wires++;
switch (debug_wire_type.type) {
case WireType::BUFFERED:
@ -2438,6 +2425,9 @@ struct CxxrtlWorker {
// Member wire
std::vector<std::string> flags;
if (!wire->name.isPublic())
flags.push_back("GENERATED");
if (wire->port_input && wire->port_output)
flags.push_back("INOUT");
else if (wire->port_output)
@ -2854,7 +2844,7 @@ struct CxxrtlWorker {
}
if (split_intf)
f << "#include \"" << basename(intf_filename) << "\"\n";
f << "#include \"" << name_from_file_path(intf_filename) << "\"\n";
else
f << "#include <cxxrtl/cxxrtl.h>\n";
f << "\n";
@ -3041,7 +3031,7 @@ struct CxxrtlWorker {
if (init == RTLIL::Const()) {
init = RTLIL::Const(State::Sx, GetSize(bit.wire));
}
init.bits()[bit.offset] = port.init_value[i];
init.set(bit.offset, port.init_value[i]);
}
}
}
@ -3477,8 +3467,8 @@ struct CxxrtlWorker {
};
struct CxxrtlBackend : public Backend {
static const int DEFAULT_OPT_LEVEL = 6;
static const int DEFAULT_DEBUG_LEVEL = 4;
static constexpr int DEFAULT_OPT_LEVEL = 6;
static constexpr int DEFAULT_DEBUG_LEVEL = 4;
CxxrtlBackend() : Backend("cxxrtl", "convert design to C++ RTL simulation") { }
void help() override
@ -3799,7 +3789,7 @@ struct CxxrtlBackend : public Backend {
if (args[argidx] == "-print-output" && argidx+1 < args.size()) {
worker.print_output = args[++argidx];
if (!(worker.print_output == "std::cout" || worker.print_output == "std::cerr")) {
log_cmd_error("Invalid output stream \"%s\".\n", worker.print_output.c_str());
log_cmd_error("Invalid output stream \"%s\".\n", worker.print_output);
worker.print_output = "std::cout";
}
continue;

View file

@ -200,6 +200,10 @@ enum cxxrtl_flag {
// node, such as inputs and dangling wires.
CXXRTL_UNDRIVEN = 1 << 4,
// Generated correspond to netlist nodes that correspond to state with an internal name, that
// need to be saved, but wouldn't otherwise have a debug item generated.
CXXRTL_GENERATED = 1 << 5,
// More object flags may be added in the future, but the existing ones will never change.
};

View file

@ -1294,6 +1294,7 @@ struct debug_item : ::cxxrtl_object {
DRIVEN_SYNC = CXXRTL_DRIVEN_SYNC,
DRIVEN_COMB = CXXRTL_DRIVEN_COMB,
UNDRIVEN = CXXRTL_UNDRIVEN,
GENERATED = CXXRTL_GENERATED,
};
debug_item(const ::cxxrtl_object &object) : cxxrtl_object(object) {}

View file

@ -30,9 +30,9 @@
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
#define EDIF_DEF(_id) edif_names(RTLIL::unescape_id(_id), true).c_str()
#define EDIF_DEFR(_id, _ren, _bl, _br) edif_names(RTLIL::unescape_id(_id), true, _ren, _bl, _br).c_str()
#define EDIF_REF(_id) edif_names(RTLIL::unescape_id(_id), false).c_str()
#define EDIF_DEF(_id) edif_names(RTLIL::unescape_id(_id), true)
#define EDIF_DEFR(_id, _ren, _bl, _br) edif_names(RTLIL::unescape_id(_id), true, _ren, _bl, _br)
#define EDIF_REF(_id) edif_names(RTLIL::unescape_id(_id), false)
struct EdifNames
{
@ -48,8 +48,8 @@ struct EdifNames
if (define) {
std::string new_id = operator()(id, false);
if (port_rename)
return stringf("(rename %s \"%s%c%d:%d%c\")", new_id.c_str(), id.c_str(), delim_left, range_left, range_right, delim_right);
return new_id != id ? stringf("(rename %s \"%s\")", new_id.c_str(), id.c_str()) : id;
return stringf("(rename %s \"%s%c%d:%d%c\")", new_id, id, delim_left, range_left, range_right, delim_right);
return new_id != id ? stringf("(rename %s \"%s\")", new_id, id) : id;
}
if (name_map.count(id) > 0)
@ -334,7 +334,7 @@ struct EdifBackend : public Backend {
auto add_prop = [&](IdString name, Const val) {
if ((val.flags & RTLIL::CONST_FLAG_STRING) != 0)
*f << stringf("\n (property %s (string \"%s\"))", EDIF_DEF(name), val.decode_string().c_str());
*f << stringf("\n (property %s (string \"%s\"))", EDIF_DEF(name), val.decode_string());
else if (val.size() <= 32 && RTLIL::SigSpec(val).is_fully_def())
*f << stringf("\n (property %s (integer %u))", EDIF_DEF(name), val.as_int());
else {
@ -348,7 +348,7 @@ struct EdifBackend : public Backend {
char digit_str[2] = { "0123456789abcdef"[digit_value], 0 };
hex_string = std::string(digit_str) + hex_string;
}
*f << stringf("\n (property %s (string \"%d'h%s\"))", EDIF_DEF(name), GetSize(val), hex_string.c_str());
*f << stringf("\n (property %s (string \"%d'h%s\"))", EDIF_DEF(name), GetSize(val), hex_string);
}
};
for (auto module : sorted_modules)
@ -513,13 +513,13 @@ struct EdifBackend : public Backend {
if (sig.wire == NULL && sig != RTLIL::State::S0 && sig != RTLIL::State::S1) {
if (sig == RTLIL::State::Sx) {
for (auto &ref : it.second)
log_warning("Exporting x-bit on %s as zero bit.\n", ref.first.c_str());
log_warning("Exporting x-bit on %s as zero bit.\n", ref.first);
sig = RTLIL::State::S0;
} else if (sig == RTLIL::State::Sz) {
continue;
} else {
for (auto &ref : it.second)
log_error("Don't know how to handle %s on %s.\n", log_signal(sig), ref.first.c_str());
log_error("Don't know how to handle %s on %s.\n", log_signal(sig), ref.first);
log_abort();
}
}
@ -536,7 +536,7 @@ struct EdifBackend : public Backend {
}
*f << stringf(" (net %s (joined\n", EDIF_DEF(netname));
for (auto &ref : it.second)
*f << stringf(" %s\n", ref.first.c_str());
*f << stringf(" %s\n", ref.first);
if (sig.wire == NULL) {
if (nogndvcc)
log_error("Design contains constant nodes (map with \"hilomap\" first).\n");
@ -577,7 +577,7 @@ struct EdifBackend : public Backend {
auto &refs = net_join_db.at(mapped_sig);
for (auto &ref : refs)
if (ref.second)
*f << stringf(" %s\n", ref.first.c_str());
*f << stringf(" %s\n", ref.first);
*f << stringf(" )");
if (attr_properties && raw_sig.wire != NULL)

View file

@ -253,7 +253,7 @@ void emit_extmodule(RTLIL::Cell *cell, RTLIL::Module *mod_instance, std::ostream
const std::string extmoduleFileinfo = getFileinfo(cell);
// Emit extmodule header.
f << stringf(" extmodule %s: %s\n", exported_name.c_str(), extmoduleFileinfo.c_str());
f << stringf(" extmodule %s: %s\n", exported_name, extmoduleFileinfo);
// Emit extmodule ports.
for (auto wire : mod_instance->wires())
@ -280,7 +280,7 @@ void emit_extmodule(RTLIL::Cell *cell, RTLIL::Module *mod_instance, std::ostream
// Emit extmodule "defname" field. This is the name of the verilog blackbox
// that is used when verilog is emitted, so we use the name of mod_instance
// here.
f << stringf("%sdefname = %s\n", indent.c_str(), blackbox_name.c_str());
f << stringf("%sdefname = %s\n", indent, blackbox_name);
// Emit extmodule generic parameters.
for (const auto &p : cell->parameters)
@ -301,7 +301,7 @@ void emit_extmodule(RTLIL::Cell *cell, RTLIL::Module *mod_instance, std::ostream
param_name.end()
);
f << stringf("%sparameter %s = %s\n", indent.c_str(), param_name.c_str(), param_value.c_str());
f << stringf("%sparameter %s = %s\n", indent, param_name, param_value);
}
f << "\n";
@ -347,7 +347,7 @@ void emit_elaborated_extmodules(RTLIL::Design *design, std::ostream &f)
auto modInstance = design->module(cell->type);
// Ensure that we actually have a module instance
if (modInstance == nullptr) {
log_error("Unknown cell type %s\n", cell->type.c_str());
log_error("Unknown cell type %s\n", cell->type);
return;
}
@ -417,7 +417,7 @@ struct FirrtlWorker
else
{
string wire_id = make_id(chunk.wire->name);
new_expr = stringf("bits(%s, %d, %d)", wire_id.c_str(), chunk.offset + chunk.width - 1, chunk.offset);
new_expr = stringf("bits(%s, %d, %d)", wire_id, chunk.offset + chunk.width - 1, chunk.offset);
}
if (expr.empty())
@ -465,7 +465,7 @@ struct FirrtlWorker
// If there is no instance for this, just return.
if (instModule == NULL)
{
log_warning("No instance for %s.%s\n", cell_type.c_str(), cell_name.c_str());
log_warning("No instance for %s.%s\n", cell_type, cell_name);
return;
}
@ -477,7 +477,7 @@ struct FirrtlWorker
instanceOf;
std::string cellFileinfo = getFileinfo(cell);
wire_exprs.push_back(stringf("%s" "inst %s%s of %s %s", indent.c_str(), cell_name.c_str(), cell_name_comment.c_str(), instanceName.c_str(), cellFileinfo.c_str()));
wire_exprs.push_back(stringf("%s" "inst %s%s of %s %s", indent, cell_name, cell_name_comment, instanceName, cellFileinfo));
for (auto it = cell->connections().begin(); it != cell->connections().end(); ++it) {
if (it->second.size() > 0) {
@ -490,7 +490,7 @@ struct FirrtlWorker
const SigSpec *sinkSig = nullptr;
switch (dir) {
case FD_INOUT:
log_warning("Instance port connection %s.%s is INOUT; treating as OUT\n", cell_type.c_str(), log_signal(it->second));
log_warning("Instance port connection %s.%s is INOUT; treating as OUT\n", cell_type, log_signal(it->second));
YS_FALLTHROUGH
case FD_OUT:
sourceExpr = firstName;
@ -498,27 +498,27 @@ struct FirrtlWorker
sinkSig = &secondSig;
break;
case FD_NODIRECTION:
log_warning("Instance port connection %s.%s is NODIRECTION; treating as IN\n", cell_type.c_str(), log_signal(it->second));
log_warning("Instance port connection %s.%s is NODIRECTION; treating as IN\n", cell_type, log_signal(it->second));
YS_FALLTHROUGH
case FD_IN:
sourceExpr = secondExpr;
sinkExpr = firstName;
break;
default:
log_error("Instance port %s.%s unrecognized connection direction 0x%x !\n", cell_type.c_str(), log_signal(it->second), dir);
log_error("Instance port %s.%s unrecognized connection direction 0x%x !\n", cell_type, log_signal(it->second), dir);
break;
}
// Check for subfield assignment.
std::string bitsString = "bits(";
if (sinkExpr.compare(0, bitsString.length(), bitsString) == 0) {
if (sinkSig == nullptr)
log_error("Unknown subfield %s.%s\n", cell_type.c_str(), sinkExpr.c_str());
log_error("Unknown subfield %s.%s\n", cell_type, sinkExpr);
// Don't generate the assignment here.
// Add the source and sink to the "reverse_wire_map" and we'll output the assignment
// as part of the coalesced subfield assignments for this wire.
register_reverse_wire_map(sourceExpr, *sinkSig);
} else {
wire_exprs.push_back(stringf("\n%s%s <= %s %s", indent.c_str(), sinkExpr.c_str(), sourceExpr.c_str(), cellFileinfo.c_str()));
wire_exprs.push_back(stringf("\n%s%s <= %s %s", indent, sinkExpr, sourceExpr, cellFileinfo));
}
}
}
@ -535,7 +535,7 @@ struct FirrtlWorker
int max_shift_width_bits = FIRRTL_MAX_DSH_WIDTH_ERROR - 1;
string max_shift_string = stringf("UInt<%d>(%d)", max_shift_width_bits, (1<<max_shift_width_bits) - 1);
// Deal with the difference in semantics between FIRRTL and verilog
result = stringf("mux(gt(%s, %s), %s, bits(%s, %d, 0))", b_expr.c_str(), max_shift_string.c_str(), max_shift_string.c_str(), b_expr.c_str(), max_shift_width_bits - 1);
result = stringf("mux(gt(%s, %s), %s, bits(%s, %d, 0))", b_expr, max_shift_string, max_shift_string, b_expr, max_shift_width_bits - 1);
}
return result;
}
@ -543,7 +543,7 @@ struct FirrtlWorker
void emit_module()
{
std::string moduleFileinfo = getFileinfo(module);
f << stringf(" module %s: %s\n", make_id(module->name), moduleFileinfo.c_str());
f << stringf(" module %s: %s\n", make_id(module->name), moduleFileinfo);
vector<string> port_decls, wire_decls, mem_exprs, cell_exprs, wire_exprs;
std::vector<Mem> memories = Mem::get_all_memories(module);
@ -565,12 +565,12 @@ struct FirrtlWorker
{
if (wire->port_input && wire->port_output)
log_error("Module port %s.%s is inout!\n", log_id(module), log_id(wire));
port_decls.push_back(stringf("%s%s %s: UInt<%d> %s\n", indent.c_str(), wire->port_input ? "input" : "output",
port_decls.push_back(stringf("%s%s %s: UInt<%d> %s\n", indent, wire->port_input ? "input" : "output",
wireName, wire->width, wireFileinfo.c_str()));
}
else
{
wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), wireName, wire->width, wireFileinfo.c_str()));
wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent, wireName, wire->width, wireFileinfo));
}
}
@ -602,7 +602,7 @@ struct FirrtlWorker
if (cell->type.in(ID($not), ID($logic_not), ID($_NOT_), ID($neg), ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_bool), ID($reduce_xnor)))
{
string a_expr = make_expr(cell->getPort(ID::A));
wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), y_id.c_str(), y_width, cellFileinfo.c_str()));
wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent, y_id, y_width, cellFileinfo));
if (a_signed) {
a_expr = "asSInt(" + a_expr + ")";
@ -610,7 +610,7 @@ struct FirrtlWorker
// Don't use the results of logical operations (a single bit) to control padding
if (!(cell->type.in(ID($eq), ID($eqx), ID($gt), ID($ge), ID($lt), ID($le), ID($ne), ID($nex), ID($reduce_bool), ID($logic_not)) && y_width == 1) ) {
a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width);
a_expr = stringf("pad(%s, %d)", a_expr, y_width);
}
// Assume the FIRRTL width is a single bit.
@ -622,27 +622,27 @@ struct FirrtlWorker
firrtl_width = a_width;
} else if (cell->type == ID($logic_not)) {
primop = "eq";
a_expr = stringf("%s, UInt(0)", a_expr.c_str());
a_expr = stringf("%s, UInt(0)", a_expr);
}
else if (cell->type == ID($reduce_and)) primop = "andr";
else if (cell->type == ID($reduce_or)) primop = "orr";
else if (cell->type == ID($reduce_xor)) primop = "xorr";
else if (cell->type == ID($reduce_xnor)) {
primop = "not";
a_expr = stringf("xorr(%s)", a_expr.c_str());
a_expr = stringf("xorr(%s)", a_expr);
}
else if (cell->type == ID($reduce_bool)) {
primop = "neq";
// Use the sign of the a_expr and its width as the type (UInt/SInt) and width of the comparand.
a_expr = stringf("%s, %cInt<%d>(0)", a_expr.c_str(), a_signed ? 'S' : 'U', a_width);
a_expr = stringf("%s, %cInt<%d>(0)", a_expr, a_signed ? 'S' : 'U', a_width);
}
string expr = stringf("%s(%s)", primop.c_str(), a_expr.c_str());
string expr = stringf("%s(%s)", primop, a_expr);
if ((firrtl_is_signed && !always_uint))
expr = stringf("asUInt(%s)", expr.c_str());
expr = stringf("asUInt(%s)", expr);
cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent, y_id, expr, cellFileinfo));
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
@ -654,13 +654,13 @@ struct FirrtlWorker
string a_expr = make_expr(cell->getPort(ID::A));
string b_expr = make_expr(cell->getPort(ID::B));
std::string cellFileinfo = getFileinfo(cell);
wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), y_id.c_str(), y_width, cellFileinfo.c_str()));
wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent, y_id, y_width, cellFileinfo));
if (a_signed) {
a_expr = "asSInt(" + a_expr + ")";
// Expand the "A" operand to the result width
if (a_width < y_width) {
a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width);
a_expr = stringf("pad(%s, %d)", a_expr, y_width);
a_width = y_width;
}
}
@ -670,7 +670,7 @@ struct FirrtlWorker
b_expr = "asSInt(" + b_expr + ")";
// Expand the "B" operand to the result width
if (b_width < y_width) {
b_expr = stringf("pad(%s, %d)", b_expr.c_str(), y_width);
b_expr = stringf("pad(%s, %d)", b_expr, y_width);
b_width = y_width;
}
}
@ -680,11 +680,11 @@ struct FirrtlWorker
if (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($xor), ID($_XOR_), ID($xnor), ID($and), ID($_AND_), ID($or), ID($_OR_)))
{
if (a_width < y_width) {
a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width);
a_expr = stringf("pad(%s, %d)", a_expr, y_width);
a_width = y_width;
}
if (b_width < y_width) {
b_expr = stringf("pad(%s, %d)", b_expr.c_str(), y_width);
b_expr = stringf("pad(%s, %d)", b_expr, y_width);
b_width = y_width;
}
}
@ -856,23 +856,23 @@ struct FirrtlWorker
string expr;
// Deal with $xnor == ~^ (not xor)
if (primop == "xnor") {
expr = stringf("not(xor(%s, %s))", a_expr.c_str(), b_expr.c_str());
expr = stringf("not(xor(%s, %s))", a_expr, b_expr);
} else {
expr = stringf("%s(%s, %s)", primop.c_str(), a_expr.c_str(), b_expr.c_str());
expr = stringf("%s(%s, %s)", primop, a_expr, b_expr);
}
// Deal with FIRRTL's "shift widens" semantics, or the need to widen the FIRRTL result.
// If the operation is signed, the FIRRTL width will be 1 one bit larger.
if (extract_y_bits) {
expr = stringf("bits(%s, %d, 0)", expr.c_str(), y_width - 1);
expr = stringf("bits(%s, %d, 0)", expr, y_width - 1);
} else if (firrtl_is_signed && (firrtl_width + 1) < y_width) {
expr = stringf("pad(%s, %d)", expr.c_str(), y_width);
expr = stringf("pad(%s, %d)", expr, y_width);
}
if ((firrtl_is_signed && !always_uint))
expr = stringf("asUInt(%s)", expr.c_str());
expr = stringf("asUInt(%s)", expr);
cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent, y_id, expr, cellFileinfo));
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
@ -885,11 +885,11 @@ struct FirrtlWorker
string a_expr = make_expr(cell->getPort(ID::A));
string b_expr = make_expr(cell->getPort(ID::B));
string s_expr = make_expr(cell->getPort(ID::S));
wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), y_id.c_str(), width, cellFileinfo.c_str()));
wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent, y_id, width, cellFileinfo));
string expr = stringf("mux(%s, %s, %s)", s_expr.c_str(), b_expr.c_str(), a_expr.c_str());
string expr = stringf("mux(%s, %s, %s)", s_expr, b_expr, a_expr);
cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent, y_id, expr, cellFileinfo));
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
@ -911,9 +911,9 @@ struct FirrtlWorker
string expr = make_expr(cell->getPort(ID::D));
string clk_expr = "asClock(" + make_expr(cell->getPort(ID::CLK)) + ")";
wire_decls.push_back(stringf("%sreg %s: UInt<%d>, %s %s\n", indent.c_str(), y_id.c_str(), width, clk_expr.c_str(), cellFileinfo.c_str()));
wire_decls.push_back(stringf("%sreg %s: UInt<%d>, %s %s\n", indent, y_id, width, clk_expr, cellFileinfo));
cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent, y_id, expr, cellFileinfo));
register_reverse_wire_map(y_id, cell->getPort(ID::Q));
continue;
@ -926,7 +926,7 @@ struct FirrtlWorker
string a_expr = make_expr(cell->getPort(ID::A));
// Get the initial bit selector
string b_expr = make_expr(cell->getPort(ID::B));
wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width));
wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent, y_id, y_width));
if (cell->getParam(ID::B_SIGNED).as_bool()) {
// Use validif to constrain the selection (test the sign bit)
@ -934,9 +934,9 @@ struct FirrtlWorker
int b_sign = cell->parameters.at(ID::B_WIDTH).as_int() - 1;
b_expr = stringf("validif(not(bits(%s, %d, %d)), %s)", b_string, b_sign, b_sign, b_string);
}
string expr = stringf("dshr(%s, %s)", a_expr.c_str(), b_expr.c_str());
string expr = stringf("dshr(%s, %s)", a_expr, b_expr);
cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), expr.c_str()));
cell_exprs.push_back(stringf("%s%s <= %s\n", indent, y_id, expr));
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
}
@ -948,21 +948,21 @@ struct FirrtlWorker
string b_expr = make_expr(cell->getPort(ID::B));
auto b_string = b_expr.c_str();
string expr;
wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width));
wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent, y_id, y_width));
if (cell->getParam(ID::B_SIGNED).as_bool()) {
// We generate a left or right shift based on the sign of b.
std::string dshl = stringf("bits(dshl(%s, %s), 0, %d)", a_expr.c_str(), gen_dshl(b_expr, b_width).c_str(), y_width);
std::string dshr = stringf("dshr(%s, %s)", a_expr.c_str(), b_string);
std::string dshl = stringf("bits(dshl(%s, %s), 0, %d)", a_expr, gen_dshl(b_expr, b_width), y_width);
std::string dshr = stringf("dshr(%s, %s)", a_expr, b_string);
expr = stringf("mux(%s < 0, %s, %s)",
b_string,
dshl.c_str(),
dshr.c_str()
);
} else {
expr = stringf("dshr(%s, %s)", a_expr.c_str(), b_string);
expr = stringf("dshr(%s, %s)", a_expr, b_string);
}
cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), expr.c_str()));
cell_exprs.push_back(stringf("%s%s <= %s\n", indent, y_id, expr));
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
}
@ -973,10 +973,10 @@ struct FirrtlWorker
// Verilog appears to treat the result as signed, so if the result is wider than "A",
// we need to pad.
if (a_width < y_width) {
a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width);
a_expr = stringf("pad(%s, %d)", a_expr, y_width);
}
wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width));
cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), a_expr.c_str()));
wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent, y_id, y_width));
cell_exprs.push_back(stringf("%s%s <= %s\n", indent, y_id, a_expr));
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
}
@ -999,7 +999,7 @@ struct FirrtlWorker
for (int i = 0; i < GetSize(mem.rd_ports); i++)
{
auto &port = mem.rd_ports[i];
string port_name(stringf("%s.r%d", mem_id.c_str(), i));
string port_name(stringf("%s.r%d", mem_id, i));
if (port.clk_enable)
log_error("Clocked read port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid));
@ -1010,17 +1010,17 @@ struct FirrtlWorker
string ena_expr = make_expr(State::S1);
string clk_expr = make_expr(State::S0);
rpe << stringf("%s%s.addr <= %s\n", indent.c_str(), port_name.c_str(), addr_expr.c_str());
rpe << stringf("%s%s.en <= %s\n", indent.c_str(), port_name.c_str(), ena_expr.c_str());
rpe << stringf("%s%s.clk <= asClock(%s)\n", indent.c_str(), port_name.c_str(), clk_expr.c_str());
rpe << stringf("%s%s.addr <= %s\n", indent, port_name, addr_expr);
rpe << stringf("%s%s.en <= %s\n", indent, port_name, ena_expr);
rpe << stringf("%s%s.clk <= asClock(%s)\n", indent, port_name, clk_expr);
cell_exprs.push_back(rpe.str());
register_reverse_wire_map(stringf("%s.data", port_name.c_str()), port.data);
register_reverse_wire_map(stringf("%s.data", port_name), port.data);
}
for (int i = 0; i < GetSize(mem.wr_ports); i++)
{
auto &port = mem.wr_ports[i];
string port_name(stringf("%s.w%d", mem_id.c_str(), i));
string port_name(stringf("%s.w%d", mem_id, i));
if (!port.clk_enable)
log_error("Unclocked write port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid));
@ -1037,18 +1037,18 @@ struct FirrtlWorker
string ena_expr = make_expr(port.en[0]);
string clk_expr = make_expr(port.clk);
string mask_expr = make_expr(State::S1);
wpe << stringf("%s%s.data <= %s\n", indent.c_str(), port_name.c_str(), data_expr.c_str());
wpe << stringf("%s%s.addr <= %s\n", indent.c_str(), port_name.c_str(), addr_expr.c_str());
wpe << stringf("%s%s.en <= %s\n", indent.c_str(), port_name.c_str(), ena_expr.c_str());
wpe << stringf("%s%s.clk <= asClock(%s)\n", indent.c_str(), port_name.c_str(), clk_expr.c_str());
wpe << stringf("%s%s.mask <= %s\n", indent.c_str(), port_name.c_str(), mask_expr.c_str());
wpe << stringf("%s%s.data <= %s\n", indent, port_name, data_expr);
wpe << stringf("%s%s.addr <= %s\n", indent, port_name, addr_expr);
wpe << stringf("%s%s.en <= %s\n", indent, port_name, ena_expr);
wpe << stringf("%s%s.clk <= asClock(%s)\n", indent, port_name, clk_expr);
wpe << stringf("%s%s.mask <= %s\n", indent, port_name, mask_expr);
cell_exprs.push_back(wpe.str());
}
std::ostringstream me;
me << stringf(" mem %s:\n", mem_id.c_str());
me << stringf(" mem %s:\n", mem_id);
me << stringf(" data-type => UInt<%d>\n", mem.width);
me << stringf(" depth => %d\n", mem.size);
for (int i = 0; i < GetSize(mem.rd_ports); i++)
@ -1068,8 +1068,8 @@ struct FirrtlWorker
int y_width = GetSize(conn.first);
string expr = make_expr(conn.second);
wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width));
cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), expr.c_str()));
wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent, y_id, y_width));
cell_exprs.push_back(stringf("%s%s <= %s\n", indent, y_id, expr));
register_reverse_wire_map(y_id, conn.first);
}
@ -1112,7 +1112,7 @@ struct FirrtlWorker
chunk_width++;
}
new_expr = stringf("bits(%s, %d, %d)", start_map.first.c_str(),
new_expr = stringf("bits(%s, %d, %d)", start_map.first,
start_map.second + chunk_width - 1, start_map.second);
is_valid = true;
}
@ -1135,13 +1135,13 @@ struct FirrtlWorker
if (is_valid) {
if (make_unconn_id) {
wire_decls.push_back(stringf("%swire %s: UInt<1> %s\n", indent.c_str(), unconn_id.c_str(), wireFileinfo.c_str()));
wire_decls.push_back(stringf("%swire %s: UInt<1> %s\n", indent, unconn_id, wireFileinfo));
// `invalid` is a firrtl construction for simulation so we will not
// tag it with a @[fileinfo] tag as it doesn't directly correspond to
// a specific line of verilog code.
wire_decls.push_back(stringf("%s%s is invalid\n", indent.c_str(), unconn_id.c_str()));
wire_decls.push_back(stringf("%s%s is invalid\n", indent, unconn_id));
}
wire_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), make_id(wire->name), expr.c_str(), wireFileinfo.c_str()));
wire_exprs.push_back(stringf("%s%s <= %s %s\n", indent, make_id(wire->name), expr, wireFileinfo));
} else {
if (make_unconn_id) {
unconn_id.clear();
@ -1149,7 +1149,7 @@ struct FirrtlWorker
// `invalid` is a firrtl construction for simulation so we will not
// tag it with a @[fileinfo] tag as it doesn't directly correspond to
// a specific line of verilog code.
wire_decls.push_back(stringf("%s%s is invalid\n", indent.c_str(), make_id(wire->name)));
wire_decls.push_back(stringf("%s%s is invalid\n", indent, make_id(wire->name)));
}
}
@ -1223,6 +1223,7 @@ struct FirrtlBackend : public Backend {
Pass::call(design, "demuxmap");
Pass::call(design, "bwmuxmap");
used_names.clear();
namecache.clear();
autoid_counter = 0;
@ -1248,7 +1249,7 @@ struct FirrtlBackend : public Backend {
log_cmd_error("There is no top module in this design!\n");
std::string circuitFileinfo = getFileinfo(top);
*f << stringf("circuit %s: %s\n", make_id(top->name), circuitFileinfo.c_str());
*f << stringf("circuit %s: %s\n", make_id(top->name), circuitFileinfo);
emit_elaborated_extmodules(design, *f);
@ -1262,6 +1263,7 @@ struct FirrtlBackend : public Backend {
}
}
used_names.clear();
namecache.clear();
autoid_counter = 0;
}

View file

@ -268,7 +268,7 @@ struct FunctionalCxxBackend : public Backend
extra_args(f, filename, args, argidx, design);
for (auto module : design->selected_modules()) {
log("Dumping module `%s'.\n", module->name.c_str());
log("Dumping module `%s'.\n", module->name);
printCxx(*f, filename, module);
}
}

View file

@ -285,7 +285,7 @@ struct FunctionalSmtBackend : public Backend {
extra_args(f, filename, args, argidx, design);
for (auto module : design->selected_modules()) {
log("Processing module `%s`.\n", module->name.c_str());
log("Processing module `%s`.\n", module->name);
SmtModule smt(module);
smt.write(*f);
}

View file

@ -19,8 +19,8 @@
*/
#include "kernel/functional.h"
#include "kernel/yosys.h"
#include "kernel/sexpr.h"
#include "kernel/yosys.h"
#include <ctype.h>
USING_YOSYS_NAMESPACE
@ -29,26 +29,24 @@ PRIVATE_NAMESPACE_BEGIN
using SExprUtil::list;
const char *reserved_keywords[] = {
// reserved keywords from the racket spec
"struct", "lambda", "values", "extract", "concat", "bv", "let", "define", "cons", "list", "read", "write",
"stream", "error", "raise", "exit", "for", "begin", "when", "unless", "module", "require", "provide", "apply",
"if", "cond", "even", "odd", "any", "and", "or", "match", "command-line", "ffi-lib", "thread", "kill", "sync",
"future", "touch", "subprocess", "make-custodian", "custodian-shutdown-all", "current-custodian", "make", "tcp",
"connect", "prepare", "malloc", "free", "_fun", "_cprocedure", "build", "path", "file", "peek", "bytes",
"flush", "with", "lexer", "parser", "syntax", "interface", "send", "make-object", "new", "instantiate",
"define-generics", "set",
// reserved keywords from the racket spec
"struct", "lambda", "values", "extract", "concat", "bv", "let", "define", "cons", "list", "read", "write", "stream", "error", "raise", "exit",
"for", "begin", "when", "unless", "module", "require", "provide", "apply", "if", "cond", "even", "odd", "any", "and", "or", "match", "command-line",
"ffi-lib", "thread", "kill", "sync", "future", "touch", "subprocess", "make-custodian", "custodian-shutdown-all", "current-custodian", "make",
"tcp", "connect", "prepare", "malloc", "free", "_fun", "_cprocedure", "build", "path", "file", "peek", "bytes", "flush", "with", "lexer", "parser",
"syntax", "interface", "send", "make-object", "new", "instantiate", "define-generics", "set",
// reserved for our own purposes
"inputs", "state", "name",
nullptr
};
// reserved for our own purposes
"inputs", "state", "name", nullptr};
struct SmtrScope : public Functional::Scope<int> {
SmtrScope() {
for(const char **p = reserved_keywords; *p != nullptr; p++)
SmtrScope()
{
for (const char **p = reserved_keywords; *p != nullptr; p++)
reserve(*p);
}
bool is_character_legal(char c, int index) override {
bool is_character_legal(char c, int index) override
{
return isascii(c) && (isalpha(c) || (isdigit(c) && index > 0) || strchr("@$%^&_+=.", c));
}
};
@ -56,10 +54,11 @@ struct SmtrScope : public Functional::Scope<int> {
struct SmtrSort {
Functional::Sort sort;
SmtrSort(Functional::Sort sort) : sort(sort) {}
SExpr to_sexpr() const {
if(sort.is_memory()) {
SExpr to_sexpr() const
{
if (sort.is_memory()) {
return list("list", list("bitvector", sort.addr_width()), list("bitvector", sort.data_width()));
} else if(sort.is_signal()) {
} else if (sort.is_signal()) {
return list("bitvector", sort.width());
} else {
log_error("unknown sort");
@ -67,7 +66,8 @@ struct SmtrSort {
}
};
class SmtrStruct {
class SmtrStruct
{
struct Field {
SmtrSort sort;
std::string accessor;
@ -77,19 +77,22 @@ class SmtrStruct {
vector<Field> fields;
SmtrScope &global_scope;
SmtrScope local_scope;
public:
public:
std::string name;
SmtrStruct(std::string name, SmtrScope &scope) : global_scope(scope), local_scope(), name(name) {}
void insert(IdString field_name, SmtrSort sort) {
void insert(IdString field_name, SmtrSort sort)
{
field_names(field_name);
auto base_name = local_scope.unique_name(field_name);
auto accessor = name + "-" + base_name;
global_scope.reserve(accessor);
fields.emplace_back(Field{sort, accessor, base_name});
}
void write_definition(SExprWriter &w) {
void write_definition(SExprWriter &w)
{
vector<SExpr> field_list;
for(const auto &field : fields) {
for (const auto &field : fields) {
field_list.emplace_back(field.name);
}
w.push();
@ -102,23 +105,26 @@ public:
}
w.pop();
}
template<typename Fn> void write_value(SExprWriter &w, Fn fn) {
template <typename Fn> void write_value(SExprWriter &w, Fn fn)
{
w.open(list(name));
for(auto field_name : field_names) {
for (auto field_name : field_names) {
w << fn(field_name);
w.comment(RTLIL::unescape_id(field_name), true);
}
w.close();
}
SExpr access(SExpr record, IdString name) {
SExpr access(SExpr record, IdString name)
{
size_t i = field_names.at(name);
return list(fields[i].accessor, std::move(record));
}
};
std::string smt_const(RTLIL::Const const &c) {
std::string smt_const(RTLIL::Const const &c)
{
std::string s = "#b";
for(int i = c.size(); i-- > 0; )
for (int i = c.size(); i-- > 0;)
s += c[i] == State::S1 ? '1' : '0';
return s;
}
@ -131,15 +137,9 @@ struct SmtrPrintVisitor : public Functional::AbstractVisitor<SExpr> {
SmtrPrintVisitor(SmtrStruct &input_struct, SmtrStruct &state_struct) : input_struct(input_struct), state_struct(state_struct) {}
SExpr from_bool(SExpr &&arg) {
return list("bool->bitvector", std::move(arg));
}
SExpr to_bool(SExpr &&arg) {
return list("bitvector->bool", std::move(arg));
}
SExpr to_list(SExpr &&arg) {
return list("bitvector->bits", std::move(arg));
}
SExpr from_bool(SExpr &&arg) { return list("bool->bitvector", std::move(arg)); }
SExpr to_bool(SExpr &&arg) { return list("bitvector->bool", std::move(arg)); }
SExpr to_list(SExpr &&arg) { return list("bitvector->bits", std::move(arg)); }
SExpr buf(Node, Node a) override { return n(a); }
SExpr slice(Node, Node a, int offset, int out_width) override { return list("extract", offset + out_width - 1, offset, n(a)); }
@ -166,8 +166,9 @@ struct SmtrPrintVisitor : public Functional::AbstractVisitor<SExpr> {
SExpr unsigned_greater_than(Node, Node a, Node b) override { return from_bool(list("bvugt", n(a), n(b))); }
SExpr unsigned_greater_equal(Node, Node a, Node b) override { return from_bool(list("bvuge", n(a), n(b))); }
SExpr extend(SExpr &&a, int in_width, int out_width) {
if(in_width < out_width)
SExpr extend(SExpr &&a, int in_width, int out_width)
{
if (in_width < out_width)
return list("zero-extend", std::move(a), list("bitvector", out_width));
else
return std::move(a);
@ -176,12 +177,20 @@ struct SmtrPrintVisitor : public Functional::AbstractVisitor<SExpr> {
SExpr logical_shift_right(Node, Node a, Node b) override { return list("bvlshr", n(a), extend(n(b), b.width(), a.width())); }
SExpr arithmetic_shift_right(Node, Node a, Node b) override { return list("bvashr", n(a), extend(n(b), b.width(), a.width())); }
SExpr mux(Node, Node a, Node b, Node s) override { return list("if", to_bool(n(s)), n(b), n(a)); }
SExpr constant(Node, RTLIL::Const const& value) override { return list("bv", smt_const(value), value.size()); }
SExpr constant(Node, RTLIL::Const const &value) override { return list("bv", smt_const(value), value.size()); }
SExpr memory_read(Node, Node mem, Node addr) override { return list("list-ref-bv", n(mem), n(addr)); }
SExpr memory_write(Node, Node mem, Node addr, Node data) override { return list("list-set-bv", n(mem), n(addr), n(data)); }
SExpr input(Node, IdString name, IdString kind) override { log_assert(kind == ID($input)); return input_struct.access("inputs", name); }
SExpr state(Node, IdString name, IdString kind) override { log_assert(kind == ID($state)); return state_struct.access("state", name); }
SExpr input(Node, IdString name, IdString kind) override
{
log_assert(kind == ID($input));
return input_struct.access("inputs", name);
}
SExpr state(Node, IdString name, IdString kind) override
{
log_assert(kind == ID($state));
return state_struct.access("state", name);
}
};
struct SmtrModule {
@ -196,12 +205,10 @@ struct SmtrModule {
SmtrStruct state_struct;
SmtrModule(Module *module, bool assoc_list_helpers)
: ir(Functional::IR::from_module(module))
, scope()
, name(scope.unique_name(module->name))
, input_struct(scope.unique_name(module->name.str() + "_Inputs"), scope)
, output_struct(scope.unique_name(module->name.str() + "_Outputs"), scope)
, state_struct(scope.unique_name(module->name.str() + "_State"), scope)
: ir(Functional::IR::from_module(module)), scope(), name(scope.unique_name(module->name)),
input_struct(scope.unique_name(module->name.str() + "_Inputs"), scope),
output_struct(scope.unique_name(module->name.str() + "_Outputs"), scope),
state_struct(scope.unique_name(module->name.str() + "_State"), scope)
{
scope.reserve(name + "_initial");
if (assoc_list_helpers) {
@ -222,19 +229,17 @@ struct SmtrModule {
{
w.push();
w.open(list("define", list(name, "inputs", "state")));
auto inlined = [&](Functional::Node n) {
return n.fn() == Functional::Fn::constant;
};
auto inlined = [&](Functional::Node n) { return n.fn() == Functional::Fn::constant; };
SmtrPrintVisitor visitor(input_struct, state_struct);
auto node_to_sexpr = [&](Functional::Node n) -> SExpr {
if(inlined(n))
if (inlined(n))
return n.visit(visitor);
else
return scope(n.id(), n.name());
};
visitor.n = node_to_sexpr;
for(auto n : ir)
if(!inlined(n)) {
for (auto n : ir)
if (!inlined(n)) {
w.open(list("let", list(list(node_to_sexpr(n), n.visit(visitor)))), false);
w.comment(SmtrSort(n.sort()).to_sexpr().to_string(), true);
}
@ -256,7 +261,7 @@ struct SmtrModule {
else if (state->sort.is_memory()) {
const auto &contents = state->initial_value_memory();
w.open(list("list"));
for(int i = 0; i < 1<<state->sort.addr_width(); i++) {
for (int i = 0; i < 1 << state->sort.addr_width(); i++) {
w << list("bv", smt_const(contents[i]), state->sort.data_width());
}
w.close();
@ -303,7 +308,7 @@ struct SmtrModule {
}
void write(std::ostream &out)
{
{
SExprWriter w(out);
input_struct.write_definition(w);
@ -324,8 +329,9 @@ struct SmtrModule {
struct FunctionalSmtrBackend : public Backend {
FunctionalSmtrBackend() : Backend("functional_rosette", "Generate Rosette compatible Racket from Functional IR") {}
void help() override {
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
void help() override
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" write_functional_rosette [options] [filename]\n");
log("\n");
@ -347,8 +353,7 @@ struct FunctionalSmtrBackend : public Backend {
log_header(design, "Executing Functional Rosette Backend.\n");
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
{
for (argidx = 1; argidx < args.size(); argidx++) {
if (args[argidx] == "-provides")
provides = true;
else if (args[argidx] == "-assoc-list-helpers")

View file

@ -105,7 +105,7 @@ struct MemContentsTest {
RTLIL::Const values;
for(addr_t addr = low; addr <= high; addr++) {
RTLIL::Const word(data_dist(rnd), data_width);
values.bits().insert(values.bits().end(), word.begin(), word.end());
values.append(word);
}
insert_concatenated(low, values);
}
@ -116,7 +116,9 @@ struct MemContentsTest {
struct FunctionalTestGeneric : public Pass
{
FunctionalTestGeneric() : Pass("test_generic", "test the generic compute graph") {}
FunctionalTestGeneric() : Pass("test_generic", "test the generic compute graph") {
internal();
}
void help() override
{
@ -141,7 +143,7 @@ struct FunctionalTestGeneric : public Pass
*/
for (auto module : design->selected_modules()) {
log("Dumping module `%s'.\n", module->name.c_str());
log("Dumping module `%s'.\n", module->name);
auto fir = Functional::IR::from_module(module);
for(auto node : fir)
std::cout << RTLIL::unescape_id(node.name()) << " = " << node.to_string([](auto n) { return RTLIL::unescape_id(n.name()); }) << "\n";

View file

@ -100,13 +100,13 @@ struct IntersynthBackend : public Backend {
}
extra_args(f, filename, args, argidx);
log("Output filename: %s\n", filename.c_str());
log("Output filename: %s\n", filename);
for (auto filename : libfiles) {
std::ifstream f;
f.open(filename.c_str());
if (f.fail())
log_error("Can't open lib file `%s'.\n", filename.c_str());
log_error("Can't open lib file `%s'.\n", filename);
RTLIL::Design *lib = new RTLIL::Design;
Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "rtlil" : "verilog"));
libs.push_back(lib);
@ -172,7 +172,7 @@ struct IntersynthBackend : public Backend {
if (sig.size() != 0) {
conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.size(), sig.size(), sig.size()));
celltype_code += stringf(" b%d %s%s", sig.size(), ct.cell_output(cell->type, port.first) ? "*" : "", log_id(port.first));
node_code += stringf(" %s %s", log_id(port.first), netname(conntypes_code, celltypes_code, constcells_code, sig).c_str());
node_code += stringf(" %s %s", log_id(port.first), netname(conntypes_code, celltypes_code, constcells_code, sig));
}
}
for (auto &param : cell->parameters) {
@ -199,13 +199,13 @@ struct IntersynthBackend : public Backend {
if (!flag_notypes) {
*f << stringf("### Connection Types\n");
for (auto code : conntypes_code)
*f << stringf("%s", code.c_str());
*f << stringf("%s", code);
*f << stringf("\n### Cell Types\n");
for (auto code : celltypes_code)
*f << stringf("%s", code.c_str());
*f << stringf("%s", code);
}
*f << stringf("\n### Netlists\n");
*f << stringf("%s", netlists_code.c_str());
*f << stringf("%s", netlists_code);
for (auto lib : libs)
delete lib;

View file

@ -125,7 +125,7 @@ struct JnyWriter
f << "{\n";
f << " \"$schema\": \"https://raw.githubusercontent.com/YosysHQ/yosys/main/misc/jny.schema.json\",\n";
f << stringf(" \"generator\": \"%s\",\n", escape_string(yosys_maybe_version()).c_str());
f << stringf(" \"generator\": \"%s\",\n", escape_string(yosys_maybe_version()));
f << " \"version\": \"0.0.1\",\n";
f << " \"invocation\": \"" << escape_string(invk) << "\",\n";
f << " \"features\": [";
@ -232,7 +232,7 @@ struct JnyWriter
const auto _indent = gen_indent(indent_level);
f << _indent << "{\n";
f << stringf(" %s\"name\": \"%s\",\n", _indent.c_str(), escape_string(RTLIL::unescape_id(mod->name)).c_str());
f << stringf(" %s\"name\": \"%s\",\n", _indent, escape_string(RTLIL::unescape_id(mod->name)));
f << _indent << " \"cell_sorts\": [\n";
bool first_sort{true};
@ -280,7 +280,7 @@ struct JnyWriter
f << ",\n";
f << _indent << " {\n";
f << stringf(" %s\"name\": \"%s\",\n", _indent.c_str(), escape_string(RTLIL::unescape_id(con.first)).c_str());
f << stringf(" %s\"name\": \"%s\",\n", _indent, escape_string(RTLIL::unescape_id(con.first)));
f << _indent << " \"direction\": \"";
if (port_cell->input(con.first))
f << "i";
@ -290,7 +290,7 @@ struct JnyWriter
if (con.second.size() == 1)
f << _indent << " \"range\": [0, 0]\n";
else
f << stringf(" %s\"range\": [%d, %d]\n", _indent.c_str(), con.second.size(), 0);
f << stringf(" %s\"range\": [%d, %d]\n", _indent, con.second.size(), 0);
f << _indent << " }";
first_port = false;
@ -304,7 +304,7 @@ struct JnyWriter
const auto _indent = gen_indent(indent_level);
f << _indent << "{\n";
f << stringf(" %s\"type\": \"%s\",\n", _indent.c_str(), sort.first.c_str());
f << stringf(" %s\"type\": \"%s\",\n", _indent, sort.first);
f << _indent << " \"ports\": [\n";
write_cell_ports(port_cell, indent_level + 2);
@ -351,10 +351,10 @@ struct JnyWriter
f << stringf(",\n");
const auto param_val = param.second;
if (!param_val.empty()) {
f << stringf(" %s\"%s\": ", _indent.c_str(), escape_string(RTLIL::unescape_id(param.first)).c_str());
f << stringf(" %s\"%s\": ", _indent, escape_string(RTLIL::unescape_id(param.first)));
write_param_val(param_val);
} else {
f << stringf(" %s\"%s\": true", _indent.c_str(), escape_string(RTLIL::unescape_id(param.first)).c_str());
f << stringf(" %s\"%s\": true", _indent, escape_string(RTLIL::unescape_id(param.first)));
}
first_param = false;
@ -366,7 +366,7 @@ struct JnyWriter
log_assert(cell != nullptr);
f << _indent << " {\n";
f << stringf(" %s\"name\": \"%s\"", _indent.c_str(), escape_string(RTLIL::unescape_id(cell->name)).c_str());
f << stringf(" %s\"name\": \"%s\"", _indent, escape_string(RTLIL::unescape_id(cell->name)));
if (_include_connections) {
f << ",\n" << _indent << " \"connections\": [\n";
@ -553,7 +553,7 @@ struct JnyPass : public Pass {
ff->open(filename.c_str(), std::ofstream::trunc);
if (ff->fail()) {
delete ff;
log_error("Can't open file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
log_error("Can't open file `%s' for writing: %s\n", filename, strerror(errno));
}
f = ff;
invk << filename;
@ -568,7 +568,7 @@ struct JnyPass : public Pass {
if (!empty) {
delete f;
} else {
log("%s", buf.str().c_str());
log("%s", buf.str());
}
}

View file

@ -135,7 +135,7 @@ struct JsonWriter
bool first = true;
for (auto &param : parameters) {
f << stringf("%s\n", first ? "" : ",");
f << stringf(" %s%s: ", for_module ? "" : " ", get_name(param.first).c_str());
f << stringf(" %s%s: ", for_module ? "" : " ", get_name(param.first));
write_parameter_value(param.second);
first = false;
}
@ -155,7 +155,7 @@ struct JsonWriter
log_error("Module %s contains processes, which are not supported by JSON backend (run `proc` first).\n", log_id(module));
}
f << stringf(" %s: {\n", get_name(module->name).c_str());
f << stringf(" %s: {\n", get_name(module->name));
f << stringf(" \"attributes\": {");
write_parameters(module->attributes, /*for_module=*/true);
@ -174,7 +174,7 @@ struct JsonWriter
if (use_selection && !module->selected(w))
continue;
f << stringf("%s\n", first ? "" : ",");
f << stringf(" %s: {\n", get_name(n).c_str());
f << stringf(" %s: {\n", get_name(n));
f << stringf(" \"direction\": \"%s\",\n", w->port_input ? w->port_output ? "inout" : "input" : "output");
if (w->start_offset)
f << stringf(" \"offset\": %d,\n", w->start_offset);
@ -182,7 +182,7 @@ struct JsonWriter
f << stringf(" \"upto\": 1,\n");
if (w->is_signed)
f << stringf(" \"signed\": %d,\n", w->is_signed);
f << stringf(" \"bits\": %s\n", get_bits(w).c_str());
f << stringf(" \"bits\": %s\n", get_bits(w));
f << stringf(" }");
first = false;
}
@ -196,13 +196,13 @@ struct JsonWriter
if (!scopeinfo_mode && c->type == ID($scopeinfo))
continue;
f << stringf("%s\n", first ? "" : ",");
f << stringf(" %s: {\n", get_name(c->name).c_str());
f << stringf(" %s: {\n", get_name(c->name));
f << stringf(" \"hide_name\": %s,\n", c->name[0] == '$' ? "1" : "0");
f << stringf(" \"type\": %s,\n", get_name(c->type).c_str());
f << stringf(" \"type\": %s,\n", get_name(c->type));
if (aig_mode) {
Aig aig(c);
if (!aig.name.empty()) {
f << stringf(" \"model\": \"%s\",\n", aig.name.c_str());
f << stringf(" \"model\": \"%s\",\n", aig.name);
aig_models.insert(aig);
}
}
@ -220,7 +220,7 @@ struct JsonWriter
if (c->input(conn.first))
direction = c->output(conn.first) ? "inout" : "input";
f << stringf("%s\n", first2 ? "" : ",");
f << stringf(" %s: \"%s\"", get_name(conn.first).c_str(), direction.c_str());
f << stringf(" %s: \"%s\"", get_name(conn.first), direction);
first2 = false;
}
f << stringf("\n },\n");
@ -229,7 +229,7 @@ struct JsonWriter
bool first2 = true;
for (auto &conn : c->connections()) {
f << stringf("%s\n", first2 ? "" : ",");
f << stringf(" %s: %s", get_name(conn.first).c_str(), get_bits(conn.second).c_str());
f << stringf(" %s: %s", get_name(conn.first), get_bits(conn.second));
first2 = false;
}
f << stringf("\n }\n");
@ -245,7 +245,7 @@ struct JsonWriter
if (use_selection && !module->selected(it.second))
continue;
f << stringf("%s\n", first ? "" : ",");
f << stringf(" %s: {\n", get_name(it.second->name).c_str());
f << stringf(" %s: {\n", get_name(it.second->name));
f << stringf(" \"hide_name\": %s,\n", it.second->name[0] == '$' ? "1" : "0");
f << stringf(" \"attributes\": {");
write_parameters(it.second->attributes);
@ -265,9 +265,9 @@ struct JsonWriter
if (use_selection && !module->selected(w))
continue;
f << stringf("%s\n", first ? "" : ",");
f << stringf(" %s: {\n", get_name(w->name).c_str());
f << stringf(" %s: {\n", get_name(w->name));
f << stringf(" \"hide_name\": %s,\n", w->name[0] == '$' ? "1" : "0");
f << stringf(" \"bits\": %s,\n", get_bits(w).c_str());
f << stringf(" \"bits\": %s,\n", get_bits(w));
if (w->start_offset)
f << stringf(" \"offset\": %d,\n", w->start_offset);
if (w->upto)
@ -291,7 +291,7 @@ struct JsonWriter
design->sort();
f << stringf("{\n");
f << stringf(" \"creator\": %s,\n", get_string(yosys_maybe_version()).c_str());
f << stringf(" \"creator\": %s,\n", get_string(yosys_maybe_version()));
f << stringf(" \"modules\": {\n");
vector<Module*> modules = use_selection ? design->selected_modules() : design->modules();
bool first_module = true;
@ -308,7 +308,7 @@ struct JsonWriter
for (auto &aig : aig_models) {
if (!first_model)
f << stringf(",\n");
f << stringf(" \"%s\": [\n", aig.name.c_str());
f << stringf(" \"%s\": [\n", aig.name);
int node_idx = 0;
for (auto &node : aig.nodes) {
if (node_idx != 0)
@ -701,7 +701,7 @@ struct JsonPass : public Pass {
ff->open(filename.c_str(), std::ofstream::trunc);
if (ff->fail()) {
delete ff;
log_error("Can't open file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
log_error("Can't open file `%s' for writing: %s\n", filename, strerror(errno));
}
f = ff;
} else {
@ -714,7 +714,7 @@ struct JsonPass : public Pass {
if (!empty) {
delete f;
} else {
log("%s", buf.str().c_str());
log("%s", buf.str());
}
}
} JsonPass;

View file

@ -24,12 +24,23 @@
#include "rtlil_backend.h"
#include "kernel/yosys.h"
#include "kernel/utils.h"
#include <errno.h>
#include <iterator>
USING_YOSYS_NAMESPACE
using namespace RTLIL_BACKEND;
YOSYS_NAMESPACE_BEGIN
void RTLIL_BACKEND::dump_attributes(std::ostream &f, std::string indent, const RTLIL::AttrObject *obj)
{
for (const auto& [name, value] : reversed(obj->attributes)) {
f << stringf("%s" "attribute %s ", indent, name);
dump_const(f, value);
f << stringf("\n");
}
}
void RTLIL_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int width, int offset, bool autoint)
{
if (width < 0)
@ -50,7 +61,9 @@ void RTLIL_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int wi
return;
}
}
f << stringf("%d'", width);
if ((data.flags & RTLIL::CONST_FLAG_UNSIZED) == 0) {
f << stringf("%d'", width);
}
if (data.flags & RTLIL::CONST_FLAG_SIGNED) {
f << stringf("s");
}
@ -96,11 +109,11 @@ void RTLIL_BACKEND::dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk,
dump_const(f, chunk.data, chunk.width, chunk.offset, autoint);
} else {
if (chunk.width == chunk.wire->width && chunk.offset == 0)
f << stringf("%s", chunk.wire->name.c_str());
f << stringf("%s", chunk.wire->name);
else if (chunk.width == 1)
f << stringf("%s [%d]", chunk.wire->name.c_str(), chunk.offset);
f << stringf("%s [%d]", chunk.wire->name, chunk.offset);
else
f << stringf("%s [%d:%d]", chunk.wire->name.c_str(), chunk.offset+chunk.width-1, chunk.offset);
f << stringf("%s [%d:%d]", chunk.wire->name, chunk.offset+chunk.width-1, chunk.offset);
}
}
@ -110,8 +123,9 @@ void RTLIL_BACKEND::dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, boo
dump_sigchunk(f, sig.as_chunk(), autoint);
} else {
f << stringf("{ ");
for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); ++it) {
dump_sigchunk(f, *it, false);
auto chunks = sig.chunks();
for (const auto& chunk : reversed(chunks)) {
dump_sigchunk(f, chunk, false);
f << stringf(" ");
}
f << stringf("}");
@ -120,16 +134,12 @@ void RTLIL_BACKEND::dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, boo
void RTLIL_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire)
{
for (auto &it : wire->attributes) {
f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str());
dump_const(f, it.second);
f << stringf("\n");
}
dump_attributes(f, indent, wire);
if (wire->driverCell_) {
f << stringf("%s" "# driver %s %s\n", indent.c_str(),
wire->driverCell()->name.c_str(), wire->driverPort().c_str());
f << stringf("%s" "# driver %s %s\n", indent,
wire->driverCell()->name, wire->driverPort());
}
f << stringf("%s" "wire ", indent.c_str());
f << stringf("%s" "wire ", indent);
if (wire->width != 1)
f << stringf("width %d ", wire->width);
if (wire->upto)
@ -144,101 +154,85 @@ void RTLIL_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::
f << stringf("inout %d ", wire->port_id);
if (wire->is_signed)
f << stringf("signed ");
f << stringf("%s\n", wire->name.c_str());
f << stringf("%s\n", wire->name);
}
void RTLIL_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL::Memory *memory)
{
for (auto &it : memory->attributes) {
f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str());
dump_const(f, it.second);
f << stringf("\n");
}
f << stringf("%s" "memory ", indent.c_str());
dump_attributes(f, indent, memory);
f << stringf("%s" "memory ", indent);
if (memory->width != 1)
f << stringf("width %d ", memory->width);
if (memory->size != 0)
f << stringf("size %d ", memory->size);
if (memory->start_offset != 0)
f << stringf("offset %d ", memory->start_offset);
f << stringf("%s\n", memory->name.c_str());
f << stringf("%s\n", memory->name);
}
void RTLIL_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL::Cell *cell)
{
for (auto &it : cell->attributes) {
f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str());
dump_const(f, it.second);
dump_attributes(f, indent, cell);
f << stringf("%s" "cell %s %s\n", indent, cell->type, cell->name);
for (const auto& [name, param] : reversed(cell->parameters)) {
f << stringf("%s parameter%s%s%s %s ", indent,
(param.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "",
(param.flags & RTLIL::CONST_FLAG_REAL) != 0 ? " real" : "",
(param.flags & RTLIL::CONST_FLAG_UNSIZED) != 0 ? " unsized" : "",
name);
dump_const(f, param);
f << stringf("\n");
}
f << stringf("%s" "cell %s %s\n", indent.c_str(), cell->type.c_str(), cell->name.c_str());
for (auto &it : cell->parameters) {
f << stringf("%s parameter%s%s %s ", indent.c_str(),
(it.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "",
(it.second.flags & RTLIL::CONST_FLAG_REAL) != 0 ? " real" : "",
it.first.c_str());
dump_const(f, it.second);
for (const auto& [port, sig] : reversed(cell->connections_)) {
f << stringf("%s connect %s ", indent, port);
dump_sigspec(f, sig);
f << stringf("\n");
}
for (auto &it : cell->connections()) {
f << stringf("%s connect %s ", indent.c_str(), it.first.c_str());
dump_sigspec(f, it.second);
f << stringf("\n");
}
f << stringf("%s" "end\n", indent.c_str());
f << stringf("%s" "end\n", indent);
}
void RTLIL_BACKEND::dump_proc_case_body(std::ostream &f, std::string indent, const RTLIL::CaseRule *cs)
{
for (auto it = cs->actions.begin(); it != cs->actions.end(); ++it)
{
f << stringf("%s" "assign ", indent.c_str());
dump_sigspec(f, it->first);
for (const auto& [lhs, rhs] : cs->actions) {
f << stringf("%s" "assign ", indent);
dump_sigspec(f, lhs);
f << stringf(" ");
dump_sigspec(f, it->second);
dump_sigspec(f, rhs);
f << stringf("\n");
}
for (auto it = cs->switches.begin(); it != cs->switches.end(); ++it)
dump_proc_switch(f, indent, *it);
for (const auto& sw : cs->switches)
dump_proc_switch(f, indent, sw);
}
void RTLIL_BACKEND::dump_proc_switch(std::ostream &f, std::string indent, const RTLIL::SwitchRule *sw)
{
for (auto it = sw->attributes.begin(); it != sw->attributes.end(); ++it) {
f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
dump_const(f, it->second);
f << stringf("\n");
}
dump_attributes(f, indent, sw);
f << stringf("%s" "switch ", indent.c_str());
f << stringf("%s" "switch ", indent);
dump_sigspec(f, sw->signal);
f << stringf("\n");
for (auto it = sw->cases.begin(); it != sw->cases.end(); ++it)
for (const auto case_ : sw->cases)
{
for (auto ait = (*it)->attributes.begin(); ait != (*it)->attributes.end(); ++ait) {
f << stringf("%s attribute %s ", indent.c_str(), ait->first.c_str());
dump_const(f, ait->second);
f << stringf("\n");
}
f << stringf("%s case ", indent.c_str());
for (size_t i = 0; i < (*it)->compare.size(); i++) {
dump_attributes(f, indent, case_);
f << stringf("%s case ", indent);
for (size_t i = 0; i < case_->compare.size(); i++) {
if (i > 0)
f << stringf(" , ");
dump_sigspec(f, (*it)->compare[i]);
dump_sigspec(f, case_->compare[i]);
}
f << stringf("\n");
dump_proc_case_body(f, indent + " ", *it);
dump_proc_case_body(f, indent + " ", case_);
}
f << stringf("%s" "end\n", indent.c_str());
f << stringf("%s" "end\n", indent);
}
void RTLIL_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RTLIL::SyncRule *sy)
{
f << stringf("%s" "sync ", indent.c_str());
f << stringf("%s" "sync ", indent);
switch (sy->type) {
case RTLIL::ST0: f << stringf("low ");
if (0) case RTLIL::ST1: f << stringf("high ");
@ -253,21 +247,17 @@ void RTLIL_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RT
case RTLIL::STi: f << stringf("init\n"); break;
}
for (auto &it: sy->actions) {
f << stringf("%s update ", indent.c_str());
dump_sigspec(f, it.first);
for (const auto& [lhs, rhs] : sy->actions) {
f << stringf("%s update ", indent);
dump_sigspec(f, lhs);
f << stringf(" ");
dump_sigspec(f, it.second);
dump_sigspec(f, rhs);
f << stringf("\n");
}
for (auto &it: sy->mem_write_actions) {
for (auto it2 = it.attributes.begin(); it2 != it.attributes.end(); ++it2) {
f << stringf("%s attribute %s ", indent.c_str(), it2->first.c_str());
dump_const(f, it2->second);
f << stringf("\n");
}
f << stringf("%s memwr %s ", indent.c_str(), it.memid.c_str());
dump_attributes(f, indent, &it);
f << stringf("%s memwr %s ", indent, it.memid);
dump_sigspec(f, it.address);
f << stringf(" ");
dump_sigspec(f, it.data);
@ -281,21 +271,17 @@ void RTLIL_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RT
void RTLIL_BACKEND::dump_proc(std::ostream &f, std::string indent, const RTLIL::Process *proc)
{
for (auto it = proc->attributes.begin(); it != proc->attributes.end(); ++it) {
f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
dump_const(f, it->second);
f << stringf("\n");
}
f << stringf("%s" "process %s\n", indent.c_str(), proc->name.c_str());
dump_attributes(f, indent, proc);
f << stringf("%s" "process %s\n", indent, proc->name);
dump_proc_case_body(f, indent + " ", &proc->root_case);
for (auto it = proc->syncs.begin(); it != proc->syncs.end(); ++it)
dump_proc_sync(f, indent + " ", *it);
f << stringf("%s" "end\n", indent.c_str());
for (auto* sync : proc->syncs)
dump_proc_sync(f, indent + " ", sync);
f << stringf("%s" "end\n", indent);
}
void RTLIL_BACKEND::dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
{
f << stringf("%s" "connect ", indent.c_str());
f << stringf("%s" "connect ", indent);
dump_sigspec(f, left);
f << stringf(" ");
dump_sigspec(f, right);
@ -309,13 +295,9 @@ void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu
if (print_header)
{
for (auto it = module->attributes.begin(); it != module->attributes.end(); ++it) {
f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
dump_const(f, it->second);
f << stringf("\n");
}
dump_attributes(f, indent, module);
f << stringf("%s" "module %s\n", indent.c_str(), module->name.c_str());
f << stringf("%s" "module %s\n", indent, module->name);
if (!module->avail_parameters.empty()) {
if (only_selected)
@ -323,9 +305,9 @@ void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu
for (const auto &p : module->avail_parameters) {
const auto &it = module->parameter_default_values.find(p);
if (it == module->parameter_default_values.end()) {
f << stringf("%s" " parameter %s\n", indent.c_str(), p.c_str());
f << stringf("%s" " parameter %s\n", indent, p);
} else {
f << stringf("%s" " parameter %s ", indent.c_str(), p.c_str());
f << stringf("%s" " parameter %s ", indent, p);
dump_const(f, it->second);
f << stringf("\n");
}
@ -335,40 +317,40 @@ void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu
if (print_body)
{
for (auto it : module->wires())
if (!only_selected || design->selected(module, it)) {
for (const auto& [_, wire] : reversed(module->wires_))
if (!only_selected || design->selected(module, wire)) {
if (only_selected)
f << stringf("\n");
dump_wire(f, indent + " ", it);
dump_wire(f, indent + " ", wire);
}
for (auto it : module->memories)
if (!only_selected || design->selected(module, it.second)) {
for (const auto& [_, mem] : reversed(module->memories))
if (!only_selected || design->selected(module, mem)) {
if (only_selected)
f << stringf("\n");
dump_memory(f, indent + " ", it.second);
dump_memory(f, indent + " ", mem);
}
for (auto it : module->cells())
if (!only_selected || design->selected(module, it)) {
for (const auto& [_, cell] : reversed(module->cells_))
if (!only_selected || design->selected(module, cell)) {
if (only_selected)
f << stringf("\n");
dump_cell(f, indent + " ", it);
dump_cell(f, indent + " ", cell);
}
for (auto it : module->processes)
if (!only_selected || design->selected(module, it.second)) {
for (const auto& [_, process] : reversed(module->processes))
if (!only_selected || design->selected(module, process)) {
if (only_selected)
f << stringf("\n");
dump_proc(f, indent + " ", it.second);
dump_proc(f, indent + " ", process);
}
bool first_conn_line = true;
for (auto it = module->connections().begin(); it != module->connections().end(); ++it) {
for (const auto& [lhs, rhs] : module->connections()) {
bool show_conn = !only_selected || design->selected_whole_module(module->name);
if (!show_conn) {
RTLIL::SigSpec sigs = it->first;
sigs.append(it->second);
RTLIL::SigSpec sigs = lhs;
sigs.append(rhs);
for (auto &c : sigs.chunks()) {
if (c.wire == NULL || !design->selected(module, c.wire))
continue;
@ -378,14 +360,14 @@ void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu
if (show_conn) {
if (only_selected && first_conn_line)
f << stringf("\n");
dump_conn(f, indent + " ", it->first, it->second);
dump_conn(f, indent + " ", lhs, rhs);
first_conn_line = false;
}
}
}
if (print_header)
f << stringf("%s" "end\n", indent.c_str());
f << stringf("%s" "end\n", indent);
}
void RTLIL_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n)
@ -394,7 +376,7 @@ void RTLIL_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool onl
if (!flag_m) {
int count_selected_mods = 0;
for (auto module : design->modules()) {
for (auto* module : design->modules()) {
if (design->selected_whole_module(module->name))
flag_m = true;
if (design->selected(module))
@ -410,7 +392,7 @@ void RTLIL_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool onl
f << stringf("autoidx %d\n", autoidx);
}
for (auto module : design->modules()) {
for (const auto& [_, module] : reversed(design->modules_)) {
if (!only_selected || design->selected(module)) {
if (only_selected)
f << stringf("\n");
@ -438,10 +420,14 @@ struct RTLILBackend : public Backend {
log(" -selected\n");
log(" only write selected parts of the design.\n");
log("\n");
log(" -sort\n");
log(" sort design in-place (used to be default).\n");
log("\n");
}
void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override
{
bool selected = false;
bool do_sort = false;
log_header(design, "Executing RTLIL backend.\n");
@ -452,13 +438,18 @@ struct RTLILBackend : public Backend {
selected = true;
continue;
}
if (arg == "-sort") {
do_sort = true;
continue;
}
break;
}
extra_args(f, filename, args, argidx);
design->sort();
log("Output filename: %s\n", filename);
log("Output filename: %s\n", filename.c_str());
if (do_sort)
design->sort();
*f << stringf("# Generated by %s\n", yosys_maybe_version());
RTLIL_BACKEND::dump_design(*f, design, selected, true, false);
@ -528,10 +519,10 @@ struct DumpPass : public Pass {
if (!empty) {
rewrite_filename(filename);
std::ofstream *ff = new std::ofstream;
ff->open(filename.c_str(), append ? std::ofstream::app : std::ofstream::trunc);
ff->open(filename, append ? std::ofstream::app : std::ofstream::trunc);
if (ff->fail()) {
delete ff;
log_error("Can't open file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
log_error("Can't open file `%s' for writing: %s\n", filename, strerror(errno));
}
f = ff;
} else {
@ -543,7 +534,7 @@ struct DumpPass : public Pass {
if (!empty) {
delete f;
} else {
log("%s", buf.str().c_str());
log("%s", buf.str());
}
}
} DumpPass;

View file

@ -31,6 +31,7 @@
YOSYS_NAMESPACE_BEGIN
namespace RTLIL_BACKEND {
void dump_attributes(std::ostream &f, std::string indent, const RTLIL::AttrObject *obj);
void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int offset = 0, bool autoint = true);
void dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, bool autoint = true);
void dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, bool autoint = true);

View file

@ -218,8 +218,8 @@ struct SimplecWorker
s[i] -= 'a' - 'A';
util_declarations.push_back("");
util_declarations.push_back(stringf("#ifndef %s", s.c_str()));
util_declarations.push_back(stringf("#define %s", s.c_str()));
util_declarations.push_back(stringf("#ifndef %s", s));
util_declarations.push_back(stringf("#define %s", s));
}
string util_get_bit(const string &signame, int n, int idx)
@ -232,33 +232,33 @@ struct SimplecWorker
if (generated_utils.count(util_name) == 0)
{
util_ifdef_guard(util_name);
util_declarations.push_back(stringf("static inline bool %s(const %s *sig)", util_name.c_str(), sigtype(n).c_str()));
util_declarations.push_back(stringf("static inline bool %s(const %s *sig)", util_name, sigtype(n)));
util_declarations.push_back(stringf("{"));
int word_idx = idx / max_uintsize, word_offset = idx % max_uintsize;
string value_name = stringf("value_%d_%d", std::min(n-1, (word_idx+1)*max_uintsize-1), word_idx*max_uintsize);
util_declarations.push_back(stringf(" return (sig->%s >> %d) & 1;", value_name.c_str(), word_offset));
util_declarations.push_back(stringf(" return (sig->%s >> %d) & 1;", value_name, word_offset));
util_declarations.push_back(stringf("}"));
util_declarations.push_back(stringf("#endif"));
generated_utils.insert(util_name);
}
return stringf("%s(&%s)", util_name.c_str(), signame.c_str());
return stringf("%s(&%s)", util_name, signame);
}
string util_set_bit(const string &signame, int n, int idx, const string &expr)
{
if (n == 1 && idx == 0)
return stringf(" %s.value_0_0 = %s;", signame.c_str(), expr.c_str());
return stringf(" %s.value_0_0 = %s;", signame, expr);
string util_name = stringf("yosys_simplec_set_bit_%d_of_%d", idx, n);
if (generated_utils.count(util_name) == 0)
{
util_ifdef_guard(util_name);
util_declarations.push_back(stringf("static inline void %s(%s *sig, bool value)", util_name.c_str(), sigtype(n).c_str()));
util_declarations.push_back(stringf("static inline void %s(%s *sig, bool value)", util_name, sigtype(n)));
util_declarations.push_back(stringf("{"));
int word_idx = idx / max_uintsize, word_offset = idx % max_uintsize;
@ -266,9 +266,9 @@ struct SimplecWorker
#if 0
util_declarations.push_back(stringf(" if (value)"));
util_declarations.push_back(stringf(" sig->%s |= 1UL << %d;", value_name.c_str(), word_offset));
util_declarations.push_back(stringf(" sig->%s |= 1UL << %d;", value_name, word_offset));
util_declarations.push_back(stringf(" else"));
util_declarations.push_back(stringf(" sig->%s &= ~(1UL << %d);", value_name.c_str(), word_offset));
util_declarations.push_back(stringf(" sig->%s &= ~(1UL << %d);", value_name, word_offset));
#else
util_declarations.push_back(stringf(" sig->%s = (sig->%s & ~((uint%d_t)1 << %d)) | ((uint%d_t)value << %d);",
value_name.c_str(), value_name.c_str(), max_uintsize, word_offset, max_uintsize, word_offset));
@ -279,7 +279,7 @@ struct SimplecWorker
generated_utils.insert(util_name);
}
return stringf(" %s(&%s, %s);", util_name.c_str(), signame.c_str(), expr.c_str());
return stringf(" %s(&%s, %s);", util_name, signame, expr);
}
void create_module_struct(Module *mod)
@ -339,38 +339,38 @@ struct SimplecWorker
for (int i = 0; i < GetSize(topo.sorted); i++)
topoidx[mod->cell(topo.sorted[i])] = i;
string ifdef_name = stringf("yosys_simplec_%s_state_t", cid(mod->name).c_str());
string ifdef_name = stringf("yosys_simplec_%s_state_t", cid(mod->name));
for (int i = 0; i < GetSize(ifdef_name); i++)
if ('a' <= ifdef_name[i] && ifdef_name[i] <= 'z')
ifdef_name[i] -= 'a' - 'A';
struct_declarations.push_back("");
struct_declarations.push_back(stringf("#ifndef %s", ifdef_name.c_str()));
struct_declarations.push_back(stringf("#define %s", ifdef_name.c_str()));
struct_declarations.push_back(stringf("struct %s_state_t", cid(mod->name).c_str()));
struct_declarations.push_back(stringf("#ifndef %s", ifdef_name));
struct_declarations.push_back(stringf("#define %s", ifdef_name));
struct_declarations.push_back(stringf("struct %s_state_t", cid(mod->name)));
struct_declarations.push_back("{");
struct_declarations.push_back(" // Input Ports");
for (Wire *w : mod->wires())
if (w->port_input)
struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width).c_str(), cid(w->name).c_str(), log_id(w)));
struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width), cid(w->name), log_id(w)));
struct_declarations.push_back("");
struct_declarations.push_back(" // Output Ports");
for (Wire *w : mod->wires())
if (!w->port_input && w->port_output)
struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width).c_str(), cid(w->name).c_str(), log_id(w)));
struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width), cid(w->name), log_id(w)));
struct_declarations.push_back("");
struct_declarations.push_back(" // Internal Wires");
for (Wire *w : mod->wires())
if (!w->port_input && !w->port_output)
struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width).c_str(), cid(w->name).c_str(), log_id(w)));
struct_declarations.push_back(stringf(" %s %s; // %s", sigtype(w->width), cid(w->name), log_id(w)));
for (Cell *c : mod->cells())
if (design->module(c->type))
struct_declarations.push_back(stringf(" struct %s_state_t %s; // %s", cid(c->type).c_str(), cid(c->name).c_str(), log_id(c)));
struct_declarations.push_back(stringf(" struct %s_state_t %s; // %s", cid(c->type), cid(c->name), log_id(c)));
struct_declarations.push_back(stringf("};"));
struct_declarations.push_back("#endif");
@ -407,14 +407,14 @@ struct SimplecWorker
string b_expr = b.wire ? util_get_bit(work->prefix + cid(b.wire->name), b.wire->width, b.offset) : b.data ? "1" : "0";
string expr;
if (cell->type == ID($_AND_)) expr = stringf("%s & %s", a_expr.c_str(), b_expr.c_str());
if (cell->type == ID($_NAND_)) expr = stringf("!(%s & %s)", a_expr.c_str(), b_expr.c_str());
if (cell->type == ID($_OR_)) expr = stringf("%s | %s", a_expr.c_str(), b_expr.c_str());
if (cell->type == ID($_NOR_)) expr = stringf("!(%s | %s)", a_expr.c_str(), b_expr.c_str());
if (cell->type == ID($_XOR_)) expr = stringf("%s ^ %s", a_expr.c_str(), b_expr.c_str());
if (cell->type == ID($_XNOR_)) expr = stringf("!(%s ^ %s)", a_expr.c_str(), b_expr.c_str());
if (cell->type == ID($_ANDNOT_)) expr = stringf("%s & (!%s)", a_expr.c_str(), b_expr.c_str());
if (cell->type == ID($_ORNOT_)) expr = stringf("%s | (!%s)", a_expr.c_str(), b_expr.c_str());
if (cell->type == ID($_AND_)) expr = stringf("%s & %s", a_expr, b_expr);
if (cell->type == ID($_NAND_)) expr = stringf("!(%s & %s)", a_expr, b_expr);
if (cell->type == ID($_OR_)) expr = stringf("%s | %s", a_expr, b_expr);
if (cell->type == ID($_NOR_)) expr = stringf("!(%s | %s)", a_expr, b_expr);
if (cell->type == ID($_XOR_)) expr = stringf("%s ^ %s", a_expr, b_expr);
if (cell->type == ID($_XNOR_)) expr = stringf("!(%s ^ %s)", a_expr, b_expr);
if (cell->type == ID($_ANDNOT_)) expr = stringf("%s & (!%s)", a_expr, b_expr);
if (cell->type == ID($_ORNOT_)) expr = stringf("%s | (!%s)", a_expr, b_expr);
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
@ -436,8 +436,8 @@ struct SimplecWorker
string c_expr = c.wire ? util_get_bit(work->prefix + cid(c.wire->name), c.wire->width, c.offset) : c.data ? "1" : "0";
string expr;
if (cell->type == ID($_AOI3_)) expr = stringf("!((%s & %s) | %s)", a_expr.c_str(), b_expr.c_str(), c_expr.c_str());
if (cell->type == ID($_OAI3_)) expr = stringf("!((%s | %s) & %s)", a_expr.c_str(), b_expr.c_str(), c_expr.c_str());
if (cell->type == ID($_AOI3_)) expr = stringf("!((%s & %s) | %s)", a_expr, b_expr, c_expr);
if (cell->type == ID($_OAI3_)) expr = stringf("!((%s | %s) & %s)", a_expr, b_expr, c_expr);
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
@ -461,8 +461,8 @@ struct SimplecWorker
string d_expr = d.wire ? util_get_bit(work->prefix + cid(d.wire->name), d.wire->width, d.offset) : d.data ? "1" : "0";
string expr;
if (cell->type == ID($_AOI4_)) expr = stringf("!((%s & %s) | (%s & %s))", a_expr.c_str(), b_expr.c_str(), c_expr.c_str(), d_expr.c_str());
if (cell->type == ID($_OAI4_)) expr = stringf("!((%s | %s) & (%s | %s))", a_expr.c_str(), b_expr.c_str(), c_expr.c_str(), d_expr.c_str());
if (cell->type == ID($_AOI4_)) expr = stringf("!((%s & %s) | (%s & %s))", a_expr, b_expr, c_expr, d_expr);
if (cell->type == ID($_OAI4_)) expr = stringf("!((%s | %s) & (%s | %s))", a_expr, b_expr, c_expr, d_expr);
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
@ -484,9 +484,9 @@ struct SimplecWorker
string s_expr = s.wire ? util_get_bit(work->prefix + cid(s.wire->name), s.wire->width, s.offset) : s.data ? "1" : "0";
// casts to bool are a workaround for CBMC bug (https://github.com/diffblue/cbmc/issues/933)
string expr = stringf("%s ? %s(bool)%s : %s(bool)%s", s_expr.c_str(),
cell->type == ID($_NMUX_) ? "!" : "", b_expr.c_str(),
cell->type == ID($_NMUX_) ? "!" : "", a_expr.c_str());
string expr = stringf("%s ? %s(bool)%s : %s(bool)%s", s_expr,
cell->type == ID($_NMUX_) ? "!" : "", b_expr,
cell->type == ID($_NMUX_) ? "!" : "", a_expr);
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
@ -504,7 +504,7 @@ struct SimplecWorker
while (work->dirty)
{
if (verbose && (!work->dirty_bits.empty() || !work->dirty_cells.empty()))
log(" In %s:\n", work->log_prefix.c_str());
log(" In %s:\n", work->log_prefix);
while (!work->dirty_bits.empty() || !work->dirty_cells.empty())
{
@ -517,8 +517,8 @@ struct SimplecWorker
if (chunk.wire == nullptr)
continue;
if (verbose)
log(" Propagating %s.%s[%d:%d].\n", work->log_prefix.c_str(), log_id(chunk.wire), chunk.offset+chunk.width-1, chunk.offset);
funct_declarations.push_back(stringf(" // Updated signal in %s: %s", work->log_prefix.c_str(), log_signal(chunk)));
log(" Propagating %s.%s[%d:%d].\n", work->log_prefix, log_id(chunk.wire), chunk.offset+chunk.width-1, chunk.offset);
funct_declarations.push_back(stringf(" // Updated signal in %s: %s", work->log_prefix, log_signal(chunk)));
}
for (SigBit bit : dirtysig)
@ -539,7 +539,7 @@ struct SimplecWorker
work->parent->set_dirty(parent_bit);
if (verbose)
log(" Propagating %s.%s[%d] -> %s.%s[%d].\n", work->log_prefix.c_str(), log_id(bit.wire), bit.offset,
log(" Propagating %s.%s[%d] -> %s.%s[%d].\n", work->log_prefix, log_id(bit.wire), bit.offset,
work->parent->log_prefix.c_str(), log_id(parent_bit.wire), parent_bit.offset);
}
@ -556,11 +556,11 @@ struct SimplecWorker
child->set_dirty(child_bit);
if (verbose)
log(" Propagating %s.%s[%d] -> %s.%s.%s[%d].\n", work->log_prefix.c_str(), log_id(bit.wire), bit.offset,
log(" Propagating %s.%s[%d] -> %s.%s.%s[%d].\n", work->log_prefix, log_id(bit.wire), bit.offset,
work->log_prefix.c_str(), log_id(std::get<0>(port)), log_id(child_bit.wire), child_bit.offset);
} else {
if (verbose)
log(" Marking cell %s.%s (via %s.%s[%d]).\n", work->log_prefix.c_str(), log_id(std::get<0>(port)),
log(" Marking cell %s.%s (via %s.%s[%d]).\n", work->log_prefix, log_id(std::get<0>(port)),
work->log_prefix.c_str(), log_id(bit.wire), bit.offset);
work->set_dirty(std::get<0>(port));
}
@ -579,7 +579,7 @@ struct SimplecWorker
string hiername = work->log_prefix + "." + log_id(cell);
if (verbose)
log(" Evaluating %s (%s, best of %d).\n", hiername.c_str(), log_id(cell->type), GetSize(work->dirty_cells));
log(" Evaluating %s (%s, best of %d).\n", hiername, log_id(cell->type), GetSize(work->dirty_cells));
if (activated_cells.count(hiername))
reactivated_cells.insert(hiername);
@ -630,13 +630,13 @@ struct SimplecWorker
void make_func(HierDirtyFlags *work, const string &func_name, const vector<string> &preamble)
{
log("Generating function %s():\n", func_name.c_str());
log("Generating function %s():\n", func_name);
activated_cells.clear();
reactivated_cells.clear();
funct_declarations.push_back("");
funct_declarations.push_back(stringf("static void %s(struct %s_state_t *state)", func_name.c_str(), cid(work->module->name).c_str()));
funct_declarations.push_back(stringf("static void %s(struct %s_state_t *state)", func_name, cid(work->module->name)));
funct_declarations.push_back("{");
for (auto &line : preamble)
funct_declarations.push_back(line);
@ -657,7 +657,7 @@ struct SimplecWorker
{
SigSpec sig = sigmaps.at(module)(w);
Const val = w->attributes.at(ID::init);
val.bits().resize(GetSize(sig), State::Sx);
val.resize(GetSize(sig), State::Sx);
for (int i = 0; i < GetSize(sig); i++)
if (val[i] == State::S0 || val[i] == State::S1) {

View file

@ -82,27 +82,27 @@ struct Smt2Worker
if (statebv)
{
if (width == 0) {
decl_str = stringf("(define-fun |%s| ((state |%s_s|)) Bool (= ((_ extract %d %d) state) #b1))", name.c_str(), get_id(module), statebv_width, statebv_width);
decl_str = stringf("(define-fun |%s| ((state |%s_s|)) Bool (= ((_ extract %d %d) state) #b1))", name, get_id(module), statebv_width, statebv_width);
statebv_width += 1;
} else {
decl_str = stringf("(define-fun |%s| ((state |%s_s|)) (_ BitVec %d) ((_ extract %d %d) state))", name.c_str(), get_id(module), width, statebv_width+width-1, statebv_width);
decl_str = stringf("(define-fun |%s| ((state |%s_s|)) (_ BitVec %d) ((_ extract %d %d) state))", name, get_id(module), width, statebv_width+width-1, statebv_width);
statebv_width += width;
}
}
else if (statedt)
{
if (width == 0) {
decl_str = stringf(" (|%s| Bool)", name.c_str());
decl_str = stringf(" (|%s| Bool)", name);
} else {
decl_str = stringf(" (|%s| (_ BitVec %d))", name.c_str(), width);
decl_str = stringf(" (|%s| (_ BitVec %d))", name, width);
}
}
else
{
if (width == 0) {
decl_str = stringf("(declare-fun |%s| (|%s_s|) Bool)", name.c_str(), get_id(module));
decl_str = stringf("(declare-fun |%s| (|%s_s|) Bool)", name, get_id(module));
} else {
decl_str = stringf("(declare-fun |%s| (|%s_s|) (_ BitVec %d))", name.c_str(), get_id(module), width);
decl_str = stringf("(declare-fun |%s| (|%s_s|) (_ BitVec %d))", name, get_id(module), width);
}
}
@ -130,7 +130,7 @@ struct Smt2Worker
for (auto &mem : memories)
{
if (is_smtlib2_module)
log_error("Memory %s.%s not allowed in module with smtlib2_module attribute", get_id(module), mem.memid.c_str());
log_error("Memory %s.%s not allowed in module with smtlib2_module attribute", get_id(module), mem.memid);
mem.narrow();
mem_dict[mem.memid] = &mem;
@ -383,7 +383,7 @@ struct Smt2Worker
}
if (fcache.count(sig[i]) && fcache.at(sig[i]).second == -1) {
subexpr.push_back(stringf("(ite %s #b1 #b0)", get_bool(sig[i], state_name).c_str()));
subexpr.push_back(stringf("(ite %s #b1 #b0)", get_bool(sig[i], state_name)));
continue;
}
@ -495,7 +495,7 @@ struct Smt2Worker
}
if (width != GetSize(sig_y) && type != 'b')
processed_expr = stringf("((_ extract %d 0) %s)", GetSize(sig_y)-1, processed_expr.c_str());
processed_expr = stringf("((_ extract %d 0) %s)", GetSize(sig_y)-1, processed_expr);
if (verbose)
log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", log_id(cell));
@ -617,14 +617,14 @@ struct Smt2Worker
string infostr = cell->attributes.count(ID::src) ? cell->attributes.at(ID::src).decode_string().c_str() : get_id(cell);
if (cell->attributes.count(ID::reg))
infostr += " " + cell->attributes.at(ID::reg).decode_string();
decls.push_back(stringf("; yosys-smt2-%s %s#%d %d %s\n", cell->type.c_str() + 1, get_id(module), idcounter, GetSize(cell->getPort(QY)), infostr.c_str()));
decls.push_back(stringf("; yosys-smt2-%s %s#%d %d %s\n", cell->type.c_str() + 1, get_id(module), idcounter, GetSize(cell->getPort(QY)), infostr));
if (cell->getPort(QY).is_wire() && cell->getPort(QY).as_wire()->get_bool_attribute(ID::maximize)){
decls.push_back(stringf("; yosys-smt2-maximize %s#%d\n", get_id(module), idcounter));
log("Wire %s is maximized\n", cell->getPort(QY).as_wire()->name.str().c_str());
log("Wire %s is maximized\n", cell->getPort(QY).as_wire()->name.str());
}
else if (cell->getPort(QY).is_wire() && cell->getPort(QY).as_wire()->get_bool_attribute(ID::minimize)){
decls.push_back(stringf("; yosys-smt2-minimize %s#%d\n", get_id(module), idcounter));
log("Wire %s is minimized\n", cell->getPort(QY).as_wire()->name.str().c_str());
log("Wire %s is minimized\n", cell->getPort(QY).as_wire()->name.str());
}
bool init_only = cell->type.in(ID($anyconst), ID($anyinit), ID($allconst));
@ -722,7 +722,7 @@ struct Smt2Worker
2*GetSize(cell->getPort(ID::A).chunks()) < GetSize(cell->getPort(ID::A))) {
bool is_and = cell->type == ID($reduce_and);
string bits(GetSize(cell->getPort(ID::A)), is_and ? '1' : '0');
return export_bvop(cell, stringf("(%s A #b%s)", is_and ? "=" : "distinct", bits.c_str()), 'b');
return export_bvop(cell, stringf("(%s A #b%s)", is_and ? "=" : "distinct", bits), 'b');
}
if (cell->type == ID($reduce_and)) return export_reduce(cell, "(and A)", true);
@ -746,7 +746,7 @@ struct Smt2Worker
get_bv(sig_s);
for (int i = 0; i < GetSize(sig_s); i++)
processed_expr = stringf("(ite %s %s %s)", get_bool(sig_s[i]).c_str(),
processed_expr = stringf("(ite %s %s %s)", get_bool(sig_s[i]),
get_bv(sig_b.extract(i*width, width)).c_str(), processed_expr.c_str());
if (verbose)
@ -1079,24 +1079,24 @@ struct Smt2Worker
RTLIL::SigSpec sig = sigmap(wire);
Const val = wire->attributes.at(ID::init);
val.bits().resize(GetSize(sig), State::Sx);
val.resize(GetSize(sig), State::Sx);
if (bvmode && GetSize(sig) > 1) {
Const mask(State::S1, GetSize(sig));
bool use_mask = false;
for (int i = 0; i < GetSize(sig); i++)
if (val[i] != State::S0 && val[i] != State::S1) {
val.bits()[i] = State::S0;
mask.bits()[i] = State::S0;
val.set(i, State::S0);
mask.set(i, State::S0);
use_mask = true;
}
if (use_mask)
init_list.push_back(stringf("(= (bvand %s #b%s) #b%s) ; %s", get_bv(sig).c_str(), mask.as_string().c_str(), val.as_string().c_str(), get_id(wire)));
init_list.push_back(stringf("(= (bvand %s #b%s) #b%s) ; %s", get_bv(sig), mask.as_string(), val.as_string(), get_id(wire)));
else
init_list.push_back(stringf("(= %s #b%s) ; %s", get_bv(sig).c_str(), val.as_string().c_str(), get_id(wire)));
init_list.push_back(stringf("(= %s #b%s) ; %s", get_bv(sig), val.as_string(), get_id(wire)));
} else {
for (int i = 0; i < GetSize(sig); i++)
if (val[i] == State::S0 || val[i] == State::S1)
init_list.push_back(stringf("(= %s %s) ; %s", get_bool(sig[i]).c_str(), val[i] == State::S1 ? "true" : "false", get_id(wire)));
init_list.push_back(stringf("(= %s %s) ; %s", get_bool(sig[i]), val[i] == State::S1 ? "true" : "false", get_id(wire)));
}
}
@ -1131,7 +1131,7 @@ struct Smt2Worker
}
if (private_name && cell->attributes.count(ID::src))
decls.push_back(stringf("; yosys-smt2-%s %d %s %s\n", cell->type.c_str() + 1, id, get_id(cell), cell->attributes.at(ID::src).decode_string().c_str()));
decls.push_back(stringf("; yosys-smt2-%s %d %s %s\n", cell->type.c_str() + 1, id, get_id(cell), cell->attributes.at(ID::src).decode_string()));
else
decls.push_back(stringf("; yosys-smt2-%s %d %s\n", cell->type.c_str() + 1, id, get_id(cell)));
@ -1180,11 +1180,11 @@ struct Smt2Worker
SigSpec sig = sigmap(conn.second);
if (bvmode || GetSize(w) == 1) {
hier.push_back(stringf(" (= %s (|%s_n %s| %s)) ; %s.%s\n", (GetSize(w) > 1 ? get_bv(sig) : get_bool(sig)).c_str(),
hier.push_back(stringf(" (= %s (|%s_n %s| %s)) ; %s.%s\n", (GetSize(w) > 1 ? get_bv(sig) : get_bool(sig)),
get_id(cell->type), get_id(w), cell_state.c_str(), get_id(cell->type), get_id(w)));
} else {
for (int i = 0; i < GetSize(w); i++)
hier.push_back(stringf(" (= %s (|%s_n %s %d| %s)) ; %s.%s[%d]\n", get_bool(sig[i]).c_str(),
hier.push_back(stringf(" (= %s (|%s_n %s %d| %s)) ; %s.%s[%d]\n", get_bool(sig[i]),
get_id(cell->type), get_id(w), i, cell_state.c_str(), get_id(cell->type), get_id(w), i));
}
}
@ -1204,25 +1204,25 @@ struct Smt2Worker
{
std::string expr_d = get_bool(cell->getPort(ID::D));
std::string expr_q = get_bool(cell->getPort(ID::Q), "next_state");
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort(ID::Q))));
ex_state_eq.push_back(stringf("(= %s %s)", get_bool(cell->getPort(ID::Q)).c_str(), get_bool(cell->getPort(ID::Q), "other_state").c_str()));
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d, expr_q, get_id(cell), log_signal(cell->getPort(ID::Q))));
ex_state_eq.push_back(stringf("(= %s %s)", get_bool(cell->getPort(ID::Q)), get_bool(cell->getPort(ID::Q), "other_state")));
}
if (cell->type.in(ID($ff), ID($dff), ID($anyinit)))
{
std::string expr_d = get_bv(cell->getPort(ID::D));
std::string expr_q = get_bv(cell->getPort(ID::Q), "next_state");
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort(ID::Q))));
ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort(ID::Q)).c_str(), get_bv(cell->getPort(ID::Q), "other_state").c_str()));
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d, expr_q, get_id(cell), log_signal(cell->getPort(ID::Q))));
ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort(ID::Q)), get_bv(cell->getPort(ID::Q), "other_state")));
}
if (cell->type.in(ID($anyconst), ID($allconst)))
{
std::string expr_d = get_bv(cell->getPort(ID::Y));
std::string expr_q = get_bv(cell->getPort(ID::Y), "next_state");
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort(ID::Y))));
trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d, expr_q, get_id(cell), log_signal(cell->getPort(ID::Y))));
if (cell->type == ID($anyconst))
ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort(ID::Y)).c_str(), get_bv(cell->getPort(ID::Y), "other_state").c_str()));
ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort(ID::Y)), get_bv(cell->getPort(ID::Y), "other_state")));
}
}
@ -1341,11 +1341,11 @@ struct Smt2Worker
std::string expr_d = stringf("(|%s#%d#%d| state)", get_id(module), arrayid, GetSize(mem->wr_ports));
std::string expr_q = stringf("(|%s#%d#0| next_state)", get_id(module), arrayid);
trans.push_back(stringf(" (= %s %s) ; %s\n", expr_d.c_str(), expr_q.c_str(), get_id(mem->memid)));
trans.push_back(stringf(" (= %s %s) ; %s\n", expr_d, expr_q, get_id(mem->memid)));
ex_state_eq.push_back(stringf("(= (|%s#%d#0| state) (|%s#%d#0| other_state))", get_id(module), arrayid, get_id(module), arrayid));
if (has_async_wr)
hier.push_back(stringf(" (= %s (|%s| state)) ; %s\n", expr_d.c_str(), final_memstate.c_str(), get_id(mem->memid)));
hier.push_back(stringf(" (= %s (|%s| state)) ; %s\n", expr_d, final_memstate, get_id(mem->memid)));
Const init_data = mem->get_init_data();
@ -1361,10 +1361,10 @@ struct Smt2Worker
for (int k = 0; k < GetSize(initword); k++) {
if (initword[k] == State::S0 || initword[k] == State::S1) {
gen_init_constr = true;
initmask.bits()[k] = State::S1;
initmask.set(k, State::S1);
} else {
initmask.bits()[k] = State::S0;
initword.bits()[k] = State::S0;
initmask.set(k, State::S0);
initword.set(k, State::S0);
}
}
@ -1402,7 +1402,7 @@ struct Smt2Worker
expr = "\n " + ex_state_eq.front() + "\n";
} else {
for (auto &str : ex_state_eq)
expr += stringf("\n %s", str.c_str());
expr += stringf("\n %s", str);
expr += "\n)";
}
}
@ -1415,7 +1415,7 @@ struct Smt2Worker
expr = "\n " + ex_input_eq.front() + "\n";
} else {
for (auto &str : ex_input_eq)
expr += stringf("\n %s", str.c_str());
expr += stringf("\n %s", str);
expr += "\n)";
}
}
@ -1429,7 +1429,7 @@ struct Smt2Worker
assert_expr = "\n " + assert_list.front() + "\n";
} else {
for (auto &str : assert_list)
assert_expr += stringf("\n %s", str.c_str());
assert_expr += stringf("\n %s", str);
assert_expr += "\n)";
}
}
@ -1442,7 +1442,7 @@ struct Smt2Worker
assume_expr = "\n " + assume_list.front() + "\n";
} else {
for (auto &str : assume_list)
assume_expr += stringf("\n %s", str.c_str());
assume_expr += stringf("\n %s", str);
assume_expr += "\n)";
}
}
@ -1455,7 +1455,7 @@ struct Smt2Worker
init_expr = "\n " + init_list.front() + "\n";
} else {
for (auto &str : init_list)
init_expr += stringf("\n %s", str.c_str());
init_expr += stringf("\n %s", str);
init_expr += "\n)";
}
}
@ -1776,7 +1776,7 @@ struct Smt2Backend : public Backend {
if (args[argidx] == "-tpl" && argidx+1 < args.size()) {
template_f.open(args[++argidx]);
if (template_f.fail())
log_error("Can't open template file `%s'.\n", args[argidx].c_str());
log_error("Can't open template file `%s'.\n", args[argidx]);
continue;
}
if (args[argidx] == "-bv" || args[argidx] == "-mem") {
@ -1846,7 +1846,7 @@ struct Smt2Backend : public Backend {
*f << stringf("; yosys-smt2-stdt\n");
for (auto &it : solver_options)
*f << stringf("; yosys-smt2-solver-option %s %s\n", it.first.c_str(), it.second.c_str());
*f << stringf("; yosys-smt2-solver-option %s %s\n", it.first, it.second);
std::vector<RTLIL::Module*> sorted_modules;
@ -1913,7 +1913,7 @@ struct Smt2Backend : public Backend {
}
if (topmod)
*f << stringf("; yosys-smt2-topmod %s\n", topmod_id.c_str());
*f << stringf("; yosys-smt2-topmod %s\n", topmod_id);
*f << stringf("; end of yosys output\n");

View file

@ -1875,6 +1875,11 @@ elif covermode:
smt_assert_antecedent("(|%s_t| s%d s%d)" % (topmod, step-1, step))
smt_assert_antecedent("(not (|%s_is| s%d))" % (topmod, step))
if step < skip_steps:
print_msg("Skipping step %d.." % (step))
step += 1
continue
while "1" in cover_mask:
print_msg("Checking cover reachability in step %d.." % (step))
smt_push()

View file

@ -59,7 +59,7 @@ struct SmvWorker
{
if (!idcache.count(id))
{
string name = stringf("_%s", id.c_str());
string name = stringf("_%s", id);
if (name.compare(0, 2, "_\\") == 0)
name = "_" + name.substr(2);
@ -163,15 +163,15 @@ struct SmvWorker
if (width >= 0) {
if (is_signed) {
if (GetSize(sig) > width)
s = stringf("signed(resize(%s, %d))", s.c_str(), width);
s = stringf("signed(resize(%s, %d))", s, width);
else
s = stringf("resize(signed(%s), %d)", s.c_str(), width);
s = stringf("resize(signed(%s), %d)", s, width);
} else
s = stringf("resize(%s, %d)", s.c_str(), width);
s = stringf("resize(%s, %d)", s, width);
} else if (is_signed)
s = stringf("signed(%s)", s.c_str());
s = stringf("signed(%s)", s);
else if (count_chunks > 1)
s = stringf("(%s)", s.c_str());
s = stringf("(%s)", s);
strbuf.push_back(s);
return strbuf.back().c_str();
@ -262,7 +262,7 @@ struct SmvWorker
if (cell->type == ID($sshr) && signed_a)
{
expr_a = rvalue_s(sig_a, width);
expr = stringf("resize(unsigned(%s %s %s), %d)", expr_a.c_str(), op.c_str(), rvalue(sig_b.extract(0, shift_b_width)), width_y);
expr = stringf("resize(unsigned(%s %s %s), %d)", expr_a, op, rvalue(sig_b.extract(0, shift_b_width)), width_y);
if (shift_b_width < GetSize(sig_b))
expr = stringf("%s != 0ud%d_0 ? (bool(%s) ? !0ud%d_0 : 0ud%d_0) : %s",
rvalue(sig_b.extract(shift_b_width, GetSize(sig_b) - shift_b_width)), GetSize(sig_b) - shift_b_width,
@ -278,8 +278,8 @@ struct SmvWorker
// f << stringf(" %s : unsigned word[%d]; -- neg(%s)\n", b_shl, GetSize(sig_b), log_signal(sig_b));
definitions.push_back(stringf("%s := unsigned(-%s);", b_shl, rvalue_s(sig_b)));
string expr_shl = stringf("resize(%s << %s[%d:0], %d)", expr_a.c_str(), b_shl, shift_b_width-1, width_y);
string expr_shr = stringf("resize(%s >> %s[%d:0], %d)", expr_a.c_str(), b_shr, shift_b_width-1, width_y);
string expr_shl = stringf("resize(%s << %s[%d:0], %d)", expr_a, b_shl, shift_b_width-1, width_y);
string expr_shr = stringf("resize(%s >> %s[%d:0], %d)", expr_a, b_shr, shift_b_width-1, width_y);
if (shift_b_width < GetSize(sig_b)) {
expr_shl = stringf("%s[%d:%d] != 0ud%d_0 ? 0ud%d_0 : %s", b_shl, GetSize(sig_b)-1, shift_b_width,
@ -288,7 +288,7 @@ struct SmvWorker
GetSize(sig_b)-shift_b_width, width_y, expr_shr.c_str());
}
expr = stringf("bool(%s) ? %s : %s", rvalue(sig_b[GetSize(sig_b)-1]), expr_shl.c_str(), expr_shr.c_str());
expr = stringf("bool(%s) ? %s : %s", rvalue(sig_b[GetSize(sig_b)-1]), expr_shl, expr_shr);
}
else
{
@ -297,13 +297,13 @@ struct SmvWorker
else
expr_a = stringf("resize(unsigned(%s), %d)", rvalue_s(sig_a, width_ay), width);
expr = stringf("resize(%s %s %s[%d:0], %d)", expr_a.c_str(), op.c_str(), rvalue_u(sig_b), shift_b_width-1, width_y);
expr = stringf("resize(%s %s %s[%d:0], %d)", expr_a, op, rvalue_u(sig_b), shift_b_width-1, width_y);
if (shift_b_width < GetSize(sig_b))
expr = stringf("%s[%d:%d] != 0ud%d_0 ? 0ud%d_0 : %s", rvalue_u(sig_b), GetSize(sig_b)-1, shift_b_width,
GetSize(sig_b)-shift_b_width, width_y, expr.c_str());
}
definitions.push_back(stringf("%s := %s;", lvalue(cell->getPort(ID::Y)), expr.c_str()));
definitions.push_back(stringf("%s := %s;", lvalue(cell->getPort(ID::Y)), expr));
continue;
}
@ -426,7 +426,7 @@ struct SmvWorker
if (cell->type == ID($reduce_or)) expr = stringf("%s != 0ub%d_0", expr_a, width_a);
if (cell->type == ID($reduce_bool)) expr = stringf("%s != 0ub%d_0", expr_a, width_a);
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr.c_str(), width_y));
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr, width_y));
continue;
}
@ -445,7 +445,7 @@ struct SmvWorker
if (cell->type == ID($reduce_xnor))
expr = "!(" + expr + ")";
definitions.push_back(stringf("%s := resize(%s, %d);", expr_y, expr.c_str(), width_y));
definitions.push_back(stringf("%s := resize(%s, %d);", expr_y, expr, width_y));
continue;
}
@ -463,7 +463,7 @@ struct SmvWorker
if (cell->type == ID($logic_and)) expr = expr_a + " & " + expr_b;
if (cell->type == ID($logic_or)) expr = expr_a + " | " + expr_b;
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr.c_str(), width_y));
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr, width_y));
continue;
}
@ -475,7 +475,7 @@ struct SmvWorker
string expr_a = stringf("(%s = 0ub%d_0)", rvalue(cell->getPort(ID::A)), width_a);
const char *expr_y = lvalue(cell->getPort(ID::Y));
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr_a.c_str(), width_y));
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr_a, width_y));
continue;
}
@ -491,7 +491,7 @@ struct SmvWorker
expr += stringf("bool(%s) ? %s : ", rvalue(sig_s[i]), rvalue(sig_b.extract(i*width, width)));
expr += rvalue(sig_a);
definitions.push_back(stringf("%s := %s;", lvalue(cell->getPort(ID::Y)), expr.c_str()));
definitions.push_back(stringf("%s := %s;", lvalue(cell->getPort(ID::Y)), expr));
continue;
}
@ -505,7 +505,7 @@ struct SmvWorker
if (cell->type.in(ID($_BUF_), ID($_NOT_)))
{
string op = cell->type == ID($_NOT_) ? "!" : "";
definitions.push_back(stringf("%s := %s%s;", lvalue(cell->getPort(ID::Y)), op.c_str(), rvalue(cell->getPort(ID::A))));
definitions.push_back(stringf("%s := %s%s;", lvalue(cell->getPort(ID::Y)), op, rvalue(cell->getPort(ID::A))));
continue;
}
@ -650,7 +650,7 @@ struct SmvWorker
for (int k = GetSize(sig)-1; k >= 0; k--)
bits += sig[k] == State::S1 ? '1' : '0';
expr = stringf("0ub%d_%s", GetSize(bits), bits.c_str()) + expr;
expr = stringf("0ub%d_%s", GetSize(bits), bits) + expr;
}
else if (sigmap(SigBit(wire, i)) == SigBit(wire, i))
{
@ -683,36 +683,36 @@ struct SmvWorker
}
}
definitions.push_back(stringf("%s := %s;", cid(wire->name), expr.c_str()));
definitions.push_back(stringf("%s := %s;", cid(wire->name), expr));
}
if (!inputvars.empty()) {
f << stringf(" IVAR\n");
for (const string &line : inputvars)
f << stringf(" %s\n", line.c_str());
f << stringf(" %s\n", line);
}
if (!vars.empty()) {
f << stringf(" VAR\n");
for (const string &line : vars)
f << stringf(" %s\n", line.c_str());
f << stringf(" %s\n", line);
}
if (!definitions.empty()) {
f << stringf(" DEFINE\n");
for (const string &line : definitions)
f << stringf(" %s\n", line.c_str());
f << stringf(" %s\n", line);
}
if (!assignments.empty()) {
f << stringf(" ASSIGN\n");
for (const string &line : assignments)
f << stringf(" %s\n", line.c_str());
f << stringf(" %s\n", line);
}
if (!invarspecs.empty()) {
for (const string &line : invarspecs)
f << stringf(" INVARSPEC %s\n", line.c_str());
f << stringf(" INVARSPEC %s\n", line);
}
}
};
@ -756,7 +756,7 @@ struct SmvBackend : public Backend {
if (args[argidx] == "-tpl" && argidx+1 < args.size()) {
template_f.open(args[++argidx]);
if (template_f.fail())
log_error("Can't open template file `%s'.\n", args[argidx].c_str());
log_error("Can't open template file `%s'.\n", args[argidx]);
continue;
}
if (args[argidx] == "-verbose") {
@ -795,7 +795,7 @@ struct SmvBackend : public Backend {
modules.erase(module);
if (module == nullptr)
log_error("Module '%s' not found.\n", stmt[1].c_str());
log_error("Module '%s' not found.\n", stmt[1]);
*f << stringf("-- SMV description generated by %s\n", yosys_maybe_version());

View file

@ -51,16 +51,16 @@ static void print_spice_net(std::ostream &f, RTLIL::SigBit s, std::string &neg,
if (s.wire->port_id)
use_inames = true;
if (s.wire->width > 1)
f << stringf(" %s.%d", spice_id2str(s.wire->name, use_inames, inums).c_str(), s.offset);
f << stringf(" %s.%d", spice_id2str(s.wire->name, use_inames, inums), s.offset);
else
f << stringf(" %s", spice_id2str(s.wire->name, use_inames, inums).c_str());
f << stringf(" %s", spice_id2str(s.wire->name, use_inames, inums));
} else {
if (s == RTLIL::State::S0)
f << stringf(" %s", neg.c_str());
f << stringf(" %s", neg);
else if (s == RTLIL::State::S1)
f << stringf(" %s", pos.c_str());
f << stringf(" %s", pos);
else
f << stringf(" %s%d", ncpf.c_str(), nc_counter++);
f << stringf(" %s%d", ncpf, nc_counter++);
}
}
@ -119,7 +119,7 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De
}
}
f << stringf(" %s\n", spice_id2str(cell->type).c_str());
f << stringf(" %s\n", spice_id2str(cell->type));
}
for (auto &conn : module->connections())
@ -127,7 +127,7 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De
f << (buf == "DC" ? stringf("V%d", conn_counter++) : stringf("X%d", cell_counter++));
print_spice_net(f, conn.second.extract(i, 1), neg, pos, ncpf, nc_counter, use_inames, inums);
print_spice_net(f, conn.first.extract(i, 1), neg, pos, ncpf, nc_counter, use_inames, inums);
f << (buf == "DC" ? " DC 0\n" : stringf(" %s\n", buf.c_str()));
f << (buf == "DC" ? " DC 0\n" : stringf(" %s\n", buf));
}
}
@ -242,23 +242,23 @@ struct SpiceBackend : public Backend {
ports.at(wire->port_id-1) = wire;
}
*f << stringf(".SUBCKT %s", spice_id2str(module->name).c_str());
*f << stringf(".SUBCKT %s", spice_id2str(module->name));
for (RTLIL::Wire *wire : ports) {
log_assert(wire != NULL);
if (wire->width > 1) {
for (int i = 0; i < wire->width; i++)
*f << stringf(" %s.%d", spice_id2str(wire->name).c_str(), big_endian ? wire->width - 1 - i : i);
*f << stringf(" %s.%d", spice_id2str(wire->name), big_endian ? wire->width - 1 - i : i);
} else
*f << stringf(" %s", spice_id2str(wire->name).c_str());
*f << stringf(" %s", spice_id2str(wire->name));
}
*f << stringf("\n");
print_spice_module(*f, module, design, neg, pos, buf, ncpf, big_endian, use_inames);
*f << stringf(".ENDS %s\n\n", spice_id2str(module->name).c_str());
*f << stringf(".ENDS %s\n\n", spice_id2str(module->name));
}
if (!top_module_name.empty()) {
if (top_module == NULL)
log_error("Can't find top module `%s'!\n", top_module_name.c_str());
log_error("Can't find top module `%s'!\n", top_module_name);
print_spice_module(*f, top_module, design, neg, pos, buf, ncpf, big_endian, use_inames);
*f << stringf("\n");
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,39 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
*
* 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.
*
* ---
*
* A simple and straightforward Verilog backend.
*
*/
#ifndef VERILOG_BACKEND_H
#define VERILOG_BACKEND_H
#include <string>
YOSYS_NAMESPACE_BEGIN
namespace VERILOG_BACKEND {
const pool<string> verilog_keywords();
bool char_is_verilog_escaped(char c);
bool id_is_verilog_escaped(const std::string &str);
}; /* namespace VERILOG_BACKEND */
YOSYS_NAMESPACE_END
#endif /* VERILOG_BACKEND_H */