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:
commit
6fe35fa46c
694 changed files with 33466 additions and 17901 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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 ¶m : 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;
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ struct JsonWriter
|
|||
bool first = true;
|
||||
for (auto ¶m : 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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
||||
|
|
|
|||
|
|
@ -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
39
backends/verilog/verilog_backend.h
Normal file
39
backends/verilog/verilog_backend.h
Normal 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 */
|
||||
Loading…
Add table
Add a link
Reference in a new issue