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:
commit
a961373c0d
35 changed files with 792 additions and 122 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -5,6 +5,7 @@
|
|||
/Brewfile.lock.json
|
||||
|
||||
## build artifacts
|
||||
/.git-abc-submodule-hash
|
||||
# compiler intermediate files
|
||||
*.o
|
||||
*.d
|
||||
|
|
|
|||
18
Makefile
18
Makefile
|
|
@ -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
2
abc
|
|
@ -1 +1 @@
|
|||
Subproject commit 8827bafb7f288de6749dc6e30fa452f2040949c0
|
||||
Subproject commit fa186342baefea06e7c2aa13fe51f338ffc84912
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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('[')) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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 = ©[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
26
passes/cmds/sort.cc
Normal 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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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") {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
399
techlibs/gowin/brams_map_gw5a.v
Normal file
399
techlibs/gowin/brams_map_gw5a.v
Normal 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
|
||||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
12
tests/rtlil/bug5424.ys
Normal 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
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
set -eu
|
||||
source ../gen-tests-makefile.sh
|
||||
generate_mk --bash
|
||||
generate_mk --bash --yosys-scripts
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
1
tests/various/.gitignore
vendored
1
tests/various/.gitignore
vendored
|
|
@ -2,6 +2,7 @@
|
|||
/write_gzip.v
|
||||
/write_gzip.v.gz
|
||||
/plugin.so
|
||||
/plugin_search
|
||||
/plugin.so.dSYM
|
||||
/temp
|
||||
/smtlib2_module.smt2
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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!"
|
||||
|
|
|
|||
13
tests/verific/ext_ramnet_err.sv
Normal file
13
tests/verific/ext_ramnet_err.sv
Normal 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
|
||||
5
tests/verific/ext_ramnet_err.ys
Normal file
5
tests/verific/ext_ramnet_err.ys
Normal 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
|
||||
15
tests/verific/import_warning_operator.vhd
Normal file
15
tests/verific/import_warning_operator.vhd
Normal 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;
|
||||
5
tests/verific/import_warning_operator.ys
Normal file
5
tests/verific/import_warning_operator.ys
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue