diff options
Diffstat (limited to 'techlibs')
37 files changed, 1273 insertions, 385 deletions
diff --git a/techlibs/cmos/cmos_cells.lib b/techlibs/cmos/cmos_cells.lib deleted file mode 100644 index 1b0bf8457..000000000 --- a/techlibs/cmos/cmos_cells.lib +++ /dev/null @@ -1,55 +0,0 @@ -// test comment -/* test comment */ -library(demo) { - cell(BUF) { - area: 6; - pin(A) { direction: input; } - pin(Y) { direction: output; - function: "A"; } - } - cell(NOT) { - area: 3; - pin(A) { direction: input; } - pin(Y) { direction: output; - function: "A'"; } - } - cell(NAND) { - area: 4; - pin(A) { direction: input; } - pin(B) { direction: input; } - pin(Y) { direction: output; - function: "(A*B)'"; } - } - cell(NOR) { - area: 4; - pin(A) { direction: input; } - pin(B) { direction: input; } - pin(Y) { direction: output; - function: "(A+B)'"; } - } - cell(DFF) { - area: 18; - ff(IQ, IQN) { clocked_on: C; - next_state: D; } - pin(C) { direction: input; - clock: true; } - pin(D) { direction: input; } - pin(Q) { direction: output; - function: "IQ"; } - } - cell(DFFSR) { - area: 18; - ff("IQ", "IQN") { clocked_on: C; - next_state: D; - preset: S; - clear: R; } - pin(C) { direction: input; - clock: true; } - pin(D) { direction: input; } - pin(Q) { direction: output; - function: "IQ"; } - pin(S) { direction: input; } - pin(R) { direction: input; } - ; // empty statement - } -} diff --git a/techlibs/cmos/cmos_cells.sp b/techlibs/cmos/cmos_cells.sp deleted file mode 100644 index 673b20d08..000000000 --- a/techlibs/cmos/cmos_cells.sp +++ /dev/null @@ -1,39 +0,0 @@ - -.SUBCKT BUF A Y -X1 A B NOT -X2 B Y NOT -.ENDS NOT - -.SUBCKT NOT A Y -M1 Y A Vdd Vdd cmosp L=1u W=10u -M2 Y A Vss Vss cmosn L=1u W=10u -.ENDS NOT - -.SUBCKT NAND A B Y -M1 Y A Vdd Vdd cmosp L=1u W=10u -M2 Y B Vdd Vdd cmosp L=1u W=10u -M3 Y A M34 Vss cmosn L=1u W=10u -M4 M34 B Vss Vss cmosn L=1u W=10u -.ENDS NAND - -.SUBCKT NOR A B Y -M1 Y A M12 Vdd cmosp L=1u W=10u -M2 M12 B Vdd Vdd cmosp L=1u W=10u -M3 Y A Vss Vss cmosn L=1u W=10u -M4 Y B Vss Vss cmosn L=1u W=10u -.ENDS NOR - -.SUBCKT DLATCH E D Q -X1 D E S NAND -X2 nD E R NAND -X3 S nQ Q NAND -X4 Q R nQ NAND -X5 D nD NOT -.ENDS DLATCH - -.SUBCKT DFF C D Q -X1 nC D t DLATCH -X2 C t Q DLATCH -X3 C nC NOT -.ENDS DFF - diff --git a/techlibs/cmos/cmos_cells.v b/techlibs/cmos/cmos_cells.v deleted file mode 100644 index 27278facb..000000000 --- a/techlibs/cmos/cmos_cells.v +++ /dev/null @@ -1,44 +0,0 @@ - -module BUF(A, Y); -input A; -output Y; -assign Y = A; -endmodule - -module NOT(A, Y); -input A; -output Y; -assign Y = ~A; -endmodule - -module NAND(A, B, Y); -input A, B; -output Y; -assign Y = ~(A & B); -endmodule - -module NOR(A, B, Y); -input A, B; -output Y; -assign Y = ~(A | B); -endmodule - -module DFF(C, D, Q); -input C, D; -output reg Q; -always @(posedge C) - Q <= D; -endmodule - -module DFFSR(C, D, Q, S, R); -input C, D, S, R; -output reg Q; -always @(posedge C, posedge S, posedge R) - if (S) - Q <= 1'b1; - else if (R) - Q <= 1'b0; - else - Q <= D; -endmodule - diff --git a/techlibs/cmos/counter.v b/techlibs/cmos/counter.v deleted file mode 100644 index f21658724..000000000 --- a/techlibs/cmos/counter.v +++ /dev/null @@ -1,12 +0,0 @@ -module counter (clk, rst, en, count); - - input clk, rst, en; - output reg [2:0] count; - - always @(posedge clk) - if (rst) - count <= 3'd0; - else if (en) - count <= count + 3'd1; - -endmodule diff --git a/techlibs/cmos/counter.ys b/techlibs/cmos/counter.ys deleted file mode 100644 index a784f3465..000000000 --- a/techlibs/cmos/counter.ys +++ /dev/null @@ -1,16 +0,0 @@ - -read_verilog counter.v -read_verilog -lib cmos_cells.v - -proc;; memory;; techmap;; - -dfflibmap -liberty cmos_cells.lib -abc -liberty cmos_cells.lib;; - -# http://vlsiarch.ecen.okstate.edu/flows/MOSIS_SCMOS/latest/cadence/lib/tsmc025/signalstorm/osu025_stdcells.lib -# dfflibmap -liberty osu025_stdcells.lib -# abc -liberty osu025_stdcells.lib;; - -write_verilog synth.v -write_spice synth.sp - diff --git a/techlibs/cmos/testbench.sh b/techlibs/cmos/testbench.sh deleted file mode 100644 index 061704b64..000000000 --- a/techlibs/cmos/testbench.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -set -ex - -../../yosys counter.ys -ngspice testbench.sp - diff --git a/techlibs/cmos/testbench.sp b/techlibs/cmos/testbench.sp deleted file mode 100644 index 95d2f67cd..000000000 --- a/techlibs/cmos/testbench.sp +++ /dev/null @@ -1,29 +0,0 @@ - -* supply voltages -.global Vss Vdd -Vss Vss 0 DC 0 -Vdd Vdd 0 DC 3 - -* simple transistor model -.MODEL cmosn NMOS LEVEL=1 VT0=0.7 KP=110U GAMMA=0.4 LAMBDA=0.04 PHI=0.7 -.MODEL cmosp PMOS LEVEL=1 VT0=-0.7 KP=50U GAMMA=0.57 LAMBDA=0.05 PHI=0.8 - -* load design and library -.include synth.sp -.include cmos_cells.sp - -* input signals -Vclk clk 0 PULSE(0 3 1 0.1 0.1 0.8 2) -Vrst rst 0 PULSE(0 3 0.5 0.1 0.1 2.9 40) -Ven en 0 PULSE(0 3 0.5 0.1 0.1 5.9 8) - -Xuut clk rst en out0 out1 out2 COUNTER - -.tran 0.01 50 - -.control -run -plot v(clk) v(rst)+5 v(en)+10 v(out0)+20 v(out1)+25 v(out2)+30 -.endc - -.end 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 diff --git a/techlibs/greenpak4/Makefile.inc b/techlibs/greenpak4/Makefile.inc new file mode 100644 index 000000000..5808e7bdf --- /dev/null +++ b/techlibs/greenpak4/Makefile.inc @@ -0,0 +1,6 @@ + +OBJS += techlibs/greenpak4/synth_greenpak4.o + +$(eval $(call add_share_file,share/greenpak4,techlibs/greenpak4/cells_map.v)) +$(eval $(call add_share_file,share/greenpak4,techlibs/greenpak4/cells_sim.v)) +$(eval $(call add_share_file,share/greenpak4,techlibs/greenpak4/gp_dff.lib)) diff --git a/techlibs/greenpak4/cells_map.v b/techlibs/greenpak4/cells_map.v new file mode 100644 index 000000000..667d853da --- /dev/null +++ b/techlibs/greenpak4/cells_map.v @@ -0,0 +1,48 @@ +module \$_DFF_P_ (input D, C, output Q); + GP_DFF _TECHMAP_REPLACE_ ( + .D(D), + .Q(Q), + .CLK(C), + .nRSTZ(1'b1), + .nSETZ(1'b1) + ); +endmodule + +module \$_DFFSR_PNN_ (input C, S, R, D, output Q); + GP_DFF _TECHMAP_REPLACE_ ( + .D(D), + .Q(Q), + .CLK(C), + .nRSTZ(R), + .nSETZ(S) + ); +endmodule + +module \$lut (A, Y); + parameter WIDTH = 0; + parameter LUT = 0; + + input [WIDTH-1:0] A; + output Y; + + generate + if (WIDTH == 1) begin + GP_2LUT #(.INIT({2'b00, LUT})) _TECHMAP_REPLACE_ (.OUT(Y), + .IN0(A[0]), .IN1(1'b0)); + end else + if (WIDTH == 2) begin + GP_2LUT #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y), + .IN0(A[0]), .IN1(A[1])); + end else + if (WIDTH == 3) begin + GP_3LUT #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y), + .IN0(A[0]), .IN1(A[1]), .IN2(A[2])); + end else + if (WIDTH == 4) begin + GP_4LUT #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y), + .IN0(A[0]), .IN1(A[1]), .IN2(A[2]), .IN3(A[3])); + end else begin + wire _TECHMAP_FAIL_ = 1; + end + endgenerate +endmodule diff --git a/techlibs/greenpak4/cells_sim.v b/techlibs/greenpak4/cells_sim.v new file mode 100644 index 000000000..d9ddaaccf --- /dev/null +++ b/techlibs/greenpak4/cells_sim.v @@ -0,0 +1,25 @@ +module GP_DFF(input D, CLK, nRSTZ, nSETZ, output reg Q); + always @(posedge CLK, negedge nRSTZ, negedge nSETZ) begin + if (!nRSTZ) + Q <= 1'b0; + else if (!nSETZ) + Q <= 1'b1; + else + Q <= D; + end +endmodule + +module GP_2LUT(input IN0, IN1, output OUT); + parameter [3:0] INIT = 0; + assign OUT = INIT[{IN1, IN0}]; +endmodule + +module GP_3LUT(input IN0, IN1, IN2, output OUT); + parameter [7:0] INIT = 0; + assign OUT = INIT[{IN2, IN1, IN0}]; +endmodule + +module GP_4LUT(input IN0, IN1, IN2, IN3, output OUT); + parameter [15:0] INIT = 0; + assign OUT = INIT[{IN3, IN2, IN1, IN0}]; +endmodule diff --git a/techlibs/greenpak4/gp_dff.lib b/techlibs/greenpak4/gp_dff.lib new file mode 100644 index 000000000..9e2e46cb4 --- /dev/null +++ b/techlibs/greenpak4/gp_dff.lib @@ -0,0 +1,26 @@ +library(gp_dff) { + cell(GP_DFF_NOSR) { + area: 1; + ff("IQ", "IQN") { clocked_on: CLK; + next_state: D; } + pin(CLK) { direction: input; + clock: true; } + pin(D) { direction: input; } + pin(Q) { direction: output; + function: "IQ"; } + } + cell(GP_DFF_SR) { + area: 1; + ff("IQ", "IQN") { clocked_on: CLK; + next_state: D; + preset: "nSETZ'"; + clear: "nRSTZ'"; } + pin(CLK) { direction: input; + clock: true; } + pin(D) { direction: input; } + pin(Q) { direction: output; + function: "IQ"; } + pin(nRSTZ) { direction: input; } + pin(nSETZ) { direction: input; } + } +} diff --git a/techlibs/greenpak4/synth_greenpak4.cc b/techlibs/greenpak4/synth_greenpak4.cc new file mode 100644 index 000000000..15b53d623 --- /dev/null +++ b/techlibs/greenpak4/synth_greenpak4.cc @@ -0,0 +1,233 @@ +/* + * 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 (label == run_from) + active = true; + if (label == run_to) + active = false; + return active; +} + +struct SynthGreenPAK4Pass : public Pass { + SynthGreenPAK4Pass() : Pass("synth_greenpak4", "synthesis for GreenPAK4 FPGAs") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" synth_greenpak4 [options]\n"); + log("\n"); + log("This command runs synthesis for GreenPAK4 FPGAs. This work is experimental.\n"); + log("\n"); + log(" -top <module>\n"); + log(" use the specified module as top module (default='top')\n"); + log("\n"); + log(" -blif <file>\n"); + log(" write the design to the specified BLIF file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -edif <file>\n"); + log(" write the design to the specified edif file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\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(" -noflatten\n"); + log(" do not flatten design before synthesis\n"); + log("\n"); + log(" -retime\n"); + log(" run 'abc' with -dff option\n"); + log("\n"); + log("\n"); + log("The following commands are executed by this synthesis command:\n"); + log("\n"); + log(" begin:\n"); + log(" read_verilog -lib +/greenpak4/cells_sim.v\n"); + log(" hierarchy -check -top <top>\n"); + log("\n"); + log(" flatten: (unless -noflatten)\n"); + log(" proc\n"); + log(" flatten\n"); + log(" tribuf -logic\n"); + log("\n"); + log(" coarse:\n"); + log(" synth -run coarse\n"); + log("\n"); + log(" fine:\n"); + log(" opt -fast -mux_undef -undriven -fine\n"); + log(" memory_map\n"); + log(" opt -undriven -fine\n"); + log(" techmap\n"); + log(" dfflibmap -prepare -liberty +/greenpak4/gp_dff.lib\n"); + log(" opt -fast\n"); + log(" abc -dff (only if -retime)\n"); + log("\n"); + log(" map_luts:\n"); + log(" nlutmap -luts 0,8,16,2\n"); + log(" clean\n"); + log("\n"); + log(" map_cells:\n"); + log(" techmap -map +/greenpak4/cells_map.v\n"); + log(" clean\n"); + log("\n"); + log(" check:\n"); + log(" hierarchy -check\n"); + log(" stat\n"); + log(" check -noinit\n"); + log("\n"); + log(" blif:\n"); + log(" write_blif -gates -attr -param <file-name>\n"); + log("\n"); + log(" edif:\n"); + log(" write_edif <file-name>\n"); + log("\n"); + } + virtual void execute(std::vector<std::string> args, RTLIL::Design *design) + { + std::string top_opt = "-auto-top"; + std::string run_from, run_to; + std::string blif_file, edif_file; + bool flatten = true; + bool retime = false; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-top" && argidx+1 < args.size()) { + top_opt = "-top " + args[++argidx]; + continue; + } + if (args[argidx] == "-blif" && argidx+1 < args.size()) { + blif_file = args[++argidx]; + continue; + } + if (args[argidx] == "-edif" && argidx+1 < args.size()) { + edif_file = args[++argidx]; + continue; + } + if (args[argidx] == "-run" && argidx+1 < args.size()) { + size_t pos = args[argidx+1].find(':'); + if (pos == std::string::npos) + break; + 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] == "-noflatten") { + flatten = false; + continue; + } + if (args[argidx] == "-retime") { + retime = true; + 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 SYNTH_GREENPAK4 pass.\n"); + log_push(); + + if (check_label(active, run_from, run_to, "begin")) + { + Pass::call(design, "read_verilog -lib +/greenpak4/cells_sim.v"); + Pass::call(design, stringf("hierarchy -check %s", top_opt.c_str())); + } + + if (flatten && check_label(active, run_from, run_to, "flatten")) + { + Pass::call(design, "proc"); + Pass::call(design, "flatten"); + Pass::call(design, "tribuf -logic"); + } + + if (check_label(active, run_from, run_to, "coarse")) + { + Pass::call(design, "synth -run coarse"); + } + + if (check_label(active, run_from, run_to, "fine")) + { + Pass::call(design, "opt -fast -mux_undef -undriven -fine"); + Pass::call(design, "memory_map"); + Pass::call(design, "opt -undriven -fine"); + Pass::call(design, "techmap"); + Pass::call(design, "dfflibmap -prepare -liberty +/greenpak4/gp_dff.lib"); + Pass::call(design, "opt -fast"); + if (retime) + Pass::call(design, "abc -dff"); + } + + if (check_label(active, run_from, run_to, "map_luts")) + { + Pass::call(design, "nlutmap -luts 0,8,16,2"); + Pass::call(design, "clean"); + } + + if (check_label(active, run_from, run_to, "map_cells")) + { + Pass::call(design, "techmap -map +/greenpak4/cells_map.v"); + Pass::call(design, "clean"); + } + + if (check_label(active, run_from, run_to, "check")) + { + Pass::call(design, "hierarchy -check"); + Pass::call(design, "stat"); + Pass::call(design, "check -noinit"); + } + + if (check_label(active, run_from, run_to, "blif")) + { + if (!blif_file.empty()) + Pass::call(design, stringf("write_blif -gates -attr -param %s", blif_file.c_str())); + } + + if (check_label(active, run_from, run_to, "edif")) + { + if (!edif_file.empty()) + Pass::call(design, stringf("write_edif %s", edif_file.c_str())); + } + + log_pop(); + } +} SynthGreenPAK4Pass; + +PRIVATE_NAMESPACE_END diff --git a/techlibs/ice40/Makefile.inc b/techlibs/ice40/Makefile.inc index ed495519a..83009d176 100644 --- a/techlibs/ice40/Makefile.inc +++ b/techlibs/ice40/Makefile.inc @@ -1,6 +1,7 @@ OBJS += techlibs/ice40/synth_ice40.o OBJS += techlibs/ice40/ice40_ffssr.o +OBJS += techlibs/ice40/ice40_ffinit.o OBJS += techlibs/ice40/ice40_opt.o GENFILES += techlibs/ice40/brams_init1.vh @@ -12,7 +13,7 @@ EXTRA_OBJS += techlibs/ice40/brams_init.mk techlibs/ice40/brams_init.mk: techlibs/ice40/brams_init.py $(Q) mkdir -p techlibs/ice40 - $(P) python $< + $(P) python3 $< $(Q) touch techlibs/ice40/brams_init.mk techlibs/ice40/brams_init1.vh: techlibs/ice40/brams_init.mk diff --git a/techlibs/ice40/brams.txt b/techlibs/ice40/brams.txt index 05131b227..03d596111 100644 --- a/techlibs/ice40/brams.txt +++ b/techlibs/ice40/brams.txt @@ -5,7 +5,7 @@ bram $__ICE40_RAM4K_M0 groups 2 ports 1 1 wrmode 0 1 - enable 0 16 + enable 1 16 transp 0 0 clocks 2 3 clkpol 2 3 @@ -22,7 +22,7 @@ bram $__ICE40_RAM4K_M123 groups 2 ports 1 1 wrmode 0 1 - enable 0 1 + enable 1 1 transp 0 0 clocks 2 3 clkpol 2 3 diff --git a/techlibs/ice40/brams_init.py b/techlibs/ice40/brams_init.py index 93eb9846b..4a1485110 100644 --- a/techlibs/ice40/brams_init.py +++ b/techlibs/ice40/brams_init.py @@ -1,7 +1,4 @@ -#!/usr/bin/python - -from __future__ import division -from __future__ import print_function +#!/usr/bin/env python3 def write_init_vh(filename, initbits): with open(filename, "w") as f: diff --git a/techlibs/ice40/brams_map.v b/techlibs/ice40/brams_map.v index 8c5c7e812..19a61d73b 100644 --- a/techlibs/ice40/brams_map.v +++ b/techlibs/ice40/brams_map.v @@ -90,7 +90,7 @@ module \$__ICE40_RAM4K ( .RCLKE(RCLKE), .RE (RE ), .RADDR(RADDR), - .WCLK (WCLK ), + .WCLKN(WCLK ), .WCLKE(WCLKE), .WE (WE ), .WADDR(WADDR), @@ -119,7 +119,7 @@ module \$__ICE40_RAM4K ( .INIT_F(INIT_F) ) _TECHMAP_REPLACE_ ( .RDATA(RDATA), - .RCLK (RCLK ), + .RCLKN(RCLK ), .RCLKE(RCLKE), .RE (RE ), .RADDR(RADDR), @@ -152,11 +152,11 @@ module \$__ICE40_RAM4K ( .INIT_F(INIT_F) ) _TECHMAP_REPLACE_ ( .RDATA(RDATA), - .RCLK (RCLK ), + .RCLKN(RCLK ), .RCLKE(RCLKE), .RE (RE ), .RADDR(RADDR), - .WCLK (WCLK ), + .WCLKN(WCLK ), .WCLKE(WCLKE), .WE (WE ), .WADDR(WADDR), @@ -168,7 +168,7 @@ module \$__ICE40_RAM4K ( endmodule -module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); +module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); parameter [0:0] CLKPOL2 = 1; parameter [0:0] CLKPOL3 = 1; @@ -179,6 +179,7 @@ module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); input [7:0] A1ADDR; output [15:0] A1DATA; + input A1EN; input [7:0] B1ADDR; input [15:0] B1DATA; @@ -212,18 +213,18 @@ module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); .RDATA(A1DATA), .RADDR(A1ADDR_11), .RCLK(CLK2), - .RCLKE(1'b1), + .RCLKE(A1EN), .RE(1'b1), .WDATA(B1DATA), .WADDR(B1ADDR_11), .MASK(~B1EN), .WCLK(CLK3), - .WCLKE(1'b1), - .WE(|B1EN) + .WCLKE(|B1EN), + .WE(1'b1) ); endmodule -module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); +module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); parameter CFG_ABITS = 9; parameter CFG_DBITS = 8; @@ -242,6 +243,7 @@ module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); input [CFG_ABITS-1:0] A1ADDR; output [CFG_DBITS-1:0] A1DATA; + input A1EN; input [CFG_ABITS-1:0] B1ADDR; input [CFG_DBITS-1:0] B1DATA; @@ -297,13 +299,13 @@ module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); .RDATA(A1DATA_16), .RADDR(A1ADDR_11), .RCLK(CLK2), - .RCLKE(1'b1), + .RCLKE(A1EN), .RE(1'b1), .WDATA(B1DATA_16), .WADDR(B1ADDR_11), .WCLK(CLK3), - .WCLKE(1'b1), - .WE(|B1EN) + .WCLKE(|B1EN), + .WE(1'b1) ); endmodule diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index f94040245..f23218c00 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -58,8 +58,8 @@ module SB_IO ( generate if (PIN_TYPE[5:4] == 2'b01) assign PACKAGE_PIN = dout; - if (PIN_TYPE[5:4] == 2'b10) assign PACKAGE_PIN = outena_q ? dout : 1'bz; - if (PIN_TYPE[5:4] == 2'b11) assign PACKAGE_PIN = OUTPUT_ENABLE ? dout : 1'bz; + if (PIN_TYPE[5:4] == 2'b10) assign PACKAGE_PIN = OUTPUT_ENABLE ? dout : 1'bz; + if (PIN_TYPE[5:4] == 2'b11) assign PACKAGE_PIN = outena_q ? dout : 1'bz; endgenerate `endif endmodule @@ -473,7 +473,7 @@ endmodule module SB_RAM40_4KNR ( output [15:0] RDATA, - input RCLK, RCLKE, RE, + input RCLKN, RCLKE, RE, input [10:0] RADDR, input WCLK, WCLKE, WE, input [10:0] WADDR, @@ -520,7 +520,7 @@ module SB_RAM40_4KNR ( .INIT_F (INIT_F ) ) RAM ( .RDATA(RDATA), - .RCLK (~RCLK), + .RCLK (~RCLKN), .RCLKE(RCLKE), .RE (RE ), .RADDR(RADDR), @@ -537,7 +537,7 @@ module SB_RAM40_4KNW ( output [15:0] RDATA, input RCLK, RCLKE, RE, input [10:0] RADDR, - input WCLK, WCLKE, WE, + input WCLKN, WCLKE, WE, input [10:0] WADDR, input [15:0] MASK, WDATA ); @@ -586,7 +586,7 @@ module SB_RAM40_4KNW ( .RCLKE(RCLKE), .RE (RE ), .RADDR(RADDR), - .WCLK (~WCLK), + .WCLK (~WCLKN), .WCLKE(WCLKE), .WE (WE ), .WADDR(WADDR), @@ -597,9 +597,9 @@ endmodule module SB_RAM40_4KNRNW ( output [15:0] RDATA, - input RCLK, RCLKE, RE, + input RCLKN, RCLKE, RE, input [10:0] RADDR, - input WCLK, WCLKE, WE, + input WCLKN, WCLKE, WE, input [10:0] WADDR, input [15:0] MASK, WDATA ); @@ -644,11 +644,11 @@ module SB_RAM40_4KNRNW ( .INIT_F (INIT_F ) ) RAM ( .RDATA(RDATA), - .RCLK (~RCLK), + .RCLK (~RCLKN), .RCLKE(RCLKE), .RE (RE ), .RADDR(RADDR), - .WCLK (~WCLK), + .WCLK (~WCLKN), .WCLKE(WCLKE), .WE (WE ), .WADDR(WADDR), diff --git a/techlibs/ice40/ice40_ffinit.cc b/techlibs/ice40/ice40_ffinit.cc new file mode 100644 index 000000000..50400be80 --- /dev/null +++ b/techlibs/ice40/ice40_ffinit.cc @@ -0,0 +1,142 @@ +/* + * 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/yosys.h" +#include "kernel/sigtools.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct Ice40FfinitPass : public Pass { + Ice40FfinitPass() : Pass("ice40_ffinit", "iCE40: handle FF init values") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" ice40_ffinit [options] [selection]\n"); + log("\n"); + log("Remove zero init values for FF output signals. Add inverters to implement\n"); + log("nonzero init values.\n"); + log("\n"); + } + virtual void execute(std::vector<std::string> args, RTLIL::Design *design) + { + log_header("Executing ICE40_FFINIT pass (implement FF init values).\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + // if (args[argidx] == "-singleton") { + // singleton_mode = true; + // continue; + // } + break; + } + extra_args(args, argidx, design); + + for (auto module : design->selected_modules()) + { + log("Handling FF init values in %s.\n", log_id(module)); + + SigMap sigmap(module); + pool<Wire*> init_wires; + dict<SigBit, State> initbits; + pool<SigBit> handled_initbits; + + for (auto wire : module->selected_wires()) + { + if (wire->attributes.count("\\init") == 0) + continue; + + SigSpec wirebits = sigmap(wire); + Const initval = wire->attributes.at("\\init"); + init_wires.insert(wire); + + for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) + { + SigBit bit = wirebits[i]; + State val = initval[i]; + + if (val != State::S0 && val != State::S1) + continue; + + if (initbits.count(bit)) { + if (initbits.at(bit) != val) + log_error("Conflicting init values for signal %s.\n", log_signal(bit)); + continue; + } + + initbits[bit] = val; + } + } + + for (auto cell : module->selected_cells()) + { + if (!cell->type.in("\\SB_DFF", "\\SB_DFFE", "\\SB_DFFN", "\\SB_DFFNE")) + continue; + + SigBit sig_d = sigmap(cell->getPort("\\D")); + SigBit sig_q = sigmap(cell->getPort("\\Q")); + + if (!initbits.count(sig_q)) + continue; + + State val = initbits.at(sig_q); + handled_initbits.insert(sig_q); + + log("FF init value for cell %s (%s): %s = %c\n", log_id(cell), log_id(cell->type), + log_signal(sig_q), val != State::S0 ? '1' : '0'); + + if (val == State::S0) + continue; + + Wire *new_sig_d = module->addWire(NEW_ID); + Wire *new_sig_q = module->addWire(NEW_ID); + + module->addNotGate(NEW_ID, sig_d, new_sig_d); + module->addNotGate(NEW_ID, new_sig_q, sig_q); + + cell->setPort("\\D", new_sig_d); + cell->setPort("\\Q", new_sig_q); + } + + for (auto wire : init_wires) + { + if (wire->attributes.count("\\init") == 0) + continue; + + SigSpec wirebits = sigmap(wire); + Const &initval = wire->attributes.at("\\init"); + bool remove_attribute = true; + + for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) { + if (handled_initbits.count(wirebits[i])) + wirebits[i] = State::Sx; + else + remove_attribute = false; + } + + if (remove_attribute) + wire->attributes.erase("\\init"); + } + } + } +} Ice40FfinitPass; + +PRIVATE_NAMESPACE_END diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 788835f1d..75cab7bda 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -104,6 +104,7 @@ struct SynthIce40Pass : public Pass { log(" techmap -map +/ice40/cells_map.v\n"); log(" opt_const -mux_undef\n"); log(" simplemap\n"); + log(" ice40_ffinit\n"); log(" ice40_ffssr\n"); log(" ice40_opt -full\n"); log("\n"); @@ -236,6 +237,7 @@ struct SynthIce40Pass : public Pass { Pass::call(design, "techmap -map +/ice40/cells_map.v"); Pass::call(design, "opt_const -mux_undef"); Pass::call(design, "simplemap"); + Pass::call(design, "ice40_ffinit"); Pass::call(design, "ice40_ffssr"); Pass::call(design, "ice40_opt -full"); } diff --git a/techlibs/xilinx/Makefile.inc b/techlibs/xilinx/Makefile.inc index cca41f917..ccf88ec7e 100644 --- a/techlibs/xilinx/Makefile.inc +++ b/techlibs/xilinx/Makefile.inc @@ -11,7 +11,7 @@ EXTRA_OBJS += techlibs/xilinx/brams_init.mk techlibs/xilinx/brams_init.mk: techlibs/xilinx/brams_init.py $(Q) mkdir -p techlibs/xilinx - $(P) python $< + $(P) python3 $< $(Q) touch $@ techlibs/xilinx/brams_init_36.vh: techlibs/xilinx/brams_init.mk diff --git a/techlibs/xilinx/brams.txt b/techlibs/xilinx/brams.txt index 894e714c6..f1161114e 100644 --- a/techlibs/xilinx/brams.txt +++ b/techlibs/xilinx/brams.txt @@ -6,7 +6,7 @@ bram $__XILINX_RAMB36_SDP groups 2 ports 1 1 wrmode 0 1 - enable 0 8 + enable 1 8 transp 0 0 clocks 2 3 clkpol 2 3 @@ -19,7 +19,7 @@ bram $__XILINX_RAMB18_SDP groups 2 ports 1 1 wrmode 0 1 - enable 0 4 + enable 1 4 transp 0 0 clocks 2 3 clkpol 2 3 @@ -42,9 +42,9 @@ bram $__XILINX_RAMB36_TDP groups 2 ports 1 1 wrmode 0 1 - enable 0 4 @a10d36 - enable 0 2 @a11d18 - enable 0 1 @a12d9 @a13d4 @a14d2 @a15d1 + enable 1 4 @a10d36 + enable 1 2 @a11d18 + enable 1 1 @a12d9 @a13d4 @a14d2 @a15d1 transp 0 0 clocks 2 3 clkpol 2 3 @@ -65,8 +65,8 @@ bram $__XILINX_RAMB18_TDP groups 2 ports 1 1 wrmode 0 1 - enable 0 2 @a10d18 - enable 0 1 @a11d9 @a12d4 @a13d2 @a14d1 + enable 1 2 @a10d18 + enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1 transp 0 0 clocks 2 3 clkpol 2 3 diff --git a/techlibs/xilinx/brams_init.py b/techlibs/xilinx/brams_init.py index eac829ddf..e787b1f76 100644 --- a/techlibs/xilinx/brams_init.py +++ b/techlibs/xilinx/brams_init.py @@ -1,7 +1,4 @@ -#!/usr/bin/python - -from __future__ import division -from __future__ import print_function +#!/usr/bin/env python3 with open("techlibs/xilinx/brams_init_18.vh", "w") as f: for i in range(8): diff --git a/techlibs/xilinx/brams_map.v b/techlibs/xilinx/brams_map.v index cbfd4e1eb..7ea49158d 100644 --- a/techlibs/xilinx/brams_map.v +++ b/techlibs/xilinx/brams_map.v @@ -1,4 +1,4 @@ -module \$__XILINX_RAMB36_SDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); +module \$__XILINX_RAMB36_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); parameter CLKPOL2 = 1; parameter CLKPOL3 = 1; parameter [36863:0] INIT = 36864'bx; @@ -8,6 +8,7 @@ module \$__XILINX_RAMB36_SDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); input [8:0] A1ADDR; output [71:0] A1DATA; + input A1EN; input [8:0] B1ADDR; input [71:0] B1DATA; @@ -47,7 +48,7 @@ module \$__XILINX_RAMB36_SDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); .ADDRARDADDR(A1ADDR_16), .CLKARDCLK(CLK2), - .ENARDEN(|1), + .ENARDEN(A1EN), .REGCEAREGCE(|1), .RSTRAMARSTRAM(|0), .RSTREGARSTREG(|0), @@ -65,7 +66,7 @@ endmodule // ------------------------------------------------------------------------ -module \$__XILINX_RAMB18_SDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); +module \$__XILINX_RAMB18_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); parameter CLKPOL2 = 1; parameter CLKPOL3 = 1; parameter [18431:0] INIT = 18432'bx; @@ -75,6 +76,7 @@ module \$__XILINX_RAMB18_SDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); input [8:0] A1ADDR; output [35:0] A1DATA; + input A1EN; input [8:0] B1ADDR; input [35:0] B1DATA; @@ -111,7 +113,7 @@ module \$__XILINX_RAMB18_SDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); .ADDRARDADDR(A1ADDR_14), .CLKARDCLK(CLK2), - .ENARDEN(|1), + .ENARDEN(A1EN), .REGCEAREGCE(|1), .RSTRAMARSTRAM(|0), .RSTREGARSTREG(|0), @@ -129,7 +131,7 @@ endmodule // ------------------------------------------------------------------------ -module \$__XILINX_RAMB36_TDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); +module \$__XILINX_RAMB36_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); parameter CFG_ABITS = 10; parameter CFG_DBITS = 36; parameter CFG_ENABLE_B = 4; @@ -143,6 +145,7 @@ module \$__XILINX_RAMB36_TDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); input [CFG_ABITS-1:0] A1ADDR; output [CFG_DBITS-1:0] A1DATA; + input A1EN; input [CFG_ABITS-1:0] B1ADDR; input [CFG_DBITS-1:0] B1DATA; @@ -181,7 +184,7 @@ module \$__XILINX_RAMB36_TDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); .DOPADOP(DOP[3:0]), .ADDRARDADDR(A1ADDR_16), .CLKARDCLK(CLK2), - .ENARDEN(|1), + .ENARDEN(A1EN), .REGCEAREGCE(|1), .RSTRAMARSTRAM(|0), .RSTREGARSTREG(|0), @@ -219,7 +222,7 @@ module \$__XILINX_RAMB36_TDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); .DOPADOP(DOP[3:0]), .ADDRARDADDR(A1ADDR_16), .CLKARDCLK(CLK2), - .ENARDEN(|1), + .ENARDEN(A1EN), .REGCEAREGCE(|1), .RSTRAMARSTRAM(|0), .RSTREGARSTREG(|0), @@ -242,7 +245,7 @@ endmodule // ------------------------------------------------------------------------ -module \$__XILINX_RAMB18_TDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); +module \$__XILINX_RAMB18_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); parameter CFG_ABITS = 10; parameter CFG_DBITS = 18; parameter CFG_ENABLE_B = 2; @@ -256,6 +259,7 @@ module \$__XILINX_RAMB18_TDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); input [CFG_ABITS-1:0] A1ADDR; output [CFG_DBITS-1:0] A1DATA; + input A1EN; input [CFG_ABITS-1:0] B1ADDR; input [CFG_DBITS-1:0] B1DATA; @@ -294,7 +298,7 @@ module \$__XILINX_RAMB18_TDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); .DOPADOP(DOP), .ADDRARDADDR(A1ADDR_14), .CLKARDCLK(CLK2), - .ENARDEN(|1), + .ENARDEN(A1EN), .REGCEAREGCE(|1), .RSTRAMARSTRAM(|0), .RSTREGARSTREG(|0), @@ -332,7 +336,7 @@ module \$__XILINX_RAMB18_TDP (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN); .DOPADOP(DOP), .ADDRARDADDR(A1ADDR_14), .CLKARDCLK(CLK2), - .ENARDEN(|1), + .ENARDEN(A1EN), .REGCEAREGCE(|1), .RSTRAMARSTRAM(|0), .RSTREGARSTREG(|0), diff --git a/techlibs/xilinx/example_basys3/README b/techlibs/xilinx/example_basys3/README deleted file mode 100644 index 85b6eab10..000000000 --- a/techlibs/xilinx/example_basys3/README +++ /dev/null @@ -1,16 +0,0 @@ - -A simple example design, based on the Digilent BASYS3 board -=========================================================== - -Running Yosys: - yosys run_yosys.ys - -Running Vivado: - vivado -nolog -nojournal -mode batch -source run_vivado.tcl - -Programming board: - vivado -nolog -nojournal -mode batch -source run_prog.tcl - -All of the above: - bash run.sh - diff --git a/techlibs/xilinx/example_basys3/example.v b/techlibs/xilinx/example_basys3/example.v deleted file mode 100644 index 2b01a22a8..000000000 --- a/techlibs/xilinx/example_basys3/example.v +++ /dev/null @@ -1,21 +0,0 @@ -module example(CLK, LD); - input CLK; - output [15:0] LD; - - wire clock; - reg [15:0] leds; - - BUFG CLK_BUF (.I(CLK), .O(clock)); - OBUF LD_BUF[15:0] (.I(leds), .O(LD)); - - parameter COUNTBITS = 26; - reg [COUNTBITS-1:0] counter; - - always @(posedge CLK) begin - counter <= counter + 1; - if (counter[COUNTBITS-1]) - leds <= 16'h8000 >> counter[COUNTBITS-2:COUNTBITS-5]; - else - leds <= 16'h0001 << counter[COUNTBITS-2:COUNTBITS-5]; - end -endmodule diff --git a/techlibs/xilinx/example_basys3/example.xdc b/techlibs/xilinx/example_basys3/example.xdc deleted file mode 100644 index c1fd0e925..000000000 --- a/techlibs/xilinx/example_basys3/example.xdc +++ /dev/null @@ -1,21 +0,0 @@ - -set_property -dict { IOSTANDARD LVCMOS33 PACKAGE_PIN W5 } [get_ports CLK] -set_property -dict { IOSTANDARD LVCMOS33 PACKAGE_PIN U16 } [get_ports {LD[0]}] -set_property -dict { IOSTANDARD LVCMOS33 PACKAGE_PIN E19 } [get_ports {LD[1]}] -set_property -dict { IOSTANDARD LVCMOS33 PACKAGE_PIN U19 } [get_ports {LD[2]}] -set_property -dict { IOSTANDARD LVCMOS33 PACKAGE_PIN V19 } [get_ports {LD[3]}] -set_property -dict { IOSTANDARD LVCMOS33 PACKAGE_PIN W18 } [get_ports {LD[4]}] -set_property -dict { IOSTANDARD LVCMOS33 PACKAGE_PIN U15 } [get_ports {LD[5]}] -set_property -dict { IOSTANDARD LVCMOS33 PACKAGE_PIN U14 } [get_ports {LD[6]}] -set_property -dict { IOSTANDARD LVCMOS33 PACKAGE_PIN V14 } [get_ports {LD[7]}] -set_property -dict { IOSTANDARD LVCMOS33 PACKAGE_PIN V13 } [get_ports {LD[8]}] -set_property -dict { IOSTANDARD LVCMOS33 PACKAGE_PIN V3 } [get_ports {LD[9]}] -set_property -dict { IOSTANDARD LVCMOS33 PACKAGE_PIN W3 } [get_ports {LD[10]}] -set_property -dict { IOSTANDARD LVCMOS33 PACKAGE_PIN U3 } [get_ports {LD[11]}] -set_property -dict { IOSTANDARD LVCMOS33 PACKAGE_PIN P3 } [get_ports {LD[12]}] -set_property -dict { IOSTANDARD LVCMOS33 PACKAGE_PIN N3 } [get_ports {LD[13]}] -set_property -dict { IOSTANDARD LVCMOS33 PACKAGE_PIN P1 } [get_ports {LD[14]}] -set_property -dict { IOSTANDARD LVCMOS33 PACKAGE_PIN L1 } [get_ports {LD[15]}] - -create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports CLK] - diff --git a/techlibs/xilinx/example_basys3/run.sh b/techlibs/xilinx/example_basys3/run.sh deleted file mode 100644 index 10f059103..000000000 --- a/techlibs/xilinx/example_basys3/run.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -yosys run_yosys.ys -vivado -nolog -nojournal -mode batch -source run_vivado.tcl -vivado -nolog -nojournal -mode batch -source run_prog.tcl diff --git a/techlibs/xilinx/example_basys3/run_prog.tcl b/techlibs/xilinx/example_basys3/run_prog.tcl deleted file mode 100644 index d711af840..000000000 --- a/techlibs/xilinx/example_basys3/run_prog.tcl +++ /dev/null @@ -1,4 +0,0 @@ -connect_hw_server -open_hw_target [lindex [get_hw_targets] 0] -set_property PROGRAM.FILE example.bit [lindex [get_hw_devices] 0] -program_hw_devices [lindex [get_hw_devices] 0] diff --git a/techlibs/xilinx/example_basys3/run_vivado.tcl b/techlibs/xilinx/example_basys3/run_vivado.tcl deleted file mode 100644 index c3b6a610e..000000000 --- a/techlibs/xilinx/example_basys3/run_vivado.tcl +++ /dev/null @@ -1,9 +0,0 @@ -read_xdc example.xdc -read_edif example.edif -link_design -part xc7a35tcpg236-1 -top example -opt_design -place_design -route_design -report_utilization -report_timing -write_bitstream -force example.bit diff --git a/techlibs/xilinx/example_basys3/run_yosys.ys b/techlibs/xilinx/example_basys3/run_yosys.ys deleted file mode 100644 index 4541826d3..000000000 --- a/techlibs/xilinx/example_basys3/run_yosys.ys +++ /dev/null @@ -1,2 +0,0 @@ -read_verilog example.v -synth_xilinx -edif example.edif -top example diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index b3d4c214f..fbcc96014 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -79,7 +79,6 @@ struct SynthXilinxPass : public Pass { log("\n"); log(" coarse:\n"); log(" synth -run coarse\n"); - log(" dff2dffe\n"); log("\n"); log(" bram:\n"); log(" memory_bram -rules +/xilinx/brams.txt\n"); @@ -92,6 +91,7 @@ struct SynthXilinxPass : public Pass { log(" fine:\n"); log(" opt -fast -full\n"); log(" memory_map\n"); + log(" dff2dffe\n"); log(" opt -full\n"); log(" techmap -map +/techmap.v -map +/xilinx/arith_map.v\n"); log(" opt -fast\n"); @@ -178,7 +178,6 @@ struct SynthXilinxPass : public Pass { if (check_label(active, run_from, run_to, "coarse")) { Pass::call(design, "synth -run coarse"); - Pass::call(design, "dff2dffe"); } if (check_label(active, run_from, run_to, "bram")) @@ -197,6 +196,7 @@ struct SynthXilinxPass : public Pass { { Pass::call(design, "opt -fast -full"); Pass::call(design, "memory_map"); + Pass::call(design, "dff2dffe"); Pass::call(design, "opt -full"); Pass::call(design, "techmap -map +/techmap.v -map +/xilinx/arith_map.v"); Pass::call(design, "opt -fast"); @@ -204,7 +204,7 @@ struct SynthXilinxPass : public Pass { if (check_label(active, run_from, run_to, "map_luts")) { - Pass::call(design, "abc -lut 5:8" + string(retime ? " -dff" : "")); + Pass::call(design, "abc -lut 6:8" + string(retime ? " -dff" : "")); Pass::call(design, "clean"); } |