From 7d3a3a317351d0f63f01a134f450bb81ba67fff7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 14 Oct 2015 16:27:42 +0200 Subject: [PATCH] Added first help messages for cell types --- .gitignore | 1 + kernel/register.cc | 49 ++++++- techlibs/common/.gitignore | 2 + techlibs/common/Makefile.inc | 15 +++ techlibs/common/cellhelp.py | 25 ++++ techlibs/common/simcells.v | 250 +++++++++++++++++++++++++++++++++++ 6 files changed, 336 insertions(+), 6 deletions(-) create mode 100644 techlibs/common/.gitignore create mode 100644 techlibs/common/cellhelp.py diff --git a/.gitignore b/.gitignore index 484faf419..93e28cd6c 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ /yosys-abc /yosys-abc.exe /yosys-config +/yosys-smtbmc /yosys-filterlib /yosys-filterlib.exe /kernel/version_*.cc diff --git a/kernel/register.cc b/kernel/register.cc index 179d064fd..421294230 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -534,14 +534,28 @@ void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string f design->check(); } +static struct CellHelpMessages { + dict cell_help, cell_code; + CellHelpMessages() { +#include "techlibs/common/simlib_help.inc" +#include "techlibs/common/simcells_help.inc" + cell_help.sort(); + cell_code.sort(); + } +} cell_help_messages; + struct HelpPass : public Pass { HelpPass() : Pass("help", "display help messages") { } virtual void help() { log("\n"); - log(" help ............. list all commands\n"); - log(" help ... print help message for given command\n"); - log(" help -all ........ print complete command reference\n"); + log(" help ................ list all commands\n"); + log(" help ...... print help message for given command\n"); + log(" help -all ........... print complete command reference\n"); + log("\n"); + log(" help -cells .......... list all cell types\n"); + log(" help ..... print help message for given cell type\n"); + log(" help + .... print verilog code for given cell type\n"); log("\n"); } void escape_tex(std::string &tex) @@ -609,6 +623,7 @@ struct HelpPass : public Pass { log(" %-20s %s\n", it.first.c_str(), it.second->short_help.c_str()); log("\n"); log("Type 'help ' for more information on a command.\n"); + log("Type 'help -cells' for a list of all cell types.\n"); log("\n"); return; } @@ -624,6 +639,18 @@ struct HelpPass : public Pass { it.second->help(); } } + 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(" %-10s %s\n", cell_name.c_str(), line.c_str()); + } + log("\n"); + log("Type 'help ' for more information on a cell type.\n"); + log("\n"); + return; + } // this option is undocumented as it is for internal use only else if (args[1] == "-write-tex-command-reference-manual") { FILE *f = fopen("command-reference-manual.tex", "wt"); @@ -649,10 +676,20 @@ struct HelpPass : public Pass { } fclose(f); } - else if (pass_register.count(args[1]) == 0) - log("No such command: %s\n", args[1].c_str()); - else + else if (pass_register.count(args[1])) { pass_register.at(args[1])->help(); + } + 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"); + } + else if (cell_help_messages.cell_code.count(args[1])) { + log("\n"); + log("%s", cell_help_messages.cell_code.at(args[1]).c_str()); + } + else + log("No such command or cell type: %s\n", args[1].c_str()); return; } diff --git a/techlibs/common/.gitignore b/techlibs/common/.gitignore new file mode 100644 index 000000000..0a1e7b68d --- /dev/null +++ b/techlibs/common/.gitignore @@ -0,0 +1,2 @@ +simlib_help.inc +simcells_help.inc diff --git a/techlibs/common/Makefile.inc b/techlibs/common/Makefile.inc index f222a0289..5c50dea01 100644 --- a/techlibs/common/Makefile.inc +++ b/techlibs/common/Makefile.inc @@ -3,6 +3,21 @@ ifneq ($(SMALL),1) OBJS += techlibs/common/synth.o endif +GENFILES += techlibs/common/simlib_help.inc +GENFILES += techlibs/common/simcells_help.inc + +techlibs/common/simlib_help.inc: techlibs/common/cellhelp.py techlibs/common/simlib.v + $(Q) mkdir -p techlibs/common + $(P) python3 $^ > $@.new + $(Q) mv $@.new $@ + +techlibs/common/simcells_help.inc: techlibs/common/cellhelp.py techlibs/common/simcells.v + $(Q) mkdir -p techlibs/common + $(P) python3 $^ > $@.new + $(Q) mv $@.new $@ + +kernel/register.o: techlibs/common/simlib_help.inc techlibs/common/simcells_help.inc + $(eval $(call add_share_file,share,techlibs/common/simlib.v)) $(eval $(call add_share_file,share,techlibs/common/simcells.v)) $(eval $(call add_share_file,share,techlibs/common/techmap.v)) diff --git a/techlibs/common/cellhelp.py b/techlibs/common/cellhelp.py new file mode 100644 index 000000000..7844ccb40 --- /dev/null +++ b/techlibs/common/cellhelp.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 + +import fileinput +import json + +current_help_msg = [] +current_module_code = [] +current_module_name = None + +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]))) + +for line in fileinput.input(): + if line.startswith("//-"): + current_help_msg.append(line[4:] if len(line) > 4 else "\n") + if line.startswith("module "): + current_module_name = line.split()[1].strip("\\") + current_module_code = [] + current_module_code.append(line) + if line.startswith("endmodule"): + if len(current_help_msg) > 0: + print_current_cell() + current_help_msg = [] + diff --git a/techlibs/common/simcells.v b/techlibs/common/simcells.v index 3b7d55c6e..3a8c24210 100644 --- a/techlibs/common/simcells.v +++ b/techlibs/common/simcells.v @@ -25,60 +25,184 @@ * */ +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_BUF_ (A, Y) +//- +//- A buffer. This cell type is always optimized away by the opt_clean pass. +//- +//- Truth table: A | Y +//- ---+--- +//- 0 | 0 +//- 1 | 1 +//- module \$_BUF_ (A, Y); input A; output Y; assign Y = A; endmodule +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_NOT_ (A, Y) +//- +//- An inverter gate. +//- +//- Truth table: A | Y +//- ---+--- +//- 0 | 1 +//- 1 | 0 +//- module \$_NOT_ (A, Y); input A; output Y; assign Y = ~A; endmodule +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_AND_ (A, B, Y) +//- +//- A 2-input AND gate. +//- +//- Truth table: A B | Y +//- -----+--- +//- 0 0 | 0 +//- 0 1 | 0 +//- 1 0 | 0 +//- 1 1 | 1 +//- module \$_AND_ (A, B, Y); input A, B; output Y; assign Y = A & B; endmodule +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_NAND_ (A, B, Y) +//- +//- A 2-input NAND gate. +//- +//- Truth table: A B | Y +//- -----+--- +//- 0 0 | 1 +//- 0 1 | 1 +//- 1 0 | 1 +//- 1 1 | 0 +//- module \$_NAND_ (A, B, Y); input A, B; output Y; assign Y = ~(A & B); endmodule +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_OR_ (A, B, Y) +//- +//- A 2-input OR gate. +//- +//- Truth table: A B | Y +//- -----+--- +//- 0 0 | 0 +//- 0 1 | 1 +//- 1 0 | 1 +//- 1 1 | 1 +//- module \$_OR_ (A, B, Y); input A, B; output Y; assign Y = A | B; endmodule +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_NOR_ (A, B, Y) +//- +//- A 2-input NOR gate. +//- +//- Truth table: A B | Y +//- -----+--- +//- 0 0 | 1 +//- 0 1 | 0 +//- 1 0 | 0 +//- 1 1 | 0 +//- module \$_NOR_ (A, B, Y); input A, B; output Y; assign Y = ~(A | B); endmodule +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_XOR_ (A, B, Y) +//- +//- A 2-input XOR gate. +//- +//- Truth table: A B | Y +//- -----+--- +//- 0 0 | 0 +//- 0 1 | 1 +//- 1 0 | 1 +//- 1 1 | 0 +//- module \$_XOR_ (A, B, Y); input A, B; output Y; assign Y = A ^ B; endmodule +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_XNOR_ (A, B, Y) +//- +//- A 2-input XNOR gate. +//- +//- Truth table: A B | Y +//- -----+--- +//- 0 0 | 1 +//- 0 1 | 0 +//- 1 0 | 0 +//- 1 1 | 1 +//- module \$_XNOR_ (A, B, Y); input A, B; output Y; assign Y = ~(A ^ B); endmodule +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_MUX_ (A, B, S, Y) +//- +//- A 2-input MUX gate. +//- +//- Truth table: A B S | Y +//- -------+--- +//- a - 0 | a +//- - b 1 | b +//- module \$_MUX_ (A, B, S, Y); input A, B, S; output Y; assign Y = S ? B : A; endmodule +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_MUX4_ (A, B, C, D, S, T, Y) +//- +//- A 4-input MUX gate. +//- +//- Truth table: A B C D S T | Y +//- -------------+--- +//- a - - - 0 0 | a +//- - b - - 1 0 | b +//- - - c - 0 1 | c +//- - - - d 1 1 | d +//- module \$_MUX4_ (A, B, C, D, S, T, Y); input A, B, C, D, S, T; output Y; @@ -86,6 +210,23 @@ assign Y = T ? (S ? D : C) : (S ? B : A); endmodule +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_MUX8_ (A, B, C, D, E, F, G, H, S, T, U, Y) +//- +//- An 8-input MUX gate. +//- +//- Truth table: A B C D E F G H S T U | Y +//- -----------------------+--- +//- a - - - - - - - 0 0 0 | a +//- - b - - - - - - 1 0 0 | b +//- - - c - - - - - 0 1 0 | c +//- - - - d - - - - 1 1 0 | d +//- - - - - e - - - 0 0 1 | e +//- - - - - - f - - 1 0 1 | f +//- - - - - - - g - 0 1 1 | g +//- - - - - - - - h 1 1 1 | h +//- module \$_MUX8_ (A, B, C, D, E, F, G, H, S, T, U, Y); input A, B, C, D, E, F, G, H, S, T, U; output Y; @@ -95,6 +236,31 @@ assign Y = U ? T ? (S ? H : G) : (S ? B : A); endmodule +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_MUX16_ (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V, Y) +//- +//- A 16-input MUX gate. +//- +//- Truth table: A B C D E F G H I J K L M N O P S T U V | Y +//- -----------------------------------------+--- +//- a - - - - - - - - - - - - - - - 0 0 0 0 | a +//- - b - - - - - - - - - - - - - - 1 0 0 0 | b +//- - - c - - - - - - - - - - - - - 0 1 0 0 | c +//- - - - d - - - - - - - - - - - - 1 1 0 0 | d +//- - - - - e - - - - - - - - - - - 0 0 1 0 | e +//- - - - - - f - - - - - - - - - - 1 0 1 0 | f +//- - - - - - - g - - - - - - - - - 0 1 1 0 | g +//- - - - - - - - h - - - - - - - - 1 1 1 0 | h +//- - - - - - - - - i - - - - - - - 0 0 0 1 | i +//- - - - - - - - - - j - - - - - - 1 0 0 1 | j +//- - - - - - - - - - - k - - - - - 0 1 0 1 | k +//- - - - - - - - - - - - l - - - - 1 1 0 1 | l +//- - - - - - - - - - - - - m - - - 0 0 1 1 | m +//- - - - - - - - - - - - - - n - - 1 0 1 1 | n +//- - - - - - - - - - - - - - - o - 0 1 1 1 | o +//- - - - - - - - - - - - - - - - p 1 1 1 1 | p +//- module \$_MUX16_ (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V, Y); input A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V; output Y; @@ -108,24 +274,108 @@ assign Y = V ? U ? T ? (S ? P : O) : (S ? B : A); endmodule +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_AOI3_ (A, B, C, Y) +//- +//- A 3-input And-Or-Invert gate. +//- +//- Truth table: A B C | Y +//- -------+--- +//- 0 0 0 | 1 +//- 0 0 1 | 0 +//- 0 1 0 | 1 +//- 0 1 1 | 0 +//- 1 0 0 | 1 +//- 1 0 1 | 0 +//- 1 1 0 | 0 +//- 1 1 1 | 0 +//- module \$_AOI3_ (A, B, C, Y); input A, B, C; output Y; assign Y = ~((A & B) | C); endmodule +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_OAI3_ (A, B, C, Y) +//- +//- A 3-input Or-And-Invert gate. +//- +//- Truth table: A B C | Y +//- -------+--- +//- 0 0 0 | 1 +//- 0 0 1 | 1 +//- 0 1 0 | 1 +//- 0 1 1 | 0 +//- 1 0 0 | 1 +//- 1 0 1 | 0 +//- 1 1 0 | 1 +//- 1 1 1 | 0 +//- module \$_OAI3_ (A, B, C, Y); input A, B, C; output Y; assign Y = ~((A | B) & C); endmodule +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_AOI4_ (A, B, C, Y) +//- +//- A 4-input And-Or-Invert gate. +//- +//- Truth table: A B C D | Y +//- ---------+--- +//- 0 0 0 0 | 1 +//- 0 0 0 1 | 1 +//- 0 0 1 0 | 1 +//- 0 0 1 1 | 0 +//- 0 1 0 0 | 1 +//- 0 1 0 1 | 1 +//- 0 1 1 0 | 1 +//- 0 1 1 1 | 0 +//- 1 0 0 0 | 1 +//- 1 0 0 1 | 1 +//- 1 0 1 0 | 1 +//- 1 0 1 1 | 0 +//- 1 1 0 0 | 0 +//- 1 1 0 1 | 0 +//- 1 1 1 0 | 0 +//- 1 1 1 1 | 0 +//- module \$_AOI4_ (A, B, C, D, Y); input A, B, C, D; output Y; assign Y = ~((A & B) | (C & D)); endmodule +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_OAI4_ (A, B, C, Y) +//- +//- A 4-input Or-And-Invert gate. +//- +//- Truth table: A B C D | Y +//- ---------+--- +//- 0 0 0 0 | 1 +//- 0 0 0 1 | 1 +//- 0 0 1 0 | 1 +//- 0 0 1 1 | 1 +//- 0 1 0 0 | 1 +//- 0 1 0 1 | 0 +//- 0 1 1 0 | 0 +//- 0 1 1 1 | 0 +//- 1 0 0 0 | 1 +//- 1 0 0 1 | 0 +//- 1 0 1 0 | 0 +//- 1 0 1 1 | 0 +//- 1 1 0 0 | 1 +//- 1 1 0 1 | 0 +//- 1 1 1 0 | 0 +//- 1 1 1 1 | 0 +//- module \$_OAI4_ (A, B, C, D, Y); input A, B, C, D; output Y;