Replace "ILANG" with "RTLIL" everywhere.
authorwhitequark <whitequark@whitequark.org>
Wed, 26 Aug 2020 17:29:32 +0000 (17:29 +0000)
committerwhitequark <whitequark@whitequark.org>
Wed, 26 Aug 2020 17:29:32 +0000 (17:29 +0000)
The only difference between "RTLIL" and "ILANG" is that the latter is
the text representation of the former, as opposed to the in-memory
graph representation. This distinction serves no purpose but confuses
people: it is not obvious that the ILANG backend writes RTLIL graphs.

Passes `write_ilang` and `read_ilang` are provided as aliases to
`write_rtlil` and `read_rtlil` for compatibility.

34 files changed:
Makefile
backends/ilang/Makefile.inc [deleted file]
backends/ilang/ilang_backend.cc [deleted file]
backends/ilang/ilang_backend.h [deleted file]
backends/intersynth/intersynth.cc
backends/rtlil/Makefile.inc [new file with mode: 0644]
backends/rtlil/rtlil_backend.cc [new file with mode: 0644]
backends/rtlil/rtlil_backend.h [new file with mode: 0644]
frontends/ilang/.gitignore [deleted file]
frontends/ilang/Makefile.inc [deleted file]
frontends/ilang/ilang_frontend.cc [deleted file]
frontends/ilang/ilang_frontend.h [deleted file]
frontends/ilang/ilang_lexer.l [deleted file]
frontends/ilang/ilang_parser.y [deleted file]
frontends/rpc/rpc_frontend.cc
frontends/rtlil/.gitignore [new file with mode: 0644]
frontends/rtlil/Makefile.inc [new file with mode: 0644]
frontends/rtlil/rtlil_frontend.cc [new file with mode: 0644]
frontends/rtlil/rtlil_frontend.h [new file with mode: 0644]
frontends/rtlil/rtlil_lexer.l [new file with mode: 0644]
frontends/rtlil/rtlil_parser.y [new file with mode: 0644]
kernel/log.cc
kernel/rtlil.cc
kernel/yosys.cc
manual/CHAPTER_Overview.tex
manual/PRESENTATION_Intro.tex
manual/PRESENTATION_Prog.tex
passes/cmds/bugpoint.cc
passes/cmds/show.cc
passes/hierarchy/hierarchy.cc
passes/techmap/extract.cc
passes/techmap/techmap.cc
passes/tests/test_abcloop.cc
passes/tests/test_cell.cc

index 444678e9d0d467495ad2bd761280e0ebb8823d38..51680276f042acd3f6efc3a1c9c0938b681b3a3d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -593,7 +593,7 @@ $(eval $(call add_include_file,libs/sha1/sha1.h))
 $(eval $(call add_include_file,libs/json11/json11.hpp))
 $(eval $(call add_include_file,passes/fsm/fsmdata.h))
 $(eval $(call add_include_file,frontends/ast/ast.h))
-$(eval $(call add_include_file,backends/ilang/ilang_backend.h))
+$(eval $(call add_include_file,backends/rtlil/rtlil_backend.h))
 $(eval $(call add_include_file,backends/cxxrtl/cxxrtl.h))
 $(eval $(call add_include_file,backends/cxxrtl/cxxrtl_vcd.h))
 $(eval $(call add_include_file,backends/cxxrtl/cxxrtl_capi.cc))
@@ -634,7 +634,7 @@ include $(YOSYS_SRC)/techlibs/*/Makefile.inc
 else
 
 include $(YOSYS_SRC)/frontends/verilog/Makefile.inc
-include $(YOSYS_SRC)/frontends/ilang/Makefile.inc
+include $(YOSYS_SRC)/frontends/rtlil/Makefile.inc
 include $(YOSYS_SRC)/frontends/ast/Makefile.inc
 include $(YOSYS_SRC)/frontends/blif/Makefile.inc
 
@@ -651,7 +651,7 @@ include $(YOSYS_SRC)/passes/opt/Makefile.inc
 include $(YOSYS_SRC)/passes/techmap/Makefile.inc
 
 include $(YOSYS_SRC)/backends/verilog/Makefile.inc
-include $(YOSYS_SRC)/backends/ilang/Makefile.inc
+include $(YOSYS_SRC)/backends/rtlil/Makefile.inc
 
 include $(YOSYS_SRC)/techlibs/common/Makefile.inc
 
diff --git a/backends/ilang/Makefile.inc b/backends/ilang/Makefile.inc
deleted file mode 100644 (file)
index 52fc2b8..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-
-OBJS += backends/ilang/ilang_backend.o
-
diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc
deleted file mode 100644 (file)
index aa5a175..0000000
+++ /dev/null
@@ -1,521 +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.
- *
- *  ---
- *
- *  A very simple and straightforward backend for the RTLIL text
- *  representation (as understood by the 'ilang' frontend).
- *
- */
-
-#include "ilang_backend.h"
-#include "kernel/yosys.h"
-#include <errno.h>
-
-USING_YOSYS_NAMESPACE
-using namespace ILANG_BACKEND;
-YOSYS_NAMESPACE_BEGIN
-
-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;
-       if ((data.flags & RTLIL::CONST_FLAG_STRING) == 0 || width != (int)data.bits.size()) {
-               if (width == 32 && autoint) {
-                       int32_t val = 0;
-                       for (int i = 0; i < width; i++) {
-                               log_assert(offset+i < (int)data.bits.size());
-                               switch (data.bits[offset+i]) {
-                               case State::S0: break;
-                               case State::S1: val |= 1 << i; break;
-                               default: val = -1; break;
-                               }
-                       }
-                       if (val >= 0) {
-                               f << stringf("%d", val);
-                               return;
-                       }
-               }
-               f << stringf("%d'", width);
-               for (int i = offset+width-1; i >= offset; i--) {
-                       log_assert(i < (int)data.bits.size());
-                       switch (data.bits[i]) {
-                       case State::S0: f << stringf("0"); break;
-                       case State::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 {
-               f << stringf("\"");
-               std::string str = data.decode_string();
-               for (size_t i = 0; i < str.size(); i++) {
-                       if (str[i] == '\n')
-                               f << stringf("\\n");
-                       else if (str[i] == '\t')
-                               f << stringf("\\t");
-                       else if (str[i] < 32)
-                               f << stringf("\\%03o", str[i]);
-                       else if (str[i] == '"')
-                               f << stringf("\\\"");
-                       else if (str[i] == '\\')
-                               f << stringf("\\\\");
-                       else
-                               f << str[i];
-               }
-               f << stringf("\"");
-       }
-}
-
-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)
-                       f << stringf("%s", chunk.wire->name.c_str());
-               else if (chunk.width == 1)
-                       f << stringf("%s [%d]", chunk.wire->name.c_str(), chunk.offset);
-               else
-                       f << stringf("%s [%d:%d]", chunk.wire->name.c_str(), chunk.offset+chunk.width-1, chunk.offset);
-       }
-}
-
-void ILANG_BACKEND::dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, bool autoint)
-{
-       if (sig.is_chunk()) {
-               dump_sigchunk(f, sig.as_chunk(), autoint);
-       } else {
-               f << stringf("{ ");
-               for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); ++it) {
-                       dump_sigchunk(f, *it, false);
-                       f << stringf(" ");
-               }
-               f << stringf("}");
-       }
-}
-
-void ILANG_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire)
-{
-       for (auto &it : wire->attributes) {
-               f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str());
-               dump_const(f, it.second);
-               f << stringf("\n");
-       }
-       f << stringf("%s" "wire ", indent.c_str());
-       if (wire->width != 1)
-               f << stringf("width %d ", wire->width);
-       if (wire->upto)
-               f << stringf("upto ");
-       if (wire->start_offset != 0)
-               f << stringf("offset %d ", wire->start_offset);
-       if (wire->port_input && !wire->port_output)
-               f << stringf("input %d ", wire->port_id);
-       if (!wire->port_input && wire->port_output)
-               f << stringf("output %d ", wire->port_id);
-       if (wire->port_input && wire->port_output)
-               f << stringf("inout %d ", wire->port_id);
-       if (wire->is_signed)
-               f << stringf("signed ");
-       f << stringf("%s\n", wire->name.c_str());
-}
-
-void ILANG_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL::Memory *memory)
-{
-       for (auto &it : memory->attributes) {
-               f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str());
-               dump_const(f, it.second);
-               f << stringf("\n");
-       }
-       f << stringf("%s" "memory ", indent.c_str());
-       if (memory->width != 1)
-               f << stringf("width %d ", memory->width);
-       if (memory->size != 0)
-               f << stringf("size %d ", memory->size);
-       if (memory->start_offset != 0)
-               f << stringf("offset %d ", memory->start_offset);
-       f << stringf("%s\n", memory->name.c_str());
-}
-
-void ILANG_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL::Cell *cell)
-{
-       for (auto &it : cell->attributes) {
-               f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str());
-               dump_const(f, it.second);
-               f << stringf("\n");
-       }
-       f << stringf("%s" "cell %s %s\n", indent.c_str(), cell->type.c_str(), cell->name.c_str());
-       for (auto &it : cell->parameters) {
-               f << stringf("%s  parameter%s%s %s ", indent.c_str(),
-                               (it.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "",
-                               (it.second.flags & RTLIL::CONST_FLAG_REAL) != 0 ? " real" : "",
-                               it.first.c_str());
-               dump_const(f, it.second);
-               f << stringf("\n");
-       }
-       for (auto &it : cell->connections()) {
-               f << stringf("%s  connect %s ", indent.c_str(), it.first.c_str());
-               dump_sigspec(f, it.second);
-               f << stringf("\n");
-       }
-       f << stringf("%s" "end\n", indent.c_str());
-}
-
-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)
-       {
-               f << stringf("%s" "assign ", indent.c_str());
-               dump_sigspec(f, it->first);
-               f << stringf(" ");
-               dump_sigspec(f, it->second);
-               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(std::ostream &f, std::string indent, const RTLIL::SwitchRule *sw)
-{
-       for (auto it = sw->attributes.begin(); it != sw->attributes.end(); ++it) {
-               f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
-               dump_const(f, it->second);
-               f << stringf("\n");
-       }
-
-       f << stringf("%s" "switch ", indent.c_str());
-       dump_sigspec(f, sw->signal);
-       f << stringf("\n");
-
-       for (auto it = sw->cases.begin(); it != sw->cases.end(); ++it)
-       {
-               for (auto ait = (*it)->attributes.begin(); ait != (*it)->attributes.end(); ++ait) {
-                       f << stringf("%s  attribute %s ", indent.c_str(), ait->first.c_str());
-                       dump_const(f, ait->second);
-                       f << stringf("\n");
-               }
-               f << stringf("%s  case ", indent.c_str());
-               for (size_t i = 0; i < (*it)->compare.size(); i++) {
-                       if (i > 0)
-                               f << stringf(" , ");
-                       dump_sigspec(f, (*it)->compare[i]);
-               }
-               f << stringf("\n");
-
-               dump_proc_case_body(f, indent + "    ", *it);
-       }
-
-       f << stringf("%s" "end\n", indent.c_str());
-}
-
-void ILANG_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RTLIL::SyncRule *sy)
-{
-       f << stringf("%s" "sync ", indent.c_str());
-       switch (sy->type) {
-       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);
-               f << stringf("\n");
-               break;
-       case RTLIL::STa: f << stringf("always\n"); break;
-       case RTLIL::STg: f << stringf("global\n"); break;
-       case RTLIL::STi: f << stringf("init\n"); break;
-       }
-
-       for (auto it = sy->actions.begin(); it != sy->actions.end(); ++it) {
-               f << stringf("%s  update ", indent.c_str());
-               dump_sigspec(f, it->first);
-               f << stringf(" ");
-               dump_sigspec(f, it->second);
-               f << stringf("\n");
-       }
-}
-
-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) {
-               f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
-               dump_const(f, it->second);
-               f << stringf("\n");
-       }
-       f << stringf("%s" "process %s\n", indent.c_str(), proc->name.c_str());
-       dump_proc_case_body(f, indent + "  ", &proc->root_case);
-       for (auto it = proc->syncs.begin(); it != proc->syncs.end(); ++it)
-               dump_proc_sync(f, indent + "  ", *it);
-       f << stringf("%s" "end\n", indent.c_str());
-}
-
-void ILANG_BACKEND::dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
-{
-       f << stringf("%s" "connect ", indent.c_str());
-       dump_sigspec(f, left);
-       f << stringf(" ");
-       dump_sigspec(f, right);
-       f << stringf("\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);
-
-       if (print_header)
-       {
-               for (auto it = module->attributes.begin(); it != module->attributes.end(); ++it) {
-                       f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
-                       dump_const(f, it->second);
-                       f << stringf("\n");
-               }
-
-               f << stringf("%s" "module %s\n", indent.c_str(), module->name.c_str());
-
-               if (!module->avail_parameters.empty()) {
-                       if (only_selected)
-                               f << stringf("\n");
-                       for (const auto &p : module->avail_parameters) {
-                               const auto &it = module->parameter_default_values.find(p);
-                               if (it == module->parameter_default_values.end()) {
-                                       f << stringf("%s" "  parameter %s\n", indent.c_str(), p.c_str());
-                               } else {
-                                       f << stringf("%s" "  parameter %s ", indent.c_str(), p.c_str());
-                                       dump_const(f, it->second);
-                                       f << stringf("\n");
-                               }
-                       }
-               }
-       }
-
-       if (print_body)
-       {
-               for (auto it : module->wires())
-                       if (!only_selected || design->selected(module, it)) {
-                               if (only_selected)
-                                       f << stringf("\n");
-                               dump_wire(f, indent + "  ", it);
-                       }
-
-               for (auto it : module->memories)
-                       if (!only_selected || design->selected(module, it.second)) {
-                               if (only_selected)
-                                       f << stringf("\n");
-                               dump_memory(f, indent + "  ", it.second);
-                       }
-
-               for (auto it : module->cells())
-                       if (!only_selected || design->selected(module, it)) {
-                               if (only_selected)
-                                       f << stringf("\n");
-                               dump_cell(f, indent + "  ", it);
-                       }
-
-               for (auto it : module->processes)
-                       if (!only_selected || design->selected(module, it.second)) {
-                               if (only_selected)
-                                       f << stringf("\n");
-                               dump_proc(f, indent + "  ", it.second);
-                       }
-
-               bool first_conn_line = true;
-               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()) {
-                                       if (c.wire == NULL || !design->selected(module, c.wire))
-                                               continue;
-                                       show_conn = true;
-                               }
-                       }
-                       if (show_conn) {
-                               if (only_selected && first_conn_line)
-                                       f << stringf("\n");
-                               dump_conn(f, indent + "  ", it->first, it->second);
-                               first_conn_line = false;
-                       }
-               }
-       }
-
-       if (print_header)
-               f << stringf("%s" "end\n", indent.c_str());
-}
-
-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 module : design->modules()) {
-                       if (design->selected_whole_module(module->name))
-                               flag_m = true;
-                       if (design->selected(module))
-                               count_selected_mods++;
-               }
-               if (count_selected_mods > 1)
-                       flag_m = true;
-       }
-
-       if (!only_selected || flag_m) {
-               if (only_selected)
-                       f << stringf("\n");
-               f << stringf("autoidx %d\n", autoidx);
-       }
-
-       for (auto module : design->modules()) {
-               if (!only_selected || design->selected(module)) {
-                       if (only_selected)
-                               f << stringf("\n");
-                       dump_module(f, "", module, design, only_selected, flag_m, flag_n);
-               }
-       }
-
-       log_assert(init_autoidx == autoidx);
-}
-
-YOSYS_NAMESPACE_END
-PRIVATE_NAMESPACE_BEGIN
-
-struct IlangBackend : public Backend {
-       IlangBackend() : Backend("ilang", "write design to ilang file") { }
-       void help() override
-       {
-               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
-               log("\n");
-               log("    write_ilang [filename]\n");
-               log("\n");
-               log("Write the current design to an 'ilang' file. (ilang is a text representation\n");
-               log("of a design in yosys's internal format.)\n");
-               log("\n");
-               log("    -selected\n");
-               log("        only write selected parts of the design.\n");
-               log("\n");
-       }
-       void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override
-       {
-               bool selected = false;
-
-               log_header(design, "Executing ILANG backend.\n");
-
-               size_t argidx;
-               for (argidx = 1; argidx < args.size(); argidx++) {
-                       std::string arg = args[argidx];
-                       if (arg == "-selected") {
-                               selected = true;
-                               continue;
-                       }
-                       break;
-               }
-               extra_args(f, filename, args, argidx);
-
-               design->sort();
-
-               log("Output filename: %s\n", filename.c_str());
-               *f << stringf("# Generated by %s\n", yosys_version_str);
-               ILANG_BACKEND::dump_design(*f, design, selected, true, false);
-       }
-} IlangBackend;
-
-struct DumpPass : public Pass {
-       DumpPass() : Pass("dump", "print parts of the design in ilang format") { }
-       void help() override
-       {
-               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
-               log("\n");
-               log("    dump [options] [selection]\n");
-               log("\n");
-               log("Write the selected parts of the design to the console or specified file in\n");
-               log("ilang format.\n");
-               log("\n");
-               log("    -m\n");
-               log("        also dump the module headers, even if only parts of a single\n");
-               log("        module is selected\n");
-               log("\n");
-               log("    -n\n");
-               log("        only dump the module headers if the entire module is selected\n");
-               log("\n");
-               log("    -o <filename>\n");
-               log("        write to the specified file.\n");
-               log("\n");
-               log("    -a <filename>\n");
-               log("        like -outfile but append instead of overwrite\n");
-               log("\n");
-       }
-       void execute(std::vector<std::string> args, RTLIL::Design *design) override
-       {
-               std::string filename;
-               bool flag_m = false, flag_n = false, append = false;
-
-               size_t argidx;
-               for (argidx = 1; argidx < args.size(); argidx++)
-               {
-                       std::string arg = args[argidx];
-                       if ((arg == "-o" || arg == "-outfile") && argidx+1 < args.size()) {
-                               filename = args[++argidx];
-                               append = false;
-                               continue;
-                       }
-                       if ((arg == "-a" || arg == "-append") && argidx+1 < args.size()) {
-                               filename = args[++argidx];
-                               append = true;
-                               continue;
-                       }
-                       if (arg == "-m") {
-                               flag_m = true;
-                               continue;
-                       }
-                       if (arg == "-n") {
-                               flag_n = true;
-                               continue;
-                       }
-                       break;
-               }
-               extra_args(args, argidx, design);
-
-               std::ostream *f;
-               std::stringstream buf;
-
-               if (!filename.empty()) {
-                       rewrite_filename(filename);
-                       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 = &buf;
-               }
-
-               ILANG_BACKEND::dump_design(*f, design, true, flag_m, flag_n);
-
-               if (!filename.empty()) {
-                       delete f;
-               } else {
-                       log("%s", buf.str().c_str());
-               }
-       }
-} DumpPass;
-
-PRIVATE_NAMESPACE_END
diff --git a/backends/ilang/ilang_backend.h b/backends/ilang/ilang_backend.h
deleted file mode 100644 (file)
index 97dcbb6..0000000
+++ /dev/null
@@ -1,51 +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.
- *
- *  ---
- *
- *  A very simple and straightforward backend for the RTLIL text
- *  representation (as understood by the 'ilang' frontend).
- *
- */
-
-#ifndef ILANG_BACKEND_H
-#define ILANG_BACKEND_H
-
-#include "kernel/yosys.h"
-#include <stdio.h>
-
-YOSYS_NAMESPACE_BEGIN
-
-namespace ILANG_BACKEND {
-       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
index 98a14173b10561bf7b024adabc877c642683d164..a6b36de6cbab0249867d4d52510eb732e5ad8b81 100644 (file)
@@ -59,7 +59,7 @@ struct IntersynthBackend : public Backend {
                log("        do not generate celltypes and conntypes commands. i.e. just output\n");
                log("        the netlists. this is used for postsilicon synthesis.\n");
                log("\n");
-               log("    -lib <verilog_or_ilang_file>\n");
+               log("    -lib <verilog_or_rtlil_file>\n");
                log("        Use the specified library file for determining whether cell ports are\n");
                log("        inputs or outputs. This option can be used multiple times to specify\n");
                log("        more than one library.\n");
@@ -108,7 +108,7 @@ struct IntersynthBackend : public Backend {
                        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.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "ilang" : "verilog"));
+                       Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "rtlil" : "verilog"));
                        libs.push_back(lib);
                }
 
