Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yosys new extractor method #644

Merged
merged 8 commits into from
May 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ set(VERSION_MAJOR 0)
set(VERSION_MINOR 0)


set(VERSION_PATCH 313)
set(VERSION_PATCH 315)


project(yosys_verific_rs)
Expand Down
76 changes: 76 additions & 0 deletions design_edit/src/primitives_extractor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,7 @@ bool PRIMITIVES_EXTRACTOR::extract(RTLIL::Design* design) {
gen_instances();
determine_fabric_clock(design->top_module());
summarize();
finalize(design->top_module());
}

EXTRACT_END:
Expand Down Expand Up @@ -1516,6 +1517,81 @@ void PRIMITIVES_EXTRACTOR::summarize(const PRIMITIVE* primitive,
}
}

/*
Function in final stage to check if there is mistake in the design (or code)
*/
void PRIMITIVES_EXTRACTOR::finalize(Yosys::RTLIL::Module* module) {
size_t design_count = 0;
size_t primitive_count = m_ports.size() + m_child_primitives.size();
size_t instance_count = 0;
for (auto cell : module->cells()) {
if (is_supported_primitive(cell->type.str(), PORT_REQ::DONT_CARE) !=
nullptr) {
design_count++;
}
}
for (auto& inst : m_instances) {
if (inst->module != "WIRE") {
instance_count++;
}
}
if (design_count == primitive_count && design_count == instance_count) {
POST_MSG(1, "Final checking is good");
} else {
POST_MSG(1,
"Error: Final checking failed. Design count: %ld, Primitive "
"count: %ld, Instance count: %ld",
design_count, primitive_count, instance_count);
if (design_count != primitive_count) {
for (auto cell : module->cells()) {
if (is_supported_primitive(cell->type.str(), PORT_REQ::DONT_CARE) !=
nullptr) {
bool found = false;
for (auto& p : m_ports) {
if (p->name == cell->name.str()) {
found = true;
break;
}
}
if (found) {
continue;
}
for (auto& p : m_child_primitives) {
if (p->name == cell->name.str()) {
found = true;
break;
}
}
if (found) {
continue;
}
POST_MSG(2, "Error: Missing %s (%s) in primitive list",
cell->type.c_str(), cell->name.c_str());
}
}
}
if (design_count != instance_count) {
for (auto cell : module->cells()) {
if (is_supported_primitive(cell->type.str(), PORT_REQ::DONT_CARE) !=
nullptr) {
bool found = false;
for (auto& inst : m_instances) {
if (inst->name == cell->name.str()) {
found = true;
break;
}
}
if (found) {
continue;
}
POST_MSG(2, "Error: Missing %s (%s) in instance list",
cell->type.c_str(), cell->name.c_str());
}
}
}
}
}

/*
Write out message and instances information into JSON
*/
Expand Down
9 changes: 5 additions & 4 deletions design_edit/src/primitives_extractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class PRIMITIVES_EXTRACTOR {
std::unordered_map<std::string, std::string>& properties);
void write_json(const std::string& file, bool simple = false);
void write_sdc(const std::string& file);
static void get_signals(const Yosys::RTLIL::SigSpec& sig,
std::vector<std::string>& signals);

private:
void post_msg(uint32_t offset, const std::string& msg);
Expand Down Expand Up @@ -79,10 +81,8 @@ class PRIMITIVES_EXTRACTOR {
Yosys::RTLIL::Cell* cell,
const std::string& connection);
void trace_gearbox_clock();
void get_chunks(const Yosys::RTLIL::SigChunk& chunk,
std::vector<std::string>& signals);
void get_signals(const Yosys::RTLIL::SigSpec& sig,
std::vector<std::string>& signals);
static void get_chunks(const Yosys::RTLIL::SigChunk& chunk,
std::vector<std::string>& signals);
void gen_instances();
void gen_instances(const std::string& linked_object,
std::vector<std::string> linked_objects,
Expand All @@ -104,6 +104,7 @@ class PRIMITIVES_EXTRACTOR {
const std::vector<std::string> traces, bool is_in_dir);
void summarize(const PRIMITIVE* primitive, const std::string& object_name,
const std::vector<std::string> traces, bool is_in_dir);
void finalize(Yosys::RTLIL::Module* module);
void write_instance(const INSTANCE* instance, std::ofstream& json,
bool simple);
void write_instance_map(std::map<std::string, std::string> map,
Expand Down
54 changes: 34 additions & 20 deletions design_edit/src/rs_design_edit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -202,17 +202,21 @@ struct DesignEditRapidSilicon : public ScriptPass {
// enhancement to auto create wire primitives
size_t i = 0;
for (auto it : mod->connections()) {
std::ostringstream left;
std::ostringstream right;
RTLIL_BACKEND::dump_sigspec(left, it.first, true, true);
RTLIL_BACKEND::dump_sigspec(right, it.second, true, true);
json instance_object;
instance_object["module"] = (std::string)("WIRE");
instance_object["name"] = (std::string)(stringf("wire%ld", i));
instance_object["connectivity"]["I"] = remove_backslashes(right.str());
instance_object["connectivity"]["O"] = remove_backslashes(left.str());
instances_array.push_back(instance_object);
i++;
std::vector<std::string> lefts;
std::vector<std::string> rights;
PRIMITIVES_EXTRACTOR::get_signals(it.first, lefts);
PRIMITIVES_EXTRACTOR::get_signals(it.second, rights);
log_assert(lefts.size() == rights.size());
// break the bus into bit by bit
for (size_t j = 0; j < lefts.size(); j++) {
json instance_object;
instance_object["module"] = (std::string)("WIRE");
instance_object["name"] = (std::string)(stringf("wire%ld", i));
instance_object["connectivity"]["I"] = remove_backslashes(rights[j]);
instance_object["connectivity"]["O"] = remove_backslashes(lefts[j]);
instances_array.push_back(instance_object);
i++;
}
}
#if 0
// Starting by marking all the "port" primitives
Expand All @@ -231,16 +235,22 @@ struct DesignEditRapidSilicon : public ScriptPass {
for (const RTLIL::Wire* wire : mod->wires()) {
// We can use one line code: !wire->port_input && !wire->port_output
// But prefer list of all the valid possible of Input, Output, Inout
if ((wire->port_input && !wire->port_output) || // Input
(!wire->port_input && wire->port_output) || // Output
(wire->port_input && wire->port_output)) { // Inout
std::string dir = "";
if (wire->port_input && !wire->port_output) {
dir = "IN";
} else if (!wire->port_input && wire->port_output) {
dir = "OUT";
} else if (wire->port_input && wire->port_output) {
dir = "INOUT";
}
if (dir.size()) {
for (int index = 0; index < wire->width; index++) {
std::string portname = wire->name.str();
if (wire->width > 1) {
portname = stringf("%s[%d]", wire->name.c_str(), index);
portname = stringf("%s[%d]", wire->name.c_str(), wire->start_offset + index);
}
portname = remove_backslashes(portname);
link_instance(instances_array, portname, portname, true);
link_instance(instances_array, portname, portname, dir, 0, false);
}
}
}
Expand All @@ -260,11 +270,13 @@ struct DesignEditRapidSilicon : public ScriptPass {
if (std::find(CONNECTING_PORTS.begin(), CONNECTING_PORTS.end(), (std::string)(iter.key())) !=
CONNECTING_PORTS.end()) {
if (i == 0) {
linked += link_instance(instances_array, inst["linked_object"], (std::string)(iter.value()), true,
linked += link_instance(instances_array, inst["linked_object"], (std::string)(iter.value()),
inst["direction"], uint32_t(inst["index"]) + 1, true,
{"I_BUF_DS", "O_BUF_DS", "O_BUFT_DS"});
} else {
// dont set allow_dual_name=true, it might become infinite loop
linked += link_instance(instances_array, inst["linked_object"], (std::string)(iter.value()), false);
linked += link_instance(instances_array, inst["linked_object"], (std::string)(iter.value()),
inst["direction"], uint32_t(inst["index"]) + 1, false);
}
}
}
Expand All @@ -284,8 +296,8 @@ struct DesignEditRapidSilicon : public ScriptPass {
}
}

size_t link_instance(json& instances_array, const std::string& object, const std::string& net, bool allow_dual_name,
std::vector<std::string> search_modules = {}) {
size_t link_instance(json& instances_array, const std::string& object, const std::string& net, const std::string& direction,
uint32_t index, bool allow_dual_name, std::vector<std::string> search_modules = {}) {
size_t linked = 0;
for (auto& inst : instances_array) {
// Only if this instance had not been linked
Expand All @@ -304,6 +316,8 @@ struct DesignEditRapidSilicon : public ScriptPass {
} else {
inst["linked_object"] = object;
}
inst["direction"] = direction;
inst["index"] = index;
linked++;
break;
}
Expand Down
Loading