#include "kernel/register.h"
#include "kernel/celltypes.h"
#include "kernel/log.h"
+#include "kernel/sigtools.h"
#include <string>
#include <sstream>
#include <set>
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
-bool norename, noattr, attr2comment, noexpr;
+bool norename, noattr, attr2comment, noexpr, nomem;
int auto_name_counter, auto_name_offset, auto_name_digits;
std::map<RTLIL::IdString, int> auto_name_map;
std::set<RTLIL::IdString> reg_wires, reg_ct;
if (*str == '$' && may_rename && !norename)
auto_name_map[id] = auto_name_counter++;
- if (str[0] != '_' && str[1] != 0)
+ if (str[0] != '\\' || str[1] != '_' || str[2] == 0)
return;
- for (int i = 0; str[i] != 0; i++) {
- if (str[i] == '_')
+
+ for (int i = 2; str[i] != 0; i++) {
+ if (str[i] == '_' && str[i+1] == 0)
continue;
if (str[i] < '0' || str[i] > '9')
return;
}
- int num = atoi(str+1);
+ int num = atoi(str+2);
if (num >= auto_name_offset)
auto_name_offset = num + 1;
}
reset_auto_counter_id(module->name, false);
- for (auto it = module->wires_.begin(); it != module->wires_.end(); it++)
+ for (auto it = module->wires_.begin(); it != module->wires_.end(); ++it)
reset_auto_counter_id(it->second->name, true);
- for (auto it = module->cells_.begin(); it != module->cells_.end(); it++) {
+ for (auto it = module->cells_.begin(); it != module->cells_.end(); ++it) {
reset_auto_counter_id(it->second->name, true);
reset_auto_counter_id(it->second->type, false);
}
- for (auto it = module->processes.begin(); it != module->processes.end(); it++)
+ for (auto it = module->processes.begin(); it != module->processes.end(); ++it)
reset_auto_counter_id(it->second->name, false);
auto_name_digits = 1;
for (size_t i = 10; i < auto_name_offset + auto_name_map.size(); i = i*10)
auto_name_digits++;
- for (auto it = auto_name_map.begin(); it != auto_name_map.end(); it++)
+ for (auto it = auto_name_map.begin(); it != auto_name_map.end(); ++it)
log(" renaming `%s' to `_%0*d_'.\n", it->first.c_str(), auto_name_digits, auto_name_offset + it->second);
}
+std::string next_auto_id()
+{
+ return stringf("_%0*d_", auto_name_digits, auto_name_offset + auto_name_counter++);
+}
+
std::string id(RTLIL::IdString internal_id, bool may_rename = true)
{
const char *str = internal_id.c_str();
bool do_escape = false;
- if (may_rename && auto_name_map.count(internal_id) != 0) {
- char buffer[100];
- snprintf(buffer, 100, "_%0*d_", auto_name_digits, auto_name_offset + auto_name_map[internal_id]);
- return std::string(buffer);
- }
+ if (may_rename && auto_name_map.count(internal_id) != 0)
+ return stringf("_%0*d_", auto_name_digits, auto_name_offset + auto_name_map[internal_id]);
if (*str == '\\')
str++;
return true;
}
-void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int offset = 0, bool no_decimal = false, bool set_signed = false)
+void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int offset = 0, bool no_decimal = false, bool set_signed = false, bool escape_comment = false)
{
if (width < 0)
width = data.bits.size() - offset;
if (data.bits[i] == RTLIL::S1)
val |= 1 << (i - offset);
}
- f << stringf("32'%sd%d", set_signed ? "s" : "", val);
+ f << stringf("32'%sd %d", set_signed ? "s" : "", val);
} else {
dump_bits:
f << stringf("%d'%sb", width, set_signed ? "s" : "");
f << stringf("\\\"");
else if (str[i] == '\\')
f << stringf("\\\\");
+ else if (str[i] == '/' && escape_comment && i > 0 && str[i-1] == '*')
+ f << stringf("\\/");
else
f << str[i];
}
dump_sigchunk(f, sig.as_chunk());
} else {
f << stringf("{ ");
- for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); it++) {
+ for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); ++it) {
if (it != sig.chunks().rbegin())
f << stringf(", ");
dump_sigchunk(f, *it, true);
}
}
-void dump_attributes(std::ostream &f, std::string indent, std::map<RTLIL::IdString, RTLIL::Const> &attributes, char term = '\n')
+void dump_attributes(std::ostream &f, std::string indent, dict<RTLIL::IdString, RTLIL::Const> &attributes, char term = '\n', bool modattr = false)
{
if (noattr)
return;
- for (auto it = attributes.begin(); it != attributes.end(); it++) {
+ for (auto it = attributes.begin(); it != attributes.end(); ++it) {
f << stringf("%s" "%s %s", indent.c_str(), attr2comment ? "/*" : "(*", id(it->first).c_str());
f << stringf(" = ");
- dump_const(f, it->second);
+ if (modattr && (it->second == Const(0, 1) || it->second == Const(0)))
+ f << stringf(" 0 ");
+ else if (modattr && (it->second == Const(1, 1) || it->second == Const(1)))
+ f << stringf(" 1 ");
+ else
+ dump_const(f, it->second, -1, 0, false, false, attr2comment);
f << stringf(" %s%c", attr2comment ? "*/" : "*)", term);
}
}
f << stringf("%s" "output%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str());
if (wire->port_input && wire->port_output)
f << stringf("%s" "inout%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str());
- if (reg_wires.count(wire->name))
+ if (reg_wires.count(wire->name)) {
f << stringf("%s" "reg%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str());
- else if (!wire->port_input && !wire->port_output)
+ if (wire->attributes.count("\\init")) {
+ f << stringf("%s" "initial %s = ", indent.c_str(), id(wire->name).c_str());
+ dump_const(f, wire->attributes.at("\\init"));
+ f << stringf(";\n");
+ }
+ } else if (!wire->port_input && !wire->port_output)
f << stringf("%s" "wire%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str());
#endif
}
if (!norename && cell->name[0] == '$' && reg_ct.count(cell->type) && cell->hasPort("\\Q"))
{
RTLIL::SigSpec sig = cell->getPort("\\Q");
- if (SIZE(sig) != 1 || sig.is_fully_const())
+ if (GetSize(sig) != 1 || sig.is_fully_const())
goto no_special_reg_name;
RTLIL::Wire *wire = sig[0].wire;
return true;
}
- if (cell->type == "$dff" || cell->type == "$adff")
+ if (cell->type == "$dffsr")
+ {
+ SigSpec sig_clk = cell->getPort("\\CLK");
+ SigSpec sig_set = cell->getPort("\\SET");
+ SigSpec sig_clr = cell->getPort("\\CLR");
+ SigSpec sig_d = cell->getPort("\\D");
+ SigSpec sig_q = cell->getPort("\\Q");
+
+ int width = cell->parameters["\\WIDTH"].as_int();
+ bool pol_clk = cell->parameters["\\CLK_POLARITY"].as_bool();
+ bool pol_set = cell->parameters["\\SET_POLARITY"].as_bool();
+ bool pol_clr = cell->parameters["\\CLR_POLARITY"].as_bool();
+
+ std::string reg_name = cellname(cell);
+ bool out_is_reg_wire = is_reg_wire(sig_q, reg_name);
+
+ if (!out_is_reg_wire)
+ f << stringf("%s" "reg [%d:0] %s;\n", indent.c_str(), width-1, reg_name.c_str());
+
+ for (int i = 0; i < width; i++) {
+ f << stringf("%s" "always @(%sedge ", indent.c_str(), pol_clk ? "pos" : "neg");
+ dump_sigspec(f, sig_clk);
+ f << stringf(", %sedge ", pol_set ? "pos" : "neg");
+ dump_sigspec(f, sig_set);
+ f << stringf(", %sedge ", pol_clr ? "pos" : "neg");
+ dump_sigspec(f, sig_clr);
+ f << stringf(")\n");
+
+ f << stringf("%s" " if (%s", indent.c_str(), pol_clr ? "" : "!");
+ dump_sigspec(f, sig_clr);
+ f << stringf(") %s[%d] <= 1'b0;\n", reg_name.c_str(), i);
+
+ f << stringf("%s" " else if (%s", indent.c_str(), pol_set ? "" : "!");
+ dump_sigspec(f, sig_set);
+ f << stringf(") %s[%d] <= 1'b1;\n", reg_name.c_str(), i);
+
+ f << stringf("%s" " else %s[%d] <= ", indent.c_str(), reg_name.c_str(), i);
+ dump_sigspec(f, sig_d[i]);
+ f << stringf(";\n");
+ }
+
+ if (!out_is_reg_wire) {
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, sig_q);
+ f << stringf(" = %s;\n", reg_name.c_str());
+ }
+
+ return true;
+ }
+
+ if (cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffe")
{
- RTLIL::SigSpec sig_clk, sig_arst, val_arst;
- bool pol_clk, pol_arst = false;
+ RTLIL::SigSpec sig_clk, sig_arst, sig_en, val_arst;
+ bool pol_clk, pol_arst = false, pol_en = false;
sig_clk = cell->getPort("\\CLK");
pol_clk = cell->parameters["\\CLK_POLARITY"].as_bool();
val_arst = RTLIL::SigSpec(cell->parameters["\\ARST_VALUE"]);
}
+ if (cell->type == "$dffe") {
+ sig_en = cell->getPort("\\EN");
+ pol_en = cell->parameters["\\EN_POLARITY"].as_bool();
+ }
+
std::string reg_name = cellname(cell);
bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name);
f << stringf("%s" " else\n", indent.c_str());
}
+ if (cell->type == "$dffe") {
+ f << stringf("%s" " if (%s", indent.c_str(), pol_en ? "" : "!");
+ dump_sigspec(f, sig_en);
+ f << stringf(")\n");
+ }
+
f << stringf("%s" " %s <= ", indent.c_str(), reg_name.c_str());
dump_cell_expr_port(f, cell, "D", false);
f << stringf(";\n");
return true;
}
+ if (cell->type == "$mem" && nomem == false)
+ {
+ RTLIL::IdString memid = cell->parameters["\\MEMID"].decode_string();
+ std::string mem_id = id(cell->parameters["\\MEMID"].decode_string());
+ int abits = cell->parameters["\\ABITS"].as_int();
+ int size = cell->parameters["\\SIZE"].as_int();
+ int width = cell->parameters["\\WIDTH"].as_int();
+ bool use_init = !(RTLIL::SigSpec(cell->parameters["\\INIT"]).is_fully_undef());
+
+ // for memory block make something like:
+ // reg [7:0] memid [3:0];
+ // initial begin
+ // memid[0] <= ...
+ // end
+ int mem_val;
+ f << stringf("%s" "reg [%d:%d] %s [%d:%d];\n", indent.c_str(), width-1, 0, mem_id.c_str(), size-1, 0);
+ if (use_init)
+ {
+ f << stringf("%s" "initial begin\n", indent.c_str());
+ for (int i=0; i<size; i++)
+ {
+ mem_val = cell->parameters["\\INIT"].extract(i*width, width).as_int();
+ f << stringf("%s" " %s[%d] <= %d'd%d;\n", indent.c_str(), mem_id.c_str(), i, width, mem_val);
+ }
+ f << stringf("%s" "end\n", indent.c_str());
+ }
+
+ int nread_ports = cell->parameters["\\RD_PORTS"].as_int();
+ RTLIL::SigSpec sig_rd_clk, sig_rd_data, sig_rd_addr;
+ bool use_rd_clk, rd_clk_posedge, rd_transparent;
+ // read ports
+ for (int i=0; i < nread_ports; i++)
+ {
+ sig_rd_clk = cell->getPort("\\RD_CLK").extract(i);
+ sig_rd_data = cell->getPort("\\RD_DATA").extract(i*width, width);
+ sig_rd_addr = cell->getPort("\\RD_ADDR").extract(i*abits, abits);
+ use_rd_clk = cell->parameters["\\RD_CLK_ENABLE"].extract(i).as_bool();
+ rd_clk_posedge = cell->parameters["\\RD_CLK_POLARITY"].extract(i).as_bool();
+ rd_transparent = cell->parameters["\\RD_TRANSPARENT"].extract(i).as_bool();
+ if (use_rd_clk && !rd_transparent)
+ {
+ // for clocked read ports make something like:
+ // reg [..] temp_id;
+ // always @(posedge clk)
+ // temp_id <= array_reg[r_addr];
+ // assign r_data = temp_id;
+ std::string temp_id = next_auto_id();
+ f << stringf("%s" "reg [%d:0] %s;\n", indent.c_str(), sig_rd_data.size() - 1, temp_id.c_str());
+ f << stringf("%s" "always @(%sedge ", indent.c_str(), rd_clk_posedge ? "pos" : "neg");
+ dump_sigspec(f, sig_rd_clk);
+ f << stringf(")\n");
+ f << stringf("%s" " %s <= %s[", indent.c_str(), temp_id.c_str(), mem_id.c_str());
+ dump_sigspec(f, sig_rd_addr);
+ f << stringf("];\n");
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, sig_rd_data);
+ f << stringf(" = %s;\n", temp_id.c_str());
+ } else {
+ if (rd_transparent) {
+ // for rd-transparent read-ports make something like:
+ // reg [..] temp_id;
+ // always @(posedge clk)
+ // temp_id <= r_addr;
+ // assign r_data = array_reg[temp_id];
+ std::string temp_id = next_auto_id();
+ f << stringf("%s" "reg [%d:0] %s;\n", indent.c_str(), sig_rd_addr.size() - 1, temp_id.c_str());
+ f << stringf("%s" "always @(%sedge ", indent.c_str(), rd_clk_posedge ? "pos" : "neg");
+ dump_sigspec(f, sig_rd_clk);
+ f << stringf(")\n");
+ f << stringf("%s" " %s <= ", indent.c_str(), temp_id.c_str());
+ dump_sigspec(f, sig_rd_addr);
+ f << stringf(";\n");
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, sig_rd_data);
+ f << stringf(" = %s[%s];\n", mem_id.c_str(), temp_id.c_str());
+ } else {
+ // for non-clocked read-ports make something like:
+ // assign r_data = array_reg[r_addr];
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, sig_rd_data);
+ f << stringf(" = %s[", mem_id.c_str());
+ dump_sigspec(f, sig_rd_addr);
+ f << stringf("];\n");
+ }
+ }
+ }
+
+ int nwrite_ports = cell->parameters["\\WR_PORTS"].as_int();
+ RTLIL::SigSpec sig_wr_clk, sig_wr_data, sig_wr_addr, sig_wr_en, sig_wr_en_bit;
+ RTLIL::SigBit last_bit;
+ bool wr_clk_posedge;
+ RTLIL::SigSpec lof_wen;
+ dict<RTLIL::SigSpec, int> wen_to_width;
+ SigMap sigmap(active_module);
+ int n, wen_width;
+ // write ports
+ for (int i=0; i < nwrite_ports; i++)
+ {
+ // for write-ports make something like:
+ // always @(posedge clk)
+ // if (wr_en)
+ // memid[w_addr] <= w_data;
+ sig_wr_clk = cell->getPort("\\WR_CLK").extract(i);
+ sig_wr_data = cell->getPort("\\WR_DATA").extract(i*width, width);
+ sig_wr_addr = cell->getPort("\\WR_ADDR").extract(i*abits, abits);
+ sig_wr_en = cell->getPort("\\WR_EN").extract(i*width, width);
+ sig_wr_en_bit = sig_wr_en.extract(0);
+ wr_clk_posedge = cell->parameters["\\WR_CLK_POLARITY"].extract(i).as_bool();
+ // group the wen bits
+ last_bit = sig_wr_en.extract(0);
+ lof_wen = RTLIL::SigSpec(last_bit);
+ wen_to_width.clear();
+ wen_to_width[last_bit] = 0;
+ for (auto ¤t_bit : sig_wr_en.bits())
+ {
+ if (sigmap(current_bit) == sigmap(last_bit)){
+ wen_to_width[current_bit] += 1;
+ } else {
+ lof_wen.append_bit(current_bit);
+ wen_to_width[current_bit] = 1;
+ }
+ last_bit = current_bit;
+ }
+ // make something like:
+ // always @(posedge clk)
+ // if (wr_en_bit)
+ // memid[w_addr][??] <= w_data[??];
+ // ...
+ n = 0;
+ for (auto &wen_bit : lof_wen) {
+ wen_width = wen_to_width[wen_bit];
+ if (!(wen_bit == RTLIL::SigBit(false)))
+ {
+ f << stringf("%s" "always @(%sedge ", indent.c_str(), wr_clk_posedge ? "pos" : "neg");
+ dump_sigspec(f, sig_wr_clk);
+ f << stringf(")\n");
+ if (!(wen_bit == RTLIL::SigBit(true)))
+ {
+ f << stringf("%s" " if (", indent.c_str());
+ dump_sigspec(f, wen_bit);
+ f << stringf(")\n ");
+ }
+ f << stringf("%s" " %s[", indent.c_str(), mem_id.c_str());
+ dump_sigspec(f, sig_wr_addr);
+ if (wen_width == width)
+ f << stringf("] <= ");
+ else
+ f << stringf("][%d:%d] <= ", n+wen_width-1, n);
+ dump_sigspec(f, sig_wr_data.extract(n, wen_width));
+ f << stringf(";\n");
+ }
+ n += wen_width;
+ }
+ }
+
+ return true;
+ }
+
// FIXME: $_SR_[PN][PN]_, $_DLATCH_[PN]_, $_DLATCHSR_[PN][PN][PN]_
- // FIXME: $sr, $dffsr, $dlatch, $memrd, $memwr, $mem, $fsm
+ // FIXME: $sr, $dlatch, $memrd, $memwr, $fsm
return false;
}
if (cell->parameters.size() > 0) {
f << stringf(" #(");
- for (auto it = cell->parameters.begin(); it != cell->parameters.end(); it++) {
+ for (auto it = cell->parameters.begin(); it != cell->parameters.end(); ++it) {
if (it != cell->parameters.begin())
f << stringf(",");
f << stringf("\n%s .%s(", indent.c_str(), id(it->first).c_str());
bool is_signed = (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0;
- dump_const(f, it->second, -1, 0, !is_signed, is_signed);
+ dump_const(f, it->second, -1, 0, false, is_signed);
f << stringf(")");
}
f << stringf("\n%s" ")", indent.c_str());
for (int i = 1; true; i++) {
char str[16];
snprintf(str, 16, "$%d", i);
- for (auto it = cell->connections().begin(); it != cell->connections().end(); it++) {
+ for (auto it = cell->connections().begin(); it != cell->connections().end(); ++it) {
if (it->first != str)
continue;
if (!first_arg)
break;
found_numbered_port:;
}
- for (auto it = cell->connections().begin(); it != cell->connections().end(); it++) {
+ for (auto it = cell->connections().begin(); it != cell->connections().end(); ++it) {
if (numbered_ports.count(it->first))
continue;
if (!first_arg)
if (!omit_trailing_begin && number_of_stmts >= 2)
f << stringf("%s" "begin\n", indent.c_str());
- for (auto it = cs->actions.begin(); it != cs->actions.end(); it++) {
+ for (auto it = cs->actions.begin(); it != cs->actions.end(); ++it) {
if (it->first.size() == 0)
continue;
f << stringf("%s ", indent.c_str());
f << stringf(";\n");
}
- for (auto it = cs->switches.begin(); it != cs->switches.end(); it++)
+ for (auto it = cs->switches.begin(); it != cs->switches.end(); ++it)
dump_proc_switch(f, indent + " ", *it);
if (!omit_trailing_begin && number_of_stmts == 0)
{
if (sw->signal.size() == 0) {
f << stringf("%s" "begin\n", indent.c_str());
- for (auto it = sw->cases.begin(); it != sw->cases.end(); it++) {
+ for (auto it = sw->cases.begin(); it != sw->cases.end(); ++it) {
if ((*it)->compare.size() == 0)
dump_case_body(f, indent + " ", *it);
}
dump_sigspec(f, sw->signal);
f << stringf(")\n");
- for (auto it = sw->cases.begin(); it != sw->cases.end(); it++) {
+ for (auto it = sw->cases.begin(); it != sw->cases.end(); ++it) {
f << stringf("%s ", indent.c_str());
if ((*it)->compare.size() == 0)
f << stringf("default");
void case_body_find_regs(RTLIL::CaseRule *cs)
{
- for (auto it = cs->switches.begin(); it != cs->switches.end(); it++)
+ for (auto it = cs->switches.begin(); it != cs->switches.end(); ++it)
for (auto it2 = (*it)->cases.begin(); it2 != (*it)->cases.end(); it2++)
case_body_find_regs(*it2);
- for (auto it = cs->actions.begin(); it != cs->actions.end(); it++) {
+ for (auto it = cs->actions.begin(); it != cs->actions.end(); ++it) {
for (auto &c : it->first.chunks())
if (c.wire != NULL)
reg_wires.insert(c.wire->name);
{
if (find_regs) {
case_body_find_regs(&proc->root_case);
- for (auto it = proc->syncs.begin(); it != proc->syncs.end(); it++)
+ for (auto it = proc->syncs.begin(); it != proc->syncs.end(); ++it)
for (auto it2 = (*it)->actions.begin(); it2 != (*it)->actions.end(); it2++) {
for (auto &c : it2->first.chunks())
if (c.wire != NULL)
}
}
- for (auto it = sync->actions.begin(); it != sync->actions.end(); it++) {
+ for (auto it = sync->actions.begin(); it != sync->actions.end(); ++it) {
if (it->first.size() == 0)
continue;
f << stringf("%s ", indent.c_str());
active_module = module;
f << stringf("\n");
- for (auto it = module->processes.begin(); it != module->processes.end(); it++)
+ for (auto it = module->processes.begin(); it != module->processes.end(); ++it)
dump_process(f, indent + " ", it->second, true);
if (!noexpr)
}
}
- dump_attributes(f, indent, module->attributes);
+ dump_attributes(f, indent, module->attributes, '\n', true);
f << stringf("%s" "module %s(", indent.c_str(), id(module->name, false).c_str());
bool keep_running = true;
for (int port_id = 1; keep_running; port_id++) {
keep_running = false;
- for (auto it = module->wires_.begin(); it != module->wires_.end(); it++) {
+ for (auto it = module->wires_.begin(); it != module->wires_.end(); ++it) {
RTLIL::Wire *wire = it->second;
if (wire->port_id == port_id) {
if (port_id != 1)
}
f << stringf(");\n");
- for (auto it = module->wires_.begin(); it != module->wires_.end(); it++)
+ for (auto it = module->wires_.begin(); it != module->wires_.end(); ++it)
dump_wire(f, indent + " ", it->second);
- for (auto it = module->memories.begin(); it != module->memories.end(); it++)
+ for (auto it = module->memories.begin(); it != module->memories.end(); ++it)
dump_memory(f, indent + " ", it->second);
- for (auto it = module->cells_.begin(); it != module->cells_.end(); it++)
+ for (auto it = module->cells_.begin(); it != module->cells_.end(); ++it)
dump_cell(f, indent + " ", it->second);
- for (auto it = module->processes.begin(); it != module->processes.end(); it++)
+ for (auto it = module->processes.begin(); it != module->processes.end(); ++it)
dump_process(f, indent + " ", it->second);
- for (auto it = module->connections().begin(); it != module->connections().end(); it++)
+ for (auto it = module->connections().begin(); it != module->connections().end(); ++it)
dump_conn(f, indent + " ", it->first, it->second);
f << stringf("%s" "endmodule\n", indent.c_str());
log(" only write selected modules. modules must be selected entirely or\n");
log(" not at all.\n");
log("\n");
+ log(" -nomem\n");
+ log(" do not create verilog code for $mem cells. This is only used for\n");
+ log(" testing.\n");
+ log("\n");
}
virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
{
noattr = false;
attr2comment = false;
noexpr = false;
+ nomem = false;
bool blackboxes = false;
bool selected = false;
selected = true;
continue;
}
+ if (arg == "-nomem") {
+ nomem = true;
+ continue;
+ }
break;
}
extra_args(f, filename, args, argidx);
+ design->sort();
+
*f << stringf("/* Generated by %s */\n", yosys_version_str);
- for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) {
+ for (auto it = design->modules_.begin(); it != design->modules_.end(); ++it) {
if (it->second->get_bool_attribute("\\blackbox") != blackboxes)
continue;
if (selected && !design->selected_whole_module(it->first)) {