diff --git a/backends/rtlil/Makefile.inc b/backends/rtlil/Makefile.inc
new file mode 100644 (file)
index 0000000..f691282
--- /dev/null
@@ -0,0 +1,3 @@
+
+OBJS += backends/rtlil/rtlil_backend.o
+
diff --git a/backends/rtlil/rtlil_backend.cc b/backends/rtlil/rtlil_backend.cc
new file mode 100644 (file)
index 0000000..01b4bde
--- /dev/null
@@ -0,0 +1,536 @@
+/*
+ *  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.
+ *
+ *  ---
+ *
+ *  A very simple and straightforward backend for the RTLIL text
+ *  representation.
+ *
+ */
+
+#include "rtlil_backend.h"
+#include "kernel/yosys.h"
+#include <errno.h>
+
+USING_YOSYS_NAMESPACE
+using namespace RTLIL_BACKEND;
+YOSYS_NAMESPACE_BEGIN
+
+void RTLIL_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int width, int offset, bool autoint)
+{
+       if (width < 0)
+               width = data.bits.size() - offset;
+       if ((data.flags & RTLIL::CONST_FLAG_STRING) == 0 || width != (int)data.bits.size()) {
+               if (width == 32 && autoint) {
+                       int32_t val = 0;
+                       for (int i = 0; i < width; i++) {
+                               log_assert(offset+i < (int)data.bits.size());
+                               switch (data.bits[offset+i]) {
+                               case State::S0: break;
+                               case State::S1: val |= 1 << i; break;
+                               default: val = -1; break;
+                               }
+                       }
+                       if (val >= 0) {
+                               f << stringf("%d", val);
+                               return;
+                       }
+               }
+               f << stringf("%d'", width);
+               for (int i = offset+width-1; i >= offset; i--) {
+                       log_assert(i < (int)data.bits.size());
+                       switch (data.bits[i]) {
+                       case State::S0: f << stringf("0"); break;
+                       case State::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 {
+               f << stringf("\"");
+               std::string str = data.decode_string();
+               for (size_t i = 0; i < str.size(); i++) {
+                       if (str[i] == '\n')
+                               f << stringf("\\n");
+                       else if (str[i] == '\t')
+                               f << stringf("\\t");
+                       else if (str[i] < 32)
+                               f << stringf("\\%03o", str[i]);
+                       else if (str[i] == '"')
+                               f << stringf("\\\"");
+                       else if (str[i] == '\\')
+                               f << stringf("\\\\");
+                       else
+                               f << str[i];
+               }
+               f << stringf("\"");
+       }
+}
+
+void RTLIL_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)
+                       f << stringf("%s", chunk.wire->name.c_str());
+               else if (chunk.width == 1)
+                       f << stringf("%s [%d]", chunk.wire->name.c_str(), chunk.offset);
+               else
+                       f << stringf("%s [%d:%d]", chunk.wire->name.c_str(), chunk.offset+chunk.width-1, chunk.offset);
+       }
+}
+
+void RTLIL_BACKEND::dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, bool autoint)
+{
+       if (sig.is_chunk()) {
+               dump_sigchunk(f, sig.as_chunk(), autoint);
+       } else {
+               f << stringf("{ ");
+               for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); ++it) {
+                       dump_sigchunk(f, *it, false);
+                       f << stringf(" ");
+               }
+               f << stringf("}");
+       }
+}
+
+void RTLIL_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire)
+{
+       for (auto &it : wire->attributes) {
+               f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str());
+               dump_const(f, it.second);
+               f << stringf("\n");
+       }
+       f << stringf("%s" "wire ", indent.c_str());
+       if (wire->width != 1)
+               f << stringf("width %d ", wire->width);
+       if (wire->upto)
+               f << stringf("upto ");
+       if (wire->start_offset != 0)
+               f << stringf("offset %d ", wire->start_offset);
+       if (wire->port_input && !wire->port_output)
+               f << stringf("input %d ", wire->port_id);
+       if (!wire->port_input && wire->port_output)
+               f << stringf("output %d ", wire->port_id);
+       if (wire->port_input && wire->port_output)
+               f << stringf("inout %d ", wire->port_id);
+       if (wire->is_signed)
+               f << stringf("signed ");
+       f << stringf("%s\n", wire->name.c_str());
+}
+
+void RTLIL_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL::Memory *memory)
+{
+       for (auto &it : memory->attributes) {
+               f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str());
+               dump_const(f, it.second);
+               f << stringf("\n");
+       }
+       f << stringf("%s" "memory ", indent.c_str());
+       if (memory->width != 1)
+               f << stringf("width %d ", memory->width);
+       if (memory->size != 0)
+               f << stringf("size %d ", memory->size);
+       if (memory->start_offset != 0)
+               f << stringf("offset %d ", memory->start_offset);
+       f << stringf("%s\n", memory->name.c_str());
+}
+
+void RTLIL_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL::Cell *cell)
+{
+       for (auto &it : cell->attributes) {
+               f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str());
+               dump_const(f, it.second);
+               f << stringf("\n");
+       }
+       f << stringf("%s" "cell %s %s\n", indent.c_str(), cell->type.c_str(), cell->name.c_str());
+       for (auto &it : cell->parameters) {
+               f << stringf("%s  parameter%s%s %s ", indent.c_str(),
+                               (it.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "",
+                               (it.second.flags & RTLIL::CONST_FLAG_REAL) != 0 ? " real" : "",
+                               it.first.c_str());
+               dump_const(f, it.second);
+               f << stringf("\n");
+       }
+       for (auto &it : cell->connections()) {
+               f << stringf("%s  connect %s ", indent.c_str(), it.first.c_str());
+               dump_sigspec(f, it.second);
+               f << stringf("\n");
+       }
+       f << stringf("%s" "end\n", indent.c_str());
+}
+
+void RTLIL_BACKEND::dump_proc_case_body(std::ostream &f, std::string indent, const RTLIL::CaseRule *cs)
+{
+       for (auto it = cs->actions.begin(); it != cs->actions.end(); ++it)
+       {
+               f << stringf("%s" "assign ", indent.c_str());
+               dump_sigspec(f, it->first);
+               f << stringf(" ");
+               dump_sigspec(f, it->second);
+               f << stringf("\n");
+       }
+
+       for (auto it = cs->switches.begin(); it != cs->switches.end(); ++it)
+               dump_proc_switch(f, indent, *it);
+}
+
+void RTLIL_BACKEND::dump_proc_switch(std::ostream &f, std::string indent, const RTLIL::SwitchRule *sw)
+{
+       for (auto it = sw->attributes.begin(); it != sw->attributes.end(); ++it) {
+               f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
+               dump_const(f, it->second);
+               f << stringf("\n");
+       }
+
+       f << stringf("%s" "switch ", indent.c_str());
+       dump_sigspec(f, sw->signal);
+       f << stringf("\n");
+
+       for (auto it = sw->cases.begin(); it != sw->cases.end(); ++it)
+       {
+               for (auto ait = (*it)->attributes.begin(); ait != (*it)->attributes.end(); ++ait) {
+                       f << stringf("%s  attribute %s ", indent.c_str(), ait->first.c_str());
+                       dump_const(f, ait->second);
+                       f << stringf("\n");
+               }
+               f << stringf("%s  case ", indent.c_str());
+               for (size_t i = 0; i < (*it)->compare.size(); i++) {
+                       if (i > 0)
+                               f << stringf(" , ");
+                       dump_sigspec(f, (*it)->compare[i]);
+               }
+               f << stringf("\n");
+
+               dump_proc_case_body(f, indent + "    ", *it);
+       }
+
+       f << stringf("%s" "end\n", indent.c_str());
+}
+
+void RTLIL_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RTLIL::SyncRule *sy)
+{
+       f << stringf("%s" "sync ", indent.c_str());
+       switch (sy->type) {
+       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);
+               f << stringf("\n");
+               break;
+       case RTLIL::STa: f << stringf("always\n"); break;
+       case RTLIL::STg: f << stringf("global\n"); break;
+       case RTLIL::STi: f << stringf("init\n"); break;
+       }
+
+       for (auto it = sy->actions.begin(); it != sy->actions.end(); ++it) {
+               f << stringf("%s  update ", indent.c_str());
+               dump_sigspec(f, it->first);
+               f << stringf(" ");
+               dump_sigspec(f, it->second);
+               f << stringf("\n");
+       }
+}
+
+void RTLIL_BACKEND::dump_proc(std::ostream &f, std::string indent, const RTLIL::Process *proc)
+{
+       for (auto it = proc->attributes.begin(); it != proc->attributes.end(); ++it) {
+               f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
+               dump_const(f, it->second);
+               f << stringf("\n");
+       }
+       f << stringf("%s" "process %s\n", indent.c_str(), proc->name.c_str());
+       dump_proc_case_body(f, indent + "  ", &proc->root_case);
+       for (auto it = proc->syncs.begin(); it != proc->syncs.end(); ++it)
+               dump_proc_sync(f, indent + "  ", *it);
+       f << stringf("%s" "end\n", indent.c_str());
+}
+
+void RTLIL_BACKEND::dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
+{
+       f << stringf("%s" "connect ", indent.c_str());
+       dump_sigspec(f, left);
+       f << stringf(" ");
+       dump_sigspec(f, right);
+       f << stringf("\n");
+}
+
+void RTLIL_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);
+
+       if (print_header)
+       {
+               for (auto it = module->attributes.begin(); it != module->attributes.end(); ++it) {
+                       f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
+                       dump_const(f, it->second);
+                       f << stringf("\n");
+               }
+
+               f << stringf("%s" "module %s\n", indent.c_str(), module->name.c_str());
+
+               if (!module->avail_parameters.empty()) {
+                       if (only_selected)
+                               f << stringf("\n");
+                       for (const auto &p : module->avail_parameters) {
+                               const auto &it = module->parameter_default_values.find(p);
+                               if (it == module->parameter_default_values.end()) {
+                                       f << stringf("%s" "  parameter %s\n", indent.c_str(), p.c_str());
+                               } else {
+                                       f << stringf("%s" "  parameter %s ", indent.c_str(), p.c_str());
+                                       dump_const(f, it->second);
+                                       f << stringf("\n");
+                               }
+                       }
+               }
+       }
+
+       if (print_body)
+       {
+               for (auto it : module->wires())
+                       if (!only_selected || design->selected(module, it)) {
+                               if (only_selected)
+                                       f << stringf("\n");
+                               dump_wire(f, indent + "  ", it);
+                       }
+
+               for (auto it : module->memories)
+                       if (!only_selected || design->selected(module, it.second)) {
+                               if (only_selected)
+                                       f << stringf("\n");
+                               dump_memory(f, indent + "  ", it.second);
+                       }
+
+               for (auto it : module->cells())
+                       if (!only_selected || design->selected(module, it)) {
+                               if (only_selected)
+                                       f << stringf("\n");
+                               dump_cell(f, indent + "  ", it);
+                       }
+
+               for (auto it : module->processes)
+                       if (!only_selected || design->selected(module, it.second)) {
+                               if (only_selected)
+                                       f << stringf("\n");
+                               dump_proc(f, indent + "  ", it.second);
+                       }
+
+               bool first_conn_line = true;
+               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()) {
+                                       if (c.wire == NULL || !design->selected(module, c.wire))
+                                               continue;
+                                       show_conn = true;
+                               }
+                       }
+                       if (show_conn) {
+                               if (only_selected && first_conn_line)
+                                       f << stringf("\n");
+                               dump_conn(f, indent + "  ", it->first, it->second);
+                               first_conn_line = false;
+                       }
+               }
+       }
+
+       if (print_header)
+               f << stringf("%s" "end\n", indent.c_str());
+}
+
+void RTLIL_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 module : design->modules()) {
+                       if (design->selected_whole_module(module->name))
+                               flag_m = true;
+                       if (design->selected(module))
+                               count_selected_mods++;
+               }
+               if (count_selected_mods > 1)
+                       flag_m = true;
+       }
+
+       if (!only_selected || flag_m) {
+               if (only_selected)
+                       f << stringf("\n");
+               f << stringf("autoidx %d\n", autoidx);
+       }
+
+       for (auto module : design->modules()) {
+               if (!only_selected || design->selected(module)) {
+                       if (only_selected)
+                               f << stringf("\n");
+                       dump_module(f, "", module, design, only_selected, flag_m, flag_n);
+               }
+       }
+
+       log_assert(init_autoidx == autoidx);
+}
+
+YOSYS_NAMESPACE_END
+PRIVATE_NAMESPACE_BEGIN
+
+struct RTLILBackend : public Backend {
+       RTLILBackend() : Backend("rtlil", "write design to RTLIL file") { }
+       void help() override
+       {
+               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+               log("\n");
+               log("    write_rtlil [filename]\n");
+               log("\n");
+               log("Write the current design to an RTLIL file. (RTLIL is a text representation\n");
+               log("of a design in yosys's internal format.)\n");
+               log("\n");
+               log("    -selected\n");
+               log("        only write selected parts of the design.\n");
+               log("\n");
+       }
+       void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override
+       {
+               bool selected = false;
+
+               log_header(design, "Executing RTLIL backend.\n");
+
+               size_t argidx;
+               for (argidx = 1; argidx < args.size(); argidx++) {
+                       std::string arg = args[argidx];
+                       if (arg == "-selected") {
+                               selected = true;
+                               continue;
+                       }
+                       break;
+               }
+               extra_args(f, filename, args, argidx);
+
+               design->sort();
+
+               log("Output filename: %s\n", filename.c_str());
+               *f << stringf("# Generated by %s\n", yosys_version_str);
+               RTLIL_BACKEND::dump_design(*f, design, selected, true, false);
+       }
+} RTLILBackend;
+
+struct IlangBackend : public Backend {
+       IlangBackend() : Backend("ilang", "(deprecated) alias of write_rtlil") { }
+       void help() override
+       {
+               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+               log("\n");
+               log("See `help write_rtlil`.\n");
+               log("\n");
+       }
+       void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override
+       {
+               RTLILBackend.execute(f, filename, args, design);
+       }
+} IlangBackend;
+
+struct DumpPass : public Pass {
+       DumpPass() : Pass("dump", "print parts of the design in RTLIL format") { }
+       void help() override
+       {
+               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+               log("\n");
+               log("    dump [options] [selection]\n");
+               log("\n");
+               log("Write the selected parts of the design to the console or specified file in\n");
+               log("RTLIL format.\n");
+               log("\n");
+               log("    -m\n");
+               log("        also dump the module headers, even if only parts of a single\n");
+               log("        module is selected\n");
+               log("\n");
+               log("    -n\n");
+               log("        only dump the module headers if the entire module is selected\n");
+               log("\n");
+               log("    -o <filename>\n");
+               log("        write to the specified file.\n");
+               log("\n");
+               log("    -a <filename>\n");
+               log("        like -outfile but append instead of overwrite\n");
+               log("\n");
+       }
+       void execute(std::vector<std::string> args, RTLIL::Design *design) override
+       {
+               std::string filename;
+               bool flag_m = false, flag_n = false, append = false;
+
+               size_t argidx;
+               for (argidx = 1; argidx < args.size(); argidx++)
+               {
+                       std::string arg = args[argidx];
+                       if ((arg == "-o" || arg == "-outfile") && argidx+1 < args.size()) {
+                               filename = args[++argidx];
+                               append = false;
+                               continue;
+                       }
+                       if ((arg == "-a" || arg == "-append") && argidx+1 < args.size()) {
+                               filename = args[++argidx];
+                               append = true;
+                               continue;
+                       }
+                       if (arg == "-m") {
+                               flag_m = true;
+                               continue;
+                       }
+                       if (arg == "-n") {
+                               flag_n = true;
+                               continue;
+                       }
+                       break;
+               }
+               extra_args(args, argidx, design);
+
+               std::ostream *f;
+               std::stringstream buf;
+
+               if (!filename.empty()) {
+                       rewrite_filename(filename);
+                       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 = &buf;
+               }
+
+               RTLIL_BACKEND::dump_design(*f, design, true, flag_m, flag_n);
+
+               if (!filename.empty()) {
+                       delete f;
+               } else {
+                       log("%s", buf.str().c_str());
+               }
+       }
+} DumpPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/backends/rtlil/rtlil_backend.h b/backends/rtlil/rtlil_backend.h
new file mode 100644 (file)
index 0000000..77eea35
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  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.
+ *
+ *  ---
+ *
+ *  A very simple and straightforward backend for the RTLIL text
+ *  representation.
+ *
+ */
+
+#ifndef RTLIL_BACKEND_H
+#define RTLIL_BACKEND_H
+
+#include "kernel/yosys.h"
+#include <stdio.h>
+
+YOSYS_NAMESPACE_BEGIN
+
+namespace RTLIL_BACKEND {
+       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/frontends/ilang/.gitignore b/frontends/ilang/.gitignore
deleted file mode 100644 (file)
index f586b33..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-ilang_lexer.cc
-ilang_parser.output
-ilang_parser.tab.cc
-ilang_parser.tab.hh
diff --git a/frontends/ilang/Makefile.inc b/frontends/ilang/Makefile.inc
deleted file mode 100644 (file)
index 6f1f0e8..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-
-GENFILES += frontends/ilang/ilang_parser.tab.cc
-GENFILES += frontends/ilang/ilang_parser.tab.hh
-GENFILES += frontends/ilang/ilang_parser.output
-GENFILES += frontends/ilang/ilang_lexer.cc
-
-frontends/ilang/ilang_parser.tab.cc: frontends/ilang/ilang_parser.y
-       $(Q) mkdir -p $(dir $@)
-       $(P) $(BISON) -o $@ -d -r all -b frontends/ilang/ilang_parser $<
-
-frontends/ilang/ilang_parser.tab.hh: frontends/ilang/ilang_parser.tab.cc
-
-frontends/ilang/ilang_lexer.cc: frontends/ilang/ilang_lexer.l
-       $(Q) mkdir -p $(dir $@)
-       $(P) flex -o frontends/ilang/ilang_lexer.cc $<
-
-OBJS += frontends/ilang/ilang_parser.tab.o frontends/ilang/ilang_lexer.o
-OBJS += frontends/ilang/ilang_frontend.o
-
diff --git a/frontends/ilang/ilang_frontend.cc b/frontends/ilang/ilang_frontend.cc
deleted file mode 100644 (file)
index 973e62f..0000000
+++ /dev/null
@@ -1,100 +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.
- *
- *  ---
- *
- *  A very simple and straightforward frontend for the RTLIL text
- *  representation (as generated by the 'ilang' backend).
- *
- */
-
-#include "ilang_frontend.h"
-#include "kernel/register.h"
-#include "kernel/log.h"
-
-void rtlil_frontend_ilang_yyerror(char const *s)
-{
-       YOSYS_NAMESPACE_PREFIX log_error("Parser error in line %d: %s\n", rtlil_frontend_ilang_yyget_lineno(), s);
-}
-
-YOSYS_NAMESPACE_BEGIN
-
-struct IlangFrontend : public Frontend {
-       IlangFrontend() : Frontend("ilang", "read modules from ilang file") { }
-       void help() override
-       {
-               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
-               log("\n");
-               log("    read_ilang [filename]\n");
-               log("\n");
-               log("Load modules from an ilang file to the current design. (ilang is a text\n");
-               log("representation of a design in yosys's internal format.)\n");
-               log("\n");
-               log("    -nooverwrite\n");
-               log("        ignore re-definitions of modules. (the default behavior is to\n");
-               log("        create an error message if the existing module is not a blackbox\n");
-               log("        module, and overwrite the existing module if it is a blackbox module.)\n");
-               log("\n");
-               log("    -overwrite\n");
-               log("        overwrite existing modules with the same name\n");
-               log("\n");
-               log("    -lib\n");
-               log("        only create empty blackbox modules\n");
-               log("\n");
-       }
-       void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override
-       {
-               ILANG_FRONTEND::flag_nooverwrite = false;
-               ILANG_FRONTEND::flag_overwrite = false;
-               ILANG_FRONTEND::flag_lib = false;
-
-               log_header(design, "Executing ILANG frontend.\n");
-
-               size_t argidx;
-               for (argidx = 1; argidx < args.size(); argidx++) {
-                       std::string arg = args[argidx];
-                       if (arg == "-nooverwrite") {
-                               ILANG_FRONTEND::flag_nooverwrite = true;
-                               ILANG_FRONTEND::flag_overwrite = false;
-                               continue;
-                       }
-                       if (arg == "-overwrite") {
-                               ILANG_FRONTEND::flag_nooverwrite = false;
-                               ILANG_FRONTEND::flag_overwrite = true;
-                               continue;
-                       }
-                       if (arg == "-lib") {
-                               ILANG_FRONTEND::flag_lib = true;
-                               continue;
-                       }
-                       break;
-               }
-               extra_args(f, filename, args, argidx);
-
-               log("Input filename: %s\n", filename.c_str());
-
-               ILANG_FRONTEND::lexin = f;
-               ILANG_FRONTEND::current_design = design;
-               rtlil_frontend_ilang_yydebug = false;
-               rtlil_frontend_ilang_yyrestart(NULL);
-               rtlil_frontend_ilang_yyparse();
-               rtlil_frontend_ilang_yylex_destroy();
-       }
-} IlangFrontend;
-
-YOSYS_NAMESPACE_END
-
diff --git a/frontends/ilang/ilang_frontend.h b/frontends/ilang/ilang_frontend.h
deleted file mode 100644 (file)
index f8a1528..0000000
+++ /dev/null
@@ -1,51 +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.
- *
- *  ---
- *
- *  A very simple and straightforward frontend for the RTLIL text
- *  representation (as generated by the 'ilang' backend).
- *
- */
-
-#ifndef ILANG_FRONTEND_H
-#define ILANG_FRONTEND_H
-
-#include "kernel/yosys.h"
-
-YOSYS_NAMESPACE_BEGIN
-
-namespace ILANG_FRONTEND {
-       extern std::istream *lexin;
-       extern RTLIL::Design *current_design;
-       extern bool flag_nooverwrite;
-       extern bool flag_overwrite;
-       extern bool flag_lib;
-}
-
-YOSYS_NAMESPACE_END
-
-extern int rtlil_frontend_ilang_yydebug;
-int rtlil_frontend_ilang_yylex(void);
-void rtlil_frontend_ilang_yyerror(char const *s);
-void rtlil_frontend_ilang_yyrestart(FILE *f);
-int rtlil_frontend_ilang_yyparse(void);
-int rtlil_frontend_ilang_yylex_destroy(void);
-int rtlil_frontend_ilang_yyget_lineno(void);
-
-#endif
-
diff --git a/frontends/ilang/ilang_lexer.l b/frontends/ilang/ilang_lexer.l
deleted file mode 100644 (file)
index 3362ed6..0000000
+++ /dev/null
@@ -1,150 +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.
- *
- *  ---
- *
- *  A very simple and straightforward frontend for the RTLIL text
- *  representation (as generated by the 'ilang' backend).
- *
- */
-
-%{
-
-#ifdef __clang__
-// bison generates code using the 'register' storage class specifier
-#pragma clang diagnostic ignored "-Wdeprecated-register"
-#endif
-
-#include <cstdlib>
-#include "frontends/ilang/ilang_frontend.h"
-#include "ilang_parser.tab.hh"
-
-USING_YOSYS_NAMESPACE
-
-#define YY_INPUT(buf,result,max_size) \
-       result = readsome(*ILANG_FRONTEND::lexin, buf, max_size)
-
-%}
-
-%option yylineno
-%option noyywrap
-%option nounput
-%option prefix="rtlil_frontend_ilang_yy"
-
-%x STRING
-
-%%
-
-"autoidx"      { return TOK_AUTOIDX; }
-"module"       { return TOK_MODULE; }
-"attribute"    { return TOK_ATTRIBUTE; }
-"parameter"    { return TOK_PARAMETER; }
-"signed"       { return TOK_SIGNED; }
-"real"         { return TOK_REAL; }
-"wire"         { return TOK_WIRE; }
-"memory"       { return TOK_MEMORY; }
-"width"                { return TOK_WIDTH; }
-"upto"         { return TOK_UPTO; }
-"offset"       { return TOK_OFFSET; }
-"size"         { return TOK_SIZE; }
-"input"                { return TOK_INPUT; }
-"output"       { return TOK_OUTPUT; }
-"inout"                { return TOK_INOUT; }
-"cell"         { return TOK_CELL; }
-"connect"      { return TOK_CONNECT; }
-"switch"       { return TOK_SWITCH; }
-"case"         { return TOK_CASE; }
-"assign"       { return TOK_ASSIGN; }
-"sync"         { return TOK_SYNC; }
-"low"          { return TOK_LOW; }
-"high"         { return TOK_HIGH; }
-"posedge"      { return TOK_POSEDGE; }
-"negedge"      { return TOK_NEGEDGE; }
-"edge"         { return TOK_EDGE; }
-"always"       { return TOK_ALWAYS; }
-"global"       { return TOK_GLOBAL; }
-"init"         { return TOK_INIT; }
-"update"       { return TOK_UPDATE; }
-"process"      { return TOK_PROCESS; }
-"end"          { return TOK_END; }
-
-[a-z]+         { return TOK_INVALID; }
-
-"\\"[^ \t\r\n]+                { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_ID; }
-"$"[^ \t\r\n]+         { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_ID; }
-"."[0-9]+              { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_ID; }
-
-[0-9]+'[01xzm-]*       { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_VALUE; }
--?[0-9]+               {
-       char *end = nullptr;
-       errno = 0;
-       long value = strtol(yytext, &end, 10);
-       log_assert(end == yytext + strlen(yytext));
-       if (errno == ERANGE)
-               return TOK_INVALID; // literal out of range of long
-       if (value < INT_MIN || value > INT_MAX)
-               return TOK_INVALID; // literal out of range of int (relevant mostly for LP64 platforms)
-       rtlil_frontend_ilang_yylval.integer = value;
-       return TOK_INT;
-}
-
-\"             { BEGIN(STRING); }
-<STRING>\\.    { yymore(); }
-<STRING>\"     {
-       BEGIN(0);
-       char *yystr = strdup(yytext);
-       yystr[strlen(yytext) - 1] = 0;
-       int i = 0, j = 0;
-       while (yystr[i]) {
-               if (yystr[i] == '\\' && yystr[i + 1]) {
-                       i++;
-                       if (yystr[i] == 'n')
-                               yystr[i] = '\n';
-                       else if (yystr[i] == 't')
-                               yystr[i] = '\t';
-                       else if ('0' <= yystr[i] && yystr[i] <= '7') {
-                               yystr[i] = yystr[i] - '0';
-                               if ('0' <= yystr[i + 1] && yystr[i + 1] <= '7') {
-                                       yystr[i + 1] = yystr[i] * 8 + yystr[i + 1] - '0';
-                                       i++;
-                               }
-                               if ('0' <= yystr[i + 1] && yystr[i + 1] <= '7') {
-                                       yystr[i + 1] = yystr[i] * 8 + yystr[i + 1] - '0';
-                                       i++;
-                               }
-                       }
-               }
-               yystr[j++] = yystr[i++];
-       }
-       yystr[j] = 0;
-       rtlil_frontend_ilang_yylval.string = yystr;
-       return TOK_STRING;
-}
-<STRING>.      { yymore(); }
-
-"#"[^\n]*      /* ignore comments */
-[ \t]          /* ignore non-newline whitespaces */
-[\r\n]+                { return TOK_EOL; }
-
-.               { return *yytext; }
-
-%%
-
-// this is a hack to avoid the 'yyinput defined but not used' error msgs
-void *rtlil_frontend_ilang_avoid_input_warnings() {
-       return (void*)&yyinput;
-}
diff --git a/frontends/ilang/ilang_parser.y b/frontends/ilang/ilang_parser.y
deleted file mode 100644 (file)
index 879ef4a..0000000
+++ /dev/null
@@ -1,484 +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.
- *
- *  ---
- *
- *  A very simple and straightforward frontend for the RTLIL text
- *  representation (as generated by the 'ilang' backend).
- *
- */
-
-%{
-#include <list>
-#include "frontends/ilang/ilang_frontend.h"
-YOSYS_NAMESPACE_BEGIN
-namespace ILANG_FRONTEND {
-       std::istream *lexin;
-       RTLIL::Design *current_design;
-       RTLIL::Module *current_module;
-       RTLIL::Wire *current_wire;
-       RTLIL::Memory *current_memory;
-       RTLIL::Cell *current_cell;
-       RTLIL::Process *current_process;
-       std::vector<std::vector<RTLIL::SwitchRule*>*> switch_stack;
-       std::vector<RTLIL::CaseRule*> case_stack;
-       dict<RTLIL::IdString, RTLIL::Const> attrbuf;
-       bool flag_nooverwrite, flag_overwrite, flag_lib;
-       bool delete_current_module;
-}
-using namespace ILANG_FRONTEND;
-YOSYS_NAMESPACE_END
-USING_YOSYS_NAMESPACE
-%}
-
-%define api.prefix {rtlil_frontend_ilang_yy}
-
-/* The union is defined in the header, so we need to provide all the
- * includes it requires
- */
-%code requires {
-#include <string>
-#include <vector>
-#include "frontends/ilang/ilang_frontend.h"
-}
-
-%union {
-       char *string;
-       int integer;
-       YOSYS_NAMESPACE_PREFIX RTLIL::Const *data;
-       YOSYS_NAMESPACE_PREFIX RTLIL::SigSpec *sigspec;
-       std::vector<YOSYS_NAMESPACE_PREFIX RTLIL::SigSpec> *rsigspec;
-}
-
-%token <string> TOK_ID TOK_VALUE TOK_STRING
-%token <integer> TOK_INT
-%token TOK_AUTOIDX TOK_MODULE TOK_WIRE TOK_WIDTH TOK_INPUT TOK_OUTPUT TOK_INOUT
-%token TOK_CELL TOK_CONNECT TOK_SWITCH TOK_CASE TOK_ASSIGN TOK_SYNC
-%token TOK_LOW TOK_HIGH TOK_POSEDGE TOK_NEGEDGE TOK_EDGE TOK_ALWAYS TOK_GLOBAL TOK_INIT
-%token TOK_UPDATE TOK_PROCESS TOK_END TOK_INVALID TOK_EOL TOK_OFFSET
-%token TOK_PARAMETER TOK_ATTRIBUTE TOK_MEMORY TOK_SIZE TOK_SIGNED TOK_REAL TOK_UPTO
-
-%type <rsigspec> sigspec_list_reversed
-%type <sigspec> sigspec sigspec_list
-%type <integer> sync_type
-%type <data> constant
-
-%expect 0
-%debug
-
-%%
-
-input:
-       optional_eol {
-               attrbuf.clear();
-       } design {
-               if (attrbuf.size() != 0)
-                       rtlil_frontend_ilang_yyerror("dangling attribute");
-       };
-
-EOL:
-       optional_eol TOK_EOL;
-
-optional_eol:
-       optional_eol TOK_EOL | /* empty */;
-
-design:
-       design module |
-       design attr_stmt |
-       design autoidx_stmt |
-       /* empty */;
-
-module:
-       TOK_MODULE TOK_ID EOL {
-               delete_current_module = false;
-               if (current_design->has($2)) {
-                       RTLIL::Module *existing_mod = current_design->module($2);
-                       if (!flag_overwrite && (flag_lib || (attrbuf.count(ID::blackbox) && attrbuf.at(ID::blackbox).as_bool()))) {
-                               log("Ignoring blackbox re-definition of module %s.\n", $2);
-                               delete_current_module = true;
-                       } else if (!flag_nooverwrite && !flag_overwrite && !existing_mod->get_bool_attribute(ID::blackbox)) {
-                               rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of module %s.", $2).c_str());
-                       } else if (flag_nooverwrite) {
-                               log("Ignoring re-definition of module %s.\n", $2);
-                               delete_current_module = true;
-                       } else {
-                               log("Replacing existing%s module %s.\n", existing_mod->get_bool_attribute(ID::blackbox) ? " blackbox" : "", $2);
-                               current_design->remove(existing_mod);
-                       }
-               }
-               current_module = new RTLIL::Module;
-               current_module->name = $2;
-               current_module->attributes = attrbuf;
-               if (!delete_current_module)
-                       current_design->add(current_module);
-               attrbuf.clear();
-               free($2);
-       } module_body TOK_END {
-               if (attrbuf.size() != 0)
-                       rtlil_frontend_ilang_yyerror("dangling attribute");
-               current_module->fixup_ports();
-               if (delete_current_module)
-                       delete current_module;
-               else if (flag_lib)
-                       current_module->makeblackbox();
-               current_module = nullptr;
-       } EOL;
-
-module_body:
-       module_body module_stmt |
-       /* empty */;
-
-module_stmt:
-       param_stmt | param_defval_stmt | attr_stmt | wire_stmt | memory_stmt | cell_stmt | proc_stmt | conn_stmt;
-
-param_stmt:
-       TOK_PARAMETER TOK_ID EOL {
-               current_module->avail_parameters($2);
-               free($2);
-       };
-
-param_defval_stmt:
-       TOK_PARAMETER TOK_ID constant EOL {
-               current_module->avail_parameters($2);
-               current_module->parameter_default_values[$2] = *$3;
-               free($2);
-       };
-
-attr_stmt:
-       TOK_ATTRIBUTE TOK_ID constant EOL {
-               attrbuf[$2] = *$3;
-               delete $3;
-               free($2);
-       };
-
-autoidx_stmt:
-       TOK_AUTOIDX TOK_INT EOL {
-               autoidx = max(autoidx, $2);
-       };
-
-wire_stmt:
-       TOK_WIRE {
-               current_wire = current_module->addWire("$__ilang_frontend_tmp__");
-               current_wire->attributes = attrbuf;
-               attrbuf.clear();
-       } wire_options TOK_ID EOL {
-               if (current_module->wire($4) != nullptr)
-                       rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of wire %s.", $4).c_str());
-               current_module->rename(current_wire, $4);
-               free($4);
-       };
-
-wire_options:
-       wire_options TOK_WIDTH TOK_INT {
-               current_wire->width = $3;
-       } |
-       wire_options TOK_WIDTH TOK_INVALID {
-               rtlil_frontend_ilang_yyerror("ilang error: invalid wire width");
-       } |
-       wire_options TOK_UPTO {
-               current_wire->upto = true;
-       } |
-       wire_options TOK_SIGNED {
-               current_wire->is_signed = true;
-       } |
-       wire_options TOK_OFFSET TOK_INT {
-               current_wire->start_offset = $3;
-       } |
-       wire_options TOK_INPUT TOK_INT {
-               current_wire->port_id = $3;
-               current_wire->port_input = true;
-               current_wire->port_output = false;
-       } |
-       wire_options TOK_OUTPUT TOK_INT {
-               current_wire->port_id = $3;
-               current_wire->port_input = false;
-               current_wire->port_output = true;
-       } |
-       wire_options TOK_INOUT TOK_INT {
-               current_wire->port_id = $3;
-               current_wire->port_input = true;
-               current_wire->port_output = true;
-       } |
-       /* empty */;
-
-memory_stmt:
-       TOK_MEMORY {
-               current_memory = new RTLIL::Memory;
-               current_memory->attributes = attrbuf;
-               attrbuf.clear();
-       } memory_options TOK_ID EOL {
-               if (current_module->memories.count($4) != 0)
-                       rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of memory %s.", $4).c_str());
-               current_memory->name = $4;
-               current_module->memories[$4] = current_memory;
-               free($4);
-       };
-
-memory_options:
-       memory_options TOK_WIDTH TOK_INT {
-               current_memory->width = $3;
-       } |
-       memory_options TOK_SIZE TOK_INT {
-               current_memory->size = $3;
-       } |
-       memory_options TOK_OFFSET TOK_INT {
-               current_memory->start_offset = $3;
-       } |
-       /* empty */;
-
-cell_stmt:
-       TOK_CELL TOK_ID TOK_ID EOL {
-               if (current_module->cell($3) != nullptr)
-                       rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell %s.", $3).c_str());
-               current_cell = current_module->addCell($3, $2);
-               current_cell->attributes = attrbuf;
-               attrbuf.clear();
-               free($2);
-               free($3);
-       } cell_body TOK_END EOL;
-
-cell_body:
-       cell_body TOK_PARAMETER TOK_ID constant EOL {
-               current_cell->parameters[$3] = *$4;
-               free($3);
-               delete $4;
-       } |
-       cell_body TOK_PARAMETER TOK_SIGNED TOK_ID constant EOL {
-               current_cell->parameters[$4] = *$5;
-               current_cell->parameters[$4].flags |= RTLIL::CONST_FLAG_SIGNED;
-               free($4);
-               delete $5;
-       } |
-       cell_body TOK_PARAMETER TOK_REAL TOK_ID constant EOL {
-               current_cell->parameters[$4] = *$5;
-               current_cell->parameters[$4].flags |= RTLIL::CONST_FLAG_REAL;
-               free($4);
-               delete $5;
-       } |
-       cell_body TOK_CONNECT TOK_ID sigspec EOL {
-               if (current_cell->hasPort($3))
-                       rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell port %s.", $3).c_str());
-               current_cell->setPort($3, *$4);
-               delete $4;
-               free($3);
-       } |
-       /* empty */;
-
-proc_stmt:
-       TOK_PROCESS TOK_ID EOL {
-               if (current_module->processes.count($2) != 0)
-                       rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of process %s.", $2).c_str());
-               current_process = new RTLIL::Process;
-               current_process->name = $2;
-               current_process->attributes = attrbuf;
-               current_module->processes[$2] = current_process;
-               switch_stack.clear();
-               switch_stack.push_back(&current_process->root_case.switches);
-               case_stack.clear();
-               case_stack.push_back(&current_process->root_case);
-               attrbuf.clear();
-               free($2);
-       } case_body sync_list TOK_END EOL;
-
-switch_stmt:
-       TOK_SWITCH sigspec EOL {
-               RTLIL::SwitchRule *rule = new RTLIL::SwitchRule;
-               rule->signal = *$2;
-               rule->attributes = attrbuf;
-               switch_stack.back()->push_back(rule);
-               attrbuf.clear();
-               delete $2;
-       } attr_list switch_body TOK_END EOL;
-
-attr_list:
-       /* empty */ |
-       attr_list attr_stmt;
-
-switch_body:
-       switch_body TOK_CASE {
-               RTLIL::CaseRule *rule = new RTLIL::CaseRule;
-               rule->attributes = attrbuf;
-               switch_stack.back()->back()->cases.push_back(rule);
-               switch_stack.push_back(&rule->switches);
-               case_stack.push_back(rule);
-               attrbuf.clear();
-       } compare_list EOL case_body {
-               switch_stack.pop_back();
-               case_stack.pop_back();
-       } |
-       /* empty */;
-
-compare_list:
-       sigspec {
-               case_stack.back()->compare.push_back(*$1);
-               delete $1;
-       } |
-       compare_list ',' sigspec {
-               case_stack.back()->compare.push_back(*$3);
-               delete $3;
-       } |
-       /* empty */;
-
-case_body:
-       case_body attr_stmt |
-       case_body switch_stmt |
-       case_body assign_stmt |
-       /* empty */;
-
-assign_stmt:
-       TOK_ASSIGN sigspec sigspec EOL {
-               if (attrbuf.size() != 0)
-                       rtlil_frontend_ilang_yyerror("dangling attribute");
-               case_stack.back()->actions.push_back(RTLIL::SigSig(*$2, *$3));
-               delete $2;
-               delete $3;
-       };
-
-sync_list:
-       sync_list TOK_SYNC sync_type sigspec EOL {
-               RTLIL::SyncRule *rule = new RTLIL::SyncRule;
-               rule->type = RTLIL::SyncType($3);
-               rule->signal = *$4;
-               current_process->syncs.push_back(rule);
-               delete $4;
-       } update_list |
-       sync_list TOK_SYNC TOK_ALWAYS EOL {
-               RTLIL::SyncRule *rule = new RTLIL::SyncRule;
-               rule->type = RTLIL::SyncType::STa;
-               rule->signal = RTLIL::SigSpec();
-               current_process->syncs.push_back(rule);
-       } update_list |
-       sync_list TOK_SYNC TOK_GLOBAL EOL {
-               RTLIL::SyncRule *rule = new RTLIL::SyncRule;
-               rule->type = RTLIL::SyncType::STg;
-               rule->signal = RTLIL::SigSpec();
-               current_process->syncs.push_back(rule);
-       } update_list |
-       sync_list TOK_SYNC TOK_INIT EOL {
-               RTLIL::SyncRule *rule = new RTLIL::SyncRule;
-               rule->type = RTLIL::SyncType::STi;
-               rule->signal = RTLIL::SigSpec();
-               current_process->syncs.push_back(rule);
-       } update_list |
-       /* empty */;
-
-sync_type:
-       TOK_LOW { $$ = RTLIL::ST0; } |
-       TOK_HIGH { $$ = RTLIL::ST1; } |
-       TOK_POSEDGE { $$ = RTLIL::STp; } |
-       TOK_NEGEDGE { $$ = RTLIL::STn; } |
-       TOK_EDGE { $$ = RTLIL::STe; };
-
-update_list:
-       update_list TOK_UPDATE sigspec sigspec EOL {
-               current_process->syncs.back()->actions.push_back(RTLIL::SigSig(*$3, *$4));
-               delete $3;
-               delete $4;
-       } |
-       /* empty */;
-
-constant:
-       TOK_VALUE {
-               char *ep;
-               int width = strtol($1, &ep, 10);
-               std::list<RTLIL::State> bits;
-               while (*(++ep) != 0) {
-                       RTLIL::State bit = RTLIL::Sx;
-                       switch (*ep) {
-                       case '0': bit = RTLIL::S0; break;
-                       case '1': bit = RTLIL::S1; break;
-                       case 'x': bit = RTLIL::Sx; break;
-                       case 'z': bit = RTLIL::Sz; break;
-                       case '-': bit = RTLIL::Sa; break;
-                       case 'm': bit = RTLIL::Sm; break;
-                       }
-                       bits.push_front(bit);
-               }
-               if (bits.size() == 0)
-                       bits.push_back(RTLIL::Sx);
-               while ((int)bits.size() < width) {
-                       RTLIL::State bit = bits.back();
-                       if (bit == RTLIL::S1)
-                               bit = RTLIL::S0;
-                       bits.push_back(bit);
-               }
-               while ((int)bits.size() > width)
-                       bits.pop_back();
-               $$ = new RTLIL::Const;
-               for (auto it = bits.begin(); it != bits.end(); it++)
-                       $$->bits.push_back(*it);
-               free($1);
-       } |
-       TOK_INT {
-               $$ = new RTLIL::Const($1, 32);
-       } |
-       TOK_STRING {
-               $$ = new RTLIL::Const($1);
-               free($1);
-       };
-
-sigspec:
-       constant {
-               $$ = new RTLIL::SigSpec(*$1);
-               delete $1;
-       } |
-       TOK_ID {
-               if (current_module->wire($1) == nullptr)
-                       rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str());
-               $$ = new RTLIL::SigSpec(current_module->wire($1));
-               free($1);
-       } |
-       sigspec '[' TOK_INT ']' {
-               if ($3 >= $1->size() || $3 < 0)
-                       rtlil_frontend_ilang_yyerror("bit index out of range");
-               $$ = new RTLIL::SigSpec($1->extract($3));
-               delete $1;
-       } |
-       sigspec '[' TOK_INT ':' TOK_INT ']' {
-               if ($3 >= $1->size() || $3 < 0 || $3 < $5)
-                       rtlil_frontend_ilang_yyerror("invalid slice");
-               $$ = new RTLIL::SigSpec($1->extract($5, $3 - $5 + 1));
-               delete $1;
-       } |
-       '{' sigspec_list '}' {
-               $$ = $2;
-       };
-
-sigspec_list_reversed:
-       sigspec_list_reversed sigspec {
-               $$->push_back(*$2);
-               delete $2;
-       } |
-       /* empty */ {
-               $$ = new std::vector<RTLIL::SigSpec>;
-       };
-
-sigspec_list: sigspec_list_reversed {
-               $$ = new RTLIL::SigSpec;
-               for (auto it = $1->rbegin(); it != $1->rend(); it++)
-                       $$->append(*it);
-               delete $1;
-       };
-
-conn_stmt:
-       TOK_CONNECT sigspec sigspec EOL {
-               if (attrbuf.size() != 0)
-                       rtlil_frontend_ilang_yyerror("dangling attribute");
-               current_module->connect(*$2, *$3);
-               delete $2;
-               delete $3;
-       };
index 6d72cbff551eb690ceed297fd3ee2a5e73e58867..5a40001cb467feca596f906e0f9159a5e44993a9 100644 (file)
@@ -378,7 +378,7 @@ struct RpcFrontend : public Pass {
                log("    -> {\"method\": \"derive\", \"module\": \"<module-name\">, \"parameters\": {\n");
                log("        \"<param-name>\": {\"type\": \"[unsigned|signed|string|real]\",\n");
                log("                           \"value\": \"<param-value>\"}, ...}}\n");
-               log("    <- {\"frontend\": \"[ilang|verilog|...]\",\"source\": \"<source>\"}}\n");
+               log("    <- {\"frontend\": \"[rtlil|verilog|...]\",\"source\": \"<source>\"}}\n");
                log("    <- {\"error\": \"<error-message>\"}\n");
                log("        request for the module <module-name> to be derived for a specific set of\n");
                log("        parameters. <param-name> starts with \\ for named parameters, and with $\n");
diff --git a/frontends/rtlil/.gitignore b/frontends/rtlil/.gitignore
new file mode 100644 (file)
index 0000000..d4a3227
--- /dev/null
@@ -0,0 +1,4 @@
+rtlil_lexer.cc
+rtlil_parser.output
+rtlil_parser.tab.cc
+rtlil_parser.tab.hh
diff --git a/frontends/rtlil/Makefile.inc b/frontends/rtlil/Makefile.inc
new file mode 100644 (file)
index 0000000..d0c0cfc
--- /dev/null
@@ -0,0 +1,19 @@
+
+GENFILES += frontends/rtlil/rtlil_parser.tab.cc
+GENFILES += frontends/rtlil/rtlil_parser.tab.hh
+GENFILES += frontends/rtlil/rtlil_parser.output
+GENFILES += frontends/rtlil/rtlil_lexer.cc
+
+frontends/rtlil/rtlil_parser.tab.cc: frontends/rtlil/rtlil_parser.y
+       $(Q) mkdir -p $(dir $@)
+       $(P) $(BISON) -o $@ -d -r all -b frontends/rtlil/rtlil_parser $<
+
+frontends/rtlil/rtlil_parser.tab.hh: frontends/rtlil/rtlil_parser.tab.cc
+
+frontends/rtlil/rtlil_lexer.cc: frontends/rtlil/rtlil_lexer.l
+       $(Q) mkdir -p $(dir $@)
+       $(P) flex -o frontends/rtlil/rtlil_lexer.cc $<
+
+OBJS += frontends/rtlil/rtlil_parser.tab.o frontends/rtlil/rtlil_lexer.o
+OBJS += frontends/rtlil/rtlil_frontend.o
+
diff --git a/frontends/rtlil/rtlil_frontend.cc b/frontends/rtlil/rtlil_frontend.cc
new file mode 100644 (file)
index 0000000..00c3417
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ *  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.
+ *
+ *  ---
+ *
+ *  A very simple and straightforward frontend for the RTLIL text
+ *  representation.
+ *
+ */
+
+#include "rtlil_frontend.h"
+#include "kernel/register.h"
+#include "kernel/log.h"
+
+void rtlil_frontend_yyerror(char const *s)
+{
+       YOSYS_NAMESPACE_PREFIX log_error("Parser error in line %d: %s\n", rtlil_frontend_yyget_lineno(), s);
+}
+
+YOSYS_NAMESPACE_BEGIN
+
+struct RTLILFrontend : public Frontend {
+       RTLILFrontend() : Frontend("rtlil", "read modules from RTLIL file") { }
+       void help() override
+       {
+               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+               log("\n");
+               log("    read_rtlil [filename]\n");
+               log("\n");
+               log("Load modules from an RTLIL file to the current design. (RTLIL is a text\n");
+               log("representation of a design in yosys's internal format.)\n");
+               log("\n");
+               log("    -nooverwrite\n");
+               log("        ignore re-definitions of modules. (the default behavior is to\n");
+               log("        create an error message if the existing module is not a blackbox\n");
+               log("        module, and overwrite the existing module if it is a blackbox module.)\n");
+               log("\n");
+               log("    -overwrite\n");
+               log("        overwrite existing modules with the same name\n");
+               log("\n");
+               log("    -lib\n");
+               log("        only create empty blackbox modules\n");
+               log("\n");
+       }
+       void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override
+       {
+               RTLIL_FRONTEND::flag_nooverwrite = false;
+               RTLIL_FRONTEND::flag_overwrite = false;
+               RTLIL_FRONTEND::flag_lib = false;
+
+               log_header(design, "Executing RTLIL frontend.\n");
+
+               size_t argidx;
+               for (argidx = 1; argidx < args.size(); argidx++) {
+                       std::string arg = args[argidx];
+                       if (arg == "-nooverwrite") {
+                               RTLIL_FRONTEND::flag_nooverwrite = true;
+                               RTLIL_FRONTEND::flag_overwrite = false;
+                               continue;
+                       }
+                       if (arg == "-overwrite") {
+                               RTLIL_FRONTEND::flag_nooverwrite = false;
+                               RTLIL_FRONTEND::flag_overwrite = true;
+                               continue;
+                       }
+                       if (arg == "-lib") {
+                               RTLIL_FRONTEND::flag_lib = true;
+                               continue;
+                       }
+                       break;
+               }
+               extra_args(f, filename, args, argidx);
+
+               log("Input filename: %s\n", filename.c_str());
+
+               RTLIL_FRONTEND::lexin = f;
+               RTLIL_FRONTEND::current_design = design;
+               rtlil_frontend_yydebug = false;
+               rtlil_frontend_yyrestart(NULL);
+               rtlil_frontend_yyparse();
+               rtlil_frontend_yylex_destroy();
+       }
+} RTLILFrontend;
+
+struct IlangFrontend : public Frontend {
+       IlangFrontend() : Frontend("ilang", "(deprecated) alias of read_rtlil") { }
+       void help() override
+       {
+               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+               log("\n");
+               log("See `help read_rtlil`.\n");
+               log("\n");
+       }
+       void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override
+       {
+               RTLILFrontend.execute(f, filename, args, design);
+       }
+} IlangFrontend;
+
+YOSYS_NAMESPACE_END
+
diff --git a/frontends/rtlil/rtlil_frontend.h b/frontends/rtlil/rtlil_frontend.h
new file mode 100644 (file)
index 0000000..a420778
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  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.
+ *
+ *  ---
+ *
+ *  A very simple and straightforward frontend for the RTLIL text
+ *  representation.
+ *
+ */
+
+#ifndef RTLIL_FRONTEND_H
+#define RTLIL_FRONTEND_H
+
+#include "kernel/yosys.h"
+
+YOSYS_NAMESPACE_BEGIN
+
+namespace RTLIL_FRONTEND {
+       extern std::istream *lexin;
+       extern RTLIL::Design *current_design;
+       extern bool flag_nooverwrite;
+       extern bool flag_overwrite;
+       extern bool flag_lib;
+}
+
+YOSYS_NAMESPACE_END
+
+extern int rtlil_frontend_yydebug;
+int rtlil_frontend_yylex(void);
+void rtlil_frontend_yyerror(char const *s);
+void rtlil_frontend_yyrestart(FILE *f);
+int rtlil_frontend_yyparse(void);
+int rtlil_frontend_yylex_destroy(void);
+int rtlil_frontend_yyget_lineno(void);
+
+#endif
+
diff --git a/frontends/rtlil/rtlil_lexer.l b/frontends/rtlil/rtlil_lexer.l
new file mode 100644 (file)
index 0000000..295455f
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ *  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.
+ *
+ *  ---
+ *
+ *  A very simple and straightforward frontend for the RTLIL text
+ *  representation.
+ *
+ */
+
+%{
+
+#ifdef __clang__
+// bison generates code using the 'register' storage class specifier
+#pragma clang diagnostic ignored "-Wdeprecated-register"
+#endif
+
+#include <cstdlib>
+#include "frontends/rtlil/rtlil_frontend.h"
+#include "rtlil_parser.tab.hh"
+
+USING_YOSYS_NAMESPACE
+
+#define YY_INPUT(buf,result,max_size) \
+       result = readsome(*RTLIL_FRONTEND::lexin, buf, max_size)
+
+%}
+
+%option yylineno
+%option noyywrap
+%option nounput
+%option prefix="rtlil_frontend_yy"
+
+%x STRING
+
+%%
+
+"autoidx"      { return TOK_AUTOIDX; }
+"module"       { return TOK_MODULE; }
+"attribute"    { return TOK_ATTRIBUTE; }
+"parameter"    { return TOK_PARAMETER; }
+"signed"       { return TOK_SIGNED; }
+"real"         { return TOK_REAL; }
+"wire"         { return TOK_WIRE; }
+"memory"       { return TOK_MEMORY; }
+"width"                { return TOK_WIDTH; }
+"upto"         { return TOK_UPTO; }
+"offset"       { return TOK_OFFSET; }
+"size"         { return TOK_SIZE; }
+"input"                { return TOK_INPUT; }
+"output"       { return TOK_OUTPUT; }
+"inout"                { return TOK_INOUT; }
+"cell"         { return TOK_CELL; }
+"connect"      { return TOK_CONNECT; }
+"switch"       { return TOK_SWITCH; }
+"case"         { return TOK_CASE; }
+"assign"       { return TOK_ASSIGN; }
+"sync"         { return TOK_SYNC; }
+"low"          { return TOK_LOW; }
+"high"         { return TOK_HIGH; }
+"posedge"      { return TOK_POSEDGE; }
+"negedge"      { return TOK_NEGEDGE; }
+"edge"         { return TOK_EDGE; }
+"always"       { return TOK_ALWAYS; }
+"global"       { return TOK_GLOBAL; }
+"init"         { return TOK_INIT; }
+"update"       { return TOK_UPDATE; }
+"process"      { return TOK_PROCESS; }
+"end"          { return TOK_END; }
+
+[a-z]+         { return TOK_INVALID; }
+
+"\\"[^ \t\r\n]+                { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; }
+"$"[^ \t\r\n]+         { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; }
+"."[0-9]+              { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; }
+
+[0-9]+'[01xzm-]*       { rtlil_frontend_yylval.string = strdup(yytext); return TOK_VALUE; }
+-?[0-9]+               {
+       char *end = nullptr;
+       errno = 0;
+       long value = strtol(yytext, &end, 10);
+       log_assert(end == yytext + strlen(yytext));
+       if (errno == ERANGE)
+               return TOK_INVALID; // literal out of range of long
+       if (value < INT_MIN || value > INT_MAX)
+               return TOK_INVALID; // literal out of range of int (relevant mostly for LP64 platforms)
+       rtlil_frontend_yylval.integer = value;
+       return TOK_INT;
+}
+
+\"             { BEGIN(STRING); }
+<STRING>\\.    { yymore(); }
+<STRING>\"     {
+       BEGIN(0);
+       char *yystr = strdup(yytext);
+       yystr[strlen(yytext) - 1] = 0;
+       int i = 0, j = 0;
+       while (yystr[i]) {
+               if (yystr[i] == '\\' && yystr[i + 1]) {
+                       i++;
+                       if (yystr[i] == 'n')
+                               yystr[i] = '\n';
+                       else if (yystr[i] == 't')
+                               yystr[i] = '\t';
+                       else if ('0' <= yystr[i] && yystr[i] <= '7') {
+                               yystr[i] = yystr[i] - '0';
+                               if ('0' <= yystr[i + 1] && yystr[i + 1] <= '7') {
+                                       yystr[i + 1] = yystr[i] * 8 + yystr[i + 1] - '0';
+                                       i++;
+                               }
+                               if ('0' <= yystr[i + 1] && yystr[i + 1] <= '7') {
+                                       yystr[i + 1] = yystr[i] * 8 + yystr[i + 1] - '0';
+                                       i++;
+                               }
+                       }
+               }
+               yystr[j++] = yystr[i++];
+       }
+       yystr[j] = 0;
+       rtlil_frontend_yylval.string = yystr;
+       return TOK_STRING;
+}
+<STRING>.      { yymore(); }
+
+"#"[^\n]*      /* ignore comments */
+[ \t]          /* ignore non-newline whitespaces */
+[\r\n]+                { return TOK_EOL; }
+
+.               { return *yytext; }
+
+%%
+
+// this is a hack to avoid the 'yyinput defined but not used' error msgs
+void *rtlil_frontend_avoid_input_warnings() {
+       return (void*)&yyinput;
+}
diff --git a/frontends/rtlil/rtlil_parser.y b/frontends/rtlil/rtlil_parser.y
new file mode 100644 (file)
index 0000000..6464891
--- /dev/null
@@ -0,0 +1,484 @@
+/*
+ *  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.
+ *
+ *  ---
+ *
+ *  A very simple and straightforward frontend for the RTLIL text
+ *  representation.
+ *
+ */
+
+%{
+#include <list>
+#include "frontends/rtlil/rtlil_frontend.h"
+YOSYS_NAMESPACE_BEGIN
+namespace RTLIL_FRONTEND {
+       std::istream *lexin;
+       RTLIL::Design *current_design;
+       RTLIL::Module *current_module;
+       RTLIL::Wire *current_wire;
+       RTLIL::Memory *current_memory;
+       RTLIL::Cell *current_cell;
+       RTLIL::Process *current_process;
+       std::vector<std::vector<RTLIL::SwitchRule*>*> switch_stack;
+       std::vector<RTLIL::CaseRule*> case_stack;
+       dict<RTLIL::IdString, RTLIL::Const> attrbuf;
+       bool flag_nooverwrite, flag_overwrite, flag_lib;
+       bool delete_current_module;
+}
+using namespace RTLIL_FRONTEND;
+YOSYS_NAMESPACE_END
+USING_YOSYS_NAMESPACE
+%}
+
+%define api.prefix {rtlil_frontend_yy}
+
+/* The union is defined in the header, so we need to provide all the
+ * includes it requires
+ */
+%code requires {
+#include <string>
+#include <vector>
+#include "frontends/rtlil/rtlil_frontend.h"
+}
+
+%union {
+       char *string;
+       int integer;
+       YOSYS_NAMESPACE_PREFIX RTLIL::Const *data;
+       YOSYS_NAMESPACE_PREFIX RTLIL::SigSpec *sigspec;
+       std::vector<YOSYS_NAMESPACE_PREFIX RTLIL::SigSpec> *rsigspec;
+}
+
+%token <string> TOK_ID TOK_VALUE TOK_STRING
+%token <integer> TOK_INT
+%token TOK_AUTOIDX TOK_MODULE TOK_WIRE TOK_WIDTH TOK_INPUT TOK_OUTPUT TOK_INOUT
+%token TOK_CELL TOK_CONNECT TOK_SWITCH TOK_CASE TOK_ASSIGN TOK_SYNC
+%token TOK_LOW TOK_HIGH TOK_POSEDGE TOK_NEGEDGE TOK_EDGE TOK_ALWAYS TOK_GLOBAL TOK_INIT
+%token TOK_UPDATE TOK_PROCESS TOK_END TOK_INVALID TOK_EOL TOK_OFFSET
+%token TOK_PARAMETER TOK_ATTRIBUTE TOK_MEMORY TOK_SIZE TOK_SIGNED TOK_REAL TOK_UPTO
+
+%type <rsigspec> sigspec_list_reversed
+%type <sigspec> sigspec sigspec_list
+%type <integer> sync_type
+%type <data> constant
+
+%expect 0
+%debug
+
+%%
+
+input:
+       optional_eol {
+               attrbuf.clear();
+       } design {
+               if (attrbuf.size() != 0)
+                       rtlil_frontend_yyerror("dangling attribute");
+       };
+
+EOL:
+       optional_eol TOK_EOL;
+
+optional_eol:
+       optional_eol TOK_EOL | /* empty */;
+
+design:
+       design module |
+       design attr_stmt |
+       design autoidx_stmt |
+       /* empty */;
+
+module:
+       TOK_MODULE TOK_ID EOL {
+               delete_current_module = false;
+               if (current_design->has($2)) {
+                       RTLIL::Module *existing_mod = current_design->module($2);
+                       if (!flag_overwrite && (flag_lib || (attrbuf.count(ID::blackbox) && attrbuf.at(ID::blackbox).as_bool()))) {
+                               log("Ignoring blackbox re-definition of module %s.\n", $2);
+                               delete_current_module = true;
+                       } else if (!flag_nooverwrite && !flag_overwrite && !existing_mod->get_bool_attribute(ID::blackbox)) {
+                               rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of module %s.", $2).c_str());
+                       } else if (flag_nooverwrite) {
+                               log("Ignoring re-definition of module %s.\n", $2);
+                               delete_current_module = true;
+                       } else {
+                               log("Replacing existing%s module %s.\n", existing_mod->get_bool_attribute(ID::blackbox) ? " blackbox" : "", $2);
+                               current_design->remove(existing_mod);
+                       }
+               }
+               current_module = new RTLIL::Module;
+               current_module->name = $2;
+               current_module->attributes = attrbuf;
+               if (!delete_current_module)
+                       current_design->add(current_module);
+               attrbuf.clear();
+               free($2);
+       } module_body TOK_END {
+               if (attrbuf.size() != 0)
+                       rtlil_frontend_yyerror("dangling attribute");
+               current_module->fixup_ports();
+               if (delete_current_module)
+                       delete current_module;
+               else if (flag_lib)
+                       current_module->makeblackbox();
+               current_module = nullptr;
+       } EOL;
+
+module_body:
+       module_body module_stmt |
+       /* empty */;
+
+module_stmt:
+       param_stmt | param_defval_stmt | attr_stmt | wire_stmt | memory_stmt | cell_stmt | proc_stmt | conn_stmt;
+
+param_stmt:
+       TOK_PARAMETER TOK_ID EOL {
+               current_module->avail_parameters($2);
+               free($2);
+       };
+
+param_defval_stmt:
+       TOK_PARAMETER TOK_ID constant EOL {
+               current_module->avail_parameters($2);
+               current_module->parameter_default_values[$2] = *$3;
+               free($2);
+       };
+
+attr_stmt:
+       TOK_ATTRIBUTE TOK_ID constant EOL {
+               attrbuf[$2] = *$3;
+               delete $3;
+               free($2);
+       };
+
+autoidx_stmt:
+       TOK_AUTOIDX TOK_INT EOL {
+               autoidx = max(autoidx, $2);
+       };
+
+wire_stmt:
+       TOK_WIRE {
+               current_wire = current_module->addWire("$__rtlil_frontend_tmp__");
+               current_wire->attributes = attrbuf;
+               attrbuf.clear();
+       } wire_options TOK_ID EOL {
+               if (current_module->wire($4) != nullptr)
+                       rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of wire %s.", $4).c_str());
+               current_module->rename(current_wire, $4);
+               free($4);
+       };
+
+wire_options:
+       wire_options TOK_WIDTH TOK_INT {
+               current_wire->width = $3;
+       } |
+       wire_options TOK_WIDTH TOK_INVALID {
+               rtlil_frontend_yyerror("RTLIL error: invalid wire width");
+       } |
+       wire_options TOK_UPTO {
+               current_wire->upto = true;
+       } |
+       wire_options TOK_SIGNED {
+               current_wire->is_signed = true;
+       } |
+       wire_options TOK_OFFSET TOK_INT {
+               current_wire->start_offset = $3;
+       } |
+       wire_options TOK_INPUT TOK_INT {
+               current_wire->port_id = $3;
+               current_wire->port_input = true;
+               current_wire->port_output = false;
+       } |
+       wire_options TOK_OUTPUT TOK_INT {
+               current_wire->port_id = $3;
+               current_wire->port_input = false;
+               current_wire->port_output = true;
+       } |
+       wire_options TOK_INOUT TOK_INT {
+               current_wire->port_id = $3;
+               current_wire->port_input = true;
+               current_wire->port_output = true;
+       } |
+       /* empty */;
+
+memory_stmt:
+       TOK_MEMORY {
+               current_memory = new RTLIL::Memory;
+               current_memory->attributes = attrbuf;
+               attrbuf.clear();
+       } memory_options TOK_ID EOL {
+               if (current_module->memories.count($4) != 0)
+                       rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of memory %s.", $4).c_str());
+               current_memory->name = $4;
+               current_module->memories[$4] = current_memory;
+               free($4);
+       };
+
+memory_options:
+       memory_options TOK_WIDTH TOK_INT {
+               current_memory->width = $3;
+       } |
+       memory_options TOK_SIZE TOK_INT {
+               current_memory->size = $3;
+       } |
+       memory_options TOK_OFFSET TOK_INT {
+               current_memory->start_offset = $3;
+       } |
+       /* empty */;
+
+cell_stmt:
+       TOK_CELL TOK_ID TOK_ID EOL {
+               if (current_module->cell($3) != nullptr)
+                       rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of cell %s.", $3).c_str());
+               current_cell = current_module->addCell($3, $2);
+               current_cell->attributes = attrbuf;
+               attrbuf.clear();
+               free($2);
+               free($3);
+       } cell_body TOK_END EOL;
+
+cell_body:
+       cell_body TOK_PARAMETER TOK_ID constant EOL {
+               current_cell->parameters[$3] = *$4;
+               free($3);
+               delete $4;
+       } |
+       cell_body TOK_PARAMETER TOK_SIGNED TOK_ID constant EOL {
+               current_cell->parameters[$4] = *$5;
+               current_cell->parameters[$4].flags |= RTLIL::CONST_FLAG_SIGNED;
+               free($4);
+               delete $5;
+       } |
+       cell_body TOK_PARAMETER TOK_REAL TOK_ID constant EOL {
+               current_cell->parameters[$4] = *$5;
+               current_cell->parameters[$4].flags |= RTLIL::CONST_FLAG_REAL;
+               free($4);
+               delete $5;
+       } |
+       cell_body TOK_CONNECT TOK_ID sigspec EOL {
+               if (current_cell->hasPort($3))
+                       rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of cell port %s.", $3).c_str());
+               current_cell->setPort($3, *$4);
+               delete $4;
+               free($3);
+       } |
+       /* empty */;
+
+proc_stmt:
+       TOK_PROCESS TOK_ID EOL {
+               if (current_module->processes.count($2) != 0)
+                       rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of process %s.", $2).c_str());
+               current_process = new RTLIL::Process;
+               current_process->name = $2;
+               current_process->attributes = attrbuf;
+               current_module->processes[$2] = current_process;
+               switch_stack.clear();
+               switch_stack.push_back(&current_process->root_case.switches);
+               case_stack.clear();
+               case_stack.push_back(&current_process->root_case);
+               attrbuf.clear();
+               free($2);
+       } case_body sync_list TOK_END EOL;
+
+switch_stmt:
+       TOK_SWITCH sigspec EOL {
+               RTLIL::SwitchRule *rule = new RTLIL::SwitchRule;
+               rule->signal = *$2;
+               rule->attributes = attrbuf;
+               switch_stack.back()->push_back(rule);
+               attrbuf.clear();
+               delete $2;
+       } attr_list switch_body TOK_END EOL;
+
+attr_list:
+       /* empty */ |
+       attr_list attr_stmt;
+
+switch_body:
+       switch_body TOK_CASE {
+               RTLIL::CaseRule *rule = new RTLIL::CaseRule;
+               rule->attributes = attrbuf;
+               switch_stack.back()->back()->cases.push_back(rule);
+               switch_stack.push_back(&rule->switches);
+               case_stack.push_back(rule);
+               attrbuf.clear();
+       } compare_list EOL case_body {
+               switch_stack.pop_back();
+               case_stack.pop_back();
+       } |
+       /* empty */;
+
+compare_list:
+       sigspec {
+               case_stack.back()->compare.push_back(*$1);
+               delete $1;
+       } |
+       compare_list ',' sigspec {
+               case_stack.back()->compare.push_back(*$3);
+               delete $3;
+       } |
+       /* empty */;
+
+case_body:
+       case_body attr_stmt |
+       case_body switch_stmt |
+       case_body assign_stmt |
+       /* empty */;
+
+assign_stmt:
+       TOK_ASSIGN sigspec sigspec EOL {
+               if (attrbuf.size() != 0)
+                       rtlil_frontend_yyerror("dangling attribute");
+               case_stack.back()->actions.push_back(RTLIL::SigSig(*$2, *$3));
+               delete $2;
+               delete $3;
+       };
+
+sync_list:
+       sync_list TOK_SYNC sync_type sigspec EOL {
+               RTLIL::SyncRule *rule = new RTLIL::SyncRule;
+               rule->type = RTLIL::SyncType($3);
+               rule->signal = *$4;
+               current_process->syncs.push_back(rule);
+               delete $4;
+       } update_list |
+       sync_list TOK_SYNC TOK_ALWAYS EOL {
+               RTLIL::SyncRule *rule = new RTLIL::SyncRule;
+               rule->type = RTLIL::SyncType::STa;
+               rule->signal = RTLIL::SigSpec();
+               current_process->syncs.push_back(rule);
+       } update_list |
+       sync_list TOK_SYNC TOK_GLOBAL EOL {
+               RTLIL::SyncRule *rule = new RTLIL::SyncRule;
+               rule->type = RTLIL::SyncType::STg;
+               rule->signal = RTLIL::SigSpec();
+               current_process->syncs.push_back(rule);
+       } update_list |
+       sync_list TOK_SYNC TOK_INIT EOL {
+               RTLIL::SyncRule *rule = new RTLIL::SyncRule;
+               rule->type = RTLIL::SyncType::STi;
+               rule->signal = RTLIL::SigSpec();
+               current_process->syncs.push_back(rule);
+       } update_list |
+       /* empty */;
+
+sync_type:
+       TOK_LOW { $$ = RTLIL::ST0; } |
+       TOK_HIGH { $$ = RTLIL::ST1; } |
+       TOK_POSEDGE { $$ = RTLIL::STp; } |
+       TOK_NEGEDGE { $$ = RTLIL::STn; } |
+       TOK_EDGE { $$ = RTLIL::STe; };
+
+update_list:
+       update_list TOK_UPDATE sigspec sigspec EOL {
+               current_process->syncs.back()->actions.push_back(RTLIL::SigSig(*$3, *$4));
+               delete $3;
+               delete $4;
+       } |
+       /* empty */;
+
+constant:
+       TOK_VALUE {
+               char *ep;
+               int width = strtol($1, &ep, 10);
+               std::list<RTLIL::State> bits;
+               while (*(++ep) != 0) {
+                       RTLIL::State bit = RTLIL::Sx;
+                       switch (*ep) {
+                       case '0': bit = RTLIL::S0; break;
+                       case '1': bit = RTLIL::S1; break;
+                       case 'x': bit = RTLIL::Sx; break;
+                       case 'z': bit = RTLIL::Sz; break;
+                       case '-': bit = RTLIL::Sa; break;
+                       case 'm': bit = RTLIL::Sm; break;
+                       }
+                       bits.push_front(bit);
+               }
+               if (bits.size() == 0)
+                       bits.push_back(RTLIL::Sx);
+               while ((int)bits.size() < width) {
+                       RTLIL::State bit = bits.back();
+                       if (bit == RTLIL::S1)
+                               bit = RTLIL::S0;
+                       bits.push_back(bit);
+               }
+               while ((int)bits.size() > width)
+                       bits.pop_back();
+               $$ = new RTLIL::Const;
+               for (auto it = bits.begin(); it != bits.end(); it++)
+                       $$->bits.push_back(*it);
+               free($1);
+       } |
+       TOK_INT {
+               $$ = new RTLIL::Const($1, 32);
+       } |
+       TOK_STRING {
+               $$ = new RTLIL::Const($1);
+               free($1);
+       };
+
+sigspec:
+       constant {
+               $$ = new RTLIL::SigSpec(*$1);
+               delete $1;
+       } |
+       TOK_ID {
+               if (current_module->wire($1) == nullptr)
+                       rtlil_frontend_yyerror(stringf("RTLIL error: wire %s not found", $1).c_str());
+               $$ = new RTLIL::SigSpec(current_module->wire($1));
+               free($1);
+       } |
+       sigspec '[' TOK_INT ']' {
+               if ($3 >= $1->size() || $3 < 0)
+                       rtlil_frontend_yyerror("bit index out of range");
+               $$ = new RTLIL::SigSpec($1->extract($3));
+               delete $1;
+       } |
+       sigspec '[' TOK_INT ':' TOK_INT ']' {
+               if ($3 >= $1->size() || $3 < 0 || $3 < $5)
+                       rtlil_frontend_yyerror("invalid slice");
+               $$ = new RTLIL::SigSpec($1->extract($5, $3 - $5 + 1));
+               delete $1;
+       } |
+       '{' sigspec_list '}' {
+               $$ = $2;
+       };
+
+sigspec_list_reversed:
+       sigspec_list_reversed sigspec {
+               $$->push_back(*$2);
+               delete $2;
+       } |
+       /* empty */ {
+               $$ = new std::vector<RTLIL::SigSpec>;
+       };
+
+sigspec_list: sigspec_list_reversed {
+               $$ = new RTLIL::SigSpec;
+               for (auto it = $1->rbegin(); it != $1->rend(); it++)
+                       $$->append(*it);
+               delete $1;
+       };
+
+conn_stmt:
+       TOK_CONNECT sigspec sigspec EOL {
+               if (attrbuf.size() != 0)
+                       rtlil_frontend_yyerror("dangling attribute");
+               current_module->connect(*$2, *$3);
+               delete $2;
+               delete $3;
+       };
index 1c1d0182e930b4401e63a1e7825ebe204ce186e3..c7ae873bc82e09ef7e16144f05bf74de781d8837 100644 (file)
@@ -19,7 +19,7 @@
 
 #include "kernel/yosys.h"
 #include "libs/sha1/sha1.h"
