mirror of https://github.com/YosysHQ/yosys.git
Docs: Improve cell_help usage
- Drop `cell_code` and instead map code lookups to the `cell_help` dict. - Add helper functions to struct for checking and getting the right cell. - Add `CellType` for cell to `write_cell_rst` function declaration in preparation for use in future. - Iterate over `yosys_celltypes.cell_types` when exporting cell rst files, reporting errors for any cells defined in `cell_types` but not `cell_help_messages`.
This commit is contained in:
parent
40ba92e956
commit
21747c468c
|
@ -766,15 +766,23 @@ struct SimHelper {
|
||||||
string ver;
|
string ver;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool is_code_getter(string name) {
|
||||||
|
return *(--(name.end())) == '+';
|
||||||
|
}
|
||||||
|
|
||||||
|
static string get_cell_name(string name) {
|
||||||
|
return is_code_getter(name) ? name.substr(0, name.length()-1) : name;
|
||||||
|
}
|
||||||
|
|
||||||
static struct CellHelpMessages {
|
static struct CellHelpMessages {
|
||||||
dict<string, SimHelper> cell_help, cell_code;
|
dict<string, SimHelper> cell_help;
|
||||||
CellHelpMessages() {
|
CellHelpMessages() {
|
||||||
SimHelper tempCell;
|
|
||||||
#include "techlibs/common/simlib_help.inc"
|
#include "techlibs/common/simlib_help.inc"
|
||||||
#include "techlibs/common/simcells_help.inc"
|
#include "techlibs/common/simcells_help.inc"
|
||||||
cell_help.sort();
|
cell_help.sort();
|
||||||
cell_code.sort();
|
|
||||||
}
|
}
|
||||||
|
bool contains(string name) { return cell_help.count(get_cell_name(name)) > 0; }
|
||||||
|
SimHelper get(string name) { return cell_help[get_cell_name(name)]; }
|
||||||
} cell_help_messages;
|
} cell_help_messages;
|
||||||
|
|
||||||
struct HelpPass : public Pass {
|
struct HelpPass : public Pass {
|
||||||
|
@ -884,7 +892,7 @@ struct HelpPass : public Pass {
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
void write_cell_rst(Yosys::SimHelper cell)
|
void write_cell_rst(Yosys::SimHelper cell, Yosys::CellType)
|
||||||
{
|
{
|
||||||
// open
|
// open
|
||||||
FILE *f = fopen(stringf("docs/source/cell/%s.rst", cell.filesafe_name().c_str()).c_str(), "wt");
|
FILE *f = fopen(stringf("docs/source/cell/%s.rst", cell.filesafe_name().c_str()).c_str(), "wt");
|
||||||
|
@ -985,9 +993,20 @@ struct HelpPass : public Pass {
|
||||||
write_cmd_rst(it.first, it.second->short_help, buf.str());
|
write_cmd_rst(it.first, it.second->short_help, buf.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// this option is also undocumented as it is for internal use only
|
||||||
else if (args[1] == "-write-rst-cells-manual") {
|
else if (args[1] == "-write-rst-cells-manual") {
|
||||||
for (auto &it : cell_help_messages.cell_help) {
|
bool raise_error = false;
|
||||||
write_cell_rst(it.second);
|
for (auto &it : yosys_celltypes.cell_types) {
|
||||||
|
auto name = it.first.str();
|
||||||
|
if (cell_help_messages.contains(name)) {
|
||||||
|
write_cell_rst(cell_help_messages.get(name), it.second);
|
||||||
|
} else {
|
||||||
|
log("ERROR: Missing cell help for cell '%s'.\n", name.c_str());
|
||||||
|
raise_error |= true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (raise_error) {
|
||||||
|
log_error("One or more cells defined in celltypes.h are missing help documentation.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (pass_register.count(args[1])) {
|
else if (pass_register.count(args[1])) {
|
||||||
|
@ -998,29 +1017,27 @@ struct HelpPass : public Pass {
|
||||||
log("\n");
|
log("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (cell_help_messages.cell_help.count(args[1])) {
|
else if (cell_help_messages.contains(args[1])) {
|
||||||
SimHelper help_cell = cell_help_messages.cell_help.at(args[1]);
|
auto help_cell = cell_help_messages.get(args[1]);
|
||||||
if (help_cell.ver == "2" || help_cell.ver == "2a") {
|
if (is_code_getter(args[1])) {
|
||||||
log("\n %s %s\n\n", help_cell.name.c_str(), help_cell.ports.c_str());
|
log("\n");
|
||||||
if (help_cell.title != "") log("%s\n", help_cell.title.c_str());
|
log("%s\n", help_cell.code.c_str());
|
||||||
std::stringstream ss;
|
} else {
|
||||||
ss << help_cell.desc;
|
if (help_cell.ver == "2" || help_cell.ver == "2a") {
|
||||||
for (std::string line; std::getline(ss, line, '\n');) {
|
log("\n %s %s\n\n", help_cell.name.c_str(), help_cell.ports.c_str());
|
||||||
if (line != "::") log("%s\n", line.c_str());
|
if (help_cell.title != "") log("%s\n", help_cell.title.c_str());
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << help_cell.desc;
|
||||||
|
for (std::string line; std::getline(ss, line, '\n');) {
|
||||||
|
if (line != "::") log("%s\n", line.c_str());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log("%s\n", help_cell.desc.c_str());
|
||||||
}
|
}
|
||||||
log("Run 'help %s+' to display the Verilog model for this cell type.\n", args[1].c_str());
|
log("Run 'help %s+' to display the Verilog model for this cell type.\n", args[1].c_str());
|
||||||
log("\n");
|
log("\n");
|
||||||
} else {
|
|
||||||
log("%s\n", help_cell.desc.c_str());
|
|
||||||
log("Run 'help %s+' to display the Verilog model for this cell type.\n", args[1].c_str());
|
|
||||||
log("\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (cell_help_messages.cell_code.count(args[1])) {
|
|
||||||
SimHelper help_cell = cell_help_messages.cell_code.at(args[1]);
|
|
||||||
log("\n");
|
|
||||||
log("%s\n", help_cell.code.c_str());
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
log("No such command or cell type: %s\n", args[1].c_str());
|
log("No such command or cell type: %s\n", args[1].c_str());
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -22,18 +22,14 @@ class SimHelper:
|
||||||
"name", "title", "ports", "source", "desc", "code", "ver",
|
"name", "title", "ports", "source", "desc", "code", "ver",
|
||||||
]
|
]
|
||||||
# generate C++ struct
|
# generate C++ struct
|
||||||
val = "tempCell = {\n"
|
val = f"cell_help[{json.dumps(self.name)}] = "
|
||||||
|
val += "{\n"
|
||||||
for field in printed_fields:
|
for field in printed_fields:
|
||||||
field_val = getattr(self, field)
|
field_val = getattr(self, field)
|
||||||
if isinstance(field_val, list):
|
if isinstance(field_val, list):
|
||||||
field_val = "\n".join(field_val)
|
field_val = "\n".join(field_val)
|
||||||
val += f' {json.dumps(field_val)},\n'
|
val += f' {json.dumps(field_val)},\n'
|
||||||
val += "};\n"
|
val += "};\n"
|
||||||
|
|
||||||
# map name to struct
|
|
||||||
val += f'cell_help[{json.dumps(self.name)}] = tempCell;'
|
|
||||||
val += "\n"
|
|
||||||
val += f'cell_code[{json.dumps(self.name + "+")}] = tempCell;'
|
|
||||||
return val
|
return val
|
||||||
|
|
||||||
def simcells_reparse(cell: SimHelper):
|
def simcells_reparse(cell: SimHelper):
|
||||||
|
|
Loading…
Reference in New Issue