3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-06-22 16:50:29 +00:00

Merge branch 'YosysHQ:main' into master

This commit is contained in:
Eder Monteiro 2025-10-21 17:14:37 -03:00 committed by GitHub
commit a961373c0d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
35 changed files with 792 additions and 122 deletions

1
.gitignore vendored
View file

@ -5,6 +5,7 @@
/Brewfile.lock.json
## build artifacts
/.git-abc-submodule-hash
# compiler intermediate files
*.o
*.d

View file

@ -160,7 +160,7 @@ ifeq ($(OS), Haiku)
CXXFLAGS += -D_DEFAULT_SOURCE
endif
YOSYS_VER := 0.58+35
YOSYS_VER := 0.58+80
YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1)
YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1)
YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2)
@ -845,7 +845,17 @@ check-git-abc:
exit 1; \
fi
abc/abc$(EXE) abc/libabc.a: | check-git-abc
.git-abc-submodule-hash: FORCE
@new=$$(cd abc 2>/dev/null && git rev-parse HEAD 2>/dev/null || echo none); \
old=$$(cat .git-abc-submodule-hash 2>/dev/null || echo none); \
if [ "$$new" != "$$old" ]; then \
echo "$$new" > .git-abc-submodule-hash; \
fi
abc/abc$(EXE) abc/libabc.a: .git-abc-submodule-hash | check-git-abc
@if [ "$$(cd abc 2>/dev/null && git rev-parse HEAD 2>/dev/null)" != "$$(cat ../.git-abc-submodule-hash 2>/dev/null || echo none)" ]; then \
rm -f abc/abc$(EXE); \
fi
$(P)
$(Q) mkdir -p abc && $(MAKE) -C $(PROGRAM_PREFIX)abc -f "$(realpath $(YOSYS_SRC)/abc/Makefile)" ABCSRC="$(realpath $(YOSYS_SRC)/abc/)" $(S) $(ABCMKARGS) $(if $(filter %.a,$@),PROG="abc",PROG="abc$(EXE)") MSG_PREFIX="$(eval P_OFFSET = 5)$(call P_SHOW)$(eval P_OFFSET = 10) ABC: " $(if $(filter %.a,$@),libabc.a)
@ -1121,7 +1131,7 @@ docs: docs/prep
clean: clean-py
rm -rf share
rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) $(EXTRA_OBJS) $(PY_WRAP_INCLUDES)
rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) $(EXTRA_OBJS)
rm -f kernel/version_*.o kernel/version_*.cc
rm -f libs/*/*.d frontends/*/*.d passes/*/*.d backends/*/*.d kernel/*.d techlibs/*/*.d
rm -rf tests/asicworld/*.out tests/asicworld/*.log
@ -1147,7 +1157,7 @@ clean-py:
clean-abc:
$(MAKE) -C abc DEP= clean
rm -f $(PROGRAM_PREFIX)yosys-abc$(EXE) $(PROGRAM_PREFIX)yosys-libabc.a abc/abc-[0-9a-f]* abc/libabc-[0-9a-f]*.a
rm -f $(PROGRAM_PREFIX)yosys-abc$(EXE) $(PROGRAM_PREFIX)yosys-libabc.a abc/abc-[0-9a-f]* abc/libabc-[0-9a-f]*.a .git-abc-submodule-hash
mrproper: clean
git clean -xdf

2
abc

@ -1 +1 @@
Subproject commit 8827bafb7f288de6749dc6e30fa452f2040949c0
Subproject commit fa186342baefea06e7c2aa13fe51f338ffc84912

View file

@ -98,6 +98,8 @@ struct BtorWorker
vector<ywmap_btor_sig> ywmap_states;
dict<SigBit, int> ywmap_clock_bits;
dict<SigBit, int> ywmap_clock_inputs;
vector<Cell *> ywmap_asserts;
vector<Cell *> ywmap_assumes;
PrettyJson ywmap_json;
@ -1280,6 +1282,8 @@ struct BtorWorker
btorf("%d or %d %d %d\n", nid_a_or_not_en, sid, nid_a, nid_not_en);
btorf("%d constraint %d\n", nid, nid_a_or_not_en);
if (ywmap_json.active()) ywmap_assumes.emplace_back(cell);
btorf_pop(log_id(cell));
}
@ -1304,6 +1308,8 @@ struct BtorWorker
} else {
int nid = next_nid++;
btorf("%d bad %d%s\n", nid, nid_en_and_not_a, getinfo(cell, true));
if (ywmap_json.active()) ywmap_asserts.emplace_back(cell);
}
}
@ -1461,6 +1467,7 @@ struct BtorWorker
log_assert(cursor == 0);
log_assert(GetSize(todo) == 1);
btorf("%d bad %d\n", nid, todo[cursor]);
// What do we do with ywmap_asserts when using single_bad?
}
}
@ -1526,6 +1533,18 @@ struct BtorWorker
emit_ywmap_btor_sig(entry);
ywmap_json.end_array();
ywmap_json.name("asserts");
ywmap_json.begin_array();
for (Cell *cell : ywmap_asserts)
ywmap_json.value(witness_path(cell));
ywmap_json.end_array();
ywmap_json.name("assumes");
ywmap_json.begin_array();
for (Cell *cell : ywmap_assumes)
ywmap_json.value(witness_path(cell));
ywmap_json.end_array();
ywmap_json.end_object();
}
}

View file

@ -324,29 +324,27 @@ struct RTLILFrontendWorker {
RTLIL::SigSpec parse_sigspec()
{
RTLIL::SigSpec sig;
if (try_parse_char('{')) {
std::vector<SigSpec> parts;
while (!try_parse_char('}'))
parts.push_back(parse_sigspec());
RTLIL::SigSpec sig;
for (auto it = parts.rbegin(); it != parts.rend(); ++it)
sig.append(std::move(*it));
return sig;
}
RTLIL::SigSpec sig;
// We could add a special path for parsing IdStrings that must already exist,
// as here.
// We don't need to addref/release in this case.
std::optional<RTLIL::IdString> id = try_parse_id();
if (id.has_value()) {
RTLIL::Wire *wire = current_module->wire(*id);
if (wire == nullptr)
error("Wire `%s' not found.", *id);
sig = RTLIL::SigSpec(wire);
} else {
sig = RTLIL::SigSpec(parse_const());
// We could add a special path for parsing IdStrings that must already exist,
// as here.
// We don't need to addref/release in this case.
std::optional<RTLIL::IdString> id = try_parse_id();
if (id.has_value()) {
RTLIL::Wire *wire = current_module->wire(*id);
if (wire == nullptr)
error("Wire `%s' not found.", *id);
sig = RTLIL::SigSpec(wire);
} else {
sig = RTLIL::SigSpec(parse_const());
}
}
while (try_parse_char('[')) {

View file

@ -168,12 +168,12 @@ string get_full_netlist_name(Netlist *nl)
std::string format_src_location(DesignObj *obj)
{
if (obj == nullptr || obj->Linefile() == nullptr)
if (obj == nullptr || !obj->Linefile())
return std::string();
#ifdef VERIFIC_LINEFILE_INCLUDES_COLUMNS
return stringf("%s:%d.%d-%d.%d", LineFile::GetFileName(obj->Linefile()), obj->Linefile()->GetLeftLine(), obj->Linefile()->GetLeftCol(), obj->Linefile()->GetRightLine(), obj->Linefile()->GetRightCol());
return stringf("%s:%d.%d-%d.%d", LineFile::GetFileName(obj->Linefile()), obj->Linefile()->GetLeftLine(), obj->Linefile()->GetLeftCol(), obj->Linefile()->GetRightLine(), obj->Linefile()->GetRightCol());
#else
return stringf("%s:%d", LineFile::GetFileName(obj->Linefile()), LineFile::GetLineNo(obj->Linefile()));
return stringf("%s:%d", LineFile::GetFileName(obj->Linefile()), LineFile::GetLineNo(obj->Linefile()));
#endif
}
@ -1663,7 +1663,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma
if (*ascii_initdata == 0)
break;
if (*ascii_initdata == '0' || *ascii_initdata == '1') {
initval.bits()[bit_idx] = (*ascii_initdata == '0') ? State::S0 : State::S1;
initval.set(bit_idx, (*ascii_initdata == '0') ? State::S0 : State::S1);
initval_valid = true;
}
ascii_initdata++;
@ -1787,9 +1787,9 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma
if (init_nets.count(net)) {
if (init_nets.at(net) == '0')
initval.bits().at(bitidx) = State::S0;
initval.set(bitidx, State::S0);
if (init_nets.at(net) == '1')
initval.bits().at(bitidx) = State::S1;
initval.set(bitidx, State::S1);
initval_valid = true;
init_nets.erase(net);
}
@ -1862,13 +1862,13 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma
if (bit.wire->attributes.count(ID::init))
initval = bit.wire->attributes.at(ID::init);
while (GetSize(initval) < GetSize(bit.wire))
initval.bits().push_back(State::Sx);
if (GetSize(initval) < GetSize(bit.wire))
initval.resize(GetSize(bit.wire), State::Sx);
if (it.second == '0')
initval.bits().at(bit.offset) = State::S0;
initval.set(bit.offset, State::S0);
if (it.second == '1')
initval.bits().at(bit.offset) = State::S1;
initval.set(bit.offset, State::S1);
bit.wire->attributes[ID::init] = initval;
}
@ -1995,7 +1995,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma
if (import_netlist_instance_cells(inst, inst_name))
continue;
if (inst->IsOperator() && !verific_sva_prims.count(inst->Type()))
log_warning("Unsupported Verific operator: %s (fallback to gate level implementation provided by verific)\n", inst->View()->Owner()->Name());
log_warning("%sUnsupported Verific operator: %s (fallback to gate level implementation provided by verific)\n", announce_src_location(inst), inst->View()->Owner()->Name());
} else {
if (import_netlist_instance_gates(inst, inst_name))
continue;
@ -2055,7 +2055,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma
}
Const qx_init = Const(State::S1, width);
qx_init.bits().resize(2 * width, State::S0);
qx_init.resize(2 * width, State::S0);
clocking.addDff(new_verific_id(inst), sig_dx, sig_qx, qx_init);
module->addXnor(new_verific_id(inst), sig_dx, sig_qx, sig_ox);
@ -2320,7 +2320,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma
continue;
if (non_ff_bits.count(SigBit(wire, i)))
initval.bits()[i] = State::Sx;
initval.set(i, State::Sx);
}
if (wire->port_input) {
@ -2513,7 +2513,7 @@ Cell *VerificClocking::addDff(IdString name, SigSpec sig_d, SigSpec sig_q, Const
if (c.wire && c.wire->attributes.count(ID::init)) {
Const val = c.wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(c); i++)
initval.bits()[offset+i] = val[c.offset+i];
initval.set(offset+i, val[c.offset+i]);
}
offset += GetSize(c);
}
@ -2584,7 +2584,7 @@ Cell *VerificClocking::addAldff(IdString name, RTLIL::SigSpec sig_aload, RTLIL::
if (c.wire && c.wire->attributes.count(ID::init)) {
Const val = c.wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(c); i++)
initval.bits()[offset+i] = val[c.offset+i];
initval.set(offset+i, val[c.offset+i]);
}
offset += GetSize(c);
}

View file

@ -577,7 +577,7 @@ struct SvaFsm
if (delta_pos >= 0 && i_within_j && j_within_i) {
did_something = true;
values[i].bits()[delta_pos] = State::Sa;
values[i].set(delta_pos, State::Sa);
values[j] = values.back();
values.pop_back();
goto next_pair;

View file

@ -384,6 +384,13 @@ std::string escape_filename_spaces(const std::string& filename)
return out;
}
void append_globbed(std::vector<std::string>& paths, std::string pattern)
{
rewrite_filename(pattern);
std::vector<std::string> globbed = glob_filename(pattern);
copy(globbed.begin(), globbed.end(), back_inserter(paths));
}
void format_emit_unescaped(std::string &result, std::string_view fmt)
{
result.reserve(result.size() + fmt.size());

View file

@ -469,6 +469,7 @@ bool is_absolute_path(std::string filename);
void remove_directory(std::string dirname);
bool create_directory(const std::string& dirname);
std::string escape_filename_spaces(const std::string& filename);
void append_globbed(std::vector<std::string>& paths, std::string pattern);
YOSYS_NAMESPACE_END

View file

@ -57,3 +57,4 @@ OBJS += passes/cmds/abstract.o
OBJS += passes/cmds/test_select.o
OBJS += passes/cmds/timeest.o
OBJS += passes/cmds/linecoverage.o
OBJS += passes/cmds/sort.o

View file

@ -51,6 +51,9 @@ struct BoxDerivePass : Pass {
log(" replaces the internal Yosys naming scheme in which the names of derived\n");
log(" modules start with '$paramod$')\n");
log("\n");
log(" -apply_derived_type\n");
log(" use the derived modules\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *d) override
{
@ -59,11 +62,14 @@ struct BoxDerivePass : Pass {
size_t argidx;
IdString naming_attr;
IdString base_name;
bool apply_mode = false;
for (argidx = 1; argidx < args.size(); argidx++) {
if (args[argidx] == "-naming_attr" && argidx + 1 < args.size())
naming_attr = RTLIL::escape_id(args[++argidx]);
else if (args[argidx] == "-base" && argidx + 1 < args.size())
base_name = RTLIL::escape_id(args[++argidx]);
else if (args[argidx] == "-apply_derived_type")
apply_mode = true;
else
break;
}
@ -90,24 +96,29 @@ struct BoxDerivePass : Pass {
auto index = std::make_pair(base->name, cell->parameters);
if (cell->parameters.empty() || done.count(index))
if (cell->parameters.empty())
continue;
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);
if (!done.count(index)) {
IdString derived_type = base->derive(d, cell->parameters);
Module *derived = d->module(derived_type);
log_assert(derived && "Failed to derive module\n");
log("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));
if (!new_name.isPublic())
log_error("Derived module %s cannot be renamed to private name %s.\n",
log_id(derived), log_id(new_name));
derived->attributes.erase(naming_attr);
d->rename(derived, new_name);
if (!naming_attr.empty() && derived->has_attribute(naming_attr)) {
IdString new_name = RTLIL::escape_id(derived->get_string_attribute(naming_attr));
if (!new_name.isPublic())
log_error("Derived module %s cannot be renamed to private name %s.\n",
log_id(derived), log_id(new_name));
derived->attributes.erase(naming_attr);
d->rename(derived, new_name);
}
done[index] = derived;
}
done[index] = derived;
if (apply_mode)
cell->type = done[index]->name;
}
}
}

View file

@ -22,6 +22,27 @@
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
static void publish(RTLIL::IdString& id) {
if (id.begins_with("$")) {
log_debug("publishing %s\n", id.c_str());
id = "\\" + id.str();
log_debug("published %s\n", id.c_str());
}
}
static void publish_design(RTLIL::Design* design) {
auto saved_modules = design->modules_;
design->modules_.clear();
for (auto& [name, mod] : saved_modules) {
publish(mod->name);
design->modules_[mod->name] = mod;
for (auto* cell : mod->cells()) {
publish(cell->type);
}
}
}
struct ChtypePass : public Pass {
ChtypePass() : Pass("chtype", "change type of cells in the design") { }
void help() override
@ -38,12 +59,16 @@ struct ChtypePass : public Pass {
log(" -map <old_type> <new_type>\n");
log(" change cells types that match <old_type> to <new_type>\n");
log("\n");
log(" -publish_icells\n");
log(" change internal cells types to public types\n");
log("\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
IdString set_type;
dict<IdString, IdString> map_types;
bool publish_mode = false;
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
@ -58,10 +83,17 @@ struct ChtypePass : public Pass {
map_types[old_type] = new_type;
continue;
}
if (args[argidx] == "-publish_icells") {
publish_mode = true;
continue;
}
break;
}
extra_args(args, argidx, design);
if (publish_mode)
publish_design(design);
for (auto module : design->selected_modules())
{
for (auto cell : module->selected_cells())

View file

@ -22,6 +22,8 @@
#ifdef YOSYS_ENABLE_PLUGINS
# include <dlfcn.h>
# include <filesystem>
namespace fs = std::filesystem;
#endif
#ifdef YOSYS_ENABLE_PYTHON
@ -39,6 +41,26 @@ std::map<std::string, void*> loaded_python_plugins;
std::map<std::string, std::string> loaded_plugin_aliases;
#ifdef YOSYS_ENABLE_PLUGINS
static constexpr const char *path_delimiters = fs::path::preferred_separator == '\\' ? ";" : ":" ;
inline const std::vector<fs::path> get_plugin_search_paths() {
std::vector<fs::path> result;
const char *yosys_plugin_path = std::getenv("YOSYS_PLUGIN_PATH");
if (yosys_plugin_path != nullptr && strlen(yosys_plugin_path)) {
// make mutable. std::string also manages allocation as a bonus
// guaranteed contiguous in c++>=11
std::string copy{yosys_plugin_path};
char *token = nullptr;
char *rest = &copy[0];
while ((token = strtok_r(rest, path_delimiters, &rest))) {
result.push_back(fs::path(token));
}
}
result.push_back(fs::path(proc_share_dirname()) / "plugins"); // lowest priority
return result;
}
void load_plugin(std::string filename, std::vector<std::string> aliases)
{
std::string orig_filename = filename;
@ -55,17 +77,17 @@ void load_plugin(std::string filename, std::vector<std::string> aliases)
const bool is_loaded = loaded_plugins.count(orig_filename);
#endif
fs::path full_path = fs::absolute(filename);
if (!is_loaded) {
// Check if we're loading a python script
if (filename.rfind(".py") != std::string::npos) {
if (full_path.extension() == ".py") {
#ifdef YOSYS_ENABLE_PYTHON
py::object Path = py::module_::import("pathlib").attr("Path");
py::object full_path = Path(py::cast(filename));
py::object plugin_python_path = full_path.attr("parent");
auto basename = py::cast<std::string>(full_path.attr("stem"));
fs::path plugin_python_path = full_path.parent_path();
fs::path basename = full_path.stem();
py::object sys = py::module_::import("sys");
sys.attr("path").attr("insert")(0, py::str(plugin_python_path));
sys.attr("path").attr("insert")(0, py::str(plugin_python_path.c_str()));
try {
auto module_container = py::module_::import(basename.c_str());
@ -83,23 +105,25 @@ void load_plugin(std::string filename, std::vector<std::string> aliases)
#endif
} else {
// Otherwise we assume it's a native plugin
void *hdl = dlopen(filename.c_str(), RTLD_LAZY|RTLD_LOCAL);
// We were unable to open the file, try to do so from the plugin directory
if (hdl == NULL && orig_filename.find('/') == std::string::npos) {
hdl = dlopen([orig_filename]() {
std::string new_path = proc_share_dirname() + "plugins/" + orig_filename;
// Check if we need to append .so
if (new_path.find(".so") == std::string::npos)
new_path.append(".so");
return new_path;
}().c_str(), RTLD_LAZY|RTLD_LOCAL);
// We were unable to open the file, try to do so from plugin search
// paths
if (hdl == nullptr && orig_filename.find('/') == std::string::npos) {
const std::vector<fs::path> search_paths = get_plugin_search_paths();
for (const auto &search_path: search_paths) {
fs::path potential_path = search_path / orig_filename;
if (potential_path.extension() != ".so") {
potential_path = search_path / (orig_filename + ".so");
}
hdl = dlopen(potential_path.string().c_str(), RTLD_LAZY | RTLD_LOCAL);
if (hdl != nullptr) {
break;
}
}
}
if (hdl == NULL)
if (hdl == nullptr)
log_cmd_error("Can't load module `%s': %s\n", filename, dlerror());
loaded_plugins[orig_filename] = hdl;
@ -116,7 +140,7 @@ void load_plugin(std::string, std::vector<std::string>)
log_error(
"\n This version of Yosys cannot load plugins at runtime.\n"
" Some plugins may have been included at build time.\n"
" Use option `-H' to see the available built-in and plugin commands.\n"
" Use `yosys -H' to see the available built-in and plugin commands.\n"
);
}
#endif

26
passes/cmds/sort.cc Normal file
View file

@ -0,0 +1,26 @@
#include "kernel/yosys.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
struct SortPass : Pass {
SortPass() : Pass("sort", "sort the design objects") {}
void help() override
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" sort\n");
log("\n");
log("Sorts the design objects.\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *d) override
{
log_header(d, "Executing SORT pass.\n");
if (args.size() != 1)
log_cmd_error("This pass takes no arguments.\n");
d->sort();
}
} SortPass;
PRIVATE_NAMESPACE_END

View file

@ -1392,7 +1392,7 @@ struct SimWorker : SimShared
}
}
void run(Module *topmod, int numcycles)
void run(Module *topmod, int cycle_width, int numcycles)
{
log_assert(top == nullptr);
top = new SimInstance(this, scope, topmod);
@ -1418,20 +1418,20 @@ struct SimWorker : SimShared
for (int cycle = 0; cycle < numcycles; cycle++)
{
if (debug)
log("\n===== %d =====\n", 10*cycle + 5);
log("\n===== %d =====\n", int(cycle_width*cycle + cycle_width/2));
else if (verbose)
log("Simulating cycle %d.\n", (cycle*2)+1);
set_inports(clock, State::S0);
set_inports(clockn, State::S1);
update(true);
register_output_step(10*cycle + 5);
register_output_step(cycle_width*cycle + cycle_width/2);
if (cycle == 0)
top->set_initstate_outputs(State::S0);
if (debug)
log("\n===== %d =====\n", 10*cycle + 10);
log("\n===== %d =====\n", int(cycle_width*cycle + cycle_width));
else if (verbose)
log("Simulating cycle %d.\n", (cycle*2)+2);
@ -1444,10 +1444,10 @@ struct SimWorker : SimShared
}
update(true);
register_output_step(10*cycle + 10);
register_output_step(cycle_width*cycle + cycle_width);
}
register_output_step(10*numcycles + 2);
register_output_step(cycle_width*numcycles + 2);
write_output_files();
}
@ -1582,7 +1582,7 @@ struct SimWorker : SimShared
return atoi(name.substr(pos+1).c_str());
}
void run_cosim_aiger_witness(Module *topmod)
void run_cosim_aiger_witness(Module *topmod, int cycle_width)
{
log_assert(top == nullptr);
if (!multiclock && (clock.size()+clockn.size())==0)
@ -1691,18 +1691,18 @@ struct SimWorker : SimShared
set_inports(clockn, State::S1);
}
update(true);
register_output_step(10*cycle);
register_output_step(cycle_width*cycle);
if (!multiclock && cycle) {
set_inports(clock, State::S0);
set_inports(clockn, State::S1);
update(true);
register_output_step(10*cycle + 5);
register_output_step(cycle_width*cycle + cycle_width/2);
}
cycle++;
break;
}
}
register_output_step(10*cycle);
register_output_step(cycle_width*cycle);
write_output_files();
}
@ -1730,7 +1730,7 @@ struct SimWorker : SimShared
return name.substr(0, pos);
}
void run_cosim_btor2_witness(Module *topmod)
void run_cosim_btor2_witness(Module *topmod, int cycle_width)
{
log_assert(top == nullptr);
if (!multiclock && (clock.size()+clockn.size())==0)
@ -1768,12 +1768,12 @@ struct SimWorker : SimShared
set_inports(clock, State::S1);
set_inports(clockn, State::S0);
update(true);
register_output_step(10*cycle+0);
register_output_step(cycle_width*cycle + 0);
if (!multiclock) {
set_inports(clock, State::S0);
set_inports(clockn, State::S1);
update(true);
register_output_step(10*cycle+5);
register_output_step(cycle_width*cycle + cycle_width/2);
}
cycle++;
prev_cycle = curr_cycle;
@ -1832,7 +1832,7 @@ struct SimWorker : SimShared
break;
}
}
register_output_step(10*cycle);
register_output_step(cycle_width*cycle);
write_output_files();
}
@ -1983,7 +1983,7 @@ struct SimWorker : SimShared
}
}
void run_cosim_yw_witness(Module *topmod, int append)
void run_cosim_yw_witness(Module *topmod, int cycle_width, int append)
{
if (!clock.empty())
log_cmd_error("The -clock option is not required nor supported when reading a Yosys witness file.\n");
@ -2013,7 +2013,7 @@ struct SimWorker : SimShared
log("Simulating non-active clock edge.\n");
set_yw_clocks(yw, hierarchy, false);
update(false);
register_output_step(5);
register_output_step(cycle_width/2);
}
top->set_initstate_outputs(State::S0);
}
@ -2026,18 +2026,18 @@ struct SimWorker : SimShared
set_yw_state(yw, hierarchy, cycle);
set_yw_clocks(yw, hierarchy, true);
update(true);
register_output_step(10 * cycle);
register_output_step(cycle_width*cycle);
if (!yw.clocks.empty()) {
if (debug)
log("Simulating non-active clock edge.\n");
set_yw_clocks(yw, hierarchy, false);
update(false);
register_output_step(5 + 10 * cycle);
register_output_step(cycle_width*cycle + cycle_width/2);
}
}
register_output_step(10 * (GetSize(yw.steps) + append));
register_output_step(cycle_width * (GetSize(yw.steps) + append));
write_output_files();
}
@ -2630,6 +2630,9 @@ struct SimPass : public Pass {
log(" File formats supported: FST, VCD, AIW, WIT and .yw\n");
log(" VCD support requires vcd2fst external tool to be present\n");
log("\n");
log(" -width <integer>\n");
log(" cycle width in generated simulation output (must be divisible by 2).\n");
log("\n");
log(" -append <integer>\n");
log(" number of extra clock cycles to simulate for a Yosys witness input\n");
log("\n");
@ -2689,6 +2692,7 @@ struct SimPass : public Pass {
{
SimWorker worker;
int numcycles = 20;
int cycle_width = 10;
int append = 0;
bool start_set = false, stop_set = false, at_set = false;
@ -2781,6 +2785,12 @@ struct SimPass : public Pass {
append = atoi(args[++argidx].c_str());
continue;
}
if (args[argidx] == "-width" && argidx+1 < args.size()) {
cycle_width = atoi(args[++argidx].c_str());
if (cycle_width <= 0 || (cycle_width % 2))
log_cmd_error("Cycle width must be positive even number.\n");
continue;
}
if (args[argidx] == "-map" && argidx+1 < args.size()) {
std::string map_filename = args[++argidx];
rewrite_filename(map_filename);
@ -2872,7 +2882,7 @@ struct SimPass : public Pass {
}
if (worker.sim_filename.empty())
worker.run(top_mod, numcycles);
worker.run(top_mod, cycle_width, numcycles);
else {
std::string filename_trim = file_base_name(worker.sim_filename);
if (filename_trim.size() > 4 && ((filename_trim.compare(filename_trim.size()-4, std::string::npos, ".fst") == 0) ||
@ -2881,11 +2891,11 @@ struct SimPass : public Pass {
} else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".aiw") == 0) {
if (worker.map_filename.empty())
log_cmd_error("For AIGER witness file map parameter is mandatory.\n");
worker.run_cosim_aiger_witness(top_mod);
worker.run_cosim_aiger_witness(top_mod, cycle_width);
} else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".wit") == 0) {
worker.run_cosim_btor2_witness(top_mod);
worker.run_cosim_btor2_witness(top_mod, cycle_width);
} else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".yw") == 0) {
worker.run_cosim_yw_witness(top_mod, append);
worker.run_cosim_yw_witness(top_mod, cycle_width, append);
} else {
log_cmd_error("Unhandled extension for simulation input file `%s`.\n", worker.sim_filename);
}

View file

@ -290,9 +290,7 @@ struct ClockgatePass : public Pass {
continue;
}
if (args[argidx] == "-liberty" && argidx+1 < args.size()) {
std::string liberty_file = args[++argidx];
rewrite_filename(liberty_file);
liberty_files.push_back(liberty_file);
append_globbed(liberty_files, args[++argidx]);
continue;
}
if (args[argidx] == "-dont_use" && argidx+1 < args.size()) {

View file

@ -609,9 +609,7 @@ struct DfflibmapPass : public Pass {
{
std::string arg = args[argidx];
if (arg == "-liberty" && argidx+1 < args.size()) {
std::string liberty_file = args[++argidx];
rewrite_filename(liberty_file);
liberty_files.push_back(liberty_file);
append_globbed(liberty_files, args[++argidx]);
continue;
}
if (arg == "-prepare") {

View file

@ -96,9 +96,7 @@
quiet = true;
continue;
}
std::string fname = args[argidx];
rewrite_filename(fname);
paths.push_back(fname);
append_globbed(paths, args[argidx]);
break;
}
int modes = enable + disable + purge + list + verbose + quiet;

View file

@ -8,6 +8,7 @@ $(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_xtra_gw2a.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_xtra_gw5a.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/arith_map.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/brams_map.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/brams_map_gw5a.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/brams.txt))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/lutrams_map.v))
$(eval $(call add_share_file,share/gowin,techlibs/gowin/lutrams.txt))

View file

@ -0,0 +1,399 @@
`define DEF_FUNCS \
function [255:0] init_slice_x8; \
input integer idx; \
integer i; \
for (i = 0; i < 32; i = i + 1) begin \
init_slice_x8[i*8+:8] = INIT[(idx * 32 + i) * 9+:8]; \
end \
endfunction \
function [287:0] init_slice_x9; \
input integer idx; \
init_slice_x9 = INIT[idx * 288+:288]; \
endfunction \
`define x8_width(width) (width / 9 * 8 + width % 9)
`define x8_rd_data(data) {1'bx, data[31:24], 1'bx, data[23:16], 1'bx, data[15:8], 1'bx, data[7:0]}
`define x8_wr_data(data) {data[34:27], data[25:18], data[16:9], data[7:0]}
`define addrbe_always(width, addr) (width < 18 ? addr : width == 18 ? {addr[13:4], 4'b0011} : {addr[13:5], 5'b01111})
`define INIT(func) \
.INIT_RAM_00(func('h00)), \
.INIT_RAM_01(func('h01)), \
.INIT_RAM_02(func('h02)), \
.INIT_RAM_03(func('h03)), \
.INIT_RAM_04(func('h04)), \
.INIT_RAM_05(func('h05)), \
.INIT_RAM_06(func('h06)), \
.INIT_RAM_07(func('h07)), \
.INIT_RAM_08(func('h08)), \
.INIT_RAM_09(func('h09)), \
.INIT_RAM_0A(func('h0a)), \
.INIT_RAM_0B(func('h0b)), \
.INIT_RAM_0C(func('h0c)), \
.INIT_RAM_0D(func('h0d)), \
.INIT_RAM_0E(func('h0e)), \
.INIT_RAM_0F(func('h0f)), \
.INIT_RAM_10(func('h10)), \
.INIT_RAM_11(func('h11)), \
.INIT_RAM_12(func('h12)), \
.INIT_RAM_13(func('h13)), \
.INIT_RAM_14(func('h14)), \
.INIT_RAM_15(func('h15)), \
.INIT_RAM_16(func('h16)), \
.INIT_RAM_17(func('h17)), \
.INIT_RAM_18(func('h18)), \
.INIT_RAM_19(func('h19)), \
.INIT_RAM_1A(func('h1a)), \
.INIT_RAM_1B(func('h1b)), \
.INIT_RAM_1C(func('h1c)), \
.INIT_RAM_1D(func('h1d)), \
.INIT_RAM_1E(func('h1e)), \
.INIT_RAM_1F(func('h1f)), \
.INIT_RAM_20(func('h20)), \
.INIT_RAM_21(func('h21)), \
.INIT_RAM_22(func('h22)), \
.INIT_RAM_23(func('h23)), \
.INIT_RAM_24(func('h24)), \
.INIT_RAM_25(func('h25)), \
.INIT_RAM_26(func('h26)), \
.INIT_RAM_27(func('h27)), \
.INIT_RAM_28(func('h28)), \
.INIT_RAM_29(func('h29)), \
.INIT_RAM_2A(func('h2a)), \
.INIT_RAM_2B(func('h2b)), \
.INIT_RAM_2C(func('h2c)), \
.INIT_RAM_2D(func('h2d)), \
.INIT_RAM_2E(func('h2e)), \
.INIT_RAM_2F(func('h2f)), \
.INIT_RAM_30(func('h30)), \
.INIT_RAM_31(func('h31)), \
.INIT_RAM_32(func('h32)), \
.INIT_RAM_33(func('h33)), \
.INIT_RAM_34(func('h34)), \
.INIT_RAM_35(func('h35)), \
.INIT_RAM_36(func('h36)), \
.INIT_RAM_37(func('h37)), \
.INIT_RAM_38(func('h38)), \
.INIT_RAM_39(func('h39)), \
.INIT_RAM_3A(func('h3a)), \
.INIT_RAM_3B(func('h3b)), \
.INIT_RAM_3C(func('h3c)), \
.INIT_RAM_3D(func('h3d)), \
.INIT_RAM_3E(func('h3e)), \
.INIT_RAM_3F(func('h3f)),
module $__GOWIN_SP_ (...);
parameter INIT = 0;
parameter OPTION_RESET_MODE = "SYNC";
parameter PORT_A_WIDTH = 36;
parameter PORT_A_OPTION_WRITE_MODE = 0;
input PORT_A_CLK;
input PORT_A_CLK_EN;
input PORT_A_WR_EN;
input PORT_A_RD_SRST;
input PORT_A_RD_ARST;
input [13:0] PORT_A_ADDR;
input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA;
output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA;
`DEF_FUNCS
wire RST = OPTION_RESET_MODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST;
wire [13:0] AD = `addrbe_always(PORT_A_WIDTH, PORT_A_ADDR);
generate
if (PORT_A_WIDTH < 9) begin
wire [31:0] DI = `x8_wr_data(PORT_A_WR_DATA);
wire [31:0] DO;
assign PORT_A_RD_DATA = `x8_rd_data(DO);
SP #(
`INIT(init_slice_x8)
.READ_MODE(1'b0),
.WRITE_MODE(PORT_A_OPTION_WRITE_MODE),
.BIT_WIDTH(`x8_width(PORT_A_WIDTH)),
.BLK_SEL(3'b000),
.RESET_MODE(OPTION_RESET_MODE),
) _TECHMAP_REPLACE_ (
.BLKSEL(3'b000),
.CLK(PORT_A_CLK),
.CE(PORT_A_CLK_EN),
.WRE(PORT_A_WR_EN),
.RESET(RST),
.OCE(1'b1),
.AD(AD),
.DI(DI),
.DO(DO),
);
end else begin
wire [35:0] DI = PORT_A_WR_DATA;
wire [35:0] DO;
assign PORT_A_RD_DATA = DO;
SPX9 #(
`INIT(init_slice_x9)
.READ_MODE(1'b0),
.WRITE_MODE(PORT_A_OPTION_WRITE_MODE),
.BIT_WIDTH(PORT_A_WIDTH),
.BLK_SEL(3'b000),
.RESET_MODE(OPTION_RESET_MODE),
) _TECHMAP_REPLACE_ (
.BLKSEL(3'b000),
.CLK(PORT_A_CLK),
.CE(PORT_A_CLK_EN),
.WRE(PORT_A_WR_EN),
.RESET(RST),
.OCE(1'b1),
.AD(AD),
.DI(DI),
.DO(DO),
);
end
endgenerate
endmodule
module $__GOWIN_DP_ (...);
parameter INIT = 0;
parameter OPTION_RESET_MODE = "SYNC";
parameter PORT_A_WIDTH = 18;
parameter PORT_A_OPTION_WRITE_MODE = 0;
parameter PORT_B_WIDTH = 18;
parameter PORT_B_OPTION_WRITE_MODE = 0;
input PORT_A_CLK;
input PORT_A_CLK_EN;
input PORT_A_WR_EN;
input PORT_A_RD_SRST;
input PORT_A_RD_ARST;
input [13:0] PORT_A_ADDR;
input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA;
output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA;
input PORT_B_CLK;
input PORT_B_CLK_EN;
input PORT_B_WR_EN;
input PORT_B_RD_SRST;
input PORT_B_RD_ARST;
input [13:0] PORT_B_ADDR;
input [PORT_A_WIDTH-1:0] PORT_B_WR_DATA;
output [PORT_A_WIDTH-1:0] PORT_B_RD_DATA;
`DEF_FUNCS
wire RSTA = OPTION_RESET_MODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST;
wire RSTB = OPTION_RESET_MODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST;
wire [13:0] ADA = `addrbe_always(PORT_A_WIDTH, PORT_A_ADDR);
wire [13:0] ADB = `addrbe_always(PORT_B_WIDTH, PORT_B_ADDR);
generate
if (PORT_A_WIDTH < 9 || PORT_B_WIDTH < 9) begin
wire [15:0] DIA = `x8_wr_data(PORT_A_WR_DATA);
wire [15:0] DIB = `x8_wr_data(PORT_B_WR_DATA);
wire [15:0] DOA;
wire [15:0] DOB;
assign PORT_A_RD_DATA = `x8_rd_data(DOA);
assign PORT_B_RD_DATA = `x8_rd_data(DOB);
DPB #(
`INIT(init_slice_x8)
.READ_MODE0(1'b0),
.READ_MODE1(1'b0),
.WRITE_MODE0(PORT_A_OPTION_WRITE_MODE),
.WRITE_MODE1(PORT_B_OPTION_WRITE_MODE),
.BIT_WIDTH_0(`x8_width(PORT_A_WIDTH)),
.BIT_WIDTH_1(`x8_width(PORT_B_WIDTH)),
.BLK_SEL_0(3'b000),
.BLK_SEL_1(3'b000),
.RESET_MODE(OPTION_RESET_MODE),
) _TECHMAP_REPLACE_ (
.BLKSELA(3'b000),
.BLKSELB(3'b000),
.CLKA(PORT_A_CLK),
.CEA(PORT_A_CLK_EN),
.WREA(PORT_A_WR_EN),
.RESETA(RSTA),
.OCEA(1'b1),
.ADA(ADA),
.DIA(DIA),
.DOA(DOA),
.CLKB(PORT_B_CLK),
.CEB(PORT_B_CLK_EN),
.WREB(PORT_B_WR_EN),
.RESETB(RSTB),
.OCEB(1'b1),
.ADB(ADB),
.DIB(DIB),
.DOB(DOB),
);
end else begin
wire [17:0] DIA = PORT_A_WR_DATA;
wire [17:0] DIB = PORT_B_WR_DATA;
wire [17:0] DOA;
wire [17:0] DOB;
assign PORT_A_RD_DATA = DOA;
assign PORT_B_RD_DATA = DOB;
DPX9B #(
`INIT(init_slice_x9)
.READ_MODE0(1'b0),
.READ_MODE1(1'b0),
.WRITE_MODE0(PORT_A_OPTION_WRITE_MODE),
.WRITE_MODE1(PORT_B_OPTION_WRITE_MODE),
.BIT_WIDTH_0(PORT_A_WIDTH),
.BIT_WIDTH_1(PORT_B_WIDTH),
.BLK_SEL_0(3'b000),
.BLK_SEL_1(3'b000),
.RESET_MODE(OPTION_RESET_MODE),
) _TECHMAP_REPLACE_ (
.BLKSELA(3'b000),
.BLKSELB(3'b000),
.CLKA(PORT_A_CLK),
.CEA(PORT_A_CLK_EN),
.WREA(PORT_A_WR_EN),
.RESETA(RSTA),
.OCEA(1'b1),
.ADA(ADA),
.DIA(DIA),
.DOA(DOA),
.CLKB(PORT_B_CLK),
.CEB(PORT_B_CLK_EN),
.WREB(PORT_B_WR_EN),
.RESETB(RSTB),
.OCEB(1'b1),
.ADB(ADB),
.DIB(DIB),
.DOB(DOB),
);
end
endgenerate
endmodule
module $__GOWIN_SDP_ (...);
parameter INIT = 0;
parameter OPTION_RESET_MODE = "SYNC";
parameter PORT_R_WIDTH = 18;
parameter PORT_W_WIDTH = 18;
input PORT_R_CLK;
input PORT_R_CLK_EN;
input PORT_R_RD_SRST;
input PORT_R_RD_ARST;
input [13:0] PORT_R_ADDR;
output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
input PORT_W_CLK;
input PORT_W_CLK_EN;
input PORT_W_WR_EN;
input [13:0] PORT_W_ADDR;
input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
`DEF_FUNCS
wire RST = OPTION_RESET_MODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST;
wire [13:0] ADW = `addrbe_always(PORT_W_WIDTH, PORT_W_ADDR);
wire WRE = PORT_W_CLK_EN & PORT_W_WR_EN;
generate
if (PORT_W_WIDTH < 9 || PORT_R_WIDTH < 9) begin
wire [31:0] DI = `x8_wr_data(PORT_W_WR_DATA);
wire [31:0] DO;
assign PORT_R_RD_DATA = `x8_rd_data(DO);
SDPB #(
`INIT(init_slice_x8)
.READ_MODE(1'b0),
.BIT_WIDTH_0(`x8_width(PORT_W_WIDTH)),
.BIT_WIDTH_1(`x8_width(PORT_R_WIDTH)),
.BLK_SEL_0(3'b000),
.BLK_SEL_1(3'b000),
.RESET_MODE(OPTION_RESET_MODE),
) _TECHMAP_REPLACE_ (
.BLKSELA(3'b000),
.BLKSELB(3'b000),
.CLKA(PORT_W_CLK),
.CEA(WRE),
.ADA(ADW),
.DI(DI),
.CLKB(PORT_R_CLK),
.CEB(PORT_R_CLK_EN),
.RESET(RST),
.OCE(1'b1),
.ADB(PORT_R_ADDR),
.DO(DO),
);
end else begin
wire [35:0] DI = PORT_W_WR_DATA;
wire [35:0] DO;
assign PORT_R_RD_DATA = DO;
SDPX9B #(
`INIT(init_slice_x9)
.READ_MODE(1'b0),
.BIT_WIDTH_0(PORT_W_WIDTH),
.BIT_WIDTH_1(PORT_R_WIDTH),
.BLK_SEL_0(3'b000),
.BLK_SEL_1(3'b000),
.RESET_MODE(OPTION_RESET_MODE),
) _TECHMAP_REPLACE_ (
.BLKSELA(3'b000),
.BLKSELB(3'b000),
.CLKA(PORT_W_CLK),
.CEA(WRE),
.ADA(ADW),
.DI(DI),
.CLKB(PORT_R_CLK),
.CEB(PORT_R_CLK_EN),
.RESET(RST),
.OCE(1'b1),
.ADB(PORT_R_ADDR),
.DO(DO),
);
end
endgenerate
endmodule

View file

@ -57,6 +57,9 @@ struct SynthGowinPass : public ScriptPass
log(" -nodffe\n");
log(" do not use flipflops with CE in output netlist\n");
log("\n");
log(" -strict-gw5a-dffs\n");
log(" use only DFFSE/DFFRE/DFFPE/DFFCE flipflops for the GW5A family\n");
log("\n");
log(" -nobram\n");
log(" do not use BRAM cells in output netlist\n");
log("\n");
@ -91,13 +94,16 @@ struct SynthGowinPass : public ScriptPass
log(" The following families are supported:\n");
log(" 'gw1n', 'gw2a', 'gw5a'.\n");
log("\n");
log(" -setundef\n");
log(" set undriven wires and parameters to zero\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
log("\n");
}
string top_opt, vout_file, json_file, family;
bool retime, nobram, nolutram, flatten, nodffe, nowidelut, abc9, noiopads, noalu, no_rw_check;
bool retime, nobram, nolutram, flatten, nodffe, strict_gw5a_dffs, nowidelut, abc9, noiopads, noalu, no_rw_check, setundef;
void clear_flags() override
{
@ -109,12 +115,14 @@ struct SynthGowinPass : public ScriptPass
flatten = true;
nobram = false;
nodffe = false;
strict_gw5a_dffs = false;
nolutram = false;
nowidelut = false;
abc9 = true;
noiopads = false;
noalu = false;
no_rw_check = false;
setundef = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
@ -165,6 +173,10 @@ struct SynthGowinPass : public ScriptPass
nodffe = true;
continue;
}
if (args[argidx] == "-strict-gw5a-dffs") {
strict_gw5a_dffs = true;
continue;
}
if (args[argidx] == "-noflatten") {
flatten = false;
continue;
@ -193,6 +205,10 @@ struct SynthGowinPass : public ScriptPass
no_rw_check = true;
continue;
}
if (args[argidx] == "-setundef") {
setundef = true;
continue;
}
break;
}
extra_args(args, argidx, design);
@ -248,7 +264,7 @@ struct SynthGowinPass : public ScriptPass
args += " -no-auto-distributed";
}
run("memory_libmap -lib +/gowin/lutrams.txt -lib +/gowin/brams.txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)");
run("techmap -map +/gowin/lutrams_map.v -map +/gowin/brams_map.v");
run(stringf("techmap -map +/gowin/lutrams_map.v -map +/gowin/brams_map%s.v", family == "gw5a" ? "_gw5a" : ""));
}
if (check_label("map_ffram"))
@ -276,10 +292,18 @@ struct SynthGowinPass : public ScriptPass
if (check_label("map_ffs"))
{
run("opt_clean");
if (nodffe)
run("dfflegalize -cell $_DFF_?_ 0 -cell $_SDFF_?P?_ r -cell $_DFF_?P?_ r");
else
run("dfflegalize -cell $_DFF_?_ 0 -cell $_DFFE_?P_ 0 -cell $_SDFF_?P?_ r -cell $_SDFFE_?P?P_ r -cell $_DFF_?P?_ r -cell $_DFFE_?P?P_ r");
if (family == "gw5a") {
if (strict_gw5a_dffs) {
run("dfflegalize -cell $_SDFFE_PP?P_ r -cell $_DFFE_PP?P_ r");
} else {
run("dfflegalize -cell $_DFF_?_ 0 -cell $_SDFFE_PP?P_ r -cell $_DFFE_PP?P_ r");
}
} else {
if (nodffe)
run("dfflegalize -cell $_DFF_?_ 0 -cell $_SDFF_?P?_ r -cell $_DFF_?P?_ r");
else
run("dfflegalize -cell $_DFF_?_ 0 -cell $_DFFE_?P_ 0 -cell $_SDFF_?P?_ r -cell $_SDFFE_?P?P_ r -cell $_DFF_?P?_ r -cell $_DFFE_?P?P_ r");
}
run("techmap -map +/gowin/cells_map.v");
run("opt_expr -mux_undef");
run("simplemap");
@ -305,10 +329,11 @@ struct SynthGowinPass : public ScriptPass
{
run("techmap -map +/gowin/cells_map.v");
run("opt_lut_ins -tech gowin");
run("setundef -undriven -params -zero");
if (setundef || help_mode)
run("setundef -undriven -params -zero", "(only if -setundef)");
run("hilomap -singleton -hicell VCC V -locell GND G");
if (!vout_file.empty() || help_mode) // vendor output requires 1-bit wires
run("splitnets -ports", "(only if -vout used)");
run("splitnets -ports", "(only if -vout)");
run("clean");
run("autoname");
}

View file

@ -1,5 +1,5 @@
libcache -verbose
libcache -enable busdef.lib
libcache -enable bus*f.lib
logger -expect log "Caching is disabled by default." 1
logger -expect log "Caching is enabled for `busdef.lib'." 1

12
tests/rtlil/bug5424.ys Normal file
View file

@ -0,0 +1,12 @@
read_rtlil <<EOT
module \meow
wire width 8 \nya
wire width 8 output 1 \mrrp
wire width 1 input 0 \purr
process $cat
assign \nya { \mrrp \purr } [7:0]
end
end
EOT
select -assert-count 1 meow/$cat

View file

@ -1,4 +1,4 @@
#!/usr/bin/env bash
set -eu
source ../gen-tests-makefile.sh
generate_mk --bash
generate_mk --bash --yosys-scripts

View file

@ -2,7 +2,7 @@ read_verilog dff.v
prep
# create fst with 20 clock cycles (41 samples, 202ns)
sim -clock clk -fst sim_cycles.fst -n 20
sim -clock clk -fst sim_cycles.fst -width 2 -n 20
logger -expect-no-warnings
@ -10,7 +10,7 @@ logger -expect-no-warnings
logger -expect log "Co-simulating cycle 41" 2
logger -warn "Co-simulating cycle 42"
sim -clock clk -r sim_cycles.fst -scope dff -n 21 -sim-cmp
sim -clock clk -r sim_cycles.fst -scope dff -stop 202 -sim-cmp
sim -clock clk -r sim_cycles.fst -scope dff -stop 41 -sim-cmp
logger -check-expected
# over limit stops at final step
@ -18,29 +18,29 @@ logger -expect log "Co-simulating cycle 41" 2
sim -clock clk -r sim_cycles.fst -scope dff -n 30 -sim-cmp
# -stop warns for over limit
logger -nowarn "Stop time is after simulation file end time"
sim -clock clk -r sim_cycles.fst -scope dff -stop 300 -sim-cmp
sim -clock clk -r sim_cycles.fst -scope dff -stop 50 -sim-cmp
logger -check-expected
# don't auto step last
logger -expect log "Co-simulating cycle 40" 2
logger -warn "Co-simulating cycle 41"
sim -clock clk -r sim_cycles.fst -scope dff -n 20 -sim-cmp
sim -clock clk -r sim_cycles.fst -scope dff -stop 200 -sim-cmp
sim -clock clk -r sim_cycles.fst -scope dff -stop 40 -sim-cmp
logger -check-expected
# -n 10 == -stop 100
# -n 10 == -stop 20
# should simulate up to 20 and not more
logger -expect log "Co-simulating cycle 20" 2
logger -warn "Co-simulating cycle 21"
sim -clock clk -r sim_cycles.fst -scope dff -n 10 -sim-cmp
sim -clock clk -r sim_cycles.fst -scope dff -stop 100 -sim-cmp
sim -clock clk -r sim_cycles.fst -scope dff -stop 20 -sim-cmp
logger -check-expected
# -n 1 == -stop 10
# -n 1 == -stop 2
logger -expect log "Co-simulating cycle 2" 2
logger -warn "Co-simulating cycle 3"
sim -clock clk -r sim_cycles.fst -scope dff -n 1 -sim-cmp
sim -clock clk -r sim_cycles.fst -scope dff -stop 10 -sim-cmp
sim -clock clk -r sim_cycles.fst -scope dff -stop 2 -sim-cmp
logger -check-expected
# -n 0 == -stop 0

View file

@ -194,7 +194,7 @@ select -assert-count 1 t:\\pdk_icg
#------------------------------------------------------------------------------
design -load before
clockgate -liberty clockgate.lib
clockgate -liberty c*ckgate.lib
# rising edge ICGs
select -module dffe_00 -assert-count 0 t:\\pos_small

View file

@ -23,7 +23,7 @@ read_liberty -lib dfflibmap.lib
equiv_opt -map dfflibmap-sim.v -assert -multiclock dfflibmap -liberty dfflibmap.lib
equiv_opt -map dfflibmap-sim.v -assert -multiclock dfflibmap -prepare -liberty dfflibmap.lib
dfflibmap -prepare -liberty dfflibmap.lib
dfflibmap -prepare -liberty dffl*bmap.lib
equiv_opt -map dfflibmap-sim.v -assert -multiclock dfflibmap -map-only -liberty dfflibmap.lib
design -load orig

View file

@ -31,3 +31,19 @@ opt
techmap -map %techmap
select -assert-count 1 t:LCU_8
design -reset
read_verilog <<EOT
module top(input A, input B, output Y);
assign Y = A ^ B;
endmodule
EOT
# We can only test that the option doesn't crash
# See https://github.com/YosysHQ/yosys/issues/5414
# select -assert-count 1 t:$xor
# select -assert-count 0 t:\$xor
chtype -publish_icells
# select -assert-count 0 t:$xor
# select -assert-count 1 t:\$xor

View file

@ -2,6 +2,7 @@
/write_gzip.v
/write_gzip.v.gz
/plugin.so
/plugin_search
/plugin.so.dSYM
/temp
/smtlib2_module.smt2

View file

@ -34,6 +34,7 @@ module top;
endmodule
EOF
design -save before
box_derive -naming_attr final_name top
select -assert-mod-count 1 =aa1
@ -48,6 +49,45 @@ select -assert-mod-count 1 =cc1
select -assert-mod-count 0 =cc2
select -assert-mod-count 0 =cc3
# no instances of the new derived modules
# you could use wildcards like t:aa* here - if that wasn't just broken
select -assert-count 0 t:aa1 t:aa2 t:aa3
select -assert-count 0 t:bb1 t:bb2 t:bb3
select -assert-count 0 t:cc1 t:cc2 t:cc3
design -load before
# same command but with -apply_derived_type
box_derive -apply_derived_type -naming_attr final_name top
# same derived modules created as without -apply_derived_type
select -assert-mod-count 1 =aa1
select -assert-mod-count 1 =aa2
select -assert-mod-count 0 =aa3
select -assert-mod-count 1 =bb1
select -assert-mod-count 0 =bb2
select -assert-mod-count 1 =bb3
select -assert-mod-count 1 =cc1
select -assert-mod-count 0 =cc2
select -assert-mod-count 0 =cc3
# but we have instances of the new derived modules
select -assert-count 1 t:aa1
select -assert-count 1 t:aa2
select -assert-count 0 t:aa3
select -assert-count 1 t:bb1
select -assert-count 0 t:bb2
select -assert-count 1 t:bb3
select -assert-count 2 t:cc1
select -assert-count 0 t:cc2
select -assert-count 0 t:cc3
# we are expecting the original aa, bb, cc modules
# and 5 specializations generated by box_derive
select -assert-mod-count 8 =A:whitebox

View file

@ -1,8 +1,12 @@
set -e
rm -f plugin.so
rm -rf plugin_search
CXXFLAGS=$(../../yosys-config --cxxflags)
DATDIR=$(../../yosys-config --datdir)
DATDIR=${DATDIR//\//\\\/}
CXXFLAGS=${CXXFLAGS//$DATDIR/..\/..\/share}
../../yosys-config --exec --cxx ${CXXFLAGS} --ldflags -shared -o plugin.so plugin.cc
../../yosys -m ./plugin.so -p "test" | grep -q "Plugin test passed!"
mkdir -p plugin_search
mv plugin.so plugin_search/plugin.so
YOSYS_PLUGIN_PATH=$PWD/plugin_search ../../yosys -m plugin.so -p "test" | grep -q "Plugin test passed!"

View file

@ -0,0 +1,13 @@
module sub_rom (input clk, input [3:0] addr, output reg [7:0] data);
reg [7:0] mem [0:15];
always @(posedge clk)
data <= mem[addr];
endmodule
module top (input clk, input [3:0] addr, output [7:0] data, input [3:0] f_addr, input [7:0] f_data);
sub_rom u_sub_rom (clk, addr, data);
always @(posedge clk)
assume(u_sub_rom.mem[f_addr] == f_data);
endmodule

View file

@ -0,0 +1,5 @@
logger -expect error "ext_ramnet_err.sv:[0-9]+\.[0-9]+-[0-9]+\.[0-9]+: Memory net '[^']+' missing, possibly no driver, use verific -flatten." 1
verific -sv ext_ramnet_err.sv
verific -import top
logger -check-expected
design -reset

View file

@ -0,0 +1,15 @@
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity top is
Port (
a : in STD_LOGIC_VECTOR(3 downto 0);
b : in STD_LOGIC_VECTOR(3 downto 0);
y : out STD_LOGIC_VECTOR(3 downto 0)
);
end top;
architecture Behavioral of top is
begin
y <= a nor b;
end Behavioral;

View file

@ -0,0 +1,5 @@
logger -expect warning "import_warning_operator.vhd:[0-9]+.[0-9]+-[0-9]+.[0-9]+: Unsupported Verific operator: nor_4 \(fallback to gate level implementation provided by verific\)" 1
verific -vhdl import_warning_operator.vhd
verific -import top
logger -check-expected
design -reset