mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-21 14:45:50 +00:00
Merge remote-tracking branch 'upstream/main' into silimate
This commit is contained in:
commit
e58125b605
834 changed files with 25281 additions and 8780 deletions
606
kernel/rtlil.cc
606
kernel/rtlil.cc
|
|
@ -19,9 +19,10 @@
|
|||
|
||||
#include "kernel/yosys.h"
|
||||
#include "kernel/macc.h"
|
||||
#include "kernel/celltypes.h"
|
||||
#include "kernel/newcelltypes.h"
|
||||
#include "kernel/binding.h"
|
||||
#include "kernel/sigtools.h"
|
||||
#include "kernel/threading.h"
|
||||
#include "frontends/verilog/verilog_frontend.h"
|
||||
#include "frontends/verilog/preproc.h"
|
||||
#include "backends/rtlil/rtlil_backend.h"
|
||||
|
|
@ -144,9 +145,17 @@ static constexpr bool check_well_known_id_order()
|
|||
// and in sorted ascii order, as required by the ID macro.
|
||||
static_assert(check_well_known_id_order());
|
||||
|
||||
constexpr int STATIC_ID_END = static_cast<int>(RTLIL::StaticId::STATIC_ID_END);
|
||||
|
||||
struct IdStringCollector {
|
||||
IdStringCollector(std::vector<MonotonicFlag> &live_ids)
|
||||
: live_ids(live_ids) {}
|
||||
|
||||
void trace(IdString id) {
|
||||
live.insert(id.index_);
|
||||
if (id.index_ >= STATIC_ID_END)
|
||||
live_ids[id.index_ - STATIC_ID_END].set();
|
||||
else if (id.index_ < 0)
|
||||
live_autoidx_ids.push_back(id.index_);
|
||||
}
|
||||
template <typename T> void trace(const T* v) {
|
||||
trace(*v);
|
||||
|
|
@ -180,10 +189,6 @@ struct IdStringCollector {
|
|||
trace(element);
|
||||
}
|
||||
|
||||
void trace(const RTLIL::Design &design) {
|
||||
trace_values(design.modules_);
|
||||
trace(design.selection_vars);
|
||||
}
|
||||
void trace(const RTLIL::Selection &selection_var) {
|
||||
trace(selection_var.selected_modules);
|
||||
trace(selection_var.selected_members);
|
||||
|
|
@ -192,15 +197,6 @@ struct IdStringCollector {
|
|||
trace_keys(named.attributes);
|
||||
trace(named.name);
|
||||
}
|
||||
void trace(const RTLIL::Module &module) {
|
||||
trace_named(module);
|
||||
trace_values(module.wires_);
|
||||
trace_values(module.cells_);
|
||||
trace(module.avail_parameters);
|
||||
trace_keys(module.parameter_default_values);
|
||||
trace_values(module.memories);
|
||||
trace_values(module.processes);
|
||||
}
|
||||
void trace(const RTLIL::Wire &wire) {
|
||||
trace_named(wire);
|
||||
if (wire.known_driver())
|
||||
|
|
@ -236,7 +232,8 @@ struct IdStringCollector {
|
|||
trace(action.memid);
|
||||
}
|
||||
|
||||
std::unordered_set<int> live;
|
||||
std::vector<MonotonicFlag> &live_ids;
|
||||
std::vector<int> live_autoidx_ids;
|
||||
};
|
||||
|
||||
int64_t RTLIL::OwningIdString::gc_ns;
|
||||
|
|
@ -245,20 +242,55 @@ int RTLIL::OwningIdString::gc_count;
|
|||
void RTLIL::OwningIdString::collect_garbage()
|
||||
{
|
||||
int64_t start = PerformanceTimer::query();
|
||||
IdStringCollector collector;
|
||||
for (auto &[idx, design] : *RTLIL::Design::get_all_designs()) {
|
||||
collector.trace(*design);
|
||||
}
|
||||
int size = GetSize(global_id_storage_);
|
||||
for (int i = static_cast<int>(StaticId::STATIC_ID_END); i < size; ++i) {
|
||||
RTLIL::IdString::Storage &storage = global_id_storage_.at(i);
|
||||
if (storage.buf == nullptr)
|
||||
continue;
|
||||
if (collector.live.find(i) != collector.live.end())
|
||||
continue;
|
||||
if (global_refcount_storage_.find(i) != global_refcount_storage_.end())
|
||||
continue;
|
||||
|
||||
int pool_size = 0;
|
||||
for (auto &[idx, design] : *RTLIL::Design::get_all_designs())
|
||||
for (RTLIL::Module *module : design->modules())
|
||||
pool_size = std::max(pool_size, ThreadPool::work_pool_size(0, module->cells_size(), 1000));
|
||||
ParallelDispatchThreadPool thread_pool(pool_size);
|
||||
|
||||
int size = GetSize(global_id_storage_);
|
||||
std::vector<MonotonicFlag> live_ids(size - STATIC_ID_END);
|
||||
std::vector<IdStringCollector> collectors;
|
||||
int num_threads = thread_pool.num_threads();
|
||||
collectors.reserve(num_threads);
|
||||
for (int i = 0; i < num_threads; ++i)
|
||||
collectors.emplace_back(live_ids);
|
||||
|
||||
for (auto &[idx, design] : *RTLIL::Design::get_all_designs()) {
|
||||
for (RTLIL::Module *module : design->modules()) {
|
||||
collectors[0].trace_named(*module);
|
||||
ParallelDispatchThreadPool::Subpool subpool(thread_pool, ThreadPool::work_pool_size(0, module->cells_size(), 1000));
|
||||
subpool.run([&collectors, module](const ParallelDispatchThreadPool::RunCtx &ctx) {
|
||||
for (int i : ctx.item_range(module->cells_size()))
|
||||
collectors[ctx.thread_num].trace(module->cell_at(i));
|
||||
for (int i : ctx.item_range(module->wires_size()))
|
||||
collectors[ctx.thread_num].trace(module->wire_at(i));
|
||||
});
|
||||
collectors[0].trace(module->avail_parameters);
|
||||
collectors[0].trace_keys(module->parameter_default_values);
|
||||
collectors[0].trace_values(module->memories);
|
||||
collectors[0].trace_values(module->processes);
|
||||
}
|
||||
collectors[0].trace(design->selection_vars);
|
||||
}
|
||||
|
||||
ShardedVector<int> free_ids(thread_pool);
|
||||
thread_pool.run([&live_ids, size, &free_ids](const ParallelDispatchThreadPool::RunCtx &ctx) {
|
||||
for (int i : ctx.item_range(size - STATIC_ID_END)) {
|
||||
int index = i + STATIC_ID_END;
|
||||
RTLIL::IdString::Storage &storage = global_id_storage_.at(index);
|
||||
if (storage.buf == nullptr)
|
||||
continue;
|
||||
if (live_ids[i].load())
|
||||
continue;
|
||||
if (global_refcount_storage_.find(index) != global_refcount_storage_.end())
|
||||
continue;
|
||||
free_ids.insert(ctx, index);
|
||||
}
|
||||
});
|
||||
for (int i : free_ids) {
|
||||
RTLIL::IdString::Storage &storage = global_id_storage_.at(i);
|
||||
if (yosys_xtrace) {
|
||||
log("#X# Removed IdString '%s' with index %d.\n", storage.buf, i);
|
||||
log_backtrace("-X- ", yosys_xtrace-1);
|
||||
|
|
@ -270,8 +302,13 @@ void RTLIL::OwningIdString::collect_garbage()
|
|||
global_free_idx_list_.push_back(i);
|
||||
}
|
||||
|
||||
std::unordered_set<int> live_autoidx_ids;
|
||||
for (IdStringCollector &collector : collectors)
|
||||
for (int id : collector.live_autoidx_ids)
|
||||
live_autoidx_ids.insert(id);
|
||||
|
||||
for (auto it = global_autoidx_id_storage_.begin(); it != global_autoidx_id_storage_.end();) {
|
||||
if (collector.live.find(it->first) != collector.live.end()) {
|
||||
if (live_autoidx_ids.find(it->first) != live_autoidx_ids.end()) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -290,159 +327,17 @@ void RTLIL::OwningIdString::collect_garbage()
|
|||
|
||||
dict<std::string, std::string> RTLIL::constpad;
|
||||
|
||||
static const pool<IdString> &builtin_ff_cell_types_internal() {
|
||||
static const pool<IdString> res = {
|
||||
ID($sr),
|
||||
ID($ff),
|
||||
ID($dff),
|
||||
ID($dffe),
|
||||
ID($dffsr),
|
||||
ID($dffsre),
|
||||
ID($adff),
|
||||
ID($adffe),
|
||||
ID($aldff),
|
||||
ID($aldffe),
|
||||
ID($sdff),
|
||||
ID($sdffe),
|
||||
ID($sdffce),
|
||||
ID($dlatch),
|
||||
ID($adlatch),
|
||||
ID($dlatchsr),
|
||||
ID($_DFFE_NN_),
|
||||
ID($_DFFE_NP_),
|
||||
ID($_DFFE_PN_),
|
||||
ID($_DFFE_PP_),
|
||||
ID($_DFFSR_NNN_),
|
||||
ID($_DFFSR_NNP_),
|
||||
ID($_DFFSR_NPN_),
|
||||
ID($_DFFSR_NPP_),
|
||||
ID($_DFFSR_PNN_),
|
||||
ID($_DFFSR_PNP_),
|
||||
ID($_DFFSR_PPN_),
|
||||
ID($_DFFSR_PPP_),
|
||||
ID($_DFFSRE_NNNN_),
|
||||
ID($_DFFSRE_NNNP_),
|
||||
ID($_DFFSRE_NNPN_),
|
||||
ID($_DFFSRE_NNPP_),
|
||||
ID($_DFFSRE_NPNN_),
|
||||
ID($_DFFSRE_NPNP_),
|
||||
ID($_DFFSRE_NPPN_),
|
||||
ID($_DFFSRE_NPPP_),
|
||||
ID($_DFFSRE_PNNN_),
|
||||
ID($_DFFSRE_PNNP_),
|
||||
ID($_DFFSRE_PNPN_),
|
||||
ID($_DFFSRE_PNPP_),
|
||||
ID($_DFFSRE_PPNN_),
|
||||
ID($_DFFSRE_PPNP_),
|
||||
ID($_DFFSRE_PPPN_),
|
||||
ID($_DFFSRE_PPPP_),
|
||||
ID($_DFF_N_),
|
||||
ID($_DFF_P_),
|
||||
ID($_DFF_NN0_),
|
||||
ID($_DFF_NN1_),
|
||||
ID($_DFF_NP0_),
|
||||
ID($_DFF_NP1_),
|
||||
ID($_DFF_PN0_),
|
||||
ID($_DFF_PN1_),
|
||||
ID($_DFF_PP0_),
|
||||
ID($_DFF_PP1_),
|
||||
ID($_DFFE_NN0N_),
|
||||
ID($_DFFE_NN0P_),
|
||||
ID($_DFFE_NN1N_),
|
||||
ID($_DFFE_NN1P_),
|
||||
ID($_DFFE_NP0N_),
|
||||
ID($_DFFE_NP0P_),
|
||||
ID($_DFFE_NP1N_),
|
||||
ID($_DFFE_NP1P_),
|
||||
ID($_DFFE_PN0N_),
|
||||
ID($_DFFE_PN0P_),
|
||||
ID($_DFFE_PN1N_),
|
||||
ID($_DFFE_PN1P_),
|
||||
ID($_DFFE_PP0N_),
|
||||
ID($_DFFE_PP0P_),
|
||||
ID($_DFFE_PP1N_),
|
||||
ID($_DFFE_PP1P_),
|
||||
ID($_ALDFF_NN_),
|
||||
ID($_ALDFF_NP_),
|
||||
ID($_ALDFF_PN_),
|
||||
ID($_ALDFF_PP_),
|
||||
ID($_ALDFFE_NNN_),
|
||||
ID($_ALDFFE_NNP_),
|
||||
ID($_ALDFFE_NPN_),
|
||||
ID($_ALDFFE_NPP_),
|
||||
ID($_ALDFFE_PNN_),
|
||||
ID($_ALDFFE_PNP_),
|
||||
ID($_ALDFFE_PPN_),
|
||||
ID($_ALDFFE_PPP_),
|
||||
ID($_SDFF_NN0_),
|
||||
ID($_SDFF_NN1_),
|
||||
ID($_SDFF_NP0_),
|
||||
ID($_SDFF_NP1_),
|
||||
ID($_SDFF_PN0_),
|
||||
ID($_SDFF_PN1_),
|
||||
ID($_SDFF_PP0_),
|
||||
ID($_SDFF_PP1_),
|
||||
ID($_SDFFE_NN0N_),
|
||||
ID($_SDFFE_NN0P_),
|
||||
ID($_SDFFE_NN1N_),
|
||||
ID($_SDFFE_NN1P_),
|
||||
ID($_SDFFE_NP0N_),
|
||||
ID($_SDFFE_NP0P_),
|
||||
ID($_SDFFE_NP1N_),
|
||||
ID($_SDFFE_NP1P_),
|
||||
ID($_SDFFE_PN0N_),
|
||||
ID($_SDFFE_PN0P_),
|
||||
ID($_SDFFE_PN1N_),
|
||||
ID($_SDFFE_PN1P_),
|
||||
ID($_SDFFE_PP0N_),
|
||||
ID($_SDFFE_PP0P_),
|
||||
ID($_SDFFE_PP1N_),
|
||||
ID($_SDFFE_PP1P_),
|
||||
ID($_SDFFCE_NN0N_),
|
||||
ID($_SDFFCE_NN0P_),
|
||||
ID($_SDFFCE_NN1N_),
|
||||
ID($_SDFFCE_NN1P_),
|
||||
ID($_SDFFCE_NP0N_),
|
||||
ID($_SDFFCE_NP0P_),
|
||||
ID($_SDFFCE_NP1N_),
|
||||
ID($_SDFFCE_NP1P_),
|
||||
ID($_SDFFCE_PN0N_),
|
||||
ID($_SDFFCE_PN0P_),
|
||||
ID($_SDFFCE_PN1N_),
|
||||
ID($_SDFFCE_PN1P_),
|
||||
ID($_SDFFCE_PP0N_),
|
||||
ID($_SDFFCE_PP0P_),
|
||||
ID($_SDFFCE_PP1N_),
|
||||
ID($_SDFFCE_PP1P_),
|
||||
ID($_SR_NN_),
|
||||
ID($_SR_NP_),
|
||||
ID($_SR_PN_),
|
||||
ID($_SR_PP_),
|
||||
ID($_DLATCH_N_),
|
||||
ID($_DLATCH_P_),
|
||||
ID($_DLATCH_NN0_),
|
||||
ID($_DLATCH_NN1_),
|
||||
ID($_DLATCH_NP0_),
|
||||
ID($_DLATCH_NP1_),
|
||||
ID($_DLATCH_PN0_),
|
||||
ID($_DLATCH_PN1_),
|
||||
ID($_DLATCH_PP0_),
|
||||
ID($_DLATCH_PP1_),
|
||||
ID($_DLATCHSR_NNN_),
|
||||
ID($_DLATCHSR_NNP_),
|
||||
ID($_DLATCHSR_NPN_),
|
||||
ID($_DLATCHSR_NPP_),
|
||||
ID($_DLATCHSR_PNN_),
|
||||
ID($_DLATCHSR_PNP_),
|
||||
ID($_DLATCHSR_PPN_),
|
||||
ID($_DLATCHSR_PPP_),
|
||||
ID($_FF_),
|
||||
};
|
||||
return res;
|
||||
}
|
||||
|
||||
const pool<IdString> &RTLIL::builtin_ff_cell_types() {
|
||||
return builtin_ff_cell_types_internal();
|
||||
static const pool<IdString> res = []() {
|
||||
pool<IdString> r;
|
||||
for (size_t i = 0; i < StaticCellTypes::builder.count; i++) {
|
||||
auto &cell = StaticCellTypes::builder.cells[i];
|
||||
if (cell.features.is_ff)
|
||||
r.insert(cell.type);
|
||||
}
|
||||
return r;
|
||||
}();
|
||||
return res;
|
||||
}
|
||||
|
||||
#define check(condition) log_assert(condition && "malformed Const union")
|
||||
|
|
@ -1333,7 +1228,7 @@ void RTLIL::Design::add(RTLIL::Module *module)
|
|||
mon->notify_module_add(module);
|
||||
|
||||
if (yosys_xtrace) {
|
||||
log("#X# New Module: %s\n", log_id(module));
|
||||
log("#X# New Module: %s\n", module);
|
||||
log_backtrace("-X- ", yosys_xtrace-1);
|
||||
}
|
||||
}
|
||||
|
|
@ -1361,7 +1256,7 @@ RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name)
|
|||
mon->notify_module_add(module);
|
||||
|
||||
if (yosys_xtrace) {
|
||||
log("#X# New Module: %s\n", log_id(module));
|
||||
log("#X# New Module: %s\n", module);
|
||||
log_backtrace("-X- ", yosys_xtrace-1);
|
||||
}
|
||||
|
||||
|
|
@ -1439,7 +1334,7 @@ void RTLIL::Design::remove(RTLIL::Module *module)
|
|||
mon->notify_module_del(module);
|
||||
|
||||
if (yosys_xtrace) {
|
||||
log("#X# Remove Module: %s\n", log_id(module));
|
||||
log("#X# Remove Module: %s\n", module);
|
||||
log_backtrace("-X- ", yosys_xtrace-1);
|
||||
}
|
||||
|
||||
|
|
@ -1470,15 +1365,21 @@ void RTLIL::Design::sort_modules()
|
|||
modules_.sort(sort_by_id_str());
|
||||
}
|
||||
|
||||
void check_module(RTLIL::Module *module, ParallelDispatchThreadPool &thread_pool);
|
||||
|
||||
void RTLIL::Design::check()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
log_assert(!selection_stack.empty());
|
||||
int pool_size = 0;
|
||||
for (auto &it : modules_)
|
||||
pool_size = std::max(pool_size, ThreadPool::work_pool_size(0, it.second->cells_size(), 1000));
|
||||
ParallelDispatchThreadPool thread_pool(pool_size);
|
||||
for (auto &it : modules_) {
|
||||
log_assert(this == it.second->design);
|
||||
log_assert(it.first == it.second->name);
|
||||
log_assert(!it.first.empty());
|
||||
it.second->check();
|
||||
check_module(it.second, thread_pool);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1575,22 +1476,22 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_modules(RTLIL::SelectPartial
|
|||
switch (boxes)
|
||||
{
|
||||
case RTLIL::SB_UNBOXED_WARN:
|
||||
log_warning("Ignoring boxed module %s.\n", log_id(it.first));
|
||||
log_warning("Ignoring boxed module %s.\n", it.first.unescape());
|
||||
break;
|
||||
case RTLIL::SB_EXCL_BB_WARN:
|
||||
log_warning("Ignoring blackbox module %s.\n", log_id(it.first));
|
||||
log_warning("Ignoring blackbox module %s.\n", it.first.unescape());
|
||||
break;
|
||||
case RTLIL::SB_UNBOXED_ERR:
|
||||
log_error("Unsupported boxed module %s.\n", log_id(it.first));
|
||||
log_error("Unsupported boxed module %s.\n", it.first.unescape());
|
||||
break;
|
||||
case RTLIL::SB_EXCL_BB_ERR:
|
||||
log_error("Unsupported blackbox module %s.\n", log_id(it.first));
|
||||
log_error("Unsupported blackbox module %s.\n", it.first.unescape());
|
||||
break;
|
||||
case RTLIL::SB_UNBOXED_CMDERR:
|
||||
log_cmd_error("Unsupported boxed module %s.\n", log_id(it.first));
|
||||
log_cmd_error("Unsupported boxed module %s.\n", it.first.unescape());
|
||||
break;
|
||||
case RTLIL::SB_EXCL_BB_CMDERR:
|
||||
log_cmd_error("Unsupported blackbox module %s.\n", log_id(it.first));
|
||||
log_cmd_error("Unsupported blackbox module %s.\n", it.first.unescape());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -1599,13 +1500,13 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_modules(RTLIL::SelectPartial
|
|||
switch(partials)
|
||||
{
|
||||
case RTLIL::SELECT_WHOLE_WARN:
|
||||
log_warning("Ignoring partially selected module %s.\n", log_id(it.first));
|
||||
log_warning("Ignoring partially selected module %s.\n", it.first.unescape());
|
||||
break;
|
||||
case RTLIL::SELECT_WHOLE_ERR:
|
||||
log_error("Unsupported partially selected module %s.\n", log_id(it.first));
|
||||
log_error("Unsupported partially selected module %s.\n", it.first.unescape());
|
||||
break;
|
||||
case RTLIL::SELECT_WHOLE_CMDERR:
|
||||
log_cmd_error("Unsupported partially selected module %s.\n", log_id(it.first));
|
||||
log_cmd_error("Unsupported partially selected module %s.\n", it.first.unescape());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -1682,7 +1583,7 @@ void RTLIL::Module::makeblackbox()
|
|||
|
||||
void RTLIL::Module::expand_interfaces(RTLIL::Design *, const dict<RTLIL::IdString, RTLIL::Module *> &)
|
||||
{
|
||||
log_error("Class doesn't support expand_interfaces (module: `%s')!\n", id2cstr(name));
|
||||
log_error("Class doesn't support expand_interfaces (module: `%s')!\n", name.unescape());
|
||||
}
|
||||
|
||||
bool RTLIL::Module::reprocess_if_necessary(RTLIL::Design *)
|
||||
|
|
@ -1694,7 +1595,7 @@ RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString
|
|||
{
|
||||
if (mayfail)
|
||||
return RTLIL::IdString();
|
||||
log_error("Module `%s' is used with parameters but is not parametric!\n", id2cstr(name));
|
||||
log_error("Module `%s' is used with parameters but is not parametric!\n", name.unescape());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1702,7 +1603,7 @@ RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString
|
|||
{
|
||||
if (mayfail)
|
||||
return RTLIL::IdString();
|
||||
log_error("Module `%s' is used with parameters but is not parametric!\n", id2cstr(name));
|
||||
log_error("Module `%s' is used with parameters but is not parametric!\n", name.unescape());
|
||||
}
|
||||
|
||||
size_t RTLIL::Module::count_id(RTLIL::IdString id)
|
||||
|
|
@ -1714,11 +1615,11 @@ size_t RTLIL::Module::count_id(RTLIL::IdString id)
|
|||
namespace {
|
||||
struct InternalCellChecker
|
||||
{
|
||||
RTLIL::Module *module;
|
||||
const RTLIL::Module *module;
|
||||
RTLIL::Cell *cell;
|
||||
pool<RTLIL::IdString> expected_params, expected_ports;
|
||||
|
||||
InternalCellChecker(RTLIL::Module *module, RTLIL::Cell *cell) : module(module), cell(cell) { }
|
||||
InternalCellChecker(const RTLIL::Module *module, RTLIL::Cell *cell) : module(module), cell(cell) { }
|
||||
|
||||
void error(int linenr)
|
||||
{
|
||||
|
|
@ -2703,88 +2604,96 @@ void RTLIL::Module::sort()
|
|||
it.second->attributes.sort(sort_by_id_str());
|
||||
}
|
||||
|
||||
void RTLIL::Module::check()
|
||||
void check_module(RTLIL::Module *module, ParallelDispatchThreadPool &thread_pool)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
std::vector<bool> ports_declared;
|
||||
for (auto &it : wires_) {
|
||||
log_assert(this == it.second->module);
|
||||
log_assert(it.first == it.second->name);
|
||||
log_assert(!it.first.empty());
|
||||
log_assert(it.second->width >= 0);
|
||||
log_assert(it.second->port_id >= 0);
|
||||
for (auto &it2 : it.second->attributes)
|
||||
log_assert(!it2.first.empty());
|
||||
if (it.second->port_id) {
|
||||
log_assert(GetSize(ports) >= it.second->port_id);
|
||||
log_assert(ports.at(it.second->port_id-1) == it.first);
|
||||
log_assert(it.second->port_input || it.second->port_output);
|
||||
if (GetSize(ports_declared) < it.second->port_id)
|
||||
ports_declared.resize(it.second->port_id);
|
||||
log_assert(ports_declared[it.second->port_id-1] == false);
|
||||
ports_declared[it.second->port_id-1] = true;
|
||||
} else
|
||||
log_assert(!it.second->port_input && !it.second->port_output);
|
||||
}
|
||||
for (auto port_declared : ports_declared)
|
||||
log_assert(port_declared == true);
|
||||
log_assert(GetSize(ports) == GetSize(ports_declared));
|
||||
ParallelDispatchThreadPool::Subpool subpool(thread_pool, ThreadPool::work_pool_size(0, module->cells_size(), 1000));
|
||||
const RTLIL::Module *const_module = module;
|
||||
|
||||
for (auto &it : memories) {
|
||||
pool<std::string> memory_strings;
|
||||
for (auto &it : module->memories) {
|
||||
log_assert(it.first == it.second->name);
|
||||
log_assert(!it.first.empty());
|
||||
log_assert(it.second->width >= 0);
|
||||
log_assert(it.second->size >= 0);
|
||||
for (auto &it2 : it.second->attributes)
|
||||
log_assert(!it2.first.empty());
|
||||
memory_strings.insert(it.second->name.str());
|
||||
}
|
||||
|
||||
pool<IdString> packed_memids;
|
||||
std::vector<MonotonicFlag> ports_declared(GetSize(module->ports));
|
||||
ShardedVector<std::string> memids(subpool);
|
||||
subpool.run([const_module, &ports_declared, &memory_strings, &memids](const ParallelDispatchThreadPool::RunCtx &ctx) {
|
||||
for (int i : ctx.item_range(const_module->cells_size())) {
|
||||
auto it = *const_module->cells_.element(i);
|
||||
log_assert(const_module == it.second->module);
|
||||
log_assert(it.first == it.second->name);
|
||||
log_assert(!it.first.empty());
|
||||
log_assert(!it.second->type.empty());
|
||||
for (auto &it2 : it.second->connections()) {
|
||||
log_assert(!it2.first.empty());
|
||||
it2.second.check(const_module);
|
||||
}
|
||||
for (auto &it2 : it.second->attributes)
|
||||
log_assert(!it2.first.empty());
|
||||
for (auto &it2 : it.second->parameters)
|
||||
log_assert(!it2.first.empty());
|
||||
InternalCellChecker checker(const_module, it.second);
|
||||
checker.check();
|
||||
if (it.second->has_memid()) {
|
||||
log_assert(memory_strings.count(it.second->parameters.at(ID::MEMID).decode_string()));
|
||||
} else if (it.second->is_mem_cell()) {
|
||||
std::string memid = it.second->parameters.at(ID::MEMID).decode_string();
|
||||
log_assert(!memory_strings.count(memid));
|
||||
memids.insert(ctx, std::move(memid));
|
||||
}
|
||||
auto cell_mod = const_module->design->module(it.first);
|
||||
if (cell_mod != nullptr) {
|
||||
// assertion check below to make sure that there are no
|
||||
// cases where a cell has a blackbox attribute since
|
||||
// that is deprecated
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
log_assert(!it.second->get_blackbox_attribute());
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &it : cells_) {
|
||||
log_assert(this == it.second->module);
|
||||
log_assert(it.first == it.second->name);
|
||||
log_assert(!it.first.empty());
|
||||
log_assert(!it.second->type.empty());
|
||||
for (auto &it2 : it.second->connections()) {
|
||||
log_assert(!it2.first.empty());
|
||||
it2.second.check(this);
|
||||
for (int i : ctx.item_range(const_module->wires_size())) {
|
||||
auto it = *const_module->wires_.element(i);
|
||||
log_assert(const_module == it.second->module);
|
||||
log_assert(it.first == it.second->name);
|
||||
log_assert(!it.first.empty());
|
||||
log_assert(it.second->width >= 0);
|
||||
log_assert(it.second->port_id >= 0);
|
||||
for (auto &it2 : it.second->attributes)
|
||||
log_assert(!it2.first.empty());
|
||||
if (it.second->port_id) {
|
||||
log_assert(GetSize(const_module->ports) >= it.second->port_id);
|
||||
log_assert(const_module->ports.at(it.second->port_id-1) == it.first);
|
||||
log_assert(it.second->port_input || it.second->port_output);
|
||||
log_assert(it.second->port_id <= GetSize(ports_declared));
|
||||
bool previously_declared = ports_declared[it.second->port_id-1].set_and_return_old();
|
||||
log_assert(previously_declared == false);
|
||||
} else
|
||||
log_assert(!it.second->port_input && !it.second->port_output);
|
||||
}
|
||||
for (auto &it2 : it.second->attributes)
|
||||
log_assert(!it2.first.empty());
|
||||
for (auto &it2 : it.second->parameters)
|
||||
log_assert(!it2.first.empty());
|
||||
InternalCellChecker checker(this, it.second);
|
||||
checker.check();
|
||||
if (it.second->has_memid()) {
|
||||
log_assert(memories.count(it.second->parameters.at(ID::MEMID).decode_string()));
|
||||
} else if (it.second->is_mem_cell()) {
|
||||
IdString memid = it.second->parameters.at(ID::MEMID).decode_string();
|
||||
log_assert(!memories.count(memid));
|
||||
log_assert(!packed_memids.count(memid));
|
||||
packed_memids.insert(memid);
|
||||
}
|
||||
auto cell_mod = design->module(it.first);
|
||||
if (cell_mod != nullptr) {
|
||||
// assertion check below to make sure that there are no
|
||||
// cases where a cell has a blackbox attribute since
|
||||
// that is deprecated
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
log_assert(!it.second->get_blackbox_attribute());
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
}
|
||||
}
|
||||
});
|
||||
for (const MonotonicFlag &port_declared : ports_declared)
|
||||
log_assert(port_declared.load() == true);
|
||||
pool<std::string> memids_pool;
|
||||
for (std::string &memid : memids)
|
||||
log_assert(memids_pool.insert(memid).second);
|
||||
|
||||
for (auto &it : processes) {
|
||||
for (auto &it : module->processes) {
|
||||
log_assert(it.first == it.second->name);
|
||||
log_assert(!it.first.empty());
|
||||
log_assert(it.second->root_case.compare.empty());
|
||||
std::vector<CaseRule*> all_cases = {&it.second->root_case};
|
||||
std::vector<RTLIL::CaseRule*> all_cases = {&it.second->root_case};
|
||||
for (size_t i = 0; i < all_cases.size(); i++) {
|
||||
for (auto &switch_it : all_cases[i]->switches) {
|
||||
for (auto &case_it : switch_it->cases) {
|
||||
|
|
@ -2797,34 +2706,41 @@ void RTLIL::Module::check()
|
|||
}
|
||||
for (auto &sync_it : it.second->syncs) {
|
||||
switch (sync_it->type) {
|
||||
case SyncType::ST0:
|
||||
case SyncType::ST1:
|
||||
case SyncType::STp:
|
||||
case SyncType::STn:
|
||||
case SyncType::STe:
|
||||
case RTLIL::SyncType::ST0:
|
||||
case RTLIL::SyncType::ST1:
|
||||
case RTLIL::SyncType::STp:
|
||||
case RTLIL::SyncType::STn:
|
||||
case RTLIL::SyncType::STe:
|
||||
log_assert(!sync_it->signal.empty());
|
||||
break;
|
||||
case SyncType::STa:
|
||||
case SyncType::STg:
|
||||
case SyncType::STi:
|
||||
case RTLIL::SyncType::STa:
|
||||
case RTLIL::SyncType::STg:
|
||||
case RTLIL::SyncType::STi:
|
||||
log_assert(sync_it->signal.empty());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &it : connections_) {
|
||||
for (auto &it : module->connections_) {
|
||||
log_assert(it.first.size() == it.second.size());
|
||||
log_assert(!it.first.has_const());
|
||||
it.first.check(this);
|
||||
it.second.check(this);
|
||||
it.first.check(module);
|
||||
it.second.check(module);
|
||||
}
|
||||
|
||||
for (auto &it : attributes)
|
||||
for (auto &it : module->attributes)
|
||||
log_assert(!it.first.empty());
|
||||
#endif
|
||||
}
|
||||
|
||||
void RTLIL::Module::check()
|
||||
{
|
||||
int pool_size = ThreadPool::work_pool_size(0, cells_size(), 1000);
|
||||
ParallelDispatchThreadPool thread_pool(pool_size);
|
||||
check_module(this, thread_pool);
|
||||
}
|
||||
|
||||
void RTLIL::Module::optimize()
|
||||
{
|
||||
}
|
||||
|
|
@ -2893,14 +2809,14 @@ bool RTLIL::Module::has_processes() const
|
|||
bool RTLIL::Module::has_memories_warn() const
|
||||
{
|
||||
if (!memories.empty())
|
||||
log_warning("Ignoring module %s because it contains memories (run 'memory' command first).\n", log_id(this));
|
||||
log_warning("Ignoring module %s because it contains memories (run 'memory' command first).\n", this);
|
||||
return !memories.empty();
|
||||
}
|
||||
|
||||
bool RTLIL::Module::has_processes_warn() const
|
||||
{
|
||||
if (!processes.empty())
|
||||
log_warning("Ignoring module %s because it contains processes (run 'proc' command first).\n", log_id(this));
|
||||
log_warning("Ignoring module %s because it contains processes (run 'proc' command first).\n", this);
|
||||
return !processes.empty();
|
||||
}
|
||||
|
||||
|
|
@ -3206,7 +3122,7 @@ void RTLIL::Module::connect(const RTLIL::SigSig &conn)
|
|||
}
|
||||
|
||||
if (yosys_xtrace) {
|
||||
log("#X# Connect (SigSig) in %s: %s = %s (%d bits)\n", log_id(this), log_signal(conn.first), log_signal(conn.second), GetSize(conn.first));
|
||||
log("#X# Connect (SigSig) in %s: %s = %s (%d bits)\n", this, log_signal(conn.first), log_signal(conn.second), GetSize(conn.first));
|
||||
log_backtrace("-X- ", yosys_xtrace-1);
|
||||
}
|
||||
|
||||
|
|
@ -3229,7 +3145,7 @@ void RTLIL::Module::new_connections(const std::vector<RTLIL::SigSig> &new_conn)
|
|||
mon->notify_connect(this, new_conn);
|
||||
|
||||
if (yosys_xtrace) {
|
||||
log("#X# New connections vector in %s:\n", log_id(this));
|
||||
log("#X# New connections vector in %s:\n", this);
|
||||
for (auto &conn: new_conn)
|
||||
log("#X# %s = %s (%d bits)\n", log_signal(conn.first), log_signal(conn.second), GetSize(conn.first));
|
||||
log_backtrace("-X- ", yosys_xtrace-1);
|
||||
|
|
@ -4702,7 +4618,7 @@ bool RTLIL::Cell::is_mem_cell() const
|
|||
}
|
||||
|
||||
bool RTLIL::Cell::is_builtin_ff() const {
|
||||
return builtin_ff_cell_types_internal().count(type) > 0;
|
||||
return StaticCellTypes::categories.is_ff(type);
|
||||
}
|
||||
|
||||
RTLIL::SigChunk::SigChunk(const RTLIL::SigBit &bit)
|
||||
|
|
@ -5166,31 +5082,35 @@ void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *othe
|
|||
other->unpack();
|
||||
}
|
||||
|
||||
bool modified = false;
|
||||
bool other_modified = false;
|
||||
for (int i = GetSize(bits_) - 1; i >= 0; i--)
|
||||
{
|
||||
if (bits_[i].wire == NULL) continue;
|
||||
// Convert pattern to pool for O(1) lookup, avoiding O(n*m) chunk iteration
|
||||
pool<SigBit> pattern_bits;
|
||||
pattern_bits.reserve(pattern.size());
|
||||
for (auto &bit : pattern)
|
||||
if (bit.wire != NULL)
|
||||
pattern_bits.insert(bit);
|
||||
|
||||
for (auto &pattern_chunk : pattern.chunks())
|
||||
if (bits_[i].wire == pattern_chunk.wire &&
|
||||
bits_[i].offset >= pattern_chunk.offset &&
|
||||
bits_[i].offset < pattern_chunk.offset + pattern_chunk.width) {
|
||||
modified = true;
|
||||
bits_.erase(bits_.begin() + i);
|
||||
if (other != NULL) {
|
||||
other_modified = true;
|
||||
other->bits_.erase(other->bits_.begin() + i);
|
||||
}
|
||||
break;
|
||||
// Compact in-place to avoid O(n^2) erase operations
|
||||
size_t write_idx = 0;
|
||||
for (size_t read_idx = 0; read_idx < bits_.size(); read_idx++)
|
||||
{
|
||||
if (!(bits_[read_idx].wire != NULL && pattern_bits.count(bits_[read_idx]))) {
|
||||
if (write_idx != read_idx) {
|
||||
bits_[write_idx] = bits_[read_idx];
|
||||
if (other != NULL)
|
||||
other->bits_[write_idx] = other->bits_[read_idx];
|
||||
}
|
||||
write_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
bool modified = (write_idx < bits_.size());
|
||||
if (modified) {
|
||||
bits_.resize(write_idx);
|
||||
hash_.clear();
|
||||
try_repack();
|
||||
}
|
||||
if (other_modified) {
|
||||
if (other != NULL && modified) {
|
||||
other->bits_.resize(write_idx);
|
||||
other->hash_.clear();
|
||||
other->try_repack();
|
||||
}
|
||||
|
|
@ -5217,24 +5137,27 @@ void RTLIL::SigSpec::remove2(const pool<RTLIL::SigBit> &pattern, RTLIL::SigSpec
|
|||
other->unpack();
|
||||
}
|
||||
|
||||
bool modified = false;
|
||||
bool other_modified = false;
|
||||
for (int i = GetSize(bits_) - 1; i >= 0; i--) {
|
||||
if (bits_[i].wire != NULL && pattern.count(bits_[i])) {
|
||||
modified = true;
|
||||
bits_.erase(bits_.begin() + i);
|
||||
if (other != NULL) {
|
||||
other_modified = true;
|
||||
other->bits_.erase(other->bits_.begin() + i);
|
||||
// Avoid O(n^2) complexity by compacting in-place
|
||||
size_t write_idx = 0;
|
||||
for (size_t read_idx = 0; read_idx < bits_.size(); read_idx++) {
|
||||
if (!(bits_[read_idx].wire != NULL && pattern.count(bits_[read_idx]))) {
|
||||
if (write_idx != read_idx) {
|
||||
bits_[write_idx] = bits_[read_idx];
|
||||
if (other != NULL)
|
||||
other->bits_[write_idx] = other->bits_[read_idx];
|
||||
}
|
||||
write_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
bool modified = (write_idx < bits_.size());
|
||||
if (modified) {
|
||||
bits_.resize(write_idx);
|
||||
hash_.clear();
|
||||
try_repack();
|
||||
}
|
||||
if (other_modified) {
|
||||
if (other != NULL && modified) {
|
||||
other->bits_.resize(write_idx);
|
||||
other->hash_.clear();
|
||||
other->try_repack();
|
||||
}
|
||||
|
|
@ -5250,24 +5173,27 @@ void RTLIL::SigSpec::remove2(const std::set<RTLIL::SigBit> &pattern, RTLIL::SigS
|
|||
other->unpack();
|
||||
}
|
||||
|
||||
bool modified = false;
|
||||
bool other_modified = false;
|
||||
for (int i = GetSize(bits_) - 1; i >= 0; i--) {
|
||||
if (bits_[i].wire != NULL && pattern.count(bits_[i])) {
|
||||
modified = true;
|
||||
bits_.erase(bits_.begin() + i);
|
||||
if (other != NULL) {
|
||||
other_modified = true;
|
||||
other->bits_.erase(other->bits_.begin() + i);
|
||||
// Avoid O(n^2) complexity by compacting in-place
|
||||
size_t write_idx = 0;
|
||||
for (size_t read_idx = 0; read_idx < bits_.size(); read_idx++) {
|
||||
if (!(bits_[read_idx].wire != NULL && pattern.count(bits_[read_idx]))) {
|
||||
if (write_idx != read_idx) {
|
||||
bits_[write_idx] = bits_[read_idx];
|
||||
if (other != NULL)
|
||||
other->bits_[write_idx] = other->bits_[read_idx];
|
||||
}
|
||||
write_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
bool modified = (write_idx < bits_.size());
|
||||
if (modified) {
|
||||
bits_.resize(write_idx);
|
||||
hash_.clear();
|
||||
try_repack();
|
||||
}
|
||||
if (other_modified) {
|
||||
if (other != NULL && modified) {
|
||||
other->bits_.resize(write_idx);
|
||||
other->hash_.clear();
|
||||
other->try_repack();
|
||||
}
|
||||
|
|
@ -5438,26 +5364,32 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const
|
|||
log_assert(length >= 0);
|
||||
log_assert(offset + length <= size());
|
||||
|
||||
SigSpec extracted;
|
||||
Chunks cs = chunks();
|
||||
auto it = cs.begin();
|
||||
for (; offset; offset -= it->width, ++it) {
|
||||
if (offset < it->width) {
|
||||
int chunk_length = min(it->width - offset, length);
|
||||
extracted.append(it->extract(offset, chunk_length));
|
||||
length -= chunk_length;
|
||||
++it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (; length; length -= it->width, ++it) {
|
||||
if (length >= it->width) {
|
||||
extracted.append(*it);
|
||||
std::vector<SigBit> extracted;
|
||||
SigBit first;
|
||||
bool is_packing = true;
|
||||
for (int i = offset; i < offset + length; i++) {
|
||||
bool was_packing_before = is_packing;
|
||||
SigBit bit = (*this)[i];
|
||||
if (i == offset) {
|
||||
first = bit;
|
||||
if (!bit.wire)
|
||||
is_packing = false;
|
||||
} else {
|
||||
extracted.append(it->extract(0, length));
|
||||
break;
|
||||
if (bit.wire != first.wire)
|
||||
is_packing = false;
|
||||
if (bit.wire)
|
||||
if (bit.offset != first.offset + (i - offset))
|
||||
is_packing = false;
|
||||
}
|
||||
if (was_packing_before && !is_packing)
|
||||
for (int j = offset; j < i; j++)
|
||||
extracted.push_back((*this)[j]);
|
||||
if (!is_packing)
|
||||
extracted.push_back((*this)[i]);
|
||||
}
|
||||
if (is_packing)
|
||||
return SigChunk(first.wire, first.offset, length);
|
||||
|
||||
return extracted;
|
||||
}
|
||||
|
||||
|
|
@ -5562,7 +5494,7 @@ RTLIL::SigSpec RTLIL::SigSpec::repeat(int num) const
|
|||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void RTLIL::SigSpec::check(Module *mod) const
|
||||
void RTLIL::SigSpec::check(const Module *mod) const
|
||||
{
|
||||
if (rep_ == CHUNK)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue