mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-16 20:25:43 +00:00
Merge upstream in
This commit is contained in:
parent
36b753285c
commit
1b3375d8df
117 changed files with 1890 additions and 984 deletions
|
|
@ -303,24 +303,24 @@ struct CellTypes
|
|||
cell_types.clear();
|
||||
}
|
||||
|
||||
bool cell_known(RTLIL::IdString type) const
|
||||
bool cell_known(const RTLIL::IdString &type) const
|
||||
{
|
||||
return cell_types.count(type) != 0;
|
||||
}
|
||||
|
||||
bool cell_output(RTLIL::IdString type, RTLIL::IdString port) const
|
||||
bool cell_output(const RTLIL::IdString &type, const RTLIL::IdString &port) const
|
||||
{
|
||||
auto it = cell_types.find(type);
|
||||
return it != cell_types.end() && it->second.outputs.count(port) != 0;
|
||||
}
|
||||
|
||||
bool cell_input(RTLIL::IdString type, RTLIL::IdString port) const
|
||||
bool cell_input(const RTLIL::IdString &type, const RTLIL::IdString &port) const
|
||||
{
|
||||
auto it = cell_types.find(type);
|
||||
return it != cell_types.end() && it->second.inputs.count(port) != 0;
|
||||
}
|
||||
|
||||
bool cell_evaluable(RTLIL::IdString type) const
|
||||
bool cell_evaluable(const RTLIL::IdString &type) const
|
||||
{
|
||||
auto it = cell_types.find(type);
|
||||
return it != cell_types.end() && it->second.is_evaluable;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -35,16 +35,8 @@ FstData::FstData(std::string filename) : ctx(nullptr)
|
|||
std::string filename_trim = file_base_name(filename);
|
||||
if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".vcd") == 0) {
|
||||
filename_trim.erase(filename_trim.size()-4);
|
||||
std::string template_name = get_base_tmpdir() + "/converted_XXXXXX";
|
||||
char *tmp = strdup(template_name.c_str());
|
||||
int fd = mkstemp(tmp);
|
||||
if (fd == -1) {
|
||||
perror("mkstemp");
|
||||
exit(1);
|
||||
}
|
||||
tmp_file = tmp;
|
||||
free(tmp);
|
||||
std::string cmd = stringf("vcd2fst %s %s", filename.c_str(), tmp_file.c_str());
|
||||
tmp_file = stringf("%s/converted_%s.fst", get_base_tmpdir(), filename_trim);
|
||||
std::string cmd = stringf("vcd2fst %s %s", filename, tmp_file);
|
||||
log("Exec: %s\n", cmd.c_str());
|
||||
if (run_command(cmd) != 0)
|
||||
log_cmd_error("Shell command failed!\n");
|
||||
|
|
|
|||
|
|
@ -189,6 +189,12 @@ template<typename P, typename Q> struct hash_ops<std::pair<P, Q>> {
|
|||
return h;
|
||||
}
|
||||
HASH_TOP_LOOP_FST (const std::pair<P, Q> &a) HASH_TOP_LOOP_SND
|
||||
[[nodiscard]] static inline Hasher hash(const P &p, const Q &q) {
|
||||
Hasher h;
|
||||
h = hash_ops<P>::hash_into(p, h);
|
||||
h = hash_ops<Q>::hash_into(q, h);
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... T> struct hash_ops<std::tuple<T...>> {
|
||||
|
|
|
|||
15
kernel/io.cc
15
kernel/io.cc
|
|
@ -307,7 +307,7 @@ bool is_absolute_path(std::string filename)
|
|||
void remove_directory(std::string dirname)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
run_command(stringf("rmdir /s /q \"%s\"", dirname.c_str()));
|
||||
run_command(stringf("rmdir /s /q \"%s\"", dirname));
|
||||
#else
|
||||
struct stat stbuf;
|
||||
struct dirent **namelist;
|
||||
|
|
@ -315,7 +315,7 @@ void remove_directory(std::string dirname)
|
|||
log_assert(n >= 0);
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (strcmp(namelist[i]->d_name, ".") && strcmp(namelist[i]->d_name, "..")) {
|
||||
std::string buffer = stringf("%s/%s", dirname.c_str(), namelist[i]->d_name);
|
||||
std::string buffer = stringf("%s/%s", dirname, namelist[i]->d_name);
|
||||
if (!stat(buffer.c_str(), &stbuf) && S_ISREG(stbuf.st_mode)) {
|
||||
remove(buffer.c_str());
|
||||
} else
|
||||
|
|
@ -575,6 +575,17 @@ void format_emit_string_view(std::string &result, std::string_view spec, int *dy
|
|||
format_emit_stringf(result, spec, dynamic_ints, num_dynamic_ints, std::string(arg).c_str());
|
||||
}
|
||||
|
||||
void format_emit_idstring(std::string &result, std::string_view spec, int *dynamic_ints,
|
||||
DynamicIntCount num_dynamic_ints, const IdString &arg)
|
||||
{
|
||||
if (spec == "%s") {
|
||||
// Format checking will have guaranteed num_dynamic_ints == 0.
|
||||
result += arg.c_str();
|
||||
return;
|
||||
}
|
||||
format_emit_stringf(result, spec, dynamic_ints, num_dynamic_ints, arg.c_str());
|
||||
}
|
||||
|
||||
void format_emit_void_ptr(std::string &result, std::string_view spec, int *dynamic_ints,
|
||||
DynamicIntCount num_dynamic_ints, const void *arg)
|
||||
{
|
||||
|
|
|
|||
18
kernel/io.h
18
kernel/io.h
|
|
@ -8,6 +8,10 @@
|
|||
|
||||
YOSYS_NAMESPACE_BEGIN
|
||||
|
||||
namespace RTLIL {
|
||||
struct IdString;
|
||||
}
|
||||
|
||||
inline std::string vstringf(const char *fmt, va_list ap)
|
||||
{
|
||||
// For the common case of strings shorter than 128, save a heap
|
||||
|
|
@ -240,7 +244,8 @@ constexpr void check_format(std::string_view fmt, int fmt_start, bool *has_escap
|
|||
case CONVSPEC_CHAR_PTR:
|
||||
if constexpr (!std::is_convertible_v<Arg, const char *> &&
|
||||
!std::is_convertible_v<Arg, const std::string &> &&
|
||||
!std::is_convertible_v<Arg, const std::string_view &>) {
|
||||
!std::is_convertible_v<Arg, const std::string_view &> &&
|
||||
!std::is_convertible_v<Arg, const RTLIL::IdString &>) {
|
||||
YOSYS_ABORT("Expected type convertible to char *");
|
||||
}
|
||||
*specs = found;
|
||||
|
|
@ -279,6 +284,10 @@ void format_emit_string(std::string &result, std::string_view spec, int *dynamic
|
|||
void format_emit_string_view(std::string &result, std::string_view spec, int *dynamic_ints,
|
||||
DynamicIntCount num_dynamic_ints, std::string_view arg);
|
||||
|
||||
// Emit the string representation of `arg` that has been converted to a `RTLIL::IdString'.
|
||||
void format_emit_idstring(std::string &result, std::string_view spec, int *dynamic_ints,
|
||||
DynamicIntCount num_dynamic_ints, const RTLIL::IdString &arg);
|
||||
|
||||
// Emit the string representation of `arg` that has been converted to a `double'.
|
||||
void format_emit_void_ptr(std::string &result, std::string_view spec, int *dynamic_ints,
|
||||
DynamicIntCount num_dynamic_ints, const void *arg);
|
||||
|
|
@ -329,6 +338,11 @@ inline void format_emit_one(std::string &result, std::string_view fmt, const Fou
|
|||
format_emit_string_view(result, spec, dynamic_ints, num_dynamic_ints, s);
|
||||
return;
|
||||
}
|
||||
if constexpr (std::is_convertible_v<Arg, const RTLIL::IdString &>) {
|
||||
const RTLIL::IdString &s = arg;
|
||||
format_emit_idstring(result, spec, dynamic_ints, num_dynamic_ints, s);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case CONVSPEC_VOID_PTR:
|
||||
if constexpr (std::is_convertible_v<Arg, const void *>) {
|
||||
|
|
@ -433,7 +447,7 @@ template <typename T> struct WrapType { using type = T; };
|
|||
template <typename T> using TypeIdentity = typename WrapType<T>::type;
|
||||
|
||||
template <typename... Args>
|
||||
inline std::string stringf(FmtString<TypeIdentity<Args>...> fmt, Args... args)
|
||||
inline std::string stringf(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
|
||||
{
|
||||
return fmt.format(args...);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -791,7 +791,7 @@ dict<std::string, std::pair<std::string, int>> get_coverage_data()
|
|||
dict<std::string, std::pair<std::string, int>> coverage_data;
|
||||
|
||||
for (auto &it : pass_register) {
|
||||
std::string key = stringf("passes.%s", it.first.c_str());
|
||||
std::string key = stringf("passes.%s", it.first);
|
||||
coverage_data[key].first = stringf("%s:%d:%s", __FILE__, __LINE__, __FUNCTION__);
|
||||
coverage_data[key].second += it.second->call_counter;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -900,7 +900,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
|
|||
|
||||
if (width)
|
||||
{
|
||||
SigSpec sig_q = module->addWire(stringf("$%s$rdreg[%d]$q", memid.c_str(), idx), width);
|
||||
SigSpec sig_q = module->addWire(stringf("$%s$rdreg[%d]$q", memid, idx), width);
|
||||
SigSpec sig_d;
|
||||
|
||||
int pos = 0;
|
||||
|
|
@ -910,7 +910,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
|
|||
port.addr[i] = sig_q[pos++];
|
||||
}
|
||||
|
||||
c = module->addDff(stringf("$%s$rdreg[%d]", memid.c_str(), idx), port.clk, sig_d, sig_q, port.clk_polarity);
|
||||
c = module->addDff(stringf("$%s$rdreg[%d]", memid, idx), port.clk, sig_d, sig_q, port.clk_polarity);
|
||||
} else {
|
||||
c = nullptr;
|
||||
}
|
||||
|
|
@ -919,7 +919,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
|
|||
{
|
||||
log_assert(port.arst == State::S0 || port.srst == State::S0);
|
||||
|
||||
SigSpec async_d = module->addWire(stringf("$%s$rdreg[%d]$d", memid.c_str(), idx), GetSize(port.data));
|
||||
SigSpec async_d = module->addWire(stringf("$%s$rdreg[%d]$d", memid, idx), GetSize(port.data));
|
||||
SigSpec sig_d = async_d;
|
||||
|
||||
for (int i = 0; i < GetSize(wr_ports); i++) {
|
||||
|
|
@ -942,7 +942,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
|
|||
raddr = port.sub_addr(sub);
|
||||
SigSpec addr_eq;
|
||||
if (raddr != waddr)
|
||||
addr_eq = module->Eq(stringf("$%s$rdtransen[%d][%d][%d]$d", memid.c_str(), idx, i, sub), raddr, waddr);
|
||||
addr_eq = module->Eq(stringf("$%s$rdtransen[%d][%d][%d]$d", memid, idx, i, sub), raddr, waddr);
|
||||
int pos = 0;
|
||||
int ewidth = width << min_wide_log2;
|
||||
int wsub = wide_write ? sub : 0;
|
||||
|
|
@ -955,10 +955,10 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
|
|||
SigSpec other = port.transparency_mask[i] ? wport.data.extract(pos + wsub * width, epos-pos) : Const(State::Sx, epos-pos);
|
||||
SigSpec cond;
|
||||
if (raddr != waddr)
|
||||
cond = module->And(stringf("$%s$rdtransgate[%d][%d][%d][%d]$d", memid.c_str(), idx, i, sub, pos), wport.en[pos + wsub * width], addr_eq);
|
||||
cond = module->And(stringf("$%s$rdtransgate[%d][%d][%d][%d]$d", memid, idx, i, sub, pos), wport.en[pos + wsub * width], addr_eq);
|
||||
else
|
||||
cond = wport.en[pos + wsub * width];
|
||||
SigSpec merged = module->Mux(stringf("$%s$rdtransmux[%d][%d][%d][%d]$d", memid.c_str(), idx, i, sub, pos), cur, other, cond);
|
||||
SigSpec merged = module->Mux(stringf("$%s$rdtransmux[%d][%d][%d][%d]$d", memid, idx, i, sub, pos), cur, other, cond);
|
||||
sig_d.replace(pos + rsub * width, merged);
|
||||
pos = epos;
|
||||
}
|
||||
|
|
@ -966,7 +966,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) {
|
|||
}
|
||||
}
|
||||
|
||||
IdString name = stringf("$%s$rdreg[%d]", memid.c_str(), idx);
|
||||
IdString name = stringf("$%s$rdreg[%d]", memid, idx);
|
||||
FfData ff(module, initvals, name);
|
||||
ff.width = GetSize(port.data);
|
||||
ff.has_clk = true;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include <algorithm>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string_view>
|
||||
|
||||
YOSYS_NAMESPACE_BEGIN
|
||||
|
||||
|
|
@ -39,7 +40,7 @@ RTLIL::IdString::destruct_guard_t RTLIL::IdString::destruct_guard;
|
|||
std::vector<char*> RTLIL::IdString::global_id_storage_;
|
||||
std::unordered_map<std::string_view, int> RTLIL::IdString::global_id_index_;
|
||||
#ifndef YOSYS_NO_IDS_REFCNT
|
||||
std::vector<int> RTLIL::IdString::global_refcount_storage_;
|
||||
std::vector<uint32_t> RTLIL::IdString::global_refcount_storage_;
|
||||
std::vector<int> RTLIL::IdString::global_free_idx_list_;
|
||||
#endif
|
||||
#ifdef YOSYS_USE_STICKY_IDS
|
||||
|
|
@ -47,10 +48,45 @@ int RTLIL::IdString::last_created_idx_[8];
|
|||
int RTLIL::IdString::last_created_idx_ptr_;
|
||||
#endif
|
||||
|
||||
#define X(_id) IdString RTLIL::ID::_id;
|
||||
#define X(N) const RTLIL::IdString RTLIL::ID::N(RTLIL::StaticId::N);
|
||||
#include "kernel/constids.inc"
|
||||
#undef X
|
||||
|
||||
static void populate(std::string_view name)
|
||||
{
|
||||
if (name[1] == '$') {
|
||||
// Skip prepended '\'
|
||||
name = name.substr(1);
|
||||
}
|
||||
RTLIL::IdString::global_id_index_.insert({name, GetSize(RTLIL::IdString::global_id_storage_)});
|
||||
RTLIL::IdString::global_id_storage_.push_back(const_cast<char*>(name.data()));
|
||||
}
|
||||
|
||||
void RTLIL::IdString::prepopulate()
|
||||
{
|
||||
int size = static_cast<short>(RTLIL::StaticId::STATIC_ID_END);
|
||||
global_id_storage_.reserve(size);
|
||||
RTLIL::IdString::global_id_storage_.push_back(const_cast<char*>(""));
|
||||
global_id_index_.reserve(size);
|
||||
global_refcount_storage_.resize(size, 1);
|
||||
#define X(N) populate("\\" #N);
|
||||
#include "kernel/constids.inc"
|
||||
#undef X
|
||||
}
|
||||
|
||||
static constexpr bool check_well_known_id_order()
|
||||
{
|
||||
int size = sizeof(IdTable) / sizeof(IdTable[0]);
|
||||
for (int i = 1; i < size; ++i)
|
||||
if (IdTable[i - 1].name >= IdTable[i].name)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ensure the statically allocated IdStrings in kernel/constids.inc are unique
|
||||
// and in sorted ascii order, as required by the ID macro.
|
||||
static_assert(check_well_known_id_order());
|
||||
|
||||
dict<std::string, std::string> RTLIL::constpad;
|
||||
|
||||
const pool<IdString> &RTLIL::builtin_ff_cell_types() {
|
||||
|
|
@ -2805,7 +2841,7 @@ RTLIL::IdString RTLIL::Module::uniquify(RTLIL::IdString name, int &index)
|
|||
}
|
||||
|
||||
while (1) {
|
||||
RTLIL::IdString new_name = stringf("%s_%d", name.c_str(), index);
|
||||
RTLIL::IdString new_name = stringf("%s_%d", name, index);
|
||||
if (count_id(new_name) == 0)
|
||||
return new_name;
|
||||
index++;
|
||||
|
|
|
|||
150
kernel/rtlil.h
150
kernel/rtlil.h
|
|
@ -83,6 +83,14 @@ namespace RTLIL
|
|||
SB_EXCL_BB_CMDERR = 15 // call log_cmd_error on black boxed module
|
||||
};
|
||||
|
||||
enum class StaticId : short {
|
||||
STATIC_ID_BEGIN = 0,
|
||||
#define X(N) N,
|
||||
#include "kernel/constids.inc"
|
||||
#undef X
|
||||
STATIC_ID_END,
|
||||
};
|
||||
|
||||
struct Const;
|
||||
struct AttrObject;
|
||||
struct NamedObject;
|
||||
|
|
@ -105,8 +113,19 @@ namespace RTLIL
|
|||
struct Process;
|
||||
struct Binding;
|
||||
struct IdString;
|
||||
struct StaticIdString;
|
||||
|
||||
typedef std::pair<SigSpec, SigSpec> SigSig;
|
||||
|
||||
struct StaticIdString {
|
||||
constexpr StaticIdString(StaticId id, const IdString &id_str) : id_str(id_str), id(id) {}
|
||||
constexpr inline operator const IdString &() const { return id_str; }
|
||||
constexpr inline int index() const { return static_cast<short>(id); }
|
||||
constexpr inline const IdString &id_string() const { return id_str; }
|
||||
|
||||
const IdString &id_str;
|
||||
const StaticId id;
|
||||
};
|
||||
};
|
||||
|
||||
struct RTLIL::IdString
|
||||
|
|
@ -127,7 +146,13 @@ struct RTLIL::IdString
|
|||
static std::vector<char*> global_id_storage_;
|
||||
static std::unordered_map<std::string_view, int> global_id_index_;
|
||||
#ifndef YOSYS_NO_IDS_REFCNT
|
||||
static std::vector<int> global_refcount_storage_;
|
||||
// For prepopulated IdStrings, the refcount is meaningless since they
|
||||
// are never freed even if the refcount is zero. For code efficiency
|
||||
// we increment the refcount of prepopulated IdStrings like any other string,
|
||||
// but we never decrement the refcount or check whether it's zero.
|
||||
// So, make this unsigned because refcounts of preopulated IdStrings may overflow
|
||||
// and overflow of signed integers is undefined behavior.
|
||||
static std::vector<uint32_t> global_refcount_storage_;
|
||||
static std::vector<int> global_free_idx_list_;
|
||||
#endif
|
||||
|
||||
|
|
@ -144,7 +169,7 @@ struct RTLIL::IdString
|
|||
if (global_id_storage_.at(idx) == nullptr)
|
||||
log("#X# DB-DUMP index %d: FREE\n", idx);
|
||||
else
|
||||
log("#X# DB-DUMP index %d: '%s' (ref %d)\n", idx, global_id_storage_.at(idx), global_refcount_storage_.at(idx));
|
||||
log("#X# DB-DUMP index %d: '%s' (ref %u)\n", idx, global_id_storage_.at(idx), global_refcount_storage_.at(idx));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -166,15 +191,13 @@ struct RTLIL::IdString
|
|||
|
||||
static inline int get_reference(int idx)
|
||||
{
|
||||
if (idx) {
|
||||
#ifndef YOSYS_NO_IDS_REFCNT
|
||||
global_refcount_storage_[idx]++;
|
||||
global_refcount_storage_[idx]++;
|
||||
#endif
|
||||
#ifdef YOSYS_XTRACE_GET_PUT
|
||||
if (yosys_xtrace)
|
||||
log("#X# GET-BY-INDEX '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx));
|
||||
if (yosys_xtrace && idx >= static_cast<short>(StaticId::STATIC_ID_END))
|
||||
log("#X# GET-BY-INDEX '%s' (index %d, refcount %u)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx));
|
||||
#endif
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
|
@ -182,9 +205,6 @@ struct RTLIL::IdString
|
|||
{
|
||||
log_assert(destruct_guard_ok);
|
||||
|
||||
if (!p[0])
|
||||
return 0;
|
||||
|
||||
auto it = global_id_index_.find((char*)p);
|
||||
if (it != global_id_index_.end()) {
|
||||
#ifndef YOSYS_NO_IDS_REFCNT
|
||||
|
|
@ -192,11 +212,16 @@ struct RTLIL::IdString
|
|||
#endif
|
||||
#ifdef YOSYS_XTRACE_GET_PUT
|
||||
if (yosys_xtrace)
|
||||
log("#X# GET-BY-NAME '%s' (index %d, refcount %d)\n", global_id_storage_.at(it->second), it->second, global_refcount_storage_.at(it->second));
|
||||
log("#X# GET-BY-NAME '%s' (index %d, refcount %u)\n", global_id_storage_.at(it->second), it->second, global_refcount_storage_.at(it->second));
|
||||
#endif
|
||||
return it->second;
|
||||
}
|
||||
|
||||
ensure_prepopulated();
|
||||
|
||||
if (!p[0])
|
||||
return 0;
|
||||
|
||||
log_assert(p[0] == '$' || p[0] == '\\');
|
||||
log_assert(p[1] != 0);
|
||||
for (const char *c = p; *c; c++)
|
||||
|
|
@ -238,7 +263,7 @@ struct RTLIL::IdString
|
|||
|
||||
#ifdef YOSYS_XTRACE_GET_PUT
|
||||
if (yosys_xtrace)
|
||||
log("#X# GET-BY-NAME '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx));
|
||||
log("#X# GET-BY-NAME '%s' (index %d, refcount %u)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx));
|
||||
#endif
|
||||
|
||||
#ifdef YOSYS_USE_STICKY_IDS
|
||||
|
|
@ -258,21 +283,20 @@ struct RTLIL::IdString
|
|||
{
|
||||
// put_reference() may be called from destructors after the destructor of
|
||||
// global_refcount_storage_ has been run. in this case we simply do nothing.
|
||||
if (!destruct_guard_ok || !idx)
|
||||
if (idx < static_cast<short>(StaticId::STATIC_ID_END) || !destruct_guard_ok)
|
||||
return;
|
||||
|
||||
#ifdef YOSYS_XTRACE_GET_PUT
|
||||
if (yosys_xtrace) {
|
||||
log("#X# PUT '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx));
|
||||
log("#X# PUT '%s' (index %d, refcount %u)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx));
|
||||
}
|
||||
#endif
|
||||
|
||||
int &refcount = global_refcount_storage_[idx];
|
||||
uint32_t &refcount = global_refcount_storage_[idx];
|
||||
|
||||
if (--refcount > 0)
|
||||
return;
|
||||
|
||||
log_assert(refcount == 0);
|
||||
free_reference(idx);
|
||||
}
|
||||
static inline void free_reference(int idx)
|
||||
|
|
@ -281,6 +305,7 @@ struct RTLIL::IdString
|
|||
log("#X# Removed IdString '%s' with index %d.\n", global_id_storage_.at(idx), idx);
|
||||
log_backtrace("-X- ", yosys_xtrace-1);
|
||||
}
|
||||
log_assert(idx >= static_cast<short>(StaticId::STATIC_ID_END));
|
||||
|
||||
global_id_index_.erase(global_id_storage_.at(idx));
|
||||
free(global_id_storage_.at(idx));
|
||||
|
|
@ -300,6 +325,7 @@ struct RTLIL::IdString
|
|||
inline IdString(const IdString &str) : index_(get_reference(str.index_)) { }
|
||||
inline IdString(IdString &&str) : index_(str.index_) { str.index_ = 0; }
|
||||
inline IdString(const std::string &str) : index_(get_reference(str.c_str())) { }
|
||||
inline IdString(StaticId id) : index_(static_cast<short>(id)) {}
|
||||
inline ~IdString() { put_reference(index_); }
|
||||
|
||||
inline void operator=(const IdString &rhs) {
|
||||
|
|
@ -317,6 +343,8 @@ struct RTLIL::IdString
|
|||
*this = id;
|
||||
}
|
||||
|
||||
constexpr inline const IdString &id_string() const { return *this; }
|
||||
|
||||
inline const char *c_str() const {
|
||||
return global_id_storage_.at(index_);
|
||||
}
|
||||
|
|
@ -331,6 +359,8 @@ struct RTLIL::IdString
|
|||
|
||||
inline bool operator==(const IdString &rhs) const { return index_ == rhs.index_; }
|
||||
inline bool operator!=(const IdString &rhs) const { return index_ != rhs.index_; }
|
||||
inline bool operator==(const StaticIdString &rhs) const;
|
||||
inline bool operator!=(const StaticIdString &rhs) const;
|
||||
|
||||
// The methods below are just convenience functions for better compatibility with std::string.
|
||||
|
||||
|
|
@ -411,17 +441,27 @@ struct RTLIL::IdString
|
|||
// often one needs to check if a given IdString is part of a list (for example a list
|
||||
// of cell types). the following functions helps with that.
|
||||
template<typename... Args>
|
||||
bool in(Args... args) const {
|
||||
bool in(const Args &... args) const {
|
||||
return (... || in(args));
|
||||
}
|
||||
|
||||
bool in(const IdString &rhs) const { return *this == rhs; }
|
||||
bool in(const StaticIdString &rhs) const { return *this == rhs; }
|
||||
bool in(const char *rhs) const { return *this == rhs; }
|
||||
bool in(const std::string &rhs) const { return *this == rhs; }
|
||||
inline bool in(const pool<IdString> &rhs) const;
|
||||
inline bool in(const pool<IdString> &&rhs) const;
|
||||
|
||||
bool isPublic() const { return begins_with("\\"); }
|
||||
|
||||
private:
|
||||
static void prepopulate();
|
||||
|
||||
public:
|
||||
static void ensure_prepopulated() {
|
||||
if (global_id_index_.empty())
|
||||
prepopulate();
|
||||
}
|
||||
};
|
||||
|
||||
namespace hashlib {
|
||||
|
|
@ -430,10 +470,10 @@ namespace hashlib {
|
|||
static inline bool cmp(const RTLIL::IdString &a, const RTLIL::IdString &b) {
|
||||
return a == b;
|
||||
}
|
||||
[[nodiscard]] static inline Hasher hash(const RTLIL::IdString id) {
|
||||
[[nodiscard]] static inline Hasher hash(const RTLIL::IdString &id) {
|
||||
return id.hash_top();
|
||||
}
|
||||
[[nodiscard]] static inline Hasher hash_into(const RTLIL::IdString id, Hasher h) {
|
||||
[[nodiscard]] static inline Hasher hash_into(const RTLIL::IdString &id, Hasher h) {
|
||||
return id.hash_into(h);
|
||||
}
|
||||
};
|
||||
|
|
@ -449,12 +489,80 @@ inline bool RTLIL::IdString::in(const pool<IdString> &rhs) const { return rhs.co
|
|||
[[deprecated]]
|
||||
inline bool RTLIL::IdString::in(const pool<IdString> &&rhs) const { return rhs.count(*this) != 0; }
|
||||
|
||||
inline bool RTLIL::IdString::operator==(const RTLIL::StaticIdString &rhs) const {
|
||||
return index_ == rhs.index();
|
||||
}
|
||||
inline bool RTLIL::IdString::operator!=(const RTLIL::StaticIdString &rhs) const {
|
||||
return index_ != rhs.index();
|
||||
}
|
||||
|
||||
namespace RTLIL {
|
||||
namespace ID {
|
||||
#define X(_id) extern IdString _id;
|
||||
#define X(_id) extern const IdString _id;
|
||||
#include "kernel/constids.inc"
|
||||
#undef X
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
struct IdTableEntry {
|
||||
const std::string_view name;
|
||||
const RTLIL::StaticIdString static_id;
|
||||
};
|
||||
|
||||
constexpr IdTableEntry IdTable[] = {
|
||||
#define X(_id) {#_id, RTLIL::StaticIdString(RTLIL::StaticId::_id, RTLIL::ID::_id)},
|
||||
#include "kernel/constids.inc"
|
||||
#undef X
|
||||
};
|
||||
|
||||
constexpr int lookup_well_known_id(std::string_view name)
|
||||
{
|
||||
int low = 0;
|
||||
int high = sizeof(IdTable) / sizeof(IdTable[0]);
|
||||
while (high - low >= 2) {
|
||||
int mid = (low + high) / 2;
|
||||
if (name < IdTable[mid].name)
|
||||
high = mid;
|
||||
else
|
||||
low = mid;
|
||||
}
|
||||
if (IdTable[low].name == name)
|
||||
return low;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create a statically allocated IdString object, using for example ID::A or ID($add).
|
||||
//
|
||||
// Recipe for Converting old code that is using conversion of strings like ID::A and
|
||||
// "$add" for creating IdStrings: Run below SED command on the .cc file and then use for
|
||||
// example "meld foo.cc foo.cc.orig" to manually compile errors, if necessary.
|
||||
//
|
||||
// sed -i.orig -r 's/"\\\\([a-zA-Z0-9_]+)"/ID(\1)/g; s/"(\$[a-zA-Z0-9_]+)"/ID(\1)/g;' <filename>
|
||||
//
|
||||
typedef const RTLIL::IdString &IDMacroHelperFunc();
|
||||
|
||||
template <int IdTableIndex> struct IDMacroHelper {
|
||||
static constexpr RTLIL::StaticIdString eval(IDMacroHelperFunc) {
|
||||
return IdTable[IdTableIndex].static_id;
|
||||
}
|
||||
};
|
||||
template <> struct IDMacroHelper<-1> {
|
||||
static constexpr const RTLIL::IdString &eval(IDMacroHelperFunc func) {
|
||||
return func();
|
||||
}
|
||||
};
|
||||
|
||||
#define ID(_id) \
|
||||
YOSYS_NAMESPACE_PREFIX IDMacroHelper< \
|
||||
YOSYS_NAMESPACE_PREFIX lookup_well_known_id(#_id) \
|
||||
>::eval([]() \
|
||||
-> const YOSYS_NAMESPACE_PREFIX RTLIL::IdString & { \
|
||||
const char *p = "\\" #_id, *q = p[1] == '$' ? p+1 : p; \
|
||||
static const YOSYS_NAMESPACE_PREFIX RTLIL::IdString id(q); \
|
||||
return id; \
|
||||
})
|
||||
|
||||
namespace RTLIL {
|
||||
extern dict<std::string, std::string> constpad;
|
||||
|
||||
const pool<IdString> &builtin_ff_cell_types();
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ struct SatGen
|
|||
} else {
|
||||
std::string wire_name = RTLIL::unescape_id(bit.wire->name);
|
||||
std::string name = pf +
|
||||
(bit.wire->width == 1 ? wire_name : stringf("%s [%d]", wire_name.c_str(), bit.offset));
|
||||
(bit.wire->width == 1 ? wire_name : stringf("%s [%d]", wire_name, bit.offset));
|
||||
vec.push_back(ez->frozen_literal(name));
|
||||
imported_signals[pf][bit] = vec.back();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *a
|
|||
if (Tcl_GetCommandInfo(interp, tcl_command_name.c_str(), &info) != 0) {
|
||||
log("[TCL: yosys -import] Command name collision: found pre-existing command `%s' -> skip.\n", it.first.c_str());
|
||||
} else {
|
||||
std::string tcl_script = stringf("proc %s args { yosys %s {*}$args }", tcl_command_name.c_str(), it.first.c_str());
|
||||
std::string tcl_script = stringf("proc %s args { yosys %s {*}$args }", tcl_command_name, it.first);
|
||||
Tcl_Eval(interp, tcl_script.c_str());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -199,6 +199,8 @@ void yosys_setup()
|
|||
already_shutdown = false;
|
||||
new backward::SignalHandling;
|
||||
|
||||
IdString::ensure_prepopulated();
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
// With Python 3.12, calling PyImport_AppendInittab on an already
|
||||
// initialized platform fails (such as when libyosys is imported
|
||||
|
|
@ -214,10 +216,6 @@ void yosys_setup()
|
|||
init_share_dirname();
|
||||
init_abc_executable_name();
|
||||
|
||||
#define X(_id) RTLIL::ID::_id = "\\" # _id;
|
||||
#include "kernel/constids.inc"
|
||||
#undef X
|
||||
|
||||
Pass::init_register();
|
||||
yosys_design = new RTLIL::Design;
|
||||
yosys_celltypes.setup();
|
||||
|
|
@ -290,7 +288,7 @@ RTLIL::IdString new_id(std::string file, int line, std::string func)
|
|||
if (pos != std::string::npos)
|
||||
func = func.substr(pos+1);
|
||||
|
||||
return stringf("$auto$%s:%d:%s$%d", file.c_str(), line, func.c_str(), autoidx++);
|
||||
return stringf("$auto$%s:%d:%s$%d", file, line, func, autoidx++);
|
||||
}
|
||||
|
||||
RTLIL::IdString new_id_suffix(std::string file, int line, std::string func, std::string suffix)
|
||||
|
|
@ -307,7 +305,7 @@ RTLIL::IdString new_id_suffix(std::string file, int line, std::string func, std:
|
|||
if (pos != std::string::npos)
|
||||
func = func.substr(pos+1);
|
||||
|
||||
return stringf("$auto$%s:%d:%s$%s$%d", file.c_str(), line, func.c_str(), suffix.c_str(), autoidx++);
|
||||
return stringf("$auto$%s:%d:%s$%s$%d", file, line, func, suffix, autoidx++);
|
||||
}
|
||||
|
||||
RTLIL::Design *yosys_get_design()
|
||||
|
|
@ -323,7 +321,7 @@ const char *create_prompt(RTLIL::Design *design, int recursion_counter)
|
|||
str += stringf("(%d) ", recursion_counter);
|
||||
str += "yosys";
|
||||
if (!design->selected_active_module.empty())
|
||||
str += stringf(" [%s]", RTLIL::unescape_id(design->selected_active_module).c_str());
|
||||
str += stringf(" [%s]", RTLIL::unescape_id(design->selected_active_module));
|
||||
if (!design->full_selection()) {
|
||||
if (design->selected_active_module.empty())
|
||||
str += "*";
|
||||
|
|
|
|||
|
|
@ -206,13 +206,13 @@ namespace RTLIL {
|
|||
struct Module;
|
||||
struct Design;
|
||||
struct Monitor;
|
||||
struct Selection;
|
||||
struct Selection;
|
||||
struct SigChunk;
|
||||
enum State : unsigned char;
|
||||
|
||||
typedef std::pair<SigSpec, SigSpec> SigSig;
|
||||
|
||||
namespace ID {}
|
||||
namespace ID {}
|
||||
}
|
||||
|
||||
namespace AST {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue