diff options
Diffstat (limited to 'techlibs/common')
-rw-r--r-- | techlibs/common/.gitignore | 2 | ||||
-rw-r--r-- | techlibs/common/Makefile.inc | 19 | ||||
-rw-r--r-- | techlibs/common/blackbox.sed | 5 | ||||
-rw-r--r-- | techlibs/common/cellhelp.py | 34 | ||||
-rw-r--r-- | techlibs/common/prep.cc | 170 | ||||
-rw-r--r-- | techlibs/common/simcells.v | 850 | ||||
-rw-r--r-- | techlibs/common/simlib.v | 210 | ||||
-rw-r--r-- | techlibs/common/synth.cc | 192 | ||||
-rw-r--r-- | techlibs/common/techmap.v | 26 |
9 files changed, 1329 insertions, 179 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 d2ce61cf6..236d6c551 100644 --- a/techlibs/common/Makefile.inc +++ b/techlibs/common/Makefile.inc @@ -1,18 +1,27 @@ ifneq ($(SMALL),1) OBJS += techlibs/common/synth.o +OBJS += techlibs/common/prep.o endif -EXTRA_TARGETS += techlibs/common/blackbox.v +GENFILES += techlibs/common/simlib_help.inc +GENFILES += techlibs/common/simcells_help.inc -techlibs/common/blackbox.v: techlibs/common/blackbox.sed techlibs/common/simlib.v techlibs/common/simcells.v - $(P) cat techlibs/common/simlib.v techlibs/common/simcells.v | $(SED) -rf techlibs/common/blackbox.sed > techlibs/common/blackbox.v.new - $(Q) mv techlibs/common/blackbox.v.new techlibs/common/blackbox.v +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)) -$(eval $(call add_share_file,share,techlibs/common/blackbox.v)) $(eval $(call add_share_file,share,techlibs/common/pmux2mux.v)) $(eval $(call add_share_file,share,techlibs/common/adff2dff.v)) $(eval $(call add_share_file,share,techlibs/common/cells.lib)) diff --git a/techlibs/common/blackbox.sed b/techlibs/common/blackbox.sed deleted file mode 100644 index db8900344..000000000 --- a/techlibs/common/blackbox.sed +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sed -r -/^(wire|assign|reg|event|integer|localparam|\/\/|[\/ ]\*| *$|`)/ d; -/^(genvar|generate|always|initial|task|function)/,/^end/ d; -/^endmodule/ s/$/\n/; -s/ reg / /; 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..9f8f6b313 --- /dev/null +++ b/techlibs/common/prep.cc @@ -0,0 +1,170 @@ +/* + * 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 + +struct PrepPass : public ScriptPass +{ + PrepPass() : ScriptPass("prep", "generic synthesis script") { } + + virtual void help() YS_OVERRIDE + { + // |---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(" -flatten\n"); + log(" flatten the design before synthesis. this will pass '-auto-top' to\n"); + log(" 'hierarchy' if no top module is specified.\n"); + log("\n"); + log(" -ifx\n"); + log(" passed to 'proc'. uses verilog simulation behavior for verilog if/case\n"); + log(" undef handling. this also prevents 'wreduce' from being run.\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"); + help_script(); + log("\n"); + } + + string top_module, fsm_opts, memory_opts; + bool flatten, ifxmode; + + virtual void clear_flags() YS_OVERRIDE + { + top_module.clear(); + memory_opts.clear(); + flatten = false; + ifxmode = false; + } + + virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + { + 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] == "-flatten") { + flatten = true; + continue; + } + if (args[argidx] == "-ifx") { + ifxmode = true; + 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"); + + log_header(design, "Executing PREP pass.\n"); + log_push(); + + run_script(design, run_from, run_to); + + log_pop(); + } + + virtual void script() YS_OVERRIDE + { + + if (check_label("begin")) + { + if (help_mode) { + run("hierarchy -check [-top <top>]"); + } else { + if (top_module.empty()) { + if (flatten) + run("hierarchy -check -auto-top"); + else + run("hierarchy -check"); + } else + run(stringf("hierarchy -check -top %s", top_module.c_str())); + } + } + + if (check_label("coarse")) + { + run(ifxmode ? "proc -ifx" : "proc"); + if (help_mode || flatten) + run("flatten", "(if -flatten)"); + run("opt_expr -keepdc"); + run("opt_clean"); + run("check"); + run("opt -keepdc"); + if (!ifxmode) + run("wreduce"); + run("memory_dff" + (help_mode ? " [-nordff]" : memory_opts)); + run("opt_clean"); + run("memory_collect"); + run("opt -keepdc -fast"); + } + + if (check_label("check")) + { + run("stat"); + run("check"); + } + } +} PrepPass; + +PRIVATE_NAMESPACE_END diff --git a/techlibs/common/simcells.v b/techlibs/common/simcells.v index eb62d7830..c4f170a3c 100644 --- a/techlibs/common/simcells.v +++ b/techlibs/common/simcells.v @@ -2,11 +2,11 @@ * 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 @@ -19,91 +19,400 @@ * * The internal logic cell simulation library. * - * This verilog library contains simple simulation models for the internal + * This Verilog library contains simple simulation models for the internal * logic cells ($_NOT_ , $_AND_ , ...) that are generated by the default technology * mapper (see "techmap.v" in this directory) and expected by the "abc" pass. * */ -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 -module \$_AOI3_ (A, B, C, Y); +// |---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; +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; +assign Y = U ? T ? (S ? H : G) : + (S ? F : E) : + T ? (S ? D : C) : + (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; +assign Y = V ? U ? T ? (S ? P : O) : + (S ? N : M) : + T ? (S ? L : K) : + (S ? J : I) : + U ? T ? (S ? H : G) : + (S ? F : E) : + T ? (S ? D : C) : + (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 -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 -module \$_SR_NN_ (S, R, Q); +// |---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 + +// |---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 @@ -114,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 @@ -125,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 @@ -136,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 @@ -147,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 @@ -155,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 @@ -163,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 @@ -171,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 @@ -179,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 @@ -187,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 @@ -195,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 @@ -206,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 @@ -217,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 @@ -228,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 @@ -239,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 @@ -250,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 @@ -261,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 @@ -272,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 @@ -283,7 +793,20 @@ always @(posedge C or posedge R) begin end endmodule -module \$_DFFSR_NNN_ (C, S, R, D, Q); +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSR_NNN_ (C, S, R, D, Q) +//- +//- A negative edge D-type flip-flop with negative polarity set and reset. +//- +//- Truth table: C S R D | Q +//- ---------+--- +//- - - 0 - | 0 +//- - 0 - - | 1 +//- \ - - d | 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 @@ -296,7 +819,21 @@ always @(negedge C, negedge S, negedge R) begin end endmodule -module \$_DFFSR_NNP_ (C, S, R, D, Q); +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSR_NNP_ (C, S, R, D, Q) +//- +//- A negative edge D-type flip-flop with negative polarity set and positive +//- polarity reset. +//- +//- Truth table: C S R D | Q +//- ---------+--- +//- - - 1 - | 0 +//- - 0 - - | 1 +//- \ - - d | 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 @@ -309,7 +846,21 @@ always @(negedge C, negedge S, posedge R) begin end endmodule -module \$_DFFSR_NPN_ (C, S, R, D, Q); +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSR_NPN_ (C, S, R, D, Q) +//- +//- A negative edge D-type flip-flop with positive polarity set and negative +//- polarity reset. +//- +//- Truth table: C S R D | Q +//- ---------+--- +//- - - 0 - | 0 +//- - 1 - - | 1 +//- \ - - d | 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 @@ -322,7 +873,20 @@ always @(negedge C, posedge S, negedge R) begin end endmodule -module \$_DFFSR_NPP_ (C, S, R, D, Q); +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSR_NPP_ (C, S, R, D, Q) +//- +//- A negative edge D-type flip-flop with positive polarity set and reset. +//- +//- Truth table: C S R D | Q +//- ---------+--- +//- - - 1 - | 0 +//- - 1 - - | 1 +//- \ - - d | 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 @@ -335,7 +899,20 @@ always @(negedge C, posedge S, posedge R) begin end endmodule -module \$_DFFSR_PNN_ (C, S, R, D, Q); +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSR_PNN_ (C, S, R, D, Q) +//- +//- A positive edge D-type flip-flop with negative polarity set and reset. +//- +//- Truth table: C S R D | Q +//- ---------+--- +//- - - 0 - | 0 +//- - 0 - - | 1 +//- / - - d | 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 @@ -348,7 +925,21 @@ always @(posedge C, negedge S, negedge R) begin end endmodule -module \$_DFFSR_PNP_ (C, S, R, D, Q); +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSR_PNP_ (C, S, R, D, Q) +//- +//- A positive edge D-type flip-flop with negative polarity set and positive +//- polarity reset. +//- +//- Truth table: C S R D | Q +//- ---------+--- +//- - - 1 - | 0 +//- - 0 - - | 1 +//- / - - d | 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 @@ -361,7 +952,21 @@ always @(posedge C, negedge S, posedge R) begin end endmodule -module \$_DFFSR_PPN_ (C, S, R, D, Q); +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSR_PPN_ (C, S, R, D, Q) +//- +//- A positive edge D-type flip-flop with positive polarity set and negative +//- polarity reset. +//- +//- Truth table: C S R D | Q +//- ---------+--- +//- - - 0 - | 0 +//- - 1 - - | 1 +//- / - - d | 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 @@ -374,7 +979,20 @@ always @(posedge C, posedge S, negedge R) begin end endmodule -module \$_DFFSR_PPP_ (C, S, R, D, Q); +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DFFSR_PPP_ (C, S, R, D, Q) +//- +//- A positive edge D-type flip-flop with positive polarity set and reset. +//- +//- Truth table: C S R D | Q +//- ---------+--- +//- - - 1 - | 0 +//- - 1 - - | 1 +//- / - - d | 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 @@ -387,7 +1005,18 @@ always @(posedge C, posedge S, posedge R) begin end endmodule -module \$_DLATCH_N_ (E, D, Q); +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DLATCH_N_ (E, D, Q) +//- +//- A negative enable D-type latch. +//- +//- Truth table: E D | Q +//- -----+--- +//- 0 d | d +//- - - | q +//- +module \$_DLATCH_N_ (E, D, Q); input E, D; output reg Q; always @* begin @@ -396,7 +1025,18 @@ always @* begin end endmodule -module \$_DLATCH_P_ (E, D, Q); +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DLATCH_P_ (E, D, Q) +//- +//- A positive enable D-type latch. +//- +//- Truth table: E D | Q +//- -----+--- +//- 1 d | d +//- - - | q +//- +module \$_DLATCH_P_ (E, D, Q); input E, D; output reg Q; always @* begin @@ -405,7 +1045,20 @@ always @* begin end endmodule -module \$_DLATCHSR_NNN_ (E, S, R, D, Q); +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DLATCHSR_NNN_ (E, S, R, D, Q) +//- +//- A negative enable D-type latch with negative polarity set and reset. +//- +//- Truth table: E S R D | Q +//- ---------+--- +//- - - 0 - | 0 +//- - 0 - - | 1 +//- 0 - - d | d +//- - - - - | q +//- +module \$_DLATCHSR_NNN_ (E, S, R, D, Q); input E, S, R, D; output reg Q; always @* begin @@ -418,7 +1071,21 @@ always @* begin end endmodule -module \$_DLATCHSR_NNP_ (E, S, R, D, Q); +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DLATCHSR_NNP_ (E, S, R, D, Q) +//- +//- A negative enable D-type latch with negative polarity set and positive polarity +//- reset. +//- +//- Truth table: E S R D | Q +//- ---------+--- +//- - - 1 - | 0 +//- - 0 - - | 1 +//- 0 - - d | d +//- - - - - | q +//- +module \$_DLATCHSR_NNP_ (E, S, R, D, Q); input E, S, R, D; output reg Q; always @* begin @@ -431,7 +1098,21 @@ always @* begin end endmodule -module \$_DLATCHSR_NPN_ (E, S, R, D, Q); +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DLATCHSR_NPN_ (E, S, R, D, Q) +//- +//- A negative enable D-type latch with positive polarity set and negative polarity +//- reset. +//- +//- Truth table: E S R D | Q +//- ---------+--- +//- - - 0 - | 0 +//- - 1 - - | 1 +//- 0 - - d | d +//- - - - - | q +//- +module \$_DLATCHSR_NPN_ (E, S, R, D, Q); input E, S, R, D; output reg Q; always @* begin @@ -444,7 +1125,20 @@ always @* begin end endmodule -module \$_DLATCHSR_NPP_ (E, S, R, D, Q); +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DLATCHSR_NPP_ (E, S, R, D, Q) +//- +//- A negative enable D-type latch with positive polarity set and reset. +//- +//- Truth table: E S R D | Q +//- ---------+--- +//- - - 1 - | 0 +//- - 1 - - | 1 +//- 0 - - d | d +//- - - - - | q +//- +module \$_DLATCHSR_NPP_ (E, S, R, D, Q); input E, S, R, D; output reg Q; always @* begin @@ -457,7 +1151,20 @@ always @* begin end endmodule -module \$_DLATCHSR_PNN_ (E, S, R, D, Q); +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DLATCHSR_PNN_ (E, S, R, D, Q) +//- +//- A positive enable D-type latch with negative polarity set and reset. +//- +//- Truth table: E S R D | Q +//- ---------+--- +//- - - 0 - | 0 +//- - 0 - - | 1 +//- 1 - - d | d +//- - - - - | q +//- +module \$_DLATCHSR_PNN_ (E, S, R, D, Q); input E, S, R, D; output reg Q; always @* begin @@ -470,7 +1177,21 @@ always @* begin end endmodule -module \$_DLATCHSR_PNP_ (E, S, R, D, Q); +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DLATCHSR_PNP_ (E, S, R, D, Q) +//- +//- A positive enable D-type latch with negative polarity set and positive polarity +//- reset. +//- +//- Truth table: E S R D | Q +//- ---------+--- +//- - - 1 - | 0 +//- - 0 - - | 1 +//- 1 - - d | d +//- - - - - | q +//- +module \$_DLATCHSR_PNP_ (E, S, R, D, Q); input E, S, R, D; output reg Q; always @* begin @@ -483,7 +1204,21 @@ always @* begin end endmodule -module \$_DLATCHSR_PPN_ (E, S, R, D, Q); +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DLATCHSR_PPN_ (E, S, R, D, Q) +//- +//- A positive enable D-type latch with positive polarity set and negative polarity +//- reset. +//- +//- Truth table: E S R D | Q +//- ---------+--- +//- - - 0 - | 0 +//- - 1 - - | 1 +//- 1 - - d | d +//- - - - - | q +//- +module \$_DLATCHSR_PPN_ (E, S, R, D, Q); input E, S, R, D; output reg Q; always @* begin @@ -496,7 +1231,20 @@ always @* begin end endmodule -module \$_DLATCHSR_PPP_ (E, S, R, D, Q); +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $_DLATCHSR_PPP_ (E, S, R, D, Q) +//- +//- A positive enable D-type latch with positive polarity set and reset. +//- +//- Truth table: E S R D | Q +//- ---------+--- +//- - - 1 - | 0 +//- - 1 - - | 1 +//- 1 - - d | 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 d0feadd81..342555024 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -2,11 +2,11 @@ * 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 @@ -19,7 +19,7 @@ * * The Simulation Library. * - * This verilog library contains simple simulation models for the internal + * This Verilog library contains simple simulation models for the internal * cells ($not, ...) generated by the frontends and used in most passes. * * This library can be used to verify the internal netlists as generated @@ -33,6 +33,12 @@ // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $not (A, Y) +//- +//- A bit-wise inverter. This corresponds to the Verilog unary prefix '~' operator. +//- module \$not (A, Y); parameter A_SIGNED = 0; @@ -55,6 +61,12 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $pos (A, Y) +//- +//- A buffer. This corresponds to the Verilog unary prefix '+' operator. +//- module \$pos (A, Y); parameter A_SIGNED = 0; @@ -76,6 +88,12 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $neg (A, Y) +//- +//- An arithmetic inverter. This corresponds to the Verilog unary prefix '-' operator. +//- module \$neg (A, Y); parameter A_SIGNED = 0; @@ -97,6 +115,12 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $and (A, B, Y) +//- +//- A bit-wise AND. This corresponds to the Verilog '&' operator. +//- module \$and (A, B, Y); parameter A_SIGNED = 0; @@ -121,6 +145,12 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $or (A, B, Y) +//- +//- A bit-wise OR. This corresponds to the Verilog '|' operator. +//- module \$or (A, B, Y); parameter A_SIGNED = 0; @@ -145,6 +175,12 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $xor (A, B, Y) +//- +//- A bit-wise XOR. This corresponds to the Verilog '^' operator. +//- module \$xor (A, B, Y); parameter A_SIGNED = 0; @@ -169,6 +205,12 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $xnor (A, B, Y) +//- +//- A bit-wise XNOR. This corresponds to the Verilog '~^' operator. +//- module \$xnor (A, B, Y); parameter A_SIGNED = 0; @@ -193,6 +235,12 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $reduce_and (A, B, Y) +//- +//- An AND reduction. This corresponds to the Verilog unary prefix '&' operator. +//- module \$reduce_and (A, Y); parameter A_SIGNED = 0; @@ -214,6 +262,12 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $reduce_or (A, B, Y) +//- +//- An OR reduction. This corresponds to the Verilog unary prefix '|' operator. +//- module \$reduce_or (A, Y); parameter A_SIGNED = 0; @@ -235,6 +289,12 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $reduce_xor (A, B, Y) +//- +//- A XOR reduction. This corresponds to the Verilog unary prefix '^' operator. +//- module \$reduce_xor (A, Y); parameter A_SIGNED = 0; @@ -256,6 +316,12 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $reduce_xnor (A, B, Y) +//- +//- A XNOR reduction. This corresponds to the Verilog unary prefix '~^' operator. +//- module \$reduce_xnor (A, Y); parameter A_SIGNED = 0; @@ -277,6 +343,13 @@ endmodule // -------------------------------------------------------- +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $reduce_bool (A, B, Y) +//- +//- An OR reduction. This cell type is used instead of $reduce_or when a signal is +//- implicitly converted to a boolean signal, e.g. for operands of '&&' and '||'. +//- module \$reduce_bool (A, Y); parameter A_SIGNED = 0; @@ -1156,6 +1229,48 @@ endmodule `endif // -------------------------------------------------------- +module \$sop (A, Y); + +parameter WIDTH = 0; +parameter DEPTH = 0; +parameter TABLE = 0; + +input [WIDTH-1:0] A; +output reg Y; + +integer i, j; +reg match; + +always @* begin + Y = 0; + for (i = 0; i < DEPTH; i=i+1) begin + match = 1; + for (j = 0; j < WIDTH; j=j+1) begin + if (TABLE[2*WIDTH*i + 2*j + 0] && A[j]) match = 0; + if (TABLE[2*WIDTH*i + 2*j + 1] && !A[j]) match = 0; + end + if (match) Y = 1; + end +end + +endmodule + +// -------------------------------------------------------- + +module \$tribuf (A, EN, Y); + +parameter WIDTH = 0; + +input [WIDTH-1:0] A; +input EN; +output [WIDTH-1:0] Y; + +assign Y = EN ? A : 'bz; + +endmodule + +// -------------------------------------------------------- + module \$assert (A, EN); input A, EN; @@ -1163,7 +1278,24 @@ input A, EN; `ifndef SIMLIB_NOCHECKS always @* begin if (A !== 1'b1 && EN === 1'b1) begin - $display("Assertation failed!"); + $display("Assertion %m failed!"); + $stop; + end +end +`endif + +endmodule + +// -------------------------------------------------------- + +module \$assume (A, EN); + +input A, EN; + +`ifndef SIMLIB_NOCHECKS +always @* begin + if (A !== 1'b1 && EN === 1'b1) begin + $display("Assumption %m failed!"); $stop; end end @@ -1208,7 +1340,7 @@ wire [WIDTH-1:0] pos_clr = CLR_POLARITY ? CLR : ~CLR; genvar i; generate - for (i = 0; i < WIDTH; i = i+1) begin:bit + for (i = 0; i < WIDTH; i = i+1) begin:bitslices always @(posedge pos_set[i], posedge pos_clr[i]) if (pos_clr[i]) Q[i] <= 0; @@ -1277,7 +1409,7 @@ wire [WIDTH-1:0] pos_clr = CLR_POLARITY ? CLR : ~CLR; genvar i; generate - for (i = 0; i < WIDTH; i = i+1) begin:bit + for (i = 0; i < WIDTH; i = i+1) begin:bitslices always @(posedge pos_set[i], posedge pos_clr[i], posedge pos_clk) if (pos_clr[i]) Q[i] <= 0; @@ -1328,7 +1460,7 @@ output reg [WIDTH-1:0] Q; always @* begin if (EN == EN_POLARITY) - Q <= D; + Q = D; end endmodule @@ -1353,14 +1485,14 @@ wire [WIDTH-1:0] pos_clr = CLR_POLARITY ? CLR : ~CLR; genvar i; generate - for (i = 0; i < WIDTH; i = i+1) begin:bit + for (i = 0; i < WIDTH; i = i+1) begin:bitslices always @* if (pos_clr[i]) - Q[i] <= 0; + Q[i] = 0; else if (pos_set[i]) - Q[i] <= 1; + Q[i] = 1; else if (pos_en) - Q[i] <= D[i]; + Q[i] = D[i]; end endgenerate @@ -1463,7 +1595,7 @@ endmodule // -------------------------------------------------------- `ifndef SIMLIB_NOMEM -module \$memrd (CLK, ADDR, DATA); +module \$memrd (CLK, EN, ADDR, DATA); parameter MEMID = ""; parameter ABITS = 8; @@ -1473,7 +1605,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; @@ -1514,24 +1646,49 @@ endmodule // -------------------------------------------------------- -module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA); +module \$meminit (ADDR, DATA); parameter MEMID = ""; -parameter SIZE = 256; -parameter OFFSET = 0; parameter ABITS = 8; parameter WIDTH = 8; +parameter WORDS = 1; + +parameter PRIORITY = 0; + +input [ABITS-1:0] ADDR; +input [WORDS*WIDTH-1:0] DATA; -parameter RD_PORTS = 1; +initial begin + if (MEMID != "") begin + $display("ERROR: Found non-simulatable instance of $meminit!"); + $finish; + end +end + +endmodule + +// -------------------------------------------------------- + +module \$mem (RD_CLK, RD_EN, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA); + +parameter MEMID = ""; +parameter signed SIZE = 4; +parameter signed OFFSET = 0; +parameter signed ABITS = 2; +parameter signed WIDTH = 8; +parameter signed INIT = 1'bx; + +parameter signed RD_PORTS = 1; parameter RD_CLK_ENABLE = 1'b1; parameter RD_CLK_POLARITY = 1'b1; parameter RD_TRANSPARENT = 1'b1; -parameter WR_PORTS = 1; +parameter signed WR_PORTS = 1; 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; @@ -1561,25 +1718,36 @@ function port_active; end endfunction +initial begin + for (i = 0; i < SIZE; i = i+1) + memory[i] = INIT >>> (i*WIDTH); +end + always @(RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA) begin `ifdef SIMLIB_MEMDELAY #`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])) + 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 end for (i = 0; i < WR_PORTS; i = i+1) begin if (port_active(WR_CLK_ENABLE[i], WR_CLK_POLARITY[i], LAST_WR_CLK[i], WR_CLK[i])) for (j = 0; j < WIDTH; j = j+1) - if (WR_EN[i*WIDTH+j]) + if (WR_EN[i*WIDTH+j]) begin + // $display("Write to %s: addr=%b data=%b", MEMID, WR_ADDR[i*ABITS +: ABITS], WR_DATA[i*WIDTH+j]); memory[WR_ADDR[i*ABITS +: ABITS] - OFFSET][j] = WR_DATA[i*WIDTH+j]; + end end 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])) + 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 + // $display("Transparent 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 end LAST_RD_CLK <= RD_CLK; diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc index 69ef5bc55..859a6606f 100644 --- a/techlibs/common/synth.cc +++ b/techlibs/common/synth.cc @@ -2,11 +2,11 @@ * 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 @@ -25,22 +25,11 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -bool check_label(bool &active, std::string run_from, std::string run_to, std::string label) +struct SynthPass : public ScriptPass { - 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; -} + SynthPass() : ScriptPass("synth", "generic synthesis script") { } -struct SynthPass : public Pass { - SynthPass() : Pass("synth", "generic synthesis script") { } - virtual void help() + virtual void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); @@ -52,12 +41,26 @@ struct SynthPass : public Pass { log(" -top <module>\n"); log(" use the specified module as top module (default='top')\n"); log("\n"); + log(" -flatten\n"); + log(" flatten the design before synthesis. this will pass '-auto-top' to\n"); + log(" 'hierarchy' if no top module is specified.\n"); + log("\n"); log(" -encfile <file>\n"); log(" passed to 'fsm_recode' via 'fsm'\n"); log("\n"); + log(" -nofsm\n"); + log(" do not run FSM optimization\n"); + log("\n"); log(" -noabc\n"); log(" do not run abc (as if yosys was compiled without ABC support)\n"); log("\n"); + log(" -noalumacc\n"); + log(" do not run 'alumacc' pass. i.e. keep arithmetic operators in\n"); + log(" their direct form ($add, $sub, etc.).\n"); + log("\n"); + log(" -nordff\n"); + log(" passed to 'memory'. 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"); @@ -65,41 +68,29 @@ struct SynthPass : public Pass { 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(" coarse:\n"); - log(" proc\n"); - log(" opt\n"); - log(" wreduce\n"); - log(" alumacc\n"); - log(" share\n"); - log(" opt\n"); - log(" fsm\n"); - log(" opt -fast\n"); - log(" memory -nomap\n"); - log(" opt_clean\n"); - log("\n"); - log(" fine:\n"); - log(" opt -fast -full\n"); - log(" memory_map\n"); - log(" opt -full\n"); - log(" techmap\n"); - log(" opt -fast\n"); - #ifdef YOSYS_ENABLE_ABC - log("\n"); - log(" abc:\n"); - log(" abc -fast\n"); - log(" opt -fast\n"); - #endif + help_script(); log("\n"); } - virtual void execute(std::vector<std::string> args, RTLIL::Design *design) + + string top_module, fsm_opts, memory_opts; + bool flatten, noalumacc, nofsm, noabc; + + virtual void clear_flags() YS_OVERRIDE { - std::string top_module, fsm_opts; - std::string run_from, run_to; - bool noabc = false; + top_module.clear(); + fsm_opts.clear(); + memory_opts.clear(); + + flatten = false; + noalumacc = false; + nofsm = false; + noabc = false; + } + + virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE + { + string run_from, run_to; + clear_flags(); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -123,10 +114,26 @@ struct SynthPass : public Pass { } continue; } + if (args[argidx] == "-flatten") { + flatten = true; + continue; + } + if (args[argidx] == "-nofsm") { + nofsm = true; + continue; + } if (args[argidx] == "-noabc") { noabc = true; continue; } + if (args[argidx] == "-noalumacc") { + noalumacc = true; + continue; + } + if (args[argidx] == "-nordff") { + memory_opts += " -nordff"; + continue; + } break; } extra_args(args, argidx, design); @@ -134,52 +141,75 @@ struct SynthPass : public Pass { if (!design->full_selection()) log_cmd_error("This comannd only operates on fully selected designs!\n"); - bool active = run_from.empty(); - - log_header("Executing SYNTH pass.\n"); + log_header(design, "Executing SYNTH pass.\n"); log_push(); - if (check_label(active, run_from, run_to, "begin")) + run_script(design, run_from, run_to); + + log_pop(); + } + + virtual void script() YS_OVERRIDE + { + if (check_label("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 (help_mode) { + run("hierarchy -check [-top <top>]"); + } else { + if (top_module.empty()) { + if (flatten) + run("hierarchy -check -auto-top"); + else + run("hierarchy -check"); + } else + run(stringf("hierarchy -check -top %s", top_module.c_str())); + } } - if (check_label(active, run_from, run_to, "coarse")) + if (check_label("coarse")) { - Pass::call(design, "proc"); - Pass::call(design, "opt"); - Pass::call(design, "wreduce"); - Pass::call(design, "alumacc"); - Pass::call(design, "share"); - Pass::call(design, "opt"); - Pass::call(design, "fsm" + fsm_opts); - Pass::call(design, "opt -fast"); - Pass::call(design, "memory -nomap"); - Pass::call(design, "opt_clean"); + run("proc"); + if (help_mode || flatten) + run("flatten", "(if -flatten)"); + run("opt_expr"); + run("opt_clean"); + run("check"); + run("opt"); + run("wreduce"); + if (!noalumacc) + run("alumacc"); + run("share"); + run("opt"); + if (!nofsm) + run("fsm" + fsm_opts); + run("opt -fast"); + run("memory -nomap" + memory_opts); + run("opt_clean"); } - if (check_label(active, run_from, run_to, "fine")) + if (check_label("fine")) { - Pass::call(design, "opt -fast -full"); - Pass::call(design, "memory_map"); - Pass::call(design, "opt -full"); - Pass::call(design, "techmap"); - Pass::call(design, "opt -fast"); + run("opt -fast -full"); + run("memory_map"); + run("opt -full"); + run("techmap"); + run("opt -fast"); + + if (!noabc) { + #ifdef YOSYS_ENABLE_ABC + run("abc -fast"); + run("opt -fast"); + #endif + } } - #ifdef YOSYS_ENABLE_ABC - if (check_label(active, run_from, run_to, "abc") && !noabc) + if (check_label("check")) { - Pass::call(design, "abc -fast"); - Pass::call(design, "opt -fast"); + run("hierarchy -check"); + run("stat"); + run("check"); } - #endif - - log_pop(); } } SynthPass; - + PRIVATE_NAMESPACE_END diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index e0ecf0c48..90c4ed7eb 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -2,11 +2,11 @@ * 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 @@ -19,8 +19,8 @@ * * The internal logic cell technology mapper. * - * This verilog library contains the mapping of internal cells (e.g. $not with - * variable bit width) to the internal logic cells (such as the single bit $_NOT_ + * This Verilog library contains the mapping of internal cells (e.g. $not with + * variable bit width) to the internal logic cells (such as the single bit $_NOT_ * gate). Usually this logic network is then mapped to the actual technology * using e.g. the "abc" pass. * @@ -59,7 +59,7 @@ module _90_simplemap_compare_ops; endmodule (* techmap_simplemap *) -(* techmap_celltype = "$pos $slice $concat $mux" *) +(* techmap_celltype = "$pos $slice $concat $mux $tribuf" *) module _90_simplemap_various; endmodule @@ -93,7 +93,7 @@ module _90_shift_ops_shr_shl_sshl_sshr (A, B, Y); localparam BB_WIDTH = `MIN($clog2(shift_left ? Y_WIDTH : A_SIGNED ? WIDTH : A_WIDTH) + 1, B_WIDTH); wire [1023:0] _TECHMAP_DO_00_ = "proc;;"; - wire [1023:0] _TECHMAP_DO_01_ = "RECURSION; CONSTMAP; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;"; + wire [1023:0] _TECHMAP_DO_01_ = "RECURSION; CONSTMAP; opt_muxtree; opt_expr -mux_undef -mux_bool -fine;;;"; integer i; reg [WIDTH-1:0] buffer; @@ -136,7 +136,7 @@ module _90_shift_shiftx (A, B, Y); localparam extbit = _TECHMAP_CELLTYPE_ == "$shift" ? 1'b0 : 1'bx; wire [1023:0] _TECHMAP_DO_00_ = "proc;;"; - wire [1023:0] _TECHMAP_DO_01_ = "CONSTMAP; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;"; + wire [1023:0] _TECHMAP_DO_01_ = "CONSTMAP; opt_muxtree; opt_expr -mux_undef -mux_bool -fine;;;"; integer i; reg [WIDTH-1:0] buffer; @@ -451,15 +451,9 @@ endmodule // -------------------------------------------------------- `ifndef NOLUT -(* techmap_celltype = "$lut" *) -module _90_lut (A, Y); - parameter WIDTH = 1; - parameter LUT = 0; - - input [WIDTH-1:0] A; - output Y; - - assign Y = LUT[A]; +(* techmap_simplemap *) +(* techmap_celltype = "$lut $sop" *) +module _90_lut; endmodule `endif |