summaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
authorAhmed Irfan <ahmedirfan1983@gmail.com>2014-09-22 11:35:04 +0200
committerAhmed Irfan <ahmedirfan1983@gmail.com>2014-09-22 11:35:04 +0200
commitd3c67ad9b61f602de1100cd264efd227dcacb417 (patch)
tree88c462c53bdab128cd1edbded42483772f82612a /backends
parentb783dbe148e6d246ebd107c0913de2989ab5af48 (diff)
parent13117bb346dd02d2345f716b4403239aebe3d0e2 (diff)
Merge branch 'master' of https://github.com/cliffordwolf/yosys into btor
added case for memwr cell that is used in muxes (same cell is used more than one time) corrected bug for xnor and logic_not added pmux cell translation Conflicts: backends/btor/btor.cc
Diffstat (limited to 'backends')
-rw-r--r--backends/autotest/Makefile.inc3
-rw-r--r--backends/autotest/autotest.cc336
-rw-r--r--backends/blif/blif.cc221
-rw-r--r--backends/btor/btor.cc394
-rwxr-xr-xbackends/btor/verilog2btor.sh4
-rw-r--r--backends/edif/edif.cc216
-rw-r--r--backends/ilang/ilang_backend.cc329
-rw-r--r--backends/ilang/ilang_backend.h32
-rw-r--r--backends/intersynth/intersynth.cc61
-rw-r--r--backends/spice/spice.cc93
-rw-r--r--backends/verilog/verilog_backend.cc729
-rw-r--r--backends/verilog/verilog_backend.h5
12 files changed, 1139 insertions, 1284 deletions
diff --git a/backends/autotest/Makefile.inc b/backends/autotest/Makefile.inc
deleted file mode 100644
index 9308dcd4..00000000
--- a/backends/autotest/Makefile.inc
+++ /dev/null
@@ -1,3 +0,0 @@
-
-OBJS += backends/autotest/autotest.o
-
diff --git a/backends/autotest/autotest.cc b/backends/autotest/autotest.cc
deleted file mode 100644
index 3e2fab00..00000000
--- a/backends/autotest/autotest.cc
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * yosys -- Yosys Open SYnthesis Suite
- *
- * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-#include "kernel/register.h"
-#include "kernel/log.h"
-#include <stdlib.h>
-#include <stdio.h>
-
-#define NUM_ITER 1000
-
-static std::string id(std::string internal_id)
-{
- const char *str = internal_id.c_str();
- bool do_escape = false;
-
- if (*str == '\\')
- str++;
-
- if ('0' <= *str && *str <= '9')
- do_escape = true;
-
- for (int i = 0; str[i]; i++) {
- if ('0' <= str[i] && str[i] <= '9')
- continue;
- if ('a' <= str[i] && str[i] <= 'z')
- continue;
- if ('A' <= str[i] && str[i] <= 'Z')
- continue;
- if (str[i] == '_')
- continue;
- do_escape = true;
- break;
- }
-
- if (do_escape)
- return "\\" + std::string(str) + " ";
- return std::string(str);
-}
-
-static std::string idx(std::string str)
-{
- if (str[0] == '\\')
- return str.substr(1);
- return str;
-}
-
-static std::string idy(std::string str1, std::string str2 = std::string(), std::string str3 = std::string())
-{
- str1 = idx(str1);
- if (!str2.empty())
- str1 += "_" + idx(str2);
- if (!str3.empty())
- str1 += "_" + idx(str3);
- return id(str1);
-}
-
-static void autotest(FILE *f, RTLIL::Design *design)
-{
- fprintf(f, "module testbench;\n\n");
-
- fprintf(f, "integer i;\n\n");
-
- fprintf(f, "reg [31:0] xorshift128_x = 123456789;\n");
- fprintf(f, "reg [31:0] xorshift128_y = 362436069;\n");
- fprintf(f, "reg [31:0] xorshift128_z = 521288629;\n");
- fprintf(f, "reg [31:0] xorshift128_w = 88675123;\n");
- fprintf(f, "reg [31:0] xorshift128_t;\n\n");
- fprintf(f, "task xorshift128;\n");
- fprintf(f, "begin\n");
- fprintf(f, "\txorshift128_t = xorshift128_x ^ (xorshift128_x << 11);\n");
- fprintf(f, "\txorshift128_x = xorshift128_y;\n");
- fprintf(f, "\txorshift128_y = xorshift128_z;\n");
- fprintf(f, "\txorshift128_z = xorshift128_w;\n");
- fprintf(f, "\txorshift128_w = xorshift128_w ^ (xorshift128_w >> 19) ^ xorshift128_t ^ (xorshift128_t >> 8);\n");
- fprintf(f, "end\n");
- fprintf(f, "endtask\n\n");
-
- for (auto it = design->modules.begin(); it != design->modules.end(); it++)
- {
- std::map<std::string, int> signal_in;
- std::map<std::string, std::string> signal_const;
- std::map<std::string, int> signal_clk;
- std::map<std::string, int> signal_out;
-
- RTLIL::Module *mod = it->second;
-
- if (mod->get_bool_attribute("\\gentb_skip"))
- continue;
-
- int count_ports = 0;
- log("Generating test bench for module `%s'.\n", it->first.c_str());
- for (auto it2 = mod->wires.begin(); it2 != mod->wires.end(); it2++) {
- RTLIL::Wire *wire = it2->second;
- if (wire->port_output) {
- count_ports++;
- signal_out[idy("sig", mod->name, wire->name)] = wire->width;
- fprintf(f, "wire [%d:0] %s;\n", wire->width-1, idy("sig", mod->name, wire->name).c_str());
- } else if (wire->port_input) {
- count_ports++;
- bool is_clksignal = wire->get_bool_attribute("\\gentb_clock");
- for (auto it3 = mod->processes.begin(); it3 != mod->processes.end(); it3++)
- for (auto it4 = it3->second->syncs.begin(); it4 != it3->second->syncs.end(); it4++) {
- if ((*it4)->type == RTLIL::ST0 || (*it4)->type == RTLIL::ST1)
- continue;
- RTLIL::SigSpec &signal = (*it4)->signal;
- for (size_t i = 0; i < signal.chunks.size(); i++) {
- if (signal.chunks[i].wire == wire)
- is_clksignal = true;
- }
- }
- if (is_clksignal && wire->attributes.count("\\gentb_constant") == 0) {
- signal_clk[idy("sig", mod->name, wire->name)] = wire->width;
- } else {
- signal_in[idy("sig", mod->name, wire->name)] = wire->width;
- if (wire->attributes.count("\\gentb_constant") != 0)
- signal_const[idy("sig", mod->name, wire->name)] = wire->attributes["\\gentb_constant"].as_string();
- }
- fprintf(f, "reg [%d:0] %s;\n", wire->width-1, idy("sig", mod->name, wire->name).c_str());
- }
- }
- fprintf(f, "%s %s(\n", id(mod->name).c_str(), idy("uut", mod->name).c_str());
- for (auto it2 = mod->wires.begin(); it2 != mod->wires.end(); it2++) {
- RTLIL::Wire *wire = it2->second;
- if (wire->port_output || wire->port_input)
- fprintf(f, "\t.%s(%s)%s\n", id(wire->name).c_str(),
- idy("sig", mod->name, wire->name).c_str(), --count_ports ? "," : "");
- }
- fprintf(f, ");\n\n");
-
- fprintf(f, "task %s;\n", idy(mod->name, "reset").c_str());
- fprintf(f, "begin\n");
- int delay_counter = 0;
- for (auto it = signal_in.begin(); it != signal_in.end(); it++)
- fprintf(f, "\t%s <= #%d 0;\n", it->first.c_str(), ++delay_counter*2);
- for (auto it = signal_clk.begin(); it != signal_clk.end(); it++)
- fprintf(f, "\t%s <= #%d 0;\n", it->first.c_str(), ++delay_counter*2);
- for (auto it = signal_clk.begin(); it != signal_clk.end(); it++) {
- fprintf(f, "\t#100; %s <= 1;\n", it->first.c_str());
- fprintf(f, "\t#100; %s <= 0;\n", it->first.c_str());
- }
- delay_counter = 0;
- for (auto it = signal_in.begin(); it != signal_in.end(); it++)
- fprintf(f, "\t%s <= #%d ~0;\n", it->first.c_str(), ++delay_counter*2);
- for (auto it = signal_clk.begin(); it != signal_clk.end(); it++) {
- fprintf(f, "\t#100; %s <= 1;\n", it->first.c_str());
- fprintf(f, "\t#100; %s <= 0;\n", it->first.c_str());
- }
- delay_counter = 0;
- for (auto it = signal_in.begin(); it != signal_in.end(); it++) {
- if (signal_const.count(it->first) == 0)
- continue;
- fprintf(f, "\t%s <= #%d 'b%s;\n", it->first.c_str(), ++delay_counter*2, signal_const[it->first].c_str());
- }
- fprintf(f, "end\n");
- fprintf(f, "endtask\n\n");
-
- fprintf(f, "task %s;\n", idy(mod->name, "update_data").c_str());
- fprintf(f, "begin\n");
- delay_counter = 0;
- for (auto it = signal_in.begin(); it != signal_in.end(); it++) {
- if (signal_const.count(it->first) > 0)
- continue;
- fprintf(f, "\txorshift128;\n");
- fprintf(f, "\t%s <= #%d { xorshift128_x, xorshift128_y, xorshift128_z, xorshift128_w };\n", it->first.c_str(), ++delay_counter*2);
- }
- fprintf(f, "end\n");
- fprintf(f, "endtask\n\n");
-
- fprintf(f, "task %s;\n", idy(mod->name, "update_clock").c_str());
- fprintf(f, "begin\n");
- if (signal_clk.size()) {
- fprintf(f, "\txorshift128;\n");
- fprintf(f, "\t{");
- int total_clock_bits = 0;
- for (auto it = signal_clk.begin(); it != signal_clk.end(); it++) {
- fprintf(f, "%s %s", it == signal_clk.begin() ? "" : ",", it->first.c_str());
- total_clock_bits += it->second;
- }
- fprintf(f, " } = {");
- for (auto it = signal_clk.begin(); it != signal_clk.end(); it++)
- fprintf(f, "%s %s", it == signal_clk.begin() ? "" : ",", it->first.c_str());
- fprintf(f, " } ^ (%d'b1 << (xorshift128_w %% %d));\n", total_clock_bits, total_clock_bits);
- }
- fprintf(f, "end\n");
- fprintf(f, "endtask\n\n");
-
- char shorthand = 'A';
- std::vector<std::string> header1;
- std::string header2 = "";
-
- fprintf(f, "task %s;\n", idy(mod->name, "print_status").c_str());
- fprintf(f, "begin\n");
- fprintf(f, "\t$display(\"#OUT# %%b %%b %%b %%t %%d\", {");
- if (signal_in.size())
- for (auto it = signal_in.begin(); it != signal_in.end(); it++) {
- fprintf(f, "%s %s", it == signal_in.begin() ? "" : ",", it->first.c_str());
- int len = it->second;
- if (len > 1)
- header2 += "/", len--;
- while (len > 1)
- header2 += "-", len--;
- if (len > 0)
- header2 += shorthand, len--;
- header1.push_back(" " + it->first);
- header1.back()[0] = shorthand++;
- }
- else {
- fprintf(f, " 1'bx");
- header2 += "#";
- }
- fprintf(f, " }, {");
- header2 += " ";
- if (signal_clk.size()) {
- for (auto it = signal_clk.begin(); it != signal_clk.end(); it++) {
- fprintf(f, "%s %s", it == signal_clk.begin() ? "" : ",", it->first.c_str());
- int len = it->second;
- if (len > 1)
- header2 += "/", len--;
- while (len > 1)
- header2 += "-", len--;
- if (len > 0)
- header2 += shorthand, len--;
- header1.push_back(" " + it->first);
- header1.back()[0] = shorthand++;
- }
- } else {
- fprintf(f, " 1'bx");
- header2 += "#";
- }
- fprintf(f, " }, {");
- header2 += " ";
- if (signal_out.size()) {
- for (auto it = signal_out.begin(); it != signal_out.end(); it++) {
- fprintf(f, "%s %s", it == signal_out.begin() ? "" : ",", it->first.c_str());
- int len = it->second;
- if (len > 1)
- header2 += "/", len--;
- while (len > 1)
- header2 += "-", len--;
- if (len > 0)
- header2 += shorthand, len--;
- header1.push_back(" " + it->first);
- header1.back()[0] = shorthand++;
- }
- } else {
- fprintf(f, " 1'bx");
- header2 += "#";
- }
- fprintf(f, " }, $time, i);\n");
- fprintf(f, "end\n");
- fprintf(f, "endtask\n\n");
-
- fprintf(f, "task %s;\n", idy(mod->name, "print_header").c_str());
- fprintf(f, "begin\n");
- fprintf(f, "\t$display(\"#OUT#\");\n");
- for (auto &hdr : header1)
- fprintf(f, "\t$display(\"#OUT# %s\");\n", hdr.c_str());
- fprintf(f, "\t$display(\"#OUT#\");\n");
- fprintf(f, "\t$display(\"#OUT# %s\");\n", header2.c_str());
- fprintf(f, "end\n");
- fprintf(f, "endtask\n\n");
-
- fprintf(f, "task %s;\n", idy(mod->name, "test").c_str());
- fprintf(f, "begin\n");
- fprintf(f, "\t$display(\"#OUT#\\n#OUT# ==== %s ====\");\n", idy(mod->name).c_str());
- fprintf(f, "\t%s;\n", idy(mod->name, "reset").c_str());
- fprintf(f, "\tfor (i=0; i<%d; i=i+1) begin\n", NUM_ITER);
- fprintf(f, "\t\tif (i %% 20 == 0) %s;\n", idy(mod->name, "print_header").c_str());
- fprintf(f, "\t\t#100; %s;\n", idy(mod->name, "update_data").c_str());
- fprintf(f, "\t\t#100; %s;\n", idy(mod->name, "update_clock").c_str());
- fprintf(f, "\t\t#100; %s;\n", idy(mod->name, "print_status").c_str());
- fprintf(f, "\tend\n");
- fprintf(f, "end\n");
- fprintf(f, "endtask\n\n");
- }
-
- fprintf(f, "initial begin\n");
- fprintf(f, "\t// $dumpfile(\"testbench.vcd\");\n");
- fprintf(f, "\t// $dumpvars(0, testbench);\n");
- for (auto it = design->modules.begin(); it != design->modules.end(); it++)
- if (!it->second->get_bool_attribute("\\gentb_skip"))
- fprintf(f, "\t%s;\n", idy(it->first, "test").c_str());
- fprintf(f, "\t$finish;\n");
- fprintf(f, "end\n\n");
-
- fprintf(f, "endmodule\n");
-}
-
-struct AutotestBackend : public Backend {
- AutotestBackend() : Backend("autotest", "generate simple test benches") { }
- virtual void help()
- {
- // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
- log("\n");
- log(" write_autotest [filename]\n");
- log("\n");
- log("Automatically create primitive verilog test benches for all modules in the\n");
- log("design. The generated testbenches toggle the input pins of the module in\n");
- log("a semi-random manner and dumps the resulting output signals.\n");
- log("\n");
- log("This can be used to check the synthesis results for simple circuits by\n");
- log("comparing the testbench output for the input files and the synthesis results.\n");
- log("\n");
- log("The backend automatically detects clock signals. Additionally a signal can\n");
- log("be forced to be interpreted as clock signal by setting the attribute\n");
- log("'gentb_clock' on the signal.\n");
- log("\n");
- log("The attribute 'gentb_constant' can be used to force a signal to a constant\n");
- log("value after initialization. This can e.g. be used to force a reset signal\n");
- log("low in order to explore more inner states in a state machine.\n");
- log("\n");
- }
- virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
- {
- log_header("Executing AUTOTEST backend (auto-generate pseudo-random test benches).\n");
- extra_args(f, filename, args, 1);
- autotest(f, design);
- }
-} AutotestBackend;
-
diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc
index f5a98276..ee12546c 100644
--- a/backends/blif/blif.cc
+++ b/backends/blif/blif.cc
@@ -27,29 +27,30 @@
#include "kernel/celltypes.h"
#include "kernel/log.h"
#include <string>
-#include <assert.h>
struct BlifDumperConfig
{
- bool subckt_mode;
+ bool icells_mode;
bool conn_mode;
bool impltf_mode;
+ bool gates_mode;
+ bool param_mode;
std::string buf_type, buf_in, buf_out;
std::string true_type, true_out, false_type, false_out;
- BlifDumperConfig() : subckt_mode(false), conn_mode(false), impltf_mode(false) { }
+ BlifDumperConfig() : icells_mode(false), conn_mode(false), impltf_mode(false), gates_mode(false), param_mode(false) { }
};
struct BlifDumper
{
- FILE *f;
+ std::ostream &f;
RTLIL::Module *module;
RTLIL::Design *design;
BlifDumperConfig *config;
CellTypes ct;
- BlifDumper(FILE *f, RTLIL::Module *module, RTLIL::Design *design, BlifDumperConfig *config) :
+ BlifDumper(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, BlifDumperConfig *config) :
f(f), module(module), design(design), config(config), ct(design)
{
}
@@ -66,34 +67,42 @@ struct BlifDumper
return cstr_buf.back().c_str();
}
- const char *cstr(RTLIL::SigSpec sig)
+ const char *cstr(RTLIL::SigBit sig)
{
- sig.optimize();
- log_assert(sig.width == 1);
+ if (sig.wire == NULL)
+ return sig == RTLIL::State::S1 ? "$true" : "$false";
- if (sig.chunks.at(0).wire == NULL)
- return sig.chunks.at(0).data.bits.at(0) == RTLIL::State::S1 ? "$true" : "$false";
-
- std::string str = RTLIL::unescape_id(sig.chunks.at(0).wire->name);
+ std::string str = RTLIL::unescape_id(sig.wire->name);
for (size_t i = 0; i < str.size(); i++)
if (str[i] == '#' || str[i] == '=')
str[i] = '?';
- if (sig.chunks.at(0).wire->width != 1)
- str += stringf("[%d]", sig.chunks.at(0).offset);
+ if (sig.wire->width != 1)
+ str += stringf("[%d]", sig.offset);
cstr_buf.push_back(str);
return cstr_buf.back().c_str();
}
+ const char *subckt_or_gate(std::string cell_type)
+ {
+ if (!config->gates_mode)
+ return "subckt";
+ if (!design->modules_.count(RTLIL::escape_id(cell_type)))
+ return "gate";
+ if (design->modules_.at(RTLIL::escape_id(cell_type))->get_bool_attribute("\\blackbox"))
+ return "gate";
+ return "subckt";
+ }
+
void dump()
{
- fprintf(f, "\n");
- fprintf(f, ".model %s\n", cstr(module->name));
+ f << stringf("\n");
+ f << stringf(".model %s\n", cstr(module->name));
std::map<int, RTLIL::Wire*> inputs, outputs;
- for (auto &wire_it : module->wires) {
+ for (auto &wire_it : module->wires_) {
RTLIL::Wire *wire = wire_it.second;
if (wire->port_input)
inputs[wire->port_id] = wire;
@@ -101,107 +110,150 @@ struct BlifDumper
outputs[wire->port_id] = wire;
}
- fprintf(f, ".inputs");
+ f << stringf(".inputs");
for (auto &it : inputs) {
RTLIL::Wire *wire = it.second;
for (int i = 0; i < wire->width; i++)
- fprintf(f, " %s", cstr(RTLIL::SigSpec(wire, 1, i)));
+ f << stringf(" %s", cstr(RTLIL::SigSpec(wire, i)));
}
- fprintf(f, "\n");
+ f << stringf("\n");
- fprintf(f, ".outputs");
+ f << stringf(".outputs");
for (auto &it : outputs) {
RTLIL::Wire *wire = it.second;
for (int i = 0; i < wire->width; i++)
- fprintf(f, " %s", cstr(RTLIL::SigSpec(wire, 1, i)));
+ f << stringf(" %s", cstr(RTLIL::SigSpec(wire, i)));
}
- fprintf(f, "\n");
+ f << stringf("\n");
if (!config->impltf_mode) {
if (!config->false_type.empty())
- fprintf(f, ".subckt %s %s=$false\n", config->false_type.c_str(), config->false_out.c_str());
+ f << stringf(".%s %s %s=$false\n", subckt_or_gate(config->false_type),
+ config->false_type.c_str(), config->false_out.c_str());
else
- fprintf(f, ".names $false\n");
+ f << stringf(".names $false\n");
if (!config->true_type.empty())
- fprintf(f, ".subckt %s %s=$true\n", config->true_type.c_str(), config->true_out.c_str());
+ f << stringf(".%s %s %s=$true\n", subckt_or_gate(config->true_type),
+ config->true_type.c_str(), config->true_out.c_str());
else
- fprintf(f, ".names $true\n1\n");
+ f << stringf(".names $true\n1\n");
}
- for (auto &cell_it : module->cells)
+ for (auto &cell_it : module->cells_)
{
RTLIL::Cell *cell = cell_it.second;
- if (!config->subckt_mode && cell->type == "$_INV_") {
- fprintf(f, ".names %s %s\n0 1\n",
- cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\Y")));
+ if (!config->icells_mode && cell->type == "$_NOT_") {
+ f << stringf(".names %s %s\n0 1\n",
+ cstr(cell->getPort("\\A")), cstr(cell->getPort("\\Y")));
+ continue;
+ }
+
+ if (!config->icells_mode && cell->type == "$_AND_") {
+ f << stringf(".names %s %s %s\n11 1\n",
+ cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
continue;
}
- if (!config->subckt_mode && cell->type == "$_AND_") {
- fprintf(f, ".names %s %s %s\n11 1\n",
- cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")), cstr(cell->connections.at("\\Y")));
+ if (!config->icells_mode && cell->type == "$_OR_") {
+ f << stringf(".names %s %s %s\n1- 1\n-1 1\n",
+ cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
continue;
}
- if (!config->subckt_mode && cell->type == "$_OR_") {
- fprintf(f, ".names %s %s %s\n1- 1\n-1 1\n",
- cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")), cstr(cell->connections.at("\\Y")));
+ if (!config->icells_mode && cell->type == "$_XOR_") {
+ f << stringf(".names %s %s %s\n10 1\n01 1\n",
+ cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
continue;
}
- if (!config->subckt_mode && cell->type == "$_XOR_") {
- fprintf(f, ".names %s %s %s\n10 1\n01 1\n",
- cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")), cstr(cell->connections.at("\\Y")));
+ if (!config->icells_mode && cell->type == "$_MUX_") {
+ f << stringf(".names %s %s %s %s\n1-0 1\n-11 1\n",
+ cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")),
+ cstr(cell->getPort("\\S")), cstr(cell->getPort("\\Y")));
continue;
}
- if (!config->subckt_mode && cell->type == "$_MUX_") {
- fprintf(f, ".names %s %s %s %s\n1-0 1\n-11 1\n",
- cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")),
- cstr(cell->connections.at("\\S")), cstr(cell->connections.at("\\Y")));
+ if (!config->icells_mode && cell->type == "$_DFF_N_") {
+ f << stringf(".latch %s %s fe %s\n",
+ cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")), cstr(cell->getPort("\\C")));
continue;
}
- if (!config->subckt_mode && cell->type == "$_DFF_N_") {
- fprintf(f, ".latch %s %s fe %s\n",
- cstr(cell->connections.at("\\D")), cstr(cell->connections.at("\\Q")), cstr(cell->connections.at("\\C")));
+ if (!config->icells_mode && cell->type == "$_DFF_P_") {
+ f << stringf(".latch %s %s re %s\n",
+ cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")), cstr(cell->getPort("\\C")));
continue;
}
- if (!config->subckt_mode && cell->type == "$_DFF_P_") {
- fprintf(f, ".latch %s %s re %s\n",
- cstr(cell->connections.at("\\D")), cstr(cell->connections.at("\\Q")), cstr(cell->connections.at("\\C")));
+ if (!config->icells_mode && cell->type == "$lut") {
+ f << stringf(".names");
+ auto &inputs = cell->getPort("\\A");
+ auto width = cell->parameters.at("\\WIDTH").as_int();
+ log_assert(inputs.size() == width);
+ for (int i = 0; i < inputs.size(); i++) {
+ f << stringf(" %s", cstr(inputs.extract(i, 1)));
+ }
+ auto &output = cell->getPort("\\Y");
+ log_assert(output.size() == 1);
+ f << stringf(" %s", cstr(output));
+ f << stringf("\n");
+ auto mask = cell->parameters.at("\\LUT").as_string();
+ for (int i = 0; i < (1 << width); i++) {
+ if (mask[i] == '0') continue;
+ for (int j = width-1; j >= 0; j--) {
+ f << ((i>>j)&1 ? '1' : '0');
+ }
+ f << stringf(" %c\n", mask[i]);
+ }
continue;
}
- fprintf(f, ".subckt %s", cstr(cell->type));
- for (auto &conn : cell->connections)
- for (int i = 0; i < conn.second.width; i++) {
- if (conn.second.width == 1)
- fprintf(f, " %s", cstr(conn.first));
+ f << stringf(".%s %s", subckt_or_gate(cell->type.str()), cstr(cell->type));
+ for (auto &conn : cell->connections())
+ for (int i = 0; i < conn.second.size(); i++) {
+ if (conn.second.size() == 1)
+ f << stringf(" %s", cstr(conn.first));
else
- fprintf(f, " %s[%d]", cstr(conn.first), i);
- fprintf(f, "=%s", cstr(conn.second.extract(i, 1)));
+ f << stringf(" %s[%d]", cstr(conn.first), i);
+ f << stringf("=%s", cstr(conn.second.extract(i, 1)));
}
- fprintf(f, "\n");
+ f << stringf("\n");
+
+ if (config->param_mode)
+ for (auto &param : cell->parameters) {
+ f << stringf(".param %s ", RTLIL::id2cstr(param.first));
+ if (param.second.flags & RTLIL::CONST_FLAG_STRING) {
+ std::string str = param.second.decode_string();
+ f << stringf("\"");
+ for (char ch : str)
+ if (ch == '"' || ch == '\\')
+ f << stringf("\\%c", ch);
+ else if (ch < 32 || ch >= 127)
+ f << stringf("\\%03o", ch);
+ else
+ f << stringf("%c", ch);
+ f << stringf("\"\n");
+ } else
+ f << stringf("%s\n", param.second.as_string().c_str());
+ }
}
- for (auto &conn : module->connections)
- for (int i = 0; i < conn.first.width; i++)
+ for (auto &conn : module->connections())
+ for (int i = 0; i < conn.first.size(); i++)
if (config->conn_mode)
- fprintf(f, ".conn %s %s\n", cstr(conn.second.extract(i, 1)), cstr(conn.first.extract(i, 1)));
+ f << stringf(".conn %s %s\n", cstr(conn.second.extract(i, 1)), cstr(conn.first.extract(i, 1)));
else if (!config->buf_type.empty())
- fprintf(f, ".subckt %s %s=%s %s=%s\n", config->buf_type.c_str(), config->buf_in.c_str(), cstr(conn.second.extract(i, 1)),
+ f << stringf(".%s %s %s=%s %s=%s\n", subckt_or_gate(config->buf_type), config->buf_type.c_str(), config->buf_in.c_str(), cstr(conn.second.extract(i, 1)),
config->buf_out.c_str(), cstr(conn.first.extract(i, 1)));
else
- fprintf(f, ".names %s %s\n1 1\n", cstr(conn.second.extract(i, 1)), cstr(conn.first.extract(i, 1)));
+ f << stringf(".names %s %s\n1 1\n", cstr(conn.second.extract(i, 1)), cstr(conn.first.extract(i, 1)));
- fprintf(f, ".end\n");
+ f << stringf(".end\n");
}
- static void dump(FILE *f, RTLIL::Module *module, RTLIL::Design *design, BlifDumperConfig &config)
+ static void dump(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, BlifDumperConfig &config)
{
BlifDumper dumper(f, module, design, &config);
dumper.dump();
@@ -228,23 +280,30 @@ struct BlifBackend : public Backend {
log(" -false <cell-type> <out-port>\n");
log(" use the specified cell types to drive nets that are constant 1 or 0\n");
log("\n");
- log("The following options can be usefull when the generated file is not going to be\n");
+ log("The following options can be useful when the generated file is not going to be\n");
log("read by a BLIF parser but a custom tool. It is recommended to not name the output\n");
log("file *.blif when any of this options is used.\n");
log("\n");
- log(" -subckt\n");
+ log(" -icells\n");
log(" do not translate Yosys's internal gates to generic BLIF logic\n");
- log(" functions. Instead create .subckt lines for all cells.\n");
+ log(" functions. Instead create .subckt or .gate lines for all cells.\n");
+ log("\n");
+ log(" -gates\n");
+ log(" print .gate instead of .subckt lines for all cells that are not\n");
+ log(" instantiations of other modules from this design.\n");
log("\n");
log(" -conn\n");
log(" do not generate buffers for connected wires. instead use the\n");
log(" non-standard .conn statement.\n");
log("\n");
+ log(" -param\n");
+ log(" use the non-standard .param statement to write module parameters\n");
+ log("\n");
log(" -impltf\n");
log(" do not write definitions for the $true and $false wires.\n");
log("\n");
}
- virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
+ virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
{
std::string top_module_name;
std::string buf_type, buf_in, buf_out;
@@ -277,14 +336,22 @@ struct BlifBackend : public Backend {
config.false_out = args[++argidx];
continue;
}
- if (args[argidx] == "-subckt") {
- config.subckt_mode = true;
+ if (args[argidx] == "-icells") {
+ config.icells_mode = true;
+ continue;
+ }
+ if (args[argidx] == "-gates") {
+ config.gates_mode = true;
continue;
}
if (args[argidx] == "-conn") {
config.conn_mode = true;
continue;
}
+ if (args[argidx] == "-param") {
+ config.param_mode = true;
+ continue;
+ }
if (args[argidx] == "-impltf") {
config.impltf_mode = true;
continue;
@@ -294,15 +361,15 @@ struct BlifBackend : public Backend {
extra_args(f, filename, args, argidx);
if (top_module_name.empty())
- for (auto & mod_it:design->modules)
+ for (auto & mod_it:design->modules_)
if (mod_it.second->get_bool_attribute("\\top"))
- top_module_name = mod_it.first;
+ top_module_name = mod_it.first.str();
- fprintf(f, "# Generated by %s\n", yosys_version_str);
+ *f << stringf("# Generated by %s\n", yosys_version_str);
std::vector<RTLIL::Module*> mod_list;
- for (auto module_it : design->modules)
+ for (auto module_it : design->modules_)
{
RTLIL::Module *module = module_it.second;
if (module->get_bool_attribute("\\blackbox"))
@@ -314,7 +381,7 @@ struct BlifBackend : public Backend {
log_error("Found munmapped emories in module %s: unmapped memories are not supported in BLIF backend!\n", RTLIL::id2cstr(module->name));
if (module->name == RTLIL::escape_id(top_module_name)) {
- BlifDumper::dump(f, module, design, config);
+ BlifDumper::dump(*f, module, design, config);
top_module_name.clear();
continue;
}
@@ -326,7 +393,7 @@ struct BlifBackend : public Backend {
log_error("Can't find top module `%s'!\n", top_module_name.c_str());
for (auto module : mod_list)
- BlifDumper::dump(f, module, design, config);
+ BlifDumper::dump(*f, module, design, config);
}
} BlifBackend;
diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc
index abe09943..8ce5bb5e 100644
--- a/backends/btor/btor.cc
+++ b/backends/btor/btor.cc
@@ -28,7 +28,6 @@
#include "kernel/celltypes.h"
#include "kernel/log.h"
#include <string>
-#include <assert.h>
#include <math.h>
struct BtorDumperConfig
@@ -46,9 +45,9 @@ struct BtorDumperConfig
struct WireInfo
{
RTLIL::IdString cell_name;
- RTLIL::SigChunk *chunk;
+ const RTLIL::SigChunk *chunk;
- WireInfo(RTLIL::IdString c, RTLIL::SigChunk* ch) : cell_name(c), chunk(ch) { }
+ WireInfo(RTLIL::IdString c, const RTLIL::SigChunk* ch) : cell_name(c), chunk(ch) { }
};
struct WireInfoOrder
@@ -61,7 +60,7 @@ struct WireInfoOrder
struct BtorDumper
{
- FILE *f;
+ std::ostream &f;
RTLIL::Module *module;
RTLIL::Design *design;
BtorDumperConfig *config;
@@ -75,14 +74,14 @@ struct BtorDumper
std::string str;//temp string for writing file
std::map<RTLIL::IdString, bool> basic_wires;//input wires and registers
RTLIL::IdString curr_cell; //current cell being dumped
- std::set<int> mem_next; //if memory (line_number) already has next
- std::map<std::string, std::string> cell_type_translation, s_cell_type_translation; //RTLIL to BTOR translation
- BtorDumper(FILE *f, RTLIL::Module *module, RTLIL::Design *design, BtorDumperConfig *config) :
- f(f), module(module), design(design), config(config), ct(design), sigmap(module)
+ std::map<std::string, std::string> cell_type_translation, s_cell_type_translation; //RTLIL to BTOR translation
+ std::set<int> mem_next; //if memory (line_number) already has next
+ BtorDumper(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, BtorDumperConfig *config) :
+ f(f), module(module), design(design), config(config), ct(design), sigmap(module)
{
line_num=0;
str.clear();
- for(auto it=module->wires.begin(); it!=module->wires.end(); ++it)
+ for(auto it=module->wires_.begin(); it!=module->wires_.end(); ++it)
{
if(it->second->port_input)
{
@@ -113,6 +112,8 @@ struct BtorDumper
cell_type_translation["$shl"] = "sll";
cell_type_translation["$sshr"] = "sra";
cell_type_translation["$sshl"] = "sll";
+ cell_type_translation["$shift"] = "srl";
+ cell_type_translation["$shiftx"] = "srl";
cell_type_translation["$lt"] = "ult";
cell_type_translation["$le"] = "ulte";
cell_type_translation["$gt"] = "ugt";
@@ -174,7 +175,7 @@ struct BtorDumper
++line_num;
line_ref[wire->name]=line_num;
str = stringf("%d var %d %s", line_num, wire->width, cstr(wire->name));
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
return line_num;
}
else return it->second;
@@ -194,11 +195,11 @@ struct BtorDumper
if(cell_id == curr_cell)
break;
log(" -- found cell %s\n", cstr(cell_id));
- RTLIL::Cell* cell = module->cells.at(cell_id);
- RTLIL::SigSpec* cell_output = get_cell_output(cell);
+ RTLIL::Cell* cell = module->cells_.at(cell_id);
+ const RTLIL::SigSpec* cell_output = get_cell_output(cell);
int cell_line = dump_cell(cell);
- if(dep_set.size()==1 && wire->width == cell_output->width)
+ if(dep_set.size()==1 && wire->width == cell_output->size())
{
wire_line = cell_line;
break;
@@ -207,22 +208,22 @@ struct BtorDumper
{
int prev_wire_line=0; //previously dumped wire line
int start_bit=0;
- for(unsigned j=0; j<cell_output->chunks.size(); ++j)
+ for(unsigned j=0; j<cell_output->chunks().size(); ++j)
{
- start_bit+=cell_output->chunks[j].width;
- if(cell_output->chunks[j].wire->name == wire->name)
+ start_bit+=cell_output->chunks().at(j).width;
+ if(cell_output->chunks().at(j).wire->name == wire->name)
{
prev_wire_line = wire_line;
wire_line = ++line_num;
- str = stringf("%d slice %d %d %d %d;1", line_num, cell_output->chunks[j].width,
- cell_line, start_bit-1, start_bit-cell_output->chunks[j].width);
- fprintf(f, "%s\n", str.c_str());
- wire_width += cell_output->chunks[j].width;
+ str = stringf("%d slice %d %d %d %d;1", line_num, cell_output->chunks().at(j).width,
+ cell_line, start_bit-1, start_bit-cell_output->chunks().at(j).width);
+ f << stringf("%s\n", str.c_str());
+ wire_width += cell_output->chunks().at(j).width;
if(prev_wire_line!=0)
{
++line_num;
str = stringf("%d concat %d %d %d", line_num, wire_width, wire_line, prev_wire_line);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
wire_line = line_num;
}
}
@@ -233,7 +234,7 @@ struct BtorDumper
{
log(" - checking sigmap\n");
RTLIL::SigSpec s = RTLIL::SigSpec(wire);
- wire_line = dump_sigspec(&s, s.width);
+ wire_line = dump_sigspec(&s, s.size());
line_ref[wire->name]=wire_line;
}
line_ref[wire->name]=wire_line;
@@ -245,7 +246,7 @@ struct BtorDumper
return it->second;
}
}
- assert(false);
+ log_abort();
return -1;
}
@@ -259,7 +260,7 @@ struct BtorDumper
int address_bits = ceil(log(memory->size)/log(2));
str = stringf("%d array %d %d", line_num, memory->width, address_bits);
line_ref[memory->name]=line_num;
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
return line_num;
}
else return it->second;
@@ -279,12 +280,12 @@ struct BtorDumper
++line_num;
str = stringf("%d const %d %s", line_num, width, data_str.c_str());
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
return line_num;
}
else
log("writing const error\n");
- assert(false);
+ log_abort();
return -1;
}
@@ -294,7 +295,8 @@ struct BtorDumper
int l=-1;
if(chunk->wire == NULL)
{
- l=dump_const(&chunk->data, chunk->width, chunk->offset);
+ RTLIL::Const data_const(chunk->data);
+ l=dump_const(&data_const, chunk->width, chunk->offset);
}
else
{
@@ -303,11 +305,11 @@ struct BtorDumper
else
{
int wire_line_num = dump_wire(chunk->wire);
- assert(wire_line_num>0);
+ log_assert(wire_line_num>0);
++line_num;
str = stringf("%d slice %d %d %d %d;2", line_num, chunk->width, wire_line_num,
chunk->width + chunk->offset - 1, chunk->offset);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
l = line_num;
}
}
@@ -322,24 +324,24 @@ struct BtorDumper
auto it = sig_ref.find(s);
if(it == std::end(sig_ref))
{
- if (s.chunks.size() == 1)
+ if (s.is_chunk())
{
- l = dump_sigchunk(&s.chunks[0]);
+ l = dump_sigchunk(&s.chunks().front());
}
else
{
int l1, l2, w1, w2;
- l1 = dump_sigchunk(&s.chunks[0]);
- assert(l1>0);
- w1 = s.chunks[0].width;
- for (unsigned i=1; i < s.chunks.size(); ++i)
+ l1 = dump_sigchunk(&s.chunks().front());
+ log_assert(l1>0);
+ w1 = s.chunks().front().width;
+ for (unsigned i=1; i < s.chunks().size(); ++i)
{
- l2 = dump_sigchunk(&s.chunks[i]);
- assert(l2>0);
- w2 = s.chunks[i].width;
+ l2 = dump_sigchunk(&s.chunks().at(i));
+ log_assert(l2>0);
+ w2 = s.chunks().at(i).width;
++line_num;
str = stringf("%d concat %d %d %d", line_num, w1+w2, l2, l1);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
l1=line_num;
w1+=w2;
}
@@ -352,30 +354,30 @@ struct BtorDumper
l = it->second;
}
- if (expected_width != s.width)
+ if (expected_width != s.size())
{
log(" - changing width of sigspec\n");
//TODO: this block may not be needed anymore, due to explicit type conversion by "splice" command
- if(expected_width > s.width)
+ if(expected_width > s.size())
{
//TODO: case the signal is signed
++line_num;
- str = stringf ("%d zero %d", line_num, expected_width - s.width);
- fprintf(f, "%s\n", str.c_str());
+ str = stringf ("%d zero %d", line_num, expected_width - s.size());
+ f << stringf("%s\n", str.c_str());
++line_num;
str = stringf ("%d concat %d %d %d", line_num, expected_width, line_num-1, l);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
l = line_num;
}
- else if(expected_width < s.width)
+ else if(expected_width < s.size())
{
++line_num;
str = stringf ("%d slice %d %d %d %d;3", line_num, expected_width, l, expected_width-1, 0);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
l = line_num;
}
}
- assert(l>0);
+ log_assert(l>0);
return l;
}
@@ -389,29 +391,29 @@ struct BtorDumper
if(cell->type == "$assert")
{
log("writing assert cell - %s\n", cstr(cell->type));
- const RTLIL::SigSpec* expr = &cell->connections.at(RTLIL::IdString("\\A"));
- const RTLIL::SigSpec* en = &cell->connections.at(RTLIL::IdString("\\EN"));
- assert(expr->width == 1);
- assert(en->width == 1);
+ const RTLIL::SigSpec* expr = &cell->getPort(RTLIL::IdString("\\A"));
+ const RTLIL::SigSpec* en = &cell->getPort(RTLIL::IdString("\\EN"));
+ log_assert(expr->size() == 1);
+ log_assert(en->size() == 1);
int expr_line = dump_sigspec(expr, 1);
int en_line = dump_sigspec(en, 1);
int one_line = ++line_num;
str = stringf("%d one 1", line_num);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
++line_num;
str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at("$eq").c_str(), 1, en_line, one_line);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
++line_num;
str = stringf("%d %s %d %d %d %d", line_num, cell_type_translation.at("$mux").c_str(), 1, line_num-1,
expr_line, one_line);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
int cell_line = ++line_num;
str = stringf("%d %s %d %d", line_num, cell_type_translation.at("$assert").c_str(), 1, -1*(line_num-1));
//multiplying the line number with -1, which means logical negation
//the reason for negative sign is that the properties in btor are given as "negation of the original property"
//bug identified by bobosoft
//http://www.reddit.com/r/yosys/comments/1w3xig/btor_backend_bug/
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
line_ref[cell->name]=cell_line;
}
//unary cells
@@ -422,20 +424,20 @@ struct BtorDumper
int w = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int();
int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int();
w = w>output_width ? w:output_width; //padding of w
- int l = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), w);
+ int l = dump_sigspec(&cell->getPort(RTLIL::IdString("\\A")), w);
int cell_line = l;
if(cell->type != "$pos")
{
cell_line = ++line_num;
bool reduced = (cell->type == "$not" || cell->type == "$neg") ? false : true;
- str = stringf ("%d %s %d %d", cell_line, cell_type_translation.at(cell->type).c_str(), reduced?output_width:w, l);
- fprintf(f, "%s\n", str.c_str());
+ str = stringf ("%d %s %d %d", cell_line, cell_type_translation.at(cell->type.str()).c_str(), reduced?output_width:w, l);
+ f << stringf("%s\n", str.c_str());
}
if(output_width < w && (cell->type == "$not" || cell->type == "$neg" || cell->type == "$pos"))
{
++line_num;
str = stringf ("%d slice %d %d %d %d;4", line_num, output_width, cell_line, output_width-1, 0);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
cell_line = line_num;
}
line_ref[cell->name]=cell_line;
@@ -445,25 +447,23 @@ struct BtorDumper
log("writing unary cell - %s\n", cstr(cell->type));
int w = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int();
int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int();
- assert(output_width == 1);
- int l = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), w);
+ log_assert(output_width == 1);
+ int l = dump_sigspec(&cell->getPort(RTLIL::IdString("\\A")), w);
if(cell->type == "$logic_not" && w > 1)
{
++line_num;
str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l);
- fprintf(f, "%s\n", str.c_str());
- l = line_num;
+ f << stringf("%s\n", str.c_str());
}
else if(cell->type == "$reduce_xnor")
{
++line_num;
str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_xor").c_str(), output_width, l);
- fprintf(f, "%s\n", str.c_str());
- l = line_num;
+ f << stringf("%s\n", str.c_str());
}
++line_num;
str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$not").c_str(), output_width, l);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
line_ref[cell->name]=line_num;
}
//binary cells
@@ -473,7 +473,7 @@ struct BtorDumper
{
log("writing binary cell - %s\n", cstr(cell->type));
int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int();
- assert(!(cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex" ||
+ log_assert(!(cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex" ||
cell->type == "$ge" || cell->type == "$gt") || output_width == 1);
bool l1_signed = cell->parameters.at(RTLIL::IdString("\\A_SIGNED")).as_bool();
bool l2_signed = cell->parameters.at(RTLIL::IdString("\\B_SIGNED")).as_bool();
@@ -485,21 +485,21 @@ struct BtorDumper
l1_width = l1_width > l2_width ? l1_width : l2_width;
l2_width = l2_width > l1_width ? l2_width : l1_width;
- int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), l1_width);
- int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), l2_width);
+ int l1 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\A")), l1_width);
+ int l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), l2_width);
++line_num;
- std::string op = cell_type_translation.at(cell->type);
+ std::string op = cell_type_translation.at(cell->type.str());
if(cell->type == "$lt" || cell->type == "$le" ||
cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex" ||
cell->type == "$ge" || cell->type == "$gt")
{
if(l1_signed)
- op = s_cell_type_translation.at(cell->type);
+ op = s_cell_type_translation.at(cell->type.str());
}
str = stringf ("%d %s %d %d %d", line_num, op.c_str(), output_width, l1, l2);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
line_ref[cell->name]=line_num;
}
@@ -514,18 +514,18 @@ struct BtorDumper
int l1_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int();
int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int();
- assert(l1_signed == l2_signed);
+ log_assert(l1_signed == l2_signed);
l1_width = l1_width > output_width ? l1_width : output_width;
l1_width = l1_width > l2_width ? l1_width : l2_width;
l2_width = l2_width > l1_width ? l2_width : l1_width;
- int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), l1_width);
- int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), l2_width);
+ int l1 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\A")), l1_width);
+ int l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), l2_width);
++line_num;
- std::string op = cell_type_translation.at(cell->type);
+ std::string op = cell_type_translation.at(cell->type.str());
if(cell->type == "$div" && l1_signed)
- op = s_cell_type_translation.at(cell->type);
+ op = s_cell_type_translation.at(cell->type.str());
else if(cell->type == "$mod")
{
if(l1_signed)
@@ -534,17 +534,17 @@ struct BtorDumper
op = s_cell_type_translation.at("$mody");
}
str = stringf ("%d %s %d %d %d", line_num, op.c_str(), l1_width, l1, l2);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
if(output_width < l1_width)
{
++line_num;
str = stringf ("%d slice %d %d %d %d;5", line_num, output_width, line_num-1, output_width-1, 0);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
}
line_ref[cell->name]=line_num;
}
- else if(cell->type == "$shr" || cell->type == "$shl" || cell->type == "$sshr" || cell->type == "$sshl")
+ else if(cell->type == "$shr" || cell->type == "$shl" || cell->type == "$sshr" || cell->type == "$sshl" || cell->type == "$shift" || cell->type == "$shiftx")
{
log("writing binary cell - %s\n", cstr(cell->type));
int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int();
@@ -553,32 +553,32 @@ struct BtorDumper
int l1_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int();
l1_width = pow(2, ceil(log(l1_width)/log(2)));
int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int();
- //assert(l2_width <= ceil(log(l1_width)/log(2)) );
- int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), l1_width);
- int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), ceil(log(l1_width)/log(2)));
+ //log_assert(l2_width <= ceil(log(l1_width)/log(2)) );
+ int l1 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\A")), l1_width);
+ int l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), ceil(log(l1_width)/log(2)));
int cell_output = ++line_num;
- str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), l1_width, l1, l2);
- fprintf(f, "%s\n", str.c_str());
+ str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type.str()).c_str(), l1_width, l1, l2);
+ f << stringf("%s\n", str.c_str());
if(l2_width > ceil(log(l1_width)/log(2)))
{
int extra_width = l2_width - ceil(log(l1_width)/log(2));
- l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), l2_width);
+ l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), l2_width);
++line_num;
str = stringf ("%d slice %d %d %d %d;6", line_num, extra_width, l2, l2_width-1, l2_width-extra_width);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
++line_num;
str = stringf ("%d one %d", line_num, extra_width);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
int mux = ++line_num;
str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at("$gt").c_str(), 1, line_num-2, line_num-1);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
++line_num;
str = stringf("%d %s %d", line_num, l1_signed && cell->type == "$sshr" ? "ones":"zero", l1_width);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
++line_num;
str = stringf ("%d %s %d %d %d %d", line_num, cell_type_translation.at("$mux").c_str(), l1_width, mux, line_num-1, cell_output);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
cell_output = line_num;
}
@@ -586,7 +586,7 @@ struct BtorDumper
{
++line_num;
str = stringf ("%d slice %d %d %d %d;5", line_num, output_width, cell_output, output_width-1, 0);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
cell_output = line_num;
}
line_ref[cell->name] = cell_output;
@@ -595,23 +595,23 @@ struct BtorDumper
{
log("writing binary cell - %s\n", cstr(cell->type));
int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int();
- assert(output_width == 1);
- int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), output_width);
- int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), output_width);
+ log_assert(output_width == 1);
+ int l1 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\A")), output_width);
+ int l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), output_width);
int l1_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int();
int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int();
if(l1_width >1)
{
++line_num;
str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l1);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
l1 = line_num;
}
if(l2_width > 1)
{
++line_num;
str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l2);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
l2 = line_num;
}
if(cell->type == "$logic_and")
@@ -624,7 +624,7 @@ struct BtorDumper
++line_num;
str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at("$or").c_str(), output_width, l1, l2);
}
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
line_ref[cell->name]=line_num;
}
//multiplexers
@@ -632,13 +632,14 @@ struct BtorDumper
{
log("writing mux cell\n");
int output_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int();
- int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), output_width);
- int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), output_width);
- int s = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\S")), 1);
+ int l1 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\A")), output_width);
+ int l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), output_width);
+ int s = dump_sigspec(&cell->getPort(RTLIL::IdString("\\S")), 1);
++line_num;
str = stringf ("%d %s %d %d %d %d",
- line_num, cell_type_translation.at(cell->type).c_str(), output_width, s, l2, l1);//if s is 0 then l1, if s is 1 then l2 //according to the implementation of mux cell
- fprintf(f, "%s\n", str.c_str());
+ line_num, cell_type_translation.at(cell->type.str()).c_str(), output_width, s, l2, l1);
+ //if s is 0 then l1, if s is 1 then l2 //according to the implementation of mux cell
+ f << stringf("%s\n", str.c_str());
line_ref[cell->name]=line_num;
}
else if(cell->type == "$pmux")
@@ -646,97 +647,97 @@ struct BtorDumper
log("writing pmux cell\n");
int output_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int();
int select_width = cell->parameters.at(RTLIL::IdString("\\S_WIDTH")).as_int();
- int default_case = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), output_width);
- int cases = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), output_width*select_width);
- int select = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\S")), select_width);
+ int default_case = dump_sigspec(&cell->getPort(RTLIL::IdString("\\A")), output_width);
+ int cases = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), output_width*select_width);
+ int select = dump_sigspec(&cell->getPort(RTLIL::IdString("\\S")), select_width);
int *c = new int[select_width];
for (int i=0; i<select_width; ++i)
{
++line_num;
str = stringf ("%d slice 1 %d %d %d", line_num, select, i, i);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
c[i] = line_num;
++line_num;
str = stringf ("%d slice %d %d %d %d", line_num, output_width, cases, i*output_width+output_width-1,
i*output_width);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
}
++line_num;
str = stringf ("%d cond %d %d %d %d", line_num, output_width, c[select_width-1], c[select_width-1]+1, default_case);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
for (int i=select_width-2; i>=0; --i)
{
++line_num;
str = stringf ("%d cond %d %d %d %d", line_num, output_width, c[i], c[i]+1, line_num-1);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
}
line_ref[cell->name]=line_num;
}
- //registers
+ //registers
else if(cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffsr")
{
//TODO: remodelling fo adff cells
log("writing cell - %s\n", cstr(cell->type));
int output_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int();
log(" - width is %d\n", output_width);
- int cond = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\CLK")), 1);
+ int cond = dump_sigspec(&cell->getPort(RTLIL::IdString("\\CLK")), 1);
bool polarity = cell->parameters.at(RTLIL::IdString("\\CLK_POLARITY")).as_bool();
- const RTLIL::SigSpec* cell_output = &cell->connections.at(RTLIL::IdString("\\Q"));
- int value = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\D")), output_width);
+ const RTLIL::SigSpec* cell_output = &cell->getPort(RTLIL::IdString("\\Q"));
+ int value = dump_sigspec(&cell->getPort(RTLIL::IdString("\\D")), output_width);
unsigned start_bit = 0;
- for(unsigned i=0; i<cell_output->chunks.size(); ++i)
+ for(unsigned i=0; i<cell_output->chunks().size(); ++i)
{
- output_width = cell_output->chunks[i].width;
- assert( output_width == cell_output->chunks[i].wire->width);//full reg is given the next value
- int reg = dump_wire(cell_output->chunks[i].wire);//register
+ output_width = cell_output->chunks().at(i).width;
+ log_assert( output_width == cell_output->chunks().at(i).wire->width);//full reg is given the next value
+ int reg = dump_wire(cell_output->chunks().at(i).wire);//register
int slice = value;
- if(cell_output->chunks.size()>1)
+ if(cell_output->chunks().size()>1)
{
start_bit+=output_width;
slice = ++line_num;
str = stringf ("%d slice %d %d %d %d;", line_num, output_width, value, start_bit-1,
start_bit-output_width);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
}
if(cell->type == "$dffsr")
{
- int sync_reset = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\CLR")), 1);
+ int sync_reset = dump_sigspec(&cell->getPort(RTLIL::IdString("\\CLR")), 1);
bool sync_reset_pol = cell->parameters.at(RTLIL::IdString("\\CLR_POLARITY")).as_bool();
- int sync_reset_value = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\SET")),
+ int sync_reset_value = dump_sigspec(&cell->getPort(RTLIL::IdString("\\SET")),
output_width);
bool sync_reset_value_pol = cell->parameters.at(RTLIL::IdString("\\SET_POLARITY")).as_bool();
++line_num;
str = stringf ("%d %s %d %s%d %s%d %d", line_num, cell_type_translation.at("$mux").c_str(),
output_width, sync_reset_pol ? "":"-", sync_reset, sync_reset_value_pol? "":"-",
sync_reset_value, slice);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
slice = line_num;
}
++line_num;
str = stringf ("%d %s %d %s%d %d %d", line_num, cell_type_translation.at("$mux").c_str(),
output_width, polarity?"":"-", cond, slice, reg);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
int next = line_num;
if(cell->type == "$adff")
{
- int async_reset = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\ARST")), 1);
+ int async_reset = dump_sigspec(&cell->getPort(RTLIL::IdString("\\ARST")), 1);
bool async_reset_pol = cell->parameters.at(RTLIL::IdString("\\ARST_POLARITY")).as_bool();
int async_reset_value = dump_const(&cell->parameters.at(RTLIL::IdString("\\ARST_VALUE")),
output_width, 0);
++line_num;
str = stringf ("%d %s %d %s%d %d %d", line_num, cell_type_translation.at("$mux").c_str(),
output_width, async_reset_pol ? "":"-", async_reset, async_reset_value, next);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
}
++line_num;
- str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(),
+ str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type.str()).c_str(),
output_width, reg, next);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
}
line_ref[cell->name]=line_num;
}
@@ -749,11 +750,11 @@ struct BtorDumper
str = cell->parameters.at(RTLIL::IdString("\\MEMID")).decode_string();
int mem = dump_memory(module->memories.at(RTLIL::IdString(str.c_str())));
int address_width = cell->parameters.at(RTLIL::IdString("\\ABITS")).as_int();
- int address = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\ADDR")), address_width);
+ int address = dump_sigspec(&cell->getPort(RTLIL::IdString("\\ADDR")), address_width);
int data_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int();
++line_num;
str = stringf("%d read %d %d %d", line_num, data_width, mem, address);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
line_ref[cell->name]=line_num;
}
else if(cell->type == "$memwr")
@@ -761,13 +762,13 @@ struct BtorDumper
log("writing memwr cell\n");
if (cell->parameters.at("\\CLK_ENABLE").as_bool() == false)
log_error("The btor backen does not support $memwr cells without built-in registers. Run memory_dff (but with -wr_only).\n");
- int clk = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\CLK")), 1);
+ int clk = dump_sigspec(&cell->getPort(RTLIL::IdString("\\CLK")), 1);
bool polarity = cell->parameters.at(RTLIL::IdString("\\CLK_POLARITY")).as_bool();
- int enable = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\EN")), 1);
+ int enable = dump_sigspec(&cell->getPort(RTLIL::IdString("\\EN")), 1);
int address_width = cell->parameters.at(RTLIL::IdString("\\ABITS")).as_int();
- int address = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\ADDR")), address_width);
- int data_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int();
- int data = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\DATA")), data_width);
+ int address = dump_sigspec(&cell->getPort(RTLIL::IdString("\\ADDR")), address_width);
+ int data_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int();
+ int data = dump_sigspec(&cell->getPort(RTLIL::IdString("\\DATA")), data_width);
str = cell->parameters.at(RTLIL::IdString("\\MEMID")).decode_string();
int mem = dump_memory(module->memories.at(RTLIL::IdString(str.c_str())));
//check if the memory has already next
@@ -779,68 +780,67 @@ struct BtorDumper
RTLIL::Memory *memory = module->memories.at(RTLIL::IdString(str.c_str()));
int address_bits = ceil(log(memory->size)/log(2));
str = stringf("%d array %d %d", line_num, memory->width, address_bits);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
++line_num;
str = stringf("%d eq 1 %d %d", line_num, mem, line_num - 1);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
mem = line_num - 1;
}
- ++line_num;
+ ++line_num;
if(polarity)
str = stringf("%d one 1", line_num);
else
str = stringf("%d zero 1", line_num);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
++line_num;
str = stringf("%d eq 1 %d %d", line_num, clk, line_num-1);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
++line_num;
str = stringf("%d and 1 %d %d", line_num, line_num-1, enable);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
++line_num;
str = stringf("%d write %d %d %d %d %d", line_num, data_width, address_width, mem, address, data);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
++line_num;
str = stringf("%d acond %d %d %d %d %d", line_num, data_width, address_width, line_num-2/*enable*/, line_num-1, mem);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
++line_num;
str = stringf("%d anext %d %d %d %d", line_num, data_width, address_width, mem, line_num-1);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
mem_next.insert(mem);
- line_ref[cell->name]=line_num;
+ line_ref[cell->name]=line_num;
}
else if(cell->type == "$slice")
{
log("writing slice cell\n");
- const RTLIL::SigSpec* input = &cell->connections.at(RTLIL::IdString("\\A"));
+ const RTLIL::SigSpec* input = &cell->getPort(RTLIL::IdString("\\A"));
int input_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int();
- assert(input->width == input_width);
+ log_assert(input->size() == input_width);
int input_line = dump_sigspec(input, input_width);
- const RTLIL::SigSpec* output = &cell->connections.at(RTLIL::IdString("\\Y"));
+ const RTLIL::SigSpec* output = &cell->getPort(RTLIL::IdString("\\Y"));
int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int();
- assert(output->width == output_width);
+ log_assert(output->size() == output_width);
int offset = cell->parameters.at(RTLIL::IdString("\\OFFSET")).as_int();
++line_num;
- str = stringf("%d %s %d %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(),
- output_width, input_line, output_width+offset-1, offset);
- fprintf(f, "%s\n", str.c_str());
+ str = stringf("%d %s %d %d %d %d", line_num, cell_type_translation.at(cell->type.str()).c_str(), output_width, input_line, output_width+offset-1, offset);
+ f << stringf("%s\n", str.c_str());
line_ref[cell->name]=line_num;
}
else if(cell->type == "$concat")
{
log("writing concat cell\n");
- const RTLIL::SigSpec* input_a = &cell->connections.at(RTLIL::IdString("\\A"));
+ const RTLIL::SigSpec* input_a = &cell->getPort(RTLIL::IdString("\\A"));
int input_a_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int();
- assert(input_a->width == input_a_width);
+ log_assert(input_a->size() == input_a_width);
int input_a_line = dump_sigspec(input_a, input_a_width);
- const RTLIL::SigSpec* input_b = &cell->connections.at(RTLIL::IdString("\\B"));
+ const RTLIL::SigSpec* input_b = &cell->getPort(RTLIL::IdString("\\B"));
int input_b_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int();
- assert(input_b->width == input_b_width);
+ log_assert(input_b->size() == input_b_width);
int input_b_line = dump_sigspec(input_b, input_b_width);
++line_num;
- str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), input_a_width+input_b_width,
+ str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type.str()).c_str(), input_a_width+input_b_width,
input_a_line, input_b_line);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
line_ref[cell->name]=line_num;
}
curr_cell.clear();
@@ -852,12 +852,12 @@ struct BtorDumper
}
}
- RTLIL::SigSpec* get_cell_output(RTLIL::Cell* cell)
+ const RTLIL::SigSpec* get_cell_output(RTLIL::Cell* cell)
{
- RTLIL::SigSpec *output_sig = nullptr;
+ const RTLIL::SigSpec *output_sig = nullptr;
if (cell->type == "$memrd")
{
- output_sig = &cell->connections.at(RTLIL::IdString("\\DATA"));
+ output_sig = &cell->getPort(RTLIL::IdString("\\DATA"));
}
else if(cell->type == "$memwr" || cell->type == "$assert")
{
@@ -865,11 +865,11 @@ struct BtorDumper
}
else if(cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffsr")
{
- output_sig = &cell->connections.at(RTLIL::IdString("\\Q"));
+ output_sig = &cell->getPort(RTLIL::IdString("\\Q"));
}
else
{
- output_sig = &cell->connections.at(RTLIL::IdString("\\Y"));
+ output_sig = &cell->getPort(RTLIL::IdString("\\Y"));
}
return output_sig;
}
@@ -879,19 +879,19 @@ struct BtorDumper
int l = dump_wire(wire);
++line_num;
str = stringf("%d root 1 %d", line_num, l);
- fprintf(f, "%s\n", str.c_str());
+ f << stringf("%s\n", str.c_str());
}
void dump()
{
- fprintf(f, ";module %s\n", cstr(module->name));
+ f << stringf(";module %s\n", cstr(module->name));
log("creating intermediate wires map\n");
//creating map of intermediate wires as output of some cell
- for (auto it = module->cells.begin(); it != module->cells.end(); ++it)
+ for (auto it = module->cells_.begin(); it != module->cells_.end(); ++it)
{
RTLIL::Cell *cell = it->second;
- RTLIL::SigSpec* output_sig = get_cell_output(cell);
+ const RTLIL::SigSpec* output_sig = get_cell_output(cell);
if(output_sig==nullptr)
continue;
RTLIL::SigSpec s = sigmap(*output_sig);
@@ -899,11 +899,11 @@ struct BtorDumper
log(" - %s\n", cstr(it->second->type));
if (cell->type == "$memrd")
{
- for(unsigned i=0; i<output_sig->chunks.size(); ++i)
+ for(unsigned i=0; i<output_sig->chunks().size(); ++i)
{
- RTLIL::Wire *w = output_sig->chunks[i].wire;
+ RTLIL::Wire *w = output_sig->chunks().at(i).wire;
RTLIL::IdString wire_id = w->name;
- inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks[i]));
+ inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks().at(i)));
}
}
else if(cell->type == "$memwr")
@@ -912,22 +912,22 @@ struct BtorDumper
}
else if(cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffsr")
{
- RTLIL::IdString wire_id = output_sig->chunks[0].wire->name;
- for(unsigned i=0; i<output_sig->chunks.size(); ++i)
+ RTLIL::IdString wire_id = output_sig->chunks().front().wire->name;
+ for(unsigned i=0; i<output_sig->chunks().size(); ++i)
{
- RTLIL::Wire *w = output_sig->chunks[i].wire;
+ RTLIL::Wire *w = output_sig->chunks().at(i).wire;
RTLIL::IdString wire_id = w->name;
- inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks[i]));
+ inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks().at(i)));
basic_wires[wire_id] = true;
}
}
else
{
- for(unsigned i=0; i<output_sig->chunks.size(); ++i)
+ for(unsigned i=0; i<output_sig->chunks().size(); ++i)
{
- RTLIL::Wire *w = output_sig->chunks[i].wire;
+ RTLIL::Wire *w = output_sig->chunks().at(i).wire;
RTLIL::IdString wire_id = w->name;
- inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks[i]));
+ inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks().at(i)));
}
}
}
@@ -936,23 +936,23 @@ struct BtorDumper
std::map<int, RTLIL::Wire*> inputs, outputs;
std::vector<RTLIL::Wire*> safety;
- for (auto &wire_it : module->wires) {
+ for (auto &wire_it : module->wires_) {
RTLIL::Wire *wire = wire_it.second;
if (wire->port_input)
inputs[wire->port_id] = wire;
if (wire->port_output) {
outputs[wire->port_id] = wire;
- if (wire->name.find("safety") != std::string::npos )
+ if (wire->name.str().find("safety") != std::string::npos )
safety.push_back(wire);
}
}
- fprintf(f, ";inputs\n");
+ f << stringf(";inputs\n");
for (auto &it : inputs) {
RTLIL::Wire *wire = it.second;
dump_wire(wire);
}
- fprintf(f, "\n");
+ f << stringf("\n");
log("writing memories\n");
for(auto mem_it = module->memories.begin(); mem_it != module->memories.end(); ++mem_it)
@@ -967,7 +967,7 @@ struct BtorDumper
}
log("writing cells\n");
- for(auto cell_it = module->cells.begin(); cell_it != module->cells.end(); ++cell_it)
+ for(auto cell_it = module->cells_.begin(); cell_it != module->cells_.end(); ++cell_it)
{
dump_cell(cell_it->second);
}
@@ -975,19 +975,19 @@ struct BtorDumper
for(auto it: safety)
dump_property(it);
- fprintf(f, "\n");
+ f << stringf("\n");
log("writing outputs info\n");
- fprintf(f, ";outputs\n");
+ f << stringf(";outputs\n");
for (auto &it : outputs) {
RTLIL::Wire *wire = it.second;
int l = dump_wire(wire);
- fprintf(f, ";%d %s", l, cstr(wire->name));
+ f << stringf(";%d %s", l, cstr(wire->name));
}
- fprintf(f, "\n");
+ f << stringf("\n");
}
- static void dump(FILE *f, RTLIL::Module *module, RTLIL::Design *design, BtorDumperConfig &config)
+ static void dump(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, BtorDumperConfig &config)
{
BtorDumper dumper(f, module, design, &config);
dumper.dump();
@@ -1006,7 +1006,7 @@ struct BtorBackend : public Backend {
log("Write the current design to an BTOR file.\n");
}
- virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
+ virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
{
std::string top_module_name;
std::string buf_type, buf_in, buf_out;
@@ -1020,18 +1020,18 @@ struct BtorBackend : public Backend {
extra_args(f, filename, args, argidx);
if (top_module_name.empty())
- for (auto & mod_it:design->modules)
+ for (auto & mod_it:design->modules_)
if (mod_it.second->get_bool_attribute("\\top"))
- top_module_name = mod_it.first;
+ top_module_name = mod_it.first.str();
- fprintf(f, "; Generated by %s\n", yosys_version_str);
- fprintf(f, "; %s developed and maintained by Clifford Wolf <clifford@clifford.at>\n", yosys_version_str);
- fprintf(f, "; BTOR Backend developed by Ahmed Irfan <irfan@fbk.eu> - Fondazione Bruno Kessler, Trento, Italy\n");
- fprintf(f, ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
+ *f << stringf("; Generated by %s\n", yosys_version_str);
+ *f << stringf("; %s developed and maintained by Clifford Wolf <clifford@clifford.at>\n", yosys_version_str);
+ *f << stringf("; BTOR Backend developed by Ahmed Irfan <irfan@fbk.eu> - Fondazione Bruno Kessler, Trento, Italy\n");
+ *f << stringf(";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
std::vector<RTLIL::Module*> mod_list;
- for (auto module_it : design->modules)
+ for (auto module_it : design->modules_)
{
RTLIL::Module *module = module_it.second;
if (module->get_bool_attribute("\\blackbox"))
@@ -1041,7 +1041,7 @@ struct BtorBackend : public Backend {
log_error("Found unmapped processes in module %s: unmapped processes are not supported in BTOR backend!\n", RTLIL::id2cstr(module->name));
if (module->name == RTLIL::escape_id(top_module_name)) {
- BtorDumper::dump(f, module, design, config);
+ BtorDumper::dump(*f, module, design, config);
top_module_name.clear();
continue;
}
@@ -1053,7 +1053,7 @@ struct BtorBackend : public Backend {
log_error("Can't find top module `%s'!\n", top_module_name.c_str());
for (auto module : mod_list)
- BtorDumper::dump(f, module, design, config);
+ BtorDumper::dump(*f, module, design, config);
}
} BtorBackend;
diff --git a/backends/btor/verilog2btor.sh b/backends/btor/verilog2btor.sh
index 870f0a28..ab45b490 100755
--- a/backends/btor/verilog2btor.sh
+++ b/backends/btor/verilog2btor.sh
@@ -17,14 +17,14 @@ FULL_PATH=$(readlink -f $1)
DIR=$(dirname $FULL_PATH)
./yosys -q -p "
-read_verilog $1;
+read_verilog -sv $1;
hierarchy -top $3;
hierarchy -libdir $DIR;
hierarchy -check;
proc;
opt; opt_const -mux_undef; opt;
rename -hide;;;
-techmap -share_map pmux2mux.v;;
+#techmap -share_map pmux2mux.v;;
splice; opt;
memory_dff -wr_only;
memory_collect;;
diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc
index 1748ed81..ccedd91d 100644
--- a/backends/edif/edif.cc
+++ b/backends/edif/edif.cc
@@ -26,9 +26,9 @@
#include "kernel/celltypes.h"
#include "kernel/log.h"
#include <string>
-#include <assert.h>
-#define EDIF_NAME(_id) edif_names(RTLIL::unescape_id(_id)).c_str()
+#define EDIF_DEF(_id) edif_names(RTLIL::unescape_id(_id), true).c_str()
+#define EDIF_REF(_id) edif_names(RTLIL::unescape_id(_id), false).c_str()
namespace
{
@@ -40,8 +40,13 @@ namespace
EdifNames() : counter(1) { }
- std::string operator()(std::string id)
+ std::string operator()(std::string id, bool define)
{
+ if (define) {
+ std::string new_id = operator()(id, false);
+ return new_id != id ? stringf("(rename %s \"%s\")", new_id.c_str(), id.c_str()) : id;
+ }
+
if (name_map.count(id) > 0)
return name_map.at(id);
if (generated_names.count(id) > 0)
@@ -74,7 +79,7 @@ namespace
}
generated_names.insert(gen_name);
name_map[id] = gen_name;
- return stringf("(rename %s \"%s\")", gen_name.c_str(), id.c_str());
+ return gen_name;
}
};
}
@@ -98,12 +103,12 @@ struct EdifBackend : public Backend {
log("is targeted.\n");
log("\n");
}
- virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
+ virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
{
log_header("Executing EDIF backend.\n");
std::string top_module_name;
- std::map<std::string, std::set<std::string>> lib_cell_ports;
+ std::map<RTLIL::IdString, std::set<RTLIL::IdString>> lib_cell_ports;
CellTypes ct(design);
EdifNames edif_names;
@@ -119,31 +124,31 @@ struct EdifBackend : public Backend {
extra_args(f, filename, args, argidx);
if (top_module_name.empty())
- for (auto & mod_it:design->modules)
+ for (auto & mod_it:design->modules_)
if (mod_it.second->get_bool_attribute("\\top"))
- top_module_name = mod_it.first;
+ top_module_name = mod_it.first.str();
- for (auto module_it : design->modules)
+ for (auto module_it : design->modules_)
{
RTLIL::Module *module = module_it.second;
if (module->get_bool_attribute("\\blackbox"))
continue;
if (top_module_name.empty())
- top_module_name = module->name;
+ top_module_name = module->name.str();
if (module->processes.size() != 0)
log_error("Found unmapped processes in module %s: unmapped processes are not supported in EDIF backend!\n", RTLIL::id2cstr(module->name));
if (module->memories.size() != 0)
log_error("Found munmapped emories in module %s: unmapped memories are not supported in EDIF backend!\n", RTLIL::id2cstr(module->name));
- for (auto cell_it : module->cells)
+ for (auto cell_it : module->cells_)
{
RTLIL::Cell *cell = cell_it.second;
- if (!design->modules.count(cell->type) || design->modules.at(cell->type)->get_bool_attribute("\\blackbox")) {
+ if (!design->modules_.count(cell->type) || design->modules_.at(cell->type)->get_bool_attribute("\\blackbox")) {
lib_cell_ports[cell->type];
- for (auto p : cell->connections) {
- if (p.second.width > 1)
+ for (auto p : cell->connections()) {
+ if (p.second.size() > 1)
log_error("Found multi-bit port %s on library cell %s.%s (%s): not supported in EDIF backend!\n",
RTLIL::id2cstr(p.first), RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
lib_cell_ports[cell->type].insert(p.first);
@@ -155,38 +160,38 @@ struct EdifBackend : public Backend {
if (top_module_name.empty())
log_error("No module found in design!\n");
- fprintf(f, "(edif %s\n", EDIF_NAME(top_module_name));
- fprintf(f, " (edifVersion 2 0 0)\n");
- fprintf(f, " (edifLevel 0)\n");
- fprintf(f, " (keywordMap (keywordLevel 0))\n");
- fprintf(f, " (comment \"Generated by %s\")\n", yosys_version_str);
-
- fprintf(f, " (external LIB\n");
- fprintf(f, " (edifLevel 0)\n");
- fprintf(f, " (technology (numberDefinition))\n");
-
- fprintf(f, " (cell GND\n");
- fprintf(f, " (cellType GENERIC)\n");
- fprintf(f, " (view VIEW_NETLIST\n");
- fprintf(f, " (viewType NETLIST)\n");
- fprintf(f, " (interface (port G (direction OUTPUT)))\n");
- fprintf(f, " )\n");
- fprintf(f, " )\n");
-
- fprintf(f, " (cell VCC\n");
- fprintf(f, " (cellType GENERIC)\n");
- fprintf(f, " (view VIEW_NETLIST\n");
- fprintf(f, " (viewType NETLIST)\n");
- fprintf(f, " (interface (port P (direction OUTPUT)))\n");
- fprintf(f, " )\n");
- fprintf(f, " )\n");
+ *f << stringf("(edif %s\n", EDIF_DEF(top_module_name));
+ *f << stringf(" (edifVersion 2 0 0)\n");
+ *f << stringf(" (edifLevel 0)\n");
+ *f << stringf(" (keywordMap (keywordLevel 0))\n");
+ *f << stringf(" (comment \"Generated by %s\")\n", yosys_version_str);
+
+ *f << stringf(" (external LIB\n");
+ *f << stringf(" (edifLevel 0)\n");
+ *f << stringf(" (technology (numberDefinition))\n");
+
+ *f << stringf(" (cell GND\n");
+ *f << stringf(" (cellType GENERIC)\n");
+ *f << stringf(" (view VIEW_NETLIST\n");
+ *f << stringf(" (viewType NETLIST)\n");
+ *f << stringf(" (interface (port G (direction OUTPUT)))\n");
+ *f << stringf(" )\n");
+ *f << stringf(" )\n");
+
+ *f << stringf(" (cell VCC\n");
+ *f << stringf(" (cellType GENERIC)\n");
+ *f << stringf(" (view VIEW_NETLIST\n");
+ *f << stringf(" (viewType NETLIST)\n");
+ *f << stringf(" (interface (port P (direction OUTPUT)))\n");
+ *f << stringf(" )\n");
+ *f << stringf(" )\n");
for (auto &cell_it : lib_cell_ports) {
- fprintf(f, " (cell %s\n", EDIF_NAME(cell_it.first));
- fprintf(f, " (cellType GENERIC)\n");
- fprintf(f, " (view VIEW_NETLIST\n");
- fprintf(f, " (viewType NETLIST)\n");
- fprintf(f, " (interface\n");
+ *f << stringf(" (cell %s\n", EDIF_DEF(cell_it.first));
+ *f << stringf(" (cellType GENERIC)\n");
+ *f << stringf(" (view VIEW_NETLIST\n");
+ *f << stringf(" (viewType NETLIST)\n");
+ *f << stringf(" (interface\n");
for (auto &port_it : cell_it.second) {
const char *dir = "INOUT";
if (ct.cell_known(cell_it.first)) {
@@ -195,23 +200,23 @@ struct EdifBackend : public Backend {
else if (!ct.cell_input(cell_it.first, port_it))
dir = "OUTPUT";
}
- fprintf(f, " (port %s (direction %s))\n", EDIF_NAME(port_it), dir);
+ *f << stringf(" (port %s (direction %s))\n", EDIF_DEF(port_it), dir);
}
- fprintf(f, " )\n");
- fprintf(f, " )\n");
- fprintf(f, " )\n");
+ *f << stringf(" )\n");
+ *f << stringf(" )\n");
+ *f << stringf(" )\n");
}
- fprintf(f, " )\n");
+ *f << stringf(" )\n");
std::vector<RTLIL::Module*> sorted_modules;
// extract module dependencies
std::map<RTLIL::Module*, std::set<RTLIL::Module*>> module_deps;
- for (auto &mod_it : design->modules) {
+ for (auto &mod_it : design->modules_) {
module_deps[mod_it.second] = std::set<RTLIL::Module*>();
- for (auto &cell_it : mod_it.second->cells)
- if (design->modules.count(cell_it.second->type) > 0)
- module_deps[mod_it.second].insert(design->modules.at(cell_it.second->type));
+ for (auto &cell_it : mod_it.second->cells_)
+ if (design->modules_.count(cell_it.second->type) > 0)
+ module_deps[mod_it.second].insert(design->modules_.at(cell_it.second->type));
}
// simple good-enough topological sort
@@ -233,9 +238,9 @@ struct EdifBackend : public Backend {
}
- fprintf(f, " (library DESIGN\n");
- fprintf(f, " (edifLevel 0)\n");
- fprintf(f, " (technology (numberDefinition))\n");
+ *f << stringf(" (library DESIGN\n");
+ *f << stringf(" (edifLevel 0)\n");
+ *f << stringf(" (technology (numberDefinition))\n");
for (auto module : sorted_modules)
{
if (module->get_bool_attribute("\\blackbox"))
@@ -244,12 +249,12 @@ struct EdifBackend : public Backend {
SigMap sigmap(module);
std::map<RTLIL::SigSpec, std::set<std::string>> net_join_db;
- fprintf(f, " (cell %s\n", EDIF_NAME(module->name));
- fprintf(f, " (cellType GENERIC)\n");
- fprintf(f, " (view VIEW_NETLIST\n");
- fprintf(f, " (viewType NETLIST)\n");
- fprintf(f, " (interface\n");
- for (auto &wire_it : module->wires) {
+ *f << stringf(" (cell %s\n", EDIF_DEF(module->name));
+ *f << stringf(" (cellType GENERIC)\n");
+ *f << stringf(" (view VIEW_NETLIST\n");
+ *f << stringf(" (viewType NETLIST)\n");
+ *f << stringf(" (interface\n");
+ for (auto &wire_it : module->wires_) {
RTLIL::Wire *wire = wire_it.second;
if (wire->port_id == 0)
continue;
@@ -259,31 +264,31 @@ struct EdifBackend : public Backend {
else if (!wire->port_input)
dir = "OUTPUT";
if (wire->width == 1) {
- fprintf(f, " (port %s (direction %s))\n", EDIF_NAME(wire->name), dir);
+ *f << stringf(" (port %s (direction %s))\n", EDIF_DEF(wire->name), dir);
RTLIL::SigSpec sig = sigmap(RTLIL::SigSpec(wire));
- net_join_db[sig].insert(stringf("(portRef %s)", EDIF_NAME(wire->name)));
+ net_join_db[sig].insert(stringf("(portRef %s)", EDIF_REF(wire->name)));
} else {
- fprintf(f, " (port (array %s %d) (direction %s))\n", EDIF_NAME(wire->name), wire->width, dir);
+ *f << stringf(" (port (array %s %d) (direction %s))\n", EDIF_DEF(wire->name), wire->width, dir);
for (int i = 0; i < wire->width; i++) {
- RTLIL::SigSpec sig = sigmap(RTLIL::SigSpec(wire, 1, i));
- net_join_db[sig].insert(stringf("(portRef (member %s %d))", EDIF_NAME(wire->name), i));
+ RTLIL::SigSpec sig = sigmap(RTLIL::SigSpec(wire, i));
+ net_join_db[sig].insert(stringf("(portRef (member %s %d))", EDIF_REF(wire->name), i));
}
}
}
- fprintf(f, " )\n");
- fprintf(f, " (contents\n");
- fprintf(f, " (instance GND (viewRef VIEW_NETLIST (cellRef GND (libraryRef LIB))))\n");
- fprintf(f, " (instance VCC (viewRef VIEW_NETLIST (cellRef VCC (libraryRef LIB))))\n");
- for (auto &cell_it : module->cells) {
+ *f << stringf(" )\n");
+ *f << stringf(" (contents\n");
+ *f << stringf(" (instance GND (viewRef VIEW_NETLIST (cellRef GND (libraryRef LIB))))\n");
+ *f << stringf(" (instance VCC (viewRef VIEW_NETLIST (cellRef VCC (libraryRef LIB))))\n");
+ for (auto &cell_it : module->cells_) {
RTLIL::Cell *cell = cell_it.second;
- fprintf(f, " (instance %s\n", EDIF_NAME(cell->name));
- fprintf(f, " (viewRef VIEW_NETLIST (cellRef %s%s))", EDIF_NAME(cell->type),
+ *f << stringf(" (instance %s\n", EDIF_DEF(cell->name));
+ *f << stringf(" (viewRef VIEW_NETLIST (cellRef %s%s))", EDIF_REF(cell->type),
lib_cell_ports.count(cell->type) > 0 ? " (libraryRef LIB)" : "");
for (auto &p : cell->parameters)
if ((p.second.flags & RTLIL::CONST_FLAG_STRING) != 0)
- fprintf(f, "\n (property %s (string \"%s\"))", EDIF_NAME(p.first), p.second.decode_string().c_str());
+ *f << stringf("\n (property %s (string \"%s\"))", EDIF_DEF(p.first), p.second.decode_string().c_str());
else if (p.second.bits.size() <= 32 && RTLIL::SigSpec(p.second).is_fully_def())
- fprintf(f, "\n (property %s (integer %u))", EDIF_NAME(p.first), p.second.as_int());
+ *f << stringf("\n (property %s (integer %u))", EDIF_DEF(p.first), p.second.as_int());
else {
std::string hex_string = "";
for (size_t i = 0; i < p.second.bits.size(); i += 4) {
@@ -295,53 +300,48 @@ struct EdifBackend : public Backend {
char digit_str[2] = { "0123456789abcdef"[digit_value], 0 };
hex_string = std::string(digit_str) + hex_string;
}
- fprintf(f, "\n (property %s (string \"%s\"))", EDIF_NAME(p.first), hex_string.c_str());
+ *f << stringf("\n (property %s (string \"%s\"))", EDIF_DEF(p.first), hex_string.c_str());
}
- fprintf(f, ")\n");
- for (auto &p : cell->connections) {
+ *f << stringf(")\n");
+ for (auto &p : cell->connections()) {
RTLIL::SigSpec sig = sigmap(p.second);
- sig.expand();
- for (int i = 0; i < sig.width; i++) {
- RTLIL::SigSpec sigbit(sig.chunks.at(i));
- std::string portname = sig.width > 1 ? stringf("%s[%d]", RTLIL::id2cstr(p.first), i) : RTLIL::id2cstr(p.first);
- net_join_db[sigbit].insert(stringf("(portRef %s (instanceRef %s))", edif_names(portname).c_str(), EDIF_NAME(cell->name)));
- }
+ for (int i = 0; i < SIZE(sig); i++)
+ if (sig.size() == 1)
+ net_join_db[sig[i]].insert(stringf("(portRef %s (instanceRef %s))", EDIF_REF(p.first), EDIF_REF(cell->name)));
+ else
+ net_join_db[sig[i]].insert(stringf("(portRef (member %s %d) (instanceRef %s))", EDIF_REF(p.first), i, EDIF_REF(cell->name)));
}
}
for (auto &it : net_join_db) {
- RTLIL::SigSpec sig = it.first;
- sig.optimize();
- log_assert(sig.width == 1);
- if (sig.chunks.at(0).wire == NULL) {
- if (sig.chunks.at(0).data.bits.at(0) != RTLIL::State::S0 && sig.chunks.at(0).data.bits.at(0) != RTLIL::State::S1)
- continue;
- }
+ RTLIL::SigBit sig = it.first;
+ if (sig.wire == NULL && sig != RTLIL::State::S0 && sig != RTLIL::State::S1)
+ continue;
std::string netname = log_signal(sig);
for (size_t i = 0; i < netname.size(); i++)
if (netname[i] == ' ' || netname[i] == '\\')
netname.erase(netname.begin() + i--);
- fprintf(f, " (net %s (joined\n", edif_names(netname).c_str());
+ *f << stringf(" (net %s (joined\n", EDIF_DEF(netname));
for (auto &ref : it.second)
- fprintf(f, " %s\n", ref.c_str());
- if (sig.chunks.at(0).wire == NULL) {
- if (sig.chunks.at(0).data.bits.at(0) == RTLIL::State::S0)
- fprintf(f, " (portRef G (instanceRef GND))\n");
- if (sig.chunks.at(0).data.bits.at(0) == RTLIL::State::S1)
- fprintf(f, " (portRef P (instanceRef VCC))\n");
+ *f << stringf(" %s\n", ref.c_str());
+ if (sig.wire == NULL) {
+ if (sig == RTLIL::State::S0)
+ *f << stringf(" (portRef G (instanceRef GND))\n");
+ if (sig == RTLIL::State::S1)
+ *f << stringf(" (portRef P (instanceRef VCC))\n");
}
- fprintf(f, " ))\n");
+ *f << stringf(" ))\n");
}
- fprintf(f, " )\n");
- fprintf(f, " )\n");
- fprintf(f, " )\n");
+ *f << stringf(" )\n");
+ *f << stringf(" )\n");
+ *f << stringf(" )\n");
}
- fprintf(f, " )\n");
+ *f << stringf(" )\n");
- fprintf(f, " (design %s\n", EDIF_NAME(top_module_name));
- fprintf(f, " (cellRef %s (libraryRef DESIGN))\n", EDIF_NAME(top_module_name));
- fprintf(f, " )\n");
+ *f << stringf(" (design %s\n", EDIF_DEF(top_module_name));
+ *f << stringf(" (cellRef %s (libraryRef DESIGN))\n", EDIF_REF(top_module_name));
+ *f << stringf(" )\n");
- fprintf(f, ")\n");
+ *f << stringf(")\n");
}
} EdifBackend;
diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc
index c585d40c..48d818d7 100644
--- a/backends/ilang/ilang_backend.cc
+++ b/backends/ilang/ilang_backend.cc
@@ -23,16 +23,12 @@
*/
#include "ilang_backend.h"
-#include "kernel/register.h"
-#include "kernel/log.h"
-#include <string>
-#include <assert.h>
-#include <string.h>
+#include "kernel/yosys.h"
#include <errno.h>
using namespace ILANG_BACKEND;
-void ILANG_BACKEND::dump_const(FILE *f, const RTLIL::Const &data, int width, int offset, bool autoint)
+void ILANG_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int width, int offset, bool autoint)
{
if (width < 0)
width = data.bits.size() - offset;
@@ -40,7 +36,7 @@ void ILANG_BACKEND::dump_const(FILE *f, const RTLIL::Const &data, int width, int
if (width == 32 && autoint) {
int32_t val = 0;
for (int i = 0; i < width; i++) {
- assert(offset+i < (int)data.bits.size());
+ log_assert(offset+i < (int)data.bits.size());
switch (data.bits[offset+i]) {
case RTLIL::S0: break;
case RTLIL::S1: val |= 1 << i; break;
@@ -48,220 +44,230 @@ void ILANG_BACKEND::dump_const(FILE *f, const RTLIL::Const &data, int width, int
}
}
if (val >= 0) {
- fprintf(f, "%d", val);
+ f << stringf("%d", val);
return;
}
}
- fprintf(f, "%d'", width);
+ f << stringf("%d'", width);
for (int i = offset+width-1; i >= offset; i--) {
- assert(i < (int)data.bits.size());
+ log_assert(i < (int)data.bits.size());
switch (data.bits[i]) {
- case RTLIL::S0: fprintf(f, "0"); break;
- case RTLIL::S1: fprintf(f, "1"); break;
- case RTLIL::Sx: fprintf(f, "x"); break;
- case RTLIL::Sz: fprintf(f, "z"); break;
- case RTLIL::Sa: fprintf(f, "-"); break;
- case RTLIL::Sm: fprintf(f, "m"); break;
+ case RTLIL::S0: f << stringf("0"); break;
+ case RTLIL::S1: f << stringf("1"); break;
+ case RTLIL::Sx: f << stringf("x"); break;
+ case RTLIL::Sz: f << stringf("z"); break;
+ case RTLIL::Sa: f << stringf("-"); break;
+ case RTLIL::Sm: f << stringf("m"); break;
}
}
} else {
- fprintf(f, "\"");
+ f << stringf("\"");
std::string str = data.decode_string();
for (size_t i = 0; i < str.size(); i++) {
if (str[i] == '\n')
- fprintf(f, "\\n");
+ f << stringf("\\n");
else if (str[i] == '\t')
- fprintf(f, "\\t");
+ f << stringf("\\t");
else if (str[i] < 32)
- fprintf(f, "\\%03o", str[i]);
+ f << stringf("\\%03o", str[i]);
else if (str[i] == '"')
- fprintf(f, "\\\"");
+ f << stringf("\\\"");
else if (str[i] == '\\')
- fprintf(f, "\\\\");
+ f << stringf("\\\\");
else
- fputc(str[i], f);
+ f << str[i];
}
- fprintf(f, "\"");
+ f << stringf("\"");
}
}
-void ILANG_BACKEND::dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool autoint)
+void ILANG_BACKEND::dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, bool autoint)
{
if (chunk.wire == NULL) {
dump_const(f, chunk.data, chunk.width, chunk.offset, autoint);
} else {
if (chunk.width == chunk.wire->width && chunk.offset == 0)
- fprintf(f, "%s", chunk.wire->name.c_str());
+ f << stringf("%s", chunk.wire->name.c_str());
else if (chunk.width == 1)
- fprintf(f, "%s [%d]", chunk.wire->name.c_str(), chunk.offset);
+ f << stringf("%s [%d]", chunk.wire->name.c_str(), chunk.offset);
else
- fprintf(f, "%s [%d:%d]", chunk.wire->name.c_str(), chunk.offset+chunk.width-1, chunk.offset);
+ f << stringf("%s [%d:%d]", chunk.wire->name.c_str(), chunk.offset+chunk.width-1, chunk.offset);
}
}
-void ILANG_BACKEND::dump_sigspec(FILE *f, const RTLIL::SigSpec &sig, bool autoint)
+void ILANG_BACKEND::dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, bool autoint)
{
- if (sig.chunks.size() == 1) {
- dump_sigchunk(f, sig.chunks[0], autoint);
+ if (sig.is_chunk()) {
+ dump_sigchunk(f, sig.as_chunk(), autoint);
} else {
- fprintf(f, "{ ");
- for (auto it = sig.chunks.rbegin(); it != sig.chunks.rend(); it++) {
+ f << stringf("{ ");
+ for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); it++) {
dump_sigchunk(f, *it, false);
- fprintf(f, " ");
+ f << stringf(" ");
}
- fprintf(f, "}");
+ f << stringf("}");
}
}
-void ILANG_BACKEND::dump_wire(FILE *f, std::string indent, const RTLIL::Wire *wire)
+void ILANG_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire)
{
- for (auto it = wire->attributes.begin(); it != wire->attributes.end(); it++) {
- fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str());
+ std::map<RTLIL::IdString, RTLIL::Const, RTLIL::sort_by_id_str> sorted_attributes(wire->attributes.begin(), wire->attributes.end());
+
+ for (auto it = sorted_attributes.begin(); it != sorted_attributes.end(); it++) {
+ f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
dump_const(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
- fprintf(f, "%s" "wire ", indent.c_str());
+ f << stringf("%s" "wire ", indent.c_str());
if (wire->width != 1)
- fprintf(f, "width %d ", wire->width);
+ f << stringf("width %d ", wire->width);
+ if (wire->upto)
+ f << stringf("upto ");
if (wire->start_offset != 0)
- fprintf(f, "offset %d ", wire->start_offset);
+ f << stringf("offset %d ", wire->start_offset);
if (wire->port_input && !wire->port_output)
- fprintf(f, "input %d ", wire->port_id);
+ f << stringf("input %d ", wire->port_id);
if (!wire->port_input && wire->port_output)
- fprintf(f, "output %d ", wire->port_id);
+ f << stringf("output %d ", wire->port_id);
if (wire->port_input && wire->port_output)
- fprintf(f, "inout %d ", wire->port_id);
- fprintf(f, "%s\n", wire->name.c_str());
+ f << stringf("inout %d ", wire->port_id);
+ f << stringf("%s\n", wire->name.c_str());
}
-void ILANG_BACKEND::dump_memory(FILE *f, std::string indent, const RTLIL::Memory *memory)
+void ILANG_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL::Memory *memory)
{
- for (auto it = memory->attributes.begin(); it != memory->attributes.end(); it++) {
- fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str());
+ std::map<RTLIL::IdString, RTLIL::Const, RTLIL::sort_by_id_str> sorted_attributes(memory->attributes.begin(), memory->attributes.end());
+
+ for (auto it = sorted_attributes.begin(); it != sorted_attributes.end(); it++) {
+ f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
dump_const(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
- fprintf(f, "%s" "memory ", indent.c_str());
+ f << stringf("%s" "memory ", indent.c_str());
if (memory->width != 1)
- fprintf(f, "width %d ", memory->width);
+ f << stringf("width %d ", memory->width);
if (memory->size != 0)
- fprintf(f, "size %d ", memory->size);
- fprintf(f, "%s\n", memory->name.c_str());
+ f << stringf("size %d ", memory->size);
+ f << stringf("%s\n", memory->name.c_str());
}
-void ILANG_BACKEND::dump_cell(FILE *f, std::string indent, const RTLIL::Cell *cell)
+void ILANG_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL::Cell *cell)
{
- for (auto it = cell->attributes.begin(); it != cell->attributes.end(); it++) {
- fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str());
+ std::map<RTLIL::IdString, RTLIL::Const, RTLIL::sort_by_id_str> sorted_attributes(cell->attributes.begin(), cell->attributes.end());
+ std::map<RTLIL::IdString, RTLIL::Const, RTLIL::sort_by_id_str> sorted_parameters(cell->parameters.begin(), cell->parameters.end());
+ std::map<RTLIL::IdString, RTLIL::SigSpec, RTLIL::sort_by_id_str> sorted_connections(cell->connections().begin(), cell->connections().end());
+
+ for (auto it = sorted_attributes.begin(); it != sorted_attributes.end(); it++) {
+ f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
dump_const(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
- fprintf(f, "%s" "cell %s %s\n", indent.c_str(), cell->type.c_str(), cell->name.c_str());
- for (auto it = cell->parameters.begin(); it != cell->parameters.end(); it++) {
- fprintf(f, "%s parameter%s %s ", indent.c_str(), (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "", it->first.c_str());
+ f << stringf("%s" "cell %s %s\n", indent.c_str(), cell->type.c_str(), cell->name.c_str());
+ for (auto it = sorted_parameters.begin(); it != sorted_parameters.end(); it++) {
+ f << stringf("%s parameter%s %s ", indent.c_str(), (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "", it->first.c_str());
dump_const(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
- for (auto it = cell->connections.begin(); it != cell->connections.end(); it++) {
- fprintf(f, "%s connect %s ", indent.c_str(), it->first.c_str());
+ for (auto it = sorted_connections.begin(); it != sorted_connections.end(); it++) {
+ f << stringf("%s connect %s ", indent.c_str(), it->first.c_str());
dump_sigspec(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
- fprintf(f, "%s" "end\n", indent.c_str());
+ f << stringf("%s" "end\n", indent.c_str());
}
-void ILANG_BACKEND::dump_proc_case_body(FILE *f, std::string indent, const RTLIL::CaseRule *cs)
+void ILANG_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++)
{
- fprintf(f, "%s" "assign ", indent.c_str());
+ f << stringf("%s" "assign ", indent.c_str());
dump_sigspec(f, it->first);
- fprintf(f, " ");
+ f << stringf(" ");
dump_sigspec(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
for (auto it = cs->switches.begin(); it != cs->switches.end(); it++)
dump_proc_switch(f, indent, *it);
}
-void ILANG_BACKEND::dump_proc_switch(FILE *f, std::string indent, const RTLIL::SwitchRule *sw)
+void ILANG_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++) {
- fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str());
+ f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
dump_const(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
- fprintf(f, "%s" "switch ", indent.c_str());
+ f << stringf("%s" "switch ", indent.c_str());
dump_sigspec(f, sw->signal);
- fprintf(f, "\n");
+ f << stringf("\n");
for (auto it = sw->cases.begin(); it != sw->cases.end(); it++)
{
- fprintf(f, "%s case ", indent.c_str());
+ f << stringf("%s case ", indent.c_str());
for (size_t i = 0; i < (*it)->compare.size(); i++) {
if (i > 0)
- fprintf(f, ", ");
+ f << stringf(", ");
dump_sigspec(f, (*it)->compare[i]);
}
- fprintf(f, "\n");
+ f << stringf("\n");
dump_proc_case_body(f, indent + " ", *it);
}
- fprintf(f, "%s" "end\n", indent.c_str());
+ f << stringf("%s" "end\n", indent.c_str());
}
-void ILANG_BACKEND::dump_proc_sync(FILE *f, std::string indent, const RTLIL::SyncRule *sy)
+void ILANG_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RTLIL::SyncRule *sy)
{
- fprintf(f, "%s" "sync ", indent.c_str());
+ f << stringf("%s" "sync ", indent.c_str());
switch (sy->type) {
- if (0) case RTLIL::ST0: fprintf(f, "low ");
- if (0) case RTLIL::ST1: fprintf(f, "high ");
- if (0) case RTLIL::STp: fprintf(f, "posedge ");
- if (0) case RTLIL::STn: fprintf(f, "negedge ");
- if (0) case RTLIL::STe: fprintf(f, "edge ");
+ if (0) case RTLIL::ST0: f << stringf("low ");
+ if (0) case RTLIL::ST1: f << stringf("high ");
+ if (0) case RTLIL::STp: f << stringf("posedge ");
+ if (0) case RTLIL::STn: f << stringf("negedge ");
+ if (0) case RTLIL::STe: f << stringf("edge ");
dump_sigspec(f, sy->signal);
- fprintf(f, "\n");
+ f << stringf("\n");
break;
- case RTLIL::STa: fprintf(f, "always\n"); break;
- case RTLIL::STi: fprintf(f, "init\n"); break;
+ case RTLIL::STa: f << stringf("always\n"); break;
+ case RTLIL::STi: f << stringf("init\n"); break;
}
for (auto it = sy->actions.begin(); it != sy->actions.end(); it++) {
- fprintf(f, "%s update ", indent.c_str());
+ f << stringf("%s update ", indent.c_str());
dump_sigspec(f, it->first);
- fprintf(f, " ");
+ f << stringf(" ");
dump_sigspec(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
}
-void ILANG_BACKEND::dump_proc(FILE *f, std::string indent, const RTLIL::Process *proc)
+void ILANG_BACKEND::dump_proc(std::ostream &f, std::string indent, const RTLIL::Process *proc)
{
for (auto it = proc->attributes.begin(); it != proc->attributes.end(); it++) {
- fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str());
+ f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
dump_const(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
- fprintf(f, "%s" "process %s\n", indent.c_str(), proc->name.c_str());
+ f << stringf("%s" "process %s\n", indent.c_str(), proc->name.c_str());
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);
- fprintf(f, "%s" "end\n", indent.c_str());
+ f << stringf("%s" "end\n", indent.c_str());
}
-void ILANG_BACKEND::dump_conn(FILE *f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
+void ILANG_BACKEND::dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
{
- fprintf(f, "%s" "connect ", indent.c_str());
+ f << stringf("%s" "connect ", indent.c_str());
dump_sigspec(f, left);
- fprintf(f, " ");
+ f << stringf(" ");
dump_sigspec(f, right);
- fprintf(f, "\n");
+ f << stringf("\n");
}
-void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module *module, const RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n)
+void ILANG_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Module *module, RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n)
{
bool print_header = flag_m || design->selected_whole_module(module->name);
bool print_body = !flag_n || !design->selected_whole_module(module->name);
@@ -269,51 +275,71 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module
if (print_header)
{
for (auto it = module->attributes.begin(); it != module->attributes.end(); it++) {
- fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str());
+ f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
dump_const(f, it->second);
- fprintf(f, "\n");
+ f << stringf("\n");
}
- fprintf(f, "%s" "module %s\n", indent.c_str(), module->name.c_str());
+ f << stringf("%s" "module %s\n", indent.c_str(), module->name.c_str());
}
if (print_body)
{
- for (auto it = module->wires.begin(); it != module->wires.end(); it++)
- if (!only_selected || design->selected(module, it->second)) {
+ std::vector<RTLIL::Wire*> sorted_wires;
+ for (auto it : module->wires())
+ sorted_wires.push_back(it);
+ std::sort(sorted_wires.begin(), sorted_wires.end(), RTLIL::sort_by_name_str<RTLIL::Wire>());
+
+ std::vector<RTLIL::Memory*> sorted_memories;
+ for (auto it : module->memories)
+ sorted_memories.push_back(it.second);
+ std::sort(sorted_memories.begin(), sorted_memories.end(), RTLIL::sort_by_name_str<RTLIL::Memory>());
+
+ std::vector<RTLIL::Cell*> sorted_cells;
+ for (auto it : module->cells())
+ sorted_cells.push_back(it);
+ std::sort(sorted_cells.begin(), sorted_cells.end(), RTLIL::sort_by_name_str<RTLIL::Cell>());
+
+ std::vector<RTLIL::Process*> sorted_processes;
+ for (auto it : module->processes)
+ sorted_processes.push_back(it.second);
+ std::sort(sorted_processes.begin(), sorted_processes.end(), RTLIL::sort_by_name_str<RTLIL::Process>());
+
+ for (auto it : sorted_wires)
+ if (!only_selected || design->selected(module, it)) {
if (only_selected)
- fprintf(f, "\n");
- dump_wire(f, indent + " ", it->second);
+ f << stringf("\n");
+ dump_wire(f, indent + " ", it);
}
- for (auto it = module->memories.begin(); it != module->memories.end(); it++)
- if (!only_selected || design->selected(module, it->second)) {
+ for (auto it : sorted_memories)
+ if (!only_selected || design->selected(module, it)) {
if (only_selected)
- fprintf(f, "\n");
- dump_memory(f, indent + " ", it->second);
+ f << stringf("\n");
+ dump_memory(f, indent + " ", it);
}
- for (auto it = module->cells.begin(); it != module->cells.end(); it++)
- if (!only_selected || design->selected(module, it->second)) {
+ for (auto it : sorted_cells)
+ if (!only_selected || design->selected(module, it)) {
if (only_selected)
- fprintf(f, "\n");
- dump_cell(f, indent + " ", it->second);
+ f << stringf("\n");
+ dump_cell(f, indent + " ", it);
}
- for (auto it = module->processes.begin(); it != module->processes.end(); it++)
- if (!only_selected || design->selected(module, it->second)) {
+ for (auto it : sorted_processes)
+ if (!only_selected || design->selected(module, it)) {
if (only_selected)
- fprintf(f, "\n");
- dump_proc(f, indent + " ", it->second);
+ f << stringf("\n");
+ dump_proc(f, indent + " ", it);
}
bool first_conn_line = true;
- for (auto it = module->connections.begin(); it != module->connections.end(); it++) {
+ for (auto it = module->connections().begin(); it != module->connections().end(); it++) {
bool show_conn = !only_selected;
if (only_selected) {
RTLIL::SigSpec sigs = it->first;
sigs.append(it->second);
- for (auto &c : sigs.chunks) {
+ for (auto &c : sigs.chunks()) {
if (c.wire == NULL || !design->selected(module, c.wire))
continue;
show_conn = true;
@@ -321,7 +347,7 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module
}
if (show_conn) {
if (only_selected && first_conn_line)
- fprintf(f, "\n");
+ f << stringf("\n");
dump_conn(f, indent + " ", it->first, it->second);
first_conn_line = false;
}
@@ -329,27 +355,40 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module
}
if (print_header)
- fprintf(f, "%s" "end\n", indent.c_str());
+ f << stringf("%s" "end\n", indent.c_str());
}
-void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n)
+void ILANG_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n)
{
+ int init_autoidx = autoidx;
+
if (!flag_m) {
int count_selected_mods = 0;
- for (auto it = design->modules.begin(); it != design->modules.end(); it++)
+ for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) {
+ if (design->selected_whole_module(it->first))
+ flag_m = true;
if (design->selected(it->second))
count_selected_mods++;
+ }
if (count_selected_mods > 1)
flag_m = true;
}
- for (auto it = design->modules.begin(); it != design->modules.end(); it++) {
+ if (!only_selected || flag_m) {
+ if (only_selected)
+ f << stringf("\n");
+ f << stringf("autoidx %d\n", autoidx);
+ }
+
+ for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) {
if (!only_selected || design->selected(it->second)) {
if (only_selected)
- fprintf(f, "\n");
+ f << stringf("\n");
dump_module(f, "", it->second, design, only_selected, flag_m, flag_n);
}
}
+
+ log_assert(init_autoidx == autoidx);
}
struct IlangBackend : public Backend {
@@ -367,7 +406,7 @@ struct IlangBackend : public Backend {
log(" only write selected parts of the design.\n");
log("\n");
}
- virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
+ virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
{
bool selected = false;
@@ -385,8 +424,8 @@ struct IlangBackend : public Backend {
extra_args(f, filename, args, argidx);
log("Output filename: %s\n", filename.c_str());
- fprintf(f, "# Generated by %s\n", yosys_version_str);
- ILANG_BACKEND::dump_design(f, design, selected, true, false);
+ *f << stringf("# Generated by %s\n", yosys_version_str);
+ ILANG_BACKEND::dump_design(*f, design, selected, true, false);
}
} IlangBackend;
@@ -446,25 +485,27 @@ struct DumpPass : public Pass {
}
extra_args(args, argidx, design);
- FILE *f = NULL;
- char *buf_ptr;
- size_t buf_size;
+ std::ostream *f;
+ std::stringstream buf;
if (!filename.empty()) {
- f = fopen(filename.c_str(), append ? "a" : "w");
- if (f == NULL)
+ std::ofstream *ff = new std::ofstream;
+ ff->open(filename.c_str(), 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));
+ }
+ f = ff;
} else {
- f = open_memstream(&buf_ptr, &buf_size);
+ f = &buf;
}
- ILANG_BACKEND::dump_design(f, design, true, flag_m, flag_n);
+ ILANG_BACKEND::dump_design(*f, design, true, flag_m, flag_n);
- fclose(f);
-
- if (filename.empty()) {
- log("%s", buf_ptr);
- free(buf_ptr);
+ if (!filename.empty()) {
+ delete f;
+ } else {
+ log("%s", buf.str().c_str());
}
}
} DumpPass;
diff --git a/backends/ilang/ilang_backend.h b/backends/ilang/ilang_backend.h
index fecbcc1f..159cd719 100644
--- a/backends/ilang/ilang_backend.h
+++ b/backends/ilang/ilang_backend.h
@@ -25,23 +25,27 @@
#ifndef ILANG_BACKEND_H
#define ILANG_BACKEND_H
-#include "kernel/rtlil.h"
+#include "kernel/yosys.h"
#include <stdio.h>
+YOSYS_NAMESPACE_BEGIN
+
namespace ILANG_BACKEND {
- void dump_const(FILE *f, const RTLIL::Const &data, int width = -1, int offset = 0, bool autoint = true);
- void dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool autoint = true);
- void dump_sigspec(FILE *f, const RTLIL::SigSpec &sig, bool autoint = true);
- void dump_wire(FILE *f, std::string indent, const RTLIL::Wire *wire);
- void dump_memory(FILE *f, std::string indent, const RTLIL::Memory *memory);
- void dump_cell(FILE *f, std::string indent, const RTLIL::Cell *cell);
- void dump_proc_case_body(FILE *f, std::string indent, const RTLIL::CaseRule *cs);
- void dump_proc_switch(FILE *f, std::string indent, const RTLIL::SwitchRule *sw);
- void dump_proc_sync(FILE *f, std::string indent, const RTLIL::SyncRule *sy);
- void dump_proc(FILE *f, std::string indent, const RTLIL::Process *proc);
- void dump_conn(FILE *f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right);
- void dump_module(FILE *f, std::string indent, const RTLIL::Module *module, const RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false);
- void dump_design(FILE *f, const RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false);
+ 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);
+ void dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire);
+ void dump_memory(std::ostream &f, std::string indent, const RTLIL::Memory *memory);
+ void dump_cell(std::ostream &f, std::string indent, const RTLIL::Cell *cell);
+ void dump_proc_case_body(std::ostream &f, std::string indent, const RTLIL::CaseRule *cs);
+ void dump_proc_switch(std::ostream &f, std::string indent, const RTLIL::SwitchRule *sw);
+ void dump_proc_sync(std::ostream &f, std::string indent, const RTLIL::SyncRule *sy);
+ void dump_proc(std::ostream &f, std::string indent, const RTLIL::Process *proc);
+ void dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right);
+ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module, RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false);
+ void dump_design(std::ostream &f, RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false);
}
+YOSYS_NAMESPACE_END
+
#endif
diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc
index 47c1125f..8502d90f 100644
--- a/backends/intersynth/intersynth.cc
+++ b/backends/intersynth/intersynth.cc
@@ -23,30 +23,23 @@
#include "kernel/celltypes.h"
#include "kernel/log.h"
#include <string>
-#include <assert.h>
static std::string netname(std::set<std::string> &conntypes_code, std::set<std::string> &celltypes_code, std::set<std::string> &constcells_code, RTLIL::SigSpec sig)
{
- sig.optimize();
-
- if (sig.chunks.size() != 1)
-error:
+ if (!sig.is_fully_const() && !sig.is_wire())
log_error("Can't export composite or non-word-wide signal %s.\n", log_signal(sig));
- conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.width, sig.width, sig.width));
+ conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.size(), sig.size(), sig.size()));
- if (sig.chunks[0].wire == NULL) {
- celltypes_code.insert(stringf("celltype CONST_%d b%d *CONST cfg:%d VALUE\n", sig.width, sig.width, sig.width));
- constcells_code.insert(stringf("node CONST_%d_0x%x CONST_%d CONST CONST_%d_0x%x VALUE 0x%x\n", sig.width, sig.chunks[0].data.as_int(),
- sig.width, sig.width, sig.chunks[0].data.as_int(), sig.chunks[0].data.as_int()));
- return stringf("CONST_%d_0x%x", sig.width, sig.chunks[0].data.as_int());
+ if (sig.is_fully_const()) {
+ celltypes_code.insert(stringf("celltype CONST_%d b%d *CONST cfg:%d VALUE\n", sig.size(), sig.size(), sig.size()));
+ constcells_code.insert(stringf("node CONST_%d_0x%x CONST_%d CONST CONST_%d_0x%x VALUE 0x%x\n",
+ sig.size(), sig.as_int(), sig.size(), sig.size(), sig.as_int(), sig.as_int()));
+ return stringf("CONST_%d_0x%x", sig.size(), sig.as_int());
}
- if (sig.chunks[0].offset != 0 || sig.width != sig.chunks[0].wire->width)
- goto error;
-
- return RTLIL::unescape_id(sig.chunks[0].wire->name);
+ return RTLIL::unescape_id(sig.as_wire()->name);
}
struct IntersynthBackend : public Backend {
@@ -76,7 +69,7 @@ struct IntersynthBackend : public Backend {
log("http://www.clifford.at/intersynth/\n");
log("\n");
}
- virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
+ virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
{
log_header("Executing INTERSYNTH backend.\n");
log_push();
@@ -108,13 +101,13 @@ struct IntersynthBackend : public Backend {
log("Output filename: %s\n", filename.c_str());
for (auto filename : libfiles) {
- FILE *f = fopen(filename.c_str(), "rt");
- if (f == NULL)
+ std::ifstream f;
+ f.open(filename.c_str());
+ if (f.fail())
log_error("Can't open lib file `%s'.\n", filename.c_str());
RTLIL::Design *lib = new RTLIL::Design;
- Frontend::frontend_call(lib, f, filename, (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") ? "ilang" : "verilog");
+ Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") ? "ilang" : "verilog");
libs.push_back(lib);
- fclose(f);
}
if (libs.size() > 0)
@@ -127,14 +120,14 @@ struct IntersynthBackend : public Backend {
for (auto lib : libs)
ct.setup_design(lib);
- for (auto module_it : design->modules)
+ for (auto module_it : design->modules_)
{
RTLIL::Module *module = module_it.second;
SigMap sigmap(module);
if (module->get_bool_attribute("\\blackbox"))
continue;
- if (module->memories.size() == 0 && module->processes.size() == 0 && module->cells.size() == 0)
+ if (module->memories.size() == 0 && module->processes.size() == 0 && module->cells_.size() == 0)
continue;
if (selected && !design->selected_whole_module(module->name)) {
@@ -153,7 +146,7 @@ struct IntersynthBackend : public Backend {
netlists_code += stringf("netlist %s\n", RTLIL::id2cstr(module->name));
// Module Ports: "std::set<string> celltypes_code" prevents duplicate top level ports
- for (auto wire_it : module->wires) {
+ for (auto wire_it : module->wires_) {
RTLIL::Wire *wire = wire_it.second;
if (wire->port_input || wire->port_output) {
celltypes_code.insert(stringf("celltype !%s b%d %sPORT\n" "%s %s %d %s PORT\n",
@@ -165,7 +158,7 @@ struct IntersynthBackend : public Backend {
}
// Submodules: "std::set<string> celltypes_code" prevents duplicate cell types
- for (auto cell_it : module->cells)
+ for (auto cell_it : module->cells_)
{
RTLIL::Cell *cell = cell_it.second;
std::string celltype_code, node_code;
@@ -175,11 +168,11 @@ struct IntersynthBackend : public Backend {
celltype_code = stringf("celltype %s", RTLIL::id2cstr(cell->type));
node_code = stringf("node %s %s", RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
- for (auto &port : cell->connections) {
+ for (auto &port : cell->connections()) {
RTLIL::SigSpec sig = sigmap(port.second);
- if (sig.width != 0) {
- conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.width, sig.width, sig.width));
- celltype_code += stringf(" b%d %s%s", sig.width, ct.cell_output(cell->type, port.first) ? "*" : "", RTLIL::id2cstr(port.first));
+ 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) ? "*" : "", RTLIL::id2cstr(port.first));
node_code += stringf(" %s %s", RTLIL::id2cstr(port.first), netname(conntypes_code, celltypes_code, constcells_code, sig).c_str());
}
}
@@ -205,15 +198,15 @@ struct IntersynthBackend : public Backend {
}
if (!flag_notypes) {
- fprintf(f, "### Connection Types\n");
+ *f << stringf("### Connection Types\n");
for (auto code : conntypes_code)
- fprintf(f, "%s", code.c_str());
- fprintf(f, "\n### Cell Types\n");
+ *f << stringf("%s", code.c_str());
+ *f << stringf("\n### Cell Types\n");
for (auto code : celltypes_code)
- fprintf(f, "%s", code.c_str());
+ *f << stringf("%s", code.c_str());
}
- fprintf(f, "\n### Netlists\n");
- fprintf(f, "%s", netlists_code.c_str());
+ *f << stringf("\n### Netlists\n");
+ *f << stringf("%s", netlists_code.c_str());
for (auto lib : libs)
delete lib;
diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc
index e7926e90..b057063c 100644
--- a/backends/spice/spice.cc
+++ b/backends/spice/spice.cc
@@ -23,53 +23,51 @@
#include "kernel/celltypes.h"
#include "kernel/log.h"
#include <string>
-#include <assert.h>
-static void print_spice_net(FILE *f, RTLIL::SigSpec s, std::string &neg, std::string &pos, std::string &ncpf, int &nc_counter)
+static void print_spice_net(std::ostream &f, RTLIL::SigBit s, std::string &neg, std::string &pos, std::string &ncpf, int &nc_counter)
{
- log_assert(s.chunks.size() == 1 && s.chunks[0].width == 1);
- if (s.chunks[0].wire) {
- if (s.chunks[0].wire->width > 1)
- fprintf(f, " %s[%d]", RTLIL::id2cstr(s.chunks[0].wire->name), s.chunks[0].offset);
+ if (s.wire) {
+ if (s.wire->width > 1)
+ f << stringf(" %s[%d]", RTLIL::id2cstr(s.wire->name), s.offset);
else
- fprintf(f, " %s", RTLIL::id2cstr(s.chunks[0].wire->name));
+ f << stringf(" %s", RTLIL::id2cstr(s.wire->name));
} else {
- if (s.chunks[0].data.bits.at(0) == RTLIL::State::S0)
- fprintf(f, " %s", neg.c_str());
- else if (s.chunks[0].data.bits.at(0) == RTLIL::State::S1)
- fprintf(f, " %s", pos.c_str());
+ if (s == RTLIL::State::S0)
+ f << stringf(" %s", neg.c_str());
+ else if (s == RTLIL::State::S1)
+ f << stringf(" %s", pos.c_str());
else
- fprintf(f, " %s%d", ncpf.c_str(), nc_counter++);
+ f << stringf(" %s%d", ncpf.c_str(), nc_counter++);
}
}
-static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *design, std::string &neg, std::string &pos, std::string &ncpf, bool big_endian)
+static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, std::string &neg, std::string &pos, std::string &ncpf, bool big_endian)
{
SigMap sigmap(module);
int cell_counter = 0, conn_counter = 0, nc_counter = 0;
- for (auto &cell_it : module->cells)
+ for (auto &cell_it : module->cells_)
{
RTLIL::Cell *cell = cell_it.second;
- fprintf(f, "X%d", cell_counter++);
+ f << stringf("X%d", cell_counter++);
std::vector<RTLIL::SigSpec> port_sigs;
- if (design->modules.count(cell->type) == 0)
+ if (design->modules_.count(cell->type) == 0)
{
log("Warning: no (blackbox) module for cell type `%s' (%s.%s) found! Guessing order of ports.\n",
RTLIL::id2cstr(cell->type), RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name));
- for (auto &conn : cell->connections) {
+ for (auto &conn : cell->connections()) {
RTLIL::SigSpec sig = sigmap(conn.second);
port_sigs.push_back(sig);
}
}
else
{
- RTLIL::Module *mod = design->modules.at(cell->type);
+ RTLIL::Module *mod = design->modules_.at(cell->type);
std::vector<RTLIL::Wire*> ports;
- for (auto wire_it : mod->wires) {
+ for (auto wire_it : mod->wires_) {
RTLIL::Wire *wire = wire_it.second;
if (wire->port_id == 0)
continue;
@@ -81,8 +79,8 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de
for (RTLIL::Wire *wire : ports) {
log_assert(wire != NULL);
RTLIL::SigSpec sig(RTLIL::State::Sz, wire->width);
- if (cell->connections.count(wire->name) > 0) {
- sig = sigmap(cell->connections.at(wire->name));
+ if (cell->hasPort(wire->name)) {
+ sig = sigmap(cell->getPort(wire->name));
sig.extend(wire->width, false);
}
port_sigs.push_back(sig);
@@ -90,22 +88,21 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de
}
for (auto &sig : port_sigs) {
- for (int i = 0; i < sig.width; i++) {
- RTLIL::SigSpec s = sig.extract(big_endian ? sig.width - 1 - i : i, 1);
- log_assert(s.chunks.size() == 1 && s.chunks[0].width == 1);
+ for (int i = 0; i < sig.size(); i++) {
+ RTLIL::SigSpec s = sig.extract(big_endian ? sig.size() - 1 - i : i, 1);
print_spice_net(f, s, neg, pos, ncpf, nc_counter);
}
}
- fprintf(f, " %s\n", RTLIL::id2cstr(cell->type));
+ f << stringf(" %s\n", RTLIL::id2cstr(cell->type));
}
- for (auto &conn : module->connections)
- for (int i = 0; i < conn.first.width; i++) {
- fprintf(f, "V%d", conn_counter++);
+ for (auto &conn : module->connections())
+ for (int i = 0; i < conn.first.size(); i++) {
+ f << stringf("V%d", conn_counter++);
print_spice_net(f, conn.first.extract(i, 1), neg, pos, ncpf, nc_counter);
print_spice_net(f, conn.second.extract(i, 1), neg, pos, ncpf, nc_counter);
- fprintf(f, " DC 0\n");
+ f << stringf(" DC 0\n");
}
}
@@ -136,7 +133,7 @@ struct SpiceBackend : public Backend {
log(" set the specified module as design top module\n");
log("\n");
}
- virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
+ virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
{
std::string top_module_name;
RTLIL::Module *top_module = NULL;
@@ -173,14 +170,14 @@ struct SpiceBackend : public Backend {
extra_args(f, filename, args, argidx);
if (top_module_name.empty())
- for (auto & mod_it:design->modules)
+ for (auto & mod_it:design->modules_)
if (mod_it.second->get_bool_attribute("\\top"))
- top_module_name = mod_it.first;
+ top_module_name = mod_it.first.str();
- fprintf(f, "* SPICE netlist generated by %s\n", yosys_version_str);
- fprintf(f, "\n");
+ *f << stringf("* SPICE netlist generated by %s\n", yosys_version_str);
+ *f << stringf("\n");
- for (auto module_it : design->modules)
+ for (auto module_it : design->modules_)
{
RTLIL::Module *module = module_it.second;
if (module->get_bool_attribute("\\blackbox"))
@@ -197,7 +194,7 @@ struct SpiceBackend : public Backend {
}
std::vector<RTLIL::Wire*> ports;
- for (auto wire_it : module->wires) {
+ for (auto wire_it : module->wires_) {
RTLIL::Wire *wire = wire_it.second;
if (wire->port_id == 0)
continue;
@@ -206,31 +203,31 @@ struct SpiceBackend : public Backend {
ports.at(wire->port_id-1) = wire;
}
- fprintf(f, ".SUBCKT %s", RTLIL::id2cstr(module->name));
+ *f << stringf(".SUBCKT %s", RTLIL::id2cstr(module->name));
for (RTLIL::Wire *wire : ports) {
log_assert(wire != NULL);
if (wire->width > 1) {
for (int i = 0; i < wire->width; i++)
- fprintf(f, " %s[%d]", RTLIL::id2cstr(wire->name), big_endian ? wire->width - 1 - i : i);
+ *f << stringf(" %s[%d]", RTLIL::id2cstr(wire->name), big_endian ? wire->width - 1 - i : i);
} else
- fprintf(f, " %s", RTLIL::id2cstr(wire->name));
+ *f << stringf(" %s", RTLIL::id2cstr(wire->name));
}
- fprintf(f, "\n");
- print_spice_module(f, module, design, neg, pos, ncpf, big_endian);
- fprintf(f, ".ENDS %s\n\n", RTLIL::id2cstr(module->name));
+ *f << stringf("\n");
+ print_spice_module(*f, module, design, neg, pos, ncpf, big_endian);
+ *f << stringf(".ENDS %s\n\n", RTLIL::id2cstr(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());
- print_spice_module(f, top_module, design, neg, pos, ncpf, big_endian);
- fprintf(f, "\n");
+ print_spice_module(*f, top_module, design, neg, pos, ncpf, big_endian);
+ *f << stringf("\n");
}
- fprintf(f, "************************\n");
- fprintf(f, "* end of SPICE netlist *\n");
- fprintf(f, "************************\n");
- fprintf(f, "\n");
+ *f << stringf("************************\n");
+ *f << stringf("* end of SPICE netlist *\n");
+ *f << stringf("************************\n");
+ *f << stringf("\n");
}
} SpiceBackend;
diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc
index d7fe4c4e..bbdbbbfa 100644
--- a/backends/verilog/verilog_backend.cc
+++ b/backends/verilog/verilog_backend.cc
@@ -30,7 +30,6 @@
#include "kernel/register.h"
#include "kernel/celltypes.h"
#include "kernel/log.h"
-#include <assert.h>
#include <string>
#include <sstream>
#include <set>
@@ -40,14 +39,12 @@ namespace {
bool norename, noattr, attr2comment, noexpr;
int auto_name_counter, auto_name_offset, auto_name_digits;
-std::map<std::string, int> auto_name_map;
+std::map<RTLIL::IdString, int> auto_name_map;
+std::set<RTLIL::IdString> reg_wires, reg_ct;
-std::set<std::string> reg_wires;
-
-CellTypes reg_ct;
RTLIL::Module *active_module;
-void reset_auto_counter_id(const std::string &id, bool may_rename)
+void reset_auto_counter_id(RTLIL::IdString id, bool may_rename)
{
const char *str = id.c_str();
@@ -76,10 +73,10 @@ void reset_auto_counter(RTLIL::Module *module)
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);
}
@@ -95,7 +92,7 @@ void reset_auto_counter(RTLIL::Module *module)
log(" renaming `%s' to `_%0*d_'.\n", it->first.c_str(), auto_name_digits, auto_name_offset + it->second);
}
-std::string id(std::string internal_id, bool may_rename = true)
+std::string id(RTLIL::IdString internal_id, bool may_rename = true)
{
const char *str = internal_id.c_str();
bool do_escape = false;
@@ -133,23 +130,27 @@ std::string id(std::string internal_id, bool may_rename = true)
bool is_reg_wire(RTLIL::SigSpec sig, std::string &reg_name)
{
- sig.optimize();
- if (sig.chunks.size() != 1 || sig.chunks[0].wire == NULL)
+ if (!sig.is_chunk() || sig.as_chunk().wire == NULL)
return false;
- if (reg_wires.count(sig.chunks[0].wire->name) == 0)
+
+ RTLIL::SigChunk chunk = sig.as_chunk();
+
+ if (reg_wires.count(chunk.wire->name) == 0)
return false;
- reg_name = id(sig.chunks[0].wire->name);
- if (sig.width != sig.chunks[0].wire->width) {
- if (sig.width == 1)
- reg_name += stringf("[%d]", sig.chunks[0].wire->start_offset + sig.chunks[0].offset);
+
+ reg_name = id(chunk.wire->name);
+ if (sig.size() != chunk.wire->width) {
+ if (sig.size() == 1)
+ reg_name += stringf("[%d]", chunk.wire->start_offset + chunk.offset);
else
- reg_name += stringf("[%d:%d]", sig.chunks[0].wire->start_offset + sig.chunks[0].offset + sig.chunks[0].width - 1,
- sig.chunks[0].wire->start_offset + sig.chunks[0].offset);
+ reg_name += stringf("[%d:%d]", chunk.wire->start_offset + chunk.offset + chunk.width - 1,
+ chunk.wire->start_offset + chunk.offset);
}
+
return true;
}
-void dump_const(FILE *f, 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)
{
if (width < 0)
width = data.bits.size() - offset;
@@ -157,159 +158,172 @@ void dump_const(FILE *f, RTLIL::Const &data, int width = -1, int offset = 0, boo
if (width == 32 && !no_decimal) {
int32_t val = 0;
for (int i = offset+width-1; i >= offset; i--) {
- assert(i < (int)data.bits.size());
+ log_assert(i < (int)data.bits.size());
if (data.bits[i] != RTLIL::S0 && data.bits[i] != RTLIL::S1)
goto dump_bits;
+ if (data.bits[i] == RTLIL::S1 && (i - offset) == 31)
+ goto dump_bits;
if (data.bits[i] == RTLIL::S1)
val |= 1 << (i - offset);
}
- // fprintf(f, "%s32'sd%u", val < 0 ? "-" : "", abs(val));
- fprintf(f, "%d", val);
+ f << stringf("32'%sd%d", set_signed ? "s" : "", val);
} else {
dump_bits:
- fprintf(f, "%d'%sb", width, set_signed ? "s" : "");
+ f << stringf("%d'%sb", width, set_signed ? "s" : "");
if (width == 0)
- fprintf(f, "0");
+ f << stringf("0");
for (int i = offset+width-1; i >= offset; i--) {
- assert(i < (int)data.bits.size());
+ log_assert(i < (int)data.bits.size());
switch (data.bits[i]) {
- case RTLIL::S0: fprintf(f, "0"); break;
- case RTLIL::S1: fprintf(f, "1"); break;
- case RTLIL::Sx: fprintf(f, "x"); break;
- case RTLIL::Sz: fprintf(f, "z"); break;
- case RTLIL::Sa: fprintf(f, "z"); break;
+ case RTLIL::S0: f << stringf("0"); break;
+ case RTLIL::S1: f << stringf("1"); break;
+ case RTLIL::Sx: f << stringf("x"); break;
+ case RTLIL::Sz: f << stringf("z"); break;
+ case RTLIL::Sa: f << stringf("z"); break;
case RTLIL::Sm: log_error("Found marker state in final netlist.");
}
}
}
} else {
- fprintf(f, "\"");
+ f << stringf("\"");
std::string str = data.decode_string();
for (size_t i = 0; i < str.size(); i++) {
if (str[i] == '\n')
- fprintf(f, "\\n");
+ f << stringf("\\n");
else if (str[i] == '\t')
- fprintf(f, "\\t");
+ f << stringf("\\t");
else if (str[i] < 32)
- fprintf(f, "\\%03o", str[i]);
+ f << stringf("\\%03o", str[i]);
else if (str[i] == '"')
- fprintf(f, "\\\"");
+ f << stringf("\\\"");
else if (str[i] == '\\')
- fprintf(f, "\\\\");
+ f << stringf("\\\\");
else
- fputc(str[i], f);
+ f << str[i];
}
- fprintf(f, "\"");
+ f << stringf("\"");
}
}
-void dump_sigchunk(FILE *f, RTLIL::SigChunk &chunk, bool no_decimal = false)
+void dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, bool no_decimal = false)
{
if (chunk.wire == NULL) {
dump_const(f, chunk.data, chunk.width, chunk.offset, no_decimal);
} else {
- if (chunk.width == chunk.wire->width && chunk.offset == 0)
- fprintf(f, "%s", id(chunk.wire->name).c_str());
- else if (chunk.width == 1)
- fprintf(f, "%s[%d]", id(chunk.wire->name).c_str(), chunk.offset + chunk.wire->start_offset);
- else
- fprintf(f, "%s[%d:%d]", id(chunk.wire->name).c_str(),
- chunk.offset + chunk.wire->start_offset + chunk.width - 1,
- chunk.offset + chunk.wire->start_offset);
+ if (chunk.width == chunk.wire->width && chunk.offset == 0) {
+ f << stringf("%s", id(chunk.wire->name).c_str());
+ } else if (chunk.width == 1) {
+ if (chunk.wire->upto)
+ f << stringf("%s[%d]", id(chunk.wire->name).c_str(), (chunk.wire->width - chunk.offset - 1) + chunk.wire->start_offset);
+ else
+ f << stringf("%s[%d]", id(chunk.wire->name).c_str(), chunk.offset + chunk.wire->start_offset);
+ } else {
+ if (chunk.wire->upto)
+ f << stringf("%s[%d:%d]", id(chunk.wire->name).c_str(),
+ (chunk.wire->width - (chunk.offset + chunk.width - 1) - 1) + chunk.wire->start_offset,
+ (chunk.wire->width - chunk.offset - 1) + chunk.wire->start_offset);
+ else
+ f << stringf("%s[%d:%d]", id(chunk.wire->name).c_str(),
+ (chunk.offset + chunk.width - 1) + chunk.wire->start_offset,
+ chunk.offset + chunk.wire->start_offset);
+ }
}
}
-void dump_sigspec(FILE *f, RTLIL::SigSpec &sig)
+void dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig)
{
- if (sig.chunks.size() == 1) {
- dump_sigchunk(f, sig.chunks[0]);
+ if (sig.is_chunk()) {
+ dump_sigchunk(f, sig.as_chunk());
} else {
- fprintf(f, "{ ");
- for (auto it = sig.chunks.rbegin(); it != sig.chunks.rend(); it++) {
- if (it != sig.chunks.rbegin())
- fprintf(f, ", ");
+ f << stringf("{ ");
+ for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); it++) {
+ if (it != sig.chunks().rbegin())
+ f << stringf(", ");
dump_sigchunk(f, *it, true);
}
- fprintf(f, " }");
+ f << stringf(" }");
}
}
-void dump_attributes(FILE *f, std::string indent, std::map<RTLIL::IdString, RTLIL::Const> &attributes, char term = '\n')
+void dump_attributes(std::ostream &f, std::string indent, std::map<RTLIL::IdString, RTLIL::Const> &attributes, char term = '\n')
{
if (noattr)
return;
for (auto it = attributes.begin(); it != attributes.end(); it++) {
- fprintf(f, "%s" "%s %s", indent.c_str(), attr2comment ? "/*" : "(*", id(it->first).c_str());
- fprintf(f, " = ");
+ f << stringf("%s" "%s %s", indent.c_str(), attr2comment ? "/*" : "(*", id(it->first).c_str());
+ f << stringf(" = ");
dump_const(f, it->second);
- fprintf(f, " %s%c", attr2comment ? "*/" : "*)", term);
+ f << stringf(" %s%c", attr2comment ? "*/" : "*)", term);
}
}
-void dump_wire(FILE *f, std::string indent, RTLIL::Wire *wire)
+void dump_wire(std::ostream &f, std::string indent, RTLIL::Wire *wire)
{
dump_attributes(f, indent, wire->attributes);
#if 0
if (wire->port_input && !wire->port_output)
- fprintf(f, "%s" "input %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : "");
+ f << stringf("%s" "input %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : "");
else if (!wire->port_input && wire->port_output)
- fprintf(f, "%s" "output %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : "");
+ f << stringf("%s" "output %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : "");
else if (wire->port_input && wire->port_output)
- fprintf(f, "%s" "inout %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : "");
+ f << stringf("%s" "inout %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : "");
else
- fprintf(f, "%s" "%s ", indent.c_str(), reg_wires.count(wire->name) ? "reg" : "wire");
+ f << stringf("%s" "%s ", indent.c_str(), reg_wires.count(wire->name) ? "reg" : "wire");
if (wire->width != 1)
- fprintf(f, "[%d:%d] ", wire->width - 1 + wire->start_offset, wire->start_offset);
- fprintf(f, "%s;\n", id(wire->name).c_str());
+ f << stringf("[%d:%d] ", wire->width - 1 + wire->start_offset, wire->start_offset);
+ f << stringf("%s;\n", id(wire->name).c_str());
#else
// do not use Verilog-2k "outut reg" syntax in verilog export
std::string range = "";
- if (wire->width != 1)
- range = stringf(" [%d:%d]", wire->width - 1 + wire->start_offset, wire->start_offset);
+ if (wire->width != 1) {
+ if (wire->upto)
+ range = stringf(" [%d:%d]", wire->start_offset, wire->width - 1 + wire->start_offset);
+ else
+ range = stringf(" [%d:%d]", wire->width - 1 + wire->start_offset, wire->start_offset);
+ }
if (wire->port_input && !wire->port_output)
- fprintf(f, "%s" "input%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str());
+ f << stringf("%s" "input%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str());
if (!wire->port_input && wire->port_output)
- fprintf(f, "%s" "output%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str());
+ 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)
- fprintf(f, "%s" "inout%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str());
+ f << stringf("%s" "inout%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str());
if (reg_wires.count(wire->name))
- fprintf(f, "%s" "reg%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str());
+ 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)
- fprintf(f, "%s" "wire%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str());
+ f << stringf("%s" "wire%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str());
#endif
}
-void dump_memory(FILE *f, std::string indent, RTLIL::Memory *memory)
+void dump_memory(std::ostream &f, std::string indent, RTLIL::Memory *memory)
{
dump_attributes(f, indent, memory->attributes);
- fprintf(f, "%s" "reg [%d:0] %s [%d:0];\n", indent.c_str(), memory->width-1, id(memory->name).c_str(), memory->size-1);
+ f << stringf("%s" "reg [%d:0] %s [%d:0];\n", indent.c_str(), memory->width-1, id(memory->name).c_str(), memory->size-1);
}
-void dump_cell_expr_port(FILE *f, RTLIL::Cell *cell, std::string port, bool gen_signed = true)
+void dump_cell_expr_port(std::ostream &f, RTLIL::Cell *cell, std::string port, bool gen_signed = true)
{
if (gen_signed && cell->parameters.count("\\" + port + "_SIGNED") > 0 && cell->parameters["\\" + port + "_SIGNED"].as_bool()) {
- fprintf(f, "$signed(");
- dump_sigspec(f, cell->connections["\\" + port]);
- fprintf(f, ")");
+ f << stringf("$signed(");
+ dump_sigspec(f, cell->getPort("\\" + port));
+ f << stringf(")");
} else
- dump_sigspec(f, cell->connections["\\" + port]);
+ dump_sigspec(f, cell->getPort("\\" + port));
}
std::string cellname(RTLIL::Cell *cell)
{
- if (!norename && cell->name[0] == '$' && reg_ct.cell_known(cell->type) && cell->connections.count("\\Q") > 0)
+ if (!norename && cell->name[0] == '$' && reg_ct.count(cell->type) && cell->hasPort("\\Q"))
{
- RTLIL::SigSpec sig = cell->connections["\\Q"];
- if (sig.width != 1 || sig.is_fully_const())
+ RTLIL::SigSpec sig = cell->getPort("\\Q");
+ if (SIZE(sig) != 1 || sig.is_fully_const())
goto no_special_reg_name;
- sig.optimize();
- RTLIL::Wire *wire = sig.chunks[0].wire;
+ RTLIL::Wire *wire = sig[0].wire;
if (wire->name[0] != '\\')
goto no_special_reg_name;
- std::string cell_name = wire->name;
+ std::string cell_name = wire->name.str();
size_t pos = cell_name.find('[');
if (pos != std::string::npos)
@@ -318,7 +332,7 @@ std::string cellname(RTLIL::Cell *cell)
cell_name = cell_name + "_reg";
if (wire->width != 1)
- cell_name += stringf("[%d]", wire->start_offset + sig.chunks[0].offset);
+ cell_name += stringf("[%d]", wire->start_offset + sig[0].offset);
if (active_module && active_module->count_id(cell_name) > 0)
goto no_special_reg_name;
@@ -332,107 +346,143 @@ no_special_reg_name:
}
}
-void dump_cell_expr_uniop(FILE *f, std::string indent, RTLIL::Cell *cell, std::string op)
+void dump_cell_expr_uniop(std::ostream &f, std::string indent, RTLIL::Cell *cell, std::string op)
{
- fprintf(f, "%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->connections["\\Y"]);
- fprintf(f, " = %s ", op.c_str());
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, cell->getPort("\\Y"));
+ f << stringf(" = %s ", op.c_str());
dump_attributes(f, "", cell->attributes, ' ');
dump_cell_expr_port(f, cell, "A", true);
- fprintf(f, ";\n");
+ f << stringf(";\n");
}
-void dump_cell_expr_binop(FILE *f, std::string indent, RTLIL::Cell *cell, std::string op)
+void dump_cell_expr_binop(std::ostream &f, std::string indent, RTLIL::Cell *cell, std::string op)
{
- fprintf(f, "%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->connections["\\Y"]);
- fprintf(f, " = ");
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, cell->getPort("\\Y"));
+ f << stringf(" = ");
dump_cell_expr_port(f, cell, "A", true);
- fprintf(f, " %s ", op.c_str());
+ f << stringf(" %s ", op.c_str());
dump_attributes(f, "", cell->attributes, ' ');
dump_cell_expr_port(f, cell, "B", true);
- fprintf(f, ";\n");
+ f << stringf(";\n");
}
-bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell)
+bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
{
- if (cell->type == "$_INV_") {
- fprintf(f, "%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->connections["\\Y"]);
- fprintf(f, " = ");
- fprintf(f, "~");
+ if (cell->type == "$_NOT_") {
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, cell->getPort("\\Y"));
+ f << stringf(" = ");
+ f << stringf("~");
dump_attributes(f, "", cell->attributes, ' ');
dump_cell_expr_port(f, cell, "A", false);
- fprintf(f, ";\n");
+ f << stringf(";\n");
return true;
}
- if (cell->type == "$_AND_" || cell->type == "$_OR_" || cell->type == "$_XOR_") {
- fprintf(f, "%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->connections["\\Y"]);
- fprintf(f, " = ");
+ if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_")) {
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, cell->getPort("\\Y"));
+ f << stringf(" = ");
+ if (cell->type.in("$_NAND_", "$_NOR_", "$_XNOR_"))
+ f << stringf("~(");
dump_cell_expr_port(f, cell, "A", false);
- fprintf(f, " ");
- if (cell->type == "$_AND_")
- fprintf(f, "&");
- if (cell->type == "$_OR_")
- fprintf(f, "|");
- if (cell->type == "$_XOR_")
- fprintf(f, "^");
+ f << stringf(" ");
+ if (cell->type.in("$_AND_", "$_NAND_"))
+ f << stringf("&");
+ if (cell->type.in("$_OR_", "$_NOR_"))
+ f << stringf("|");
+ if (cell->type.in("$_XOR_", "$_XNOR_"))
+ f << stringf("^");
dump_attributes(f, "", cell->attributes, ' ');
- fprintf(f, " ");
+ f << stringf(" ");
dump_cell_expr_port(f, cell, "B", false);
- fprintf(f, ";\n");
+ if (cell->type.in("$_NAND_", "$_NOR_", "$_XNOR_"))
+ f << stringf(")");
+ f << stringf(";\n");
return true;
}
if (cell->type == "$_MUX_") {
- fprintf(f, "%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->connections["\\Y"]);
- fprintf(f, " = ");
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, cell->getPort("\\Y"));
+ f << stringf(" = ");
dump_cell_expr_port(f, cell, "S", false);
- fprintf(f, " ? ");
+ f << stringf(" ? ");
dump_attributes(f, "", cell->attributes, ' ');
dump_cell_expr_port(f, cell, "B", false);
- fprintf(f, " : ");
+ f << stringf(" : ");
+ dump_cell_expr_port(f, cell, "A", false);
+ f << stringf(";\n");
+ return true;
+ }
+
+ if (cell->type.in("$_AOI3_", "$_OAI3_")) {
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, cell->getPort("\\Y"));
+ f << stringf(" = ~((");
dump_cell_expr_port(f, cell, "A", false);
- fprintf(f, ";\n");
+ f << stringf(cell->type == "$_AOI3_" ? " & " : " | ");
+ dump_cell_expr_port(f, cell, "B", false);
+ f << stringf(cell->type == "$_AOI3_" ? ") |" : ") &");
+ dump_attributes(f, "", cell->attributes, ' ');
+ f << stringf(" ");
+ dump_cell_expr_port(f, cell, "C", false);
+ f << stringf(");\n");
+ return true;
+ }
+
+ if (cell->type.in("$_AOI4_", "$_OAI4_")) {
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, cell->getPort("\\Y"));
+ f << stringf(" = ~((");
+ dump_cell_expr_port(f, cell, "A", false);
+ f << stringf(cell->type == "$_AOI4_" ? " & " : " | ");
+ dump_cell_expr_port(f, cell, "B", false);
+ f << stringf(cell->type == "$_AOI4_" ? ") |" : ") &");
+ dump_attributes(f, "", cell->attributes, ' ');
+ f << stringf(" (");
+ dump_cell_expr_port(f, cell, "C", false);
+ f << stringf(cell->type == "$_AOI4_" ? " & " : " | ");
+ dump_cell_expr_port(f, cell, "D", false);
+ f << stringf("));\n");
return true;
}
if (cell->type.substr(0, 6) == "$_DFF_")
{
std::string reg_name = cellname(cell);
- bool out_is_reg_wire = is_reg_wire(cell->connections["\\Q"], reg_name);
+ bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name);
if (!out_is_reg_wire)
- fprintf(f, "%s" "reg %s;\n", indent.c_str(), reg_name.c_str());
+ f << stringf("%s" "reg %s;\n", indent.c_str(), reg_name.c_str());
dump_attributes(f, indent, cell->attributes);
- fprintf(f, "%s" "always @(%sedge ", indent.c_str(), cell->type[6] == 'P' ? "pos" : "neg");
- dump_sigspec(f, cell->connections["\\C"]);
+ f << stringf("%s" "always @(%sedge ", indent.c_str(), cell->type[6] == 'P' ? "pos" : "neg");
+ dump_sigspec(f, cell->getPort("\\C"));
if (cell->type[7] != '_') {
- fprintf(f, " or %sedge ", cell->type[7] == 'P' ? "pos" : "neg");
- dump_sigspec(f, cell->connections["\\R"]);
+ f << stringf(" or %sedge ", cell->type[7] == 'P' ? "pos" : "neg");
+ dump_sigspec(f, cell->getPort("\\R"));
}
- fprintf(f, ")\n");
+ f << stringf(")\n");
if (cell->type[7] != '_') {
- fprintf(f, "%s" " if (%s", indent.c_str(), cell->type[7] == 'P' ? "" : "!");
- dump_sigspec(f, cell->connections["\\R"]);
- fprintf(f, ")\n");
- fprintf(f, "%s" " %s <= %c;\n", indent.c_str(), reg_name.c_str(), cell->type[8]);
- fprintf(f, "%s" " else\n", indent.c_str());
+ f << stringf("%s" " if (%s", indent.c_str(), cell->type[7] == 'P' ? "" : "!");
+ dump_sigspec(f, cell->getPort("\\R"));
+ f << stringf(")\n");
+ f << stringf("%s" " %s <= %c;\n", indent.c_str(), reg_name.c_str(), cell->type[8]);
+ f << stringf("%s" " else\n", indent.c_str());
}
- fprintf(f, "%s" " %s <= ", indent.c_str(), reg_name.c_str());
+ f << stringf("%s" " %s <= ", indent.c_str(), reg_name.c_str());
dump_cell_expr_port(f, cell, "D", false);
- fprintf(f, ";\n");
+ f << stringf(";\n");
if (!out_is_reg_wire) {
- fprintf(f, "%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->connections["\\Q"]);
- fprintf(f, " = %s;\n", reg_name.c_str());
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, cell->getPort("\\Q"));
+ f << stringf(" = %s;\n", reg_name.c_str());
}
return true;
@@ -443,39 +493,39 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell)
char pol_c = cell->type[8], pol_s = cell->type[9], pol_r = cell->type[10];
std::string reg_name = cellname(cell);
- bool out_is_reg_wire = is_reg_wire(cell->connections["\\Q"], reg_name);
+ bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name);
if (!out_is_reg_wire)
- fprintf(f, "%s" "reg %s;\n", indent.c_str(), reg_name.c_str());
+ f << stringf("%s" "reg %s;\n", indent.c_str(), reg_name.c_str());
dump_attributes(f, indent, cell->attributes);
- fprintf(f, "%s" "always @(%sedge ", indent.c_str(), pol_c == 'P' ? "pos" : "neg");
- dump_sigspec(f, cell->connections["\\C"]);
- fprintf(f, " or %sedge ", pol_s == 'P' ? "pos" : "neg");
- dump_sigspec(f, cell->connections["\\S"]);
- fprintf(f, " or %sedge ", pol_r == 'P' ? "pos" : "neg");
- dump_sigspec(f, cell->connections["\\R"]);
- fprintf(f, ")\n");
-
- fprintf(f, "%s" " if (%s", indent.c_str(), pol_r == 'P' ? "" : "!");
- dump_sigspec(f, cell->connections["\\R"]);
- fprintf(f, ")\n");
- fprintf(f, "%s" " %s <= 0;\n", indent.c_str(), reg_name.c_str());
-
- fprintf(f, "%s" " else if (%s", indent.c_str(), pol_s == 'P' ? "" : "!");
- dump_sigspec(f, cell->connections["\\S"]);
- fprintf(f, ")\n");
- fprintf(f, "%s" " %s <= 1;\n", indent.c_str(), reg_name.c_str());
-
- fprintf(f, "%s" " else\n", indent.c_str());
- fprintf(f, "%s" " %s <= ", indent.c_str(), reg_name.c_str());
+ f << stringf("%s" "always @(%sedge ", indent.c_str(), pol_c == 'P' ? "pos" : "neg");
+ dump_sigspec(f, cell->getPort("\\C"));
+ f << stringf(" or %sedge ", pol_s == 'P' ? "pos" : "neg");
+ dump_sigspec(f, cell->getPort("\\S"));
+ f << stringf(" or %sedge ", pol_r == 'P' ? "pos" : "neg");
+ dump_sigspec(f, cell->getPort("\\R"));
+ f << stringf(")\n");
+
+ f << stringf("%s" " if (%s", indent.c_str(), pol_r == 'P' ? "" : "!");
+ dump_sigspec(f, cell->getPort("\\R"));
+ f << stringf(")\n");
+ f << stringf("%s" " %s <= 0;\n", indent.c_str(), reg_name.c_str());
+
+ f << stringf("%s" " else if (%s", indent.c_str(), pol_s == 'P' ? "" : "!");
+ dump_sigspec(f, cell->getPort("\\S"));
+ f << stringf(")\n");
+ f << stringf("%s" " %s <= 1;\n", indent.c_str(), reg_name.c_str());
+
+ f << stringf("%s" " else\n", indent.c_str());
+ f << stringf("%s" " %s <= ", indent.c_str(), reg_name.c_str());
dump_cell_expr_port(f, cell, "D", false);
- fprintf(f, ";\n");
+ f << stringf(";\n");
if (!out_is_reg_wire) {
- fprintf(f, "%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->connections["\\Q"]);
- fprintf(f, " = %s;\n", reg_name.c_str());
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, cell->getPort("\\Q"));
+ f << stringf(" = %s;\n", reg_name.c_str());
}
return true;
@@ -529,67 +579,87 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell)
#undef HANDLE_UNIOP
#undef HANDLE_BINOP
- if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$pmux_safe")
+ if (cell->type == "$mux")
+ {
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, cell->getPort("\\Y"));
+ f << stringf(" = ");
+ dump_sigspec(f, cell->getPort("\\S"));
+ f << stringf(" ? ");
+ dump_attributes(f, "", cell->attributes, ' ');
+ dump_sigspec(f, cell->getPort("\\B"));
+ f << stringf(" : ");
+ dump_sigspec(f, cell->getPort("\\A"));
+ f << stringf(";\n");
+ return true;
+ }
+
+ if (cell->type == "$pmux" || cell->type == "$pmux_safe")
{
int width = cell->parameters["\\WIDTH"].as_int();
- int s_width = cell->connections["\\S"].width;
- std::string reg_name = cellname(cell);
- fprintf(f, "%s" "reg [%d:0] %s;\n", indent.c_str(), width-1, reg_name.c_str());
+ int s_width = cell->getPort("\\S").size();
+ std::string func_name = cellname(cell);
- dump_attributes(f, indent, cell->attributes);
- if (!noattr)
- fprintf(f, "%s" "(* parallel_case *)\n", indent.c_str());
- fprintf(f, "%s" "always @*\n", indent.c_str());
- fprintf(f, "%s" " casez (", indent.c_str());
- dump_sigspec(f, cell->connections["\\S"]);
- fprintf(f, noattr ? ") // synopsys parallel_case\n" : ")\n");
+ f << stringf("%s" "function [%d:0] %s;\n", indent.c_str(), width-1, func_name.c_str());
+ f << stringf("%s" " input [%d:0] a;\n", indent.c_str(), width-1);
+ f << stringf("%s" " input [%d:0] b;\n", indent.c_str(), s_width*width-1);
+ f << stringf("%s" " input [%d:0] s;\n", indent.c_str(), s_width-1);
+
+ dump_attributes(f, indent + " ", cell->attributes);
+ if (cell->type != "$pmux_safe" && !noattr)
+ f << stringf("%s" " (* parallel_case *)\n", indent.c_str());
+ f << stringf("%s" " casez (s)", indent.c_str());
+ if (cell->type != "$pmux_safe")
+ f << stringf(noattr ? " // synopsys parallel_case\n" : "\n");
for (int i = 0; i < s_width; i++)
{
- fprintf(f, "%s" " %d'b", indent.c_str(), s_width);
+ f << stringf("%s" " %d'b", indent.c_str(), s_width);
for (int j = s_width-1; j >= 0; j--)
- fprintf(f, "%c", j == i ? '1' : cell->type == "$pmux_safe" ? '0' : '?');
+ f << stringf("%c", j == i ? '1' : cell->type == "$pmux_safe" ? '0' : '?');
- fprintf(f, ":\n");
- fprintf(f, "%s" " %s = ", indent.c_str(), reg_name.c_str());
-
- RTLIL::SigSpec s = cell->connections["\\B"].extract(i * width, width);
- dump_sigspec(f, s);
- fprintf(f, ";\n");
+ f << stringf(":\n");
+ f << stringf("%s" " %s = b[%d:%d];\n", indent.c_str(), func_name.c_str(), (i+1)*width-1, i*width);
}
- fprintf(f, "%s" " default:\n", indent.c_str());
- fprintf(f, "%s" " %s = ", indent.c_str(), reg_name.c_str());
- dump_sigspec(f, cell->connections["\\A"]);
- fprintf(f, ";\n");
-
- fprintf(f, "%s" " endcase\n", indent.c_str());
- fprintf(f, "%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->connections["\\Y"]);
- fprintf(f, " = %s;\n", reg_name.c_str());
+ f << stringf("%s" " default:\n", indent.c_str());
+ f << stringf("%s" " %s = a;\n", indent.c_str(), func_name.c_str());
+
+ f << stringf("%s" " endcase\n", indent.c_str());
+ f << stringf("%s" "endfunction\n", indent.c_str());
+
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, cell->getPort("\\Y"));
+ f << stringf(" = %s(", func_name.c_str());
+ dump_sigspec(f, cell->getPort("\\A"));
+ f << stringf(", ");
+ dump_sigspec(f, cell->getPort("\\B"));
+ f << stringf(", ");
+ dump_sigspec(f, cell->getPort("\\S"));
+ f << stringf(");\n");
return true;
}
if (cell->type == "$slice")
{
- fprintf(f, "%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->connections["\\Y"]);
- fprintf(f, " = ");
- dump_sigspec(f, cell->connections["\\A"]);
- fprintf(f, " >> %d;\n", cell->parameters.at("\\OFFSET").as_int());
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, cell->getPort("\\Y"));
+ f << stringf(" = ");
+ dump_sigspec(f, cell->getPort("\\A"));
+ f << stringf(" >> %d;\n", cell->parameters.at("\\OFFSET").as_int());
return true;
}
if (cell->type == "$concat")
{
- fprintf(f, "%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->connections["\\Y"]);
- fprintf(f, " = { ");
- dump_sigspec(f, cell->connections["\\B"]);
- fprintf(f, " , ");
- dump_sigspec(f, cell->connections["\\A"]);
- fprintf(f, " };\n");
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, cell->getPort("\\Y"));
+ f << stringf(" = { ");
+ dump_sigspec(f, cell->getPort("\\B"));
+ f << stringf(" , ");
+ dump_sigspec(f, cell->getPort("\\A"));
+ f << stringf(" };\n");
return true;
}
@@ -598,59 +668,59 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell)
RTLIL::SigSpec sig_clk, sig_arst, val_arst;
bool pol_clk, pol_arst = false;
- sig_clk = cell->connections["\\CLK"];
+ sig_clk = cell->getPort("\\CLK");
pol_clk = cell->parameters["\\CLK_POLARITY"].as_bool();
if (cell->type == "$adff") {
- sig_arst = cell->connections["\\ARST"];
+ sig_arst = cell->getPort("\\ARST");
pol_arst = cell->parameters["\\ARST_POLARITY"].as_bool();
val_arst = RTLIL::SigSpec(cell->parameters["\\ARST_VALUE"]);
}
std::string reg_name = cellname(cell);
- bool out_is_reg_wire = is_reg_wire(cell->connections["\\Q"], reg_name);
+ bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name);
if (!out_is_reg_wire)
- fprintf(f, "%s" "reg [%d:0] %s;\n", indent.c_str(), cell->parameters["\\WIDTH"].as_int()-1, reg_name.c_str());
+ f << stringf("%s" "reg [%d:0] %s;\n", indent.c_str(), cell->parameters["\\WIDTH"].as_int()-1, reg_name.c_str());
- fprintf(f, "%s" "always @(%sedge ", indent.c_str(), pol_clk ? "pos" : "neg");
+ f << stringf("%s" "always @(%sedge ", indent.c_str(), pol_clk ? "pos" : "neg");
dump_sigspec(f, sig_clk);
if (cell->type == "$adff") {
- fprintf(f, " or %sedge ", pol_arst ? "pos" : "neg");
+ f << stringf(" or %sedge ", pol_arst ? "pos" : "neg");
dump_sigspec(f, sig_arst);
}
- fprintf(f, ")\n");
+ f << stringf(")\n");
if (cell->type == "$adff") {
- fprintf(f, "%s" " if (%s", indent.c_str(), pol_arst ? "" : "!");
+ f << stringf("%s" " if (%s", indent.c_str(), pol_arst ? "" : "!");
dump_sigspec(f, sig_arst);
- fprintf(f, ")\n");
- fprintf(f, "%s" " %s <= ", indent.c_str(), reg_name.c_str());
+ f << stringf(")\n");
+ f << stringf("%s" " %s <= ", indent.c_str(), reg_name.c_str());
dump_sigspec(f, val_arst);
- fprintf(f, ";\n");
- fprintf(f, "%s" " else\n", indent.c_str());
+ f << stringf(";\n");
+ f << stringf("%s" " else\n", indent.c_str());
}
- fprintf(f, "%s" " %s <= ", indent.c_str(), reg_name.c_str());
+ f << stringf("%s" " %s <= ", indent.c_str(), reg_name.c_str());
dump_cell_expr_port(f, cell, "D", false);
- fprintf(f, ";\n");
+ f << stringf(";\n");
if (!out_is_reg_wire) {
- fprintf(f, "%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->connections["\\Q"]);
- fprintf(f, " = %s;\n", reg_name.c_str());
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, cell->getPort("\\Q"));
+ f << stringf(" = %s;\n", reg_name.c_str());
}
return true;
}
- // FIXME: $_SR_[PN][PN]_, $_DLATCH_[PN]_
+ // FIXME: $_SR_[PN][PN]_, $_DLATCH_[PN]_, $_DLATCHSR_[PN][PN][PN]_
// FIXME: $sr, $dffsr, $dlatch, $memrd, $memwr, $mem, $fsm
return false;
}
-void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell)
+void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
{
if (cell->type[0] == '$' && !noexpr) {
if (dump_cell_expr(f, indent, cell))
@@ -658,39 +728,39 @@ void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell)
}
dump_attributes(f, indent, cell->attributes);
- fprintf(f, "%s" "%s", indent.c_str(), id(cell->type, false).c_str());
+ f << stringf("%s" "%s", indent.c_str(), id(cell->type, false).c_str());
if (cell->parameters.size() > 0) {
- fprintf(f, " #(");
+ f << stringf(" #(");
for (auto it = cell->parameters.begin(); it != cell->parameters.end(); it++) {
if (it != cell->parameters.begin())
- fprintf(f, ",");
- fprintf(f, "\n%s .%s(", indent.c_str(), id(it->first).c_str());
+ 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);
- fprintf(f, ")");
+ f << stringf(")");
}
- fprintf(f, "\n%s" ")", indent.c_str());
+ f << stringf("\n%s" ")", indent.c_str());
}
std::string cell_name = cellname(cell);
if (cell_name != id(cell->name))
- fprintf(f, " %s /* %s */ (", cell_name.c_str(), id(cell->name).c_str());
+ f << stringf(" %s /* %s */ (", cell_name.c_str(), id(cell->name).c_str());
else
- fprintf(f, " %s (", cell_name.c_str());
+ f << stringf(" %s (", cell_name.c_str());
bool first_arg = true;
- std::set<std::string> numbered_ports;
+ std::set<RTLIL::IdString> numbered_ports;
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)
- fprintf(f, ",");
+ f << stringf(",");
first_arg = false;
- fprintf(f, "\n%s ", indent.c_str());
+ f << stringf("\n%s ", indent.c_str());
dump_sigspec(f, it->second);
numbered_ports.insert(it->first);
goto found_numbered_port;
@@ -698,90 +768,90 @@ void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell)
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)
- fprintf(f, ",");
+ f << stringf(",");
first_arg = false;
- fprintf(f, "\n%s .%s(", indent.c_str(), id(it->first).c_str());
- if (it->second.width > 0)
+ f << stringf("\n%s .%s(", indent.c_str(), id(it->first).c_str());
+ if (it->second.size() > 0)
dump_sigspec(f, it->second);
- fprintf(f, ")");
+ f << stringf(")");
}
- fprintf(f, "\n%s" ");\n", indent.c_str());
+ f << stringf("\n%s" ");\n", indent.c_str());
}
-void dump_conn(FILE *f, std::string indent, RTLIL::SigSpec &left, RTLIL::SigSpec &right)
+void dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
{
- fprintf(f, "%s" "assign ", indent.c_str());
+ f << stringf("%s" "assign ", indent.c_str());
dump_sigspec(f, left);
- fprintf(f, " = ");
+ f << stringf(" = ");
dump_sigspec(f, right);
- fprintf(f, ";\n");
+ f << stringf(";\n");
}
-void dump_proc_switch(FILE *f, std::string indent, RTLIL::SwitchRule *sw);
+void dump_proc_switch(std::ostream &f, std::string indent, RTLIL::SwitchRule *sw);
-void dump_case_body(FILE *f, std::string indent, RTLIL::CaseRule *cs, bool omit_trailing_begin = false)
+void dump_case_body(std::ostream &f, std::string indent, RTLIL::CaseRule *cs, bool omit_trailing_begin = false)
{
int number_of_stmts = cs->switches.size() + cs->actions.size();
if (!omit_trailing_begin && number_of_stmts >= 2)
- fprintf(f, "%s" "begin\n", indent.c_str());
+ f << stringf("%s" "begin\n", indent.c_str());
for (auto it = cs->actions.begin(); it != cs->actions.end(); it++) {
- if (it->first.width == 0)
+ if (it->first.size() == 0)
continue;
- fprintf(f, "%s ", indent.c_str());
+ f << stringf("%s ", indent.c_str());
dump_sigspec(f, it->first);
- fprintf(f, " = ");
+ f << stringf(" = ");
dump_sigspec(f, it->second);
- fprintf(f, ";\n");
+ f << stringf(";\n");
}
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)
- fprintf(f, "%s /* empty */;\n", indent.c_str());
+ f << stringf("%s /* empty */;\n", indent.c_str());
if (omit_trailing_begin || number_of_stmts >= 2)
- fprintf(f, "%s" "end\n", indent.c_str());
+ f << stringf("%s" "end\n", indent.c_str());
}
-void dump_proc_switch(FILE *f, std::string indent, RTLIL::SwitchRule *sw)
+void dump_proc_switch(std::ostream &f, std::string indent, RTLIL::SwitchRule *sw)
{
- if (sw->signal.width == 0) {
- fprintf(f, "%s" "begin\n", indent.c_str());
+ if (sw->signal.size() == 0) {
+ f << stringf("%s" "begin\n", indent.c_str());
for (auto it = sw->cases.begin(); it != sw->cases.end(); it++) {
if ((*it)->compare.size() == 0)
dump_case_body(f, indent + " ", *it);
}
- fprintf(f, "%s" "end\n", indent.c_str());
+ f << stringf("%s" "end\n", indent.c_str());
return;
}
- fprintf(f, "%s" "casez (", indent.c_str());
+ f << stringf("%s" "casez (", indent.c_str());
dump_sigspec(f, sw->signal);
- fprintf(f, ")\n");
+ f << stringf(")\n");
for (auto it = sw->cases.begin(); it != sw->cases.end(); it++) {
- fprintf(f, "%s ", indent.c_str());
+ f << stringf("%s ", indent.c_str());
if ((*it)->compare.size() == 0)
- fprintf(f, "default");
+ f << stringf("default");
else {
for (size_t i = 0; i < (*it)->compare.size(); i++) {
if (i > 0)
- fprintf(f, ", ");
+ f << stringf(", ");
dump_sigspec(f, (*it)->compare[i]);
}
}
- fprintf(f, ":\n");
+ f << stringf(":\n");
dump_case_body(f, indent + " ", *it);
}
- fprintf(f, "%s" "endcase\n", indent.c_str());
+ f << stringf("%s" "endcase\n", indent.c_str());
}
void case_body_find_regs(RTLIL::CaseRule *cs)
@@ -791,26 +861,26 @@ void case_body_find_regs(RTLIL::CaseRule *cs)
case_body_find_regs(*it2);
for (auto it = cs->actions.begin(); it != cs->actions.end(); it++) {
- for (size_t i = 0; i < it->first.chunks.size(); i++)
- if (it->first.chunks[i].wire)
- reg_wires.insert(it->first.chunks[i].wire->name);
+ for (auto &c : it->first.chunks())
+ if (c.wire != NULL)
+ reg_wires.insert(c.wire->name);
}
}
-void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_regs = false)
+void dump_process(std::ostream &f, std::string indent, RTLIL::Process *proc, bool find_regs = false)
{
if (find_regs) {
case_body_find_regs(&proc->root_case);
for (auto it = proc->syncs.begin(); it != proc->syncs.end(); it++)
for (auto it2 = (*it)->actions.begin(); it2 != (*it)->actions.end(); it2++) {
- for (size_t i = 0; i < it2->first.chunks.size(); i++)
- if (it2->first.chunks[i].wire)
- reg_wires.insert(it2->first.chunks[i].wire->name);
+ for (auto &c : it2->first.chunks())
+ if (c.wire != NULL)
+ reg_wires.insert(c.wire->name);
}
return;
}
- fprintf(f, "%s" "always @* begin\n", indent.c_str());
+ f << stringf("%s" "always @* begin\n", indent.c_str());
dump_case_body(f, indent, &proc->root_case, true);
std::string backup_indent = indent;
@@ -821,23 +891,23 @@ void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_r
indent = backup_indent;
if (sync->type == RTLIL::STa) {
- fprintf(f, "%s" "always @* begin\n", indent.c_str());
+ f << stringf("%s" "always @* begin\n", indent.c_str());
} else {
- fprintf(f, "%s" "always @(", indent.c_str());
+ f << stringf("%s" "always @(", indent.c_str());
if (sync->type == RTLIL::STp || sync->type == RTLIL::ST1)
- fprintf(f, "posedge ");
+ f << stringf("posedge ");
if (sync->type == RTLIL::STn || sync->type == RTLIL::ST0)
- fprintf(f, "negedge ");
+ f << stringf("negedge ");
dump_sigspec(f, sync->signal);
- fprintf(f, ") begin\n");
+ f << stringf(") begin\n");
}
std::string ends = indent + "end\n";
indent += " ";
if (sync->type == RTLIL::ST0 || sync->type == RTLIL::ST1) {
- fprintf(f, "%s" "if (%s", indent.c_str(), sync->type == RTLIL::ST0 ? "!" : "");
+ f << stringf("%s" "if (%s", indent.c_str(), sync->type == RTLIL::ST0 ? "!" : "");
dump_sigspec(f, sync->signal);
- fprintf(f, ") begin\n");
+ f << stringf(") begin\n");
ends = indent + "end\n" + ends;
indent += " ";
}
@@ -846,9 +916,9 @@ void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_r
for (size_t j = 0; j < proc->syncs.size(); j++) {
RTLIL::SyncRule *sync2 = proc->syncs[j];
if (sync2->type == RTLIL::ST0 || sync2->type == RTLIL::ST1) {
- fprintf(f, "%s" "if (%s", indent.c_str(), sync2->type == RTLIL::ST1 ? "!" : "");
+ f << stringf("%s" "if (%s", indent.c_str(), sync2->type == RTLIL::ST1 ? "!" : "");
dump_sigspec(f, sync2->signal);
- fprintf(f, ") begin\n");
+ f << stringf(") begin\n");
ends = indent + "end\n" + ends;
indent += " ";
}
@@ -856,90 +926,93 @@ void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_r
}
for (auto it = sync->actions.begin(); it != sync->actions.end(); it++) {
- if (it->first.width == 0)
+ if (it->first.size() == 0)
continue;
- fprintf(f, "%s ", indent.c_str());
+ f << stringf("%s ", indent.c_str());
dump_sigspec(f, it->first);
- fprintf(f, " <= ");
+ f << stringf(" <= ");
dump_sigspec(f, it->second);
- fprintf(f, ";\n");
+ f << stringf(";\n");
}
- fprintf(f, "%s", ends.c_str());
+ f << stringf("%s", ends.c_str());
}
}
-void dump_module(FILE *f, std::string indent, RTLIL::Module *module)
+void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
{
reg_wires.clear();
reset_auto_counter(module);
active_module = module;
- fprintf(f, "\n");
+ f << stringf("\n");
for (auto it = module->processes.begin(); it != module->processes.end(); it++)
dump_process(f, indent + " ", it->second, true);
if (!noexpr)
{
std::set<std::pair<RTLIL::Wire*,int>> reg_bits;
- for (auto &it : module->cells)
+ for (auto &it : module->cells_)
{
RTLIL::Cell *cell = it.second;
- if (!reg_ct.cell_known(cell->type) || cell->connections.count("\\Q") == 0)
+ if (!reg_ct.count(cell->type) || !cell->hasPort("\\Q"))
continue;
- RTLIL::SigSpec sig = cell->connections["\\Q"];
- sig.optimize();
+ RTLIL::SigSpec sig = cell->getPort("\\Q");
- if (sig.chunks.size() == 1 && sig.chunks[0].wire)
- for (int i = 0; i < sig.chunks[0].width; i++)
- reg_bits.insert(std::pair<RTLIL::Wire*,int>(sig.chunks[0].wire, sig.chunks[0].offset+i));
+ if (sig.is_chunk()) {
+ RTLIL::SigChunk chunk = sig.as_chunk();
+ if (chunk.wire != NULL)
+ for (int i = 0; i < chunk.width; i++)
+ reg_bits.insert(std::pair<RTLIL::Wire*,int>(chunk.wire, chunk.offset+i));
+ }
}
- for (auto &it : module->wires)
+ for (auto &it : module->wires_)
{
RTLIL::Wire *wire = it.second;
for (int i = 0; i < wire->width; i++)
if (reg_bits.count(std::pair<RTLIL::Wire*,int>(wire, i)) == 0)
goto this_wire_aint_reg;
- reg_wires.insert(wire->name);
+ if (wire->width)
+ reg_wires.insert(wire->name);
this_wire_aint_reg:;
}
}
dump_attributes(f, indent, module->attributes);
- fprintf(f, "%s" "module %s(", indent.c_str(), id(module->name, false).c_str());
+ 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)
- fprintf(f, ", ");
- fprintf(f, "%s", id(wire->name).c_str());
+ f << stringf(", ");
+ f << stringf("%s", id(wire->name).c_str());
keep_running = true;
continue;
}
}
}
- fprintf(f, ");\n");
+ 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++)
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++)
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);
- fprintf(f, "%s" "endmodule\n", indent.c_str());
+ f << stringf("%s" "endmodule\n", indent.c_str());
active_module = NULL;
}
@@ -980,7 +1053,7 @@ struct VerilogBackend : public Backend {
log(" not at all.\n");
log("\n");
}
- virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
+ virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
{
log_header("Executing Verilog backend.\n");
@@ -993,10 +1066,30 @@ struct VerilogBackend : public Backend {
bool selected = false;
reg_ct.clear();
- reg_ct.setup_stdcells_mem();
- reg_ct.cell_types.insert("$sr");
- reg_ct.cell_types.insert("$dff");
- reg_ct.cell_types.insert("$adff");
+
+ reg_ct.insert("$dff");
+ reg_ct.insert("$adff");
+
+ reg_ct.insert("$_DFF_N_");
+ reg_ct.insert("$_DFF_P_");
+
+ reg_ct.insert("$_DFF_NN0_");
+ reg_ct.insert("$_DFF_NN1_");
+ reg_ct.insert("$_DFF_NP0_");
+ reg_ct.insert("$_DFF_NP1_");
+ reg_ct.insert("$_DFF_PN0_");
+ reg_ct.insert("$_DFF_PN1_");
+ reg_ct.insert("$_DFF_PP0_");
+ reg_ct.insert("$_DFF_PP1_");
+
+ reg_ct.insert("$_DFFSR_NNN_");
+ reg_ct.insert("$_DFFSR_NNP_");
+ reg_ct.insert("$_DFFSR_NPN_");
+ reg_ct.insert("$_DFFSR_NPP_");
+ reg_ct.insert("$_DFFSR_PNN_");
+ reg_ct.insert("$_DFFSR_PNP_");
+ reg_ct.insert("$_DFFSR_PPN_");
+ reg_ct.insert("$_DFFSR_PPP_");
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) {
@@ -1029,8 +1122,8 @@ struct VerilogBackend : public Backend {
}
extra_args(f, filename, args, argidx);
- fprintf(f, "/* Generated by %s */\n", yosys_version_str);
- for (auto it = design->modules.begin(); it != design->modules.end(); it++) {
+ *f << stringf("/* Generated by %s */\n", yosys_version_str);
+ 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)) {
@@ -1039,7 +1132,7 @@ struct VerilogBackend : public Backend {
continue;
}
log("Dumping module `%s'.\n", it->first.c_str());
- dump_module(f, "", it->second);
+ dump_module(*f, "", it->second);
}
reg_ct.clear();
diff --git a/backends/verilog/verilog_backend.h b/backends/verilog/verilog_backend.h
index c40830ef..7e6ef5ab 100644
--- a/backends/verilog/verilog_backend.h
+++ b/backends/verilog/verilog_backend.h
@@ -29,11 +29,10 @@
#ifndef VERILOG_BACKEND_H
#define VERILOG_BACKEND_H
-#include "kernel/rtlil.h"
-#include <stdio.h>
+#include "kernel/yosys.h"
namespace VERILOG_BACKEND {
- void verilog_backend(FILE *f, std::vector<std::string> args, RTLIL::Design *design);
+ void verilog_backend(std::ostream &f, std::vector<std::string> args, RTLIL::Design *design);
}
#endif