From 6bbe763845023c55f66c270cab347d54a989836f Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 9 Apr 2024 15:33:50 +1200 Subject: [PATCH] Docs: Put cell library help strings into a struct Allows for more expressive code when constructing help messages for cells. Will also move extra logic in parsing help strings into the initial python parse instead of doing it in the C++ at export time. --- kernel/register.cc | 43 +++++++++++++++++++------ techlibs/common/cellhelp.py | 64 +++++++++++++++++++++++++------------ 2 files changed, 78 insertions(+), 29 deletions(-) diff --git a/kernel/register.cc b/kernel/register.cc index 17bfb079a..85d3d4748 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -747,9 +747,25 @@ void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string f design->selection_stack.pop_back(); } +struct SimHelper { + string name; + inline string filesafe_name() { + if (name.at(0) == '$') + return name.substr(1); + else + return name; + } + string short_desc; + string ports; + string desc; + string code; + string ver; +}; + static struct CellHelpMessages { - dict cell_help, cell_code; + dict cell_help, cell_code; CellHelpMessages() { + SimHelper tempCell; #include "techlibs/common/simlib_help.inc" #include "techlibs/common/simcells_help.inc" cell_help.sort(); @@ -947,9 +963,8 @@ struct HelpPass : public Pass { else if (args[1] == "-cells") { log("\n"); for (auto &it : cell_help_messages.cell_help) { - string line = split_tokens(it.second, "\n").at(0); - string cell_name = next_token(line); - log(" %-15s %s\n", cell_name.c_str(), line.c_str()); + SimHelper help_cell = it.second; + log(" %-15s %s\n", help_cell.name.c_str(), help_cell.ports.c_str()); } log("\n"); log("Type 'help ' for more information on a cell type.\n"); @@ -973,7 +988,7 @@ struct HelpPass : public Pass { } else if (args[1] == "-write-rst-cells-manual") { for (auto &it : cell_help_messages.cell_help) { - write_cell_rst(it.first, it.second, cell_help_messages.cell_code.at(it.first + "+")); + write_cell_rst(it.first, it.second.desc, it.second.code); } } else if (pass_register.count(args[1])) { @@ -985,13 +1000,23 @@ struct HelpPass : public Pass { } } else if (cell_help_messages.cell_help.count(args[1])) { - log("%s", cell_help_messages.cell_help.at(args[1]).c_str()); - log("Run 'help %s+' to display the Verilog model for this cell type.\n", args[1].c_str()); - log("\n"); + SimHelper help_cell = cell_help_messages.cell_help.at(args[1]); + if (help_cell.ver == "2") { + log("\n %s %s\n", help_cell.name.c_str(), help_cell.ports.c_str()); + log("\n%s\n", help_cell.short_desc.c_str()); + 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 { + 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", cell_help_messages.cell_code.at(args[1]).c_str()); + log("%s\n", help_cell.code.c_str()); } else log("No such command or cell type: %s\n", args[1].c_str()); diff --git a/techlibs/common/cellhelp.py b/techlibs/common/cellhelp.py index 5c44cb802..8d0d7d757 100644 --- a/techlibs/common/cellhelp.py +++ b/techlibs/common/cellhelp.py @@ -1,34 +1,58 @@ #!/usr/bin/env python3 +from __future__ import annotations import fileinput import json -current_help_msg = [] -current_module_code = [] -current_module_name = None -current_module_signature = None +class SimHelper: + name: str = "" + short_desc: str = "" + ports: str = "" + desc: list[str] + code: list[str] + ver: str = "1" -def print_current_cell(): - print("cell_help[\"%s\"] = %s;" % (current_module_name, "\n".join([json.dumps(line) for line in current_help_msg]))) - print("cell_code[\"%s+\"] = %s;" % (current_module_name, "\n".join([json.dumps(line) for line in current_module_code]))) + def __init__(self) -> None: + self.desc = [] + + def __str__(self) -> str: + val = "tempCell = {\n" + val += f' {json.dumps(self.name)},\n' + val += f' {json.dumps(self.short_desc)},\n' + val += f' {json.dumps(self.ports)},\n' + val += ' ' + json.dumps("\n".join(self.desc)) + ',\n' + val += ' ' + json.dumps("\n".join(self.code)) + ',\n' + val += f' {json.dumps(self.ver)},\n' + val += "};\n" + val += f'cell_help[{json.dumps(self.name)}] = tempCell;' + val += "\n" + val += f'cell_code[{json.dumps(self.name + "+")}] = tempCell;' + return val + +simHelper = SimHelper() for line in fileinput.input(): + line = line.rstrip() + # special comments if line.startswith("//-"): - current_help_msg.append(line[4:] if len(line) > 4 else "\n") + simHelper.desc.append(line[4:] if len(line) > 4 else "") + elif line.startswith("//* "): + _, key, val = line.split(maxsplit=2) + setattr(simHelper, key, val) + + # code parsing if line.startswith("module "): - current_module_name = line.split()[1].strip("\\") - current_module_signature = " ".join(line.replace("\\", "").replace(";", "").split()[1:]) - current_module_code = [] + clean_line = line[7:].replace("\\", "").replace(";", "") + simHelper.name, simHelper.ports = clean_line.split(maxsplit=1) + simHelper.code = [] elif not line.startswith("endmodule"): line = " " + line - current_module_code.append(line.replace("\t", " ")) + try: + simHelper.code.append(line.replace("\t", " ")) + except AttributeError: + # no module definition, ignore line + pass if line.startswith("endmodule"): - if len(current_help_msg) == 0: - current_help_msg.append("\n") - current_help_msg.append(" %s\n" % current_module_signature) - current_help_msg.append("\n") - current_help_msg.append("No help message for this cell type found.\n") - current_help_msg.append("\n") - print_current_cell() - current_help_msg = [] + print(simHelper) + simHelper = SimHelper()