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:
commit
f7a9769c14
140 changed files with 4698 additions and 1852 deletions
|
@ -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");
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -183,8 +183,9 @@ bool is_reg_wire(RTLIL::SigSpec sig, std::string ®_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())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue