Bump to latest

This commit is contained in:
Akash Levy 2025-09-21 01:10:04 -07:00
commit 60d969530b
171 changed files with 2574 additions and 1077 deletions

View File

@ -42,7 +42,7 @@ jobs:
- 'gcc-10'
# newest, make sure to update maximum standard step to match
- 'clang-19'
- 'gcc-13'
- 'gcc-14'
include:
# macOS x86
- os: macos-13
@ -81,7 +81,7 @@ jobs:
# maximum standard, only on newest compilers
- name: Build C++20
if: ${{ matrix.compiler == 'clang-19' || matrix.compiler == 'gcc-13' }}
if: ${{ matrix.compiler == 'clang-19' || matrix.compiler == 'gcc-14' }}
shell: bash
run: |
make config-$CC_SHORT

View File

@ -180,7 +180,7 @@ ifeq ($(OS), Haiku)
CXXFLAGS += -D_DEFAULT_SOURCE
endif
YOSYS_VER := 0.57+72
YOSYS_VER := 0.57+157
YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1)
YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2)
YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'.' -f3)
@ -681,6 +681,7 @@ $(eval $(call add_include_file,frontends/blif/blifparse.h))
$(eval $(call add_include_file,backends/rtlil/rtlil_backend.h))
OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o kernel/io.o kernel/gzip.o
OBJS += kernel/rtlil_bufnorm.o
OBJS += kernel/log_help.o
ifeq ($(ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS),1)
OBJS += kernel/log_compat.o

View File

