mirror of https://github.com/YosysHQ/yosys.git
Bump to latest
This commit is contained in:
commit
60d969530b
|
|
@ -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
|
||||
|
|
|
|||
3
Makefile
3
Makefile
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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:;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 ¶m : 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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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") {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
31
kernel/ff.cc
31
kernel/ff.cc
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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. "
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
465
kernel/rtlil.cc
465
kernel/rtlil.cc
|
|
@ -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()
|
||||
|
|
|
|||
158
kernel/rtlil.h
158
kernel/rtlil.h
|
|
@ -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 ¶mname) 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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 + ")";
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ struct SetundefPass : public Pass {
|
|||
{
|
||||
for (auto *cell : module->selected_cells()) {
|
||||
for (auto ¶meter : 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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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 ¶ : 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 ¶ : 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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue