mirror of
https://github.com/YosysHQ/yosys
synced 2025-09-12 12:41:28 +00:00
Merge 9de931b902
into 012ddc2f1e
This commit is contained in:
commit
023f867044
21 changed files with 1730 additions and 107 deletions
1
Makefile
1
Makefile
|
@ -874,6 +874,7 @@ MK_TEST_DIRS += tests/sim
|
|||
MK_TEST_DIRS += tests/svtypes
|
||||
MK_TEST_DIRS += tests/techmap
|
||||
MK_TEST_DIRS += tests/various
|
||||
MK_TEST_DIRS += tests/rtlil
|
||||
ifeq ($(ENABLE_VERIFIC),1)
|
||||
ifneq ($(YOSYS_NOVERIFIC),1)
|
||||
MK_TEST_DIRS += tests/verific
|
||||
|
|
|
@ -24,12 +24,23 @@
|
|||
|
||||
#include "rtlil_backend.h"
|
||||
#include "kernel/yosys.h"
|
||||
#include "kernel/utils.h"
|
||||
#include <errno.h>
|
||||
#include <iterator>
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
using namespace RTLIL_BACKEND;
|
||||
YOSYS_NAMESPACE_BEGIN
|
||||
|
||||
void RTLIL_BACKEND::dump_attributes(std::ostream &f, std::string indent, const RTLIL::AttrObject *obj)
|
||||
{
|
||||
for (const auto& [name, value] : reversed(obj->attributes)) {
|
||||
f << stringf("%s" "attribute %s ", indent.c_str(), name.c_str());
|
||||
dump_const(f, value);
|
||||
f << stringf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void RTLIL_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int width, int offset, bool autoint)
|
||||
{
|
||||
if (width < 0)
|
||||
|
@ -110,8 +121,8 @@ void RTLIL_BACKEND::dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, boo
|
|||
dump_sigchunk(f, sig.as_chunk(), autoint);
|
||||
} else {
|
||||
f << stringf("{ ");
|
||||
for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); ++it) {
|
||||
dump_sigchunk(f, *it, false);
|
||||
for (const auto& chunk : reversed(sig.chunks())) {
|
||||
dump_sigchunk(f, chunk, false);
|
||||
f << stringf(" ");
|
||||
}
|
||||
f << stringf("}");
|
||||
|
@ -120,11 +131,7 @@ void RTLIL_BACKEND::dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, boo
|
|||
|
||||
void RTLIL_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire)
|
||||
{
|
||||
for (auto &it : wire->attributes) {
|
||||
f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str());
|
||||
dump_const(f, it.second);
|
||||
f << stringf("\n");
|
||||
}
|
||||
dump_attributes(f, indent, wire);
|
||||
if (wire->driverCell_) {
|
||||
f << stringf("%s" "# driver %s %s\n", indent.c_str(),
|
||||
wire->driverCell()->name.c_str(), wire->driverPort().c_str());
|
||||
|
@ -149,11 +156,7 @@ void RTLIL_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::
|
|||
|
||||
void RTLIL_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL::Memory *memory)
|
||||
{
|
||||
for (auto &it : memory->attributes) {
|
||||
f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str());
|
||||
dump_const(f, it.second);
|
||||
f << stringf("\n");
|
||||
}
|
||||
dump_attributes(f, indent, memory);
|
||||
f << stringf("%s" "memory ", indent.c_str());
|
||||
if (memory->width != 1)
|
||||
f << stringf("width %d ", memory->width);
|
||||
|
@ -166,23 +169,19 @@ void RTLIL_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL
|
|||
|
||||
void RTLIL_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL::Cell *cell)
|
||||
{
|
||||
for (auto &it : cell->attributes) {
|
||||
f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str());
|
||||
dump_const(f, it.second);
|
||||
f << stringf("\n");
|
||||
}
|
||||
dump_attributes(f, indent, cell);
|
||||
f << stringf("%s" "cell %s %s\n", indent.c_str(), cell->type.c_str(), cell->name.c_str());
|
||||
for (auto &it : cell->parameters) {
|
||||
for (const auto& [name, param] : reversed(cell->parameters)) {
|
||||
f << stringf("%s parameter%s%s %s ", indent.c_str(),
|
||||
(it.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "",
|
||||
(it.second.flags & RTLIL::CONST_FLAG_REAL) != 0 ? " real" : "",
|
||||
it.first.c_str());
|
||||
dump_const(f, it.second);
|
||||
(param.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "",
|
||||
(param.flags & RTLIL::CONST_FLAG_REAL) != 0 ? " real" : "",
|
||||
name.c_str());
|
||||
dump_const(f, param);
|
||||
f << stringf("\n");
|
||||
}
|
||||
for (auto &it : cell->connections()) {
|
||||
f << stringf("%s connect %s ", indent.c_str(), it.first.c_str());
|
||||
dump_sigspec(f, it.second);
|
||||
for (const auto& [port, sig] : reversed(cell->connections_)) {
|
||||
f << stringf("%s connect %s ", indent.c_str(), port.c_str());
|
||||
dump_sigspec(f, sig);
|
||||
f << stringf("\n");
|
||||
}
|
||||
f << stringf("%s" "end\n", indent.c_str());
|
||||
|
@ -190,47 +189,38 @@ void RTLIL_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL::
|
|||
|
||||
void RTLIL_BACKEND::dump_proc_case_body(std::ostream &f, std::string indent, const RTLIL::CaseRule *cs)
|
||||
{
|
||||
for (auto it = cs->actions.begin(); it != cs->actions.end(); ++it)
|
||||
{
|
||||
for (const auto& [lhs, rhs] : cs->actions) {
|
||||
f << stringf("%s" "assign ", indent.c_str());
|
||||
dump_sigspec(f, it->first);
|
||||
dump_sigspec(f, lhs);
|
||||
f << stringf(" ");
|
||||
dump_sigspec(f, it->second);
|
||||
dump_sigspec(f, rhs);
|
||||
f << stringf("\n");
|
||||
}
|
||||
|
||||
for (auto it = cs->switches.begin(); it != cs->switches.end(); ++it)
|
||||
dump_proc_switch(f, indent, *it);
|
||||
for (const auto& sw : cs->switches)
|
||||
dump_proc_switch(f, indent, sw);
|
||||
}
|
||||
|
||||
void RTLIL_BACKEND::dump_proc_switch(std::ostream &f, std::string indent, const RTLIL::SwitchRule *sw)
|
||||
{
|
||||
for (auto it = sw->attributes.begin(); it != sw->attributes.end(); ++it) {
|
||||
f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
|
||||
dump_const(f, it->second);
|
||||
f << stringf("\n");
|
||||
}
|
||||
dump_attributes(f, indent, sw);
|
||||
|
||||
f << stringf("%s" "switch ", indent.c_str());
|
||||
dump_sigspec(f, sw->signal);
|
||||
f << stringf("\n");
|
||||
|
||||
for (auto it = sw->cases.begin(); it != sw->cases.end(); ++it)
|
||||
for (const auto case_ : sw->cases)
|
||||
{
|
||||
for (auto ait = (*it)->attributes.begin(); ait != (*it)->attributes.end(); ++ait) {
|
||||
f << stringf("%s attribute %s ", indent.c_str(), ait->first.c_str());
|
||||
dump_const(f, ait->second);
|
||||
f << stringf("\n");
|
||||
}
|
||||
dump_attributes(f, indent, case_);
|
||||
f << stringf("%s case ", indent.c_str());
|
||||
for (size_t i = 0; i < (*it)->compare.size(); i++) {
|
||||
for (size_t i = 0; i < case_->compare.size(); i++) {
|
||||
if (i > 0)
|
||||
f << stringf(" , ");
|
||||
dump_sigspec(f, (*it)->compare[i]);
|
||||
dump_sigspec(f, case_->compare[i]);
|
||||
}
|
||||
f << stringf("\n");
|
||||
|
||||
dump_proc_case_body(f, indent + " ", *it);
|
||||
dump_proc_case_body(f, indent + " ", case_);
|
||||
}
|
||||
|
||||
f << stringf("%s" "end\n", indent.c_str());
|
||||
|
@ -253,20 +243,16 @@ void RTLIL_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RT
|
|||
case RTLIL::STi: f << stringf("init\n"); break;
|
||||
}
|
||||
|
||||
for (auto &it: sy->actions) {
|
||||
for (const auto& [lhs, rhs] : sy->actions) {
|
||||
f << stringf("%s update ", indent.c_str());
|
||||
dump_sigspec(f, it.first);
|
||||
dump_sigspec(f, lhs);
|
||||
f << stringf(" ");
|
||||
dump_sigspec(f, it.second);
|
||||
dump_sigspec(f, rhs);
|
||||
f << stringf("\n");
|
||||
}
|
||||
|
||||
for (auto &it: sy->mem_write_actions) {
|
||||
for (auto it2 = it.attributes.begin(); it2 != it.attributes.end(); ++it2) {
|
||||
f << stringf("%s attribute %s ", indent.c_str(), it2->first.c_str());
|
||||
dump_const(f, it2->second);
|
||||
f << stringf("\n");
|
||||
}
|
||||
dump_attributes(f, indent, &it);
|
||||
f << stringf("%s memwr %s ", indent.c_str(), it.memid.c_str());
|
||||
dump_sigspec(f, it.address);
|
||||
f << stringf(" ");
|
||||
|
@ -281,15 +267,11 @@ void RTLIL_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RT
|
|||
|
||||
void RTLIL_BACKEND::dump_proc(std::ostream &f, std::string indent, const RTLIL::Process *proc)
|
||||
{
|
||||
for (auto it = proc->attributes.begin(); it != proc->attributes.end(); ++it) {
|
||||
f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
|
||||
dump_const(f, it->second);
|
||||
f << stringf("\n");
|
||||
}
|
||||
dump_attributes(f, indent, proc);
|
||||
f << stringf("%s" "process %s\n", indent.c_str(), proc->name.c_str());
|
||||
dump_proc_case_body(f, indent + " ", &proc->root_case);
|
||||
for (auto it = proc->syncs.begin(); it != proc->syncs.end(); ++it)
|
||||
dump_proc_sync(f, indent + " ", *it);
|
||||
for (auto* sync : proc->syncs)
|
||||
dump_proc_sync(f, indent + " ", sync);
|
||||
f << stringf("%s" "end\n", indent.c_str());
|
||||
}
|
||||
|
||||
|
@ -309,11 +291,7 @@ void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu
|
|||
|
||||
if (print_header)
|
||||
{
|
||||
for (auto it = module->attributes.begin(); it != module->attributes.end(); ++it) {
|
||||
f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
|
||||
dump_const(f, it->second);
|
||||
f << stringf("\n");
|
||||
}
|
||||
dump_attributes(f, indent, module);
|
||||
|
||||
f << stringf("%s" "module %s\n", indent.c_str(), module->name.c_str());
|
||||
|
||||
|
@ -335,40 +313,40 @@ void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu
|
|||
|
||||
if (print_body)
|
||||
{
|
||||
for (auto it : module->wires())
|
||||
if (!only_selected || design->selected(module, it)) {
|
||||
for (const auto& [_, wire] : reversed(module->wires_))
|
||||
if (!only_selected || design->selected(module, wire)) {
|
||||
if (only_selected)
|
||||
f << stringf("\n");
|
||||
dump_wire(f, indent + " ", it);
|
||||
dump_wire(f, indent + " ", wire);
|
||||
}
|
||||
|
||||
for (auto it : module->memories)
|
||||
if (!only_selected || design->selected(module, it.second)) {
|
||||
for (const auto& [_, mem] : reversed(module->memories))
|
||||
if (!only_selected || design->selected(module, mem)) {
|
||||
if (only_selected)
|
||||
f << stringf("\n");
|
||||
dump_memory(f, indent + " ", it.second);
|
||||
dump_memory(f, indent + " ", mem);
|
||||
}
|
||||
|
||||
for (auto it : module->cells())
|
||||
if (!only_selected || design->selected(module, it)) {
|
||||
for (const auto& [_, cell] : reversed(module->cells_))
|
||||
if (!only_selected || design->selected(module, cell)) {
|
||||
if (only_selected)
|
||||
f << stringf("\n");
|
||||
dump_cell(f, indent + " ", it);
|
||||
dump_cell(f, indent + " ", cell);
|
||||
}
|
||||
|
||||
for (auto it : module->processes)
|
||||
if (!only_selected || design->selected(module, it.second)) {
|
||||
for (const auto& [_, process] : reversed(module->processes))
|
||||
if (!only_selected || design->selected(module, process)) {
|
||||
if (only_selected)
|
||||
f << stringf("\n");
|
||||
dump_proc(f, indent + " ", it.second);
|
||||
dump_proc(f, indent + " ", process);
|
||||
}
|
||||
|
||||
bool first_conn_line = true;
|
||||
for (auto it = module->connections().begin(); it != module->connections().end(); ++it) {
|
||||
for (const auto& [lhs, rhs] : module->connections()) {
|
||||
bool show_conn = !only_selected || design->selected_whole_module(module->name);
|
||||
if (!show_conn) {
|
||||
RTLIL::SigSpec sigs = it->first;
|
||||
sigs.append(it->second);
|
||||
RTLIL::SigSpec sigs = lhs;
|
||||
sigs.append(rhs);
|
||||
for (auto &c : sigs.chunks()) {
|
||||
if (c.wire == NULL || !design->selected(module, c.wire))
|
||||
continue;
|
||||
|
@ -378,7 +356,7 @@ void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Modu
|
|||
if (show_conn) {
|
||||
if (only_selected && first_conn_line)
|
||||
f << stringf("\n");
|
||||
dump_conn(f, indent + " ", it->first, it->second);
|
||||
dump_conn(f, indent + " ", lhs, rhs);
|
||||
first_conn_line = false;
|
||||
}
|
||||
}
|
||||
|
@ -394,7 +372,7 @@ void RTLIL_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool onl
|
|||
|
||||
if (!flag_m) {
|
||||
int count_selected_mods = 0;
|
||||
for (auto module : design->modules()) {
|
||||
for (auto* module : design->modules()) {
|
||||
if (design->selected_whole_module(module->name))
|
||||
flag_m = true;
|
||||
if (design->selected(module))
|
||||
|
@ -410,7 +388,7 @@ void RTLIL_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool onl
|
|||
f << stringf("autoidx %d\n", autoidx);
|
||||
}
|
||||
|
||||
for (auto module : design->modules()) {
|
||||
for (const auto& [_, module] : reversed(design->modules_)) {
|
||||
if (!only_selected || design->selected(module)) {
|
||||
if (only_selected)
|
||||
f << stringf("\n");
|
||||
|
@ -438,10 +416,14 @@ struct RTLILBackend : public Backend {
|
|||
log(" -selected\n");
|
||||
log(" only write selected parts of the design.\n");
|
||||
log("\n");
|
||||
log(" -sort\n");
|
||||
log(" sort design in-place (used to be default).\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
bool selected = false;
|
||||
bool do_sort = false;
|
||||
|
||||
log_header(design, "Executing RTLIL backend.\n");
|
||||
|
||||
|
@ -452,14 +434,19 @@ struct RTLILBackend : public Backend {
|
|||
selected = true;
|
||||
continue;
|
||||
}
|
||||
if (arg == "-sort") {
|
||||
do_sort = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(f, filename, args, argidx);
|
||||
|
||||
design->sort();
|
||||
|
||||
log("Output filename: %s\n", filename.c_str());
|
||||
|
||||
if (do_sort)
|
||||
design->sort();
|
||||
|
||||
*f << stringf("# Generated by %s\n", yosys_maybe_version());
|
||||
RTLIL_BACKEND::dump_design(*f, design, selected, true, false);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
YOSYS_NAMESPACE_BEGIN
|
||||
|
||||
namespace RTLIL_BACKEND {
|
||||
void dump_attributes(std::ostream &f, std::string indent, const RTLIL::AttrObject *obj);
|
||||
void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int offset = 0, bool autoint = true);
|
||||
void dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, bool autoint = true);
|
||||
void dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, bool autoint = true);
|
||||
|
|
|
@ -229,6 +229,10 @@ struct VerilogFrontend : public Frontend {
|
|||
log(" add 'dir' to the directories which are used when searching include\n");
|
||||
log(" files\n");
|
||||
log("\n");
|
||||
log(" -relativeshare\n");
|
||||
log(" use paths relative to share directory for source locations\n");
|
||||
log(" where possible (experimental).\n");
|
||||
log("\n");
|
||||
log("The command 'verilog_defaults' can be used to register default options for\n");
|
||||
log("subsequent calls to 'read_verilog'.\n");
|
||||
log("\n");
|
||||
|
@ -273,6 +277,7 @@ struct VerilogFrontend : public Frontend {
|
|||
bool flag_nowb = false;
|
||||
bool flag_nosynthesis = false;
|
||||
bool flag_yydebug = false;
|
||||
bool flag_relative_share = false;
|
||||
define_map_t defines_map;
|
||||
|
||||
std::list<std::string> include_dirs;
|
||||
|
@ -450,6 +455,11 @@ struct VerilogFrontend : public Frontend {
|
|||
attributes.push_back(RTLIL::escape_id(args[++argidx]));
|
||||
continue;
|
||||
}
|
||||
if (arg == "-relativeshare") {
|
||||
flag_relative_share = true;
|
||||
log_experimental("read_verilog -relativeshare");
|
||||
continue;
|
||||
}
|
||||
if (arg == "-D" && argidx+1 < args.size()) {
|
||||
std::string name = args[++argidx], value;
|
||||
size_t equal = name.find('=');
|
||||
|
@ -490,6 +500,13 @@ struct VerilogFrontend : public Frontend {
|
|||
log("Parsing %s%s input from `%s' to AST representation.\n",
|
||||
parse_mode.formal ? "formal " : "", parse_mode.sv ? "SystemVerilog" : "Verilog", filename.c_str());
|
||||
|
||||
log("verilog frontend filename %s\n", filename.c_str());
|
||||
if (flag_relative_share) {
|
||||
auto share_path = proc_share_dirname();
|
||||
if (filename.substr(0, share_path.length()) == share_path)
|
||||
filename = std::string("+/") + filename.substr(share_path.length());
|
||||
log("new filename %s\n", filename.c_str());
|
||||
}
|
||||
AST::sv_mode_but_global_and_used_for_literally_one_condition = parse_mode.sv;
|
||||
std::string code_after_preproc;
|
||||
|
||||
|
|
|
@ -558,13 +558,16 @@ public:
|
|||
int index;
|
||||
const_iterator(const dict *ptr, int index) : ptr(ptr), index(index) { }
|
||||
public:
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef std::pair<K, T> value_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef std::pair<K, T>* pointer;
|
||||
typedef std::pair<K, T>& reference;
|
||||
typedef const std::pair<K, T>* pointer;
|
||||
typedef const std::pair<K, T>& reference;
|
||||
const_iterator() { }
|
||||
const_iterator operator++() { index--; return *this; }
|
||||
const_iterator operator++(int) { const_iterator tmp = *this; index--; return tmp; }
|
||||
const_iterator operator--() { index++; return *this; }
|
||||
const_iterator operator--(int) { const_iterator tmp = *this; index++; return tmp; }
|
||||
const_iterator operator+=(int amt) { index -= amt; return *this; }
|
||||
bool operator<(const const_iterator &other) const { return index > other.index; }
|
||||
bool operator==(const const_iterator &other) const { return index == other.index; }
|
||||
|
@ -598,6 +601,13 @@ public:
|
|||
const std::pair<K, T> *operator->() const { return &ptr->entries[index].udata; }
|
||||
operator const_iterator() const { return const_iterator(ptr, index); }
|
||||
};
|
||||
using reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
reverse_iterator rbegin() const {
|
||||
return std::make_reverse_iterator(end());
|
||||
}
|
||||
reverse_iterator rend() const {
|
||||
return std::make_reverse_iterator(begin());
|
||||
}
|
||||
|
||||
constexpr dict()
|
||||
{
|
||||
|
@ -847,7 +857,7 @@ public:
|
|||
|
||||
const_iterator begin() const { return const_iterator(this, int(entries.size())-1); }
|
||||
const_iterator element(int n) const { return const_iterator(this, int(entries.size())-1-n); }
|
||||
const_iterator end() const { return const_iterator(nullptr, -1); }
|
||||
const_iterator end() const { return const_iterator(this, -1); }
|
||||
};
|
||||
|
||||
template<typename K, typename OPS>
|
||||
|
|
|
@ -5855,6 +5855,7 @@ RTLIL::CaseRule *RTLIL::CaseRule::clone() const
|
|||
RTLIL::CaseRule *new_caserule = new RTLIL::CaseRule;
|
||||
new_caserule->compare = compare;
|
||||
new_caserule->actions = actions;
|
||||
new_caserule->attributes = attributes;
|
||||
for (auto &it : switches)
|
||||
new_caserule->switches.push_back(it->clone());
|
||||
return new_caserule;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
// do not depend on any other components of yosys (except stuff like log_*).
|
||||
|
||||
#include "kernel/yosys.h"
|
||||
#include <iterator>
|
||||
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
@ -276,6 +277,16 @@ inline int ceil_log2(int x)
|
|||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto reversed(const T& container) {
|
||||
struct reverse_view {
|
||||
const T& cont;
|
||||
auto begin() const { return cont.rbegin(); }
|
||||
auto end() const { return cont.rend(); }
|
||||
};
|
||||
return reverse_view{container};
|
||||
}
|
||||
|
||||
YOSYS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
|
@ -122,8 +122,6 @@ struct BugpointPass : public Pass {
|
|||
|
||||
int run_yosys(RTLIL::Design *design, string runner, string yosys_cmd, string yosys_arg, string suffix, bool catch_err)
|
||||
{
|
||||
design->sort();
|
||||
|
||||
string bugpoint_file = "bugpoint-case";
|
||||
if (suffix.size())
|
||||
bugpoint_file += stringf(".%.8s", suffix.c_str());
|
||||
|
|
|
@ -1031,6 +1031,10 @@ struct TechmapPass : public Pass {
|
|||
log(" -dont_map <celltype>\n");
|
||||
log(" leave the given cell type unmapped by ignoring any mapping rules for it\n");
|
||||
log("\n");
|
||||
log(" -relativeshare\n");
|
||||
log(" use paths relative to share directory for source locations\n");
|
||||
log(" where possible (experimental).\n");
|
||||
log("\n");
|
||||
log("When a module in the map file has the 'techmap_celltype' attribute set, it will\n");
|
||||
log("match cells with a type that match the text value of this attribute. Otherwise\n");
|
||||
log("the module name will be used to match the cell. Multiple space-separated cell\n");
|
||||
|
@ -1184,6 +1188,11 @@ struct TechmapPass : public Pass {
|
|||
verilog_frontend += " -I " + args[++argidx];
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-relativeshare") {
|
||||
verilog_frontend += " -relativeshare";
|
||||
log_experimental("techmap -relativeshare");
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-assert") {
|
||||
worker.assert_mode = true;
|
||||
continue;
|
||||
|
|
|
@ -98,13 +98,17 @@ struct SynthPass : public ScriptPass {
|
|||
log(" mapping library in the `techmap` step. this option can be\n");
|
||||
log(" repeated.\n");
|
||||
log("\n");
|
||||
log(" -relativeshare\n");
|
||||
log(" use paths relative to share directory for source locations\n");
|
||||
log(" where possible (experimental).\n");
|
||||
log("\n");
|
||||
log("The following commands are executed by this synthesis command:\n");
|
||||
help_script();
|
||||
log("\n");
|
||||
}
|
||||
|
||||
string top_module, fsm_opts, memory_opts, abc;
|
||||
bool autotop, flatten, noalumacc, nofsm, noabc, noshare, flowmap, booth, hieropt;
|
||||
bool autotop, flatten, noalumacc, nofsm, noabc, noshare, flowmap, booth, hieropt, relative_share;
|
||||
int lut;
|
||||
std::vector<std::string> techmap_maps;
|
||||
|
||||
|
@ -124,6 +128,7 @@ struct SynthPass : public ScriptPass {
|
|||
flowmap = false;
|
||||
booth = false;
|
||||
hieropt = false;
|
||||
relative_share = false;
|
||||
abc = "abc";
|
||||
techmap_maps.clear();
|
||||
}
|
||||
|
@ -211,6 +216,11 @@ struct SynthPass : public ScriptPass {
|
|||
hieropt = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-relativeshare") {
|
||||
relative_share = true;
|
||||
log_experimental("synth -relativeshare");
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
@ -239,6 +249,10 @@ struct SynthPass : public ScriptPass {
|
|||
else
|
||||
hieropt_flag = hieropt ? " -hier" : "";
|
||||
|
||||
std::string techmap_cmd = "techmap";
|
||||
if (relative_share)
|
||||
techmap_cmd += " -relativeshare";
|
||||
|
||||
if (check_label("begin")) {
|
||||
if (help_mode) {
|
||||
run("hierarchy -check [-top <top> | -auto-top]");
|
||||
|
@ -268,9 +282,9 @@ struct SynthPass : public ScriptPass {
|
|||
run("peepopt");
|
||||
run("opt_clean");
|
||||
if (help_mode)
|
||||
run("techmap -map +/cmp2lut.v -map +/cmp2lcu.v", " (if -lut)");
|
||||
run(techmap_cmd + " -map +/cmp2lut.v -map +/cmp2lcu.v", " (if -lut)");
|
||||
else if (lut)
|
||||
run(stringf("techmap -map +/cmp2lut.v -map +/cmp2lcu.v -D LUT_WIDTH=%d", lut));
|
||||
run(stringf("%s -map +/cmp2lut.v -map +/cmp2lcu.v -D LUT_WIDTH=%d", techmap_cmd, lut));
|
||||
if (booth || help_mode)
|
||||
run("booth", " (if -booth)");
|
||||
if (!noalumacc)
|
||||
|
@ -287,22 +301,22 @@ struct SynthPass : public ScriptPass {
|
|||
run("memory_map");
|
||||
run("opt -full");
|
||||
if (help_mode) {
|
||||
run("techmap", " (unless -extra-map)");
|
||||
run("techmap -map +/techmap.v -map <inject>", " (if -extra-map)");
|
||||
run(techmap_cmd, " (unless -extra-map)");
|
||||
run(techmap_cmd + " -map +/techmap.v -map <inject>", " (if -extra-map)");
|
||||
} else {
|
||||
std::string techmap_opts;
|
||||
if (!techmap_maps.empty())
|
||||
techmap_opts += " -map +/techmap.v";
|
||||
for (auto fn : techmap_maps)
|
||||
techmap_opts += stringf(" -map %s", fn.c_str());
|
||||
run("techmap" + techmap_opts);
|
||||
run(techmap_cmd + techmap_opts);
|
||||
}
|
||||
if (help_mode) {
|
||||
run("techmap -map +/gate2lut.v", "(if -noabc and -lut)");
|
||||
run(techmap_cmd + " -map +/gate2lut.v", "(if -noabc and -lut)");
|
||||
run("clean; opt_lut", " (if -noabc and -lut)");
|
||||
run("flowmap -maxlut K", " (if -flowmap and -lut)");
|
||||
} else if (noabc && lut) {
|
||||
run(stringf("techmap -map +/gate2lut.v -D LUT_WIDTH=%d", lut));
|
||||
run(stringf("%s -map +/gate2lut.v -D LUT_WIDTH=%d", techmap_cmd, lut));
|
||||
run("clean; opt_lut");
|
||||
} else if (flowmap) {
|
||||
run(stringf("flowmap -maxlut %d", lut));
|
||||
|
|
|
@ -69,7 +69,7 @@ struct SynthPass : public ScriptPass
|
|||
log(" use the specified Verilog file for extra primitives (can be specified multiple\n");
|
||||
log(" times).\n");
|
||||
log("\n");
|
||||
log(" -extra-map <techamp.v>\n");
|
||||
log(" -extra-map <techmap.v>\n");
|
||||
log(" use the specified Verilog file for extra techmap rules (can be specified multiple\n");
|
||||
log(" times).\n");
|
||||
log("\n");
|
||||
|
|
|
@ -22,34 +22,37 @@ logger -check-expected
|
|||
|
||||
# raise_error with int exits with status
|
||||
design -load read
|
||||
setattr -mod -unset raise_error def other
|
||||
dump
|
||||
bugpoint -suffix error -yosys ../../yosys -command raise_error -expect-return 7
|
||||
select -assert-mod-count 1 =*
|
||||
select -assert-mod-count 1 top
|
||||
|
||||
# raise_error -always still uses 'raise_error' attribute if possible
|
||||
design -load read
|
||||
setattr -mod -unset raise_error def other
|
||||
bugpoint -suffix error -yosys ../../yosys -command "raise_error -always" -expect-return 7
|
||||
select -assert-mod-count 1 =*
|
||||
select -assert-mod-count 1 top
|
||||
|
||||
# raise_error with string prints message and exits with 1
|
||||
design -load read
|
||||
rename top abc
|
||||
setattr -mod -unset raise_error top def
|
||||
bugpoint -suffix error -yosys ../../yosys -command raise_error -grep "help me" -expect-return 1
|
||||
select -assert-mod-count 1 =*
|
||||
select -assert-mod-count 1 other
|
||||
|
||||
# raise_error with no value exits with 1
|
||||
design -load read
|
||||
rename def zzy
|
||||
setattr -mod -unset raise_error top
|
||||
delete other
|
||||
bugpoint -suffix error -yosys ../../yosys -command raise_error -expect-return 1
|
||||
select -assert-mod-count 1 =*
|
||||
select -assert-mod-count 1 zzy
|
||||
select -assert-mod-count 1 def
|
||||
|
||||
# raise_error -stderr prints to stderr and exits with 1
|
||||
design -load read
|
||||
rename top abc
|
||||
setattr -mod -unset raise_error top def
|
||||
bugpoint -suffix error -yosys ../../yosys -command "raise_error -stderr" -err-grep "help me" -expect-return 1
|
||||
select -assert-mod-count 1 =*
|
||||
select -assert-mod-count 1 other
|
||||
|
|
|
@ -24,7 +24,7 @@ def compile_cpp(in_path, out_path, args):
|
|||
run(['g++', '-g', '-std=c++17'] + args + [str(in_path), '-o', str(out_path)])
|
||||
|
||||
def yosys_synth(verilog_file, rtlil_file):
|
||||
yosys(f"read_verilog {quote(verilog_file)} ; prep ; write_rtlil {quote(rtlil_file)}")
|
||||
yosys(f"read_verilog {quote(verilog_file)} ; prep ; setundef -undriven -undef ; write_rtlil {quote(rtlil_file)}")
|
||||
|
||||
# simulate an rtlil file with yosys, comparing with a given vcd file, and writing out the yosys simulation results into a second vcd file
|
||||
def yosys_sim(rtlil_file, vcd_reference_file, vcd_out_file, preprocessing = ""):
|
||||
|
@ -91,4 +91,4 @@ def test_print_graph(tmp_path):
|
|||
tb_file = base_path / 'tests/functional/picorv32_tb.v'
|
||||
cpu_file = base_path / 'tests/functional/picorv32.v'
|
||||
# currently we only check that we can print the graph without getting an error, not that it prints anything sensibl
|
||||
yosys(f"read_verilog {quote(tb_file)} {quote(cpu_file)}; prep -top gold; flatten; clk2fflogic; test_generic")
|
||||
yosys(f"read_verilog {quote(tb_file)} {quote(cpu_file)}; prep -top gold; setundef -undriven -undef ; flatten; clk2fflogic; test_generic")
|
||||
|
|
1
tests/rtlil/.gitignore
vendored
Normal file
1
tests/rtlil/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/temp
|
40
tests/rtlil/everything.v
Normal file
40
tests/rtlil/everything.v
Normal file
|
@ -0,0 +1,40 @@
|
|||
module alu(
|
||||
input clk,
|
||||
input [7:0] A,
|
||||
input [7:0] B,
|
||||
input [3:0] operation,
|
||||
output reg [7:0] result,
|
||||
output reg CF,
|
||||
output reg ZF,
|
||||
output reg SF
|
||||
);
|
||||
|
||||
localparam ALU_OP_ADD = 4'b0000;
|
||||
localparam ALU_OP_SUB = 4'b0001;
|
||||
|
||||
reg [8:0] tmp;
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
case (operation)
|
||||
ALU_OP_ADD :
|
||||
tmp = A + B;
|
||||
ALU_OP_SUB :
|
||||
tmp = A - B;
|
||||
endcase
|
||||
|
||||
CF <= tmp[8];
|
||||
ZF <= tmp[7:0] == 0;
|
||||
SF <= tmp[7];
|
||||
|
||||
result <= tmp[7:0];
|
||||
end
|
||||
endmodule
|
||||
|
||||
module foo(
|
||||
input [7:0] a, input [7:0] b, output [7:0] y
|
||||
);
|
||||
wire [7:0] bb;
|
||||
assign b = bb;
|
||||
assign y = a + bb;
|
||||
endmodule
|
10
tests/rtlil/roundtrip-design.sh
Normal file
10
tests/rtlil/roundtrip-design.sh
Normal file
|
@ -0,0 +1,10 @@
|
|||
set -euo pipefail
|
||||
YS=../../yosys
|
||||
|
||||
mkdir -p temp
|
||||
|
||||
$YS -p "read_verilog -sv everything.v; write_rtlil temp/roundtrip-design-push.il; design -push; design -pop; write_rtlil temp/roundtrip-design-pop.il"
|
||||
diff temp/roundtrip-design-push.il temp/roundtrip-design-pop.il
|
||||
|
||||
$YS -p "read_verilog -sv everything.v; write_rtlil temp/roundtrip-design-save.il; design -save foo; design -load foo; write_rtlil temp/roundtrip-design-load.il"
|
||||
diff temp/roundtrip-design-save.il temp/roundtrip-design-load.il
|
283
tests/rtlil/roundtrip-text.ref.il
Normal file
283
tests/rtlil/roundtrip-text.ref.il
Normal file
|
@ -0,0 +1,283 @@
|
|||
autoidx 15
|
||||
attribute \src "everything.v:1.1-32.10"
|
||||
attribute \cells_not_processed 1
|
||||
module \alu
|
||||
attribute \src "everything.v:2.8-2.11"
|
||||
wire input 1 \clk
|
||||
attribute \src "everything.v:3.14-3.15"
|
||||
wire width 8 input 2 \A
|
||||
attribute \src "everything.v:4.14-4.15"
|
||||
wire width 8 input 3 \B
|
||||
attribute \src "everything.v:5.14-5.23"
|
||||
wire width 4 input 4 \operation
|
||||
attribute \src "everything.v:6.19-6.25"
|
||||
wire width 8 output 5 \result
|
||||
attribute \src "everything.v:7.13-7.15"
|
||||
wire output 6 \CF
|
||||
attribute \src "everything.v:8.13-8.15"
|
||||
wire output 7 \ZF
|
||||
attribute \src "everything.v:9.13-9.15"
|
||||
wire output 8 \SF
|
||||
attribute \src "everything.v:15.12-15.15"
|
||||
wire width 9 \tmp
|
||||
attribute \src "everything.v:17.2-31.5"
|
||||
wire width 8 $0\result[7:0]
|
||||
attribute \src "everything.v:17.2-31.5"
|
||||
wire $0\CF[0:0]
|
||||
attribute \src "everything.v:17.2-31.5"
|
||||
wire $0\ZF[0:0]
|
||||
attribute \src "everything.v:17.2-31.5"
|
||||
wire $0\SF[0:0]
|
||||
attribute \src "everything.v:17.2-31.5"
|
||||
wire width 9 $0\tmp[8:0]
|
||||
attribute \src "everything.v:17.2-31.5"
|
||||
wire width 9 $1\tmp[8:0]
|
||||
attribute \src "everything.v:21.11-21.16"
|
||||
wire width 9 $add$everything.v:21$2_Y
|
||||
attribute \src "everything.v:23.11-23.16"
|
||||
wire width 9 $sub$everything.v:23$3_Y
|
||||
attribute \src "everything.v:27.9-27.22"
|
||||
wire $eq$everything.v:27$4_Y
|
||||
attribute \src "everything.v:21.11-21.16"
|
||||
cell $add $add$everything.v:21$2
|
||||
parameter \A_SIGNED 0
|
||||
parameter \B_SIGNED 0
|
||||
parameter \A_WIDTH 8
|
||||
parameter \B_WIDTH 8
|
||||
parameter \Y_WIDTH 9
|
||||
connect \A \A
|
||||
connect \B \B
|
||||
connect \Y $add$everything.v:21$2_Y
|
||||
end
|
||||
attribute \src "everything.v:23.11-23.16"
|
||||
cell $sub $sub$everything.v:23$3
|
||||
parameter \A_SIGNED 0
|
||||
parameter \B_SIGNED 0
|
||||
parameter \A_WIDTH 8
|
||||
parameter \B_WIDTH 8
|
||||
parameter \Y_WIDTH 9
|
||||
connect \A \A
|
||||
connect \B \B
|
||||
connect \Y $sub$everything.v:23$3_Y
|
||||
end
|
||||
attribute \src "everything.v:27.9-27.22"
|
||||
cell $eq $eq$everything.v:27$4
|
||||
parameter \A_SIGNED 0
|
||||
parameter \B_SIGNED 0
|
||||
parameter \A_WIDTH 8
|
||||
parameter \B_WIDTH 32
|
||||
parameter \Y_WIDTH 1
|
||||
connect \A $1\tmp[8:0] [7:0]
|
||||
connect \B 0
|
||||
connect \Y $eq$everything.v:27$4_Y
|
||||
end
|
||||
attribute \src "everything.v:17.2-31.5"
|
||||
process $proc$everything.v:17$1
|
||||
assign { } { }
|
||||
assign { } { }
|
||||
assign { } { }
|
||||
assign { } { }
|
||||
assign { } { }
|
||||
assign $0\tmp[8:0] $1\tmp[8:0]
|
||||
assign $0\CF[0:0] $1\tmp[8:0] [8]
|
||||
assign $0\ZF[0:0] $eq$everything.v:27$4_Y
|
||||
assign $0\SF[0:0] $1\tmp[8:0] [7]
|
||||
assign $0\result[7:0] $1\tmp[8:0] [7:0]
|
||||
attribute \src "everything.v:19.3-24.10"
|
||||
switch \operation
|
||||
attribute \src "everything.v:19.19-19.19"
|
||||
case 4'0000
|
||||
assign { } { }
|
||||
assign $1\tmp[8:0] $add$everything.v:21$2_Y
|
||||
attribute \src "everything.v:21.17-21.17"
|
||||
case 4'0001
|
||||
assign { } { }
|
||||
assign $1\tmp[8:0] $sub$everything.v:23$3_Y
|
||||
case
|
||||
assign $1\tmp[8:0] \tmp
|
||||
end
|
||||
sync posedge \clk
|
||||
update \result $0\result[7:0]
|
||||
update \CF $0\CF[0:0]
|
||||
update \ZF $0\ZF[0:0]
|
||||
update \SF $0\SF[0:0]
|
||||
update \tmp $0\tmp[8:0]
|
||||
end
|
||||
end
|
||||
attribute \src "everything.v:34.1-40.10"
|
||||
attribute \cells_not_processed 1
|
||||
module \foo
|
||||
attribute \src "everything.v:35.17-35.18"
|
||||
wire width 8 input 1 \a
|
||||
attribute \src "everything.v:35.32-35.33"
|
||||
wire width 8 input 2 \b
|
||||
attribute \src "everything.v:35.48-35.49"
|
||||
wire width 8 output 3 \y
|
||||
attribute \src "everything.v:37.16-37.18"
|
||||
wire width 8 \bb
|
||||
attribute \src "everything.v:39.16-39.22"
|
||||
wire width 8 $add$everything.v:39$5_Y
|
||||
attribute \src "everything.v:39.16-39.22"
|
||||
cell $add $add$everything.v:39$5
|
||||
parameter \A_SIGNED 0
|
||||
parameter \B_SIGNED 0
|
||||
parameter \A_WIDTH 8
|
||||
parameter \B_WIDTH 8
|
||||
parameter \Y_WIDTH 8
|
||||
connect \A \a
|
||||
connect \B \bb
|
||||
connect \Y $add$everything.v:39$5_Y
|
||||
end
|
||||
connect \b \bb
|
||||
connect \y $add$everything.v:39$5_Y
|
||||
end
|
||||
attribute \cells_not_processed 1
|
||||
attribute \src "everything.v:1.1-32.10"
|
||||
module \zzz
|
||||
attribute \src "everything.v:27.9-27.22"
|
||||
wire $eq$everything.v:27$4_Y
|
||||
attribute \src "everything.v:23.11-23.16"
|
||||
wire width 9 $sub$everything.v:23$3_Y
|
||||
attribute \src "everything.v:21.11-21.16"
|
||||
wire width 9 $add$everything.v:21$2_Y
|
||||
attribute \src "everything.v:17.2-31.5"
|
||||
wire width 9 $1\tmp[8:0]
|
||||
attribute \src "everything.v:17.2-31.5"
|
||||
wire width 9 $0\tmp[8:0]
|
||||
attribute \src "everything.v:17.2-31.5"
|
||||
wire $0\SF[0:0]
|
||||
attribute \src "everything.v:17.2-31.5"
|
||||
wire $0\ZF[0:0]
|
||||
attribute \src "everything.v:17.2-31.5"
|
||||
wire $0\CF[0:0]
|
||||
attribute \src "everything.v:17.2-31.5"
|
||||
wire width 8 $0\result[7:0]
|
||||
attribute \src "everything.v:15.12-15.15"
|
||||
wire width 9 \tmp
|
||||
attribute \src "everything.v:9.13-9.15"
|
||||
wire output 8 \SF
|
||||
attribute \src "everything.v:8.13-8.15"
|
||||
wire output 7 \ZF
|
||||
attribute \src "everything.v:7.13-7.15"
|
||||
wire output 6 \CF
|
||||
attribute \src "everything.v:6.19-6.25"
|
||||
wire width 8 output 5 \result
|
||||
attribute \src "everything.v:5.14-5.23"
|
||||
wire width 4 input 4 \operation
|
||||
attribute \src "everything.v:4.14-4.15"
|
||||
wire width 8 input 3 \B
|
||||
attribute \src "everything.v:3.14-3.15"
|
||||
wire width 8 input 2 \A
|
||||
attribute \src "everything.v:2.8-2.11"
|
||||
wire input 1 \clk
|
||||
wire $procmux$8_CMP
|
||||
wire width 9 $procmux$7_Y
|
||||
wire $procmux$9_CMP
|
||||
attribute \src "everything.v:27.9-27.22"
|
||||
cell $logic_not $eq$everything.v:27$4
|
||||
parameter \A_SIGNED 0
|
||||
parameter \Y_WIDTH 1
|
||||
parameter \A_WIDTH 8
|
||||
connect \A $1\tmp[8:0] [7:0]
|
||||
connect \Y $eq$everything.v:27$4_Y
|
||||
end
|
||||
attribute \src "everything.v:23.11-23.16"
|
||||
cell $sub $sub$everything.v:23$3
|
||||
parameter \A_SIGNED 0
|
||||
parameter \B_SIGNED 0
|
||||
parameter \A_WIDTH 8
|
||||
parameter \B_WIDTH 8
|
||||
parameter \Y_WIDTH 9
|
||||
connect \A \A
|
||||
connect \B \B
|
||||
connect \Y $sub$everything.v:23$3_Y
|
||||
end
|
||||
attribute \src "everything.v:21.11-21.16"
|
||||
cell $add $add$everything.v:21$2
|
||||
parameter \A_SIGNED 0
|
||||
parameter \B_SIGNED 0
|
||||
parameter \A_WIDTH 8
|
||||
parameter \B_WIDTH 8
|
||||
parameter \Y_WIDTH 9
|
||||
connect \A \A
|
||||
connect \B \B
|
||||
connect \Y $add$everything.v:21$2_Y
|
||||
end
|
||||
attribute \src "everything.v:21.17-21.17|everything.v:19.3-24.10"
|
||||
attribute \full_case 1
|
||||
cell $eq $procmux$8_CMP0
|
||||
parameter \A_SIGNED 0
|
||||
parameter \B_SIGNED 0
|
||||
parameter \A_WIDTH 4
|
||||
parameter \B_WIDTH 4
|
||||
parameter \Y_WIDTH 1
|
||||
connect \A \operation
|
||||
connect \B 4'0001
|
||||
connect \Y $procmux$8_CMP
|
||||
end
|
||||
attribute \src "everything.v:21.17-21.17|everything.v:19.3-24.10"
|
||||
attribute \full_case 1
|
||||
cell $pmux $procmux$7
|
||||
parameter \WIDTH 9
|
||||
parameter \S_WIDTH 2
|
||||
connect \A \tmp
|
||||
connect \B { $add$everything.v:21$2_Y $sub$everything.v:23$3_Y }
|
||||
connect \S { $procmux$9_CMP $procmux$8_CMP }
|
||||
connect \Y $procmux$7_Y
|
||||
end
|
||||
attribute \src "everything.v:19.19-19.19|everything.v:19.3-24.10"
|
||||
attribute \full_case 1
|
||||
cell $logic_not $procmux$9_CMP0
|
||||
parameter \A_SIGNED 0
|
||||
parameter \Y_WIDTH 1
|
||||
parameter \A_WIDTH 4
|
||||
connect \A \operation
|
||||
connect \Y $procmux$9_CMP
|
||||
end
|
||||
attribute \src "everything.v:17.2-31.5"
|
||||
cell $dff $procdff$10
|
||||
parameter \WIDTH 8
|
||||
parameter \CLK_POLARITY 1'1
|
||||
connect \D $procmux$7_Y [7:0]
|
||||
connect \Q \result
|
||||
connect \CLK \clk
|
||||
end
|
||||
attribute \src "everything.v:17.2-31.5"
|
||||
cell $dff $procdff$11
|
||||
parameter \WIDTH 1
|
||||
parameter \CLK_POLARITY 1'1
|
||||
connect \D $procmux$7_Y [8]
|
||||
connect \Q \CF
|
||||
connect \CLK \clk
|
||||
end
|
||||
attribute \src "everything.v:17.2-31.5"
|
||||
cell $dff $procdff$12
|
||||
parameter \WIDTH 1
|
||||
parameter \CLK_POLARITY 1'1
|
||||
connect \D $eq$everything.v:27$4_Y
|
||||
connect \Q \ZF
|
||||
connect \CLK \clk
|
||||
end
|
||||
attribute \src "everything.v:17.2-31.5"
|
||||
cell $dff $procdff$13
|
||||
parameter \WIDTH 1
|
||||
parameter \CLK_POLARITY 1'1
|
||||
connect \D $procmux$7_Y [7]
|
||||
connect \Q \SF
|
||||
connect \CLK \clk
|
||||
end
|
||||
attribute \src "everything.v:17.2-31.5"
|
||||
cell $dff $procdff$14
|
||||
parameter \WIDTH 9
|
||||
parameter \CLK_POLARITY 1'1
|
||||
connect \D $procmux$7_Y
|
||||
connect \Q \tmp
|
||||
connect \CLK \clk
|
||||
end
|
||||
connect $0\result[7:0] $1\tmp[8:0] [7:0]
|
||||
connect $0\SF[0:0] $1\tmp[8:0] [7]
|
||||
connect $0\ZF[0:0] $eq$everything.v:27$4_Y
|
||||
connect $0\CF[0:0] $1\tmp[8:0] [8]
|
||||
connect $0\tmp[8:0] $1\tmp[8:0]
|
||||
connect $1\tmp[8:0] $procmux$7_Y
|
||||
end
|
39
tests/rtlil/roundtrip-text.sh
Normal file
39
tests/rtlil/roundtrip-text.sh
Normal file
|
@ -0,0 +1,39 @@
|
|||
set -euo pipefail
|
||||
YS=../../yosys
|
||||
|
||||
mkdir -p temp
|
||||
|
||||
# non-POSIX sed -i inconsistency workaround
|
||||
remove_empty_lines() {
|
||||
local file="$1"
|
||||
sed '/^$/d' "$file" > temp/tmp
|
||||
mv temp/tmp "$file"
|
||||
}
|
||||
|
||||
# write_rtlil and dump are equivalent
|
||||
$YS -p "read_verilog -sv everything.v; copy alu zzz; proc zzz; dump -o temp/roundtrip-text.dump.il; write_rtlil temp/roundtrip-text.write.il"
|
||||
remove_empty_lines temp/roundtrip-text.dump.il
|
||||
remove_empty_lines temp/roundtrip-text.write.il
|
||||
# Trim first line ("Generated by Yosys ...")
|
||||
tail -n +2 temp/roundtrip-text.write.il > temp/roundtrip-text.write-nogen.il
|
||||
diff temp/roundtrip-text.dump.il temp/roundtrip-text.write-nogen.il
|
||||
diff temp/roundtrip-text.dump.il roundtrip-text.ref.il
|
||||
|
||||
# Loading and writing it out again doesn't change the RTLIL
|
||||
$YS -p "read_rtlil temp/roundtrip-text.dump.il; write_rtlil temp/roundtrip-text.reload.il"
|
||||
remove_empty_lines temp/roundtrip-text.reload.il
|
||||
tail -n +2 temp/roundtrip-text.reload.il > temp/roundtrip-text.reload-nogen.il
|
||||
diff temp/roundtrip-text.dump.il temp/roundtrip-text.reload-nogen.il
|
||||
|
||||
# Hashing differences don't change the RTLIL
|
||||
$YS --hash-seed=2345678 -p "read_rtlil temp/roundtrip-text.dump.il; write_rtlil temp/roundtrip-text.reload-hash.il"
|
||||
remove_empty_lines temp/roundtrip-text.reload-hash.il
|
||||
tail -n +2 temp/roundtrip-text.reload-hash.il > temp/roundtrip-text.reload-hash-nogen.il
|
||||
diff temp/roundtrip-text.dump.il temp/roundtrip-text.reload-hash-nogen.il
|
||||
|
||||
echo "Without ABC, we don't get any irreproducibility and can pin that"
|
||||
echo "Has this test case started failing for you? Consider updating the reference"
|
||||
$YS -p "read_verilog -sv everything.v; synth -relativeshare -noabc; write_rtlil temp/roundtrip-text.synth.il"
|
||||
remove_empty_lines temp/roundtrip-text.synth.il
|
||||
tail -n +2 temp/roundtrip-text.synth.il > temp/roundtrip-text.synth-nogen.il
|
||||
diff temp/roundtrip-text.synth-nogen.il roundtrip-text.synth.ref.il
|
1194
tests/rtlil/roundtrip-text.synth.ref.il
Normal file
1194
tests/rtlil/roundtrip-text.synth.ref.il
Normal file
File diff suppressed because it is too large
Load diff
4
tests/rtlil/run-test.sh
Executable file
4
tests/rtlil/run-test.sh
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
set -eu
|
||||
source ../gen-tests-makefile.sh
|
||||
generate_mk --bash
|
Loading…
Add table
Add a link
Reference in a new issue