diff options
author | Eddie Hung <eddie@fpgeh.com> | 2019-08-06 14:50:00 -0700 |
---|---|---|
committer | Eddie Hung <eddie@fpgeh.com> | 2019-08-06 14:50:00 -0700 |
commit | 26cb3e7afc603b5aa703434c2cdfad444a4d4db0 (patch) | |
tree | cb346623885c4bc1e98affc623084f58b0a87ce2 /kernel | |
parent | 09beeee38a5af767f70d24e86c976e43b1b27547 (diff) | |
parent | 8110fb9266e685aaea48359a5aebc4e5ac865240 (diff) | |
download | yosys-26cb3e7afc603b5aa703434c2cdfad444a4d4db0.tar.gz yosys-26cb3e7afc603b5aa703434c2cdfad444a4d4db0.tar.bz2 yosys-26cb3e7afc603b5aa703434c2cdfad444a4d4db0.zip |
Merge remote-tracking branch 'origin/master' into eddie/wreduce_add
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/cellaigs.cc | 2 | ||||
-rw-r--r-- | kernel/celltypes.h | 1 | ||||
-rw-r--r-- | kernel/consteval.h | 7 | ||||
-rw-r--r-- | kernel/cost.h | 34 | ||||
-rw-r--r-- | kernel/register.cc | 109 | ||||
-rw-r--r-- | kernel/rtlil.cc | 2 | ||||
-rw-r--r-- | kernel/rtlil.h | 24 | ||||
-rw-r--r-- | kernel/satgen.h | 7 | ||||
-rw-r--r-- | kernel/yosys.cc | 21 | ||||
-rw-r--r-- | kernel/yosys.h | 5 |
10 files changed, 184 insertions, 28 deletions
diff --git a/kernel/cellaigs.cc b/kernel/cellaigs.cc index 26c625f89..fbc6d045e 100644 --- a/kernel/cellaigs.cc +++ b/kernel/cellaigs.cc @@ -325,6 +325,8 @@ Aig::Aig(Cell *cell) int A = mk.inport("\\A", i); int B = mk.inport("\\B", i); int Y = mk.mux_gate(A, B, S); + if (cell->type == "$_NMUX_") + Y = mk.not_gate(Y); mk.outport(Y, "\\Y", i); } goto optimize; diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 758661c02..d2594bc46 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -193,6 +193,7 @@ struct CellTypes setup_type("$_ANDNOT_", {A, B}, {Y}, true); setup_type("$_ORNOT_", {A, B}, {Y}, true); setup_type("$_MUX_", {A, B, S}, {Y}, true); + setup_type("$_NMUX_", {A, B, S}, {Y}, true); setup_type("$_MUX4_", {A, B, C, D, S, T}, {Y}, true); setup_type("$_MUX8_", {A, B, C, D, E, F, G, H, S, T, U}, {Y}, true); setup_type("$_MUX16_", {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V}, {Y}, true); diff --git a/kernel/consteval.h b/kernel/consteval.h index 154373a8d..f70dfa0fb 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -145,7 +145,7 @@ struct ConstEval if (cell->hasPort("\\B")) sig_b = cell->getPort("\\B"); - if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$_MUX_") + if (cell->type.in("$mux", "$pmux", "$_MUX_", "$_NMUX_")) { std::vector<RTLIL::SigSpec> y_candidates; int count_maybe_set_s_bits = 0; @@ -175,7 +175,10 @@ struct ConstEval for (auto &yc : y_candidates) { if (!eval(yc, undef, cell)) return false; - y_values.push_back(yc.as_const()); + if (cell->type == "$_NMUX_") + y_values.push_back(RTLIL::const_not(yc.as_const(), Const(), false, false, GetSize(yc))); + else + y_values.push_back(yc.as_const()); } if (y_values.size() > 1) diff --git a/kernel/cost.h b/kernel/cost.h index 41a09eb63..e8e077ff5 100644 --- a/kernel/cost.h +++ b/kernel/cost.h @@ -24,10 +24,10 @@ YOSYS_NAMESPACE_BEGIN -int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr); +int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr, bool cmos_cost = false); inline int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL::Const> ¶meters = dict<RTLIL::IdString, RTLIL::Const>(), - RTLIL::Design *design = nullptr, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr) + RTLIL::Design *design = nullptr, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr, bool cmos_cost = false) { static dict<RTLIL::IdString, int> gate_cost = { { "$_BUF_", 1 }, @@ -44,9 +44,33 @@ inline int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL { "$_OAI3_", 6 }, { "$_AOI4_", 8 }, { "$_OAI4_", 8 }, - { "$_MUX_", 4 } + { "$_MUX_", 4 }, + { "$_NMUX_", 4 } }; + // match costs in "stat -tech cmos" + static dict<RTLIL::IdString, int> cmos_gate_cost = { + { "$_BUF_", 1 }, + { "$_NOT_", 2 }, + { "$_AND_", 6 }, + { "$_NAND_", 4 }, + { "$_OR_", 6 }, + { "$_NOR_", 4 }, + { "$_ANDNOT_", 6 }, + { "$_ORNOT_", 6 }, + { "$_XOR_", 12 }, + { "$_XNOR_", 12 }, + { "$_AOI3_", 6 }, + { "$_OAI3_", 6 }, + { "$_AOI4_", 8 }, + { "$_OAI4_", 8 }, + { "$_MUX_", 12 }, + { "$_NMUX_", 10 } + }; + + if (cmos_cost && cmos_gate_cost.count(type)) + return cmos_gate_cost.at(type); + if (gate_cost.count(type)) return gate_cost.at(type); @@ -76,9 +100,9 @@ inline int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL return 1; } -inline int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache) +inline int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache, bool cmos_cost) { - return get_cell_cost(cell->type, cell->parameters, cell->module->design, mod_cost_cache); + return get_cell_cost(cell->type, cell->parameters, cell->module->design, mod_cost_cache, cmos_cost); } YOSYS_NAMESPACE_END diff --git a/kernel/register.cc b/kernel/register.cc index 26da96b95..4f60338e9 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -25,6 +25,65 @@ #include <stdio.h> #include <errno.h> +#ifdef YOSYS_ENABLE_ZLIB +#include <zlib.h> + +PRIVATE_NAMESPACE_BEGIN +#define GZ_BUFFER_SIZE 8192 +void decompress_gzip(const std::string &filename, std::stringstream &out) +{ + char buffer[GZ_BUFFER_SIZE]; + int bytes_read; + gzFile gzf = gzopen(filename.c_str(), "rb"); + while(!gzeof(gzf)) { + bytes_read = gzread(gzf, reinterpret_cast<void *>(buffer), GZ_BUFFER_SIZE); + out.write(buffer, bytes_read); + } + gzclose(gzf); +} + +/* +An output stream that uses a stringbuf to buffer data internally, +using zlib to write gzip-compressed data every time the stream is flushed. +*/ +class gzip_ostream : public std::ostream { +public: + gzip_ostream() + { + rdbuf(&outbuf); + } + bool open(const std::string &filename) + { + return outbuf.open(filename); + } +private: + class gzip_streambuf : public std::stringbuf { + public: + gzip_streambuf() { }; + bool open(const std::string &filename) + { + gzf = gzopen(filename.c_str(), "wb"); + return gzf != nullptr; + } + virtual int sync() override + { + gzwrite(gzf, reinterpret_cast<const void *>(str().c_str()), unsigned(str().size())); + str(""); + return 0; + } + ~gzip_streambuf() + { + sync(); + gzclose(gzf); + } + private: + gzFile gzf = nullptr; + } outbuf; +}; +PRIVATE_NAMESPACE_END + +#endif + YOSYS_NAMESPACE_BEGIN #define MAX_REG_COUNT 1000 @@ -436,6 +495,28 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s delete ff; else f = ff; + if (f != NULL) { + // Check for gzip magic + unsigned char magic[3]; + int n = readsome(*ff, reinterpret_cast<char*>(magic), 3); + if (n == 3 && magic[0] == 0x1f && magic[1] == 0x8b) { + #ifdef YOSYS_ENABLE_ZLIB + log("Found gzip magic in file `%s', decompressing using zlib.\n", filename.c_str()); + if (magic[2] != 8) + log_cmd_error("gzip file `%s' uses unsupported compression type %02x\n", + filename.c_str(), unsigned(magic[2])); + delete ff; + std::stringstream *df = new std::stringstream(); + decompress_gzip(filename, *df); + f = df; + #else + log_cmd_error("File `%s' is a gzip file, but Yosys is compiled without zlib.\n", filename.c_str()); + #endif + } else { + ff->clear(); + ff->seekg(0, std::ios::beg); + } + } } if (f == NULL) log_cmd_error("Can't open input file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); @@ -546,14 +627,28 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<st filename = arg; rewrite_filename(filename); - std::ofstream *ff = new std::ofstream; - ff->open(filename.c_str(), std::ofstream::trunc); - yosys_output_files.insert(filename); - if (ff->fail()) { - delete ff; - log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); + if (filename.size() > 3 && filename.substr(filename.size()-3) == ".gz") { +#ifdef YOSYS_ENABLE_ZLIB + gzip_ostream *gf = new gzip_ostream; + if (!gf->open(filename)) { + delete gf; + log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); + } + yosys_output_files.insert(filename); + f = gf; +#else + log_cmd_error("Yosys is compiled without zlib support, unable to write gzip output.\n"); +#endif + } else { + std::ofstream *ff = new std::ofstream; + ff->open(filename.c_str(), std::ofstream::trunc); + yosys_output_files.insert(filename); + if (ff->fail()) { + delete ff; + log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); + } + f = ff; } - f = ff; } if (called_with_fp) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 85b013bdc..f2c81db72 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1249,6 +1249,7 @@ namespace { if (cell->type == "$_ANDNOT_") { check_gate("ABY"); return; } if (cell->type == "$_ORNOT_") { check_gate("ABY"); return; } if (cell->type == "$_MUX_") { check_gate("ABSY"); return; } + if (cell->type == "$_NMUX_") { check_gate("ABSY"); return; } if (cell->type == "$_AOI3_") { check_gate("ABCY"); return; } if (cell->type == "$_OAI3_") { check_gate("ABCY"); return; } if (cell->type == "$_AOI4_") { check_gate("ABCDY"); return; } @@ -1976,6 +1977,7 @@ DEF_METHOD_3(XnorGate, "$_XNOR_", A, B, Y) DEF_METHOD_3(AndnotGate, "$_ANDNOT_", A, B, Y) DEF_METHOD_3(OrnotGate, "$_ORNOT_", A, B, Y) DEF_METHOD_4(MuxGate, "$_MUX_", A, B, S, Y) +DEF_METHOD_4(NmuxGate, "$_NMUX_", A, B, S, Y) DEF_METHOD_4(Aoi3Gate, "$_AOI3_", A, B, C, Y) DEF_METHOD_4(Oai3Gate, "$_OAI3_", A, B, C, Y) DEF_METHOD_5(Aoi4Gate, "$_AOI4_", A, B, C, D, Y) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index f9412e776..633cb51d6 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -420,8 +420,12 @@ namespace RTLIL // It maintains a reference counter that is used to make sure that the container is not modified while being iterated over. template<typename T> - struct ObjIterator - { + struct ObjIterator { + using iterator_category = std::forward_iterator_tag; + using value_type = T; + using difference_type = ptrdiff_t; + using pointer = T*; + using reference = T&; typename dict<RTLIL::IdString, T>::iterator it; dict<RTLIL::IdString, T> *list_p; int *refcount_p; @@ -474,13 +478,25 @@ namespace RTLIL return it != other.it; } - inline void operator++() { + + inline bool operator==(const RTLIL::ObjIterator<T> &other) const { + return !(*this != other); + } + + inline ObjIterator<T>& operator++() { log_assert(list_p != nullptr); if (++it == list_p->end()) { (*refcount_p)--; list_p = nullptr; refcount_p = nullptr; } + return *this; + } + + inline const ObjIterator<T> operator++(int) { + ObjIterator<T> result(*this); + ++(*this); + return result; } }; @@ -1139,6 +1155,7 @@ public: RTLIL::Cell* addAndnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = ""); RTLIL::Cell* addOrnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = ""); RTLIL::Cell* addMuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y, const std::string &src = ""); + RTLIL::Cell* addNmuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y, const std::string &src = ""); RTLIL::Cell* addAoi3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y, const std::string &src = ""); RTLIL::Cell* addOai3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y, const std::string &src = ""); RTLIL::Cell* addAoi4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, RTLIL::SigBit sig_y, const std::string &src = ""); @@ -1214,6 +1231,7 @@ public: RTLIL::SigBit AndnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = ""); RTLIL::SigBit OrnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = ""); RTLIL::SigBit MuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, const std::string &src = ""); + RTLIL::SigBit NmuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, const std::string &src = ""); RTLIL::SigBit Aoi3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, const std::string &src = ""); RTLIL::SigBit Oai3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, const std::string &src = ""); RTLIL::SigBit Aoi4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, const std::string &src = ""); diff --git a/kernel/satgen.h b/kernel/satgen.h index 210cca3f3..e9f3ecd44 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -475,7 +475,7 @@ struct SatGen return true; } - if (cell->type == "$_MUX_" || cell->type == "$mux") + if (cell->type == "$_MUX_" || cell->type == "$mux" || cell->type == "$_NMUX_") { std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep); @@ -483,7 +483,10 @@ struct SatGen std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; - ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy)); + if (cell->type == "$_NMUX_") + ez->assume(ez->vec_eq(ez->vec_not(ez->vec_ite(s.at(0), b, a)), yy)); + else + ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy)); if (model_undef) { diff --git a/kernel/yosys.cc b/kernel/yosys.cc index a42a7c0b8..191b6d5c7 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -894,23 +894,26 @@ void run_frontend(std::string filename, std::string command, std::string *backen design = yosys_design; if (command == "auto") { - if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") + std::string filename_trim = filename; + if (filename_trim.size() > 3 && filename_trim.substr(filename_trim.size()-3) == ".gz") + filename_trim.erase(filename_trim.size()-3); + if (filename_trim.size() > 2 && filename_trim.substr(filename_trim.size()-2) == ".v") command = "verilog"; - else if (filename.size() > 2 && filename.substr(filename.size()-3) == ".sv") + else if (filename_trim.size() > 2 && filename_trim.substr(filename_trim.size()-3) == ".sv") command = "verilog -sv"; - else if (filename.size() > 3 && filename.substr(filename.size()-4) == ".vhd") + else if (filename_trim.size() > 3 && filename_trim.substr(filename_trim.size()-4) == ".vhd") command = "vhdl"; - else if (filename.size() > 4 && filename.substr(filename.size()-5) == ".blif") + else if (filename_trim.size() > 4 && filename_trim.substr(filename_trim.size()-5) == ".blif") command = "blif"; - else if (filename.size() > 5 && filename.substr(filename.size()-6) == ".eblif") + else if (filename_trim.size() > 5 && filename_trim.substr(filename_trim.size()-6) == ".eblif") command = "blif"; - else if (filename.size() > 4 && filename.substr(filename.size()-5) == ".json") + else if (filename_trim.size() > 4 && filename_trim.substr(filename_trim.size()-5) == ".json") command = "json"; - else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") + else if (filename_trim.size() > 3 && filename_trim.substr(filename_trim.size()-3) == ".il") command = "ilang"; - else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".ys") + else if (filename_trim.size() > 3 && filename_trim.substr(filename_trim.size()-3) == ".ys") command = "script"; - else if (filename.size() > 3 && filename.substr(filename.size()-4) == ".tcl") + else if (filename_trim.size() > 3 && filename_trim.substr(filename_trim.size()-4) == ".tcl") command = "tcl"; else if (filename == "-") command = "script"; diff --git a/kernel/yosys.h b/kernel/yosys.h index c7b671724..09e8139bb 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -52,6 +52,7 @@ #include <stdexcept> #include <memory> #include <cmath> +#include <cstddef> #include <sstream> #include <fstream> @@ -87,6 +88,10 @@ extern int Tcl_EvalFile(Tcl_Interp *interp, const char *fileName); extern void Tcl_Finalize(void); extern int Tcl_GetCommandInfo(Tcl_Interp *interp, const char *cmdName, Tcl_CmdInfo *infoPtr); extern const char *Tcl_GetStringResult(Tcl_Interp *interp); +extern Tcl_Obj *Tcl_NewStringObj(const char *bytes, int length); +extern Tcl_Obj *Tcl_NewIntObj(int intValue); +extern Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *const objv[]); +extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags); # endif #endif |