-#include "backends/ilang/ilang_backend.h"
+#include "backends/rtlil/rtlil_backend.h"
 
 #if !defined(_WIN32) || defined(__MINGW32__)
 #  include <sys/time.h>
@@ -600,7 +600,7 @@ void log_dump_val_worker(RTLIL::State v) {
 const char *log_signal(const RTLIL::SigSpec &sig, bool autoint)
 {
        std::stringstream buf;
-       ILANG_BACKEND::dump_sigspec(buf, sig, autoint);
+       RTLIL_BACKEND::dump_sigspec(buf, sig, autoint);
 
        if (string_buf.size() < 100) {
                string_buf.push_back(buf.str());
@@ -647,21 +647,21 @@ const char *log_id(RTLIL::IdString str)
 void log_module(RTLIL::Module *module, std::string indent)
 {
        std::stringstream buf;
-       ILANG_BACKEND::dump_module(buf, indent, module, module->design, false);
+       RTLIL_BACKEND::dump_module(buf, indent, module, module->design, false);
        log("%s", buf.str().c_str());
 }
 
 void log_cell(RTLIL::Cell *cell, std::string indent)
 {
        std::stringstream buf;
-       ILANG_BACKEND::dump_cell(buf, indent, cell);
+       RTLIL_BACKEND::dump_cell(buf, indent, cell);
        log("%s", buf.str().c_str());
 }
 
 void log_wire(RTLIL::Wire *wire, std::string indent)
 {
        std::stringstream buf;
-       ILANG_BACKEND::dump_wire(buf, indent, wire);
+       RTLIL_BACKEND::dump_wire(buf, indent, wire);
        log("%s", buf.str().c_str());
 }
 
index c56f0dcabe0338b91cc308e1958756ef2053afe9..a9f5856160f636d2dccb9ea40a2cf44950e8038d 100644 (file)
@@ -22,7 +22,7 @@
 #include "kernel/celltypes.h"
 #include "frontends/verilog/verilog_frontend.h"
 #include "frontends/verilog/preproc.h"
-#include "backends/ilang/ilang_backend.h"
+#include "backends/rtlil/rtlil_backend.h"
 
 #include <string.h>
 #include <algorithm>
@@ -923,7 +923,7 @@ namespace {
                void error(int linenr)
                {
                        std::stringstream buf;
-                       ILANG_BACKEND::dump_cell(buf, "  ", cell);
+                       RTLIL_BACKEND::dump_cell(buf, "  ", cell);
 
                        log_error("Found error in internal cell %s%s%s (%s) at %s:%d:\n%s",
                                        module ? module->name.c_str() : "", module ? "." : "",
index 8986c8091ca4c37cdc1c0f21295fbf3f50f2548f..7a2ef49134b43f512e2282bacfcfb61d1e9079d2 100644 (file)
@@ -930,7 +930,7 @@ void run_frontend(std::string filename, std::string command, std::string *backen
                else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-5, std::string::npos, ".json") == 0)
                        command = "json";
                else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".il") == 0)
-                       command = "ilang";
+                       command = "rtlil";
                else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".ys") == 0)
                        command = "script";
                else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".tcl") == 0)
