3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-23 17:15:33 +00:00

Merge remote-tracking branch 'origin/master' into eddie/wreduce_add

This commit is contained in:
Eddie Hung 2019-08-06 14:50:00 -07:00
commit 26cb3e7afc
56 changed files with 763 additions and 172 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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)

View file

@ -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> &parameters = 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

View file

@ -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)

View file

@ -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)

View file

@ -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 = "");

View file

@ -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)
{

View file

@ -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";

View file

@ -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