3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-08-04 02:10:24 +00:00

Merge remote-tracking branch 'origin/master' into xaig

This commit is contained in:
Eddie Hung 2019-06-12 08:50:39 -07:00
commit f7a9769c14
140 changed files with 4698 additions and 1852 deletions

View file

@ -409,12 +409,26 @@ struct BlifDumper
f << stringf(".%s %s", subckt_or_gate(cell->type.str()), cstr(cell->type));
for (auto &conn : cell->connections())
for (int i = 0; i < conn.second.size(); i++) {
if (conn.second.size() == 1)
f << stringf(" %s", cstr(conn.first));
else
f << stringf(" %s[%d]", cstr(conn.first), i);
f << stringf("=%s", cstr(conn.second.extract(i, 1)));
{
if (conn.second.size() == 1) {
f << stringf(" %s=%s", cstr(conn.first), cstr(conn.second[0]));
continue;
}
Module *m = design->module(cell->type);
Wire *w = m ? m->wire(conn.first) : nullptr;
if (w == nullptr) {
for (int i = 0; i < GetSize(conn.second); i++)
f << stringf(" %s[%d]=%s", cstr(conn.first), i, cstr(conn.second[i]));
} else {
for (int i = 0; i < std::min(GetSize(conn.second), GetSize(w)); i++) {
SigBit sig(w, i);
f << stringf(" %s[%d]=%s", cstr(conn.first), sig.wire->upto ?
sig.wire->start_offset+sig.wire->width-sig.offset-1 :
sig.wire->start_offset+sig.offset, cstr(conn.second[i]));
}
}
}
f << stringf("\n");

View file

@ -129,7 +129,13 @@ struct BtorWorker
void export_cell(Cell *cell)
{
log_assert(cell_recursion_guard.count(cell) == 0);
if (cell_recursion_guard.count(cell)) {
string cell_list;
for (auto c : cell_recursion_guard)
cell_list += stringf("\n %s", log_id(c));
log_error("Found topological loop while processing cell %s. Active cells:%s\n", log_id(cell), cell_list.c_str());
}
cell_recursion_guard.insert(cell);
btorf_push(log_id(cell));

View file

@ -146,7 +146,7 @@ struct FirrtlWorker
if (!mask.is_fully_def())
this->ena = SigSpec(RTLIL::Const(1));
}
string gen_read(const char * /* indent */) {
string gen_read(const char * /* indent */) {
log_error("gen_read called on write_port: %s\n", name.c_str());
return stringf("gen_read called on write_port: %s\n", name.c_str());
}
@ -163,31 +163,61 @@ struct FirrtlWorker
}
};
/* Memories defined within this module. */
struct memory {
string name; // memory name
int abits; // number of address bits
int size; // size (in units) of the memory
int width; // size (in bits) of each element
int read_latency;
int write_latency;
vector<read_port> read_ports;
vector<write_port> write_ports;
std::string init_file;
std::string init_file_srcFileSpec;
memory(string name, int abits, int size, int width) : name(name), abits(abits), size(size), width(width), read_latency(0), write_latency(1), init_file(""), init_file_srcFileSpec("") {}
memory() : read_latency(0), write_latency(1), init_file(""), init_file_srcFileSpec(""){}
void add_memory_read_port(read_port &rp) {
read_ports.push_back(rp);
}
void add_memory_write_port(write_port &wp) {
write_ports.push_back(wp);
}
void add_memory_file(std::string init_file, std::string init_file_srcFileSpec) {
this->init_file = init_file;
this->init_file_srcFileSpec = init_file_srcFileSpec;
struct memory {
Cell *pCell; // for error reporting
string name; // memory name
int abits; // number of address bits
int size; // size (in units) of the memory
int width; // size (in bits) of each element
int read_latency;
int write_latency;
vector<read_port> read_ports;
vector<write_port> write_ports;
std::string init_file;
std::string init_file_srcFileSpec;
string srcLine;
memory(Cell *pCell, string name, int abits, int size, int width) : pCell(pCell), name(name), abits(abits), size(size), width(width), read_latency(0), write_latency(1), init_file(""), init_file_srcFileSpec("") {
// Provide defaults for abits or size if one (but not the other) is specified.
if (this->abits == 0 && this->size != 0) {
this->abits = ceil_log2(this->size);
} else if (this->abits != 0 && this->size == 0) {
this->size = 1 << this->abits;
}
// Sanity-check this construction.
if (this->name == "") {
log_error("Nameless memory%s\n", this->atLine());
}
if (this->abits == 0 && this->size == 0) {
log_error("Memory %s has zero address bits and size%s\n", this->name.c_str(), this->atLine());
}
if (this->width == 0) {
log_error("Memory %s has zero width%s\n", this->name.c_str(), this->atLine());
}
}
// We need a default constructor for the dict insert.
memory() : pCell(0), read_latency(0), write_latency(1), init_file(""), init_file_srcFileSpec(""){}
};
const char *atLine() {
if (srcLine == "") {
if (pCell) {
auto p = pCell->attributes.find("\\src");
srcLine = " at " + p->second.decode_string();
}
}
return srcLine.c_str();
}
void add_memory_read_port(read_port &rp) {
read_ports.push_back(rp);
}
void add_memory_write_port(write_port &wp) {
write_ports.push_back(wp);
}
void add_memory_file(std::string init_file, std::string init_file_srcFileSpec) {
this->init_file = init_file;
this->init_file_srcFileSpec = init_file_srcFileSpec;
}
};
dict<string, memory> memories;
void register_memory(memory &m)
@ -314,6 +344,7 @@ struct FirrtlWorker
switch (dir) {
case FD_INOUT:
log_warning("Instance port connection %s.%s is INOUT; treating as OUT\n", cell_type.c_str(), log_signal(it->second));
/* FALLTHRU */
case FD_OUT:
sourceExpr = firstName;
sinkExpr = secondExpr;
@ -321,7 +352,7 @@ struct FirrtlWorker
break;
case FD_NODIRECTION:
log_warning("Instance port connection %s.%s is NODIRECTION; treating as IN\n", cell_type.c_str(), log_signal(it->second));
/* FALL_THROUGH */
/* FALLTHRU */
case FD_IN:
sourceExpr = secondExpr;
sinkExpr = firstName;
@ -418,8 +449,10 @@ struct FirrtlWorker
string primop;
bool always_uint = false;
if (cell->type == "$not") primop = "not";
else if (cell->type == "$neg") primop = "neg";
else if (cell->type == "$logic_not") {
else if (cell->type == "$neg") {
primop = "neg";
is_signed = true; // Result of "neg" is signed (an SInt).
} else if (cell->type == "$logic_not") {
primop = "eq";
a_expr = stringf("%s, UInt(0)", a_expr.c_str());
}
@ -531,6 +564,7 @@ struct FirrtlWorker
auto b_sig = cell->getPort("\\B");
if (b_sig.is_fully_const()) {
primop = "shl";
b_expr = std::to_string(b_sig.as_int());
} else {
primop = "dshl";
// Convert from FIRRTL left shift semantics.
@ -544,6 +578,7 @@ struct FirrtlWorker
auto b_sig = cell->getPort("\\B");
if (b_sig.is_fully_const()) {
primop = "shr";
b_expr = std::to_string(b_sig.as_int());
} else {
primop = "dshr";
}
@ -604,7 +639,7 @@ struct FirrtlWorker
int abits = cell->parameters.at("\\ABITS").as_int();
int width = cell->parameters.at("\\WIDTH").as_int();
int size = cell->parameters.at("\\SIZE").as_int();
memory m(mem_id, abits, size, width);
memory m(cell, mem_id, abits, size, width);
int rd_ports = cell->parameters.at("\\RD_PORTS").as_int();
int wr_ports = cell->parameters.at("\\WR_PORTS").as_int();
@ -681,6 +716,8 @@ struct FirrtlWorker
{
std::string cell_type = fid(cell->type);
std::string mem_id = make_id(cell->parameters["\\MEMID"].decode_string());
int abits = cell->parameters.at("\\ABITS").as_int();
int width = cell->parameters.at("\\WIDTH").as_int();
memory *mp = nullptr;
if (cell->type == "$meminit" ) {
log_error("$meminit (%s.%s.%s) currently unsupported\n", log_id(module), log_id(cell), mem_id.c_str());
@ -693,6 +730,11 @@ struct FirrtlWorker
Const clk_enable = cell->parameters.at("\\CLK_ENABLE");
Const clk_polarity = cell->parameters.at("\\CLK_POLARITY");
// Do we already have an entry for this memory?
if (memories.count(mem_id) == 0) {
memory m(cell, mem_id, abits, 0, width);
register_memory(m);
}
mp = &memories.at(mem_id);
int portNum = 0;
bool transparency = false;
@ -890,7 +932,7 @@ struct FirrtlWorker
// If we have any memory definitions, output them.
for (auto kv : memories) {
memory m = kv.second;
memory &m = kv.second;
f << stringf(" mem %s:\n", m.name.c_str());
f << stringf(" data-type => UInt<%d>\n", m.width);
f << stringf(" depth => %d\n", m.size);

View file

@ -160,7 +160,10 @@ void ILANG_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL::
}
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 ", indent.c_str(), (it.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "", it.first.c_str());
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");
}

View file

@ -183,8 +183,9 @@ bool is_reg_wire(RTLIL::SigSpec sig, std::string &reg_name)
return true;
}
void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int offset = 0, bool no_decimal = false, bool set_signed = false, bool escape_comment = false)
void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int offset = 0, bool no_decimal = false, bool escape_comment = false)
{
bool set_signed = (data.flags & RTLIL::CONST_FLAG_SIGNED) != 0;
if (width < 0)
width = data.bits.size() - offset;
if (width == 0) {
@ -275,7 +276,8 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o
}
}
} else {
f << stringf("\"");
if ((data.flags & RTLIL::CONST_FLAG_REAL) == 0)
f << stringf("\"");
std::string str = data.decode_string();
for (size_t i = 0; i < str.size(); i++) {
if (str[i] == '\n')
@ -293,7 +295,8 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o
else
f << str[i];
}
f << stringf("\"");
if ((data.flags & RTLIL::CONST_FLAG_REAL) == 0)
f << stringf("\"");
}
}
@ -373,7 +376,7 @@ void dump_attributes(std::ostream &f, std::string indent, dict<RTLIL::IdString,
else if (modattr && (it->second == Const(1, 1) || it->second == Const(1)))
f << stringf(" 1 ");
else
dump_const(f, it->second, -1, 0, false, false, attr2comment);
dump_const(f, it->second, -1, 0, false, attr2comment);
f << stringf(" %s%c", attr2comment ? "*/" : "*)", term);
}
}
@ -1242,6 +1245,118 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true;
}
if (cell->type.in("$assert", "$assume", "$cover"))
{
f << stringf("%s" "always @* if (", indent.c_str());
dump_sigspec(f, cell->getPort("\\EN"));
f << stringf(") %s(", cell->type.c_str()+1);
dump_sigspec(f, cell->getPort("\\A"));
f << stringf(");\n");
return true;
}
if (cell->type.in("$specify2", "$specify3"))
{
f << stringf("%s" "specify\n%s ", indent.c_str(), indent.c_str());
SigSpec en = cell->getPort("\\EN");
if (en != State::S1) {
f << stringf("if (");
dump_sigspec(f, cell->getPort("\\EN"));
f << stringf(") ");
}
f << "(";
if (cell->type == "$specify3" && cell->getParam("\\EDGE_EN").as_bool())
f << (cell->getParam("\\EDGE_POL").as_bool() ? "posedge ": "negedge ");
dump_sigspec(f, cell->getPort("\\SRC"));
f << " ";
if (cell->getParam("\\SRC_DST_PEN").as_bool())
f << (cell->getParam("\\SRC_DST_POL").as_bool() ? "+": "-");
f << (cell->getParam("\\FULL").as_bool() ? "*> ": "=> ");
if (cell->type == "$specify3") {
f << "(";
dump_sigspec(f, cell->getPort("\\DST"));
f << " ";
if (cell->getParam("\\DAT_DST_PEN").as_bool())
f << (cell->getParam("\\DAT_DST_POL").as_bool() ? "+": "-");
f << ": ";
dump_sigspec(f, cell->getPort("\\DAT"));
f << ")";
} else {
dump_sigspec(f, cell->getPort("\\DST"));
}
bool bak_decimal = decimal;
decimal = 1;
f << ") = (";
dump_const(f, cell->getParam("\\T_RISE_MIN"));
f << ":";
dump_const(f, cell->getParam("\\T_RISE_TYP"));
f << ":";
dump_const(f, cell->getParam("\\T_RISE_MAX"));
f << ", ";
dump_const(f, cell->getParam("\\T_FALL_MIN"));
f << ":";
dump_const(f, cell->getParam("\\T_FALL_TYP"));
f << ":";
dump_const(f, cell->getParam("\\T_FALL_MAX"));
f << ");\n";
decimal = bak_decimal;
f << stringf("%s" "endspecify\n", indent.c_str());
return true;
}
if (cell->type == "$specrule")
{
f << stringf("%s" "specify\n%s ", indent.c_str(), indent.c_str());
string spec_type = cell->getParam("\\TYPE").decode_string();
f << stringf("%s(", spec_type.c_str());
if (cell->getParam("\\SRC_PEN").as_bool())
f << (cell->getParam("\\SRC_POL").as_bool() ? "posedge ": "negedge ");
dump_sigspec(f, cell->getPort("\\SRC"));
if (cell->getPort("\\SRC_EN") != State::S1) {
f << " &&& ";
dump_sigspec(f, cell->getPort("\\SRC_EN"));
}
f << ", ";
if (cell->getParam("\\DST_PEN").as_bool())
f << (cell->getParam("\\DST_POL").as_bool() ? "posedge ": "negedge ");
dump_sigspec(f, cell->getPort("\\DST"));
if (cell->getPort("\\DST_EN") != State::S1) {
f << " &&& ";
dump_sigspec(f, cell->getPort("\\DST_EN"));
}
bool bak_decimal = decimal;
decimal = 1;
f << ", ";
dump_const(f, cell->getParam("\\T_LIMIT"));
if (spec_type == "$setuphold" || spec_type == "$recrem" || spec_type == "$fullskew") {
f << ", ";
dump_const(f, cell->getParam("\\T_LIMIT2"));
}
f << ");\n";
decimal = bak_decimal;
f << stringf("%s" "endspecify\n", indent.c_str());
return true;
}
// FIXME: $_SR_[PN][PN]_, $_DLATCH_[PN]_, $_DLATCHSR_[PN][PN][PN]_
// FIXME: $sr, $dlatch, $memrd, $memwr, $fsm
@ -1264,8 +1379,7 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
if (it != cell->parameters.begin())
f << stringf(",");
f << stringf("\n%s .%s(", indent.c_str(), id(it->first).c_str());
bool is_signed = (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0;
dump_const(f, it->second, -1, 0, false, is_signed);
dump_const(f, it->second);
f << stringf(")");
}
f << stringf("\n%s" ")", indent.c_str());
@ -1312,8 +1426,7 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
if (defparam && cell->parameters.size() > 0) {
for (auto it = cell->parameters.begin(); it != cell->parameters.end(); ++it) {
f << stringf("%sdefparam %s.%s = ", indent.c_str(), cell_name.c_str(), id(it->first).c_str());
bool is_signed = (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0;
dump_const(f, it->second, -1, 0, false, is_signed);
dump_const(f, it->second);
f << stringf(";\n");
}
}
@ -1505,7 +1618,8 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
SigSpec sig = active_sigmap(wire);
Const val = wire->attributes.at("\\init");
for (int i = 0; i < GetSize(sig) && i < GetSize(val); i++)
active_initdata[sig[i]] = val.bits.at(i);
if (val[i] == State::S0 || val[i] == State::S1)
active_initdata[sig[i]] = val[i];
}
if (!module->processes.empty())