mirror of https://github.com/YosysHQ/yosys.git
Update to latest and fix all disabled tests
This commit is contained in:
commit
652a9a63b2
|
|
@ -1,4 +1,4 @@
|
|||
name: Build environment setup
|
||||
4name: Build environment setup
|
||||
description: Configure build env for Yosys builds
|
||||
runs:
|
||||
using: composite
|
||||
|
|
@ -8,7 +8,8 @@ runs:
|
|||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install gperf build-essential bison flex libfl-dev libreadline-dev gawk tcl-dev libffi-dev git graphviz xdot pkg-config python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev libbz2-dev libnsl-dev libdwarf-dev libelf-dev elfutils libdw-dev ccache
|
||||
sudo apt-get install libdwarf-dev libelf-dev elfutils libdw-dev ccache
|
||||
sudo apt-get install gperf build-essential bison flex libfl-dev libreadline-dev gawk tcl-dev libffi-dev git graphviz xdot pkg-config python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev libbz2-dev libgtest-dev
|
||||
|
||||
- name: Install macOS Dependencies
|
||||
if: runner.os == 'macOS'
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ jobs:
|
|||
echo "ENABLE_VERIFIC_YOSYSHQ_EXTENSIONS := 1" >> Makefile.conf
|
||||
echo "ENABLE_CCACHE := 1" >> Makefile.conf
|
||||
echo "ENABLE_HELP_SOURCE := 1" >> Makefile.conf
|
||||
make -j$procs ENABLE_LTO=1
|
||||
make -j$procs
|
||||
|
||||
- name: Prepare docs
|
||||
shell: bash
|
||||
|
|
|
|||
|
|
@ -114,3 +114,8 @@ jobs:
|
|||
shell: bash
|
||||
run: |
|
||||
find tests/**/*.err -print -exec cat {} \;
|
||||
|
||||
- name: Run unit tests
|
||||
shell: bash
|
||||
run: |
|
||||
make -j$procs unit-test ENABLE_LIBYOSYS=1
|
||||
|
|
|
|||
|
|
@ -78,3 +78,8 @@ jobs:
|
|||
if: ${{ github.ref == 'refs/heads/main' }}
|
||||
run: |
|
||||
make -C sby run_ci
|
||||
|
||||
- name: Run unit tests
|
||||
shell: bash
|
||||
run: |
|
||||
make -j$procs unit-test ENABLE_LTO=1 ENABLE_LIBYOSYS=1
|
||||
|
|
|
|||
2
Brewfile
2
Brewfile
|
|
@ -12,6 +12,8 @@ brew "boost-python3"
|
|||
brew "llvm@20"
|
||||
brew "lld"
|
||||
|
||||
brew "googletest"
|
||||
|
||||
brew "autoconf"
|
||||
|
||||
brew "dwarfutils"
|
||||
|
|
|
|||
|
|
@ -60,14 +60,11 @@ merge; please do not use these labels if you are not a maintainer.
|
|||
|
||||
# Asking questions
|
||||
|
||||
If you have a question about how to use Yosys, please ask on our [discussions
|
||||
page](https://github.com/YosysHQ/yosys/discussions) or in our [community
|
||||
slack](https://join.slack.com/t/yosyshq/shared_invite/zt-1aopkns2q-EiQ97BeQDt_pwvE41sGSuA).
|
||||
The slack is also a great place to ask questions about developing or
|
||||
If you have a question about how to use Yosys, please ask on our [Discourse forum](https://yosyshq.discourse.group/) or in our [discussions
|
||||
page](https://github.com/YosysHQ/yosys/discussions).
|
||||
The Discourse is also a great place to ask questions about developing or
|
||||
contributing to Yosys.
|
||||
|
||||
We have open dev 'jour fixe' (JF) meetings where developers from YosysHQ and the
|
||||
We have open [dev 'jour fixe' (JF) meetings](https://docs.google.com/document/d/1SapA6QAsJcsgwsdKJDgnGR2mr97pJjV4eeXg_TVJhRU/edit?usp=sharing) where developers from YosysHQ and the
|
||||
community come together to discuss open issues and PRs. This is also a good
|
||||
place to talk to us about how to implement larger PRs. Please join the
|
||||
community slack if you would like to join the next meeting, the link is
|
||||
available in the description of the #devel-discuss channel.
|
||||
place to talk to us about how to implement larger PRs.
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -180,7 +180,7 @@ ifeq ($(OS), Haiku)
|
|||
CXXFLAGS += -D_DEFAULT_SOURCE
|
||||
endif
|
||||
|
||||
YOSYS_VER := 0.57+178
|
||||
YOSYS_VER := 0.57+218
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ struct Index {
|
|||
info.found_blackboxes.insert(cell);
|
||||
} else {
|
||||
if (!submodule || submodule->get_blackbox_attribute())
|
||||
log_error("Unsupported cell type: %s (%s in %s)\n",
|
||||
log_warning("Unsupported cell type: %s (%s in %s)\n",
|
||||
log_id(cell->type), log_id(cell), log_id(m));
|
||||
}
|
||||
}
|
||||
|
|
@ -1017,7 +1017,7 @@ struct XAigerWriter : AigerWriter {
|
|||
auto &minfo = cursor.leaf_minfo(*this);
|
||||
|
||||
for (auto box : minfo.found_blackboxes) {
|
||||
log_debug(" - %s.%s (type %s): ", cursor.path().c_str(),
|
||||
log_debug(" - %s.%s (type %s): ", cursor.path(),
|
||||
RTLIL::unescape_id(box->name),
|
||||
log_id(box->type));
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ The ``formatted_help()`` method
|
|||
Dumping command help to json
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- `help -dump-cells-json cmds.json`
|
||||
- `help -dump-cmds-json cmds.json`
|
||||
|
||||
+ generates a ``ContentListing`` for each command registered in Yosys
|
||||
+ tries to parse unformatted ``Pass::help()`` output if
|
||||
|
|
|
|||
|
|
@ -476,7 +476,7 @@ void AigerReader::parse_xaiger()
|
|||
else if (c == 'n') {
|
||||
parse_xaiger_literal(f);
|
||||
f >> s;
|
||||
log_debug("n: '%s'\n", s.c_str());
|
||||
log_debug("n: '%s'\n", s);
|
||||
}
|
||||
else if (c == 'h') {
|
||||
f.ignore(sizeof(uint32_t));
|
||||
|
|
|
|||
|
|
@ -83,11 +83,11 @@ struct RpcServer {
|
|||
std::string request;
|
||||
json_request.dump(request);
|
||||
request += '\n';
|
||||
log_debug("RPC frontend request: %s", request.c_str());
|
||||
log_debug("RPC frontend request: %s", request);
|
||||
write(request);
|
||||
|
||||
std::string response = read();
|
||||
log_debug("RPC frontend response: %s", response.c_str());
|
||||
log_debug("RPC frontend response: %s", response);
|
||||
std::string error;
|
||||
Json json_response = Json::parse(response, error);
|
||||
if (json_response.is_null())
|
||||
|
|
|
|||
|
|
@ -150,14 +150,14 @@ unsigned int CellCosts::get(RTLIL::Cell *cell)
|
|||
return 1;
|
||||
|
||||
if (design_ && design_->module(cell->type) && cell->parameters.empty()) {
|
||||
log_debug("%s is a module, recurse\n", cell->name.c_str());
|
||||
log_debug("%s is a module, recurse\n", cell->name);
|
||||
return get(design_->module(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());
|
||||
log_debug("%s is ff\n", cell->name);
|
||||
return cell->getParam(ID::WIDTH).as_int();
|
||||
} else if (cell->type.in(ID($mem), ID($mem_v2))) {
|
||||
log_debug("%s is mem\n", cell->name.c_str());
|
||||
log_debug("%s is mem\n", cell->name);
|
||||
return cell->getParam(ID::WIDTH).as_int() * cell->getParam(ID::SIZE).as_int();
|
||||
} else if (y_coef(cell->type)) {
|
||||
// linear with Y_WIDTH or WIDTH
|
||||
|
|
@ -166,23 +166,23 @@ unsigned int CellCosts::get(RTLIL::Cell *cell)
|
|||
int width = cell->getParam(param).as_int();
|
||||
if (cell->type == ID($demux))
|
||||
width <<= cell->getParam(ID::S_WIDTH).as_int();
|
||||
log_debug("%s Y*coef %d * %d\n", cell->name.c_str(), width, y_coef(cell->type));
|
||||
log_debug("%s Y*coef %d * %d\n", cell->name, width, y_coef(cell->type));
|
||||
return width * y_coef(cell->type);
|
||||
} else if (sum_coef(cell->type)) {
|
||||
// linear with sum of port widths
|
||||
unsigned int sum = port_width_sum(cell);
|
||||
log_debug("%s sum*coef %d * %d\n", cell->name.c_str(), sum, sum_coef(cell->type));
|
||||
log_debug("%s sum*coef %d * %d\n", cell->name, sum, sum_coef(cell->type));
|
||||
return sum * sum_coef(cell->type);
|
||||
} else if (max_inp_coef(cell->type)) {
|
||||
// linear with largest input width
|
||||
unsigned int max = max_inp_width(cell);
|
||||
log_debug("%s max*coef %d * %d\n", cell->name.c_str(), max, max_inp_coef(cell->type));
|
||||
log_debug("%s max*coef %d * %d\n", cell->name, max, max_inp_coef(cell->type));
|
||||
return max * max_inp_coef(cell->type);
|
||||
} else if (is_div_mod(cell->type) || cell->type == ID($mul)) {
|
||||
// quadratic with sum of port widths
|
||||
unsigned int sum = port_width_sum(cell);
|
||||
unsigned int coef = cell->type == ID($mul) ? 3 : 5;
|
||||
log_debug("%s coef*(sum**2) %d * %d\n", cell->name.c_str(), coef, sum * sum);
|
||||
log_debug("%s coef*(sum**2) %d * %d\n", cell->name, coef, sum * sum);
|
||||
return coef * sum * sum;
|
||||
} else if (cell->type.in(ID($macc), ID($macc_v2))) {
|
||||
// quadratic per term
|
||||
|
|
@ -203,15 +203,15 @@ unsigned int CellCosts::get(RTLIL::Cell *cell)
|
|||
} else if (cell->type == ID($lut)) {
|
||||
int width = cell->getParam(ID::WIDTH).as_int();
|
||||
unsigned int cost = 1U << (unsigned int)width;
|
||||
log_debug("%s is 2**%d\n", cell->name.c_str(), width);
|
||||
log_debug("%s is 2**%d\n", cell->name, width);
|
||||
return cost;
|
||||
} else if (cell->type == ID($sop)) {
|
||||
int width = cell->getParam(ID::WIDTH).as_int();
|
||||
int depth = cell->getParam(ID::DEPTH).as_int();
|
||||
log_debug("%s is (2*%d + 1)*%d\n", cell->name.c_str(), width, depth);
|
||||
log_debug("%s is (2*%d + 1)*%d\n", cell->name, width, depth);
|
||||
return (2 * width + 1) * depth;
|
||||
} else if (is_free(cell->type)) {
|
||||
log_debug("%s is free\n", cell->name.c_str());
|
||||
log_debug("%s is free\n", cell->name);
|
||||
return 0;
|
||||
} else if (is_mem(cell->type)) {
|
||||
// SILIMATE: Memory cells have no bearing on cross module optimizations
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ void FstData::extractVarNames()
|
|||
char *endptr;
|
||||
int mem_addr = strtol(addr.c_str(), &endptr, 16);
|
||||
if (*endptr) {
|
||||
log_debug("Error parsing memory address in : %s\n", clean_name.c_str());
|
||||
log_debug("Error parsing memory address in : %s\n", clean_name);
|
||||
} else {
|
||||
memory_to_handle[var.scope+"."+mem_cell][mem_addr] = var.id;
|
||||
}
|
||||
|
|
@ -178,7 +178,7 @@ void FstData::extractVarNames()
|
|||
char *endptr;
|
||||
int mem_addr = strtol(addr.c_str(), &endptr, 10);
|
||||
if (*endptr) {
|
||||
log_debug("Error parsing memory address in : %s\n", clean_name.c_str());
|
||||
log_debug("Error parsing memory address in : %s\n", clean_name);
|
||||
} else {
|
||||
memory_to_handle[var.scope+"."+mem_cell][mem_addr] = var.id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -331,10 +331,12 @@ static void log_error_with_prefix(std::string_view prefix, std::string str)
|
|||
if (log_errfile != NULL)
|
||||
log_files.push_back(log_errfile);
|
||||
|
||||
if (log_error_stderr)
|
||||
if (log_error_stderr) {
|
||||
log_flush(); // Make sure we flush stdout before replacing it with stderr
|
||||
for (auto &f : log_files)
|
||||
if (f == stdout)
|
||||
f = stderr;
|
||||
}
|
||||
|
||||
log_last_error = std::move(str);
|
||||
log("%s%s", prefix, log_last_error);
|
||||
|
|
@ -405,6 +407,11 @@ void log_abort_internal(const char *file, int line)
|
|||
log_error("Abort in %s:%d.\n", file, line);
|
||||
}
|
||||
|
||||
void log_yosys_abort_message(std::string_view file, int line, std::string_view func, std::string_view message)
|
||||
{
|
||||
log_error("Abort in %s:%d (%s): %s\n", file, line, func, message);
|
||||
}
|
||||
|
||||
void log_formatted_cmd_error(std::string str)
|
||||
{
|
||||
if (log_cmd_error_throw) {
|
||||
|
|
|
|||
|
|
@ -4456,7 +4456,7 @@ RTLIL::SigChunk RTLIL::SigChunk::extract(int offset, int length) const
|
|||
RTLIL::SigBit RTLIL::SigChunk::operator[](int offset) const
|
||||
{
|
||||
log_assert(offset >= 0);
|
||||
log_assert(offset <= width);
|
||||
log_assert(offset < width);
|
||||
RTLIL::SigBit ret;
|
||||
if (wire) {
|
||||
ret.wire = wire;
|
||||
|
|
|
|||
|
|
@ -1252,7 +1252,8 @@ private:
|
|||
public:
|
||||
SigSpec() : width_(0), hash_(0) {}
|
||||
SigSpec(std::initializer_list<RTLIL::SigSpec> parts);
|
||||
|
||||
SigSpec(const SigSpec &value) = default;
|
||||
SigSpec(SigSpec &&value) = default;
|
||||
SigSpec(const RTLIL::Const &value);
|
||||
SigSpec(RTLIL::Const &&value);
|
||||
SigSpec(const RTLIL::SigChunk &chunk);
|
||||
|
|
@ -1269,6 +1270,9 @@ public:
|
|||
SigSpec(const std::set<RTLIL::SigBit> &bits);
|
||||
explicit SigSpec(bool bit);
|
||||
|
||||
SigSpec &operator=(const SigSpec &rhs) = default;
|
||||
SigSpec &operator=(SigSpec &&rhs) = default;
|
||||
|
||||
inline const std::vector<RTLIL::SigChunk> &chunks() const { pack(); return chunks_; }
|
||||
inline const std::vector<RTLIL::SigBit> &bits() const { inline_unpack(); return bits_; }
|
||||
|
||||
|
|
|
|||
|
|
@ -142,7 +142,12 @@
|
|||
#define YOSYS_CONSTEVAL constexpr
|
||||
#endif
|
||||
|
||||
#define YOSYS_ABORT(s) abort()
|
||||
#define YOSYS_ABORT(s) YOSYS_NAMESPACE_PREFIX log_yosys_abort_message(__FILE__, __LINE__, __FUNCTION__, s)
|
||||
|
||||
// This has to precede including "kernel/io.h"
|
||||
YOSYS_NAMESPACE_BEGIN
|
||||
[[noreturn]] void log_yosys_abort_message(std::string_view file, int line, std::string_view func, std::string_view message);
|
||||
YOSYS_NAMESPACE_END
|
||||
|
||||
#include "kernel/io.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -156,9 +156,9 @@ dict<SigBit, std::vector<SelReason>> gather_selected_reps(Module* mod, const std
|
|||
void explain_selections(const std::vector<SelReason>& reasons) {
|
||||
for (std::variant<Wire*, Cell*> reason : reasons) {
|
||||
if (Cell** cell_reason = std::get_if<Cell*>(&reason))
|
||||
log_debug("\tcell %s\n", (*cell_reason)->name.c_str());
|
||||
log_debug("\tcell %s\n", (*cell_reason)->name);
|
||||
else if (Wire** wire_reason = std::get_if<Wire*>(&reason))
|
||||
log_debug("\twire %s\n", (*wire_reason)->name.c_str());
|
||||
log_debug("\twire %s\n", (*wire_reason)->name);
|
||||
else
|
||||
log_assert(false && "insane reason variant\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,11 +22,24 @@
|
|||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
int autoname_worker(Module *module, const dict<Wire*, int>& wire_score)
|
||||
typedef struct name_proposal {
|
||||
string name;
|
||||
unsigned int score;
|
||||
name_proposal() : name(""), score(-1) { }
|
||||
name_proposal(string name, unsigned int score) : name(name), score(score) { }
|
||||
bool operator<(const name_proposal &other) const {
|
||||
if (score != other.score)
|
||||
return score < other.score;
|
||||
else
|
||||
return name.length() < other.name.length();
|
||||
}
|
||||
} name_proposal;
|
||||
|
||||
int autoname_worker(Module *module, const dict<Wire*, unsigned int>& wire_score)
|
||||
{
|
||||
dict<Cell*, pair<int, string>> proposed_cell_names;
|
||||
dict<Wire*, pair<int, string>> proposed_wire_names;
|
||||
int best_score = -1;
|
||||
dict<Cell*, name_proposal> proposed_cell_names;
|
||||
dict<Wire*, name_proposal> proposed_wire_names;
|
||||
name_proposal best_name;
|
||||
|
||||
for (auto cell : module->selected_cells()) {
|
||||
if (cell->name[0] == '$') {
|
||||
|
|
@ -36,14 +49,14 @@ int autoname_worker(Module *module, const dict<Wire*, int>& wire_score)
|
|||
if (bit.wire != nullptr && bit.wire->name[0] != '$') {
|
||||
if (suffix.empty())
|
||||
suffix = stringf("_%s_%s", log_id(cell->type), log_id(conn.first));
|
||||
string new_name(bit.wire->name.str() + suffix);
|
||||
int score = wire_score.at(bit.wire);
|
||||
if (cell->output(conn.first)) score = 0;
|
||||
score = 10000*score + new_name.size();
|
||||
if (!proposed_cell_names.count(cell) || score < proposed_cell_names.at(cell).first) {
|
||||
if (best_score < 0 || score < best_score)
|
||||
best_score = score;
|
||||
proposed_cell_names[cell] = make_pair(score, new_name);
|
||||
name_proposal proposed_name(
|
||||
bit.wire->name.str() + suffix,
|
||||
cell->output(conn.first) ? 0 : wire_score.at(bit.wire)
|
||||
);
|
||||
if (!proposed_cell_names.count(cell) || proposed_name < proposed_cell_names.at(cell)) {
|
||||
if (proposed_name < best_name)
|
||||
best_name = proposed_name;
|
||||
proposed_cell_names[cell] = proposed_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -54,37 +67,44 @@ int autoname_worker(Module *module, const dict<Wire*, int>& wire_score)
|
|||
if (bit.wire != nullptr && bit.wire->name[0] == '$' && !bit.wire->port_id) {
|
||||
if (suffix.empty())
|
||||
suffix = stringf("_%s", log_id(conn.first));
|
||||
string new_name(cell->name.str() + suffix);
|
||||
int score = wire_score.at(bit.wire);
|
||||
if (cell->output(conn.first)) score = 0;
|
||||
score = 10000*score + new_name.size();
|
||||
if (!proposed_wire_names.count(bit.wire) || score < proposed_wire_names.at(bit.wire).first) {
|
||||
if (best_score < 0 || score < best_score)
|
||||
best_score = score;
|
||||
proposed_wire_names[bit.wire] = make_pair(score, new_name);
|
||||
name_proposal proposed_name(
|
||||
cell->name.str() + suffix,
|
||||
cell->output(conn.first) ? 0 : wire_score.at(bit.wire)
|
||||
);
|
||||
if (!proposed_wire_names.count(bit.wire) || proposed_name < proposed_wire_names.at(bit.wire)) {
|
||||
if (proposed_name < best_name)
|
||||
best_name = proposed_name;
|
||||
proposed_wire_names[bit.wire] = proposed_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
// compare against double best score for following comparisons so we don't
|
||||
// pre-empt a future iteration
|
||||
best_name.score *= 2;
|
||||
|
||||
for (auto &it : proposed_cell_names) {
|
||||
if (best_score*2 < it.second.first)
|
||||
if (best_name < it.second)
|
||||
continue;
|
||||
IdString n = module->uniquify(IdString(it.second.second));
|
||||
IdString n = module->uniquify(IdString(it.second.name));
|
||||
log_debug("Rename cell %s in %s to %s.\n", log_id(it.first), log_id(module), log_id(n));
|
||||
module->rename(it.first, n);
|
||||
count++;
|
||||
}
|
||||
|
||||
for (auto &it : proposed_wire_names) {
|
||||
if (best_score*2 < it.second.first)
|
||||
if (best_name < it.second)
|
||||
continue;
|
||||
IdString n = module->uniquify(IdString(it.second.second));
|
||||
IdString n = module->uniquify(IdString(it.second.name));
|
||||
log_debug("Rename wire %s in %s to %s.\n", log_id(it.first), log_id(module), log_id(n));
|
||||
module->rename(it.first, n);
|
||||
count++;
|
||||
}
|
||||
|
||||
return proposed_cell_names.size() + proposed_wire_names.size();
|
||||
return count;
|
||||
}
|
||||
|
||||
struct AutonamePass : public Pass {
|
||||
|
|
@ -110,12 +130,13 @@ struct AutonamePass : public Pass {
|
|||
// }
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
log_header(design, "Executing AUTONAME pass.\n");
|
||||
|
||||
for (auto module : design->selected_modules())
|
||||
{
|
||||
dict<Wire*, int> wire_score;
|
||||
dict<Wire*, unsigned int> wire_score;
|
||||
for (auto cell : module->selected_cells())
|
||||
for (auto &conn : cell->connections())
|
||||
for (auto bit : conn.second)
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ struct BoxDerivePass : Pass {
|
|||
IdString derived_type = base->derive(d, cell->parameters);
|
||||
Module *derived = d->module(derived_type);
|
||||
log_assert(derived && "Failed to derive module\n");
|
||||
log_debug("derived %s\n", derived_type.c_str());
|
||||
log_debug("derived %s\n", derived_type);
|
||||
|
||||
if (!naming_attr.empty() && derived->has_attribute(naming_attr)) {
|
||||
IdString new_name = RTLIL::escape_id(derived->get_string_attribute(naming_attr));
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ struct CoveragePass : public Pass {
|
|||
{
|
||||
log_debug("Module %s:\n", log_id(module));
|
||||
for (auto wire: module->wires()) {
|
||||
log_debug("%s\t%s\t%s\n", module->selected(wire) ? "*" : " ", wire->get_src_attribute().c_str(), log_id(wire->name));
|
||||
log_debug("%s\t%s\t%s\n", module->selected(wire) ? "*" : " ", wire->get_src_attribute(), log_id(wire->name));
|
||||
for (auto src: wire->get_strpool_attribute(ID::src)) {
|
||||
auto filename = extract_src_filename(src);
|
||||
if (filename.empty()) continue;
|
||||
|
|
@ -109,7 +109,7 @@ struct CoveragePass : public Pass {
|
|||
}
|
||||
}
|
||||
for (auto cell: module->cells()) {
|
||||
log_debug("%s\t%s\t%s\n", module->selected(cell) ? "*" : " ", cell->get_src_attribute().c_str(), log_id(cell->name));
|
||||
log_debug("%s\t%s\t%s\n", module->selected(cell) ? "*" : " ", cell->get_src_attribute(), log_id(cell->name));
|
||||
for (auto src: cell->get_strpool_attribute(ID::src)) {
|
||||
auto filename = extract_src_filename(src);
|
||||
if (filename.empty()) continue;
|
||||
|
|
|
|||
|
|
@ -392,7 +392,7 @@ void MemMapping::dump_configs(int stage) {
|
|||
void MemMapping::dump_config(MemConfig &cfg) {
|
||||
log_debug("- %s:\n", log_id(cfg.def->id));
|
||||
for (auto &it: cfg.def->options)
|
||||
log_debug(" - option %s %s\n", it.first.c_str(), log_const(it.second));
|
||||
log_debug(" - option %s %s\n", it.first, log_const(it.second));
|
||||
log_debug(" - emulation score: %d\n", cfg.score_emu);
|
||||
log_debug(" - replicates (for ports): %d\n", cfg.repl_port);
|
||||
log_debug(" - replicates (for data): %d\n", cfg.repl_d);
|
||||
|
|
@ -403,7 +403,7 @@ void MemMapping::dump_config(MemConfig &cfg) {
|
|||
for (int x: cfg.def->dbits)
|
||||
os << " " << x;
|
||||
std::string dbits_s = os.str();
|
||||
log_debug(" - abits %d dbits%s\n", cfg.def->abits, dbits_s.c_str());
|
||||
log_debug(" - abits %d dbits%s\n", cfg.def->abits, dbits_s);
|
||||
if (cfg.def->byte != 0)
|
||||
log_debug(" - byte width %d\n", cfg.def->byte);
|
||||
log_debug(" - chosen base width %d\n", cfg.def->dbits[cfg.base_width_log2]);
|
||||
|
|
@ -414,25 +414,25 @@ void MemMapping::dump_config(MemConfig &cfg) {
|
|||
else
|
||||
os << " " << x;
|
||||
std::string swizzle_s = os.str();
|
||||
log_debug(" - swizzle%s\n", swizzle_s.c_str());
|
||||
log_debug(" - swizzle%s\n", swizzle_s);
|
||||
os.str("");
|
||||
for (int i = 0; (1 << i) <= cfg.hard_wide_mask; i++)
|
||||
if (cfg.hard_wide_mask & 1 << i)
|
||||
os << " " << i;
|
||||
std::string wide_s = os.str();
|
||||
if (cfg.hard_wide_mask)
|
||||
log_debug(" - hard wide bits%s\n", wide_s.c_str());
|
||||
log_debug(" - hard wide bits%s\n", wide_s);
|
||||
if (cfg.emu_read_first)
|
||||
log_debug(" - emulate read-first behavior\n");
|
||||
for (int i = 0; i < GetSize(mem.wr_ports); i++) {
|
||||
auto &pcfg = cfg.wr_ports[i];
|
||||
if (pcfg.rd_port == -1)
|
||||
log_debug(" - write port %d: port group %s\n", i, cfg.def->port_groups[pcfg.port_group].names[0].c_str());
|
||||
log_debug(" - write port %d: port group %s\n", i, cfg.def->port_groups[pcfg.port_group].names[0]);
|
||||
else
|
||||
log_debug(" - write port %d: port group %s (shared with read port %d)\n", i, cfg.def->port_groups[pcfg.port_group].names[0].c_str(), pcfg.rd_port);
|
||||
log_debug(" - write port %d: port group %s (shared with read port %d)\n", i, cfg.def->port_groups[pcfg.port_group].names[0], pcfg.rd_port);
|
||||
|
||||
for (auto &it: pcfg.def->options)
|
||||
log_debug(" - option %s %s\n", it.first.c_str(), log_const(it.second));
|
||||
log_debug(" - option %s %s\n", it.first, log_const(it.second));
|
||||
if (cfg.def->width_mode == WidthMode::PerPort) {
|
||||
std::stringstream os;
|
||||
for (int i = pcfg.def->min_wr_wide_log2; i <= pcfg.def->max_wr_wide_log2; i++)
|
||||
|
|
@ -441,7 +441,7 @@ void MemMapping::dump_config(MemConfig &cfg) {
|
|||
const char *note = "";
|
||||
if (pcfg.rd_port != -1)
|
||||
note = pcfg.def->width_tied ? " (tied)" : " (independent)";
|
||||
log_debug(" - widths%s%s\n", widths_s.c_str(), note);
|
||||
log_debug(" - widths%s%s\n", widths_s, note);
|
||||
}
|
||||
for (auto i: pcfg.emu_prio)
|
||||
log_debug(" - emulate priority over write port %d\n", i);
|
||||
|
|
@ -449,11 +449,11 @@ void MemMapping::dump_config(MemConfig &cfg) {
|
|||
for (int i = 0; i < GetSize(mem.rd_ports); i++) {
|
||||
auto &pcfg = cfg.rd_ports[i];
|
||||
if (pcfg.wr_port == -1)
|
||||
log_debug(" - read port %d: port group %s\n", i, cfg.def->port_groups[pcfg.port_group].names[0].c_str());
|
||||
log_debug(" - read port %d: port group %s\n", i, cfg.def->port_groups[pcfg.port_group].names[0]);
|
||||
else
|
||||
log_debug(" - read port %d: port group %s (shared with write port %d)\n", i, cfg.def->port_groups[pcfg.port_group].names[0].c_str(), pcfg.wr_port);
|
||||
log_debug(" - read port %d: port group %s (shared with write port %d)\n", i, cfg.def->port_groups[pcfg.port_group].names[0], pcfg.wr_port);
|
||||
for (auto &it: pcfg.def->options)
|
||||
log_debug(" - option %s %s\n", it.first.c_str(), log_const(it.second));
|
||||
log_debug(" - option %s %s\n", it.first, log_const(it.second));
|
||||
if (cfg.def->width_mode == WidthMode::PerPort) {
|
||||
std::stringstream os;
|
||||
for (int i = pcfg.def->min_rd_wide_log2; i <= pcfg.def->max_rd_wide_log2; i++)
|
||||
|
|
@ -462,7 +462,7 @@ void MemMapping::dump_config(MemConfig &cfg) {
|
|||
const char *note = "";
|
||||
if (pcfg.wr_port != -1)
|
||||
note = pcfg.def->width_tied ? " (tied)" : " (independent)";
|
||||
log_debug(" - widths%s%s\n", widths_s.c_str(), note);
|
||||
log_debug(" - widths%s%s\n", widths_s, note);
|
||||
}
|
||||
if (pcfg.emu_sync)
|
||||
log_debug(" - emulate data register\n");
|
||||
|
|
@ -2242,7 +2242,7 @@ struct MemoryLibMapPass : public Pass {
|
|||
if (!map.logic_ok) {
|
||||
if (map.cfgs.empty()) {
|
||||
log_debug("Rejected candidates for mapping memory %s.%s:\n", log_id(module->name), log_id(mem.memid));
|
||||
log_debug("%s", map.rejected_cfg_debug_msgs.c_str());
|
||||
log_debug("%s", map.rejected_cfg_debug_msgs);
|
||||
log_error("no valid mapping found for memory %s.%s\n", log_id(module->name), log_id(mem.memid));
|
||||
}
|
||||
idx = 0;
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ void rmunused_module_cells(Module *module, bool verbose)
|
|||
|
||||
for (auto cell : unused) {
|
||||
if (verbose)
|
||||
log_debug(" removing unused `%s' cell `%s'.\n", cell->type.c_str(), cell->name.c_str());
|
||||
log_debug(" removing unused `%s' cell `%s'.\n", cell->type, cell->name);
|
||||
module->design->scratchpad_set_bool("opt.did_something", true);
|
||||
if (cell->is_builtin_ff())
|
||||
ffinit.remove_init(cell->getPort(ID::Q));
|
||||
|
|
@ -215,7 +215,7 @@ void rmunused_module_cells(Module *module, bool verbose)
|
|||
for (auto it : mem_unused)
|
||||
{
|
||||
if (verbose)
|
||||
log_debug(" removing unused memory `%s'.\n", it.c_str());
|
||||
log_debug(" removing unused memory `%s'.\n", it);
|
||||
delete module->memories.at(it);
|
||||
module->memories.erase(it);
|
||||
}
|
||||
|
|
@ -496,7 +496,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool unused
|
|||
int del_temp_wires_count = 0;
|
||||
for (auto wire : del_wires_queue) {
|
||||
if (ys_debug() || (check_public_name(wire->name) && verbose))
|
||||
log_debug(" removing unused non-port wire %s.\n", wire->name.c_str());
|
||||
log_debug(" removing unused non-port wire %s.\n", wire->name);
|
||||
else
|
||||
del_temp_wires_count++;
|
||||
}
|
||||
|
|
@ -636,7 +636,7 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool unusedbitsattr
|
|||
}
|
||||
for (auto cell : delcells) {
|
||||
if (verbose)
|
||||
log_debug(" removing buffer cell `%s': %s = %s\n", cell->name.c_str(),
|
||||
log_debug(" removing buffer cell `%s': %s = %s\n", cell->name,
|
||||
log_signal(cell->getPort(ID::Y)), log_signal(cell->getPort(ID::A)));
|
||||
module->remove(cell);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ struct OptLutWorker
|
|||
{
|
||||
if (lut_width <= dlogic_conn.first)
|
||||
{
|
||||
log_debug(" LUT has illegal connection to %s cell %s.%s.\n", lut_dlogic.second->type.c_str(), log_id(module), log_id(lut_dlogic.second));
|
||||
log_debug(" LUT has illegal connection to %s cell %s.%s.\n", lut_dlogic.second->type, log_id(module), log_id(lut_dlogic.second));
|
||||
log_debug(" LUT input A[%d] not present.\n", dlogic_conn.first);
|
||||
legal = false;
|
||||
break;
|
||||
|
|
@ -173,8 +173,8 @@ struct OptLutWorker
|
|||
|
||||
if (sigmap(lut_input[dlogic_conn.first]) != sigmap(lut_dlogic.second->getPort(dlogic_conn.second)[0]))
|
||||
{
|
||||
log_debug(" LUT has illegal connection to %s cell %s.%s.\n", lut_dlogic.second->type.c_str(), log_id(module), log_id(lut_dlogic.second));
|
||||
log_debug(" LUT input A[%d] (wire %s) not connected to %s port %s (wire %s).\n", dlogic_conn.first, log_signal(lut_input[dlogic_conn.first]), lut_dlogic.second->type.c_str(), dlogic_conn.second.c_str(), log_signal(lut_dlogic.second->getPort(dlogic_conn.second)));
|
||||
log_debug(" LUT has illegal connection to %s cell %s.%s.\n", lut_dlogic.second->type, log_id(module), log_id(lut_dlogic.second));
|
||||
log_debug(" LUT input A[%d] (wire %s) not connected to %s port %s (wire %s).\n", dlogic_conn.first, log_signal(lut_input[dlogic_conn.first]), lut_dlogic.second->type, dlogic_conn.second, log_signal(lut_dlogic.second->getPort(dlogic_conn.second)));
|
||||
legal = false;
|
||||
break;
|
||||
}
|
||||
|
|
@ -182,7 +182,7 @@ struct OptLutWorker
|
|||
|
||||
if (legal)
|
||||
{
|
||||
log_debug(" LUT has legal connection to %s cell %s.%s.\n", lut_dlogic.second->type.c_str(), log_id(module), log_id(lut_dlogic.second));
|
||||
log_debug(" LUT has legal connection to %s cell %s.%s.\n", lut_dlogic.second->type, log_id(module), log_id(lut_dlogic.second));
|
||||
lut_legal_dlogics.insert(lut_dlogic);
|
||||
for (auto &dlogic_conn : dlogic_map)
|
||||
lut_dlogic_inputs.insert(dlogic_conn.first);
|
||||
|
|
@ -496,9 +496,9 @@ struct OptLutWorker
|
|||
lutM_new_table.set(eval, (RTLIL::State) evaluate_lut(lutB, eval_inputs));
|
||||
}
|
||||
|
||||
log_debug(" Cell A truth table: %s.\n", lutA->getParam(ID::LUT).as_string().c_str());
|
||||
log_debug(" Cell B truth table: %s.\n", lutB->getParam(ID::LUT).as_string().c_str());
|
||||
log_debug(" Merged truth table: %s.\n", lutM_new_table.as_string().c_str());
|
||||
log_debug(" Cell A truth table: %s.\n", lutA->getParam(ID::LUT).as_string());
|
||||
log_debug(" Cell B truth table: %s.\n", lutB->getParam(ID::LUT).as_string());
|
||||
log_debug(" Merged truth table: %s.\n", lutM_new_table.as_string());
|
||||
|
||||
lutM->setParam(ID::LUT, lutM_new_table);
|
||||
lutM->setPort(ID::A, lutM_new_inputs);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "libs/sha1/sha1.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <array>
|
||||
|
|
@ -170,24 +171,20 @@ struct OptMergeWorker
|
|||
}
|
||||
}
|
||||
|
||||
if (cell1->type == ID($and) || cell1->type == ID($or) || cell1->type == ID($xor) || cell1->type == ID($xnor) || cell1->type == ID($add) || cell1->type == ID($mul) ||
|
||||
cell1->type == ID($logic_and) || cell1->type == ID($logic_or) || cell1->type == ID($_AND_) || cell1->type == ID($_OR_) || cell1->type == ID($_XOR_)) {
|
||||
if (cell1->type.in(ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($mul),
|
||||
ID($logic_and), ID($logic_or), ID($_AND_), ID($_OR_), ID($_XOR_))) {
|
||||
if (conn1.at(ID::A) < conn1.at(ID::B)) {
|
||||
RTLIL::SigSpec tmp = conn1[ID::A];
|
||||
conn1[ID::A] = conn1[ID::B];
|
||||
conn1[ID::B] = tmp;
|
||||
std::swap(conn1[ID::A], conn1[ID::B]);
|
||||
}
|
||||
if (conn2.at(ID::A) < conn2.at(ID::B)) {
|
||||
RTLIL::SigSpec tmp = conn2[ID::A];
|
||||
conn2[ID::A] = conn2[ID::B];
|
||||
conn2[ID::B] = tmp;
|
||||
std::swap(conn2[ID::A], conn2[ID::B]);
|
||||
}
|
||||
} else
|
||||
if (cell1->type == ID($reduce_xor) || cell1->type == ID($reduce_xnor)) {
|
||||
if (cell1->type.in(ID($reduce_xor), ID($reduce_xnor))) {
|
||||
conn1[ID::A].sort();
|
||||
conn2[ID::A].sort();
|
||||
} else
|
||||
if (cell1->type == ID($reduce_and) || cell1->type == ID($reduce_or) || cell1->type == ID($reduce_bool)) {
|
||||
if (cell1->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool))) {
|
||||
conn1[ID::A].sort_and_unify();
|
||||
conn2[ID::A].sort_and_unify();
|
||||
} else
|
||||
|
|
@ -300,11 +297,11 @@ struct OptMergeWorker
|
|||
}
|
||||
|
||||
did_something = true;
|
||||
log_debug(" Cell `%s' is identical to cell `%s'.\n", cell->name.c_str(), other_cell->name.c_str());
|
||||
log_debug(" Cell `%s' is identical to cell `%s'.\n", cell->name, other_cell->name);
|
||||
for (auto &it : cell->connections()) {
|
||||
if (cell->output(it.first)) {
|
||||
RTLIL::SigSpec other_sig = other_cell->getPort(it.first);
|
||||
log_debug(" Redirecting output %s: %s = %s\n", it.first.c_str(),
|
||||
log_debug(" Redirecting output %s: %s = %s\n", it.first,
|
||||
log_signal(it.second), log_signal(other_sig));
|
||||
Const init = initvals(other_sig);
|
||||
initvals.remove_init(it.second);
|
||||
|
|
@ -314,7 +311,7 @@ struct OptMergeWorker
|
|||
initvals.set_init(other_sig, init);
|
||||
}
|
||||
}
|
||||
log_debug(" Removing %s cell `%s' from module `%s'.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str());
|
||||
log_debug(" Removing %s cell `%s' from module `%s'.\n", cell->type, cell->name, module->name);
|
||||
module->remove(cell);
|
||||
total_count++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,13 +109,43 @@ struct CutpointPass : public Pass {
|
|||
SigMap sigmap(module);
|
||||
pool<SigBit> cutpoint_bits;
|
||||
|
||||
pool<SigBit> wire_drivers;
|
||||
for (auto cell : module->cells())
|
||||
for (auto &conn : cell->connections())
|
||||
if (cell->output(conn.first) && !cell->input(conn.first))
|
||||
for (auto bit : sigmap(conn.second))
|
||||
if (bit.wire)
|
||||
wire_drivers.insert(bit);
|
||||
|
||||
for (auto wire : module->wires())
|
||||
if (wire->port_input)
|
||||
for (auto bit : sigmap(wire))
|
||||
wire_drivers.insert(bit);
|
||||
|
||||
for (auto cell : module->selected_cells()) {
|
||||
if (cell->type == ID($anyseq))
|
||||
continue;
|
||||
log("Removing cell %s.%s, making all cell outputs cutpoints.\n", log_id(module), log_id(cell));
|
||||
for (auto &conn : cell->connections()) {
|
||||
if (cell->output(conn.first))
|
||||
module->connect(conn.second, flag_undef ? Const(State::Sx, GetSize(conn.second)) : module->Anyseq(NEW_ID, GetSize(conn.second)));
|
||||
if (cell->output(conn.first)) {
|
||||
bool do_cut = true;
|
||||
if (cell->input(conn.first))
|
||||
for (auto bit : sigmap(conn.second))
|
||||
if (wire_drivers.count(bit)) {
|
||||
log_debug(" Treating inout port '%s' as input.\n", id2cstr(conn.first));
|
||||
do_cut = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (do_cut) {
|
||||
module->connect(conn.second, flag_undef ? Const(State::Sx, GetSize(conn.second)) : module->Anyseq(NEW_ID, GetSize(conn.second)));
|
||||
if (cell->input(conn.first)) {
|
||||
log_debug(" Treating inout port '%s' as output.\n", id2cstr(conn.first));
|
||||
for (auto bit : sigmap(conn.second))
|
||||
wire_drivers.insert(bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RTLIL::Cell *scopeinfo = nullptr;
|
||||
|
|
|
|||
|
|
@ -181,8 +181,10 @@ void abc9_module(RTLIL::Design *design, std::string script_file, std::string exe
|
|||
for (std::string dont_use_cell : dont_use_cells) {
|
||||
dont_use_args += stringf("-X \"%s\" ", dont_use_cell);
|
||||
}
|
||||
bool first_lib = true;
|
||||
for (std::string liberty_file : liberty_files) {
|
||||
abc9_script += stringf("read_lib %s -w \"%s\" ; ", dont_use_args, liberty_file);
|
||||
abc9_script += stringf("read_lib %s %s -w \"%s\" ; ", dont_use_args, first_lib ? "" : "-m", liberty_file);
|
||||
first_lib = false;
|
||||
}
|
||||
if (!constr_file.empty())
|
||||
abc9_script += stringf("read_constr -v \"%s\"; ", constr_file);
|
||||
|
|
|
|||
|
|
@ -1600,7 +1600,6 @@ static void replace_zbufs(Design *design)
|
|||
sig[i] = w;
|
||||
}
|
||||
}
|
||||
log("XXX %s -> %s\n", log_signal(cell->getPort(ID::A)), log_signal(sig));
|
||||
cell->setPort(ID::A, sig);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ static std::pair<std::optional<ClockGateCell>, std::optional<ClockGateCell>>
|
|||
continue;
|
||||
}
|
||||
|
||||
log_debug("maybe valid icg: %s\n", cell_name.c_str());
|
||||
log_debug("maybe valid icg: %s\n", cell_name);
|
||||
ClockGateCell icg_interface;
|
||||
icg_interface.name = RTLIL::escape_id(cell_name);
|
||||
|
||||
|
|
@ -162,9 +162,9 @@ static std::pair<std::optional<ClockGateCell>, std::optional<ClockGateCell>>
|
|||
winning = cost < goal;
|
||||
|
||||
if (winning)
|
||||
log_debug("%s beats %s\n", icg_interface.name.c_str(), icg_to_beat->name.c_str());
|
||||
log_debug("%s beats %s\n", icg_interface.name, icg_to_beat->name);
|
||||
} else {
|
||||
log_debug("%s is the first of its polarity\n", icg_interface.name.c_str());
|
||||
log_debug("%s is the first of its polarity\n", icg_interface.name);
|
||||
winning = true;
|
||||
}
|
||||
if (winning) {
|
||||
|
|
@ -396,7 +396,7 @@ struct ClockgatePass : public Pass {
|
|||
if (!it->second.new_net)
|
||||
continue;
|
||||
|
||||
log_debug("Fix up FF %s\n", cell->name.c_str());
|
||||
log_debug("Fix up FF %s\n", cell->name);
|
||||
// Now we start messing with the design
|
||||
ff.has_ce = false;
|
||||
// Construct the clock gate
|
||||
|
|
|
|||
|
|
@ -117,11 +117,11 @@ static bool parse_next_state(const LibertyAst *cell, const LibertyAst *attr, std
|
|||
// the next_state variable isn't just a pin name; perhaps this is an enable?
|
||||
auto helper = LibertyExpression::Lexer(expr);
|
||||
auto tree = LibertyExpression::parse(helper);
|
||||
// log_debug("liberty expression:\n%s\n", tree.str().c_str());
|
||||
// log_debug("liberty expression:\n%s\n", tree.str());
|
||||
|
||||
if (tree.kind == LibertyExpression::Kind::EMPTY) {
|
||||
if (!warned_cells.count(cell_name)) {
|
||||
log_debug("Invalid expression '%s' in next_state attribute of cell '%s' - skipping.\n", expr.c_str(), cell_name.c_str());
|
||||
log_debug("Invalid expression '%s' in next_state attribute of cell '%s' - skipping.\n", expr, cell_name);
|
||||
warned_cells.insert(cell_name);
|
||||
}
|
||||
return false;
|
||||
|
|
@ -140,7 +140,7 @@ static bool parse_next_state(const LibertyAst *cell, const LibertyAst *attr, std
|
|||
// position that gives better diagnostics here.
|
||||
if (!pin_names.count(ff_output)) {
|
||||
if (!warned_cells.count(cell_name)) {
|
||||
log_debug("Inference failed on expression '%s' in next_state attribute of cell '%s' because it does not contain ff output '%s' - skipping.\n", expr.c_str(), cell_name.c_str(), ff_output.c_str());
|
||||
log_debug("Inference failed on expression '%s' in next_state attribute of cell '%s' because it does not contain ff output '%s' - skipping.\n", expr, cell_name, ff_output);
|
||||
warned_cells.insert(cell_name);
|
||||
}
|
||||
return false;
|
||||
|
|
@ -189,7 +189,7 @@ static bool parse_next_state(const LibertyAst *cell, const LibertyAst *attr, std
|
|||
}
|
||||
|
||||
if (!warned_cells.count(cell_name)) {
|
||||
log_debug("Inference failed on expression '%s' in next_state attribute of cell '%s' because it does not evaluate to an enable flop - skipping.\n", expr.c_str(), cell_name.c_str());
|
||||
log_debug("Inference failed on expression '%s' in next_state attribute of cell '%s' because it does not evaluate to an enable flop - skipping.\n", expr, cell_name);
|
||||
warned_cells.insert(cell_name);
|
||||
}
|
||||
return false;
|
||||
|
|
@ -225,10 +225,10 @@ static bool parse_pin(const LibertyAst *cell, const LibertyAst *attr, std::strin
|
|||
For now, we'll simply produce a warning to let the user know something is up.
|
||||
*/
|
||||
if (pin_name.find_first_of("^*|&") == std::string::npos) {
|
||||
log_debug("Malformed liberty file - cannot find pin '%s' in cell '%s' - skipping.\n", pin_name.c_str(), cell->args[0].c_str());
|
||||
log_debug("Malformed liberty file - cannot find pin '%s' in cell '%s' - skipping.\n", pin_name, cell->args[0]);
|
||||
}
|
||||
else {
|
||||
log_debug("Found unsupported expression '%s' in pin attribute of cell '%s' - skipping.\n", pin_name.c_str(), cell->args[0].c_str());
|
||||
log_debug("Found unsupported expression '%s' in pin attribute of cell '%s' - skipping.\n", pin_name, cell->args[0]);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,14 @@
|
|||
USING_YOSYS_NAMESPACE
|
||||
YOSYS_NAMESPACE_BEGIN
|
||||
|
||||
static void transfer_attr (Cell* to, const Cell* from, const IdString& attr) {
|
||||
if (from->has_attribute(attr))
|
||||
to->attributes[attr] = from->attributes.at(attr);
|
||||
}
|
||||
static void transfer_src (Cell* to, const Cell* from) {
|
||||
transfer_attr(to, from, ID::src);
|
||||
}
|
||||
|
||||
void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||
{
|
||||
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
|
||||
|
|
@ -261,21 +269,21 @@ void simplemap_eqne(RTLIL::Module *module, RTLIL::Cell *cell)
|
|||
bool is_ne = cell->type.in(ID($ne), ID($nex));
|
||||
|
||||
RTLIL::SigSpec xor_out = module->addWire(NEW_ID2_SUFFIX("xor"), max(GetSize(sig_a), GetSize(sig_b))); // SILIMATE: Improve the naming
|
||||
RTLIL::Cell *xor_cell = module->addXor(NEW_ID2, sig_a, sig_b, xor_out, is_signed, cell->get_src_attribute()); // SILIMATE: Improve the naming
|
||||
RTLIL::Cell *xor_cell = module->addXor(NEW_ID2, sig_a, sig_b, xor_out, is_signed); // SILIMATE: Improve the naming
|
||||
xor_cell->attributes = cell->attributes;
|
||||
simplemap_bitop(module, xor_cell);
|
||||
module->remove(xor_cell);
|
||||
|
||||
RTLIL::SigSpec reduce_out = is_ne ? sig_y : module->addWire(NEW_ID2_SUFFIX("reduce_out")); // SILIMATE: Improve the naming
|
||||
RTLIL::Cell *reduce_cell = module->addReduceOr(NEW_ID2_SUFFIX("reduce_or"), xor_out, reduce_out, false, cell->get_src_attribute()); // SILIMATE: Improve the naming
|
||||
RTLIL::Cell *reduce_cell = module->addReduceOr(NEW_ID2_SUFFIX("reduce_or"), xor_out, reduce_out, false); // SILIMATE: Improve the naming
|
||||
reduce_cell->attributes = cell->attributes;
|
||||
simplemap_reduce(module, reduce_cell);
|
||||
module->remove(reduce_cell);
|
||||
|
||||
if (!is_ne) {
|
||||
RTLIL::Cell *not_cell = module->addLogicNot(NEW_ID2_SUFFIX("not"), reduce_out, sig_y, false, cell->get_src_attribute()); // SILIMATE: Improve the naming
|
||||
RTLIL::Cell *not_cell = module->addLogicNot(NEW_ID2_SUFFIX("not"), reduce_out, sig_y, false); // SILIMATE: Improve the naming
|
||||
not_cell->attributes = cell->attributes;
|
||||
simplemap_lognot(module, not_cell);
|
||||
simplemap_lognot(module, not_cell);
|
||||
module->remove(not_cell);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -592,7 +592,7 @@ struct TechmapWorker
|
|||
log_msg_cache.insert(msg);
|
||||
log("%s\n", msg);
|
||||
}
|
||||
log_debug("%s %s.%s (%s) to %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), log_id(extmapper_module));
|
||||
log_debug("%s %s.%s (%s) to %s.\n", mapmsg_prefix, log_id(module), log_id(cell), log_id(cell->type), log_id(extmapper_module));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -601,7 +601,7 @@ struct TechmapWorker
|
|||
log_msg_cache.insert(msg);
|
||||
log("%s\n", msg);
|
||||
}
|
||||
log_debug("%s %s.%s (%s) with %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), extmapper_name.c_str());
|
||||
log_debug("%s %s.%s (%s) with %s.\n", mapmsg_prefix, log_id(module), log_id(cell), log_id(cell->type), extmapper_name);
|
||||
|
||||
if (extmapper_name == "simplemap") {
|
||||
if (simplemap_mappers.count(cell->type) == 0)
|
||||
|
|
@ -953,7 +953,7 @@ struct TechmapWorker
|
|||
module_queue.insert(m);
|
||||
}
|
||||
|
||||
log_debug("%s %s.%s to imported %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(m_name));
|
||||
log_debug("%s %s.%s to imported %s.\n", mapmsg_prefix, log_id(module), log_id(cell), log_id(m_name));
|
||||
cell->type = m_name;
|
||||
cell->parameters.clear();
|
||||
}
|
||||
|
|
@ -964,7 +964,7 @@ struct TechmapWorker
|
|||
log_msg_cache.insert(msg);
|
||||
log("%s\n", msg);
|
||||
}
|
||||
log_debug("%s %s.%s (%s) using %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), log_id(tpl));
|
||||
log_debug("%s %s.%s (%s) using %s.\n", mapmsg_prefix, log_id(module), log_id(cell), log_id(cell->type), log_id(tpl));
|
||||
techmap_module_worker(design, module, cell, tpl);
|
||||
cell = nullptr;
|
||||
}
|
||||
|
|
@ -1295,7 +1295,7 @@ struct TechmapPass : public Pass {
|
|||
std::string maps = "";
|
||||
for (auto &map : i.second)
|
||||
maps += stringf(" %s", log_id(map));
|
||||
log_debug(" %s:%s\n", log_id(i.first), maps.c_str());
|
||||
log_debug(" %s:%s\n", log_id(i.first), maps);
|
||||
}
|
||||
log_debug("\n");
|
||||
|
||||
|
|
|
|||
|
|
@ -1185,7 +1185,7 @@ struct TestCellPass : public Pass {
|
|||
// Expected to run once
|
||||
int num_cells_estimate = costs.get(uut);
|
||||
if (num_cells <= num_cells_estimate) {
|
||||
log_debug("Correct upper bound for %s: %d <= %d\n", cell_type.c_str(), num_cells, num_cells_estimate);
|
||||
log_debug("Correct upper bound for %s: %d <= %d\n", cell_type, num_cells, num_cells_estimate);
|
||||
} else {
|
||||
failed++;
|
||||
if (worst_abs < num_cells - num_cells_estimate) {
|
||||
|
|
|
|||
|
|
@ -283,9 +283,16 @@ module _90_alu (A, B, CI, BI, X, Y, CO);
|
|||
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
|
||||
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
|
||||
|
||||
\$lcu #(.WIDTH(Y_WIDTH)) lcu (.P(X), .G(AA & BB), .CI(CI), .CO(CO));
|
||||
(* force_downto *)
|
||||
wire [Y_WIDTH-1:0] P;
|
||||
wire [Y_WIDTH-1:0] G;
|
||||
wire [Y_WIDTH-1:0] Cnull;
|
||||
assign Cnull = 1'b0;
|
||||
|
||||
assign X = AA ^ BB;
|
||||
\$fa #(.WIDTH(Y_WIDTH)) fa (.A(AA), .B(BB), .C(Cnull), .X(G), .Y(P));
|
||||
\$lcu #(.WIDTH(Y_WIDTH)) lcu (.P(P), .G(G), .CI(CI), .CO(CO));
|
||||
|
||||
assign X = P;
|
||||
assign Y = X ^ {CO, CI};
|
||||
endmodule
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ struct QlIoffPass : public Pass {
|
|||
|
||||
for (auto cell : module->selected_cells()) {
|
||||
if (cell->type.in(ID(dffsre), ID(sdffsre))) {
|
||||
log_debug("Checking cell %s.\n", cell->name.c_str());
|
||||
log_debug("Checking cell %s.\n", cell->name);
|
||||
bool e_const = cell->getPort(ID::E).is_fully_ones();
|
||||
bool r_const = cell->getPort(ID::R).is_fully_ones();
|
||||
bool s_const = cell->getPort(ID::S).is_fully_ones();
|
||||
|
|
@ -55,7 +55,7 @@ struct QlIoffPass : public Pass {
|
|||
SigSpec d = cell->getPort(ID::D);
|
||||
log_assert(GetSize(d) == 1);
|
||||
if (modwalker.has_inputs(d)) {
|
||||
log_debug("Cell %s is potentially eligible for promotion to input IOFF.\n", cell->name.c_str());
|
||||
log_debug("Cell %s is potentially eligible for promotion to input IOFF.\n", cell->name);
|
||||
// check that d_sig has no other consumers
|
||||
pool<ModWalker::PortBit> portbits;
|
||||
modwalker.get_consumers(portbits, d);
|
||||
|
|
@ -70,7 +70,7 @@ struct QlIoffPass : public Pass {
|
|||
SigSpec q = cell->getPort(ID::Q);
|
||||
log_assert(GetSize(q) == 1);
|
||||
if (modwalker.has_outputs(q) && !modwalker.has_consumers(q)) {
|
||||
log_debug("Cell %s is potentially eligible for promotion to output IOFF.\n", cell->name.c_str());
|
||||
log_debug("Cell %s is potentially eligible for promotion to output IOFF.\n", cell->name);
|
||||
for (SigBit bit : output_bit_aliases[modwalker.sigmap(q)]) {
|
||||
log_assert(bit.is_wire());
|
||||
output_ffs[bit.wire][bit.offset] = cell;
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ proc
|
|||
equiv_opt -assert -map +/gowin/cells_sim.v synth_gowin # equivalency check
|
||||
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||
cd mux8 # Constrain all select calls below inside the top module
|
||||
select -assert-count 1 t:LUT1
|
||||
select -assert-count 10 t:LUT3
|
||||
select -assert-count 3 t:LUT1
|
||||
select -assert-count 2 t:LUT3
|
||||
select -assert-count 1 t:LUT4
|
||||
select -assert-count 5 t:MUX2_LUT5
|
||||
select -assert-count 2 t:MUX2_LUT6
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
# Opt tests
|
||||
|
||||
## Disabled
|
||||
|
||||
- `opt_lut`: we do not support `abc9`
|
||||
|
|
@ -1,11 +1,27 @@
|
|||
GTESTFLAG := -lgtest -lgtest_main
|
||||
RPATH := -Wl,-rpath
|
||||
EXTRAFLAGS := -lyosys -pthreads
|
||||
UNAME_S := $(shell uname -s)
|
||||
|
||||
# GoogleTest flags
|
||||
GTEST_PREFIX := $(shell brew --prefix googletest 2>/dev/null)
|
||||
ifeq ($(GTEST_PREFIX),)
|
||||
GTEST_CXXFLAGS :=
|
||||
GTEST_LDFLAGS := -lgtest -lgtest_main
|
||||
else
|
||||
GTEST_CXXFLAGS := -I$(GTEST_PREFIX)/include
|
||||
GTEST_LDFLAGS := -L$(GTEST_PREFIX)/lib -lgtest -lgtest_main
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
RPATH = -Wl,-rpath,$(ROOTPATH)
|
||||
else
|
||||
RPATH = -Wl,-rpath=$(ROOTPATH)
|
||||
endif
|
||||
|
||||
EXTRAFLAGS := -lyosys -pthread
|
||||
|
||||
OBJTEST := objtest
|
||||
BINTEST := bintest
|
||||
|
||||
ALLTESTFILE := $(shell find -name '*Test.cc' -printf '%P ')
|
||||
ALLTESTFILE := $(shell find . -name '*Test.cc' | sed 's|^\./||' | tr '\n' ' ')
|
||||
TESTDIRS := $(sort $(dir $(ALLTESTFILE)))
|
||||
TESTS := $(addprefix $(BINTEST)/, $(basename $(ALLTESTFILE:%Test.cc=%Test.o)))
|
||||
|
||||
|
|
@ -15,16 +31,26 @@ TESTS := $(addprefix $(BINTEST)/, $(basename $(ALLTESTFILE:%Test.cc=%Test.o)))
|
|||
all: prepare $(TESTS) run-tests
|
||||
|
||||
$(BINTEST)/%: $(OBJTEST)/%.o
|
||||
$(CXX) -L$(ROOTPATH) $(RPATH)=$(ROOTPATH) $(LINKFLAGS) -o $@ $^ $(LIBS) \
|
||||
$(GTESTFLAG) $(EXTRAFLAGS)
|
||||
$(CXX) -L$(ROOTPATH) $(RPATH) $(LINKFLAGS) -o $@ $^ $(LIBS) \
|
||||
$(GTEST_LDFLAGS) $(EXTRAFLAGS)
|
||||
|
||||
$(OBJTEST)/%.o: $(basename $(subst $(OBJTEST),.,%)).cc
|
||||
$(CXX) -o $@ -c -I$(ROOTPATH) $(CPPFLAGS) $(CXXFLAGS) $^
|
||||
$(CXX) -o $@ -c -I$(ROOTPATH) $(CPPFLAGS) $(CXXFLAGS) $(GTEST_CXXFLAGS) $^
|
||||
|
||||
.PHONY: prepare run-tests clean
|
||||
|
||||
run-tests: $(TESTS)
|
||||
$(subst Test ,Test&& ,$^)
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
@for t in $^; do \
|
||||
echo "Running $$t"; \
|
||||
DYLD_LIBRARY_PATH=$(ROOTPATH) $$t || exit 1; \
|
||||
done
|
||||
else
|
||||
@for t in $^; do \
|
||||
echo "Running $$t"; \
|
||||
$$t || exit 1; \
|
||||
done
|
||||
endif
|
||||
|
||||
prepare:
|
||||
mkdir -p $(addprefix $(BINTEST)/,$(TESTDIRS))
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ namespace RTLIL {
|
|||
KernelRtlilTest() {
|
||||
if (log_files.empty()) log_files.emplace_back(stdout);
|
||||
}
|
||||
virtual void SetUp() override {
|
||||
IdString::ensure_prepopulated();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(KernelRtlilTest, ConstAssignCompare)
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
# Various tests
|
||||
|
||||
## Disabled
|
||||
|
||||
- `abc9`: we do not support `abc9`
|
||||
- `check`: we do not support memory initialization
|
||||
- `ice40_mince_abc9`: we do not support `abc9`
|
||||
- `plugin`: we do not support plugins
|
||||
|
||||
## FIXME
|
||||
|
||||
- `cutpoint_blackbox`: unknown issue, needs to be looked into
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
# prefer output name
|
||||
design -reset
|
||||
read_rtlil <<EOT
|
||||
autoidx 2
|
||||
module \top
|
||||
wire output 3 $y
|
||||
wire output 3 \y
|
||||
wire input 1 \a
|
||||
wire input 2 \b
|
||||
cell $and \b_$and_B
|
||||
cell $and $name
|
||||
parameter \A_SIGNED 0
|
||||
parameter \A_WIDTH 1
|
||||
parameter \B_SIGNED 0
|
||||
|
|
@ -12,8 +13,193 @@ module \top
|
|||
parameter \Y_WIDTH 1
|
||||
connect \A \a
|
||||
connect \B \b
|
||||
connect \Y \y
|
||||
end
|
||||
end
|
||||
EOT
|
||||
logger -expect log "Rename cell .name in top to y_.and_Y" 1
|
||||
logger -expect log "Renamed 1 objects" 1
|
||||
debug autoname
|
||||
logger -check-expected
|
||||
|
||||
# fallback to shortest name if output is private
|
||||
design -reset
|
||||
read_rtlil <<EOT
|
||||
autoidx 2
|
||||
module \top
|
||||
wire output 3 $y
|
||||
wire input 1 \ab
|
||||
wire input 2 \abcd
|
||||
cell $or $name
|
||||
parameter \A_SIGNED 0
|
||||
parameter \A_WIDTH 1
|
||||
parameter \B_SIGNED 0
|
||||
parameter \B_WIDTH 1
|
||||
parameter \Y_WIDTH 1
|
||||
connect \A \ab
|
||||
connect \B \abcd
|
||||
connect \Y $y
|
||||
end
|
||||
end
|
||||
EOT
|
||||
autoname
|
||||
logger -expect log "Rename cell .name in top to ab_.or_A" 1
|
||||
logger -expect log "Renamed 1 objects" 1
|
||||
debug autoname
|
||||
logger -check-expected
|
||||
|
||||
# prefer low fanout over low name length
|
||||
design -reset
|
||||
read_rtlil <<EOT
|
||||
module \top
|
||||
wire output 1 $y
|
||||
wire input 2 \a
|
||||
wire input 3 \bcd
|
||||
wire input 4 \c_has_a_long_name
|
||||
cell $and $name
|
||||
parameter \A_SIGNED 0
|
||||
parameter \A_WIDTH 1
|
||||
parameter \B_SIGNED 0
|
||||
parameter \B_WIDTH 1
|
||||
parameter \Y_WIDTH 1
|
||||
connect \A \a
|
||||
connect \B \bcd
|
||||
connect \Y $y
|
||||
end
|
||||
|
||||
cell $or $name2
|
||||
parameter \A_SIGNED 0
|
||||
parameter \A_WIDTH 1
|
||||
parameter \B_SIGNED 0
|
||||
parameter \B_WIDTH 1
|
||||
parameter \Y_WIDTH 1
|
||||
connect \A \a
|
||||
connect \B \c_has_a_long_name
|
||||
connect \Y $y
|
||||
end
|
||||
end
|
||||
EOT
|
||||
logger -expect log "Rename cell .name in top to bcd_.and_B" 1
|
||||
logger -expect log "Rename cell .name2 in top to c_has_a_long_name_.or_B" 1
|
||||
logger -expect log "Renamed 2 objects" 1
|
||||
debug autoname
|
||||
logger -check-expected
|
||||
|
||||
# names are unique
|
||||
design -reset
|
||||
read_rtlil <<EOT
|
||||
module \top
|
||||
wire output 3 \y
|
||||
wire input 1 \a
|
||||
wire input 2 \b
|
||||
cell $and $name
|
||||
parameter \A_SIGNED 0
|
||||
parameter \A_WIDTH 1
|
||||
parameter \B_SIGNED 0
|
||||
parameter \B_WIDTH 1
|
||||
parameter \Y_WIDTH 1
|
||||
connect \A \a
|
||||
connect \B \b
|
||||
connect \Y \y
|
||||
end
|
||||
|
||||
cell $and $name2
|
||||
parameter \A_SIGNED 0
|
||||
parameter \A_WIDTH 1
|
||||
parameter \B_SIGNED 0
|
||||
parameter \B_WIDTH 1
|
||||
parameter \Y_WIDTH 1
|
||||
connect \A \a
|
||||
connect \B \b
|
||||
connect \Y \y
|
||||
end
|
||||
end
|
||||
EOT
|
||||
logger -expect log "Rename cell .name in top to y_.and_Y" 1
|
||||
logger -expect log "Rename cell .name2 in top to y_.and_Y_1" 1
|
||||
logger -expect log "Renamed 2 objects" 1
|
||||
debug autoname
|
||||
logger -check-expected
|
||||
|
||||
# wires get autonames too
|
||||
design -reset
|
||||
read_rtlil <<EOT
|
||||
module \top
|
||||
wire output 1 $y
|
||||
wire input 2 \a
|
||||
wire input 3 \bcd
|
||||
wire $c
|
||||
wire $d
|
||||
wire $e
|
||||
cell $__unknown $name
|
||||
parameter \A_SIGNED 0
|
||||
parameter \A_WIDTH 1
|
||||
parameter \B_SIGNED 0
|
||||
parameter \B_WIDTH 1
|
||||
parameter \Y_WIDTH 1
|
||||
connect \A \a
|
||||
connect \B \bcd
|
||||
connect \Y $c
|
||||
end
|
||||
|
||||
cell $or \or
|
||||
parameter \A_SIGNED 0
|
||||
parameter \A_WIDTH 1
|
||||
parameter \B_SIGNED 0
|
||||
parameter \B_WIDTH 1
|
||||
parameter \Y_WIDTH 1
|
||||
connect \A \a
|
||||
connect \B \bcd
|
||||
connect \Y $d
|
||||
end
|
||||
|
||||
cell $or $name2
|
||||
parameter \A_SIGNED 0
|
||||
parameter \A_WIDTH 1
|
||||
parameter \B_SIGNED 0
|
||||
parameter \B_WIDTH 1
|
||||
parameter \Y_WIDTH 1
|
||||
connect \A $c
|
||||
connect \B $d
|
||||
connect \Y $e
|
||||
end
|
||||
|
||||
cell $and $name3
|
||||
parameter \A_SIGNED 0
|
||||
parameter \A_WIDTH 1
|
||||
parameter \B_SIGNED 0
|
||||
parameter \B_WIDTH 1
|
||||
parameter \Y_WIDTH 1
|
||||
connect \A $c
|
||||
connect \B $e
|
||||
connect \Y $y
|
||||
end
|
||||
end
|
||||
EOT
|
||||
design -save order_test
|
||||
|
||||
# wires are named for being cell outputs
|
||||
logger -expect log "Rename wire .d in top to or_Y" 1
|
||||
logger -expect log "Rename cell .name2 in top to or_Y_.or_B" 1
|
||||
logger -expect log "Renamed 2 objects" 1
|
||||
debug autoname t:$or
|
||||
logger -check-expected
|
||||
|
||||
# $name gets shortest name (otherwise bcd_$__unknown_B)
|
||||
logger -expect log "Rename cell .name in top to a_.__unknown_A" 1
|
||||
# another output wire
|
||||
logger -expect log "Rename wire .e in top to or_Y_.or_B_Y" 1
|
||||
logger -expect log "Renamed 4 objects" 1
|
||||
debug autoname
|
||||
logger -check-expected
|
||||
|
||||
# don't rename prematurely (some objects should be named after $name2)
|
||||
design -load order_test
|
||||
|
||||
# $c gets shortest name, since the cell driving it doesn't have known port
|
||||
# directions (otherwise a_$__unknown_A_Y)
|
||||
logger -expect log "Rename wire .c in top to or_Y_.or_B_A" 1
|
||||
# $name3 named for lowest fanout wire (otherwise a_$__unknown_A_Y_$and_A)
|
||||
logger -expect log "Rename cell .name3 in top to or_Y_.or_B_Y_.and_B" 1
|
||||
logger -expect log "Renamed 6 objects" 1
|
||||
debug autoname
|
||||
logger -check-expected
|
||||
|
|
|
|||
|
|
@ -67,6 +67,47 @@ select -read cutpoint.gold.sel
|
|||
#select -assert-none % %n
|
||||
|
||||
design -load gold
|
||||
select -read cutpoint.gate.sel
|
||||
select -read cutpoint.gold.sel
|
||||
# nothing in gold but not gate
|
||||
#select -assert-none % %n
|
||||
select -assert-none % %n
|
||||
|
||||
# replacing the blackbox with a verific-style unknown module should work too
|
||||
# (note this specific example loses the values of SOME_PARAM which would
|
||||
# normally be retained by verific)
|
||||
design -load hier
|
||||
delete =bb
|
||||
read_rtlil << EOT
|
||||
attribute \blackbox 1
|
||||
module \bb
|
||||
parameter \SOME_PARAM 0
|
||||
wire inout 3 \o
|
||||
wire inout 2 \b
|
||||
wire inout 1 \a
|
||||
end
|
||||
EOT
|
||||
cutpoint -blackbox
|
||||
check -assert
|
||||
|
||||
# also concatenated signals, and signals between two inout ports
|
||||
design -load hier
|
||||
delete top =bb
|
||||
read_verilog << EOT
|
||||
module top(input [1:0] a, b, output [1:0] o);
|
||||
wire [1:0] c, d, e;
|
||||
bb #(.SOME_PARAM(1)) bb1 (.a ({a[0], e[1]}), .b (b), .o (c));
|
||||
bb #(.SOME_PARAM(2)) bb2 (.a ({c[1], a[0]}), .b (c), .o (d));
|
||||
wb wb1 (.a (a), .b (b), .o (e));
|
||||
some_mod some_inst (.a (c), .b (d), .c (e), .o (o));
|
||||
endmodule
|
||||
EOT
|
||||
read_rtlil << EOT
|
||||
attribute \blackbox 1
|
||||
module \bb
|
||||
parameter \SOME_PARAM 0
|
||||
wire inout 3 width 2 \o
|
||||
wire inout 2 width 2 \b
|
||||
wire inout 1 width 2 \a
|
||||
end
|
||||
EOT
|
||||
cutpoint -blackbox
|
||||
check -assert
|
||||
Loading…
Reference in New Issue