@@ -1053,7 +1053,7 @@ void run_backend(std::string filename, std::string command, RTLIL::Design *desig
                else if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".sv") == 0)
                        command = "verilog -sv";
                else if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0)
-                       command = "ilang";
+                       command = "rtlil";
                else if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".cc") == 0)
                        command = "cxxrtl";
                else if (filename.size() > 4 && filename.compare(filename.size()-4, std::string::npos, ".aig") == 0)
@@ -1065,7 +1065,7 @@ void run_backend(std::string filename, std::string command, RTLIL::Design *desig
                else if (filename.size() > 5 && filename.compare(filename.size()-5, std::string::npos, ".json") == 0)
                        command = "json";
                else if (filename == "-")
-                       command = "ilang";
+                       command = "rtlil";
                else if (filename.empty())
                        return;
                else
index 83cfa5cc46092a380a66567d40475e6d25a6b0af..61d628a9cf6126c76b14c05c73ab608ba821db27 100644 (file)
@@ -39,15 +39,15 @@ the RTL Intermediate Language (RTLIL). A more detailed description of this forma
 is given in the next section.
 
 There is also a text representation of the RTLIL data structure that can be
-parsed using the ILANG Frontend.
+parsed using the RTLIL Frontend.
 
 The design data may then be transformed using a series of passes that all
 operate on the RTLIL representation of the design.
 
 Finally the design in RTLIL representation is converted back to text by one
 of the backends, namely the Verilog Backend for generating Verilog netlists
-and the ILANG Backend for writing the RTLIL data in the same format that is
-understood by the ILANG Frontend.
+and the RTLIL Backend for writing the RTLIL data in the same format that is
+understood by the RTLIL Frontend.
 
 With the exception of the AST Frontend, which is called by the high-level HDL
 frontends and can't be called directly by the user, all program modules are
@@ -67,13 +67,13 @@ in different stages of the synthesis.
                \tikzstyle{data} = [draw, fill=blue!10, ellipse, minimum height=3em, minimum width=7em, node distance=15em]
                \node[process] (vlog) {Verilog Frontend};
                \node[process, dashed, fill=green!5] (vhdl) [right of=vlog] {VHDL Frontend};
-               \node[process] (ilang) [right of=vhdl] {ILANG Frontend};
+               \node[process] (ilang) [right of=vhdl] {RTLIL Frontend};
                \node[data] (ast) [below of=vlog, node distance=5em, xshift=7.5em] {AST};
                \node[process] (astfe) [below of=ast, node distance=5em] {AST Frontend};
                \node[data] (rtlil) [below of=astfe, node distance=5em, xshift=7.5em] {RTLIL};
                \node[process] (pass) [right of=rtlil, node distance=5em, xshift=7.5em] {Passes};
                \node[process] (vlbe) [below of=rtlil, node distance=7em, xshift=-13em] {Verilog Backend};
-               \node[process] (ilangbe) [below of=rtlil, node distance=7em, xshift=0em] {ILANG Backend};
+               \node[process] (ilangbe) [below of=rtlil, node distance=7em, xshift=0em] {RTLIL Backend};
                \node[process, dashed, fill=green!5] (otherbe) [below of=rtlil, node distance=7em, xshift=+13em] {Other Backends};
 
                \draw[-latex] (vlog) -- (ast);
@@ -92,8 +92,7 @@ in different stages of the synthesis.
 
 \section{The RTL Intermediate Language}
 
-All frontends, passes and backends in Yosys operate on a design in RTLIL\footnote{The {\it Language} in {\it RTL Intermediate Language}
-refers to the fact, that RTLIL also has a text representation, usually referred to as {\it Intermediate Language} (ILANG).} representation.
+All frontends, passes and backends in Yosys operate on a design in RTLIL} representation.
 The only exception are the high-level frontends that use the AST representation as an intermediate step before generating RTLIL
 data.
 
