aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/common
diff options
context:
space:
mode:
Diffstat (limited to 'techlibs/common')
-rw-r--r--techlibs/common/.gitignore2
-rw-r--r--techlibs/common/Makefile.inc16
-rw-r--r--techlibs/common/cellhelp.py34
-rw-r--r--techlibs/common/prep.cc156
-rw-r--r--techlibs/common/simcells.v571
-rw-r--r--techlibs/common/simlib.v9
6 files changed, 736 insertions, 52 deletions
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..236d6c551 100644
--- a/techlibs/common/Makefile.inc
+++ b/techlibs/common/Makefile.inc
@@ -1,8 +1,24 @@
ifneq ($(SMALL),1)
OBJS += techlibs/common/synth.o
+OBJS += techlibs/common/prep.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..5c44cb802
--- /dev/null
+++ b/techlibs/common/cellhelp.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+
+import fileinput
+import json
+
+current_help_msg = []
+current_module_code = []
+current_module_name = None
+current_module_signature = 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_signature = " ".join(line.replace("\\", "").replace(";", "").split()[1:])
+ current_module_code = []
+ elif not line.startswith("endmodule"):
+ line = " " + line
+ current_module_code.append(line.replace("\t", " "))
+ 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 = []
+
diff --git a/techlibs/common/prep.cc b/techlibs/common/prep.cc
new file mode 100644
index 000000000..ebd329746
--- /dev/null
+++ b/techlibs/common/prep.cc
@@ -0,0 +1,156 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/register.h"
+#include "kernel/celltypes.h"
+#include "kernel/rtlil.h"
+#include "kernel/log.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+bool check_label(bool &active, std::string run_from, std::string run_to, std::string label)
+{
+ if (!run_from.empty() && run_from == run_to) {
+ active = (label == run_from);
+ } else {
+ if (label == run_from)
+ active = true;
+ if (label == run_to)
+ active = false;
+ }
+ return active;
+}
+
+struct PrepPass : public Pass {
+ PrepPass() : Pass("prep", "generic synthesis script") { }
+ virtual void help()
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" prep [options]\n");
+ log("\n");
+ log("This command runs a conservative RTL synthesis. A typical application for this\n");
+ log("is the preparation stage of a verification flow. This command does not operate\n");
+ log("on partly selected designs.\n");
+ log("\n");
+ log(" -top <module>\n");
+ log(" use the specified module as top module (default='top')\n");
+ log("\n");
+ log(" -nordff\n");
+ log(" passed to 'memory_dff'. prohibits merging of FFs into memory read ports\n");
+ log("\n");
+ log(" -run <from_label>[:<to_label>]\n");
+ log(" only run the commands between the labels (see below). an empty\n");
+ log(" from label is synonymous to 'begin', and empty to label is\n");
+ log(" synonymous to the end of the command list.\n");
+ log("\n");
+ log("\n");
+ log("The following commands are executed by this synthesis command:\n");
+ log("\n");
+ log(" begin:\n");
+ log(" hierarchy -check [-top <top>]\n");
+ log("\n");
+ log(" prep:\n");
+ log(" proc\n");
+ log(" opt_clean\n");
+ log(" check\n");
+ log(" opt -keepdc\n");
+ log(" wreduce\n");
+ log(" memory_dff [-nordff]\n");
+ log(" opt_clean\n");
+ log(" memory_collect\n");
+ log(" opt -keepdc -fast\n");
+ log("\n");
+ log(" check:\n");
+ log(" stat\n");
+ log(" check\n");
+ log("\n");
+ }
+ virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+ {
+ std::string top_module, memory_opts;
+ std::string run_from, run_to;
+
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++)
+ {
+ if (args[argidx] == "-top" && argidx+1 < args.size()) {
+ top_module = args[++argidx];
+ continue;
+ }
+ if (args[argidx] == "-run" && argidx+1 < args.size()) {
+ size_t pos = args[argidx+1].find(':');
+ if (pos == std::string::npos) {
+ run_from = args[++argidx];
+ run_to = args[argidx];
+ } else {
+ run_from = args[++argidx].substr(0, pos);
+ run_to = args[argidx].substr(pos+1);
+ }
+ continue;
+ }
+ if (args[argidx] == "-nordff") {
+ memory_opts += " -nordff";
+ continue;
+ }
+ break;
+ }
+ extra_args(args, argidx, design);
+
+ if (!design->full_selection())
+ log_cmd_error("This comannd only operates on fully selected designs!\n");
+
+ bool active = run_from.empty();
+
+ log_header("Executing PREP pass.\n");
+ log_push();
+
+ if (check_label(active, run_from, run_to, "begin"))
+ {
+ if (top_module.empty())
+ Pass::call(design, stringf("hierarchy -check"));
+ else
+ Pass::call(design, stringf("hierarchy -check -top %s", top_module.c_str()));
+ }
+
+ if (check_label(active, run_from, run_to, "coarse"))
+ {
+ Pass::call(design, "proc");
+ Pass::call(design, "opt_clean");
+ Pass::call(design, "check");
+ Pass::call(design, "opt -keepdc");
+ Pass::call(design, "wreduce");
+ Pass::call(design, "memory_dff" + memory_opts);
+ Pass::call(design, "opt_clean");
+ Pass::call(design, "memory_collect");
+ Pass::call(design, "opt -keepdc -fast");
+ }
+
+ if (check_label(active, run_from, run_to, "check"))
+ {
+ Pass::call(design, "stat");
+ Pass::call(design, "check");
+ }
+
+ log_pop();
+ }
+} PrepPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/techlibs/common/simcells.v b/techlibs/common/simcells.v
index 3b7d55c6e..26de2d4fa 100644
--- a/techlibs/common/simcells.v
+++ b/techlibs/common/simcells.v
@@ -25,60 +25,184 @@
*
*/
-module \$_BUF_ (A, Y);
+// |---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
-module \$_NOT_ (A, Y);
+// |---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
-module \$_AND_ (A, B, Y);
+// |---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
-module \$_NAND_ (A, B, Y);
+// |---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
-module \$_OR_ (A, B, Y);
+// |---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
-module \$_NOR_ (A, B, Y);
+// |---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
-module \$_XOR_ (A, B, Y);
+// |---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
-module \$_XNOR_ (A, B, Y);
+// |---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,37 +274,145 @@ assign Y = V ? U ? T ? (S ? P : O) :
(S ? B : A);
endmodule
-module \$_AOI3_ (A, B, C, Y);
+// |---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
-module \$_OAI3_ (A, B, C, Y);
+// |---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
-module \$_AOI4_ (A, B, C, D, Y);
+// |---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
-module \$_OAI4_ (A, B, C, D, Y);
+// |---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;
assign Y = ~((A | B) & (C | D));
endmodule
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_TBUF_ (A, E, Y)
+//-
+//- A tri-state buffer.
+//-
+//- Truth table: A E | Y
+//- -----+---
+//- a 1 | a
+//- - 0 | z
+//-
module \$_TBUF_ (A, E, Y);
input A, E;
output Y;
assign Y = E ? A : 1'bz;
endmodule
-module \$_SR_NN_ (S, R, Q);
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_SR_NN_ (S, R, Q)
+//-
+//- A set-reset latch with negative polarity SET and RESET.
+//-
+//- Truth table: S R | Q
+//- -----+---
+//- 0 0 | x
+//- 0 1 | 1
+//- 1 0 | 0
+//- 1 1 | y
+//-
+module \$_SR_NN_ (S, R, Q);
input S, R;
output reg Q;
always @(negedge S, negedge R) begin
@@ -149,7 +423,20 @@ always @(negedge S, negedge R) begin
end
endmodule
-module \$_SR_NP_ (S, R, Q);
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_SR_NP_ (S, R, Q)
+//-
+//- A set-reset latch with negative polarity SET and positive polarioty RESET.
+//-
+//- Truth table: S R | Q
+//- -----+---
+//- 0 1 | x
+//- 0 0 | 1
+//- 1 1 | 0
+//- 1 0 | y
+//-
+module \$_SR_NP_ (S, R, Q);
input S, R;
output reg Q;
always @(negedge S, posedge R) begin
@@ -160,7 +447,20 @@ always @(negedge S, posedge R) begin
end
endmodule
-module \$_SR_PN_ (S, R, Q);
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_SR_PN_ (S, R, Q)
+//-
+//- A set-reset latch with positive polarity SET and negative polarioty RESET.
+//-
+//- Truth table: S R | Q
+//- -----+---
+//- 1 0 | x
+//- 1 1 | 1
+//- 0 0 | 0
+//- 0 1 | y
+//-
+module \$_SR_PN_ (S, R, Q);
input S, R;
output reg Q;
always @(posedge S, negedge R) begin
@@ -171,7 +471,20 @@ always @(posedge S, negedge R) begin
end
endmodule
-module \$_SR_PP_ (S, R, Q);
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_SR_PP_ (S, R, Q)
+//-
+//- A set-reset latch with positive polarity SET and RESET.
+//-
+//- Truth table: S R | Q
+//- -----+---
+//- 1 1 | x
+//- 1 0 | 1
+//- 0 1 | 0
+//- 0 0 | y
+//-
+module \$_SR_PP_ (S, R, Q);
input S, R;
output reg Q;
always @(posedge S, posedge R) begin
@@ -182,7 +495,18 @@ always @(posedge S, posedge R) begin
end
endmodule
-module \$_DFF_N_ (D, Q, C);
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DFF_N_ (D, C, Q)
+//-
+//- A negative edge D-type flip-flop.
+//-
+//- Truth table: D C | Q
+//- -----+---
+//- d \ | d
+//- - - | q
+//-
+module \$_DFF_N_ (D, C, Q);
input D, C;
output reg Q;
always @(negedge C) begin
@@ -190,7 +514,18 @@ always @(negedge C) begin
end
endmodule
-module \$_DFF_P_ (D, Q, C);
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DFF_P_ (D, C, Q)
+//-
+//- A positive edge D-type flip-flop.
+//-
+//- Truth table: D C | Q
+//- -----+---
+//- d / | d
+//- - - | q
+//-
+module \$_DFF_P_ (D, C, Q);
input D, C;
output reg Q;
always @(posedge C) begin
@@ -198,7 +533,18 @@ always @(posedge C) begin
end
endmodule
-module \$_DFFE_NN_ (D, Q, C, E);
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DFFE_NN_ (D, C, E, Q)
+//-
+//- A negative edge D-type flip-flop with negative polarity enable.
+//-
+//- Truth table: D C E | Q
+//- -------+---
+//- d \ 0 | d
+//- - - - | q
+//-
+module \$_DFFE_NN_ (D, C, E, Q);
input D, C, E;
output reg Q;
always @(negedge C) begin
@@ -206,7 +552,18 @@ always @(negedge C) begin
end
endmodule
-module \$_DFFE_NP_ (D, Q, C, E);
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DFFE_NP_ (D, C, E, Q)
+//-
+//- A negative edge D-type flip-flop with positive polarity enable.
+//-
+//- Truth table: D C E | Q
+//- -------+---
+//- d \ 1 | d
+//- - - - | q
+//-
+module \$_DFFE_NP_ (D, C, E, Q);
input D, C, E;
output reg Q;
always @(negedge C) begin
@@ -214,7 +571,18 @@ always @(negedge C) begin
end
endmodule
-module \$_DFFE_PN_ (D, Q, C, E);
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DFFE_PN_ (D, C, E, Q)
+//-
+//- A positive edge D-type flip-flop with negative polarity enable.
+//-
+//- Truth table: D C E | Q
+//- -------+---
+//- d / 0 | d
+//- - - - | q
+//-
+module \$_DFFE_PN_ (D, C, E, Q);
input D, C, E;
output reg Q;
always @(posedge C) begin
@@ -222,7 +590,18 @@ always @(posedge C) begin
end
endmodule
-module \$_DFFE_PP_ (D, Q, C, E);
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DFFE_PP_ (D, C, E, Q)
+//-
+//- A positive edge D-type flip-flop with positive polarity enable.
+//-
+//- Truth table: D C E | Q
+//- -------+---
+//- d / 1 | d
+//- - - - | q
+//-
+module \$_DFFE_PP_ (D, C, E, Q);
input D, C, E;
output reg Q;
always @(posedge C) begin
@@ -230,7 +609,19 @@ always @(posedge C) begin
end
endmodule
-module \$_DFF_NN0_ (D, Q, C, R);
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DFF_NN0_ (D, C, R, Q)
+//-
+//- A negative edge D-type flip-flop with negative polarity reset.
+//-
+//- Truth table: D C R | Q
+//- -------+---
+//- - - 0 | 0
+//- d \ - | d
+//- - - - | q
+//-
+module \$_DFF_NN0_ (D, C, R, Q);
input D, C, R;
output reg Q;
always @(negedge C or negedge R) begin
@@ -241,7 +632,19 @@ always @(negedge C or negedge R) begin
end
endmodule
-module \$_DFF_NN1_ (D, Q, C, R);
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DFF_NN1_ (D, C, R, Q)
+//-
+//- A negative edge D-type flip-flop with negative polarity set.
+//-
+//- Truth table: D C R | Q
+//- -------+---
+//- - - 0 | 1
+//- d \ - | d
+//- - - - | q
+//-
+module \$_DFF_NN1_ (D, C, R, Q);
input D, C, R;
output reg Q;
always @(negedge C or negedge R) begin
@@ -252,7 +655,19 @@ always @(negedge C or negedge R) begin
end
endmodule
-module \$_DFF_NP0_ (D, Q, C, R);
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DFF_NP0_ (D, C, R, Q)
+//-
+//- A negative edge D-type flip-flop with positive polarity reset.
+//-
+//- Truth table: D C R | Q
+//- -------+---
+//- - - 1 | 0
+//- d \ - | d
+//- - - - | q
+//-
+module \$_DFF_NP0_ (D, C, R, Q);
input D, C, R;
output reg Q;
always @(negedge C or posedge R) begin
@@ -263,7 +678,19 @@ always @(negedge C or posedge R) begin
end
endmodule
-module \$_DFF_NP1_ (D, Q, C, R);
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DFF_NP1_ (D, C, R, Q)
+//-
+//- A negative edge D-type flip-flop with positive polarity set.
+//-
+//- Truth table: D C R | Q
+//- -------+---
+//- - - 1 | 1
+//- d \ - | d
+//- - - - | q
+//-
+module \$_DFF_NP1_ (D, C, R, Q);
input D, C, R;
output reg Q;
always @(negedge C or posedge R) begin
@@ -274,7 +701,19 @@ always @(negedge C or posedge R) begin
end
endmodule
-module \$_DFF_PN0_ (D, Q, C, R);
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DFF_PN0_ (D, C, R, Q)
+//-
+//- A positive edge D-type flip-flop with negative polarity reset.
+//-
+//- Truth table: D C R | Q
+//- -------+---
+//- - - 0 | 0
+//- d / - | d
+//- - - - | q
+//-
+module \$_DFF_PN0_ (D, C, R, Q);
input D, C, R;
output reg Q;
always @(posedge C or negedge R) begin
@@ -285,7 +724,19 @@ always @(posedge C or negedge R) begin
end
endmodule
-module \$_DFF_PN1_ (D, Q, C, R);
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DFF_PN1_ (D, C, R, Q)
+//-
+//- A positive edge D-type flip-flop with negative polarity set.
+//-
+//- Truth table: D C R | Q
+//- -------+---
+//- - - 0 | 1
+//- d / - | d
+//- - - - | q
+//-
+module \$_DFF_PN1_ (D, C, R, Q);
input D, C, R;
output reg Q;
always @(posedge C or negedge R) begin
@@ -296,7 +747,19 @@ always @(posedge C or negedge R) begin
end
endmodule
-module \$_DFF_PP0_ (D, Q, C, R);
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DFF_PP0_ (D, C, R, Q)
+//-
+//- A positive edge D-type flip-flop with positive polarity reset.
+//-
+//- Truth table: D C R | Q
+//- -------+---
+//- - - 1 | 0
+//- d / - | d
+//- - - - | q
+//-
+module \$_DFF_PP0_ (D, C, R, Q);
input D, C, R;
output reg Q;
always @(posedge C or posedge R) begin
@@ -307,7 +770,19 @@ always @(posedge C or posedge R) begin
end
endmodule
-module \$_DFF_PP1_ (D, Q, C, R);
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DFF_PP1_ (D, C, R, Q)
+//-
+//- A positive edge D-type flip-flop with positive polarity set.
+//-
+//- Truth table: D C R | Q
+//- -------+---
+//- - - 1 | 1
+//- d / - | d
+//- - - - | q
+//-
+module \$_DFF_PP1_ (D, C, R, Q);
input D, C, R;
output reg Q;
always @(posedge C or posedge R) begin
@@ -318,7 +793,7 @@ always @(posedge C or posedge R) begin
end
endmodule
-module \$_DFFSR_NNN_ (C, S, R, D, Q);
+module \$_DFFSR_NNN_ (C, S, R, D, Q);
input C, S, R, D;
output reg Q;
always @(negedge C, negedge S, negedge R) begin
@@ -331,7 +806,7 @@ always @(negedge C, negedge S, negedge R) begin
end
endmodule
-module \$_DFFSR_NNP_ (C, S, R, D, Q);
+module \$_DFFSR_NNP_ (C, S, R, D, Q);
input C, S, R, D;
output reg Q;
always @(negedge C, negedge S, posedge R) begin
@@ -344,7 +819,7 @@ always @(negedge C, negedge S, posedge R) begin
end
endmodule
-module \$_DFFSR_NPN_ (C, S, R, D, Q);
+module \$_DFFSR_NPN_ (C, S, R, D, Q);
input C, S, R, D;
output reg Q;
always @(negedge C, posedge S, negedge R) begin
@@ -357,7 +832,7 @@ always @(negedge C, posedge S, negedge R) begin
end
endmodule
-module \$_DFFSR_NPP_ (C, S, R, D, Q);
+module \$_DFFSR_NPP_ (C, S, R, D, Q);
input C, S, R, D;
output reg Q;
always @(negedge C, posedge S, posedge R) begin
@@ -370,7 +845,7 @@ always @(negedge C, posedge S, posedge R) begin
end
endmodule
-module \$_DFFSR_PNN_ (C, S, R, D, Q);
+module \$_DFFSR_PNN_ (C, S, R, D, Q);
input C, S, R, D;
output reg Q;
always @(posedge C, negedge S, negedge R) begin
@@ -383,7 +858,7 @@ always @(posedge C, negedge S, negedge R) begin
end
endmodule
-module \$_DFFSR_PNP_ (C, S, R, D, Q);
+module \$_DFFSR_PNP_ (C, S, R, D, Q);
input C, S, R, D;
output reg Q;
always @(posedge C, negedge S, posedge R) begin
@@ -396,7 +871,7 @@ always @(posedge C, negedge S, posedge R) begin
end
endmodule
-module \$_DFFSR_PPN_ (C, S, R, D, Q);
+module \$_DFFSR_PPN_ (C, S, R, D, Q);
input C, S, R, D;
output reg Q;
always @(posedge C, posedge S, negedge R) begin
@@ -409,7 +884,7 @@ always @(posedge C, posedge S, negedge R) begin
end
endmodule
-module \$_DFFSR_PPP_ (C, S, R, D, Q);
+module \$_DFFSR_PPP_ (C, S, R, D, Q);
input C, S, R, D;
output reg Q;
always @(posedge C, posedge S, posedge R) begin
@@ -422,7 +897,7 @@ always @(posedge C, posedge S, posedge R) begin
end
endmodule
-module \$_DLATCH_N_ (E, D, Q);
+module \$_DLATCH_N_ (E, D, Q);
input E, D;
output reg Q;
always @* begin
@@ -431,7 +906,7 @@ always @* begin
end
endmodule
-module \$_DLATCH_P_ (E, D, Q);
+module \$_DLATCH_P_ (E, D, Q);
input E, D;
output reg Q;
always @* begin
@@ -440,7 +915,7 @@ always @* begin
end
endmodule
-module \$_DLATCHSR_NNN_ (E, S, R, D, Q);
+module \$_DLATCHSR_NNN_ (E, S, R, D, Q);
input E, S, R, D;
output reg Q;
always @* begin
@@ -453,7 +928,7 @@ always @* begin
end
endmodule
-module \$_DLATCHSR_NNP_ (E, S, R, D, Q);
+module \$_DLATCHSR_NNP_ (E, S, R, D, Q);
input E, S, R, D;
output reg Q;
always @* begin
@@ -466,7 +941,7 @@ always @* begin
end
endmodule
-module \$_DLATCHSR_NPN_ (E, S, R, D, Q);
+module \$_DLATCHSR_NPN_ (E, S, R, D, Q);
input E, S, R, D;
output reg Q;
always @* begin
@@ -479,7 +954,7 @@ always @* begin
end
endmodule
-module \$_DLATCHSR_NPP_ (E, S, R, D, Q);
+module \$_DLATCHSR_NPP_ (E, S, R, D, Q);
input E, S, R, D;
output reg Q;
always @* begin
@@ -492,7 +967,7 @@ always @* begin
end
endmodule
-module \$_DLATCHSR_PNN_ (E, S, R, D, Q);
+module \$_DLATCHSR_PNN_ (E, S, R, D, Q);
input E, S, R, D;
output reg Q;
always @* begin
@@ -505,7 +980,7 @@ always @* begin
end
endmodule
-module \$_DLATCHSR_PNP_ (E, S, R, D, Q);
+module \$_DLATCHSR_PNP_ (E, S, R, D, Q);
input E, S, R, D;
output reg Q;
always @* begin
@@ -518,7 +993,7 @@ always @* begin
end
endmodule
-module \$_DLATCHSR_PPN_ (E, S, R, D, Q);
+module \$_DLATCHSR_PPN_ (E, S, R, D, Q);
input E, S, R, D;
output reg Q;
always @* begin
@@ -531,7 +1006,7 @@ always @* begin
end
endmodule
-module \$_DLATCHSR_PPP_ (E, S, R, D, Q);
+module \$_DLATCHSR_PPP_ (E, S, R, D, Q);
input E, S, R, D;
output reg Q;
always @* begin
diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v
index 2a56b3a1e..a2dc466d4 100644
--- a/techlibs/common/simlib.v
+++ b/techlibs/common/simlib.v
@@ -1494,7 +1494,7 @@ endmodule
// --------------------------------------------------------
`ifndef SIMLIB_NOMEM
-module \$memrd (CLK, ADDR, DATA);
+module \$memrd (CLK, EN, ADDR, DATA);
parameter MEMID = "";
parameter ABITS = 8;
@@ -1504,7 +1504,7 @@ parameter CLK_ENABLE = 0;
parameter CLK_POLARITY = 0;
parameter TRANSPARENT = 0;
-input CLK;
+input CLK, EN;
input [ABITS-1:0] ADDR;
output [WIDTH-1:0] DATA;
@@ -1568,7 +1568,7 @@ endmodule
// --------------------------------------------------------
-module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA);
+module \$mem (RD_CLK, RD_EN, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA);
parameter MEMID = "";
parameter signed SIZE = 4;
@@ -1587,6 +1587,7 @@ parameter WR_CLK_ENABLE = 1'b1;
parameter WR_CLK_POLARITY = 1'b1;
input [RD_PORTS-1:0] RD_CLK;
+input [RD_PORTS-1:0] RD_EN;
input [RD_PORTS*ABITS-1:0] RD_ADDR;
output reg [RD_PORTS*WIDTH-1:0] RD_DATA;
@@ -1626,7 +1627,7 @@ always @(RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA) begin
#`SIMLIB_MEMDELAY;
`endif
for (i = 0; i < RD_PORTS; i = i+1) begin
- if ((!RD_TRANSPARENT[i] && RD_CLK_ENABLE[i]) && port_active(RD_CLK_ENABLE[i], RD_CLK_POLARITY[i], LAST_RD_CLK[i], RD_CLK[i])) begin
+ if (!RD_TRANSPARENT[i] && RD_CLK_ENABLE[i] && RD_EN[i] && port_active(RD_CLK_ENABLE[i], RD_CLK_POLARITY[i], LAST_RD_CLK[i], RD_CLK[i])) begin
// $display("Read from %s: addr=%b data=%b", MEMID, RD_ADDR[i*ABITS +: ABITS], memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET]);
RD_DATA[i*WIDTH +: WIDTH] <= memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET];
end