@ -91,7 +91,7 @@ struct Index {
int pos = index_wires(info, m);
for (auto cell : m->cells()) {
if (cell->type.in(KNOWN_OPS) || cell->type.in(ID($scopeinfo), ID($specify2), ID($specify3)))
if (cell->type.in(KNOWN_OPS) || cell->type.in(ID($scopeinfo), ID($specify2), ID($specify3), ID($input_port)))
continue;
Module *submodule = m->design->module(cell->type);
@ -566,7 +566,7 @@ struct Index {
}
Lit ret;
if (!bit.wire->port_input) {
if (!bit.wire->port_input || bit.wire->port_output) {
// an output of a cell
Cell *driver = bit.wire->driverCell();
@ -618,7 +618,7 @@ struct Index {
if (!cursor) {
log_assert(bit.wire->module == top);
log_assert(bit.wire->port_input);
log_assert(bit.wire->port_input && !bit.wire->port_output);
return lits[top_minfo->windices[bit.wire] + bit.offset];
} else {
log_assert(bit.wire->module == cursor->leaf_module(*this));
@ -723,7 +723,7 @@ struct AigerWriter : Index<AigerWriter, unsigned int, 0, 1> {
for (auto id : top->ports) {
Wire *w = top->wire(id);
log_assert(w);
if (w->port_input)
if (w->port_input && !w->port_output)
for (int i = 0; i < w->width; i++) {
pi_literal(SigBit(w, i)) = lit_counter;
inputs.push_back(SigBit(w, i));
@ -828,7 +828,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
{
log_assert(cursor.is_top()); // TOOD: fix analyzer to work with hierarchy
if (bit.wire->port_input)
if (bit.wire->port_input && !bit.wire->port_output)
return false;
Cell *driver = bit.wire->driverCell();
@ -838,7 +838,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
int max = 1;
for (auto wire : mod->wires())
if (wire->port_input)
if (wire->port_input && !wire->port_output)
for (int i = 0; i < wire->width; i++) {
int ilevel = visit(cursor, driver->getPort(wire->name)[i]);
max = std::max(max, ilevel + 1);
@ -858,7 +858,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
for (auto id : top->ports) {
Wire *w = top->wire(id);
log_assert(w);
if (w->port_input)
if (w->port_input && !w->port_output)
for (int i = 0; i < w->width; i++)
pi_literal(SigBit(w, i)) = 0;
}
@ -868,7 +868,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
Module *def = design->module(box->type);
if (!(def && def->has_attribute(ID::abc9_box_id)))
for (auto &conn : box->connections_)
if (box->output(conn.first))
if (box->port_dir(conn.first) != RTLIL::PD_INPUT)
for (auto bit : conn.second)
pi_literal(bit, &cursor) = 0;
}
@ -883,7 +883,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
Module *def = design->module(box->type);
if (!(def && def->has_attribute(ID::abc9_box_id)))
for (auto &conn : box->connections_)
if (box->input(conn.first))
if (box->port_dir(conn.first) == RTLIL::PD_INPUT)
for (auto bit : conn.second)
(void) eval_po(bit);
}
@ -903,6 +903,16 @@ struct XAigerWriter : AigerWriter {
typedef std::pair<SigBit, HierCursor> HierBit;
std::vector<HierBit> pos;
std::vector<HierBit> pis;
// * The aiger output port sequence is COs (inputs to modeled boxes),
// inputs to opaque boxes, then module outputs. COs going first is
// required by abc.
// * proper_pos_counter counts ports which follow after COs
// * The mapping file `pseudopo` and `po` statements use indexing relative
// to the first port following COs.
// * If a module output is directly driven by an opaque box, the emission
// of the po statement in the mapping file is skipped. This is done to
// aid re-integration of the mapped result.
int proper_pos_counter = 0;
pool<SigBit> driven_by_opaque_box;
@ -937,15 +947,10 @@ struct XAigerWriter : AigerWriter {
lit_counter += 2;
}
void append_box_ports(Cell *box, HierCursor &cursor, bool inputs)
void append_opaque_box_ports(Cell *box, HierCursor &cursor, bool inputs)
{
for (auto &conn : box->connections_) {
bool is_input = box->input(conn.first);
bool is_output = box->output(conn.first);
if (!(is_input || is_output) || (is_input && is_output))
log_error("Ambiguous port direction on %s/%s\n",
log_id(box->type), log_id(conn.first));
bool is_input = box->port_dir(conn.first) == RTLIL::PD_INPUT;
if (is_input && inputs) {
int bitp = 0;
@ -955,13 +960,14 @@ struct XAigerWriter : AigerWriter {
continue;
}
// Inputs to opaque boxes are proper POs as far as abc is concerned
if (map_file.is_open()) {
log_assert(cursor.is_top());
map_file << "pseudopo " << proper_pos_counter++ << " " << bitp
map_file << "pseudopo " << proper_pos_counter << " " << bitp
<< " " << box->name.c_str()
<< " " << conn.first.c_str() << "\n";
}
proper_pos_counter++;
pos.push_back(std::make_pair(bit, cursor));
if (mapping_prep)
@ -969,10 +975,10 @@ struct XAigerWriter : AigerWriter {
bitp++;
}
} else if (is_output && !inputs) {
} else if (!is_input && !inputs) {
for (auto &bit : conn.second) {
if (!bit.wire || bit.wire->port_input)
log_error("Bad connection");
if (!bit.wire || (bit.wire->port_input && !bit.wire->port_output))
log_error("Bad connection %s/%s ~ %s\n", log_id(box), log_id(conn.first), log_signal(conn.second));
ensure_pi(bit, cursor);
@ -1012,7 +1018,7 @@ struct XAigerWriter : AigerWriter {
for (auto box : minfo.found_blackboxes) {
log_debug(" - %s.%s (type %s): ", cursor.path().c_str(),
RTLIL::unescape_id(box->name).c_str(),
RTLIL::unescape_id(box->name),
log_id(box->type));
Module *box_module = design->module(box->type), *box_derived;
@ -1038,7 +1044,7 @@ struct XAigerWriter : AigerWriter {
});
for (auto [cursor, box, def] : opaque_boxes)
append_box_ports(box, cursor, false);
append_opaque_box_ports(box, cursor, false);
holes_module = design->addModule(NEW_ID);
std::vector<RTLIL::Wire *> holes_pis;
@ -1086,6 +1092,8 @@ struct XAigerWriter : AigerWriter {
bit = RTLIL::Sx;
}
// Nonopaque box inputs come first and are not part of
// the PO numbering used by the mapping file.
pos.push_back(std::make_pair(bit, cursor));
}
boxes_co_num += port->width;
@ -1106,7 +1114,7 @@ struct XAigerWriter : AigerWriter {
holes_pi_idx++;
}
holes_wb->setPort(port_id, in_conn);
} else if (port->port_output && !port->port_input) {
} else if (port->port_output) {
// primary
for (int i = 0; i < port->width; i++) {
SigBit bit;
@ -1138,7 +1146,7 @@ struct XAigerWriter : AigerWriter {
}
for (auto [cursor, box, def] : opaque_boxes)
append_box_ports(box, cursor, true);
append_opaque_box_ports(box, cursor, true);
write_be32(h_buffer, 1);
write_be32(h_buffer, pis.size());
@ -1159,7 +1167,7 @@ struct XAigerWriter : AigerWriter {
log_assert(port);
if (port->port_input && !port->port_output) {
box_co_num += port->width;
} else if (port->port_output && !port->port_input) {
} else if (port->port_output) {
box_ci_num += port->width;
} else {
log_abort();
@ -1182,7 +1190,7 @@ struct XAigerWriter : AigerWriter {
reset_counters();
for (auto w : top->wires())
if (w->port_input)
if (w->port_input && !w->port_output)
for (int i = 0; i < w->width; i++)
ensure_pi(SigBit(w, i));
@ -1195,10 +1203,14 @@ struct XAigerWriter : AigerWriter {
for (auto w : top->wires())
if (w->port_output)
for (int i = 0; i < w->width; i++) {
// When a module output is directly driven by an opaque box, we
// don't emit it to the mapping file to aid re-integration, but we
// do emit a proper PO.
if (map_file.is_open() && !driven_by_opaque_box.count(SigBit(w, i))) {
map_file << "po " << proper_pos_counter++ << " " << i
map_file << "po " << proper_pos_counter << " " << i
<< " " << w->name.c_str() << "\n";
}
proper_pos_counter++;
pos.push_back(std::make_pair(SigBit(w, i), HierCursor{}));
}
@ -1446,7 +1458,7 @@ struct XAiger2Backend : Backend {
if (!map_filename.empty()) {
writer.map_file.open(map_filename);
if (!writer.map_file)
log_cmd_error("Failed to open '%s' for writing\n", map_filename.c_str());
log_cmd_error("Failed to open '%s' for writing\n", map_filename);
}
design->bufNormalize(true);

View File

@ -705,12 +705,13 @@ struct BtorWorker
}
}
Const initval;
Const::Builder initval_bits(GetSize(sig_q));
for (int i = 0; i < GetSize(sig_q); i++)
if (initbits.count(sig_q[i]))
initval.bits().push_back(initbits.at(sig_q[i]) ? State::S1 : State::S0);
initval_bits.push_back(initbits.at(sig_q[i]) ? State::S1 : State::S0);
else
initval.bits().push_back(State::Sx);
initval_bits.push_back(State::Sx);
Const initval = initval_bits.build();
int nid_init_val = -1;
@ -1039,10 +1040,11 @@ struct BtorWorker
{
if (bit.wire == nullptr)
{
Const c(bit.data);
while (i+GetSize(c) < GetSize(sig) && sig[i+GetSize(c)].wire == nullptr)
c.bits().push_back(sig[i+GetSize(c)].data);
Const::Builder c_bits;
c_bits.push_back(bit.data);
while (i + GetSize(c_bits) < GetSize(sig) && sig[i + GetSize(c_bits)].wire == nullptr)
c_bits.push_back(sig[i + GetSize(c_bits)].data);
Const c = c_bits.build();
if (consts.count(c) == 0) {
int sid = get_bv_sid(GetSize(c));

View File

@ -1533,7 +1533,7 @@ struct CxxrtlWorker {
}
// Internal cells
} else if (is_internal_cell(cell->type)) {
log_cmd_error("Unsupported internal cell `%s'.\n", cell->type.c_str());
log_cmd_error("Unsupported internal cell `%s'.\n", cell->type);
// User cells
} else if (for_debug) {
// Outlines are called on demand when computing the value of a debug item. Nothing to do here.
@ -1668,26 +1668,29 @@ struct CxxrtlWorker {
f << signal_temp << " == ";
dump_sigspec(compare, /*is_lhs=*/false, for_debug);
} else if (compare.is_fully_const()) {
RTLIL::Const compare_mask, compare_value;
RTLIL::Const::Builder compare_mask_builder(compare.size());
RTLIL::Const::Builder compare_value_builder(compare.size());
for (auto bit : compare.as_const()) {
switch (bit) {
case RTLIL::S0:
case RTLIL::S1:
compare_mask.bits().push_back(RTLIL::S1);
compare_value.bits().push_back(bit);
compare_mask_builder.push_back(RTLIL::S1);
compare_value_builder.push_back(bit);
break;
case RTLIL::Sx:
case RTLIL::Sz:
case RTLIL::Sa:
compare_mask.bits().push_back(RTLIL::S0);
compare_value.bits().push_back(RTLIL::S0);
compare_mask_builder.push_back(RTLIL::S0);
compare_value_builder.push_back(RTLIL::S0);
break;
default:
log_assert(false);
}
}
RTLIL::Const compare_mask = compare_mask_builder.build();
RTLIL::Const compare_value = compare_value_builder.build();
f << "and_uu<" << compare.size() << ">(" << signal_temp << ", ";
dump_const(compare_mask);
f << ") == ";
@ -3042,7 +3045,7 @@ struct CxxrtlWorker {
if (init == RTLIL::Const()) {
init = RTLIL::Const(State::Sx, GetSize(bit.wire));
}
init.bits()[bit.offset] = port.init_value[i];
init.set(bit.offset, port.init_value[i]);
}
}
}
@ -3800,7 +3803,7 @@ struct CxxrtlBackend : public Backend {
if (args[argidx] == "-print-output" && argidx+1 < args.size()) {
worker.print_output = args[++argidx];
if (!(worker.print_output == "std::cout" || worker.print_output == "std::cerr")) {
log_cmd_error("Invalid output stream \"%s\".\n", worker.print_output.c_str());
log_cmd_error("Invalid output stream \"%s\".\n", worker.print_output);
worker.print_output = "std::cout";
}
continue;

View File

@ -30,9 +30,9 @@
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
#define EDIF_DEF(_id) edif_names(RTLIL::unescape_id(_id), true).c_str()
#define EDIF_DEFR(_id, _ren, _bl, _br) edif_names(RTLIL::unescape_id(_id), true, _ren, _bl, _br).c_str()
#define EDIF_REF(_id) edif_names(RTLIL::unescape_id(_id), false).c_str()
#define EDIF_DEF(_id) edif_names(RTLIL::unescape_id(_id), true)
#define EDIF_DEFR(_id, _ren, _bl, _br) edif_names(RTLIL::unescape_id(_id), true, _ren, _bl, _br)
#define EDIF_REF(_id) edif_names(RTLIL::unescape_id(_id), false)
struct EdifNames
{
@ -513,7 +513,7 @@ struct EdifBackend : public Backend {
if (sig.wire == NULL && sig != RTLIL::State::S0 && sig != RTLIL::State::S1) {
if (sig == RTLIL::State::Sx) {
for (auto &ref : it.second)
log_warning("Exporting x-bit on %s as zero bit.\n", ref.first.c_str());
log_warning("Exporting x-bit on %s as zero bit.\n", ref.first);
sig = RTLIL::State::S0;
} else if (sig == RTLIL::State::Sz) {
continue;

View File

@ -465,7 +465,7 @@ struct FirrtlWorker
// If there is no instance for this, just return.
if (instModule == NULL)
{
log_warning("No instance for %s.%s\n", cell_type.c_str(), cell_name.c_str());
log_warning("No instance for %s.%s\n", cell_type, cell_name);
return;
}
@ -490,7 +490,7 @@ struct FirrtlWorker
const SigSpec *sinkSig = nullptr;
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));
log_warning("Instance port connection %s.%s is INOUT; treating as OUT\n", cell_type, log_signal(it->second));
YS_FALLTHROUGH
case FD_OUT:
sourceExpr = firstName;
@ -498,7 +498,7 @@ struct FirrtlWorker
sinkSig = &secondSig;
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));
log_warning("Instance port connection %s.%s is NODIRECTION; treating as IN\n", cell_type, log_signal(it->second));
YS_FALLTHROUGH
case FD_IN:
sourceExpr = secondExpr;

View File

@ -105,7 +105,7 @@ struct MemContentsTest {
RTLIL::Const values;
for(addr_t addr = low; addr <= high; addr++) {
RTLIL::Const word(data_dist(rnd), data_width);
values.bits().insert(values.bits().end(), word.begin(), word.end());
values.append(word);
}
insert_concatenated(low, values);
}

View File

@ -657,7 +657,7 @@ struct SimplecWorker
{
SigSpec sig = sigmaps.at(module)(w);
Const val = w->attributes.at(ID::init);
val.bits().resize(GetSize(sig), State::Sx);
val.resize(GetSize(sig), State::Sx);
for (int i = 0; i < GetSize(sig); i++)
if (val[i] == State::S0 || val[i] == State::S1) {

View File

@ -1079,14 +1079,14 @@ struct Smt2Worker
RTLIL::SigSpec sig = sigmap(wire);
Const val = wire->attributes.at(ID::init);
val.bits().resize(GetSize(sig), State::Sx);
val.resize(GetSize(sig), State::Sx);
if (bvmode && GetSize(sig) > 1) {
Const mask(State::S1, GetSize(sig));
bool use_mask = false;
for (int i = 0; i < GetSize(sig); i++)
if (val[i] != State::S0 && val[i] != State::S1) {
val.bits()[i] = State::S0;
mask.bits()[i] = State::S0;
val.set(i, State::S0);
mask.set(i, State::S0);
use_mask = true;
}
if (use_mask)
@ -1361,10 +1361,10 @@ struct Smt2Worker
for (int k = 0; k < GetSize(initword); k++) {
if (initword[k] == State::S0 || initword[k] == State::S1) {
gen_init_constr = true;
initmask.bits()[k] = State::S1;
initmask.set(k, State::S1);
} else {
initmask.bits()[k] = State::S0;
initword.bits()[k] = State::S0;
initmask.set(k, State::S0);
initword.set(k, State::S0);
}
}

View File

@ -327,19 +327,20 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o
void dump_reg_init(std::ostream &f, SigSpec sig)
{
Const initval;
bool gotinit = false;
Const::Builder initval_bits(sig.size());
for (auto bit : active_sigmap(sig)) {
if (active_initdata.count(bit)) {
initval.bits().push_back(active_initdata.at(bit));
initval_bits.push_back(active_initdata.at(bit));
gotinit = true;
} else {
initval.bits().push_back(State::Sx);
initval_bits.push_back(State::Sx);
}
}
if (gotinit) {
Const initval = initval_bits.build();
f << " = ";
dump_const(f, initval);
}
@ -784,9 +785,10 @@ void dump_memory(std::ostream &f, std::string indent, Mem &mem)
dump_sigspec(os, port.data.extract(sub * mem.width, mem.width));
os << stringf(" = %s[", mem_id);;
if (port.wide_log2) {
Const addr_lo;
Const::Builder addr_lo_builder(port.wide_log2);
for (int i = 0; i < port.wide_log2; i++)
addr_lo.bits().push_back(State(sub >> i & 1));
addr_lo_builder.push_back(State(sub >> i & 1));
Const addr_lo = addr_lo_builder.build();
os << "{";
os << temp_id;
os << ", ";
@ -985,7 +987,7 @@ void dump_cell_expr_port(std::ostream &f, RTLIL::Cell *cell, std::string port, b
std::string cellname(RTLIL::Cell *cell)
{
if (!norename && cell->name[0] == '$' && RTLIL::builtin_ff_cell_types().count(cell->type) && cell->hasPort(ID::Q) && !cell->type.in(ID($ff), ID($_FF_)))
if (!norename && cell->name[0] == '$' && cell->is_builtin_ff() && cell->hasPort(ID::Q) && !cell->type.in(ID($ff), ID($_FF_)))
{
RTLIL::SigSpec sig = cell->getPort(ID::Q);
if (GetSize(sig) != 1 || sig.is_fully_const())
@ -1114,6 +1116,33 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
}
if (cell->type.in(ID($_BUF_), ID($buf))) {
if (cell->type == ID($buf) && cell->getPort(ID::A).has_const(State::Sz)) {
RTLIL::SigSpec a = cell->getPort(ID::A);
RTLIL::SigSpec y = cell->getPort(ID::Y);
a.extend_u0(GetSize(y));
if (a.has_const(State::Sz)) {
SigSpec new_a;
SigSpec new_y;
for (int i = 0; i < GetSize(a); ++i) {
SigBit b = a[i];
if (b == State::Sz)
continue;
new_a.append(b);
new_y.append(y[i]);
}
a = std::move(new_a);
y = std::move(new_y);
}
if (!y.empty()) {
f << stringf("%s" "assign ", indent);
dump_sigspec(f, y);
f << stringf(" = ");
dump_sigspec(f, a);
f << stringf(";\n");
}
return true;
}
f << stringf("%s" "assign ", indent);
dump_sigspec(f, cell->getPort(ID::Y));
f << stringf(" = ");
@ -1513,7 +1542,30 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true;
}
if (RTLIL::builtin_ff_cell_types().count(cell->type))
if (cell->type == ID($input_port))
return true;
if (cell->type == ID($connect))
{
int width = cell->getParam(ID::WIDTH).as_int() ;
if (width == 1) {
f << stringf("%s" "tran(", indent);
dump_sigspec(f, cell->getPort(ID::A));
f << stringf(", ");
dump_sigspec(f, cell->getPort(ID::B));
f << stringf(");\n");
} else {
auto tran_id = next_auto_id();
f << stringf("%s" "tran %s[%d:0](", indent, tran_id, width - 1);
dump_sigspec(f, cell->getPort(ID::A));
f << stringf(", ");
dump_sigspec(f, cell->getPort(ID::B));
f << stringf(");\n");
}
return true;
}
if (cell->is_builtin_ff())
{
FfData ff(nullptr, cell);
@ -1991,7 +2043,7 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
}
}
if (siminit && RTLIL::builtin_ff_cell_types().count(cell->type) && cell->hasPort(ID::Q) && !cell->type.in(ID($ff), ID($_FF_))) {
if (siminit && cell->is_builtin_ff() && cell->hasPort(ID::Q) && !cell->type.in(ID($ff), ID($_FF_))) {
std::stringstream ss;
dump_reg_init(ss, cell->getPort(ID::Q));
if (!ss.str().empty()) {
@ -2349,7 +2401,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
continue;
}
if (!RTLIL::builtin_ff_cell_types().count(cell->type) || !cell->hasPort(ID::Q) || cell->type.in(ID($ff), ID($_FF_)))
if (!cell->is_builtin_ff() || !cell->hasPort(ID::Q) || cell->type.in(ID($ff), ID($_FF_)))
continue;
RTLIL::SigSpec sig = cell->getPort(ID::Q);

View File

@ -448,7 +448,7 @@ void AigerReader::parse_xaiger()
bool success = ce.eval(o);
log_assert(success);
log_assert(o.wire == nullptr);
lut_mask.bits()[gray] = o.data;
lut_mask.set(gray, o.data);
}
RTLIL::Cell *output_cell = module->cell(stringf("$and$aiger%d$%d", aiger_autoidx, rootNodeID));
log_assert(output_cell);

View File

@ -1076,8 +1076,10 @@ RTLIL::Const AstNode::realAsConst(int width)
bool is_negative = v < 0;
if (is_negative)
v *= -1;
RTLIL::Const::Builder b(width);
for (int i = 0; i < width; i++, v /= 2)
result.bits().push_back((fmod(floor(v), 2) != 0) ? RTLIL::State::S1 : RTLIL::State::S0);
b.push_back((fmod(floor(v), 2) != 0) ? RTLIL::State::S1 : RTLIL::State::S0);
result = b.build();
if (is_negative)
result = const_neg(result, result, false, false, result.size());
}
@ -1444,7 +1446,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool nodisplay, bool dump
if (design->has(child->str)) {
RTLIL::Module *existing_mod = design->module(child->str);
if (!nooverwrite && !overwrite && !existing_mod->get_blackbox_attribute()) {
log_file_error(*child->location.begin.filename, child->location.begin.line, "Re-definition of module `%s'!\n", child->str.c_str());
log_file_error(*child->location.begin.filename, child->location.begin.line, "Re-definition of module `%s'!\n", child->str);
} else if (nooverwrite) {
log("Ignoring re-definition of module `%s' at %s.\n",
child->str.c_str(), child->loc_string().c_str());
@ -1820,7 +1822,7 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dict<RTLIL::Id
return modname;
if (!quiet)
log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str());
log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name);
loadconfig();
pool<IdString> rewritten;

View File

@ -732,16 +732,17 @@ struct AST_INTERNAL::ProcessGenerator
current_case->actions.push_back(SigSig(en, true));
RTLIL::SigSpec triggers;
RTLIL::Const polarity;
RTLIL::Const::Builder polarity_builder;
for (auto sync : proc->syncs) {
if (sync->type == RTLIL::STp) {
triggers.append(sync->signal);
polarity.bits().push_back(RTLIL::S1);
polarity_builder.push_back(RTLIL::S1);
} else if (sync->type == RTLIL::STn) {
triggers.append(sync->signal);
polarity.bits().push_back(RTLIL::S0);
polarity_builder.push_back(RTLIL::S0);
}
}
RTLIL::Const polarity = polarity_builder.build();
RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($print));
set_src_attr(cell, ast);
@ -794,7 +795,7 @@ struct AST_INTERNAL::ProcessGenerator
fmt.append_literal("\n");
fmt.emit_rtlil(cell);
} else if (!ast->str.empty()) {
log_file_error(*ast->location.begin.filename, ast->location.begin.line, "Found unsupported invocation of system task `%s'!\n", ast->str.c_str());
log_file_error(*ast->location.begin.filename, ast->location.begin.line, "Found unsupported invocation of system task `%s'!\n", ast->str);
}
break;
@ -829,22 +830,23 @@ struct AST_INTERNAL::ProcessGenerator
current_case->actions.push_back(SigSig(en, true));
RTLIL::SigSpec triggers;
RTLIL::Const polarity;
RTLIL::Const::Builder polarity_builder;
for (auto sync : proc->syncs) {
if (sync->type == RTLIL::STp) {
triggers.append(sync->signal);
polarity.bits().push_back(RTLIL::S1);
polarity_builder.push_back(RTLIL::S1);
} else if (sync->type == RTLIL::STn) {
triggers.append(sync->signal);
polarity.bits().push_back(RTLIL::S0);
polarity_builder.push_back(RTLIL::S0);
}
}
RTLIL::Const polarity = polarity_builder.build();
RTLIL::Cell *cell = current_module->addCell(cellname, ID($check));
set_src_attr(cell, ast);
for (auto &attr : ast->attributes) {
if (attr.second->type != AST_CONSTANT)
log_file_error(*ast->location.begin.filename, ast->location.begin.line, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
log_file_error(*ast->location.begin.filename, ast->location.begin.line, "Attribute `%s' with non-constant value!\n", attr.first);
cell->attributes[attr.first] = attr.second->asAttrConst();
}
cell->setParam(ID::FLAVOR, flavor);
@ -893,7 +895,7 @@ struct AST_INTERNAL::ProcessGenerator
RTLIL::Const priority_mask = RTLIL::Const(0, cur_idx);
for (int i = 0; i < portid; i++) {
int new_bit = port_map[std::make_pair(memid, i)];
priority_mask.bits()[new_bit] = orig_priority_mask[i];
priority_mask.set(new_bit, orig_priority_mask[i]);
}
action.priority_mask = priority_mask;
sync->mem_write_actions.push_back(action);
@ -1239,7 +1241,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
while (children[0]->simplify(true, 1, -1, false) == true) { }
if (children[0]->type != AST_CONSTANT)
input_error("System function %s called with non-const argument!\n",
RTLIL::unescape_id(str).c_str());
RTLIL::unescape_id(str));
width_hint = max(width_hint, int(children[0]->asInt(true)));
}
break;
@ -1289,7 +1291,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
while (right->simplify(true, 1, -1, false)) { }
if (left->type != AST_CONSTANT || right->type != AST_CONSTANT)
input_error("Function %s has non-constant width!",
RTLIL::unescape_id(str).c_str());
RTLIL::unescape_id(str));
result_width = abs(int(left->asInt(true) - right->asInt(true)));
}
width_hint = max(width_hint, result_width);
@ -1537,7 +1539,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
if (dynamic_cast<RTLIL::Binding*>(current_module)) {
/* nothing to do here */
} else if (flag_autowire)
log_file_warning(*location.begin.filename, location.begin.line, "Identifier `%s' is implicitly declared.\n", str.c_str());
log_file_warning(*location.begin.filename, location.begin.line, "Identifier `%s' is implicitly declared.\n", str);
else
input_error("Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str);
}
@ -2193,12 +2195,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
int sz = children.size();
if (str == "$info") {
if (sz > 0)
log_file_info(*location.begin.filename, location.begin.line, "%s.\n", children[0]->str.c_str());
log_file_info(*location.begin.filename, location.begin.line, "%s.\n", children[0]->str);
else
log_file_info(*location.begin.filename, location.begin.line, "\n");
} else if (str == "$warning") {
if (sz > 0)
log_file_warning(*location.begin.filename, location.begin.line, "%s.\n", children[0]->str.c_str());
log_file_warning(*location.begin.filename, location.begin.line, "%s.\n", children[0]->str);
else
log_file_warning(*location.begin.filename, location.begin.line, "\n");
} else if (str == "$error") {
@ -2235,12 +2237,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
if (GetSize(children) > 1)
input_error("System function %s got %d arguments, expected 1 or 0.\n",
RTLIL::unescape_id(str).c_str(), GetSize(children));
RTLIL::unescape_id(str), GetSize(children));
if (GetSize(children) == 1) {
if (children[0]->type != AST_CONSTANT)
input_error("System function %s called with non-const argument!\n",
RTLIL::unescape_id(str).c_str());
RTLIL::unescape_id(str));
width = children[0]->asInt(true);
}

View File

@ -161,10 +161,10 @@ Fmt AstNode::processFormat(int stage, bool sformat_like, int default_base, size_
arg.sig = node_arg->bitsAsConst();
arg.signed_ = node_arg->is_signed;
} else if (may_fail) {
log_file_info(*location.begin.filename, location.begin.line, "Skipping system task `%s' with non-constant argument at position %zu.\n", str.c_str(), index + 1);
log_file_info(*location.begin.filename, location.begin.line, "Skipping system task `%s' with non-constant argument at position %zu.\n", str, index + 1);
return Fmt();
} else {
log_file_error(*location.begin.filename, location.begin.line, "Failed to evaluate system task `%s' with non-constant argument at position %zu.\n", str.c_str(), index + 1);
log_file_error(*location.begin.filename, location.begin.line, "Failed to evaluate system task `%s' with non-constant argument at position %zu.\n", str, index + 1);
}
args.push_back(arg);
}
@ -974,7 +974,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
message += stringf("%s%s", first_element ? " See " : ", ", place);
first_element = false;
}
log_warning("%s\n", message.c_str());
log_warning("%s\n", message);
}
silent_activate:
@ -1032,7 +1032,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
// note that $display, $finish, and $stop are used for synthesis-time DRC so they're not in this list
if ((type == AST_FCALL || type == AST_TCALL) && (str == "$strobe" || str == "$monitor" || str == "$time" ||
str == "$dumpfile" || str == "$dumpvars" || str == "$dumpon" || str == "$dumpoff" || str == "$dumpall")) {
log_file_warning(*location.begin.filename, location.begin.line, "Ignoring call to system %s %s.\n", type == AST_FCALL ? "function" : "task", str.c_str());
log_file_warning(*location.begin.filename, location.begin.line, "Ignoring call to system %s %s.\n", type == AST_FCALL ? "function" : "task", str);
delete_children();
str = std::string();
}
@ -1042,7 +1042,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
str == "$write" || str == "$writeb" || str == "$writeh" || str == "$writeo"))
{
if (!current_always) {
log_file_warning(*location.begin.filename, location.begin.line, "System task `%s' outside initial or always block is unsupported.\n", str.c_str());
log_file_warning(*location.begin.filename, location.begin.line, "System task `%s' outside initial or always block is unsupported.\n", str);
delete_children();
str = std::string();
} else {
@ -1144,7 +1144,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
i--; // Adjust index since we removed an element
} else {
// If we can't find the package, just remove the import node to avoid errors later
log_warning("Package `%s' not found for import, removing import statement\n", child->str.c_str());
log_warning("Package `%s' not found for import, removing import statement\n", child->str);
children.erase(children.begin() + i);
i--; // Adjust index since we removed an element
}
@ -1438,7 +1438,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && children[0]->id2ast->is_logic)
children[0]->id2ast->is_reg = true; // if logic type is used in a block asignment
if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && !children[0]->id2ast->is_reg)
log_warning("wire '%s' is assigned in a block at %s.\n", children[0]->str.c_str(), loc_string().c_str());
log_warning("wire '%s' is assigned in a block at %s.\n", children[0]->str, loc_string());
if (type == AST_ASSIGN && children[0]->id2ast->is_reg) {
bool is_rand_reg = false;
if (children[1]->type == AST_FCALL) {
@ -1452,7 +1452,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
is_rand_reg = true;
}
if (!is_rand_reg)
log_warning("reg '%s' is assigned in a continuous assignment at %s.\n", children[0]->str.c_str(), loc_string().c_str());
log_warning("reg '%s' is assigned in a continuous assignment at %s.\n", children[0]->str, loc_string());
}
children[0]->was_checked = true;
}
@ -1915,7 +1915,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
if (current_scope.at(modname)->type != AST_CELL)
input_error("Defparam argument `%s . %s` does not match a cell!\n",
RTLIL::unescape_id(modname).c_str(), RTLIL::unescape_id(paramname).c_str());
RTLIL::unescape_id(modname), RTLIL::unescape_id(paramname));
auto paraset = std::make_unique<AstNode>(location, AST_PARASET, children[1]->clone(), GetSize(children) > 2 ? children[2]->clone() : nullptr);
paraset->str = paramname;
@ -2756,19 +2756,24 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
newNode = std::make_unique<AstNode>(location, AST_GENBLOCK);
int num = max(children.at(0)->range_left, children.at(0)->range_right) - min(children.at(0)->range_left, children.at(0)->range_right) + 1;
if (this->children.at(1)->type == AST_PRIMITIVE) {
// Move the range to the AST_PRIMITIVE node and replace this with the AST_PRIMITIVE node handled below
newNode = std::move(this->children.at(1));
newNode->range_left = this->children.at(0)->range_left;
newNode->range_right = this->children.at(0)->range_right;
newNode->range_valid = true;
goto apply_newNode;
}
for (int i = 0; i < num; i++) {
int idx = children.at(0)->range_left > children.at(0)->range_right ? children.at(0)->range_right + i : children.at(0)->range_right - i;
auto new_cell_owned = children.at(1)->clone();
auto* new_cell = new_cell_owned.get();
newNode->children.push_back(std::move(new_cell_owned));
new_cell->str += stringf("[%d]", idx);
if (new_cell->type == AST_PRIMITIVE) {
input_error("Cell arrays of primitives are currently not supported.\n");
} else {
this->dumpAst(NULL, " ");
log_assert(new_cell->children.at(0)->type == AST_CELLTYPE);
new_cell->children.at(0)->str = stringf("$array:%d:%d:%s", i, num, new_cell->children.at(0)->str);
}
log_assert(new_cell->children.at(0)->type == AST_CELLTYPE);
new_cell->children.at(0)->str = stringf("$array:%d:%d:%s", i, num, new_cell->children.at(0)->str);
}
goto apply_newNode;
@ -2789,6 +2794,11 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
}
children.clear();
// TODO handle bit-widths of primitives and support cell arrays for more primitives
if (range_valid && str != "tran")
input_error("Cell arrays of primitives are currently not supported.\n");
if (str == "bufif0" || str == "bufif1" || str == "notif0" || str == "notif1")
{
if (children_list.size() != 3)
@ -2817,7 +2827,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
fixup_hierarchy_flags();
did_something = true;
}
else if (str == "buf" || str == "not")
else if (str == "buf" || str == "not" || str == "tran")
{
auto& input = children_list.back();
if (str == "not")
@ -3394,11 +3404,11 @@ skip_dynamic_range_lvalue_expansion:;
if (GetSize(children) != 1 && GetSize(children) != 2)
input_error("System function %s got %d arguments, expected 1 or 2.\n",
RTLIL::unescape_id(str).c_str(), int(children.size()));
RTLIL::unescape_id(str), int(children.size()));
if (!current_always_clocked)
input_error("System function %s is only allowed in clocked blocks.\n",
RTLIL::unescape_id(str).c_str());
RTLIL::unescape_id(str));
if (GetSize(children) == 2)
{
@ -3469,11 +3479,11 @@ skip_dynamic_range_lvalue_expansion:;
{
if (GetSize(children) != 1)
input_error("System function %s got %d arguments, expected 1.\n",
RTLIL::unescape_id(str).c_str(), int(children.size()));
RTLIL::unescape_id(str), int(children.size()));
if (!current_always_clocked)
input_error("System function %s is only allowed in clocked blocks.\n",
RTLIL::unescape_id(str).c_str());
RTLIL::unescape_id(str));
auto present = children.at(0)->clone();
auto past = clone();
@ -3511,7 +3521,7 @@ skip_dynamic_range_lvalue_expansion:;
{
if (children.size() != 1)
input_error("System function %s got %d arguments, expected 1.\n",
RTLIL::unescape_id(str).c_str(), int(children.size()));
RTLIL::unescape_id(str), int(children.size()));
auto buf = children[0]->clone();
while (buf->simplify(true, stage, width_hint, sign_hint)) { }
@ -3538,11 +3548,11 @@ skip_dynamic_range_lvalue_expansion:;
if (str == "\\$dimensions" || str == "\\$unpacked_dimensions" || str == "\\$bits") {
if (children.size() != 1)
input_error("System function %s got %d arguments, expected 1.\n",
RTLIL::unescape_id(str).c_str(), int(children.size()));
RTLIL::unescape_id(str), int(children.size()));
} else {
if (children.size() != 1 && children.size() != 2)
input_error("System function %s got %d arguments, expected 1 or 2.\n",
RTLIL::unescape_id(str).c_str(), int(children.size()));
RTLIL::unescape_id(str), int(children.size()));
if (children.size() == 2) {
auto buf = children[1]->clone();
// Evaluate constant expression
@ -3634,18 +3644,18 @@ skip_dynamic_range_lvalue_expansion:;
if (func_with_two_arguments) {
if (children.size() != 2)
input_error("System function %s got %d arguments, expected 2.\n",
RTLIL::unescape_id(str).c_str(), int(children.size()));
RTLIL::unescape_id(str), int(children.size()));
} else {
if (children.size() != 1)
input_error("System function %s got %d arguments, expected 1.\n",
RTLIL::unescape_id(str).c_str(), int(children.size()));
RTLIL::unescape_id(str), int(children.size()));
}
if (children.size() >= 1) {
while (children[0]->simplify(true, stage, width_hint, sign_hint)) { }
if (!children[0]->isConst())
input_error("Failed to evaluate system function `%s' with non-constant argument.\n",
RTLIL::unescape_id(str).c_str());
RTLIL::unescape_id(str));
int child_width_hint = width_hint;
bool child_sign_hint = sign_hint;
children[0]->detectSignWidth(child_width_hint, child_sign_hint);
@ -3656,7 +3666,7 @@ skip_dynamic_range_lvalue_expansion:;
while (children[1]->simplify(true, stage, width_hint, sign_hint)) { }
if (!children[1]->isConst())
input_error("Failed to evaluate system function `%s' with non-constant argument.\n",
RTLIL::unescape_id(str).c_str());
RTLIL::unescape_id(str));
int child_width_hint = width_hint;
bool child_sign_hint = sign_hint;
children[1]->detectSignWidth(child_width_hint, child_sign_hint);
@ -3703,7 +3713,7 @@ skip_dynamic_range_lvalue_expansion:;
if (str == "\\$countbits") {
if (children.size() < 2)
input_error("System function %s got %d arguments, expected at least 2.\n",
RTLIL::unescape_id(str).c_str(), int(children.size()));
RTLIL::unescape_id(str), int(children.size()));
std::vector<RTLIL::State> control_bits;
@ -3760,7 +3770,7 @@ skip_dynamic_range_lvalue_expansion:;
if (str == "\\$countones" || str == "\\$isunknown" || str == "\\$onehot" || str == "\\$onehot0") {
if (children.size() != 1)
input_error("System function %s got %d arguments, expected 1.\n",
RTLIL::unescape_id(str).c_str(), int(children.size()));
RTLIL::unescape_id(str), int(children.size()));
auto countbits = clone();
countbits->str = "\\$countbits";
@ -3834,7 +3844,7 @@ skip_dynamic_range_lvalue_expansion:;
{
if (GetSize(children) < 2 || GetSize(children) > 4)
input_error("System function %s got %d arguments, expected 2-4.\n",
RTLIL::unescape_id(str).c_str(), int(children.size()));
RTLIL::unescape_id(str), int(children.size()));
auto node_filename = children[0]->clone();
while (node_filename->simplify(true, stage, width_hint, sign_hint)) { }
@ -4366,7 +4376,7 @@ replace_fcall_later:;
log_assert(a.size() == b.size());
for (auto i = 0; i < a.size(); i++)
if (a[i] != b[i])
a.bits()[i] = RTLIL::State::Sx;
a.set(i, RTLIL::State::Sx);
newNode = mkconst_bits(location, a.to_bits(), sign_hint);
} else if (children[1]->isConst() && children[2]->isConst()) {
newNode = std::make_unique<AstNode>(location, AST_REALVALUE);
@ -5368,8 +5378,11 @@ bool AstNode::replace_variables(std::map<std::string, AstNode::varinfo_t> &varia
offset -= variables.at(str).offset;
if (variables.at(str).range_swapped)
offset = -offset;
std::vector<RTLIL::State> &var_bits = variables.at(str).val.bits();
std::vector<RTLIL::State> new_bits(var_bits.begin() + offset, var_bits.begin() + offset + width);
const RTLIL::Const &val = variables.at(str).val;
std::vector<RTLIL::State> new_bits;
new_bits.reserve(width);
for (int i = 0; i < width; i++)
new_bits.push_back(val[offset+i]);
auto newNode = mkconst_bits(location, new_bits, variables.at(str).is_signed);
newNode->cloneInto(*this);
return true;
@ -5513,7 +5526,7 @@ std::unique_ptr<AstNode> AstNode::eval_const_function(AstNode *fcall, bool must_
int index = i + offset - v.offset;
if (v.range_swapped)
index = -index;
v.val.bits().at(index) = r.at(i);
v.val.set(index, r.at(i));
}
}

View File

@ -149,7 +149,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
if (buffer[0] == '.')
{
if (lutptr) {
for (auto &bit : lutptr->bits())
for (auto bit : *lutptr)
if (bit == RTLIL::State::Sx)
bit = lut_default_state;
lutptr = NULL;
@ -321,9 +321,10 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
const_v = Const(str);
} else {
int n = strlen(v);
const_v.bits().resize(n);
Const::Builder const_v_builder(n);
for (int i = 0; i < n; i++)
const_v.bits()[i] = v[n-i-1] != '0' ? State::S1 : State::S0;
const_v_builder.push_back(v[n-i-1] != '0' ? State::S1 : State::S0);
const_v = const_v_builder.build();
}
if (!strcmp(cmd, ".attr")) {
if (obj_attributes == nullptr) {
@ -563,21 +564,23 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
log_assert(sopcell->parameters[ID::WIDTH].as_int() == input_len);
sopcell->parameters[ID::DEPTH] = sopcell->parameters[ID::DEPTH].as_int() + 1;
Const::Builder table_bits_builder(input_len * 2);
for (int i = 0; i < input_len; i++)
switch (input[i]) {
case '0':
sopcell->parameters[ID::TABLE].bits().push_back(State::S1);
sopcell->parameters[ID::TABLE].bits().push_back(State::S0);
table_bits_builder.push_back(State::S1);
table_bits_builder.push_back(State::S0);
break;
case '1':
sopcell->parameters[ID::TABLE].bits().push_back(State::S0);
sopcell->parameters[ID::TABLE].bits().push_back(State::S1);
table_bits_builder.push_back(State::S0);
table_bits_builder.push_back(State::S1);
break;
default:
sopcell->parameters[ID::TABLE].bits().push_back(State::S0);
sopcell->parameters[ID::TABLE].bits().push_back(State::S0);
table_bits_builder.push_back(State::S0);
table_bits_builder.push_back(State::S0);
break;
}
sopcell->parameters[ID::TABLE].append(table_bits_builder.build());
if (sopmode == -1) {
sopmode = (*output == '1');
@ -605,7 +608,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
goto try_next_value;
}
}
lutptr->bits().at(i) = !strcmp(output, "0") ? RTLIL::State::S0 : RTLIL::State::S1;
lutptr->set(i, !strcmp(output, "0") ? RTLIL::State::S0 : RTLIL::State::S1);
try_next_value:;
}

View File

@ -258,7 +258,7 @@ Const json_parse_attr_param_value(JsonNode *node)
}
} else
if (node->type == 'N') {
value = Const(node->data_number, 32);
value = Const(node->data_number);
if (node->data_number < 0)
value.flags |= RTLIL::CONST_FLAG_SIGNED;
} else

View File

@ -537,7 +537,7 @@ struct LibertyFrontend : public Frontend {
if (flag_wb && flag_lib)
log_error("-wb and -lib cannot be specified together!\n");
log_header(design, "Executing Liberty frontend: %s\n", filename.c_str());
log_header(design, "Executing Liberty frontend: %s\n", filename);
LibertyParser parser(*f, filename);
int cell_count = 0;

View File

@ -91,9 +91,9 @@ struct RpcServer {
std::string error;
Json json_response = Json::parse(response, error);
if (json_response.is_null())
log_cmd_error("parsing JSON failed: %s\n", error.c_str());
log_cmd_error("parsing JSON failed: %s\n", error);
if (json_response["error"].is_string())
log_cmd_error("RPC frontend returned an error: %s\n", json_response["error"].string_value().c_str());
log_cmd_error("RPC frontend returned an error: %s\n", json_response["error"].string_value());
return json_response;
}
@ -111,7 +111,7 @@ struct RpcServer {
}
} else is_valid = false;
if (!is_valid)
log_cmd_error("RPC frontend returned malformed response: %s\n", response.dump().c_str());
log_cmd_error("RPC frontend returned malformed response: %s\n", response.dump());
return modules;
}
@ -149,7 +149,7 @@ struct RpcServer {
source = response["source"].string_value();
else is_valid = false;
if (!is_valid)
log_cmd_error("RPC frontend returned malformed response: %s\n", response.dump().c_str());
log_cmd_error("RPC frontend returned malformed response: %s\n", response.dump());
return std::make_pair(frontend, source);
}
};
@ -163,7 +163,7 @@ struct RpcModule : RTLIL::Module {
stripped_name = stripped_name.substr(9);
log_assert(stripped_name[0] == '\\');
log_header(design, "Executing RPC frontend `%s' for module `%s'.\n", server->name.c_str(), stripped_name.c_str());
log_header(design, "Executing RPC frontend `%s' for module `%s'.\n", server->name, stripped_name);
std::string parameter_info;
for (auto &param : parameters) {
@ -202,7 +202,7 @@ struct RpcModule : RTLIL::Module {
}
}
if (!found_derived_top)
log_cmd_error("RPC frontend did not return requested module `%s`!\n", stripped_name.c_str());
log_cmd_error("RPC frontend did not return requested module `%s`!\n", stripped_name);
for (auto module : derived_design->modules())
for (auto cell : module->cells())
@ -256,7 +256,7 @@ struct HandleRpcServer : RpcServer {
do {
DWORD data_written;
if (!WriteFile(hsend, &data[offset], data.length() - offset, &data_written, /*lpOverlapped=*/NULL))
log_cmd_error("WriteFile failed: %s\n", get_last_error_str().c_str());
log_cmd_error("WriteFile failed: %s\n", get_last_error_str());
offset += data_written;
} while(offset < (ssize_t)data.length());
}
@ -268,7 +268,7 @@ struct HandleRpcServer : RpcServer {
data.resize(data.length() + 1024);
DWORD data_read;
if (!ReadFile(hrecv, &data[offset], data.length() - offset, &data_read, /*lpOverlapped=*/NULL))
log_cmd_error("ReadFile failed: %s\n", get_last_error_str().c_str());
log_cmd_error("ReadFile failed: %s\n", get_last_error_str());
offset += data_read;
data.resize(offset);
size_t term_pos = data.find('\n', offset);

View File

@ -455,16 +455,17 @@ constant:
}
while ((int)bits.size() > width)
bits.pop_back();
$$ = new RTLIL::Const;
for (auto it = bits.begin(); it != bits.end(); it++)
$$->bits().push_back(*it);
RTLIL::Const::Builder builder(bits.size());
for (RTLIL::State bit : bits)
builder.push_back(bit);
$$ = new RTLIL::Const(builder.build());
if (is_signed) {
$$->flags |= RTLIL::CONST_FLAG_SIGNED;
}
free($1);
} |
TOK_INT {
$$ = new RTLIL::Const($1, 32);
$$ = new RTLIL::Const($1);
} |
TOK_STRING {
$$ = new RTLIL::Const($1);

View File

@ -154,7 +154,7 @@ void msg_func(msg_type_t msg_type, const char *message_id, linefile_type linefil
#endif
} else {
if (msg_type == VERIFIC_ERROR || msg_type == VERIFIC_WARNING || msg_type == VERIFIC_PROGRAM_ERROR)
log_warning_noprefix("%s%s\n", message_prefix.c_str(), message.c_str());
log_warning_noprefix("%s%s\n", message_prefix, message);
else
log("%s%s\n", message_prefix, message);
}
@ -284,13 +284,13 @@ static const RTLIL::Const extract_vhdl_bit_vector(std::string &val, std::string
static const RTLIL::Const extract_vhdl_integer(std::string &val)
{
char *end;
return RTLIL::Const((int)std::strtol(val.c_str(), &end, 10), 32);
return RTLIL::Const((int)std::strtol(val.c_str(), &end, 10));
}
static const RTLIL::Const extract_vhdl_char(std::string &val)
{
if (val.size()==3 && val[0]=='\"' && val.back()=='\"')
return RTLIL::Const((int)val[1], 32);
return RTLIL::Const((int)val[1]);
log_error("Error parsing VHDL character.\n");
}
@ -328,7 +328,7 @@ static const RTLIL::Const extract_vhdl_const(const char *value, bool output_sig
} else if ((value[0] == '-' || (value[0] >= '0' && value[0] <= '9')) &&
((decimal = std::strtol(value, &end, 10)), !end[0])) {
is_signed = output_signed;
c = RTLIL::Const((int)decimal, 32);
c = RTLIL::Const((int)decimal);
} else if (val == "false") {
c = RTLIL::Const::from_string("0");
} else if (val == "true") {
@ -361,7 +361,7 @@ static const RTLIL::Const extract_verilog_const(const char *value, bool allow_s
} else if ((value[0] == '-' || (value[0] >= '0' && value[0] <= '9')) &&
((decimal = std::strtol(value, &end, 10)), !end[0])) {
is_signed = output_signed;
c = RTLIL::Const((int)decimal, 32);
c = RTLIL::Const((int)decimal);
} else if (allow_string) {
c = RTLIL::Const(val);
} else {
@ -1541,7 +1541,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma
if (design->has(module_name)) {
if (!nl->IsOperator() && !is_blackbox(nl))
log_cmd_error("Re-definition of module `%s'.\n", netlist_name.c_str());
log_cmd_error("Re-definition of module `%s'.\n", netlist_name);
return;
}
@ -4052,7 +4052,7 @@ struct VerificPass : public Pass {
add_units_to_map(map, work, flag_lib);
std::string filename = frontent_rewrite(args, argidx, tmp_files);
if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_87))
log_cmd_error("Reading `%s' in VHDL_87 mode failed.\n", filename.c_str());
log_cmd_error("Reading `%s' in VHDL_87 mode failed.\n", filename);
set_units_to_blackbox(map, work, flag_lib);
}
verific_import_pending = true;
@ -4077,7 +4077,7 @@ struct VerificPass : public Pass {
add_units_to_map(map, work, flag_lib);
std::string filename = frontent_rewrite(args, argidx, tmp_files);
if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_93))
log_cmd_error("Reading `%s' in VHDL_93 mode failed.\n", filename.c_str());
log_cmd_error("Reading `%s' in VHDL_93 mode failed.\n", filename);
set_units_to_blackbox(map, work, flag_lib);
}
verific_import_pending = true;
@ -4102,7 +4102,7 @@ struct VerificPass : public Pass {
add_units_to_map(map, work, flag_lib);
std::string filename = frontent_rewrite(args, argidx, tmp_files);
if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_2K))
log_cmd_error("Reading `%s' in VHDL_2K mode failed.\n", filename.c_str());
log_cmd_error("Reading `%s' in VHDL_2K mode failed.\n", filename);
set_units_to_blackbox(map, work, flag_lib);
}
verific_import_pending = true;
@ -4127,7 +4127,7 @@ struct VerificPass : public Pass {
add_units_to_map(map, work, flag_lib);
std::string filename = frontent_rewrite(args, argidx, tmp_files);
if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_2019))
log_cmd_error("Reading `%s' in VHDL_2019 mode failed.\n", filename.c_str());
log_cmd_error("Reading `%s' in VHDL_2019 mode failed.\n", filename);
set_units_to_blackbox(map, work, flag_lib);
}
verific_import_pending = true;
@ -4152,7 +4152,7 @@ struct VerificPass : public Pass {
add_units_to_map(map, work, flag_lib);
std::string filename = frontent_rewrite(args, argidx, tmp_files);
if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_2008))
log_cmd_error("Reading `%s' in VHDL_2008 mode failed.\n", filename.c_str());
log_cmd_error("Reading `%s' in VHDL_2008 mode failed.\n", filename);
set_units_to_blackbox(map, work, flag_lib);
}
verific_import_pending = true;
@ -4166,7 +4166,7 @@ struct VerificPass : public Pass {
while (argidx < GetSize(args)) {
std::string filename = frontent_rewrite(args, argidx, tmp_files);
if (!edif.Read(filename.c_str()))
log_cmd_error("Reading `%s' in EDIF mode failed.\n", filename.c_str());
log_cmd_error("Reading `%s' in EDIF mode failed.\n", filename);
}
goto check_error;
}
@ -4189,7 +4189,7 @@ struct VerificPass : public Pass {
while (argidx < GetSize(args)) {
std::string filename = frontent_rewrite(args, argidx, tmp_files);
if (!synlib_file::Read(filename.c_str(), is_work_set ? work.c_str() : nullptr))
log_cmd_error("Reading `%s' in LIBERTY mode failed.\n", filename.c_str());
log_cmd_error("Reading `%s' in LIBERTY mode failed.\n", filename);
SynlibLibrary *lib = synlib_file::GetLastLibraryAnalyzed();
if (lib && flag_lib) {
MapIter mi ;
@ -4326,7 +4326,7 @@ struct VerificPass : public Pass {
unsigned new_insertion = parameters.Insert(key.c_str(), value.c_str(),
1 /* force_overwrite */);
if (!new_insertion)
log_warning_noprefix("-chparam %s already specified: overwriting.\n", key.c_str());
log_warning_noprefix("-chparam %s already specified: overwriting.\n", key);
continue;
}
if (args[argidx] == "-V") {

View File

@ -1025,7 +1025,7 @@ struct VerificSvaImporter
{
if (!importer->mode_keep)
log_error("%s", errmsg);
log_warning("%s", errmsg.c_str());
log_warning("%s", errmsg);
throw ParserErrorException();
}

View File

@ -45,11 +45,11 @@ using namespace AST;
using namespace VERILOG_FRONTEND;
void ConstParser::log_maybe_loc_error(std::string msg) {
log_file_error(*loc.begin.filename, loc.begin.line, "%s", msg.c_str());
log_file_error(*loc.begin.filename, loc.begin.line, "%s", msg);
}
void ConstParser::log_maybe_loc_warn(std::string msg) {
log_file_warning(*loc.begin.filename, loc.begin.line, "%s", msg.c_str());
log_file_warning(*loc.begin.filename, loc.begin.line, "%s", msg);
}
// divide an arbitrary length decimal number by two and return the rest

View File

@ -741,7 +741,7 @@ read_define(const std::string &filename,
defines_map.add(name, value, (state == 2) ? &args : nullptr);
global_defines_cache.add(name, value, (state == 2) ? &args : nullptr);
} else {
log_file_error(filename, 0, "Invalid name for macro definition: >>%s<<.\n", name.c_str());
log_file_error(filename, 0, "Invalid name for macro definition: >>%s<<.\n", name);
}
}

View File

@ -485,7 +485,7 @@ struct VerilogFrontend : public Frontend {
extra_args(f, filename, args, argidx);
log_header(design, "Executing Verilog-2005 frontend: %s\n", filename.c_str());
log_header(design, "Executing Verilog-2005 frontend: %s\n", filename);
log("Parsing %s%s input from `%s' to AST representation.\n",
parse_mode.formal ? "formal " : "", parse_mode.sv ? "SystemVerilog" : "Verilog", filename.c_str());

View File

@ -493,7 +493,7 @@ TIME_SCALE_SUFFIX [munpf]?s
\"{3}(\"{0,2}([^\\"]|\\.|\\\n))*\"{3} { return process_str(yytext + 3, yyleng - 6, true, out_loc); }
and|nand|or|nor|xor|xnor|not|buf|bufif0|bufif1|notif0|notif1 {
and|nand|or|nor|xor|xnor|not|buf|bufif0|bufif1|notif0|notif1|tran {
auto val = std::make_unique<std::string>(YYText());
return parser::make_TOK_PRIMITIVE(std::move(val), out_loc);
}

View File

@ -100,7 +100,7 @@ struct BitPatternPool
bits_t sig2bits(RTLIL::SigSpec sig)
{
bits_t bits;
bits.bitdata = sig.as_const().bits();
bits.bitdata = sig.as_const().to_bits();
for (auto &b : bits.bitdata)
if (b > RTLIL::State::S1)
b = RTLIL::State::Sa;

View File

@ -33,10 +33,7 @@ static void extend_u0(RTLIL::Const &arg, int width, bool is_signed)
if (arg.size() > 0 && is_signed)
padding = arg.back();
while (GetSize(arg) < width)
arg.bits().push_back(padding);
arg.bits().resize(width);
arg.resize(width, padding);
}
static BigInteger const2big(const RTLIL::Const &val, bool as_signed, int &undef_bit_pos)
@ -79,12 +76,12 @@ static RTLIL::Const big2const(const BigInteger &val, int result_len, int undef_b
{
mag--;
for (auto i = 0; i < result_len; i++)
result.bits()[i] = mag.getBit(i) ? RTLIL::State::S0 : RTLIL::State::S1;
result.set(i, mag.getBit(i) ? RTLIL::State::S0 : RTLIL::State::S1);
}
else
{
for (auto i = 0; i < result_len; i++)
result.bits()[i] = mag.getBit(i) ? RTLIL::State::S1 : RTLIL::State::S0;
result.set(i, mag.getBit(i) ? RTLIL::State::S1 : RTLIL::State::S0);
}
}
@ -140,11 +137,11 @@ RTLIL::Const RTLIL::const_not(const RTLIL::Const &arg1, const RTLIL::Const&, boo
RTLIL::Const result(RTLIL::State::Sx, result_len);
for (auto i = 0; i < result_len; i++) {
if (i >= GetSize(arg1_ext))
result.bits()[i] = RTLIL::State::S0;
else if (arg1_ext.bits()[i] == RTLIL::State::S0)
result.bits()[i] = RTLIL::State::S1;
else if (arg1_ext.bits()[i] == RTLIL::State::S1)
result.bits()[i] = RTLIL::State::S0;
result.set(i, RTLIL::State::S0);
else if (arg1_ext[i] == RTLIL::State::S0)
result.set(i, RTLIL::State::S1);
else if (arg1_ext[i] == RTLIL::State::S1)
result.set(i, RTLIL::State::S0);
}
return result;
@ -161,9 +158,9 @@ static RTLIL::Const logic_wrapper(RTLIL::State(*logic_func)(RTLIL::State, RTLIL:
RTLIL::Const result(RTLIL::State::Sx, result_len);
for (auto i = 0; i < result_len; i++) {
RTLIL::State a = i < GetSize(arg1) ? arg1.bits()[i] : RTLIL::State::S0;
RTLIL::State b = i < GetSize(arg2) ? arg2.bits()[i] : RTLIL::State::S0;
result.bits()[i] = logic_func(a, b);
RTLIL::State a = i < GetSize(arg1) ? arg1[i] : RTLIL::State::S0;
RTLIL::State b = i < GetSize(arg2) ? arg2[i] : RTLIL::State::S0;
result.set(i, logic_func(a, b));
}
return result;
@ -197,8 +194,8 @@ static RTLIL::Const logic_reduce_wrapper(RTLIL::State initial, RTLIL::State(*log
temp = logic_func(temp, arg1[i]);
RTLIL::Const result(temp);
while (GetSize(result) < result_len)
result.bits().push_back(RTLIL::State::S0);
if (GetSize(result) < result_len)
result.resize(result_len, RTLIL::State::S0);
return result;
}
@ -222,9 +219,9 @@ RTLIL::Const RTLIL::const_reduce_xnor(const RTLIL::Const &arg1, const RTLIL::Con
RTLIL::Const buffer = logic_reduce_wrapper(RTLIL::State::S0, logic_xor, arg1, result_len);
if (!buffer.empty()) {
if (buffer.front() == RTLIL::State::S0)
buffer.bits().front() = RTLIL::State::S1;
buffer.set(0, RTLIL::State::S1);
else if (buffer.front() == RTLIL::State::S1)
buffer.bits().front() = RTLIL::State::S0;
buffer.set(0, RTLIL::State::S0);
}
return buffer;
}
@ -239,9 +236,8 @@ RTLIL::Const RTLIL::const_logic_not(const RTLIL::Const &arg1, const RTLIL::Const
int undef_bit_pos_a = -1;
BigInteger a = const2big(arg1, signed1, undef_bit_pos_a);
RTLIL::Const result(a.isZero() ? undef_bit_pos_a >= 0 ? RTLIL::State::Sx : RTLIL::State::S1 : RTLIL::State::S0);
while (GetSize(result) < result_len)
result.bits().push_back(RTLIL::State::S0);
if (GetSize(result) < result_len)
result.resize(result_len, RTLIL::State::S0);
return result;
}
@ -254,9 +250,8 @@ RTLIL::Const RTLIL::const_logic_and(const RTLIL::Const &arg1, const RTLIL::Const
RTLIL::State bit_a = a.isZero() ? undef_bit_pos_a >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1;
RTLIL::State bit_b = b.isZero() ? undef_bit_pos_b >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1;
RTLIL::Const result(logic_and(bit_a, bit_b));
while (GetSize(result) < result_len)
result.bits().push_back(RTLIL::State::S0);
if (GetSize(result) < result_len)
result.resize(result_len, RTLIL::State::S0);
return result;
}
@ -269,9 +264,8 @@ RTLIL::Const RTLIL::const_logic_or(const RTLIL::Const &arg1, const RTLIL::Const
RTLIL::State bit_a = a.isZero() ? undef_bit_pos_a >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1;
RTLIL::State bit_b = b.isZero() ? undef_bit_pos_b >= 0 ? RTLIL::State::Sx : RTLIL::State::S0 : RTLIL::State::S1;
RTLIL::Const result(logic_or(bit_a, bit_b));
while (GetSize(result) < result_len)
result.bits().push_back(RTLIL::State::S0);
if (GetSize(result) < result_len)
result.resize(result_len, RTLIL::State::S0);
return result;
}
@ -295,11 +289,11 @@ static RTLIL::Const const_shift_worker(const RTLIL::Const &arg1, const RTLIL::Co
for (int i = 0; i < result_len; i++) {
BigInteger pos = BigInteger(i) + offset;
if (pos < 0)
result.bits()[i] = vacant_bits;
result.set(i, vacant_bits);
else if (pos >= BigInteger(GetSize(arg1)))
result.bits()[i] = sign_ext ? arg1.back() : vacant_bits;
result.set(i, sign_ext ? arg1.back() : vacant_bits);
else
result.bits()[i] = arg1[pos.toInt()];
result.set(i, arg1[pos.toInt()]);
}
return result;
@ -346,9 +340,8 @@ RTLIL::Const RTLIL::const_lt(const RTLIL::Const &arg1, const RTLIL::Const &arg2,
int undef_bit_pos = -1;
bool y = const2big(arg1, signed1, undef_bit_pos) < const2big(arg2, signed2, undef_bit_pos);
RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0);
while (GetSize(result) < result_len)
result.bits().push_back(RTLIL::State::S0);
if (GetSize(result) < result_len)
result.resize(result_len, RTLIL::State::S0);
return result;
}
@ -357,9 +350,8 @@ RTLIL::Const RTLIL::const_le(const RTLIL::Const &arg1, const RTLIL::Const &arg2,
int undef_bit_pos = -1;
bool y = const2big(arg1, signed1, undef_bit_pos) <= const2big(arg2, signed2, undef_bit_pos);
RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0);
while (GetSize(result) < result_len)
result.bits().push_back(RTLIL::State::S0);
if (GetSize(result) < result_len)
result.resize(result_len, RTLIL::State::S0);
return result;
}
@ -383,7 +375,7 @@ RTLIL::Const RTLIL::const_eq(const RTLIL::Const &arg1, const RTLIL::Const &arg2,
matched_status = RTLIL::State::Sx;
}
result.bits().front() = matched_status;
result.set(0, matched_status);
return result;
}
@ -391,9 +383,9 @@ RTLIL::Const RTLIL::const_ne(const RTLIL::Const &arg1, const RTLIL::Const &arg2,
{
RTLIL::Const result = RTLIL::const_eq(arg1, arg2, signed1, signed2, result_len);
if (result.front() == RTLIL::State::S0)
result.bits().front() = RTLIL::State::S1;
result.set(0, RTLIL::State::S1);
else if (result.front() == RTLIL::State::S1)
result.bits().front() = RTLIL::State::S0;
result.set(0, RTLIL::State::S0);
return result;
}
@ -412,7 +404,7 @@ RTLIL::Const RTLIL::const_eqx(const RTLIL::Const &arg1, const RTLIL::Const &arg2
return result;
}
result.bits().front() = RTLIL::State::S1;
result.set(0, RTLIL::State::S1);
return result;
}
@ -420,9 +412,9 @@ RTLIL::Const RTLIL::const_nex(const RTLIL::Const &arg1, const RTLIL::Const &arg2
{
RTLIL::Const result = RTLIL::const_eqx(arg1, arg2, signed1, signed2, result_len);
if (result.front() == RTLIL::State::S0)
result.bits().front() = RTLIL::State::S1;
result.set(0, RTLIL::State::S1);
else if (result.front() == RTLIL::State::S1)
result.bits().front() = RTLIL::State::S0;
result.set(0, RTLIL::State::S0);
return result;
}
@ -431,9 +423,8 @@ RTLIL::Const RTLIL::const_ge(const RTLIL::Const &arg1, const RTLIL::Const &arg2,
int undef_bit_pos = -1;
bool y = const2big(arg1, signed1, undef_bit_pos) >= const2big(arg2, signed2, undef_bit_pos);
RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0);
while (GetSize(result) < result_len)
result.bits().push_back(RTLIL::State::S0);
if (GetSize(result) < result_len)
result.resize(result_len, RTLIL::State::S0);
return result;
}
@ -442,9 +433,8 @@ RTLIL::Const RTLIL::const_gt(const RTLIL::Const &arg1, const RTLIL::Const &arg2,
int undef_bit_pos = -1;
bool y = const2big(arg1, signed1, undef_bit_pos) > const2big(arg2, signed2, undef_bit_pos);
RTLIL::Const result(undef_bit_pos >= 0 ? RTLIL::State::Sx : y ? RTLIL::State::S1 : RTLIL::State::S0);
while (GetSize(result) < result_len)
result.bits().push_back(RTLIL::State::S0);
if (GetSize(result) < result_len)
result.resize(result_len, RTLIL::State::S0);
return result;
}
@ -628,7 +618,7 @@ RTLIL::Const RTLIL::const_mux(const RTLIL::Const &arg1, const RTLIL::Const &arg2
RTLIL::Const ret = arg1;
for (auto i = 0; i < ret.size(); i++)
if (ret[i] != arg2[i])
ret.bits()[i] = State::Sx;
ret.set(i, State::Sx);
return ret;
}
@ -703,7 +693,7 @@ RTLIL::Const RTLIL::const_bweqx(const RTLIL::Const &arg1, const RTLIL::Const &ar
log_assert(arg2.size() == arg1.size());
RTLIL::Const result(RTLIL::State::S0, arg1.size());
for (auto i = 0; i < arg1.size(); i++)
result.bits()[i] = arg1[i] == arg2[i] ? State::S1 : State::S0;
result.set(i, arg1[i] == arg2[i] ? State::S1 : State::S0);
return result;
}
@ -715,7 +705,7 @@ RTLIL::Const RTLIL::const_bwmux(const RTLIL::Const &arg1, const RTLIL::Const &ar
RTLIL::Const result(RTLIL::State::Sx, arg1.size());
for (auto i = 0; i < arg1.size(); i++) {
if (arg3[i] != State::Sx || arg1[i] == arg2[i])
result.bits()[i] = arg3[i] == State::S1 ? arg2[i] : arg1[i];
result.set(i, arg3[i] == State::S1 ? arg2[i] : arg1[i]);
}
return result;

View File

@ -447,7 +447,7 @@ bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL
return true;
}
if (RTLIL::builtin_ff_cell_types().count(cell->type)) {
if (cell->is_builtin_ff()) {
ff_op(this, cell);
return true;
}

View File

@ -111,6 +111,8 @@ struct CellTypes
setup_type(ID($original_tag), {ID::A}, {ID::Y});
setup_type(ID($future_ff), {ID::A}, {ID::Y});
setup_type(ID($scopeinfo), {}, {});
setup_type(ID($input_port), {}, {ID::Y});
setup_type(ID($connect), {ID::A, ID::B}, {});
}
void setup_internals_eval()
@ -320,6 +322,16 @@ struct CellTypes
return it != cell_types.end() && it->second.inputs.count(port) != 0;
}
RTLIL::PortDir cell_port_dir(RTLIL::IdString type, RTLIL::IdString port) const
{
auto it = cell_types.find(type);
if (it == cell_types.end())
return RTLIL::PD_UNKNOWN;
bool is_input = it->second.inputs.count(port);
bool is_output = it->second.outputs.count(port);
return RTLIL::PortDir(is_input + is_output * 2);
}
bool cell_evaluable(const RTLIL::IdString &type) const
{
auto it = cell_types.find(type);
@ -328,7 +340,7 @@ struct CellTypes
static RTLIL::Const eval_not(RTLIL::Const v)
{
for (auto &bit : v.bits())
for (auto bit : v)
if (bit == State::S0) bit = State::S1;
else if (bit == State::S1) bit = State::S0;
return v;
@ -421,16 +433,14 @@ struct CellTypes
static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool *errp = nullptr)
{
if (cell->type == ID($slice)) {
RTLIL::Const ret;
int width = cell->parameters.at(ID::Y_WIDTH).as_int();
int offset = cell->parameters.at(ID::OFFSET).as_int();
ret.bits().insert(ret.bits().end(), arg1.begin()+offset, arg1.begin()+offset+width);
return ret;
return arg1.extract(offset, width);
}
if (cell->type == ID($concat)) {
RTLIL::Const ret = arg1;
ret.bits().insert(ret.bits().end(), arg2.begin(), arg2.end());
ret.append(arg2);
return ret;
}

View File

@ -115,7 +115,7 @@ struct ConstEval
for (int i = 0; i < GetSize(coval); i++) {
carry = (sig_g[i] == State::S1) || (sig_p[i] == RTLIL::S1 && carry);
coval.bits()[i] = carry ? State::S1 : State::S0;
coval.set(i, carry ? State::S1 : State::S0);
}
set(sig_co, coval);
@ -249,7 +249,7 @@ struct ConstEval
for (int i = 0; i < GetSize(val_y); i++)
if (val_y[i] == RTLIL::Sx)
val_x.bits()[i] = RTLIL::Sx;
val_x.set(i, RTLIL::Sx);
set(sig_y, val_y);
set(sig_x, val_x);

View File

@ -152,7 +152,7 @@ unsigned int CellCosts::get(RTLIL::Cell *cell)
if (design_ && design_->module(cell->type) && cell->parameters.empty()) {
log_debug("%s is a module, recurse\n", cell->name.c_str());
return get(design_->module(cell->type));
} else if (RTLIL::builtin_ff_cell_types().count(cell->type)) {
} else if (cell->is_builtin_ff()) {
log_assert(cell->hasPort(ID::Q) && "Weird flip flop");
log_debug("%s is ff\n", cell->name.c_str());
return cell->getParam(ID::WIDTH).as_int();

View File

@ -260,7 +260,7 @@ bool DriveChunkMultiple::try_append(DriveBitMultiple const &bit)
switch (single.type())
{
case DriveType::CONSTANT: {
single.constant().bits().push_back(constant);
single.constant().append(RTLIL::Const(constant));
} break;
case DriveType::WIRE: {
single.wire().width += 1;
@ -295,8 +295,7 @@ bool DriveChunkMultiple::try_append(DriveChunkMultiple const &chunk)
switch (single.type())
{
case DriveType::CONSTANT: {
auto &bits = single.constant().bits();
bits.insert(bits.end(), constant.bits().begin(), constant.bits().end());
single.constant().append(constant);
} break;
case DriveType::WIRE: {
single.wire().width += width;
@ -349,7 +348,7 @@ bool DriveChunk::try_append(DriveBit const &bit)
none_ += 1;
return true;
case DriveType::CONSTANT:
constant_.bits().push_back(bit.constant());
constant_.append(RTLIL::Const(bit.constant()));
return true;
case DriveType::WIRE:
return wire_.try_append(bit.wire());
@ -375,7 +374,7 @@ bool DriveChunk::try_append(DriveChunk const &chunk)
none_ += chunk.none_;
return true;
case DriveType::CONSTANT:
constant_.bits().insert(constant_.bits().end(), chunk.constant_.begin(), chunk.constant_.end());
constant_.append(chunk.constant_);
return true;
case DriveType::WIRE:
return wire_.try_append(chunk.wire());

View File

@ -287,6 +287,16 @@ FfData FfData::slice(const std::vector<int> &bits) {
res.pol_clr = pol_clr;
res.pol_set = pol_set;
res.attributes = attributes;
std::optional<Const::Builder> arst_bits;
if (has_arst)
arst_bits.emplace(bits.size());
std::optional<Const::Builder> srst_bits;
if (has_srst)
srst_bits.emplace(bits.size());
std::optional<Const::Builder> init_bits;
if (initvals)
init_bits.emplace(bits.size());
for (int i : bits) {
res.sig_q.append(sig_q[i]);
if (has_clk || has_gclk)
@ -298,12 +308,19 @@ FfData FfData::slice(const std::vector<int> &bits) {
res.sig_set.append(sig_set[i]);
}
if (has_arst)
res.val_arst.bits().push_back(val_arst[i]);
arst_bits->push_back(val_arst[i]);
if (has_srst)
res.val_srst.bits().push_back(val_srst[i]);
srst_bits->push_back(val_srst[i]);
if (initvals)
res.val_init.bits().push_back(val_init[i]);
init_bits->push_back(val_init[i]);
}
if (has_arst)
res.val_arst = arst_bits->build();
if (has_srst)
res.val_srst = srst_bits->build();
if (initvals)
res.val_init = init_bits->build();
res.width = GetSize(res.sig_q);
return res;
}
@ -688,10 +705,10 @@ void FfData::flip_rst_bits(const pool<int> &bits) {
for (auto bit: bits) {
if (has_arst)
val_arst.bits()[bit] = invert(val_arst[bit]);
val_arst.set(bit, invert(val_arst[bit]));
if (has_srst)
val_srst.bits()[bit] = invert(val_srst[bit]);
val_init.bits()[bit] = invert(val_init[bit]);
val_srst.set(bit, invert(val_srst[bit]));
val_init.set(bit, invert(val_init[bit]));
}
}
@ -760,7 +777,7 @@ void FfData::flip_bits(const pool<int> &bits) {
Const mask = Const(State::S0, width);
for (auto bit: bits)
mask.bits()[bit] = State::S1;
mask.set(bit, State::S1);
if (has_clk || has_gclk)
sig_d = module->Xor(NEW_ID4_SUFFIX("d"), sig_d, mask, false, attributes[ID::src].decode_string()); // SILIMATE: Improve the naming

View File

@ -74,10 +74,10 @@ struct FfInitVals
RTLIL::Const operator()(const RTLIL::SigSpec &sig) const
{
RTLIL::Const res;
RTLIL::Const::Builder res_bits(GetSize(sig));
for (auto bit : sig)
res.bits().push_back((*this)(bit));
return res;
res_bits.push_back((*this)(bit));
return res_bits.build();
}
void set_init(RTLIL::SigBit bit, RTLIL::State val)
@ -93,12 +93,12 @@ struct FfInitVals
initbits[mbit] = std::make_pair(val,abit);
auto it2 = abit.wire->attributes.find(ID::init);
if (it2 != abit.wire->attributes.end()) {
it2->second.bits()[abit.offset] = val;
it2->second.set(abit.offset, val);
if (it2->second.is_fully_undef())
abit.wire->attributes.erase(it2);
} else if (val != State::Sx) {
Const cval(State::Sx, GetSize(abit.wire));
cval.bits()[abit.offset] = val;
cval.set(abit.offset, val);
abit.wire->attributes[ID::init] = cval;
}
}

View File

@ -42,9 +42,9 @@ bool FfMergeHelper::find_output_ff(RTLIL::SigSpec sig, FfData &ff, pool<std::pai
ff.sig_d.append(bit);
ff.sig_clr.append(State::Sx);
ff.sig_set.append(State::Sx);
ff.val_init.bits().push_back(State::Sx);
ff.val_srst.bits().push_back(State::Sx);
ff.val_arst.bits().push_back(State::Sx);
ff.val_init.append(RTLIL::Const(State::Sx));
ff.val_srst.append(RTLIL::Const(State::Sx));
ff.val_arst.append(RTLIL::Const(State::Sx));
continue;
}
@ -147,9 +147,9 @@ bool FfMergeHelper::find_output_ff(RTLIL::SigSpec sig, FfData &ff, pool<std::pai
ff.sig_q.append(cur_ff.sig_q[idx]);
ff.sig_clr.append(ff.has_sr ? cur_ff.sig_clr[idx] : State::S0);
ff.sig_set.append(ff.has_sr ? cur_ff.sig_set[idx] : State::S0);
ff.val_arst.bits().push_back(ff.has_arst ? cur_ff.val_arst[idx] : State::Sx);
ff.val_srst.bits().push_back(ff.has_srst ? cur_ff.val_srst[idx] : State::Sx);
ff.val_init.bits().push_back(cur_ff.val_init[idx]);
ff.val_arst.append(RTLIL::Const(ff.has_arst ? cur_ff.val_arst[idx] : State::Sx));
ff.val_srst.append(RTLIL::Const(ff.has_srst ? cur_ff.val_srst[idx] : State::Sx));
ff.val_init.append(RTLIL::Const(cur_ff.val_init[idx]));
found = true;
}
@ -174,9 +174,9 @@ bool FfMergeHelper::find_input_ff(RTLIL::SigSpec sig, FfData &ff, pool<std::pair
// These two will be fixed up later.
ff.sig_clr.append(State::Sx);
ff.sig_set.append(State::Sx);
ff.val_init.bits().push_back(bit.data);
ff.val_srst.bits().push_back(bit.data);
ff.val_arst.bits().push_back(bit.data);
ff.val_init.append(RTLIL::Const(bit.data));
ff.val_srst.append(RTLIL::Const(bit.data));
ff.val_arst.append(RTLIL::Const(bit.data));
continue;
}
@ -274,9 +274,9 @@ bool FfMergeHelper::find_input_ff(RTLIL::SigSpec sig, FfData &ff, pool<std::pair
ff.sig_q.append(cur_ff.sig_q[idx]);
ff.sig_clr.append(ff.has_sr ? cur_ff.sig_clr[idx] : State::S0);
ff.sig_set.append(ff.has_sr ? cur_ff.sig_set[idx] : State::S0);
ff.val_arst.bits().push_back(ff.has_arst ? cur_ff.val_arst[idx] : State::Sx);
ff.val_srst.bits().push_back(ff.has_srst ? cur_ff.val_srst[idx] : State::Sx);
ff.val_init.bits().push_back(cur_ff.val_init[idx]);
ff.val_arst.append(RTLIL::Const(ff.has_arst ? cur_ff.val_arst[idx] : State::Sx));
ff.val_srst.append(RTLIL::Const(ff.has_srst ? cur_ff.val_srst[idx] : State::Sx));
ff.val_init.append(RTLIL::Const(cur_ff.val_init[idx]));
found = true;
}
@ -335,7 +335,7 @@ void FfMergeHelper::set(FfInitVals *initvals_, RTLIL::Module *module_)
}
for (auto cell : module->cells()) {
if (RTLIL::builtin_ff_cell_types().count(cell->type)) {
if (cell->is_builtin_ff()) {
if (cell->hasPort(ID::D)) {
SigSpec d = (*sigmap)(cell->getPort(ID::D));
for (int i = 0; i < GetSize(d); i++)

View File

@ -401,11 +401,11 @@ void Fmt::parse_verilog(const std::vector<VerilogFmtArg> &args, bool sformat_lik
part = {};
}
if (++i == fmt.size()) {
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1);
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name, fmtarg - args.begin() + 1);
}
if (++arg == args.end()) {
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with fewer arguments than the format specifiers in argument %zu require.\n", task_name.c_str(), fmtarg - args.begin() + 1);
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with fewer arguments than the format specifiers in argument %zu require.\n", task_name, fmtarg - args.begin() + 1);
}
part.sig = arg->sig;
part.signed_ = arg->signed_;
@ -420,7 +420,7 @@ void Fmt::parse_verilog(const std::vector<VerilogFmtArg> &args, bool sformat_lik
} else break;
}
if (i == fmt.size()) {
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1);
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name, fmtarg - args.begin() + 1);
}
bool has_leading_zero = false, has_width = false;
@ -465,15 +465,15 @@ void Fmt::parse_verilog(const std::vector<VerilogFmtArg> &args, bool sformat_lik
if (!has_width && !has_leading_zero)
part.width = 20;
} else {
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with format character `%c' in argument %zu, but the argument is not $time or $realtime.\n", task_name.c_str(), fmt[i], fmtarg - args.begin() + 1);
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with format character `%c' in argument %zu, but the argument is not $time or $realtime.\n", task_name, fmt[i], fmtarg - args.begin() + 1);
}
} else {
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with unrecognized format character `%c' in argument %zu.\n", task_name.c_str(), fmt[i], fmtarg - args.begin() + 1);
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with unrecognized format character `%c' in argument %zu.\n", task_name, fmt[i], fmtarg - args.begin() + 1);
}
break;
}
if (i == fmt.size()) {
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1);
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name, fmtarg - args.begin() + 1);
}
if (part.padding == '\0') {
@ -486,7 +486,7 @@ void Fmt::parse_verilog(const std::vector<VerilogFmtArg> &args, bool sformat_lik
}
if (part.type == FmtPart::INTEGER && part.base != 10 && part.sign != FmtPart::MINUS)
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1);
log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name, fmtarg - args.begin() + 1);
if (part.base != 10)
part.signed_ = false;

View File

@ -605,7 +605,7 @@ private:
}
Node node = handle_memory(mem);
factory.update_pending(cell_outputs.at({cell, ID(RD_DATA)}), node);
} else if (RTLIL::builtin_ff_cell_types().count(cell->type)) {
} else if (cell->is_builtin_ff()) {
FfData ff(&ff_initvals, cell);
if (!ff.has_gclk)
log_error("The design contains a %s flip-flop at %s. This is not supported by the functional backend. "

View File

@ -103,11 +103,11 @@ gzip_istream::ibuf::~ibuf() {
// Never returns nullptr or failed state istream*
std::istream* uncompressed(const std::string filename, std::ios_base::openmode mode) {
if (!check_file_exists(filename))
log_cmd_error("File `%s' not found or is a directory\n", filename.c_str());
log_cmd_error("File `%s' not found or is a directory\n", filename);
std::ifstream* f = new std::ifstream();
f->open(filename, mode);
if (f->fail())
log_cmd_error("Can't open input file `%s' for reading: %s\n", filename.c_str(), strerror(errno));
log_cmd_error("Can't open input file `%s' for reading: %s\n", filename, strerror(errno));
// Check for gzip magic
unsigned char magic[3];
int n = 0;
@ -131,7 +131,7 @@ std::istream* uncompressed(const std::string filename, std::ios_base::openmode m
log_assert(ok && "Failed to open gzipped file.\n");
return s;
#else
log_cmd_error("File `%s' is a gzip file, but Yosys is compiled without zlib.\n", filename.c_str());
log_cmd_error("File `%s' is a gzip file, but Yosys is compiled without zlib.\n", filename);
#endif // YOSYS_ENABLE_ZLIB
} else {
f->clear();

View File

@ -169,8 +169,17 @@ struct hash_ops {
} else if constexpr (std::is_pointer_v<T>) {
return hash_ops<uintptr_t>::hash_into((uintptr_t) a, h);
} else if constexpr (std::is_same_v<T, std::string>) {
for (auto c : a)
h.hash32(c);
int size = a.size();
int i = 0;
while (i + 8 < size) {
uint64_t v;
memcpy(&v, a.data() + i, 8);
h.hash64(v);
i += 8;
}
uint64_t v = 0;
memcpy(&v, a.data() + i, size - i);
h.hash64(v);
return h;
} else {
return a.hash_into(h);

View File

@ -68,8 +68,6 @@ int log_debug_suppressed = 0;
vector<int> header_count;
vector<char*> log_id_cache;
vector<shared_str> string_buf;
int string_buf_index = -1;
static struct timeval initial_tv = { 0, 0 };
static bool next_print_log = false;
@ -189,7 +187,7 @@ static void logv_string(std::string_view format, std::string str) {
if (!linebuffer.empty() && linebuffer.back() == '\n') {
for (auto &re : log_warn_regexes)
if (std::regex_search(linebuffer, re))
log_warning("Found log message matching -W regex:\n%s", str.c_str());
log_warning("Found log message matching -W regex:\n%s", str);
for (auto &[_, item] : log_expect_log)
if (std::regex_search(linebuffer, item.pattern))
@ -447,8 +445,6 @@ void log_pop()
{
header_count.pop_back();
log_id_cache_clear();
string_buf.clear();
string_buf_index = -1;
log_flush();
}
@ -554,8 +550,6 @@ void log_reset_stack()
while (header_count.size() > 1)
header_count.pop_back();
log_id_cache_clear();
string_buf.clear();
string_buf_index = -1;
log_flush();
}
@ -580,38 +574,19 @@ void log_dump_val_worker(RTLIL::State v) {
log("%s", log_signal(v));
}
const char *log_signal(const RTLIL::SigSpec &sig, bool autoint)
std::string log_signal(const RTLIL::SigSpec &sig, bool autoint)
{
std::stringstream buf;
RTLIL_BACKEND::dump_sigspec(buf, sig, autoint);
if (string_buf.size() < 100) {
string_buf.push_back(buf.str());
return string_buf.back().c_str();
} else {
if (++string_buf_index == 100)
string_buf_index = 0;
string_buf[string_buf_index] = buf.str();
return string_buf[string_buf_index].c_str();
}
return buf.str();
}
const char *log_const(const RTLIL::Const &value, bool autoint)
std::string log_const(const RTLIL::Const &value, bool autoint)
{
if ((value.flags & RTLIL::CONST_FLAG_STRING) == 0)
return log_signal(value, autoint);
std::string str = "\"" + value.decode_string() + "\"";
if (string_buf.size() < 100) {
string_buf.push_back(str);
return string_buf.back().c_str();
} else {
if (++string_buf_index == 100)
string_buf_index = 0;
string_buf[string_buf_index] = str;
return string_buf[string_buf_index].c_str();
}
return "\"" + value.decode_string() + "\"";
}
const char *log_id(const RTLIL::IdString &str)
@ -729,7 +704,7 @@ dict<std::string, std::pair<std::string, int>> get_coverage_data()
for (auto &it : extra_coverage_data) {
if (coverage_data.count(it.first))
log_warning("found duplicate coverage id \"%s\".\n", it.first.c_str());
log_warning("found duplicate coverage id \"%s\".\n", it.first);
coverage_data[it.first].first = it.second.first;
coverage_data[it.first].second += it.second.second;
}

View File

@ -153,6 +153,11 @@ inline void log_warning(FmtString<TypeIdentity<Args>...> fmt, const Args &... ar
{
log_formatted_warning("Warning: ", fmt.format(args...));
}
inline void log_formatted_warning_noprefix(std::string str)
{
log_formatted_warning("", str);
}
template <typename... Args>
inline void log_warning_noprefix(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
{
@ -253,8 +258,8 @@ extern dict<std::string, LogExpectedItem> log_expect_log, log_expect_warning, lo
extern dict<std::string, LogExpectedItem> log_expect_prefix_log, log_expect_prefix_warning, log_expect_prefix_error;
void log_check_expected();
const char *log_signal(const RTLIL::SigSpec &sig, bool autoint = true);
const char *log_const(const RTLIL::Const &value, bool autoint = true);
std::string log_signal(const RTLIL::SigSpec &sig, bool autoint = true);
std::string log_const(const RTLIL::Const &value, bool autoint = true);
const char *log_id(const RTLIL::IdString &id);
template<typename T> static inline const char *log_id(T *obj, const char *nullstr = nullptr) {

View File

@ -262,7 +262,7 @@ struct Macc
bool eval(RTLIL::Const &result) const
{
for (auto &bit : result.bits())
for (auto bit : result)
bit = State::S0;
for (auto &port : terms)

View File

@ -131,9 +131,6 @@ void Mem::emit() {
cell->parameters[ID::WIDTH] = Const(width);
cell->parameters[ID::OFFSET] = Const(start_offset);
cell->parameters[ID::SIZE] = Const(size);
Const rd_wide_continuation, rd_clk_enable, rd_clk_polarity, rd_transparency_mask, rd_collision_x_mask;
Const wr_wide_continuation, wr_clk_enable, wr_clk_polarity, wr_priority_mask;
Const rd_ce_over_srst, rd_arst_value, rd_srst_value, rd_init_value;
SigSpec rd_clk, rd_en, rd_addr, rd_data;
SigSpec wr_clk, wr_en, wr_addr, wr_data;
SigSpec rd_arst, rd_srst;
@ -147,6 +144,15 @@ void Mem::emit() {
for (int i = 0; i < GetSize(wr_ports); i++)
for (int j = 0; j < (1 << wr_ports[i].wide_log2); j++)
wr_port_xlat.push_back(i);
Const::Builder rd_wide_continuation_builder;
Const::Builder rd_clk_enable_builder;
Const::Builder rd_clk_polarity_builder;
Const::Builder rd_transparency_mask_builder;
Const::Builder rd_collision_x_mask_builder;
Const::Builder rd_ce_over_srst_builder;
Const::Builder rd_arst_value_builder;
Const::Builder rd_srst_value_builder;
Const::Builder rd_init_value_builder;
for (auto &port : rd_ports) {
for (auto attr: port.attributes)
if (!cell->has_attribute(attr.first))
@ -157,10 +163,10 @@ void Mem::emit() {
}
for (int sub = 0; sub < (1 << port.wide_log2); sub++)
{
rd_wide_continuation.bits().push_back(State(sub != 0));
rd_clk_enable.bits().push_back(State(port.clk_enable));
rd_clk_polarity.bits().push_back(State(port.clk_polarity));
rd_ce_over_srst.bits().push_back(State(port.ce_over_srst));
rd_wide_continuation_builder.push_back(State(sub != 0));
rd_clk_enable_builder.push_back(State(port.clk_enable));
rd_clk_polarity_builder.push_back(State(port.clk_polarity));
rd_ce_over_srst_builder.push_back(State(port.ce_over_srst));
rd_clk.append(port.clk);
rd_arst.append(port.arst);
rd_srst.append(port.srst);
@ -170,18 +176,27 @@ void Mem::emit() {
rd_addr.append(addr);
log_assert(GetSize(addr) == abits);
for (auto idx : wr_port_xlat) {
rd_transparency_mask.bits().push_back(State(bool(port.transparency_mask[idx])));
rd_collision_x_mask.bits().push_back(State(bool(port.collision_x_mask[idx])));
rd_transparency_mask_builder.push_back(State(bool(port.transparency_mask[idx])));
rd_collision_x_mask_builder.push_back(State(bool(port.collision_x_mask[idx])));
}
}
rd_data.append(port.data);
for (auto bit : port.arst_value)
rd_arst_value.bits().push_back(bit);
rd_arst_value_builder.push_back(bit);
for (auto bit : port.srst_value)
rd_srst_value.bits().push_back(bit);
rd_srst_value_builder.push_back(bit);
for (auto bit : port.init_value)
rd_init_value.bits().push_back(bit);
rd_init_value_builder.push_back(bit);
}
Const rd_wide_continuation = rd_wide_continuation_builder.build();
Const rd_clk_enable = rd_clk_enable_builder.build();
Const rd_clk_polarity = rd_clk_polarity_builder.build();
Const rd_transparency_mask = rd_transparency_mask_builder.build();
Const rd_collision_x_mask = rd_collision_x_mask_builder.build();
Const rd_ce_over_srst = rd_ce_over_srst_builder.build();
Const rd_arst_value = rd_arst_value_builder.build();
Const rd_srst_value = rd_srst_value_builder.build();
Const rd_init_value = rd_init_value_builder.build();
if (rd_ports.empty()) {
rd_wide_continuation = State::S0;
rd_clk_enable = State::S0;
@ -212,6 +227,10 @@ void Mem::emit() {
cell->setPort(ID::RD_SRST, rd_srst);
cell->setPort(ID::RD_ADDR, rd_addr);
cell->setPort(ID::RD_DATA, rd_data);
Const::Builder wr_wide_continuation_builder;
Const::Builder wr_clk_enable_builder;
Const::Builder wr_clk_polarity_builder;
Const::Builder wr_priority_mask_builder;
for (auto &port : wr_ports) {
for (auto attr: port.attributes)
if (!cell->has_attribute(attr.first))
@ -222,12 +241,12 @@ void Mem::emit() {
}
for (int sub = 0; sub < (1 << port.wide_log2); sub++)
{
wr_wide_continuation.bits().push_back(State(sub != 0));
wr_clk_enable.bits().push_back(State(port.clk_enable));
wr_clk_polarity.bits().push_back(State(port.clk_polarity));
wr_wide_continuation_builder.push_back(State(sub != 0));
wr_clk_enable_builder.push_back(State(port.clk_enable));
wr_clk_polarity_builder.push_back(State(port.clk_polarity));
wr_clk.append(port.clk);
for (auto idx : wr_port_xlat)
wr_priority_mask.bits().push_back(State(bool(port.priority_mask[idx])));
wr_priority_mask_builder.push_back(State(bool(port.priority_mask[idx])));
SigSpec addr = port.sub_addr(sub);
addr.extend_u0(abits, false);
wr_addr.append(addr);
@ -236,6 +255,10 @@ void Mem::emit() {
wr_en.append(port.en);
wr_data.append(port.data);
}
Const wr_wide_continuation = wr_wide_continuation_builder.build();
Const wr_clk_enable = wr_clk_enable_builder.build();
Const wr_clk_polarity = wr_clk_polarity_builder.build();
Const wr_priority_mask = wr_priority_mask_builder.build();
if (wr_ports.empty()) {
wr_wide_continuation = State::S0;
wr_clk_enable = State::S0;
@ -414,7 +437,7 @@ void Mem::coalesce_inits() {
if (!init.en.is_fully_ones()) {
for (int i = 0; i < GetSize(init.data); i++)
if (init.en[i % width] != State::S1)
init.data.bits()[i] = State::Sx;
init.data.set(i, State::Sx);
init.en = Const(State::S1, width);
}
continue;
@ -427,7 +450,7 @@ void Mem::coalesce_inits() {
log_assert(offset + GetSize(init.data) <= GetSize(cdata));
for (int i = 0; i < GetSize(init.data); i++)
if (init.en[i % width] == State::S1)
cdata.bits()[i+offset] = init.data[i];
cdata.set(i+offset, init.data[i]);
init.removed = true;
}
MemInit new_init;
@ -446,7 +469,7 @@ Const Mem::get_init_data() const {
int offset = (init.addr.as_int() - start_offset) * width;
for (int i = 0; i < GetSize(init.data); i++)
if (0 <= i+offset && i+offset < GetSize(init_data) && init.en[i % width] == State::S1)
init_data.bits()[i+offset] = init.data[i];
init_data.set(i+offset, init.data[i]);
}
return init_data;
}
@ -1700,7 +1723,7 @@ MemContents::MemContents(Mem *mem) :
RTLIL::Const previous = (*this)[addr + i];
for(int j = 0; j < _data_width; j++)
if(init.en[j] != State::S1)
data.bits()[_data_width * i + j] = previous[j];
data.set(_data_width * i + j, previous[j]);
}
insert_concatenated(init.addr.as_int(), data);
}
@ -1846,7 +1869,7 @@ std::map<MemContents::addr_t, RTLIL::Const>::iterator MemContents::_reserve_rang
// we have two different ranges touching at either end, we need to merge them
auto upper_end = _range_end(upper_it);
// make range bigger (maybe reserve here instead of resize?)
lower_it->second.bits().resize(_range_offset(lower_it, upper_end), State::Sx);
lower_it->second.resize(_range_offset(lower_it, upper_end), State::Sx);
// copy only the data beyond our range
std::copy(_range_data(upper_it, end_addr), _range_data(upper_it, upper_end), _range_data(lower_it, end_addr));
// keep lower_it, but delete upper_it
@ -1854,16 +1877,16 @@ std::map<MemContents::addr_t, RTLIL::Const>::iterator MemContents::_reserve_rang
return lower_it;
} else if (lower_touch) {
// we have a range to the left, just make it bigger and delete any other that may exist.
lower_it->second.bits().resize(_range_offset(lower_it, end_addr), State::Sx);
lower_it->second.resize(_range_offset(lower_it, end_addr), State::Sx);
// keep lower_it and upper_it
_values.erase(std::next(lower_it), upper_it);
return lower_it;
} else if (upper_touch) {
// we have a range to the right, we need to expand it
// since we need to erase and reinsert to a new address, steal the data
RTLIL::Const data = std::move(upper_it->second);
// note that begin_addr is not in upper_it, otherwise the whole range covered check would have tripped
data.bits().insert(data.bits().begin(), (_range_begin(upper_it) - begin_addr) * _data_width, State::Sx);
RTLIL::Const data(State::Sx, (_range_begin(upper_it) - begin_addr) * _data_width);
data.append(std::move(upper_it->second));
// delete lower_it and upper_it, then reinsert
_values.erase(lower_it, std::next(upper_it));
return _values.emplace(begin_addr, std::move(data)).first;
@ -1886,7 +1909,7 @@ void MemContents::insert_concatenated(addr_t addr, RTLIL::Const const &values) {
std::fill(to_begin + values.size(), to_begin + words * _data_width, State::S0);
}
std::vector<State>::iterator MemContents::_range_write(std::vector<State>::iterator it, RTLIL::Const const &word) {
RTLIL::Const::iterator MemContents::_range_write(RTLIL::Const::iterator it, RTLIL::Const const &word) {
auto from_end = word.size() <= _data_width ? word.end() : word.begin() + _data_width;
auto to_end = std::copy(word.begin(), from_end, it);
auto it_next = std::next(it, _data_width);

View File

@ -255,11 +255,13 @@ private:
// return the offset the addr would have in the range at `it`
size_t _range_offset(std::map<addr_t, RTLIL::Const>::iterator it, addr_t addr) const { return (addr - it->first) * _data_width; }
// assuming _range_contains(it, addr), return an iterator pointing to the data at addr
std::vector<State>::iterator _range_data(std::map<addr_t, RTLIL::Const>::iterator it, addr_t addr) { return it->second.bits().begin() + _range_offset(it, addr); }
RTLIL::Const::iterator _range_data(std::map<addr_t, RTLIL::Const>::iterator it, addr_t addr) {
return RTLIL::Const::iterator(it->second, _range_offset(it, addr));
}
// internal version of reserve_range that returns an iterator to the range
std::map<addr_t, RTLIL::Const>::iterator _reserve_range(addr_t begin_addr, addr_t end_addr);
// write a single word at addr, return iterator to next word
std::vector<State>::iterator _range_write(std::vector<State>::iterator it, RTLIL::Const const &data);
RTLIL::Const::iterator _range_write(RTLIL::Const::iterator it, RTLIL::Const const &data);
public:
class range {
int _data_width;

View File

@ -199,7 +199,7 @@ void Pass::call(RTLIL::Design *design, std::string command)
while (!cmd_buf.empty() && (cmd_buf.back() == ' ' || cmd_buf.back() == '\t' ||
cmd_buf.back() == '\r' || cmd_buf.back() == '\n'))
cmd_buf.resize(cmd_buf.size()-1);
log_header(design, "Shell command: %s\n", cmd_buf.c_str());
log_header(design, "Shell command: %s\n", cmd_buf);
int retCode = run_command(cmd_buf);
if (retCode != 0)
log_cmd_error("Shell command returned error code %d.\n", retCode);
@ -262,7 +262,7 @@ void Pass::call(RTLIL::Design *design, std::vector<std::string> args)
}
if (pass_register.count(args[0]) == 0)
log_cmd_error("No such command: %s (type 'help' for a command overview)\n", args[0].c_str());
log_cmd_error("No such command: %s (type 'help' for a command overview)\n", args[0]);
if (pass_register[args[0]]->experimental_flag)
log_experimental(args[0]);
@ -521,7 +521,7 @@ void Frontend::frontend_call(RTLIL::Design *design, std::istream *f, std::string
if (args.size() == 0)
return;
if (frontend_register.count(args[0]) == 0)
log_cmd_error("No such frontend: %s\n", args[0].c_str());
log_cmd_error("No such frontend: %s\n", args[0]);
if (f != NULL) {
auto state = frontend_register[args[0]]->pre_execute();
@ -596,7 +596,7 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<st
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));
log_cmd_error("Can't open output file `%s' for writing: %s\n", filename, strerror(errno));
}
yosys_output_files.insert(filename);
f = gf;
@ -609,7 +609,7 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<st
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));
log_cmd_error("Can't open output file `%s' for writing: %s\n", filename, strerror(errno));
}
f = ff;
}
@ -641,7 +641,7 @@ void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string f
if (args.size() == 0)
return;
if (backend_register.count(args[0]) == 0)
log_cmd_error("No such backend: %s\n", args[0].c_str());
log_cmd_error("No such backend: %s\n", args[0]);
size_t orig_sel_stack_pos = design->selection_stack.size();
@ -956,13 +956,7 @@ struct HelpPass : public Pass {
auto name = it.first.str();
if (cell_help_messages.contains(name)) {
auto cell_help = cell_help_messages.get(name);
if (groups.count(cell_help.group) != 0) {
auto group_cells = &groups.at(cell_help.group);
group_cells->push_back(name);
} else {
auto group_cells = new vector<string>(1, name);
groups.emplace(cell_help.group, *group_cells);
}
groups[cell_help.group].emplace_back(name);
auto cell_pair = pair<SimHelper, CellType>(cell_help, it.second);
cells.emplace(name, cell_pair);
} else {
@ -972,7 +966,7 @@ struct HelpPass : public Pass {
}
for (auto &it : cell_help_messages.cell_help) {
if (cells.count(it.first) == 0) {
log_warning("Found cell model '%s' without matching cell type.\n", it.first.c_str());
log_warning("Found cell model '%s' without matching cell type.\n", it.first);
}
}

View File

@ -89,7 +89,7 @@ static_assert(check_well_known_id_order());
dict<std::string, std::string> RTLIL::constpad;
const pool<IdString> &RTLIL::builtin_ff_cell_types() {
static const pool<IdString> &builtin_ff_cell_types_internal() {
static const pool<IdString> res = {
ID($sr),
ID($ff),
@ -240,14 +240,28 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() {
return res;
}
const pool<IdString> &RTLIL::builtin_ff_cell_types() {
return builtin_ff_cell_types_internal();
}
#define check(condition) log_assert(condition && "malformed Const union")
Const::bitvectype& Const::get_bits() const {
const Const::bitvectype& Const::get_bits() const {
check(is_bits());
return *get_if_bits();
}
std::string& Const::get_str() const {
const std::string& Const::get_str() const {
check(is_str());
return *get_if_str();
}
Const::bitvectype& Const::get_bits() {
check(is_bits());
return *get_if_bits();
}
std::string& Const::get_str() {
check(is_str());
return *get_if_str();
}
@ -259,9 +273,34 @@ RTLIL::Const::Const(const std::string &str)
tag = backing_tag::string;
}
RTLIL::Const::Const(int val, int width)
RTLIL::Const::Const(long long val) // default width 32
{
flags = RTLIL::CONST_FLAG_NONE;
char bytes[] = {
(char)(val >> 24), (char)(val >> 16), (char)(val >> 8), (char)val
};
new ((void*)&str_) std::string(bytes, 4);
tag = backing_tag::string;
}
RTLIL::Const::Const(long long val, int width)
{
flags = RTLIL::CONST_FLAG_NONE;
if ((width & 7) == 0) {
new ((void*)&str_) std::string();
tag = backing_tag::string;
std::string& str = get_str();
int bytes = width >> 3;
signed char sign_byte = val < 0 ? -1 : 0;
str.resize(bytes, sign_byte);
bytes = std::min<int>(bytes, sizeof(val));
for (int i = 0; i < bytes; i++) {
str[str.size() - 1 - i] = val;
val = val >> 8;
}
return;
}
new ((void*)&bits_) bitvectype();
tag = backing_tag::bits;
bitvectype& bv = get_bits();
@ -365,6 +404,11 @@ bool RTLIL::Const::operator<(const RTLIL::Const &other) const
bool RTLIL::Const::operator ==(const RTLIL::Const &other) const
{
if (is_str() && other.is_str())
return get_str() == other.get_str();
if (is_bits() && other.is_bits())
return get_bits() == other.get_bits();
if (size() != other.size())
return false;
@ -380,9 +424,9 @@ bool RTLIL::Const::operator !=(const RTLIL::Const &other) const
return !(*this == other);
}
std::vector<RTLIL::State>& RTLIL::Const::bits()
std::vector<RTLIL::State>& RTLIL::Const::bits_internal()
{
bitvectorize();
bitvectorize_internal();
return get_bits();
}
@ -396,8 +440,14 @@ std::vector<RTLIL::State> RTLIL::Const::to_bits() const
bool RTLIL::Const::as_bool() const
{
bitvectorize();
bitvectype& bv = get_bits();
if (is_str()) {
for (char ch : get_str())
if (ch != 0)
return true;
return false;
}
const bitvectype& bv = get_bits();
for (size_t i = 0; i < bv.size(); i++)
if (bv[i] == State::S1)
return true;
@ -406,15 +456,25 @@ bool RTLIL::Const::as_bool() const
int RTLIL::Const::as_int(bool is_signed) const
{
bitvectorize();
bitvectype& bv = get_bits();
int32_t ret = 0;
for (size_t i = 0; i < bv.size() && i < 32; i++)
if (const std::string *s = get_if_str()) {
int size = GetSize(*s);
// Ignore any bytes after the first 4 since bits beyond 32 are truncated.
for (int i = std::min(4, size); i > 0; i--)
ret |= static_cast<unsigned char>((*s)[size - i]) << ((i - 1) * 8);
// If is_signed and the string is shorter than 4 bytes then apply sign extension.
if (is_signed && size > 0 && size < 4 && ((*s)[0] & 0x80))
ret |= UINT32_MAX << size*8;
return ret;
}
const bitvectype& bv = get_bits();
int significant_bits = std::min(GetSize(bv), 32);
for (int i = 0; i < significant_bits; i++)
if (bv[i] == State::S1)
ret |= 1 << i;
if (is_signed && bv.back() == State::S1)
for (size_t i = bv.size(); i < 32; i++)
ret |= 1 << i;
if (is_signed && significant_bits > 0 && significant_bits < 32 && bv.back() == State::S1 )
ret |= UINT32_MAX << significant_bits;
return ret;
}
@ -434,7 +494,7 @@ bool RTLIL::Const::convertible_to_int(bool is_signed) const
if (size == 32) {
if (is_signed)
return true;
return get_bits().at(31) != State::S1;
return back() != State::S1;
}
return false;
@ -455,7 +515,7 @@ int RTLIL::Const::as_int_saturating(bool is_signed) const
const auto min_size = get_min_size(is_signed);
log_assert(min_size > 0);
const auto neg = get_bits().at(min_size - 1);
const auto neg = (*this)[min_size - 1];
return neg ? std::numeric_limits<int>::min() : std::numeric_limits<int>::max();
}
return as_int(is_signed);
@ -488,7 +548,7 @@ int RTLIL::Const::get_min_size(bool is_signed) const
void RTLIL::Const::compress(bool is_signed)
{
auto idx = get_min_size(is_signed);
bits().erase(bits().begin() + idx, bits().end());
resize(idx, RTLIL::State::S0);
}
std::optional<int> RTLIL::Const::as_int_compress(bool is_signed) const
@ -498,18 +558,17 @@ std::optional<int> RTLIL::Const::as_int_compress(bool is_signed) const
std::string RTLIL::Const::as_string(const char* any) const
{
bitvectorize();
bitvectype& bv = get_bits();
int sz = size();
std::string ret;
ret.reserve(bv.size());
for (size_t i = bv.size(); i > 0; i--)
switch (bv[i-1]) {
case S0: ret += "0"; break;
case S1: ret += "1"; break;
case Sx: ret += "x"; break;
case Sz: ret += "z"; break;
ret.reserve(sz);
for (int i = sz - 1; i >= 0; --i)
switch ((*this)[i]) {
case S0: ret.push_back('0'); break;
case S1: ret.push_back('1'); break;
case Sx: ret.push_back('x'); break;
case Sz: ret.push_back('z'); break;
case Sa: ret += any; break;
case Sm: ret += "m"; break;
case Sm: ret.push_back('m'); break;
}
return ret;
}
@ -536,8 +595,7 @@ std::string RTLIL::Const::decode_string() const
if (auto str = get_if_str())
return *str;
bitvectorize();
bitvectype& bv = get_bits();
const bitvectype& bv = get_bits();
const int n = GetSize(bv);
const int n_over_8 = n / 8;
std::string s;
@ -585,7 +643,7 @@ bool RTLIL::Const::empty() const {
}
}
void RTLIL::Const::bitvectorize() const {
void RTLIL::Const::bitvectorize_internal() {
if (tag == backing_tag::bits)
return;
@ -611,26 +669,33 @@ void RTLIL::Const::bitvectorize() const {
}
void RTLIL::Const::append(const RTLIL::Const &other) {
bitvectorize();
bitvectorize_internal();
bitvectype& bv = get_bits();
bv.insert(bv.end(), other.begin(), other.end());
}
RTLIL::State RTLIL::Const::const_iterator::operator*() const {
if (auto bv = parent.get_if_bits())
if (auto bv = parent->get_if_bits())
return (*bv)[idx];
int char_idx = parent.get_str().size() - idx / 8 - 1;
bool bit = (parent.get_str()[char_idx] & (1 << (idx % 8)));
int char_idx = parent->get_str().size() - idx / 8 - 1;
bool bit = (parent->get_str()[char_idx] & (1 << (idx % 8)));
return bit ? State::S1 : State::S0;
}
bool RTLIL::Const::is_fully_zero() const
{
bitvectorize();
bitvectype& bv = get_bits();
cover("kernel.rtlil.const.is_fully_zero");
if (auto str = get_if_str()) {
for (char ch : *str)
if (ch != 0)
return false;
return true;
}
const bitvectype& bv = get_bits();
for (const auto &bit : bv)
if (bit != RTLIL::State::S0)
return false;
@ -640,10 +705,16 @@ bool RTLIL::Const::is_fully_zero() const
bool RTLIL::Const::is_fully_ones() const
{
bitvectorize();
bitvectype& bv = get_bits();
cover("kernel.rtlil.const.is_fully_ones");
if (auto str = get_if_str()) {
for (char ch : *str)
if (ch != (char)0xff)
return false;
return true;
}
const bitvectype& bv = get_bits();
for (const auto &bit : bv)
if (bit != RTLIL::State::S1)
return false;
@ -655,9 +726,10 @@ bool RTLIL::Const::is_fully_def() const
{
cover("kernel.rtlil.const.is_fully_def");
bitvectorize();
bitvectype& bv = get_bits();
if (is_str())
return true;
const bitvectype& bv = get_bits();
for (const auto &bit : bv)
if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1)
return false;
@ -669,9 +741,10 @@ bool RTLIL::Const::is_fully_undef() const
{
cover("kernel.rtlil.const.is_fully_undef");
bitvectorize();
bitvectype& bv = get_bits();
if (auto str = get_if_str())
return str->empty();
const bitvectype& bv = get_bits();
for (const auto &bit : bv)
if (bit != RTLIL::State::Sx && bit != RTLIL::State::Sz)
return false;
@ -683,9 +756,10 @@ bool RTLIL::Const::is_fully_undef_x_only() const
{
cover("kernel.rtlil.const.is_fully_undef_x_only");
bitvectorize();
bitvectype& bv = get_bits();
if (auto str = get_if_str())
return str->empty();
const bitvectype& bv = get_bits();
for (const auto &bit : bv)
if (bit != RTLIL::State::Sx)
return false;
@ -697,12 +771,10 @@ bool RTLIL::Const::is_onehot(int *pos) const
{
cover("kernel.rtlil.const.is_onehot");
bitvectorize();
bitvectype& bv = get_bits();
bool found = false;
for (int i = 0; i < GetSize(*this); i++) {
auto &bit = bv[i];
int size = GetSize(*this);
for (int i = 0; i < size; i++) {
State bit = (*this)[i];
if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1)
return false;
if (bit == RTLIL::State::S1) {
@ -716,6 +788,40 @@ bool RTLIL::Const::is_onehot(int *pos) const
return found;
}
Hasher RTLIL::Const::hash_into(Hasher h) const
{
if (auto str = get_if_str())
return hashlib::hash_ops<std::string>::hash_into(*str, h);
// If the bits are all 0/1, hash packed bits using the string hash.
// Otherwise hash the leading packed bits with the rest of the bits individually.
const bitvectype &bv = get_bits();
int size = GetSize(bv);
std::string packed;
int packed_size = (size + 7) >> 3;
packed.resize(packed_size, 0);
for (int bi = 0; bi < packed_size; ++bi) {
char ch = 0;
int end = std::min((bi + 1)*8, size);
for (int i = bi*8; i < end; ++i) {
RTLIL::State b = bv[i];
if (b > RTLIL::State::S1) {
// Hash the packed bits we've seen so far, plus the remaining bits.
h = hashlib::hash_ops<std::string>::hash_into(packed, h);
h = hashlib::hash_ops<char>::hash_into(ch, h);
for (; i < size; ++i) {
h = hashlib::hash_ops<RTLIL::State>::hash_into(bv[i], h);
}
h.eat(size);
return h;
}
ch |= static_cast<int>(b) << (i & 7);
}
packed[packed_size - 1 - bi] = ch;
}
return hashlib::hash_ops<std::string>::hash_into(packed, h);
}
RTLIL::Const RTLIL::Const::extract(int offset, int len, RTLIL::State padding) const {
bitvectype ret_bv;
ret_bv.reserve(len);
@ -2361,6 +2467,19 @@ namespace {
check_expected();
return;
}
if (cell->type.in(ID($input_port))) {
param(ID::WIDTH);
port(ID::Y, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type.in(ID($connect))) {
param(ID::WIDTH);
port(ID::A, param(ID::WIDTH));
port(ID::B, param(ID::WIDTH));
check_expected();
return;
}
/*
* Checklist for adding internal cell types
* ========================================
@ -2741,7 +2860,13 @@ void RTLIL::Module::remove(RTLIL::Cell *cell)
log_assert(cells_.count(cell->name) != 0);
log_assert(refcount_cells_ == 0);
cells_.erase(cell->name);
delete cell;
if (design && design->flagBufferedNormalized && buf_norm_cell_queue.count(cell)) {
cell->type.clear();
cell->name.clear();
pending_deleted_cells.insert(cell);
} else {
delete cell;
}
}
void RTLIL::Module::remove(RTLIL::Process *process)
@ -2932,6 +3057,14 @@ void RTLIL::Module::fixup_ports()
std::sort(all_ports.begin(), all_ports.end(), fixup_ports_compare);
if (design && design->flagBufferedNormalized) {
for (auto &w : wires_)
if (w.second->driverCell_ && w.second->driverCell_->type == ID($input_port))
buf_norm_wire_queue.insert(w.second);
buf_norm_wire_queue.insert(all_ports.begin(), all_ports.end());
}
ports.clear();
for (size_t i = 0; i < all_ports.size(); i++) {
ports.push_back(all_ports[i]->name);
@ -4097,190 +4230,7 @@ bool RTLIL::Cell::hasPort(const RTLIL::IdString& portname) const
return connections_.count(portname) != 0;
}
void RTLIL::Cell::unsetPort(const RTLIL::IdString& portname)
{
RTLIL::SigSpec signal;
auto conn_it = connections_.find(portname);
if (conn_it != connections_.end())
{
for (auto mon : module->monitors)
mon->notify_connect(this, conn_it->first, conn_it->second, signal);
if (module->design)
for (auto mon : module->design->monitors)
mon->notify_connect(this, conn_it->first, conn_it->second, signal);
if (yosys_xtrace) {
log("#X# Unconnect %s.%s.%s\n", log_id(this->module), log_id(this), log_id(portname));
log_backtrace("-X- ", yosys_xtrace-1);
}
connections_.erase(conn_it);
}
}
void RTLIL::Design::bufNormalize(bool enable)
{
if (!enable)
{
if (!flagBufferedNormalized)
return;
for (auto module : modules()) {
module->bufNormQueue.clear();
for (auto wire : module->wires()) {
wire->driverCell_ = nullptr;
wire->driverPort_ = IdString();
}
}
flagBufferedNormalized = false;
return;
}
if (!flagBufferedNormalized)
{
for (auto module : modules())
{
for (auto cell : module->cells())
for (auto &conn : cell->connections()) {
if (!cell->output(conn.first) || GetSize(conn.second) == 0)
continue;
if (conn.second.is_wire()) {
Wire *wire = conn.second.as_wire();
log_assert(wire->driverCell_ == nullptr);
wire->driverCell_ = cell;
wire->driverPort_ = conn.first;
} else {
pair<RTLIL::Cell*, RTLIL::IdString> key(cell, conn.first);
module->bufNormQueue.insert(key);
}
}
}
flagBufferedNormalized = true;
}
for (auto module : modules())
module->bufNormalize();
}
void RTLIL::Module::bufNormalize()
{
if (!design->flagBufferedNormalized)
return;
while (GetSize(bufNormQueue) || !connections_.empty())
{
pool<pair<RTLIL::Cell*, RTLIL::IdString>> queue;
bufNormQueue.swap(queue);
pool<Wire*> outWires;
for (auto &conn : connections())
for (auto &chunk : conn.first.chunks())
if (chunk.wire) outWires.insert(chunk.wire);
SigMap sigmap(this);
new_connections({});
Module *module = this; // SILIMATE: Improve the naming
for (auto &key : queue)
{
Cell *cell = key.first;
const IdString &portname = key.second;
const SigSpec &sig = cell->getPort(portname);
if (GetSize(sig) == 0) continue;
if (sig.is_wire()) {
Wire *wire = sig.as_wire();
if (wire->driverCell_) {
log_error("Conflict between %s %s in module %s\n",
log_id(cell), log_id(wire->driverCell_), log_id(this));
}
log_assert(wire->driverCell_ == nullptr);
wire->driverCell_ = cell;
wire->driverPort_ = portname;
continue;
}
for (auto &chunk : sig.chunks())
if (chunk.wire) outWires.insert(chunk.wire);
Wire *wire = addWire(NEW_ID2_SUFFIX(portname.str()), GetSize(sig)); // SILIMATE: Improve the naming
sigmap.add(sig, wire);
cell->setPort(portname, wire);
// FIXME: Move init attributes from old 'sig' to new 'wire'
}
for (auto wire : outWires)
{
SigSpec outsig = wire, insig = sigmap(wire);
for (int i = 0; i < GetSize(wire); i++)
if (insig[i] == outsig[i])
insig[i] = State::Sx;
addBuf(NEW_ID4_SUFFIX("buf"), insig, outsig); // SILIMATE: Improve the naming
}
}
}
void RTLIL::Cell::setPort(const RTLIL::IdString& portname, RTLIL::SigSpec signal)
{
auto r = connections_.insert(portname);
auto conn_it = r.first;
if (!r.second && conn_it->second == signal)
return;
for (auto mon : module->monitors)
mon->notify_connect(this, conn_it->first, conn_it->second, signal);
if (module->design)
for (auto mon : module->design->monitors)
mon->notify_connect(this, conn_it->first, conn_it->second, signal);
if (yosys_xtrace) {
log("#X# Connect %s.%s.%s = %s (%d)\n", log_id(this->module), log_id(this), log_id(portname), log_signal(signal), GetSize(signal));
log_backtrace("-X- ", yosys_xtrace-1);
}
while (module->design && module->design->flagBufferedNormalized && output(portname))
{
pair<RTLIL::Cell*, RTLIL::IdString> key(this, portname);
if (conn_it->second.is_wire()) {
Wire *w = conn_it->second.as_wire();
if (w->driverCell_ == this && w->driverPort_ == portname) {
w->driverCell_ = nullptr;
w->driverPort_ = IdString();
}
}
if (GetSize(signal) == 0) {
module->bufNormQueue.erase(key);
break;
}
if (!signal.is_wire()) {
module->bufNormQueue.insert(key);
break;
}
Wire *w = signal.as_wire();
if (w->driverCell_ != nullptr) {
pair<RTLIL::Cell*, RTLIL::IdString> other_key(w->driverCell_, w->driverPort_);
module->bufNormQueue.insert(other_key);
}
w->driverCell_ = this;
w->driverPort_ = portname;
module->bufNormQueue.erase(key);
break;
}
conn_it->second = std::move(signal);
}
// bufnorm
const RTLIL::SigSpec &RTLIL::Cell::getPort(const RTLIL::IdString& portname) const
{
@ -4325,6 +4275,22 @@ bool RTLIL::Cell::output(const RTLIL::IdString& portname) const
return false;
}
RTLIL::PortDir RTLIL::Cell::port_dir(const RTLIL::IdString& portname) const
{
if (yosys_celltypes.cell_known(type))
return yosys_celltypes.cell_port_dir(type, portname);
if (module && module->design) {
RTLIL::Module *m = module->design->module(type);
if (m == nullptr)
return PortDir::PD_UNKNOWN;
RTLIL::Wire *w = m->wire(portname);
if (w == nullptr)
return PortDir::PD_UNKNOWN;
return PortDir(w->port_input + w->port_output * 2);
}
return PortDir::PD_UNKNOWN;
}
bool RTLIL::Cell::hasParam(const RTLIL::IdString& paramname) const
{
return parameters.count(paramname) != 0;
@ -4454,6 +4420,10 @@ bool RTLIL::Cell::is_mem_cell() const
return type.in(ID($mem), ID($mem_v2)) || has_memid();
}
bool RTLIL::Cell::is_builtin_ff() const {
return builtin_ff_cell_types_internal().count(type) > 0;
}
RTLIL::SigChunk::SigChunk(const RTLIL::SigBit &bit)
{
wire = bit.wire;
@ -5479,6 +5449,15 @@ bool RTLIL::SigSpec::is_mostly_const() const
return (constbits > width_/2);
}
bool RTLIL::SigSpec::known_driver() const
{
pack();
for (auto &chunk : chunks_)
if (chunk.is_wire() && !chunk.wire->known_driver())
return false;
return true;
}
bool RTLIL::SigSpec::is_fully_const() const
{
cover("kernel.rtlil.sigspec.is_fully_const");
@ -5561,6 +5540,18 @@ bool RTLIL::SigSpec::has_const() const
return false;
}
bool RTLIL::SigSpec::has_const(State state) const
{
cover("kernel.rtlil.sigspec.has_const");
pack();
for (auto it = chunks_.begin(); it != chunks_.end(); it++)
if (it->width > 0 && it->wire == NULL && std::find(it->data.begin(), it->data.end(), state) != it->data.end())
return true;
return false;
}
bool RTLIL::SigSpec::has_marked_bits() const
{
cover("kernel.rtlil.sigspec.has_marked_bits");
@ -5943,7 +5934,11 @@ bool RTLIL::SigSpec::parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, R
}
}
return parse(sig, module, str);
if (!parse(sig, module, str))
return false;
if (sig.width_ > lhs.width_)
sig.remove(lhs.width_, sig.width_ - lhs.width_);
return true;
}
RTLIL::CaseRule::~CaseRule()

View File

@ -91,6 +91,13 @@ namespace RTLIL
STATIC_ID_END,
};
enum PortDir : unsigned char {
PD_UNKNOWN = 0,
PD_INPUT = 1,
PD_OUTPUT = 2,
PD_INOUT = 3
};
struct Const;
struct AttrObject;
struct NamedObject;
@ -557,6 +564,7 @@ template <> struct IDMacroHelper<-1> {
namespace RTLIL {
extern dict<std::string, std::string> constpad;
[[deprecated("Call cell->is_builtin_ff() instead")]]
const pool<IdString> &builtin_ff_cell_types();
static inline std::string escape_id(const std::string &str) {
@ -829,38 +837,61 @@ private:
using bitvectype = std::vector<RTLIL::State>;
enum class backing_tag: bool { bits, string };
// Do not access the union or tag even in Const methods unless necessary
mutable backing_tag tag;
backing_tag tag;
union {
mutable bitvectype bits_;
mutable std::string str_;
bitvectype bits_;
std::string str_;
};
// Use these private utilities instead
bool is_bits() const { return tag == backing_tag::bits; }
bool is_str() const { return tag == backing_tag::string; }
bitvectype* get_if_bits() const { return is_bits() ? &bits_ : NULL; }
std::string* get_if_str() const { return is_str() ? &str_ : NULL; }
bitvectype* get_if_bits() { return is_bits() ? &bits_ : NULL; }
std::string* get_if_str() { return is_str() ? &str_ : NULL; }
const bitvectype* get_if_bits() const { return is_bits() ? &bits_ : NULL; }
const std::string* get_if_str() const { return is_str() ? &str_ : NULL; }
bitvectype& get_bits();
std::string& get_str();
const bitvectype& get_bits() const;
const std::string& get_str() const;
std::vector<RTLIL::State>& bits_internal();
void bitvectorize_internal();
bitvectype& get_bits() const;
std::string& get_str() const;
public:
Const() : flags(RTLIL::CONST_FLAG_NONE), tag(backing_tag::bits), bits_(std::vector<RTLIL::State>()) {}
Const(const std::string &str);
Const(int val, int width = 32);
Const(long long val); // default width is 32
Const(long long val, int width);
Const(RTLIL::State bit, int width = 1);
Const(const std::vector<RTLIL::State> &bits) : flags(RTLIL::CONST_FLAG_NONE), tag(backing_tag::bits), bits_(bits) {}
Const(std::vector<RTLIL::State> bits) : flags(RTLIL::CONST_FLAG_NONE), tag(backing_tag::bits), bits_(std::move(bits)) {}
Const(const std::vector<bool> &bits);
Const(const RTLIL::Const &other);
Const(RTLIL::Const &&other);
RTLIL::Const &operator =(const RTLIL::Const &other);
~Const();
struct Builder
{
Builder() {}
Builder(int expected_width) { bits.reserve(expected_width); }
void push_back(RTLIL::State b) { bits.push_back(b); }
int size() const { return static_cast<int>(bits.size()); }
Const build() { return Const(std::move(bits)); }
private:
std::vector<RTLIL::State> bits;
};
bool operator <(const RTLIL::Const &other) const;
bool operator ==(const RTLIL::Const &other) const;
bool operator !=(const RTLIL::Const &other) const;
std::vector<RTLIL::State>& bits();
[[deprecated("Don't use direct access to the internal std::vector<State>, that's an implementation detail.")]]
std::vector<RTLIL::State>& bits() { return bits_internal(); }
[[deprecated("Don't call bitvectorize() directly, it's an implementation detail.")]]
void bitvectorize() const { const_cast<Const*>(this)->bitvectorize_internal(); }
bool as_bool() const;
// Convert the constant value to a C++ int.
@ -889,37 +920,42 @@ public:
std::string decode_string() const;
int size() const;
bool empty() const;
void bitvectorize() const;
void append(const RTLIL::Const &other);
void set(int i, RTLIL::State state) {
bits_internal()[i] = state;
}
void resize(int size, RTLIL::State fill) {
bits_internal().resize(size, fill);
}
class const_iterator {
private:
const Const& parent;
const Const* parent;
size_t idx;
public:
using iterator_category = std::input_iterator_tag;
using iterator_category = std::bidirectional_iterator_tag;
using value_type = State;
using difference_type = std::ptrdiff_t;
using pointer = const State*;
using reference = const State&;
const_iterator(const Const& c, size_t i) : parent(c), idx(i) {}
const_iterator(const Const& c, size_t i) : parent(&c), idx(i) {}
State operator*() const;
const_iterator& operator++() { ++idx; return *this; }
const_iterator& operator--() { --idx; return *this; }
const_iterator& operator++(int) { ++idx; return *this; }
const_iterator& operator--(int) { --idx; return *this; }
const_iterator operator++(int) { const_iterator result(*this); ++idx; return result; }
const_iterator operator--(int) { const_iterator result(*this); --idx; return result; }
const_iterator& operator+=(int i) { idx += i; return *this; }
const_iterator operator+(int add) {
return const_iterator(parent, idx + add);
return const_iterator(*parent, idx + add);
}
const_iterator operator-(int sub) {
return const_iterator(parent, idx - sub);
return const_iterator(*parent, idx - sub);
}
int operator-(const const_iterator& other) {
return idx - other.idx;
@ -934,12 +970,69 @@ public:
}
};
class iterator {
private:
Const* parent;
size_t idx;
public:
class proxy {
private:
Const* parent;
size_t idx;
public:
proxy(Const* parent, size_t idx) : parent(parent), idx(idx) {}
operator State() const { return (*parent)[idx]; }
proxy& operator=(State s) { parent->set(idx, s); return *this; }
proxy& operator=(const proxy& other) { parent->set(idx, (*other.parent)[other.idx]); return *this; }
};
using iterator_category = std::bidirectional_iterator_tag;
using value_type = State;
using difference_type = std::ptrdiff_t;
using pointer = proxy*;
using reference = proxy;
iterator(Const& c, size_t i) : parent(&c), idx(i) {}
proxy operator*() const { return proxy(parent, idx); }
iterator& operator++() { ++idx; return *this; }
iterator& operator--() { --idx; return *this; }
iterator operator++(int) { iterator result(*this); ++idx; return result; }
iterator operator--(int) { iterator result(*this); --idx; return result; }
iterator& operator+=(int i) { idx += i; return *this; }
iterator operator+(int add) {
return iterator(*parent, idx + add);
}
iterator operator-(int sub) {
return iterator(*parent, idx - sub);
}
int operator-(const iterator& other) {
return idx - other.idx;
}
bool operator==(const iterator& other) const {
return idx == other.idx;
}
bool operator!=(const iterator& other) const {
return !(*this == other);
}
};
const_iterator begin() const {
return const_iterator(*this, 0);
}
const_iterator end() const {
return const_iterator(*this, size());
}
iterator begin() {
return iterator(*this, 0);
}
iterator end() {
return iterator(*this, size());
}
State back() const {
return *(end() - 1);
}
@ -971,20 +1064,14 @@ public:
std::optional<int> as_int_compress(bool is_signed) const;
void extu(int width) {
bits().resize(width, RTLIL::State::S0);
resize(width, RTLIL::State::S0);
}
void exts(int width) {
bitvectype& bv = bits();
bv.resize(width, bv.empty() ? RTLIL::State::Sx : bv.back());
resize(width, empty() ? RTLIL::State::Sx : back());
}
[[nodiscard]] Hasher hash_into(Hasher h) const {
h.eat(size());
for (auto b : *this)
h.eat(b);
return h;
}
[[nodiscard]] Hasher hash_into(Hasher h) const;
};
struct RTLIL::AttrObject
@ -1040,7 +1127,8 @@ struct RTLIL::SigChunk
SigChunk(RTLIL::Wire *wire) : wire(wire), width(GetSize(wire)), offset(0) {}
SigChunk(RTLIL::Wire *wire, int offset, int width = 1) : wire(wire), width(width), offset(offset) {}
SigChunk(const std::string &str) : SigChunk(RTLIL::Const(str)) {}
SigChunk(int val, int width = 32) : SigChunk(RTLIL::Const(val, width)) {}
SigChunk(int val) /*default width 32*/ : SigChunk(RTLIL::Const(val)) {}
SigChunk(int val, int width) : SigChunk(RTLIL::Const(val, width)) {}
SigChunk(RTLIL::State bit, int width = 1) : SigChunk(RTLIL::Const(bit, width)) {}
SigChunk(const RTLIL::SigBit &bit);
@ -1250,12 +1338,16 @@ public:
inline bool is_bit() const { return width_ == 1; }
bool is_mostly_const() const;
bool known_driver() const;
bool is_fully_const() const;
bool is_fully_zero() const;
bool is_fully_ones() const;
bool is_fully_def() const;
bool is_fully_undef() const;
bool has_const() const;
bool has_const(State state) const;
bool has_marked_bits() const;
bool is_onehot(int *pos = nullptr) const;
@ -1651,7 +1743,11 @@ public:
std::vector<RTLIL::IdString> ports;
void fixup_ports();
pool<pair<RTLIL::Cell*, RTLIL::IdString>> bufNormQueue;
pool<RTLIL::Cell *> buf_norm_cell_queue;
pool<pair<RTLIL::Cell *, RTLIL::IdString>> buf_norm_cell_port_queue;
pool<RTLIL::Wire *> buf_norm_wire_queue;
pool<RTLIL::Cell *> pending_deleted_cells;
dict<RTLIL::Wire *, pool<RTLIL::Cell *>> buf_norm_connect_index;
void bufNormalize();
template<typename T> void rewrite_sigspecs(T &functor);
@ -1987,6 +2083,8 @@ public:
int width, start_offset, port_id;
bool port_input, port_output, upto, is_signed;
bool known_driver() const { return driverCell_ != nullptr; }
RTLIL::Cell *driverCell() const { log_assert(driverCell_); return driverCell_; };
RTLIL::IdString driverPort() const { log_assert(driverCell_); return driverPort_; };
@ -2058,6 +2156,7 @@ public:
bool known() const;
bool input(const RTLIL::IdString &portname) const;
bool output(const RTLIL::IdString &portname) const;
PortDir port_dir(const RTLIL::IdString &portname) const;
// access cell parameters
bool hasParam(const RTLIL::IdString &paramname) const;
@ -2083,6 +2182,7 @@ public:
bool has_memid() const;
bool is_mem_cell() const;
bool is_builtin_ff() const;
};
struct RTLIL::CaseRule : public RTLIL::AttrObject

679
kernel/rtlil_bufnorm.cc Normal file
View File

@ -0,0 +1,679 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
*
* 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.
*
*/
#include "kernel/yosys.h"
#include "kernel/sigtools.h"
#include "kernel/modtools.h"
#include <string.h>
#include <algorithm>
#include <optional>
YOSYS_NAMESPACE_BEGIN
void RTLIL::Design::bufNormalize(bool enable)
{
if (!enable)
{
if (!flagBufferedNormalized)
return;
for (auto module : modules()) {
module->buf_norm_cell_queue.clear();
module->buf_norm_wire_queue.clear();
module->buf_norm_cell_port_queue.clear();
for (auto wire : module->wires()) {
wire->driverCell_ = nullptr;
wire->driverPort_ = IdString();
}
}
flagBufferedNormalized = false;
return;
}
if (!flagBufferedNormalized)
{
for (auto module : modules())
{
// When entering buf normalized mode, we need the first module-level bufNormalize
// call to know about all drivers, about all module ports (whether represented by
// a cell or not) and about all used but undriven wires (whether represented by a
// cell or not). We ensure this by enqueing all cell output ports and all wires.
for (auto cell : module->cells())
for (auto &conn : cell->connections()) {
if (GetSize(conn.second) == 0 || (cell->port_dir(conn.first) != RTLIL::PD_OUTPUT && cell->port_dir(conn.first) != RTLIL::PD_INOUT))
continue;
module->buf_norm_cell_queue.insert(cell);
module->buf_norm_cell_port_queue.emplace(cell, conn.first);
}
for (auto wire : module->wires())
module->buf_norm_wire_queue.insert(wire);
}
flagBufferedNormalized = true;
}
for (auto module : modules())
module->bufNormalize();
}
struct bit_drive_data_t {
int drivers = 0;
int inout = 0;
int users = 0;
};
typedef ModWalker::PortBit PortBit;
void RTLIL::Module::bufNormalize()
{
// Since this is kernel code, we only log with yosys_xtrace set to not get
// in the way when using `debug` to debug specific passes.q
#define xlog(...) do { if (yosys_xtrace) log("#X [bufnorm] " __VA_ARGS__); } while (0)
if (!design->flagBufferedNormalized)
return;
if (!buf_norm_cell_queue.empty() || !buf_norm_wire_queue.empty() || !connections_.empty())
{
// Ensure that every enqueued input port is represented by a cell
for (auto wire : buf_norm_wire_queue) {
if (wire->port_input && !wire->port_output) {
if (wire->driverCell_ != nullptr && wire->driverCell_->type != ID($input_port)) {
wire->driverCell_ = nullptr;
wire->driverPort_.clear();
}
if (wire->driverCell_ == nullptr) {
Cell *input_port_cell = addCell(NEW_ID, ID($input_port));
input_port_cell->setParam(ID::WIDTH, GetSize(wire));
input_port_cell->setPort(ID::Y, wire); // this hits the fast path that doesn't mutate the queues
}
}
}
// Next we will temporarily undo buf normalization locally for
// everything enqueued. This means we will turn $buf and $connect back
// into connections. When doing this we also need to enqueue the other
// end of $buf and $connect cells, so we use a queue and do this until
// reaching a fixed point.
// While doing this, we will also discover all drivers fully connected
// to enqueued wires. We keep track of which wires are driven by a
// unique and full cell ports (in which case the wire can stay
// connected to the port) and which cell ports will need to be
// reconnected to a fresh intermediate wire to re-normalize the module.
idict<Wire *> wire_queue_entries; // Ordered queue of wires to process
int wire_queue_pos = 0; // Index up to which we processed the wires
// Wires with their unique driving cell port. If we know a wire is
// driven by multiple (potential) drivers, this is indicated by a
// nullptr as cell.
dict<Wire *, std::pair<Cell *, IdString>> direct_driven_wires;
// Set of non-unique or driving cell ports for each processed wire.
dict<Wire *, pool<std::pair<Cell *, IdString>>> direct_driven_wires_conflicts;
// Set of cell ports that need a fresh intermediate wire.
pool<std::pair<Cell *, IdString>> pending_ports;
// This helper will be called for every output/inout cell port that is
// already enqueued or becomes reachable when denormalizing $buf or
// $connect cells.
auto enqueue_cell_port = [&](Cell *cell, IdString port) {
xlog("processing cell port %s.%s\n", log_id(cell), log_id(port));
// An empty cell type means the cell got removed
if (cell->type.empty())
return;
SigSpec const &sig = cell->getPort(port);
if (cell->type == ID($input_port)) {
// If an `$input_port` cell isn't fully connected to a full
// input port wire, we remove it since the wires are still the
// canonical source of module ports and the `$input_port` cells
// are just helpers to simplfiy the bufnorm invariant.
log_assert(port == ID::Y);
if (!sig.is_wire()) {
buf_norm_cell_queue.insert(cell);
remove(cell);
return;
}
Wire *w = sig.as_wire();
if (!w->port_input || w->port_output) {
buf_norm_cell_queue.insert(cell);
remove(cell);
return;
}
w->driverCell_ = cell;
w->driverPort_ = ID::Y;
} else if (cell->type == ID($buf) && cell->attributes.empty() && !cell->name.isPublic()) {
// For a plain `$buf` cell, we enqueue all wires on its input
// side, bypass it using module level connections (skipping 'z
// bits) and then remove the cell. Eventually the module level
// connections will turn back into `$buf` and `$connect` cells,
// but since we also need to handle externally added module
// level connections, turning everything into connections first
// simplifies the logic for doing so.
// TODO: We could defer removing the $buf cells here, and
// re-use them in case we would create a new identical cell
// later.
log_assert(port == ID::Y);
SigSpec sig_a = cell->getPort(ID::A);
SigSpec sig_y = sig;
for (auto const &s : {sig_a, sig})
for (auto const &chunk : s.chunks())
if (chunk.wire)
wire_queue_entries(chunk.wire);
if (sig_a.has_const(State::Sz)) {
SigSpec new_a;
SigSpec new_y;
for (int i = 0; i < GetSize(sig_a); ++i) {
SigBit b = sig_a[i];
if (b == State::Sz)
continue;
new_a.append(b);
new_y.append(sig_y[i]);
}
sig_a = std::move(new_a);
sig_y = std::move(new_y);
}
if (!sig_y.empty())
connect(sig_y, sig_a);
buf_norm_cell_queue.insert(cell);
remove(cell);
return;
}
// Make sure all wires of the cell port are enqueued, ensuring we
// detect other connected drivers (output and inout).
for (auto const &chunk : sig.chunks())
if (chunk.wire)
wire_queue_entries(chunk.wire);
if (sig.is_wire()) {
// If the full cell port is connected to a full wire, we might be
// able to keep that connection if this is a unique output port driving that wire
Wire *w = sig.as_wire();
// We try to store the current port as unique driver, if this
// succeeds we're done with the port.
auto [found, inserted] = direct_driven_wires.emplace(w, {cell, port});
if (inserted || (found->second.first == cell && found->second.second == port))
return;
// When this failed, we store this port as a conflict. If we
// had already stored a candidate for a unique driver, we also
// move it to the conflicts, leaving a nullptr marker.
auto &conflicts = direct_driven_wires_conflicts[w];
if (Cell *other_cell = found->second.first) {
if (other_cell->type == ID($input_port)) {
// Multiple input port cells
log_assert(cell->type != ID($input_port));
} else {
pending_ports.insert(found->second);
conflicts.emplace(found->second);
found->second = {nullptr, {}};
}
}
if (cell->type == ID($input_port)) {
found->second = {cell, port};
} else {
conflicts.emplace(cell, port);
}
}
// Adds this port to the ports that need a fresh intermediate wire.
// For full wires uniquely driven by a full output port, this isn't
// reached due to the `return` above.
pending_ports.emplace(cell, port);
};
// We process all explicitly enqueued cell ports (clearing the module level queue).
for (auto const &[cell, port_name] : buf_norm_cell_port_queue)
enqueue_cell_port(cell, port_name);
buf_norm_cell_port_queue.clear();
// And enqueue all wires for `$buf`/`$connect` processing (clearing the module level queue).
for (auto wire : buf_norm_wire_queue)
wire_queue_entries(wire);
buf_norm_wire_queue.clear();
// We also enqueue all wires that saw newly added module level connections.
for (auto &[a, b] : connections_)
for (auto &sig : {a, b})
for (auto const &chunk : sig.chunks())
if (chunk.wire)
wire_queue_entries(chunk.wire);
// We then process all wires by processing known driving cell ports
// (previously buf normalized) and following all `$connect` cells (that
// have a dedicated module level index while the design is in buf
// normalized mode).
while (wire_queue_pos < GetSize(wire_queue_entries)) {
auto wire = wire_queue_entries[wire_queue_pos++];
xlog("processing wire %s\n", log_id(wire));
if (wire->driverCell_) {
Cell *cell = wire->driverCell_;
IdString port = wire->driverPort_;
enqueue_cell_port(cell, port);
}
while (true) {
auto found = buf_norm_connect_index.find(wire);
if (found == buf_norm_connect_index.end())
break;
while (!found->second.empty()) {
Cell *connect_cell = *found->second.begin();
log_assert(connect_cell->type == ID($connect));
SigSpec const &sig_a = connect_cell->getPort(ID::A);
SigSpec const &sig_b = connect_cell->getPort(ID::B);
xlog("found $connect cell %s: %s <-> %s\n", log_id(connect_cell), log_signal(sig_a), log_signal(sig_b));
for (auto &side : {sig_a, sig_b})
for (auto chunk : side.chunks())
if (chunk.wire)
wire_queue_entries(chunk.wire);
connect(sig_a, sig_b);
buf_norm_cell_queue.insert(connect_cell);
remove(connect_cell);
}
}
}
// At this point we know all cell ports and wires that need to be
// re-normalized and know their connectivity is represented by module
// level connections.
// As a first step for re-normalization we add all require intermediate
// wires for cell output and inout ports.
for (auto &[cell, port] : pending_ports) {
SigSpec const &sig = cell->getPort(port);
Wire *w = addWire(NEW_ID, GetSize(sig));
// We update the module level connections, `direct_driven_wires`
// and `direct_driven_wires_conflicts` in such a way that they
// correspond to what you would get if the intermediate wires had
// been in place from the beginning.
connect(sig, w);
auto port_dir = cell->port_dir(port);
if (port_dir == RTLIL::PD_INOUT || port_dir == RTLIL::PD_UNKNOWN) {
direct_driven_wires.emplace(w, {nullptr, {}});
direct_driven_wires_conflicts[w].emplace(cell, port);
} else {
direct_driven_wires.emplace(w, {cell, port});
}
cell->setPort(port, w);
wire_queue_entries(w);
}
// At this point we're done with creating wires and know which ones are
// fully driven by full output ports of existing cells.
// First we clear the bufnorm data for all processed wires, all of
// these will be reassigned later, but we use `driverCell_ == nullptr`
// to keep track of the wires that we still have to update.
for (auto wire : wire_queue_entries) {
wire->driverCell_ = nullptr;
wire->driverPort_.clear();
}
// For the unique output cell ports fully connected to a full wire, we
// can update the bufnorm data right away. For all other wires we will
// have to create new `$buf` cells.
for (auto const &[wire, cellport] : direct_driven_wires) {
wire->driverCell_ = cellport.first;
wire->driverPort_ = cellport.second;
}
// To create fresh `$buf` cells for all remaining wires, we need to
// process the module level connectivity to figure out what the input
// of those `$buf` cells should be and to figure out whether we need
// any `$connect` cells to represent bidirectional inout connections
// (or driver conflicts).
if (yosys_xtrace)
for (auto const &[lhs, rhs] : connections_)
xlog("connection %s <-> %s\n", log_signal(lhs), log_signal(rhs));
// We transfer the connectivity into a sigmap and then clear the module
// level connections. This forgets about the structure of module level
// connections, but bufnorm only guarantees that the connectivity as
// maintained by a `SigMap` is preserved.
SigMap sigmap(this);
new_connections({});
pool<SigBit> conflicted;
pool<SigBit> driven;
// We iterate over all direct driven wires and try to make that wire's
// sigbits the representative sigbit for the net. We do a second pass
// to detect conflicts to then remove the conflicts from `driven`.
for (bool check : {false, true}) {
for (auto const &[wire, cellport] : direct_driven_wires) {
if (cellport.first == nullptr)
continue;
auto const &[cell, port] = cellport;
SigSpec z_mask;
if (cell->type == ID($buf))
z_mask = cell->getPort(ID::A);
for (int i = 0; i != GetSize(wire); ++i) {
SigBit driver = SigBit(wire, i);
if (!z_mask.empty() && z_mask[i] == State::Sz)
continue;
if (check) {
SigBit repr = sigmap(driver);
if (repr != driver)
conflicted.insert(repr);
else
driven.insert(repr);
} else {
sigmap.database.promote(driver);
}
}
}
}
// Ensure that module level inout ports are directly driven or
// connected using `$connect` cells and never `$buf`fered.
for (auto wire : wire_queue_entries) {
if (!wire->port_input || !wire->port_output)
continue;
for (int i = 0; i != GetSize(wire); ++i) {
SigBit driver = SigBit(wire, i);
SigBit repr = sigmap(driver);
if (driver != repr)
driven.erase(repr);
}
}
for (auto &bit : conflicted)
driven.erase(bit);
// Module level bitwise connections not representable by `$buf` cells
pool<pair<SigBit, SigBit>> undirected_connections;
// Starts out empty but is updated with the connectivity realized by freshly added `$buf` cells
SigMap buf_connected;
// For every enqueued wire, we compute a SigSpec of representative
// drivers. If there are any bits without a unique driver we represent
// that with `Sz`. If there are multiple drivers for a net, they become
// connected via `$connect` cells but every wire of the net has the
// corresponding bit still driven by a buffered `Sz`.
for (auto wire : wire_queue_entries) {
SigSpec wire_drivers;
for (int i = 0; i < GetSize(wire); ++i) {
SigBit bit(wire, i);
SigBit mapped = sigmap(bit);
xlog("bit %s -> mapped %s\n", log_signal(bit), log_signal(mapped));
buf_connected.apply(bit);
buf_connected.add(bit, mapped);
buf_connected.database.promote(mapped);
if (wire->driverCell_ == nullptr) {
if (!mapped.is_wire() || driven.count(mapped)) {
wire_drivers.append(mapped);
continue;
} else {
wire_drivers.append(State::Sz);
}
}
if (bit < mapped)
undirected_connections.emplace(bit, mapped);
else if (mapped < bit)
undirected_connections.emplace(mapped, bit);
}
if (wire->driverCell_ == nullptr) {
xlog("wire %s drivers %s\n", log_id(wire), log_signal(wire_drivers));
addBuf(NEW_ID, wire_drivers, wire);
}
}
// Finally we group the bitwise connections to emit word-level $connect cells
static auto sort_key = [](std::pair<SigBit, SigBit> const &p) {
int first_offset = p.first.is_wire() ? p.first.offset : 0;
int second_offset = p.second.is_wire() ? p.second.offset : 0;
return std::make_tuple(p.first.wire, p.second.wire, first_offset - second_offset, p);
};
undirected_connections.sort([](std::pair<SigBit, SigBit> const &p, std::pair<SigBit, SigBit> const &q) {
return sort_key(p) < sort_key(q);
});
SigSpec tmp_a, tmp_b;
for (auto &[bit_a, bit_b] : undirected_connections) {
tmp_a.append(bit_a);
tmp_b.append(bit_b);
}
xlog("LHS: %s\n", log_signal(tmp_a));
xlog("RHS: %s\n", log_signal(tmp_b));
SigSpec sig_a, sig_b;
SigBit next_a, next_b;
auto emit_connect_cell = [&]() {
if (sig_a.empty())
return;
xlog("connect %s <-> %s\n", log_signal(sig_a), log_signal(sig_b));
Cell *connect_cell = addCell(NEW_ID, ID($connect));
connect_cell->setParam(ID::WIDTH, GetSize(sig_a));
connect_cell->setPort(ID::A, sig_a);
connect_cell->setPort(ID::B, sig_b);
sig_a = SigSpec();
sig_b = SigSpec();
};
for (auto &[bit_a, bit_b] : undirected_connections) {
if (bit_a == bit_b)
continue;
if (bit_a != next_a || bit_b != next_b)
emit_connect_cell();
sig_a.append(bit_a);
sig_b.append(bit_b);
next_a = bit_a;
next_b = bit_b;
if (next_a.is_wire())
next_a.offset++;
if (next_b.is_wire())
next_b.offset++;
}
emit_connect_cell();
buf_norm_cell_queue.clear();
log_assert(buf_norm_cell_port_queue.empty());
log_assert(buf_norm_wire_queue.empty());
log_assert(connections_.empty());
}
for (auto cell : pending_deleted_cells) {
delete cell;
}
pending_deleted_cells.clear();
}
void RTLIL::Cell::unsetPort(const RTLIL::IdString& portname)
{
RTLIL::SigSpec signal;
auto conn_it = connections_.find(portname);
if (conn_it != connections_.end())
{
for (auto mon : module->monitors)
mon->notify_connect(this, conn_it->first, conn_it->second, signal);
if (module->design)
for (auto mon : module->design->monitors)
mon->notify_connect(this, conn_it->first, conn_it->second, signal);
if (yosys_xtrace) {
log("#X# Unconnect %s.%s.%s\n", log_id(this->module), log_id(this), log_id(portname));
log_backtrace("-X- ", yosys_xtrace-1);
}
if (module->design && module->design->flagBufferedNormalized) {
if (conn_it->second.is_wire()) {
Wire *w = conn_it->second.as_wire();
if (w->driverCell_ == this && w->driverPort_ == portname) {
w->driverCell_ = nullptr;
w->driverPort_ = IdString();
module->buf_norm_wire_queue.insert(w);
}
}
if (type == ID($connect)) {
for (auto &[port, sig] : connections_) {
for (auto &chunk : sig.chunks()) {
if (!chunk.wire)
continue;
auto it = module->buf_norm_connect_index.find(chunk.wire);
if (it == module->buf_norm_connect_index.end())
continue;
it->second.erase(this);
if (it->second.empty())
module->buf_norm_connect_index.erase(it);
}
}
connections_.erase(conn_it);
for (auto &[port, sig] : connections_) {
for (auto &chunk : sig.chunks()) {
if (!chunk.wire)
continue;
module->buf_norm_connect_index[chunk.wire].insert(this);
}
}
return;
}
}
connections_.erase(conn_it);
}
}
void RTLIL::Cell::setPort(const RTLIL::IdString& portname, RTLIL::SigSpec signal)
{
auto r = connections_.insert(portname);
auto conn_it = r.first;
if (!r.second && conn_it->second == signal)
return;
for (auto mon : module->monitors)
mon->notify_connect(this, conn_it->first, conn_it->second, signal);
if (module->design)
for (auto mon : module->design->monitors)
mon->notify_connect(this, conn_it->first, conn_it->second, signal);
if (yosys_xtrace) {
log("#X# Connect %s.%s.%s = %s (%d)\n", log_id(this->module), log_id(this), log_id(portname), log_signal(signal), GetSize(signal));
log_backtrace("-X- ", yosys_xtrace-1);
}
if (module->design && module->design->flagBufferedNormalized)
{
// We eagerly clear a driver that got disconnected by changing this port connection
if (conn_it->second.is_wire()) {
Wire *w = conn_it->second.as_wire();
if (w->driverCell_ == this && w->driverPort_ == portname) {
w->driverCell_ = nullptr;
w->driverPort_ = IdString();
module->buf_norm_wire_queue.insert(w);
}
}
auto dir = port_dir(portname);
// This is a fast path that handles connecting a full driverless wire to an output port,
// everything else is goes through the bufnorm queues and is handled during the next
// bufNormalize call
if ((dir == RTLIL::PD_OUTPUT || dir == RTLIL::PD_INOUT) && signal.is_wire()) {
Wire *w = signal.as_wire();
if (w->driverCell_ == nullptr) {
w->driverCell_ = this;
w->driverPort_ = portname;
conn_it->second = std::move(signal);
return;
}
}
if (dir == RTLIL::PD_OUTPUT || dir == RTLIL::PD_INOUT) {
module->buf_norm_cell_queue.insert(this);
module->buf_norm_cell_port_queue.emplace(this, portname);
} else {
for (auto &chunk : signal.chunks())
if (chunk.wire != nullptr && chunk.wire->driverCell_ == nullptr)
module->buf_norm_wire_queue.insert(chunk.wire);
}
if (type == ID($connect)) {
for (auto &[port, sig] : connections_) {
for (auto &chunk : sig.chunks()) {
if (!chunk.wire)
continue;
auto it = module->buf_norm_connect_index.find(chunk.wire);
if (it == module->buf_norm_connect_index.end())
continue;
it->second.erase(this);
if (it->second.empty())
module->buf_norm_connect_index.erase(it);
}
}
conn_it->second = std::move(signal);
for (auto &[port, sig] : connections_) {
for (auto &chunk : sig.chunks()) {
if (!chunk.wire)
continue;
module->buf_norm_connect_index[chunk.wire].insert(this);
}
}
return;
}
}
conn_it->second = std::move(signal);
}
YOSYS_NAMESPACE_END

View File

@ -1202,7 +1202,7 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
return true;
}
if (timestep > 0 && (RTLIL::builtin_ff_cell_types().count(cell->type) || cell->type == ID($anyinit)))
if (timestep > 0 && (cell->is_builtin_ff() || cell->type == ID($anyinit)))
{
FfData ff(nullptr, cell);

View File

@ -137,7 +137,7 @@ static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *a
if (err.empty()) {
Tcl_SetObjResult(interp, json_to_tcl(interp, json));
} else
log_warning("Ignoring result.json scratchpad value due to parse error: %s\n", err.c_str());
log_warning("Ignoring result.json scratchpad value due to parse error: %s\n", err);
} else if ((result = scratchpad.find("result.string")) != scratchpad.end()) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(result->second.data(), result->second.size()));
}
@ -214,18 +214,19 @@ bool mp_int_to_const(mp_int *a, Const &b, bool is_signed)
buf.resize(mp_unsigned_bin_size(a));
mp_to_unsigned_bin(a, buf.data());
b.bits().reserve(mp_count_bits(a) + is_signed);
Const::Builder b_bits(mp_count_bits(a) + is_signed);
for (int i = 0; i < mp_count_bits(a);) {
for (int j = 0; j < 8 && i < mp_count_bits(a); j++, i++) {
bool bv = ((buf.back() & (1 << j)) != 0) ^ negative;
b.bits().push_back(bv ? RTLIL::S1 : RTLIL::S0);
b_bits.push_back(bv ? RTLIL::S1 : RTLIL::S0);
}
buf.pop_back();
}
if (is_signed) {
b.bits().push_back(negative ? RTLIL::S1 : RTLIL::S0);
b_bits.push_back(negative ? RTLIL::S1 : RTLIL::S0);
}
b = b_bits.build();
return true;
}

View File

@ -185,7 +185,6 @@ RTLIL::Const ReadWitness::get_bits(int t, int bits_offset, int width) const
const std::string &bits = steps[t].bits;
RTLIL::Const result(State::Sa, width);
result.bits().reserve(width);
int read_begin = GetSize(bits) - 1 - bits_offset;
int read_end = max(-1, read_begin - width);
@ -200,7 +199,7 @@ RTLIL::Const ReadWitness::get_bits(int t, int bits_offset, int width) const
default:
log_abort();
}
result.bits()[j] = bit;
result.set(j, bit);
}
return result;

View File

@ -411,7 +411,7 @@ class SubCircuit::SolverWorker
std::string toString() const
{
return my_stringf("%s[%d]:%s[%d]", fromPort, fromBit, toPort, toBit);
return my_stringf("%s[%d]:%s[%d]", fromPort.c_str(), fromBit, toPort.c_str(), toBit);
}
};
@ -444,7 +444,7 @@ class SubCircuit::SolverWorker
std::string str;
bool firstPort = true;
for (const auto &it : portSizes) {
str += my_stringf("%s%s[%d]", firstPort ? "" : ",", it.first, it.second);
str += my_stringf("%s%s[%d]", firstPort ? "" : ",", it.first.c_str(), it.second);
firstPort = false;
}
return typeId + "(" + str + ")";

View File

@ -71,7 +71,7 @@ keyword_aliases = {
#These can be used without any explicit conversion
primitive_types = ["void", "bool", "int", "double", "size_t", "std::string",
"string", "State", "char_p", "std::source_location", "source_location"]
"string", "string_view", "std::string_view", "State", "char_p", "std::source_location", "source_location"]
from enum import Enum
@ -557,6 +557,7 @@ class Attribute:
default_value = None
pos = None
pos_counter = 0
coerce_arg = None
def __init__(self, wtype, varname, is_const = False, default_value = None):
self.wtype = wtype
@ -566,7 +567,7 @@ class Attribute:
self.container = None
@staticmethod
def from_string(str_def, containing_file, line_number):
def from_string(str_def, containing_file, line_number, *, owner_fn_name=""):
if len(str_def) < 3:
return None
orig = str_def
@ -630,6 +631,19 @@ class Attribute:
else:
arg.wtype.attr_type = attr_types.amp
arg.varname = arg.varname[1:]
# handle string views
if arg.wtype.name in ["std::string_view", "string_view"]:
if arg.varname == "format" and owner_fn_name.startswith("log_"):
# coerce format strings to "%s" (not bridgable)
arg.coerce_arg = '"%s"'
elif arg.varname == "prefix" and "warning" in owner_fn_name:
# coerce warning prefix to "warning:"
arg.coerce_arg = '"Warning: "'
else:
# boost::python can't bridge string views, so just copy them
arg.wtype.name = "string"
return arg
#Generates the varname. If the attribute has no name in the header file,
@ -1391,7 +1405,7 @@ class WFunction:
for i, arg in enumerate(args):
if arg.strip() == "...":
continue
parsed = Attribute.from_string(arg.strip(), containing_file, line_number)
parsed = Attribute.from_string(arg.strip(), containing_file, line_number, owner_fn_name=func.name)
if parsed == None:
return None
# Only allow std::source_location as defaulted last argument, and
@ -1431,6 +1445,8 @@ class WFunction:
text += "static "
text += self.ret_type.gen_text() + " " + self.alias + "("
for arg in self.args:
if arg.coerce_arg:
continue
text += arg.gen_listitem()
text += ", "
if len(self.args) > 0:
@ -1497,6 +1513,8 @@ class WFunction:
text += self.member_of.name + "::"
text += self.alias + "("
for arg in self.args:
if arg.coerce_arg:
continue
text += arg.gen_listitem()
text += ", "
if len(self.args) > 0:
@ -1516,13 +1534,14 @@ class WFunction:
if self.ret_type.name in classnames:
text += self.ret_type.name + "::get_py_obj("
if self.member_of == None:
text += "::" + self.namespace + "::" + self.alias + "("
text += "::" + self.namespace + "::" + self.name + "("
elif self.is_static:
text += self.member_of.namespace + "::" + self.member_of.name + "::" + self.name + "("
else:
text += "this->get_cpp_obj()->" + self.name + "("
for arg in self.args:
text += arg.gen_call() + ", "
text += arg.coerce_arg or arg.gen_call()
text += ", "
if len(self.args) > 0:
text = text[:-2]
if self.ret_type.name in classnames:
@ -1639,6 +1658,8 @@ class WFunction:
else:
text += "(" + self.member_of.name + "::*)("
for a in self.args:
if a.coerce_arg:
continue
text += a.gen_listitem_hash() + ", "
if len(self.args) > 0:
text = text[0:-2] + f"){self.gen_post_qualifiers(True)}>"
@ -2122,6 +2143,16 @@ def parse_header(source):
if class_ == None:
debug("\tFound unowned function \"" + candidate.name + "\" in namespace " + concat_namespace(namespaces),2)
unowned_functions.append(candidate)
# generate log aliases
if candidate.name.startswith("log_formatted"):
alias = candidate.name.replace("log_formatted", "log")
if alias == "log_string":
alias = "log"
copied_candidate = copy.copy(candidate)
copied_candidate.alias = alias
unowned_functions.append(copied_candidate)
else:
debug("\t\tFound function \"" + candidate.name + "\" of class \"" + class_[0].name + "\" in namespace " + concat_namespace(namespaces),2)
class_[0].found_funs.append(candidate)
@ -2359,6 +2390,8 @@ def gen_wrappers(filename, debug_level_ = 0):
#include <boost/iostreams/stream.hpp>
USING_YOSYS_NAMESPACE
using std::string_view;
namespace YOSYS_PYTHON {
[[noreturn]] static void log_python_exception_as_error() {

View File

@ -53,7 +53,7 @@ struct Slice {
}
static void syntax_error(const std::string &slice) {
log_cmd_error("Invalid slice '%s', expected '<first>:<last>' or '<single>'", slice.c_str());
log_cmd_error("Invalid slice '%s', expected '<first>:<last>' or '<single>'", slice);
}
std::string to_string() const {
@ -494,7 +494,7 @@ struct AbstractPass : public Pass {
case Enable::ActiveHigh: {
Wire *enable_wire = mod->wire("\\" + enable_name);
if (!enable_wire)
log_cmd_error("Enable wire %s not found in module %s\n", enable_name.c_str(), mod->name.c_str());
log_cmd_error("Enable wire %s not found in module %s\n", enable_name, mod->name);
if (GetSize(enable_wire) != 1)
log_cmd_error("Enable wire %s must have width 1 but has width %d in module %s\n",
enable_name.c_str(), GetSize(enable_wire), mod->name.c_str());

View File

@ -77,7 +77,7 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n
wire = nullptr;
if (wire == nullptr)
log_cmd_error("Found incompatible object with same name in module %s!\n", module->name.c_str());
log_cmd_error("Found incompatible object with same name in module %s!\n", module->name);
log("Module %s already has such an object.\n", module->name);
}

View File

@ -405,7 +405,11 @@ struct BugpointPass : public Pass {
for (auto it2 = sy->mem_write_actions.begin(); it2 != sy->mem_write_actions.end(); ++it2) {
auto &mask = it2->priority_mask;
if (GetSize(mask) > i) {
mask.bits().erase(mask.bits().begin() + i);
RTLIL::Const::Builder new_mask_builder(GetSize(mask) - 1);
for (int k = 0; k < GetSize(mask); k++)
if (k != i)
new_mask_builder.push_back(mask[k]);
mask = new_mask_builder.build();
}
}
return design_copy;

View File

@ -285,7 +285,7 @@ struct CheckPass : public Pass {
}
if (yosys_celltypes.cell_evaluable(cell->type) || cell->type.in(ID($mem_v2), ID($memrd), ID($memrd_v2)) \
|| RTLIL::builtin_ff_cell_types().count(cell->type)) {
|| cell->is_builtin_ff()) {
if (!edges_db.add_edges_from_cell(cell))
coarsened_cells.insert(cell);
}
@ -323,7 +323,7 @@ struct CheckPass : public Pass {
string message = stringf("Drivers conflicting with a constant %s driver:\n", log_signal(state));
for (auto str : wire_drivers[state])
message += stringf(" %s\n", str);
log_warning("%s", message.c_str());
log_warning("%s", message);
counter++;
}
@ -332,7 +332,7 @@ struct CheckPass : public Pass {
string message = stringf("multiple conflicting drivers for %s.%s:\n", log_id(module), log_signal(it.first));
for (auto str : it.second)
message += stringf(" %s\n", str);
log_warning("%s", message.c_str());
log_warning("%s", message);
counter++;
}
@ -418,7 +418,7 @@ struct CheckPass : public Pass {
prev = bit;
}
log_warning("%s", message.c_str());
log_warning("%s", message);
counter++;
}
@ -426,7 +426,7 @@ struct CheckPass : public Pass {
{
for (auto cell : module->cells())
{
if (RTLIL::builtin_ff_cell_types().count(cell->type) == 0)
if (cell->is_builtin_ff() == 0)
continue;
for (auto bit : sigmap(cell->getPort(ID::Q)))

View File

@ -73,7 +73,7 @@ struct CleanZeroWidthPass : public Pass {
cell->unsetPort(it.first);
}
}
} else if (RTLIL::builtin_ff_cell_types().count(cell->type)) {
} else if (cell->is_builtin_ff()) {
// Coarse FF cells: remove if WIDTH == 0 (no outputs).
// This will also trigger on fine cells, so use the Q port
// width instead of actual WIDTH parameter.
@ -158,11 +158,11 @@ struct CleanZeroWidthPass : public Pass {
continue;
if (GetSize(memwr.address) == 0)
memwr.address = State::S0;
Const priority_mask;
RTLIL::Const::Builder new_mask_bits(swizzle.size());
for (auto x : swizzle) {
priority_mask.bits().push_back(memwr.priority_mask[x]);
new_mask_bits.push_back(memwr.priority_mask[x]);
}
memwr.priority_mask = priority_mask;
memwr.priority_mask = new_mask_bits.build();
swizzle.push_back(i);
new_memwr_actions.push_back(memwr);
}

View File

@ -150,9 +150,9 @@ struct ConnectPass : public Pass {
RTLIL::SigSpec sig_lhs, sig_rhs;
if (!RTLIL::SigSpec::parse_sel(sig_lhs, design, module, set_lhs))
log_cmd_error("Failed to parse set lhs expression `%s'.\n", set_lhs.c_str());
log_cmd_error("Failed to parse set lhs expression `%s'.\n", set_lhs);
if (!RTLIL::SigSpec::parse_rhs(sig_lhs, sig_rhs, module, set_rhs))
log_cmd_error("Failed to parse set rhs expression `%s'.\n", set_rhs.c_str());
log_cmd_error("Failed to parse set rhs expression `%s'.\n", set_rhs);
sigmap.apply(sig_lhs);
sigmap.apply(sig_rhs);
@ -173,7 +173,7 @@ struct ConnectPass : public Pass {
RTLIL::SigSpec sig;
if (!RTLIL::SigSpec::parse_sel(sig, design, module, unset_expr))
log_cmd_error("Failed to parse unset expression `%s'.\n", unset_expr.c_str());
log_cmd_error("Failed to parse unset expression `%s'.\n", unset_expr);
sigmap.apply(sig);
unset_drivers(design, module, sigmap, sig);
@ -185,11 +185,11 @@ struct ConnectPass : public Pass {
log_cmd_error("Can't use -port together with -nounset.\n");
if (module->cell(RTLIL::escape_id(port_cell)) == nullptr)
log_cmd_error("Can't find cell %s.\n", port_cell.c_str());
log_cmd_error("Can't find cell %s.\n", port_cell);
RTLIL::SigSpec sig;
if (!RTLIL::SigSpec::parse_sel(sig, design, module, port_expr))
log_cmd_error("Failed to parse port expression `%s'.\n", port_expr.c_str());
log_cmd_error("Failed to parse port expression `%s'.\n", port_expr);
if (!flag_assert) {
module->cell(RTLIL::escape_id(port_cell))->setPort(RTLIL::escape_id(port_port), sigmap(sig));

View File

@ -42,7 +42,7 @@ struct ConnwrappersWorker
decl_celltypes.insert(key.first);
if (decls.count(key))
log_cmd_error("Duplicate port decl: %s %s\n", celltype.c_str(), portname.c_str());
log_cmd_error("Duplicate port decl: %s %s\n", celltype, portname);
portdecl_t decl;
decl.widthparam = RTLIL::escape_id(widthparam);
@ -57,7 +57,7 @@ struct ConnwrappersWorker
decl_celltypes.insert(key.first);
if (decls.count(key))
log_cmd_error("Duplicate port decl: %s %s\n", celltype.c_str(), portname.c_str());
log_cmd_error("Duplicate port decl: %s %s\n", celltype, portname);
portdecl_t decl;
decl.widthparam = RTLIL::escape_id(widthparam);

View File

@ -45,10 +45,10 @@ struct CopyPass : public Pass {
std::string trg_name = RTLIL::escape_id(args[2]);
if (design->module(src_name) == nullptr)
log_cmd_error("Can't find source module %s.\n", src_name.c_str());
log_cmd_error("Can't find source module %s.\n", src_name);
if (design->module(trg_name) != nullptr)
log_cmd_error("Target module name %s already exists.\n", trg_name.c_str());
log_cmd_error("Target module name %s already exists.\n", trg_name);
RTLIL::Module *new_mod = design->module(src_name)->clone();
new_mod->name = trg_name;

View File

@ -118,7 +118,7 @@ struct CoverPass : public Pass {
if (f == NULL) {
for (auto f : out_files)
fclose(f);
log_cmd_error("Can't create file %s%s.\n", args[argidx-1] == "-d" ? "in directory " : "", args[argidx].c_str());
log_cmd_error("Can't create file %s%s.\n", args[argidx-1] == "-d" ? "in directory " : "", args[argidx]);
}
out_files.push_back(f);
continue;

View File

@ -165,13 +165,13 @@ struct DesignPass : public Pass {
got_mode = true;
load_name = args[++argidx];
if (saved_designs.count(load_name) == 0)
log_cmd_error("No saved design '%s' found!\n", load_name.c_str());
log_cmd_error("No saved design '%s' found!\n", load_name);
continue;
}
if (!got_mode && args[argidx] == "-copy-from" && argidx+1 < args.size()) {
got_mode = true;
if (saved_designs.count(args[++argidx]) == 0)
log_cmd_error("No saved design '%s' found!\n", args[argidx].c_str());
log_cmd_error("No saved design '%s' found!\n", args[argidx]);
copy_from_design = saved_designs.at(args[argidx]);
copy_to_design = design;
continue;
@ -188,7 +188,7 @@ struct DesignPass : public Pass {
got_mode = true;
import_mode = true;
if (saved_designs.count(args[++argidx]) == 0)
log_cmd_error("No saved design '%s' found!\n", args[argidx].c_str());
log_cmd_error("No saved design '%s' found!\n", args[argidx]);
copy_from_design = saved_designs.at(args[argidx]);
copy_to_design = design;
as_name = args[argidx];
@ -202,7 +202,7 @@ struct DesignPass : public Pass {
got_mode = true;
delete_name = args[++argidx];
if (saved_designs.count(delete_name) == 0)
log_cmd_error("No saved design '%s' found!\n", delete_name.c_str());
log_cmd_error("No saved design '%s' found!\n", delete_name);
continue;
}
break;

View File

@ -430,7 +430,7 @@ struct DftTagWorker {
return;
}
if (RTLIL::builtin_ff_cell_types().count(cell->type) || cell->type == ID($anyinit)) {
if (cell->is_builtin_ff() || cell->type == ID($anyinit)) {
FfData ff(&initvals, cell);
if (ff.has_clk || ff.has_gclk)
@ -686,7 +686,7 @@ struct DftTagWorker {
return;
}
if (RTLIL::builtin_ff_cell_types().count(cell->type) || cell->type == ID($anyinit)) {
if (cell->is_builtin_ff() || cell->type == ID($anyinit)) {
FfData ff(&initvals, cell);
// TODO handle some more variants
if ((ff.has_clk || ff.has_gclk) && !ff.has_ce && !ff.has_aload && !ff.has_srst && !ff.has_arst && !ff.has_sr) {
@ -884,8 +884,10 @@ struct DftTagWorker {
{
if (sig_a.is_fully_const()) {
auto const_val = sig_a.as_const();
for (State& bit : const_val.bits())
bit = bit == State::S0 ? State::S1 : bit == State::S1 ? State::S0 : bit;
for (auto bit : const_val) {
State b = bit;
bit = b == State::S0 ? State::S1 : b == State::S1 ? State::S0 : b;
}
return const_val;
}
return module->Not(name, sig_a);

View File

@ -127,7 +127,7 @@ struct ExecPass : public Pass {
x.re = YS_REGEX_COMPILE(args[argidx]);
expect_stdout.push_back(x);
} catch (const std::regex_error& e) {
log_cmd_error("Error in regex expression '%s' !\n", args[argidx].c_str());
log_cmd_error("Error in regex expression '%s' !\n", args[argidx]);
}
} else if (args[argidx] == "-not-expect-stdout") {
flag_expect_stdout = true;
@ -142,15 +142,15 @@ struct ExecPass : public Pass {
x.polarity = false;
expect_stdout.push_back(x);
} catch (const std::regex_error& e) {
log_cmd_error("Error in regex expression '%s' !\n", args[argidx].c_str());
log_cmd_error("Error in regex expression '%s' !\n", args[argidx]);
}
} else
log_cmd_error("Unknown option \"%s\" or \"--\" doesn\'t precede command.\n", args[argidx].c_str());
log_cmd_error("Unknown option \"%s\" or \"--\" doesn\'t precede command.\n", args[argidx]);
}
}
log_header(design, "Executing command \"%s\".\n", cmd.c_str());
log_header(design, "Executing command \"%s\".\n", cmd);
log_push();
fflush(stdout);
@ -201,7 +201,7 @@ struct ExecPass : public Pass {
if (flag_expect_stdout)
for (auto &x : expect_stdout)
if (x.polarity ^ x.matched)
log_cmd_error("Command stdout did%s have a line matching given regex \"%s\".\n", (x.polarity? " not" : ""), x.str.c_str());
log_cmd_error("Command stdout did%s have a line matching given regex \"%s\".\n", (x.polarity? " not" : ""), x.str);
log_pop();
}

View File

@ -85,7 +85,7 @@ struct FutureWorker {
if (found_driver->second.size() > 1)
log_error("Found multiple drivers for future_ff target signal %s\n", log_signal(bit));
auto driver = *found_driver->second.begin();
if (!RTLIL::builtin_ff_cell_types().count(driver.cell->type) && driver.cell->type != ID($anyinit))
if (!driver.cell->is_builtin_ff() && driver.cell->type != ID($anyinit))
log_error("Driver for future_ff target signal %s has non-FF cell type %s\n", log_signal(bit), log_id(driver.cell->type));
FfData ff(&initvals, driver.cell);

View File

@ -184,7 +184,7 @@ private:
for(auto &cell : module->cells().to_vector()) {
if (!cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_MUX_), ID($_NMUX_), ID($_NOT_), ID($anyconst), ID($allconst), ID($assume), ID($assert)) && module->design->module(cell->type) == nullptr) {
log_cmd_error("Unsupported cell type \"%s\" found. Run `techmap` first.\n", cell->type.c_str());
log_cmd_error("Unsupported cell type \"%s\" found. Run `techmap` first.\n", cell->type);
}
if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_))) {
const unsigned int A = 0, B = 1, Y = 2;

View File

@ -107,7 +107,7 @@ struct LogPass : public Pass {
if (to_stderr) fprintf(stderr, "%s%s", text.c_str(), line_end);
if (to_log) {
if (!header) log("%s%s", text, line_end);
else log_header(design, "%s%s", text.c_str(), line_end);
else log_header(design, "%s%s", text, line_end);
}
}
} LogPass;

View File

@ -112,7 +112,7 @@ struct LoggerPass : public Pass {
log_warn_regexes.push_back(YS_REGEX_COMPILE(pattern));
}
catch (const std::regex_error& e) {
log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str());
log_cmd_error("Error in regex expression '%s' !\n", pattern);
}
continue;
}
@ -124,7 +124,7 @@ struct LoggerPass : public Pass {
log_nowarn_regexes.push_back(YS_REGEX_COMPILE(pattern));
}
catch (const std::regex_error& e) {
log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str());
log_cmd_error("Error in regex expression '%s' !\n", pattern);
}
continue;
}
@ -136,7 +136,7 @@ struct LoggerPass : public Pass {
log_werror_regexes.push_back(YS_REGEX_COMPILE(pattern));
}
catch (const std::regex_error& e) {
log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str());
log_cmd_error("Error in regex expression '%s' !\n", pattern);
}
continue;
}
@ -188,7 +188,7 @@ struct LoggerPass : public Pass {
else log_abort();
}
catch (const std::regex_error& e) {
log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str());
log_cmd_error("Error in regex expression '%s' !\n", pattern);
}
continue;
}

View File

@ -70,7 +70,7 @@ void load_plugin(std::string filename, std::vector<std::string> aliases)
if(module_p == NULL)
{
PyErr_Print();
log_cmd_error("Can't load python module `%s'\n", full_path.filename().c_str());
log_cmd_error("Can't load python module `%s'\n", full_path.filename());
return;
}
loaded_python_plugins[orig_filename] = module_p;
@ -100,7 +100,7 @@ void load_plugin(std::string filename, std::vector<std::string> aliases)
}
if (hdl == NULL)
log_cmd_error("Can't load module `%s': %s\n", filename.c_str(), dlerror());
log_cmd_error("Can't load module `%s': %s\n", filename, dlerror());
loaded_plugins[orig_filename] = hdl;
Pass::init_register();

View File

@ -31,7 +31,7 @@ static void rename_in_module(RTLIL::Module *module, std::string from_name, std::
to_name = RTLIL::escape_id(to_name);
if (module->count_id(to_name))
log_cmd_error("There is already an object `%s' in module `%s'.\n", to_name.c_str(), module->name.c_str());
log_cmd_error("There is already an object `%s' in module `%s'.\n", to_name, module->name);
RTLIL::Wire *wire_to_rename = module->wire(from_name);
RTLIL::Cell *cell_to_rename = module->cell(from_name);
@ -55,7 +55,7 @@ static void rename_in_module(RTLIL::Module *module, std::string from_name, std::
return;
}
log_cmd_error("Object `%s' not found!\n", from_name.c_str());
log_cmd_error("Object `%s' not found!\n", from_name);
}
static std::string derive_name_from_src(const std::string &src, int counter)
@ -632,7 +632,7 @@ struct RenamePass : public Pass {
log("Renaming module %s to %s.\n", module_to_rename->name, to_name);
design->rename(module_to_rename, to_name);
} else
log_cmd_error("Object `%s' not found!\n", from_name.c_str());
log_cmd_error("Object `%s' not found!\n", from_name);
}
}
}

View File

@ -592,7 +592,7 @@ static void select_op_expand(RTLIL::Design *design, const std::string &arg, char
while (pos < int(arg.size())) {
if (arg[pos] != ':' || pos+1 == int(arg.size()))
log_cmd_error("Syntax error in expand operator '%s'.\n", arg.c_str());
log_cmd_error("Syntax error in expand operator '%s'.\n", arg);
pos++;
if (arg[pos] == '+' || arg[pos] == '-') {
expand_rule_t rule;
@ -617,7 +617,7 @@ static void select_op_expand(RTLIL::Design *design, const std::string &arg, char
for (auto i2 : i1.second)
limits.insert(i2);
} else
log_cmd_error("Selection %s is not defined!\n", RTLIL::unescape_id(str).c_str());
log_cmd_error("Selection %s is not defined!\n", RTLIL::unescape_id(str));
} else
limits.insert(RTLIL::escape_id(str));
}
@ -658,7 +658,7 @@ static void select_op_expand(RTLIL::Design *design, const std::string &arg, char
}
if (rem_objects == 0)
log_warning("reached configured limit at `%s'.\n", arg.c_str());
log_warning("reached configured limit at `%s'.\n", arg);
}
static void select_filter_active_mod(RTLIL::Design *design, RTLIL::Selection &sel)
@ -804,7 +804,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp
log_cmd_error("Must have at least one element on the stack for operator %%coe.\n");
select_op_expand(design, arg, 'o', true);
} else
log_cmd_error("Unknown selection operator '%s'.\n", arg.c_str());
log_cmd_error("Unknown selection operator '%s'.\n", arg);
if (work_stack.size() >= 1)
select_filter_active_mod(design, work_stack.back());
return;
@ -815,7 +815,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp
if (design->selection_vars.count(set_name) > 0)
work_stack.push_back(design->selection_vars[set_name]);
else
log_cmd_error("Selection @%s is not defined!\n", RTLIL::unescape_id(set_name).c_str());
log_cmd_error("Selection @%s is not defined!\n", RTLIL::unescape_id(set_name));
select_filter_active_mod(design, work_stack.back());
return;
}
@ -934,7 +934,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp
if (arg_memb.compare(2, 1, "@") == 0) {
std::string set_name = RTLIL::escape_id(arg_memb.substr(3));
if (!design->selection_vars.count(set_name))
log_cmd_error("Selection @%s is not defined!\n", RTLIL::unescape_id(set_name).c_str());
log_cmd_error("Selection @%s is not defined!\n", RTLIL::unescape_id(set_name));
auto &muster = design->selection_vars[set_name];
for (auto cell : mod->cells())
@ -1002,14 +1002,14 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp
if (it.second == false && !disable_empty_warning) {
std::string selection_str = select_blackboxes ? "=" : "";
selection_str += it.first;
log_warning("Selection \"%s\" did not match any module.\n", selection_str.c_str());
log_warning("Selection \"%s\" did not match any module.\n", selection_str);
}
}
for (auto &it : arg_memb_found) {
if (it.second == false && !disable_empty_warning) {
std::string selection_str = select_blackboxes ? "=" : "";
selection_str += it.first;
log_warning("Selection \"%s\" did not match any object.\n", selection_str.c_str());
log_warning("Selection \"%s\" did not match any object.\n", selection_str);
}
}
}
@ -1428,7 +1428,7 @@ struct SelectPass : public Pass {
continue;
}
if (arg.size() > 0 && arg[0] == '-')
log_cmd_error("Unknown option %s.\n", arg.c_str());
log_cmd_error("Unknown option %s.\n", arg);
bool disable_empty_warning = count_mode || assert_none || assert_any || (assert_modcount != -1) ||
(assert_count != -1) || (assert_max != -1) || (assert_min != -1);
select_stmt(design, arg, disable_empty_warning);
@ -1451,7 +1451,7 @@ struct SelectPass : public Pass {
while (std::getline(f, line)) {
size_t slash_pos = line.find('/');
if (slash_pos == string::npos) {
log_warning("Ignoring line without slash in 'select -read': %s\n", line.c_str());
log_warning("Ignoring line without slash in 'select -read': %s\n", line);
continue;
}
IdString mod_name = RTLIL::escape_id(line.substr(0, slash_pos));
@ -1762,7 +1762,7 @@ struct CdPass : public Pass {
return;
}
log_cmd_error("No such module `%s' found!\n", RTLIL::unescape_id(modname).c_str());
log_cmd_error("No such module `%s' found!\n", RTLIL::unescape_id(modname));
}
} CdPass;

View File

@ -39,7 +39,7 @@ struct setunset_t
} else {
RTLIL::SigSpec sig_value;
if (!RTLIL::SigSpec::parse(sig_value, nullptr, set_value))
log_cmd_error("Can't decode value '%s'!\n", set_value.c_str());
log_cmd_error("Can't decode value '%s'!\n", set_value);
value = sig_value.as_const();
}
}

View File

@ -52,7 +52,7 @@ struct SetenvPass : public Pass {
_putenv_s(name.c_str(), value.c_str());
#else
if (setenv(name.c_str(), value.c_str(), 1))
log_cmd_error("Invalid name \"%s\".\n", name.c_str());
log_cmd_error("Invalid name \"%s\".\n", name);
#endif
}

View File

@ -243,7 +243,7 @@ struct SetundefPass : public Pass {
{
for (auto *cell : module->selected_cells()) {
for (auto &parameter : cell->parameters) {
for (auto &bit : parameter.second.bits()) {
for (auto bit : parameter.second) {
if (bit > RTLIL::State::S1)
bit = worker.next_bit();
}
@ -364,7 +364,7 @@ struct SetundefPass : public Pass {
for (auto cell : module->cells())
{
if (!RTLIL::builtin_ff_cell_types().count(cell->type))
if (!cell->is_builtin_ff())
continue;
for (auto bit : sigmap(cell->getPort(ID::Q)))
@ -390,12 +390,12 @@ struct SetundefPass : public Pass {
for (auto wire : initwires)
{
Const &initval = wire->attributes[ID::init];
initval.bits().resize(GetSize(wire), State::Sx);
initval.resize(GetSize(wire), State::Sx);
for (int i = 0; i < GetSize(wire); i++) {
SigBit bit = sigmap(SigBit(wire, i));
if (initval[i] == State::Sx && ffbits.count(bit)) {
initval.bits()[i] = worker.next_bit();
initval.set(i, worker.next_bit());
ffbits.erase(bit);
}
}
@ -421,7 +421,7 @@ struct SetundefPass : public Pass {
continue;
Const &initval = wire->attributes[ID::init];
initval.bits().resize(GetSize(wire), State::Sx);
initval.resize(GetSize(wire), State::Sx);
if (initval.is_fully_undef()) {
wire->attributes.erase(ID::init);

View File

@ -926,7 +926,7 @@ struct ShowPass : public Pass {
if (f == nullptr) {
for (auto lib : libs)
delete lib;
log_cmd_error("Can't open dot file `%s' for writing.\n", dot_file.c_str());
log_cmd_error("Can't open dot file `%s' for writing.\n", dot_file);
}
ShowWorker worker(f, design, libs, colorSeed, flag_width, flag_wireshape, flag_signed, flag_stretch, flag_enum, flag_abbreviate, flag_notitle, flag_href, color_selections, label_selections, colorattr);
fclose(f);

View File

@ -75,10 +75,11 @@ struct SplitnetsWorker
it = wire->attributes.find(ID::init);
if (it != wire->attributes.end()) {
Const old_init = it->second, new_init;
Const old_init = it->second;
RTLIL::Const::Builder new_init_bits_builder(width);
for (int i = offset; i < offset+width; i++)
new_init.bits().push_back(i < GetSize(old_init) ? old_init.at(i) : State::Sx);
new_wire->attributes.emplace(ID::init, new_init);
new_init_bits_builder.push_back(i < GetSize(old_init) ? old_init.at(i) : State::Sx);
new_wire->attributes.emplace(ID::init, new_init_bits_builder.build());
}
std::vector<RTLIL::SigBit> sigvec = RTLIL::SigSpec(new_wire).to_sigbit_vector();

View File

@ -477,9 +477,9 @@ struct StatPass : public Pass {
techname = args[++argidx];
continue;
}
if (args[argidx] == "-top" && argidx+1 < args.size()) {
if (design->module(RTLIL::escape_id(args[argidx+1])) == nullptr)
log_cmd_error("Can't find module %s.\n", args[argidx+1].c_str());
if (args[argidx] == "-top" && argidx + 1 < args.size()) {
if (design->module(RTLIL::escape_id(args[argidx + 1])) == nullptr)
log_cmd_error("Can't find module %s.\n", args[argidx + 1]);
top_mod = design->module(RTLIL::escape_id(args[++argidx]));
continue;
}
@ -495,7 +495,7 @@ struct StatPass : public Pass {
log_header(design, "Printing statistics.\n");
if (techname != "" && techname != "xilinx" && techname != "cmos" && !json_mode)
log_cmd_error("Unsupported technology: '%s'\n", techname.c_str());
log_cmd_error("Unsupported technology: '%s'\n", techname);
if (json_mode) {
log("{\n");

View File

@ -83,7 +83,7 @@ struct TeePass : public Pass {
if (f == NULL) {
for (auto cf : files_to_close)
fclose(cf);
log_cmd_error("Can't create file %s.\n", args[argidx].c_str());
log_cmd_error("Can't create file %s.\n", args[argidx]);
}
log_files.push_back(f);
files_to_close.push_back(f);

View File

@ -88,7 +88,7 @@ struct EstimateSta {
for (auto cell : m->cells()) {
SigSpec launch, sample;
if (RTLIL::builtin_ff_cell_types().count(cell->type)) {
if (cell->is_builtin_ff()) {
// collect launch and sample points for FF cell
FfData ff(nullptr, cell);
if (!ff.has_clk) {
@ -403,7 +403,7 @@ struct TimeestPass : Pass {
for (auto m : d->selected_modules()) {
if (!m->wire(RTLIL::escape_id(clk))) {
log_warning("No domain '%s' in module %s\n", clk.c_str(), log_id(m));
log_warning("No domain '%s' in module %s\n", clk, log_id(m));
continue;
}

View File

@ -994,7 +994,7 @@ struct VizPass : public Pass {
if (f != nullptr) return;
f = fopen(dot_file.c_str(), "w");
if (f == nullptr)
log_cmd_error("Can't open dot file `%s' for writing.\n", dot_file.c_str());
log_cmd_error("Can't open dot file `%s' for writing.\n", dot_file);
};
for (auto module : modlist) {
VizWorker worker(module, config);

View File

@ -302,7 +302,7 @@ struct XpropWorker
return;
}
if (RTLIL::builtin_ff_cell_types().count(cell->type) || cell->type == ID($anyinit)) {
if (cell->is_builtin_ff() || cell->type == ID($anyinit)) {
FfData ff(&initvals, cell);
if (cell->type != ID($anyinit))
@ -828,9 +828,9 @@ struct XpropWorker
auto init_q_is_1 = init_q;
auto init_q_is_x = init_q;
for (auto &bit : init_q_is_1.bits())
for (auto bit : init_q_is_1)
bit = bit == State::S1 ? State::S1 : State::S0;
for (auto &bit : init_q_is_x.bits())
for (auto bit : init_q_is_x)
bit = bit == State::Sx ? State::S1 : State::S0;
initvals.remove_init(sig_q);
@ -853,7 +853,7 @@ struct XpropWorker
return;
}
if (RTLIL::builtin_ff_cell_types().count(cell->type) || cell->type == ID($anyinit)) {
if (cell->is_builtin_ff() || cell->type == ID($anyinit)) {
FfData ff(&initvals, cell);
if ((ff.has_clk || ff.has_gclk) && !ff.has_ce && !ff.has_aload && !ff.has_srst && !ff.has_arst && !ff.has_sr) {
@ -865,14 +865,14 @@ struct XpropWorker
auto init_q_is_x = init_q;
if (ff.is_anyinit) {
for (auto &bit : init_q_is_1.bits())
for (auto bit : init_q_is_1)
bit = State::Sx;
for (auto &bit : init_q_is_x.bits())
for (auto bit : init_q_is_x)
bit = State::S0;
} else {
for (auto &bit : init_q_is_1.bits())
for (auto bit : init_q_is_1)
bit = bit == State::S1 ? State::S1 : State::S0;
for (auto &bit : init_q_is_x.bits())
for (auto bit : init_q_is_x)
bit = bit == State::Sx ? State::S1 : State::S0;
}

View File

@ -61,18 +61,18 @@ struct EquivAddPass : public Pass {
if (gold_cell == nullptr) {
if (try_mode) {
log_warning("Can't find gold cell '%s'.\n", args[2].c_str());
log_warning("Can't find gold cell '%s'.\n", args[2]);
return;
}
log_cmd_error("Can't find gold cell '%s'.\n", args[2].c_str());
log_cmd_error("Can't find gold cell '%s'.\n", args[2]);
}
if (gate_cell == nullptr) {
if (try_mode) {
log_warning("Can't find gate cell '%s'.\n", args[3].c_str());
log_warning("Can't find gate cell '%s'.\n", args[3]);
return;
}
log_cmd_error("Can't find gate cell '%s'.\n", args[3].c_str());
log_cmd_error("Can't find gate cell '%s'.\n", args[3]);
}
for (auto conn : gold_cell->connections())
@ -126,18 +126,18 @@ struct EquivAddPass : public Pass {
if (!SigSpec::parse(gate_signal, module, args[2])) {
if (try_mode) {
log_warning("Error in gate signal: %s\n", args[2].c_str());
log_warning("Error in gate signal: %s\n", args[2]);
return;
}
log_cmd_error("Error in gate signal: %s\n", args[2].c_str());
log_cmd_error("Error in gate signal: %s\n", args[2]);
}
if (!SigSpec::parse_rhs(gate_signal, gold_signal, module, args[1])) {
if (try_mode) {
log_warning("Error in gold signal: %s\n", args[1].c_str());
log_warning("Error in gold signal: %s\n", args[1]);
return;
}
log_cmd_error("Error in gold signal: %s\n", args[1].c_str());
log_cmd_error("Error in gold signal: %s\n", args[1]);
}
log_assert(GetSize(gold_signal) == GetSize(gate_signal));

View File

@ -56,7 +56,7 @@ struct EquivInductWorker
for (auto cell : cells) {
if (!satgen.importCell(cell, step) && !cell_warn_cache.count(cell)) {
if (RTLIL::builtin_ff_cell_types().count(cell->type))
if (cell->is_builtin_ff())
log_warning("No SAT model available for async FF cell %s (%s). Consider running `async2sync` or `clk2fflogic` first.\n", log_id(cell), log_id(cell->type));
else
log_warning("No SAT model available for cell %s (%s).\n", log_id(cell), log_id(cell->type));

View File

@ -48,7 +48,7 @@ struct EquivMakeWorker
{
std::ifstream f(fn);
if (f.fail())
log_cmd_error("Can't open blacklist file '%s'!\n", fn.c_str());
log_cmd_error("Can't open blacklist file '%s'!\n", fn);
string line, token;
while (std::getline(f, line)) {
@ -68,7 +68,7 @@ struct EquivMakeWorker
{
std::ifstream f(fn);
if (f.fail())
log_cmd_error("Can't open encfile '%s'!\n", fn.c_str());
log_cmd_error("Can't open encfile '%s'!\n", fn);
dict<Const, Const> *ed = nullptr;
string line, token;
@ -82,7 +82,7 @@ struct EquivMakeWorker
IdString modname = RTLIL::escape_id(next_token(line));
IdString signame = RTLIL::escape_id(next_token(line));
if (encdata.count(signame))
log_cmd_error("Re-definition of signal '%s' in encfile '%s'!\n", signame.c_str(), fn.c_str());
log_cmd_error("Re-definition of signal '%s' in encfile '%s'!\n", signame, fn);
encdata[signame] = dict<Const, Const>();
ed = &encdata[signame];
continue;
@ -95,7 +95,7 @@ struct EquivMakeWorker
continue;
}
log_cmd_error("Syntax error in encfile '%s'!\n", fn.c_str());
log_cmd_error("Syntax error in encfile '%s'!\n", fn);
}
}
}
@ -502,13 +502,13 @@ struct EquivMakePass : public Pass {
worker.equiv_mod = design->module(RTLIL::escape_id(args[argidx+2]));
if (worker.gold_mod == nullptr)
log_cmd_error("Can't find gold module %s.\n", args[argidx].c_str());
log_cmd_error("Can't find gold module %s.\n", args[argidx]);
if (worker.gate_mod == nullptr)
log_cmd_error("Can't find gate module %s.\n", args[argidx+1].c_str());
log_cmd_error("Can't find gate module %s.\n", args[argidx+1]);
if (worker.equiv_mod != nullptr)
log_cmd_error("Equiv module %s already exists.\n", args[argidx+2].c_str());
log_cmd_error("Equiv module %s already exists.\n", args[argidx+2]);
if (worker.gold_mod->has_memories() || worker.gold_mod->has_processes())
log_cmd_error("Gold module contains memories or processes. Run 'memory' or 'proc' respectively.\n");

View File

@ -93,7 +93,7 @@ struct EquivSimpleWorker
for (auto &conn : cell->connections())
if (yosys_celltypes.cell_input(cell->type, conn.first))
for (auto bit : model.sigmap(conn.second)) {
if (RTLIL::builtin_ff_cell_types().count(cell->type)) {
if (cell->is_builtin_ff()) {
if (!conn.first.in(ID::CLK, ID::C))
next_seed.insert(bit);
} else
@ -231,7 +231,7 @@ struct EquivSimpleWorker
static void report_missing_model(Cell* cell)
{
if (RTLIL::builtin_ff_cell_types().count(cell->type))
if (cell->is_builtin_ff())
log_cmd_error("No SAT model available for async FF cell %s (%s). Consider running `async2sync` or `clk2fflogic` first.\n", log_id(cell), log_id(cell->type));
else
log_cmd_error("No SAT model available for cell %s (%s).\n", log_id(cell), log_id(cell->type));

View File

@ -225,7 +225,7 @@ static void detect_fsm(RTLIL::Wire *wire, bool ignore_self_reset=false)
if (!warnings.empty()) {
string warnmsg = stringf("Regarding the user-specified fsm_encoding attribute on %s.%s:\n", log_id(wire->module), log_id(wire));
for (auto w : warnings) warnmsg += " " + w;
log_warning("%s", warnmsg.c_str());
log_warning("%s", warnmsg);
} else {
log("FSM state register %s.%s already has fsm_encoding attribute.\n", log_id(wire->module), log_id(wire));
}

View File

@ -171,7 +171,7 @@ undef_bit_in_next_state:
if (tr.ctrl_in.at(it.second) == State::S1 && exclusive_ctrls.count(it.first) != 0)
for (auto &dc_bit : exclusive_ctrls.at(it.first))
if (ctrl_in_bit_indices.count(dc_bit))
tr.ctrl_in.bits().at(ctrl_in_bit_indices.at(dc_bit)) = RTLIL::State::Sa;
tr.ctrl_in.set(ctrl_in_bit_indices.at(dc_bit), RTLIL::State::Sa);
RTLIL::Const log_state_in = RTLIL::Const(RTLIL::State::Sx, fsm_data.state_bits);
if (state_in >= 0)

View File

@ -176,7 +176,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module)
state_dff->type = ID($adff);
state_dff->parameters[ID::ARST_POLARITY] = fsm_cell->parameters[ID::ARST_POLARITY];
state_dff->parameters[ID::ARST_VALUE] = fsm_data.state_table[fsm_data.reset_state];
for (auto &bit : state_dff->parameters[ID::ARST_VALUE].bits())
for (auto bit : state_dff->parameters[ID::ARST_VALUE])
if (bit != RTLIL::State::S1)
bit = RTLIL::State::S0;
state_dff->setPort(ID::ARST, fsm_cell->getPort(ID::ARST));

View File

@ -169,13 +169,16 @@ struct FsmOpt
for (auto tr : fsm_data.transition_table)
{
RTLIL::State &si = tr.ctrl_in.bits()[i];
RTLIL::State &sj = tr.ctrl_in.bits()[j];
RTLIL::State si = tr.ctrl_in[i];
RTLIL::State sj = tr.ctrl_in[j];
if (si > RTLIL::State::S1)
if (si > RTLIL::State::S1) {
si = sj;
else if (sj > RTLIL::State::S1)
tr.ctrl_in.set(i, si);
} else if (sj > RTLIL::State::S1) {
sj = si;
tr.ctrl_in.set(j, sj);
}
if (si == sj) {
RTLIL::SigSpec tmp(tr.ctrl_in);
@ -207,8 +210,8 @@ struct FsmOpt
for (auto tr : fsm_data.transition_table)
{
RTLIL::State &si = tr.ctrl_in.bits()[i];
RTLIL::State &sj = tr.ctrl_out.bits()[j];
RTLIL::State si = tr.ctrl_in[i];
RTLIL::State sj = tr.ctrl_out[j];
if (si > RTLIL::State::S1 || si == sj) {
RTLIL::SigSpec tmp(tr.ctrl_in);
@ -240,14 +243,14 @@ struct FsmOpt
RTLIL::Const other_pattern = pattern;
if (pattern[bit] == RTLIL::State::S1)
other_pattern.bits()[bit] = RTLIL::State::S0;
other_pattern.set(bit, RTLIL::State::S0);
else
other_pattern.bits()[bit] = RTLIL::State::S1;
other_pattern.set(bit, RTLIL::State::S1);
if (set.count(other_pattern) > 0) {
log(" Merging pattern %s and %s from group (%d %d %s).\n", log_signal(pattern), log_signal(other_pattern),
tr.state_in, tr.state_out, log_signal(tr.ctrl_out));
other_pattern.bits()[bit] = RTLIL::State::Sa;
other_pattern.set(bit, RTLIL::State::Sa);
new_set.insert(other_pattern);
did_something = true;
continue;

View File

@ -106,7 +106,7 @@ static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fs
if (encoding == "one-hot") {
new_code = RTLIL::Const(RTLIL::State::Sa, fsm_data.state_bits);
new_code.bits()[state_idx] = RTLIL::State::S1;
new_code.set(state_idx, RTLIL::State::S1);
} else
if (encoding == "binary") {
new_code = RTLIL::Const(state_idx, fsm_data.state_bits);

View File

@ -45,35 +45,27 @@ struct FsmData
cell->parameters[ID::STATE_NUM] = RTLIL::Const(state_table.size());
cell->parameters[ID::STATE_NUM_LOG2] = RTLIL::Const(state_num_log2);
cell->parameters[ID::STATE_RST] = RTLIL::Const(reset_state);
cell->parameters[ID::STATE_TABLE] = RTLIL::Const();
for (int i = 0; i < int(state_table.size()); i++) {
std::vector<RTLIL::State> &bits_table = cell->parameters[ID::STATE_TABLE].bits();
std::vector<RTLIL::State> &bits_state = state_table[i].bits();
bits_table.insert(bits_table.end(), bits_state.begin(), bits_state.end());
}
RTLIL::Const cell_state_table;
for (const RTLIL::Const &c : state_table)
cell_state_table.append(c);
cell->parameters[ID::STATE_TABLE] = std::move(cell_state_table);
cell->parameters[ID::TRANS_NUM] = RTLIL::Const(transition_table.size());
cell->parameters[ID::TRANS_TABLE] = RTLIL::Const();
RTLIL::Const cell_trans_table;
for (int i = 0; i < int(transition_table.size()); i++)
{
std::vector<RTLIL::State> &bits_table = cell->parameters[ID::TRANS_TABLE].bits();
transition_t &tr = transition_table[i];
RTLIL::Const const_state_in = RTLIL::Const(tr.state_in, state_num_log2);
RTLIL::Const const_state_out = RTLIL::Const(tr.state_out, state_num_log2);
std::vector<RTLIL::State> &bits_state_in = const_state_in.bits();
std::vector<RTLIL::State> &bits_state_out = const_state_out.bits();
std::vector<RTLIL::State> &bits_ctrl_in = tr.ctrl_in.bits();
std::vector<RTLIL::State> &bits_ctrl_out = tr.ctrl_out.bits();
// append lsb first
bits_table.insert(bits_table.end(), bits_ctrl_out.begin(), bits_ctrl_out.end());
bits_table.insert(bits_table.end(), bits_state_out.begin(), bits_state_out.end());
bits_table.insert(bits_table.end(), bits_ctrl_in.begin(), bits_ctrl_in.end());
bits_table.insert(bits_table.end(), bits_state_in.begin(), bits_state_in.end());
cell_trans_table.append(tr.ctrl_out);
cell_trans_table.append(const_state_out);
cell_trans_table.append(tr.ctrl_in);
cell_trans_table.append(const_state_in);
}
cell->parameters[ID::TRANS_TABLE] = std::move(cell_trans_table);
}
void copy_from_cell(RTLIL::Cell *cell)
@ -95,25 +87,18 @@ struct FsmData
const RTLIL::Const &trans_table = cell->parameters[ID::TRANS_TABLE];
for (int i = 0; i < state_num; i++) {
RTLIL::Const state_code;
int off_begin = i*state_bits, off_end = off_begin + state_bits;
state_code.bits().insert(state_code.bits().begin(), state_table.begin()+off_begin, state_table.begin()+off_end);
int off_begin = i*state_bits;
RTLIL::Const state_code = state_table.extract(off_begin, state_bits);
this->state_table.push_back(state_code);
}
for (int i = 0; i < trans_num; i++)
{
auto off_ctrl_out = trans_table.begin() + i*(num_inputs+num_outputs+2*state_num_log2);
auto off_state_out = off_ctrl_out + num_outputs;
auto off_ctrl_in = off_state_out + state_num_log2;
auto off_state_in = off_ctrl_in + num_inputs;
auto off_end = off_state_in + state_num_log2;
RTLIL::Const state_in, state_out, ctrl_in, ctrl_out;
ctrl_out.bits().insert(ctrl_out.bits().begin(), off_ctrl_out, off_state_out);
state_out.bits().insert(state_out.bits().begin(), off_state_out, off_ctrl_in);
ctrl_in.bits().insert(ctrl_in.bits().begin(), off_ctrl_in, off_state_in);
state_in.bits().insert(state_in.bits().begin(), off_state_in, off_end);
int base_offset = i*(num_inputs+num_outputs+2*state_num_log2);
RTLIL::Const ctrl_out = trans_table.extract(base_offset, num_outputs);
RTLIL::Const state_out = trans_table.extract(base_offset + num_outputs, state_num_log2);
RTLIL::Const ctrl_in = trans_table.extract(base_offset + num_outputs + state_num_log2, num_inputs);
RTLIL::Const state_in = trans_table.extract(base_offset + num_outputs + state_num_log2 + num_inputs, state_num_log2);
transition_t tr;
tr.state_in = state_in.as_int();

View File

@ -937,7 +937,7 @@ struct HierarchyPass : public Pass {
const std::string &value = args[++argidx];
auto r = parameters.emplace(key, value);
if (!r.second) {
log_warning("-chparam %s already specified: overwriting.\n", key.c_str());
log_warning("-chparam %s already specified: overwriting.\n", key);
r.first->second = value;
}
continue;
@ -957,7 +957,7 @@ struct HierarchyPass : public Pass {
for (auto &para : parameters) {
SigSpec sig_value;
if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second))
log_cmd_error("Can't decode value '%s'!\n", para.second.c_str());
log_cmd_error("Can't decode value '%s'!\n", para.second);
top_parameters[RTLIL::escape_id(para.first)] = sig_value.as_const();
}
}
@ -991,7 +991,7 @@ struct HierarchyPass : public Pass {
}
#endif
if (top_mod == NULL)
log_cmd_error("Module `%s' not found!\n", load_top_mod.c_str());
log_cmd_error("Module `%s' not found!\n", load_top_mod);
} else {
#ifdef YOSYS_ENABLE_VERIFIC
if (verific_import_pending)
@ -1045,7 +1045,7 @@ struct HierarchyPass : public Pass {
for (auto &para : parameters) {
SigSpec sig_value;
if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second))
log_cmd_error("Can't decode value '%s'!\n", para.second.c_str());
log_cmd_error("Can't decode value '%s'!\n", para.second);
top_parameters[RTLIL::escape_id(para.first)] = sig_value.as_const();
}

View File

@ -80,7 +80,7 @@ struct SubmodWorker
flag_wire(c.wire, create, set_int_used, set_ext_driven, set_ext_used);
if (set_int_driven)
for (int i = c.offset; i < c.offset+c.width; i++) {
wire_flags.at(c.wire).is_int_driven.bits()[i] = State::S1;
wire_flags.at(c.wire).is_int_driven.set(i, State::S1);
flag_found_something = true;
}
}
@ -97,7 +97,7 @@ struct SubmodWorker
for (auto &conn : cell->connections())
flag_signal(conn.second, true, ct.cell_output(cell->type, conn.first), ct.cell_input(cell->type, conn.first), false, false);
} else {
log_warning("Port directions for cell %s (%s) are unknown. Assuming inout for all ports.\n", cell->name.c_str(), cell->type.c_str());
log_warning("Port directions for cell %s (%s) are unknown. Assuming inout for all ports.\n", cell->name, cell->type);
for (auto &conn : cell->connections())
flag_signal(conn.second, true, true, true, false, false);
}
@ -113,7 +113,7 @@ struct SubmodWorker
for (auto &conn : cell->connections())
flag_signal(conn.second, false, false, false, true, true);
if (flag_found_something)
log_warning("Port directions for cell %s (%s) are unknown. Assuming inout for all ports.\n", cell->name.c_str(), cell->type.c_str());
log_warning("Port directions for cell %s (%s) are unknown. Assuming inout for all ports.\n", cell->name, cell->type);
}
}
@ -187,8 +187,8 @@ struct SubmodWorker
auto it = sig[i].wire->attributes.find(ID::init);
if (it != sig[i].wire->attributes.end()) {
auto jt = new_wire->attributes.insert(std::make_pair(ID::init, Const(State::Sx, GetSize(sig)))).first;
jt->second.bits()[i] = it->second[sig[i].offset];
it->second.bits()[sig[i].offset] = State::Sx;
jt->second.set(i, it->second[sig[i].offset]);
it->second.set(sig[i].offset, State::Sx);
}
}
}
@ -430,7 +430,7 @@ struct SubmodPass : public Pass {
RTLIL::Module *module = nullptr;
for (auto mod : design->selected_modules()) {
if (module != nullptr)
log_cmd_error("More than one module selected: %s %s\n", module->name.c_str(), mod->name.c_str());
log_cmd_error("More than one module selected: %s %s\n", module->name, mod->name);
module = mod;
}
if (module == nullptr)

View File

@ -1097,7 +1097,7 @@ Library MemLibrary::parse_library(const std::vector<std::string> &filenames, con
Parser(file, res, defines, defines_unused);
}
for (auto def: defines_unused) {
log_warning("define %s not used in the library.\n", def.c_str());
log_warning("define %s not used in the library.\n", def);
}
return res;
}

View File

@ -848,9 +848,9 @@ grow_read_ports:;
for (int i = 0; i < mem.width; i++)
if (shuffle_map[i] != -1) {
module->connect(port.data[shuffle_map[i]], new_data[i]);
new_init_value.bits()[i] = port.init_value[shuffle_map[i]];
new_arst_value.bits()[i] = port.arst_value[shuffle_map[i]];
new_srst_value.bits()[i] = port.srst_value[shuffle_map[i]];
new_init_value.set(i, port.init_value[shuffle_map[i]]);
new_arst_value.set(i, port.arst_value[shuffle_map[i]]);
new_srst_value.set(i, port.srst_value[shuffle_map[i]]);
}
port.data = new_data;
port.init_value = new_init_value;
@ -887,9 +887,9 @@ grow_read_ports:;
for (int i = 0; i < init_size; i++)
for (int j = 0; j < bram.dbits; j++)
if (init_offset+i < GetSize(initdata) && init_offset+i >= 0)
initparam.bits()[i*bram.dbits+j] = initdata[init_offset+i][init_shift+j];
initparam.set(i*bram.dbits+j, initdata[init_offset+i][init_shift+j]);
else
initparam.bits()[i*bram.dbits+j] = State::Sx;
initparam.set(i*bram.dbits+j, State::Sx);
c->setParam(ID::INIT, initparam);
}

View File

@ -60,16 +60,17 @@ struct MemoryShareWorker
bool merge_rst_value(Mem &mem, Const &res, int wide_log2, const Const &src1, int sub1, const Const &src2, int sub2) {
res = Const(State::Sx, mem.width << wide_log2);
for (int i = 0; i < GetSize(src1); i++)
res.bits()[i + sub1 * mem.width] = src1[i];
res.set(i + sub1 * mem.width, src1[i]);
for (int i = 0; i < GetSize(src2); i++) {
if (src2[i] == State::Sx)
continue;
auto &dst = res.bits()[i + sub2 * mem.width];
int idx = i + sub2 * mem.width;
RTLIL::State dst = res[idx];
if (dst == src2[i])
continue;
if (dst != State::Sx)
return false;
dst = src2[i];
res.set(idx, src2[i]);
}
return true;
}

View File

@ -206,7 +206,7 @@ void rmunused_module_cells(Module *module, bool verbose)
if (verbose)
log_debug(" removing unused `%s' cell `%s'.\n", cell->type.c_str(), cell->name.c_str());
module->design->scratchpad_set_bool("opt.did_something", true);
if (RTLIL::builtin_ff_cell_types().count(cell->type))
if (cell->is_builtin_ff())
ffinit.remove_init(cell->getPort(ID::Q));
module->remove(cell);
count_rm_cells++;
@ -233,7 +233,7 @@ void rmunused_module_cells(Module *module, bool verbose)
for (auto it : driver_driver_logs) {
if (used_raw_bits.count(it.first))
for (auto msg : it.second)
log_warning("%s\n", msg.c_str());
log_warning("%s\n", msg);
}
}
@ -406,7 +406,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool unused
for (int i = 0; i < wire->width; i++) {
auto it = init_bits.find(RTLIL::SigBit(wire, i));
if (it != init_bits.end()) {
val.bits()[i] = it->second;
val.set(i, it->second);
found = true;
}
}
@ -425,7 +425,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool unused
if (wire->attributes.count(ID::init))
initval = wire->attributes.at(ID::init);
if (GetSize(initval) != GetSize(wire))
initval.bits().resize(GetSize(wire), State::Sx);
initval.resize(GetSize(wire), State::Sx);
if (initval.is_fully_undef())
wire->attributes.erase(ID::init);
@ -457,7 +457,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool unused
if (s1[i] != s2[i]) {
if (s2[i] == State::Sx && (initval[i] == State::S0 || initval[i] == State::S1)) {
s2[i] = initval[i];
initval.bits()[i] = State::Sx;
initval.set(i, State::Sx);
}
new_conn.first.append(s1[i]);
new_conn.second.append(s2[i]);
@ -600,15 +600,40 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool unusedbitsattr
log("Finding unused cells or wires in module %s..\n", module->name);
std::vector<RTLIL::Cell*> delcells;
for (auto cell : module->cells())
for (auto cell : module->cells()) {
if (cell->type.in(ID($pos), ID($_BUF_), ID($buf)) && !cell->has_keep_attr()) {
bool is_signed = cell->type == ID($pos) && cell->getParam(ID::A_SIGNED).as_bool();
RTLIL::SigSpec a = cell->getPort(ID::A);
RTLIL::SigSpec y = cell->getPort(ID::Y);
a.extend_u0(GetSize(y), is_signed);
module->connect(y, a);
if (a.has_const(State::Sz)) {
SigSpec new_a;
SigSpec new_y;
for (int i = 0; i < GetSize(a); ++i) {
SigBit b = a[i];
if (b == State::Sz)
continue;
new_a.append(b);
new_y.append(y[i]);
}
a = std::move(new_a);
y = std::move(new_y);
}
if (!y.empty())
module->connect(y, a);
delcells.push_back(cell);
} else if (cell->type.in(ID($connect)) && !cell->has_keep_attr()) {
RTLIL::SigSpec a = cell->getPort(ID::A);
RTLIL::SigSpec b = cell->getPort(ID::B);
if (a.has_const() && !b.has_const())
std::swap(a, b);
module->connect(a, b);
delcells.push_back(cell);
} else if (cell->type.in(ID($input_port)) && !cell->has_keep_attr()) {
delcells.push_back(cell);
}
}
for (auto cell : delcells) {
if (verbose)
log_debug(" removing buffer cell `%s': %s = %s\n", cell->name.c_str(),

View File

@ -89,7 +89,7 @@ struct OptDffWorker
}
}
if (module->design->selected(module, cell) && RTLIL::builtin_ff_cell_types().count(cell->type))
if (module->design->selected(module, cell) && cell->is_builtin_ff())
dff_cells.push_back(cell);
}
@ -409,27 +409,29 @@ struct OptDffWorker
} else if (ff.pol_clr == ff.pol_set) {
// Try a more complex conversion to plain async reset.
State val_neutral = ff.pol_set ? State::S0 : State::S1;
Const val_arst;
SigBit sig_arst;
if (ff.sig_clr[0] == val_neutral)
sig_arst = ff.sig_set[0];
else
sig_arst = ff.sig_clr[0];
bool failed = false;
Const::Builder val_arst_builder(ff.width);
for (int i = 0; i < ff.width; i++) {
if (ff.sig_clr[i] == sig_arst && ff.sig_set[i] == val_neutral)
val_arst.bits().push_back(State::S0);
val_arst_builder.push_back(State::S0);
else if (ff.sig_set[i] == sig_arst && ff.sig_clr[i] == val_neutral)
val_arst.bits().push_back(State::S1);
else
val_arst_builder.push_back(State::S1);
else {
failed = true;
break;
}
}
if (!failed) {
log_debug("Converting CLR/SET to ARST on %s (%s) from module %s.\n",
log_id(cell), log_id(cell->type), log_id(module));
ff.has_sr = false;
ff.has_arst = true;
ff.val_arst = val_arst;
ff.val_arst = val_arst_builder.build();
ff.sig_arst = sig_arst;
ff.pol_arst = ff.pol_clr;
changed = true;
@ -648,7 +650,7 @@ struct OptDffWorker
std::map<ctrls_t, std::vector<int>> groups;
std::vector<int> remaining_indices;
std::vector<Cell *> new_cells;
Const val_srst;
Const::Builder val_srst_builder(ff.width);
for (int i = 0 ; i < ff.width; i++) {
ctrls_t resets;
@ -690,17 +692,19 @@ struct OptDffWorker
groups[resets].push_back(i);
} else
remaining_indices.push_back(i);
val_srst.bits().push_back(reset_val);
val_srst_builder.push_back(reset_val);
}
Const val_srst = val_srst_builder.build();
for (auto &it : groups) {
FfData new_ff = ff.slice(it.second);
new_ff.val_srst = Const();
Const::Builder new_val_srst_builder(new_ff.width);
for (int i = 0; i < new_ff.width; i++) {
int j = it.second[i];
new_ff.val_srst.bits().push_back(val_srst[j]);
new_val_srst_builder.push_back(val_srst[j]);
}
ctrl_t srst = combine_resets(it.first, ff.is_fine, module, cell);
new_ff.val_srst = new_val_srst_builder.build();
ctrl_t srst = combine_resets(it.first, ff.is_fine);
new_ff.has_srst = true;
new_ff.sig_srst = srst.first;
@ -820,7 +824,7 @@ struct OptDffWorker
bool did_something = false;
for (auto cell : module->selected_cells()) {
if (!RTLIL::builtin_ff_cell_types().count(cell->type))
if (!cell->is_builtin_ff())
continue;
FfData ff(&initvals, cell);

Some files were not shown because too many files have changed in this diff Show More