@@ -316,7 +315,7 @@ endmodule
 
 In this example there is no data path and therefore the RTLIL::Module generated by
 the frontend only contains a few RTLIL::Wire objects and an RTLIL::Process.
-The RTLIL::Process in ILANG syntax:
+The RTLIL::Process in RTLIL syntax:
 
 \begin{lstlisting}[numbers=left,frame=single,language=rtlil]
 process $proc$ff_with_en_and_async_reset.v:4$1
@@ -362,7 +361,7 @@ also contains an RTLIL::SwitchRule object (lines $3 \dots 12$). Such an object i
 statement as it uses a control signal ({\tt \textbackslash{}reset} in this case) to determine
 which of its cases should be active. The RTLIL::SwitchRule object then contains one RTLIL::CaseRule
 object per case. In this example there is a case\footnote{The
-syntax {\tt 1'1} in the ILANG code specifies a constant with a length of one bit (the first ``1''),
+syntax {\tt 1'1} in the RTLIL code specifies a constant with a length of one bit (the first ``1''),
 and this bit is a one (the second ``1'').} for {\tt \textbackslash{}reset == 1} that causes
 {\tt \$0\textbackslash{}q[0:0]} to be set (lines 4 and 5) and a default case that in turn contains a switch that
 sets {\tt \$0\textbackslash{}q[0:0]} to the value of {\tt \textbackslash{}d} if {\tt
index 555ec9175d9b1fb9392587912a33cc8c639b2e62..af561d01b67fb20537aaa7c23ae39c3847893584 100644 (file)
@@ -231,7 +231,7 @@ as Qflow\footnote[frame]{\url{http://opencircuitdesign.com/qflow/}} for ASIC des
                \node[data] (rtlil) [below of=astfe, node distance=5em, xshift=7.5em] {RTLIL};
                \node[process] (pass) [right of=rtlil, node distance=5em, xshift=7.5em] {Passes};
                \node[process] (vlbe) [below of=rtlil, node distance=7em, xshift=-13em] {Verilog Backend};
-               \node[process] (ilangbe) [below of=rtlil, node distance=7em, xshift=0em] {ILANG Backend};
+               \node[process] (ilangbe) [below of=rtlil, node distance=7em, xshift=0em] {RTLIL Backend};
                \node[process, fill=green!5] (otherbe) [below of=rtlil, node distance=7em, xshift=+13em] {Other Backends};
 
                \draw[-latex] (vlog) -- (ast);
@@ -484,7 +484,7 @@ Commands for design navigation and investigation:
 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys]
     cd                   # a shortcut for 'select -module <name>'
     ls                   # list modules or objects in modules
-    dump                 # print parts of the design in ilang format
+    dump                 # print parts of the design in RTLIL format
     show                 # generate schematics using graphviz
     select               # modify and view the list of selected objects
 \end{lstlisting}
@@ -502,7 +502,7 @@ Commands for executing scripts or entering interactive mode:
 \begin{frame}[fragile]{\subsecname{} 2/3 \hspace{0pt plus 1 filll} (excerpt)}
 Commands for reading and elaborating the design:
 \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys]
-    read_ilang           # read modules from ilang file
+    read_rtlil           # read modules from RTLIL file
     read_verilog         # read modules from Verilog file
     hierarchy            # check, expand and clean up design hierarchy
 \end{lstlisting}
@@ -534,7 +534,7 @@ Commands for writing the results:
     write_blif           # write design to BLIF file
     write_btor           # write design to BTOR file
     write_edif           # write design to EDIF netlist file
-    write_ilang          # write design to ilang file
+    write_rtlil          # write design to RTLIL file
     write_spice          # write design to SPICE netlist file
     write_verilog        # write design to Verilog file
 \end{lstlisting}
index a9416f82a4aca72908c936e28e6c329756656b62..3b61361aff4f258d94f956ba1c79c9c7171e7005 100644 (file)
@@ -22,7 +22,7 @@
        \node[data] (rtlil) [below of=astfe, node distance=5em, xshift=7.5em] {RTLIL};
        \node[process] (pass) [right of=rtlil, node distance=5em, xshift=7.5em] {Passes};
        \node[process] (vlbe) [below of=rtlil, node distance=7em, xshift=-13em] {Verilog Backend};
-       \node[process] (ilangbe) [below of=rtlil, node distance=7em, xshift=0em] {ILANG Backend};
+       \node[process] (ilangbe) [below of=rtlil, node distance=7em, xshift=0em] {RTLIL Backend};
        \node[process, fill=green!5] (otherbe) [below of=rtlil, node distance=7em, xshift=+13em] {Other Backends};
 
        \draw[-latex] (vlog) -- (ast);
@@ -105,8 +105,7 @@ For simplicity we only discuss this version of RTLIL in this presentation.
 
 \begin{frame}{\subsecname}
 \begin{itemize}
-\item The {\tt dump} command prints the design (or parts of it) in ILANG format. This is
-a text representation of RTLIL.
+\item The {\tt dump} command prints the design (or parts of it) in the text representation of RTLIL.
 
 \bigskip
 \item The {\tt show} command visualizes how the components in the design are connected.
index 98d42aa83babbfdcbac06087807c93dc7ce129c2..81d7a34bbe64cfcbc5bebb623d3fac9feb037945 100644 (file)
  */
 
 #include "kernel/yosys.h"
-#include "backends/ilang/ilang_backend.h"
+#include "backends/rtlil/rtlil_backend.h"
 
 USING_YOSYS_NAMESPACE
-using namespace ILANG_BACKEND;
+using namespace RTLIL_BACKEND;
 PRIVATE_NAMESPACE_BEGIN
 
 struct BugpointPass : public Pass {
@@ -90,7 +90,7 @@ struct BugpointPass : public Pass {
                design->sort();
 
                std::ofstream f("bugpoint-case.il");
-               ILANG_BACKEND::dump_design(f, design, /*only_selected=*/false, /*flag_m=*/true, /*flag_n=*/false);
+               RTLIL_BACKEND::dump_design(f, design, /*only_selected=*/false, /*flag_m=*/true, /*flag_n=*/false);
                f.close();
 
                string yosys_cmdline = stringf("%s -qq -L bugpoint-case.log -s %s bugpoint-case.il", yosys_cmd.c_str(), script.c_str());
index cbed08a3f62e8d1675b82f9fecf4cbadec4faa99..a4ad861f62437dea41891af991c0ec4358966e28 100644 (file)
@@ -605,7 +605,7 @@ struct ShowPass : public Pass {
                log("        generate a .dot file, or other <format> strings such as 'svg' or 'ps'\n");
                log("        to generate files in other formats (this calls the 'dot' command).\n");
                log("\n");
-               log("    -lib <verilog_or_ilang_file>\n");
+               log("    -lib <verilog_or_rtlil_file>\n");
                log("        Use the specified library file for determining whether cell ports are\n");
                log("        inputs or outputs. This option can be used multiple times to specify\n");
                log("        more than one library.\n");
@@ -811,7 +811,7 @@ struct ShowPass : public Pass {
                        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.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "ilang" : "verilog"));
+                       Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "rtlil" : "verilog"));
                        libs.push_back(lib);
                }
 
index a2a428d15280a3e685fbb49ddf9a0c3be714fe70..90b25949d9e7b4388672270cf835d14a57f17117 100644 (file)
@@ -224,7 +224,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
                                {
                                        {".v", "verilog"},
                                        {".sv", "verilog -sv"},
-                                       {".il", "ilang"}
+                                       {".il", "rtlil"}
                                };
 
                                for (auto &ext : extensions_list)
index 7278cb680967b12cc9c9531a040881198b8bcf19..f5966fac0f850fd249e0e17a30dfee180cd2cd16 100644 (file)
@@ -354,7 +354,7 @@ struct ExtractPass : public Pass {
                log("\n");
                log("This pass looks for subcircuits that are isomorphic to any of the modules\n");
                log("in the given map file and replaces them with instances of this modules. The\n");
-               log("map file can be a Verilog source file (*.v) or an ilang file (*.il).\n");
+               log("map file can be a Verilog source file (*.v) or an RTLIL source file (*.il).\n");
                log("\n");
                log("    -map <map_file>\n");
                log("        use the modules in this file as reference. This option can be used\n");
@@ -409,7 +409,7 @@ struct ExtractPass : public Pass {
                log("the following options are to be used instead of the -map option.\n");
                log("\n");
                log("    -mine <out_file>\n");
-               log("        mine for frequent subcircuits and write them to the given ilang file\n");
+               log("        mine for frequent subcircuits and write them to the given RTLIL file\n");
                log("\n");
                log("    -mine_cells_span <min> <max>\n");
                log("        only mine for subcircuits with the specified number of cells\n");
@@ -578,7 +578,7 @@ struct ExtractPass : public Pass {
                }
 
                if (map_filenames.empty() && mine_outfile.empty())
-                       log_cmd_error("Missing option -map <verilog_or_ilang_file> or -mine <output_ilang_file>.\n");
+                       log_cmd_error("Missing option -map <verilog_or_rtlil_file> or -mine <output_rtlil_file>.\n");
 
                RTLIL::Design *map = nullptr;
 
@@ -606,7 +606,7 @@ struct ExtractPass : public Pass {
                                                delete map;
                                                log_cmd_error("Can't open map file `%s'.\n", filename.c_str());
                                        }
-                                       Frontend::frontend_call(map, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "ilang" : "verilog"));
+                                       Frontend::frontend_call(map, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "rtlil" : "verilog"));
                                        f.close();
 
                                        if (filename.size() <= 3 || filename.compare(filename.size()-3, std::string::npos, ".il") != 0) {
@@ -744,7 +744,7 @@ struct ExtractPass : public Pass {
                        f.open(mine_outfile.c_str(), std::ofstream::trunc);
                        if (f.fail())
                                log_error("Can't open output file `%s'.\n", mine_outfile.c_str());
-                       Backend::backend_call(map, &f, mine_outfile, "ilang");
+                       Backend::backend_call(map, &f, mine_outfile, "rtlil");
                        f.close();
                }
 
index 4a1a74ce93bda4385ab35793f32501d11094102a..5cd35929ee4a08c08ba3cb99f4c434cf7fedce46 100644 (file)
@@ -985,7 +985,7 @@ struct TechmapPass : public Pass {
                log("    techmap [-map filename] [selection]\n");
                log("\n");
                log("This pass implements a very simple technology mapper that replaces cells in\n");
-               log("the design with implementations given in form of a Verilog or ilang source\n");
+               log("the design with implementations given in form of a Verilog or RTLIL source\n");
                log("file.\n");
                log("\n");
                log("    -map filename\n");
@@ -1212,7 +1212,7 @@ struct TechmapPass : public Pass {
                                                if (!map->module(mod->name))
                                                        map->add(mod->clone());
                                } else {
-                                       Frontend::frontend_call(map, nullptr, fn, (fn.size() > 3 && fn.compare(fn.size()-3, std::string::npos, ".il") == 0 ? "ilang" : verilog_frontend));
+                                       Frontend::frontend_call(map, nullptr, fn, (fn.size() > 3 && fn.compare(fn.size()-3, std::string::npos, ".il") == 0 ? "rtlil" : verilog_frontend));
                                }
                }
 
index 2d80e66e45467b8947c52bba07df3fa2a6b8e442..ac31e36f1207f7032cdfae16fff8bb43e9bb929f 100644 (file)
@@ -171,7 +171,7 @@ static void test_abcloop()
        }
 
        log("Found viable UUT after %d cycles:\n", create_cycles);
-       Pass::call(design, "write_ilang");
+       Pass::call(design, "write_rtlil");
        Pass::call(design, "abc");
 
        log("\n");
index 228b6b67afe6f284f9d22a2186252bee468c0fc1..616981f32d4954903c9f84625e2989414a8d9edf 100644 (file)
@@ -678,12 +678,12 @@ struct TestCellPass : public Pass {
                log("    -s {positive_integer}\n");
                log("        use this value as rng seed value (default = unix time).\n");
                log("\n");
-               log("    -f {ilang_file}\n");
-               log("        don't generate circuits. instead load the specified ilang file.\n");
+               log("    -f {rtlil_file}\n");
+               log("        don't generate circuits. instead load the specified RTLIL file.\n");
                log("\n");
                log("    -w {filename_prefix}\n");
                log("        don't test anything. just generate the circuits and write them\n");
-               log("        to ilang files with the specified prefix\n");
+               log("        to RTLIL files with the specified prefix\n");
                log("\n");
                log("    -map {filename}\n");
                log("        pass this option to techmap.\n");
@@ -724,7 +724,7 @@ struct TestCellPass : public Pass {
        {
                int num_iter = 100;
                std::string techmap_cmd = "techmap -assert";
-               std::string ilang_file, write_prefix;
+               std::string rtlil_file, write_prefix;
                xorshift32_state = 0;
                std::ofstream vlog_file;
                bool muxdiv = false;
@@ -750,7 +750,7 @@ struct TestCellPass : public Pass {
                                continue;
                        }
                        if (args[argidx] == "-f" && argidx+1 < GetSize(args)) {
-                               ilang_file = args[++argidx];
+                               rtlil_file = args[++argidx];
                                num_iter = 1;
                                continue;
                        }
@@ -910,10 +910,10 @@ struct TestCellPass : public Pass {
                                selected_cell_types.push_back(args[argidx]);
                }
 
-               if (!ilang_file.empty()) {
+               if (!rtlil_file.empty()) {
                        if (!selected_cell_types.empty())
                                log_cmd_error("Do not specify any cell types when using -f.\n");
-                       selected_cell_types.push_back(ID(ilang));
+                       selected_cell_types.push_back(ID(rtlil));
                }
 
                if (selected_cell_types.empty())
@@ -925,12 +925,12 @@ struct TestCellPass : public Pass {
                        for (int i = 0; i < num_iter; i++)
                        {
                                RTLIL::Design *design = new RTLIL::Design;
-                               if (cell_type == ID(ilang))
-                                       Frontend::frontend_call(design, NULL, std::string(), "ilang " + ilang_file);
+                               if (cell_type == ID(rtlil))
+                                       Frontend::frontend_call(design, NULL, std::string(), "rtlil " + rtlil_file);
                                else
                                        create_gold_module(design, cell_type, cell_types.at(cell_type), constmode, muxdiv);
                                if (!write_prefix.empty()) {
-                                       Pass::call(design, stringf("write_ilang %s_%s_%05d.il", write_prefix.c_str(), cell_type.c_str()+1, i));
+                                       Pass::call(design, stringf("write_rtlil %s_%s_%05d.il", write_prefix.c_str(), cell_type.c_str()+1, i));
                                } else if (edges) {
                                        Pass::call(design, "dump gold");
                                        run_edges_test(design, verbose);