From 288ba9618af9c5ba9db1131955c92d59166d120d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Sep 2013 11:52:57 +0200 Subject: Moved common techlib files to techlibs/common --- Makefile | 2 +- manual/CHAPTER_CellLib.tex | 4 +- manual/CHAPTER_Techmap.tex | 2 +- passes/techmap/Makefile.inc | 2 +- techlibs/Makefile.inc | 7 - techlibs/blackbox.sed | 4 - techlibs/common/Makefile.inc | 7 + techlibs/common/blackbox.sed | 4 + techlibs/common/simlib.v | 944 +++++++++++++++++++++++++ techlibs/common/stdcells.v | 1522 ++++++++++++++++++++++++++++++++++++++++ techlibs/common/stdcells_sim.v | 166 +++++ techlibs/simlib.v | 944 ------------------------- techlibs/stdcells.v | 1522 ---------------------------------------- techlibs/stdcells_sim.v | 166 ----- tests/i2c_bench/run-test.sh | 4 +- tests/tools/autotest.sh | 4 +- tests/tools/rtlview.sh | 2 +- 17 files changed, 2653 insertions(+), 2653 deletions(-) delete mode 100644 techlibs/Makefile.inc delete mode 100644 techlibs/blackbox.sed create mode 100644 techlibs/common/Makefile.inc create mode 100644 techlibs/common/blackbox.sed create mode 100644 techlibs/common/simlib.v create mode 100644 techlibs/common/stdcells.v create mode 100644 techlibs/common/stdcells_sim.v delete mode 100644 techlibs/simlib.v delete mode 100644 techlibs/stdcells.v delete mode 100644 techlibs/stdcells_sim.v diff --git a/Makefile b/Makefile index 21da8852..8205b43a 100644 --- a/Makefile +++ b/Makefile @@ -73,7 +73,7 @@ endif include frontends/*/Makefile.inc include passes/*/Makefile.inc include backends/*/Makefile.inc -include techlibs/Makefile.inc +include techlibs/*/Makefile.inc top-all: $(TARGETS) $(EXTRA_TARGETS) diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index b4f98812..09be0870 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -22,7 +22,7 @@ Note that all RTL cells have parameters indicating the size of inputs and output passes modify RTL cells they must always keep the values of these parameters in sync with the size of the signals connected to the inputs and outputs. -Simulation models for the RTL cells can be found in the file {\tt techlibs/simlib.v} in the Yosys +Simulation models for the RTL cells can be found in the file {\tt techlibs/common/simlib.v} in the Yosys source tree. \subsection{Unary Operators} @@ -347,7 +347,7 @@ Add a brief description of the {\tt \$fsm} cell type. For gate level logic networks, fixed function single bit cells are used that do not provide any parameters. -Simulation models for these cells can be found in the file {\tt techlibs/stdcells\_sim.v} in the Yosys +Simulation models for these cells can be found in the file {\tt techlibs/common/stdcells\_sim.v} in the Yosys source tree. \begin{table}[t] diff --git a/manual/CHAPTER_Techmap.tex b/manual/CHAPTER_Techmap.tex index 6a84864e..be74c356 100644 --- a/manual/CHAPTER_Techmap.tex +++ b/manual/CHAPTER_Techmap.tex @@ -27,7 +27,7 @@ cells with the provided implementation. When no map file is provided, {\tt techmap} uses a built-in map file that maps the Yosys RTL cell types to the internal gate library used by Yosys. -The curious reader may find this map file as {\tt techlibs/stdcells.v} in +The curious reader may find this map file as {\tt techlibs/common/stdcells.v} in the Yosys source tree. Additional features have been added to {\tt techmap} to allow for conditional diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index 97023625..15295066 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -2,7 +2,7 @@ GENFILES += passes/techmap/stdcells.inc OBJS += passes/techmap/techmap.o -passes/techmap/stdcells.inc: techlibs/stdcells.v +passes/techmap/stdcells.inc: techlibs/common/stdcells.v echo "// autogenerated from $<" > $@.new od -v -td1 -w1 $< | awk 'BEGIN { print "static char stdcells_code[] = {"; } $$2 != "" { print $$2 ","; } \ END { print 0 "};"; }' | fmt >> $@.new diff --git a/techlibs/Makefile.inc b/techlibs/Makefile.inc deleted file mode 100644 index 6c2a5f66..00000000 --- a/techlibs/Makefile.inc +++ /dev/null @@ -1,7 +0,0 @@ - -EXTRA_TARGETS += techlibs/blackbox.v - -techlibs/blackbox.v: techlibs/blackbox.sed techlibs/simlib.v techlibs/stdcells_sim.v - cat techlibs/simlib.v techlibs/stdcells_sim.v | sed -rf techlibs/blackbox.sed > techlibs/blackbox.v.new - mv techlibs/blackbox.v.new techlibs/blackbox.v - diff --git a/techlibs/blackbox.sed b/techlibs/blackbox.sed deleted file mode 100644 index 4e9a3a7c..00000000 --- a/techlibs/blackbox.sed +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sed -r -/^(wire|assign|reg)/ d; -/^(genvar|always|initial)/,/^end/ d; -s/ reg / /; diff --git a/techlibs/common/Makefile.inc b/techlibs/common/Makefile.inc new file mode 100644 index 00000000..ad007645 --- /dev/null +++ b/techlibs/common/Makefile.inc @@ -0,0 +1,7 @@ + +EXTRA_TARGETS += techlibs/common/blackbox.v + +techlibs/common/blackbox.v: techlibs/common/blackbox.sed techlibs/common/simlib.v techlibs/common/stdcells_sim.v + cat techlibs/common/simlib.v techlibs/common/stdcells_sim.v | sed -rf techlibs/common/blackbox.sed > techlibs/common/blackbox.v.new + mv techlibs/common/blackbox.v.new techlibs/common/blackbox.v + diff --git a/techlibs/common/blackbox.sed b/techlibs/common/blackbox.sed new file mode 100644 index 00000000..4e9a3a7c --- /dev/null +++ b/techlibs/common/blackbox.sed @@ -0,0 +1,4 @@ +#!/bin/sed -r +/^(wire|assign|reg)/ d; +/^(genvar|always|initial)/,/^end/ d; +s/ reg / /; diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v new file mode 100644 index 00000000..7cd9906c --- /dev/null +++ b/techlibs/common/simlib.v @@ -0,0 +1,944 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * 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. + * + * --- + * + * The Simulation Library. + * + * 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 + * by the different frontends and passes. + * + * Note that memory can only be simulated when all $memrd and $memwr cells + * have been merged to stand-alone $mem cells (this is what the "memory_collect" + * pass is doing). + * + */ + +`define INPUT_A \ +input [A_WIDTH-1:0] A; \ +generate if (A_SIGNED) begin:A_BUF wire signed [A_WIDTH-1:0] val = A; end else begin:A_BUF wire [A_WIDTH-1:0] val = A; end endgenerate + +`define INPUT_B \ +input [B_WIDTH-1:0] B; \ +generate if (B_SIGNED) begin:B_BUF wire signed [B_WIDTH-1:0] val = B; end else begin:B_BUF wire [B_WIDTH-1:0] val = B; end endgenerate + +// -------------------------------------------------------- + +module \$not (A, Y); + +parameter A_SIGNED = 0; +parameter A_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +output [Y_WIDTH-1:0] Y; + +assign Y = ~A_BUF.val; + +endmodule + + +// -------------------------------------------------------- + +module \$pos (A, Y); + +parameter A_SIGNED = 0; +parameter A_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +output [Y_WIDTH-1:0] Y; + +assign Y = +A_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$neg (A, Y); + +parameter A_SIGNED = 0; +parameter A_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +output [Y_WIDTH-1:0] Y; + +assign Y = -A_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$and (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val & B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$or (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val | B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$xor (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val ^ B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$xnor (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val ~^ B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$reduce_and (A, Y); + +parameter A_SIGNED = 0; +parameter A_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +output Y; + +assign Y = &A_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$reduce_or (A, Y); + +parameter A_SIGNED = 0; +parameter A_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +output Y; + +assign Y = |A_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$reduce_xor (A, Y); + +parameter A_SIGNED = 0; +parameter A_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +output Y; + +assign Y = ^A_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$reduce_xnor (A, Y); + +parameter A_SIGNED = 0; +parameter A_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +output Y; + +assign Y = ~^A_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$reduce_bool (A, Y); + +parameter A_SIGNED = 0; +parameter A_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +output Y; + +assign Y = A_BUF.val != 0; + +endmodule + +// -------------------------------------------------------- + +module \$shl (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val << B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$shr (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val >> B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$sshl (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val <<< B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$sshr (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val >>> B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$lt (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val < B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$le (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val <= B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$eq (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val == B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$ne (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val != B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$ge (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val >= B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$gt (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val > B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$add (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val + B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$sub (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val - B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$mul (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val * B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$div (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val / B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$mod (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val % B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$pow (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val ** B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$logic_not (A, Y); + +parameter A_SIGNED = 0; +parameter A_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +output [Y_WIDTH-1:0] Y; + +assign Y = !A_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$logic_and (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val && B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$logic_or (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +`INPUT_A +`INPUT_B +output [Y_WIDTH-1:0] Y; + +assign Y = A_BUF.val || B_BUF.val; + +endmodule + +// -------------------------------------------------------- + +module \$mux (A, B, S, Y); + +parameter WIDTH = 0; + +input [WIDTH-1:0] A, B; +input S; +output reg [WIDTH-1:0] Y; + +always @* begin + if (S) + Y = B; + else + Y = A; +end + +endmodule + +// -------------------------------------------------------- + +module \$pmux (A, B, S, Y); + +parameter WIDTH = 0; +parameter S_WIDTH = 0; + +input [WIDTH-1:0] A; +input [WIDTH*S_WIDTH-1:0] B; +input [S_WIDTH-1:0] S; +output reg [WIDTH-1:0] Y; + +integer i; + +always @* begin + Y = A; + for (i = 0; i < S_WIDTH; i = i+1) + if (S[i]) + Y = B >> (WIDTH*i); +end + +endmodule + +// -------------------------------------------------------- + +module \$safe_pmux (A, B, S, Y); + +parameter WIDTH = 0; +parameter S_WIDTH = 0; + +input [WIDTH-1:0] A; +input [WIDTH*S_WIDTH-1:0] B; +input [S_WIDTH-1:0] S; +output reg [WIDTH-1:0] Y; + +integer i, j; + +always @* begin + j = 0; + for (i = 0; i < S_WIDTH; i = i+1) + if (S[i]) begin + Y = B >> (WIDTH*i); + j = j + 1; + end + if (j != 1) + Y = A; +end + +endmodule + +// -------------------------------------------------------- + +module \$sr (S, R, Q); + +parameter WIDTH = 0; + +input [WIDTH-1:0] S, R; +output reg [WIDTH-1:0] Q; + +integer i; +always @(S, R) + for (i = 0; i < WIDTH; i = i+1) begin + if (R[i]) + Q[i] <= 0; + else if (S[i]) + Q[i] <= 1; + end + +endmodule + +// -------------------------------------------------------- + +module \$lut (I, O); + +parameter WIDTH = 0; +parameter LUT = 0; + +input [WIDTH-1:0] I; +output reg O; + +wire lut0_out, lut1_out; + +generate + if (WIDTH <= 1) begin:simple + assign {lut1_out, lut0_out} = LUT; + end else begin:complex + \$lut #( .WIDTH(WIDTH-1), .LUT(LUT ) ) lut0 ( .I(I[WIDTH-2:0]), .O(lut0_out) ); + \$lut #( .WIDTH(WIDTH-1), .LUT(LUT >> (2**(WIDTH-1))) ) lut1 ( .I(I[WIDTH-2:0]), .O(lut1_out) ); + end +endgenerate + +always @* + casez ({I[WIDTH-1], lut0_out, lut1_out}) + 3'b?11: O = 1'b1; + 3'b?00: O = 1'b0; + 3'b0??: O = lut0_out; + 3'b1??: O = lut1_out; + default: O = 1'bx; + endcase + +endmodule + +// -------------------------------------------------------- + +module \$dff (CLK, D, Q); + +parameter WIDTH = 0; +parameter CLK_POLARITY = 1'b1; + +input CLK; +input [WIDTH-1:0] D; +output reg [WIDTH-1:0] Q; +wire pos_clk = CLK == CLK_POLARITY; + +always @(posedge pos_clk) begin + Q <= D; +end + +endmodule + +// -------------------------------------------------------- + +module \$adff (CLK, ARST, D, Q); + +parameter WIDTH = 0; +parameter CLK_POLARITY = 1'b1; +parameter ARST_POLARITY = 1'b1; +parameter ARST_VALUE = 0; + +input CLK, ARST; +input [WIDTH-1:0] D; +output reg [WIDTH-1:0] Q; +wire pos_clk = CLK == CLK_POLARITY; +wire pos_arst = ARST == ARST_POLARITY; + +always @(posedge pos_clk, posedge pos_arst) begin + if (pos_arst) + Q <= ARST_VALUE; + else + Q <= D; +end + +endmodule + +// -------------------------------------------------------- + +module \$fsm (CLK, ARST, CTRL_IN, CTRL_OUT); + +parameter NAME = ""; + +parameter CLK_POLARITY = 1'b1; +parameter ARST_POLARITY = 1'b1; + +parameter CTRL_IN_WIDTH = 1; +parameter CTRL_OUT_WIDTH = 1; + +parameter STATE_BITS = 1; +parameter STATE_NUM = 1; +parameter STATE_NUM_LOG2 = 1; +parameter STATE_RST = 0; +parameter STATE_TABLE = 1'b0; + +parameter TRANS_NUM = 1; +parameter TRANS_TABLE = 4'b0x0x; + +input CLK, ARST; +input [CTRL_IN_WIDTH-1:0] CTRL_IN; +output reg [CTRL_OUT_WIDTH-1:0] CTRL_OUT; + +wire pos_clk = CLK == CLK_POLARITY; +wire pos_arst = ARST == ARST_POLARITY; + +reg [STATE_BITS-1:0] state; +reg [STATE_BITS-1:0] state_tmp; +reg [STATE_BITS-1:0] next_state; + +reg [STATE_BITS-1:0] tr_state_in; +reg [STATE_BITS-1:0] tr_state_out; +reg [CTRL_IN_WIDTH-1:0] tr_ctrl_in; +reg [CTRL_OUT_WIDTH-1:0] tr_ctrl_out; + +integer i; + +task tr_fetch; + input [31:0] tr_num; + reg [31:0] tr_pos; + reg [STATE_NUM_LOG2-1:0] state_num; + begin + tr_pos = (2*STATE_NUM_LOG2+CTRL_IN_WIDTH+CTRL_OUT_WIDTH)*tr_num; + tr_ctrl_out = TRANS_TABLE >> tr_pos; + tr_pos = tr_pos + CTRL_OUT_WIDTH; + state_num = TRANS_TABLE >> tr_pos; + tr_state_out = STATE_TABLE >> (STATE_BITS*state_num); + tr_pos = tr_pos + STATE_NUM_LOG2; + tr_ctrl_in = TRANS_TABLE >> tr_pos; + tr_pos = tr_pos + CTRL_IN_WIDTH; + state_num = TRANS_TABLE >> tr_pos; + tr_state_in = STATE_TABLE >> (STATE_BITS*state_num); + tr_pos = tr_pos + STATE_NUM_LOG2; + end +endtask + +always @(posedge pos_clk, posedge pos_arst) begin + if (pos_arst) + state_tmp = STATE_TABLE[STATE_BITS*(STATE_RST+1)-1:STATE_BITS*STATE_RST]; + else + state_tmp = next_state; + for (i = 0; i < STATE_BITS; i = i+1) + if (state_tmp[i] === 1'bz) + state_tmp[i] = 0; + state <= state_tmp; +end + +always @(state, CTRL_IN) begin + next_state <= STATE_TABLE[STATE_BITS*(STATE_RST+1)-1:STATE_BITS*STATE_RST]; + CTRL_OUT <= 'bx; + // $display("---"); + // $display("Q: %b %b", state, CTRL_IN); + for (i = 0; i < TRANS_NUM; i = i+1) begin + tr_fetch(i); + // $display("T: %b %b -> %b %b [%d]", tr_state_in, tr_ctrl_in, tr_state_out, tr_ctrl_out, i); + casez ({state, CTRL_IN}) + {tr_state_in, tr_ctrl_in}: begin + // $display("-> %b %b <- MATCH", state, CTRL_IN); + {next_state, CTRL_OUT} <= {tr_state_out, tr_ctrl_out}; + end + endcase + end +end + +endmodule + +// -------------------------------------------------------- +`ifndef SIMLIB_NOMEM + +module \$memrd (CLK, ADDR, DATA); + +parameter MEMID = ""; +parameter ABITS = 8; +parameter WIDTH = 8; + +parameter CLK_ENABLE = 0; +parameter CLK_POLARITY = 0; + +input CLK; +input [ABITS-1:0] ADDR; +output [WIDTH-1:0] DATA; + +initial begin + $display("ERROR: Found non-simulatable instance of $memrd!"); + $finish; +end + +endmodule + +// -------------------------------------------------------- + +module \$memwr (CLK, EN, ADDR, DATA); + +parameter MEMID = ""; +parameter ABITS = 8; +parameter WIDTH = 8; + +parameter CLK_ENABLE = 0; +parameter CLK_POLARITY = 0; + +input CLK, EN; +input [ABITS-1:0] ADDR; +input [WIDTH-1:0] DATA; + +initial begin + $display("ERROR: Found non-simulatable instance of $memwr!"); + $finish; +end + +endmodule + +// -------------------------------------------------------- + +module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA); + +parameter MEMID = ""; +parameter SIZE = 256; +parameter ABITS = 8; +parameter WIDTH = 8; + +parameter RD_PORTS = 1; +parameter RD_CLK_ENABLE = 1'b1; +parameter RD_CLK_POLARITY = 1'b1; + +parameter 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*ABITS-1:0] RD_ADDR; +output reg [RD_PORTS*WIDTH-1:0] RD_DATA; + +input [WR_PORTS-1:0] WR_CLK, WR_EN; +input [WR_PORTS*ABITS-1:0] WR_ADDR; +input [WR_PORTS*WIDTH-1:0] WR_DATA; + +reg [WIDTH-1:0] data [SIZE-1:0]; +event update_async_rd; + +genvar i; +generate + + for (i = 0; i < RD_PORTS; i = i+1) begin:rd + if (RD_CLK_ENABLE[i] == 0) begin:rd_noclk + always @(RD_ADDR or update_async_rd) + RD_DATA[ (i+1)*WIDTH-1 : i*WIDTH ] <= data[ RD_ADDR[ (i+1)*ABITS-1 : i*ABITS ] ]; + end else + if (RD_CLK_POLARITY[i] == 1) begin:rd_posclk + always @(posedge RD_CLK[i]) + RD_DATA[ (i+1)*WIDTH-1 : i*WIDTH ] <= data[ RD_ADDR[ (i+1)*ABITS-1 : i*ABITS ] ]; + end else begin:rd_negclk + always @(negedge RD_CLK[i]) + RD_DATA[ (i+1)*WIDTH-1 : i*WIDTH ] <= data[ RD_ADDR[ (i+1)*ABITS-1 : i*ABITS ] ]; + end + end + + for (i = 0; i < WR_PORTS; i = i+1) begin:wr + if (WR_CLK_ENABLE[i] == 0) begin:wr_noclk + always @(WR_ADDR or WR_DATA or WR_EN) begin + if (WR_EN[i]) begin + data[ WR_ADDR[ (i+1)*ABITS-1 : i*ABITS ] ] <= WR_DATA[ (i+1)*WIDTH-1 : i*WIDTH ]; + #1 -> update_async_rd; + end + end + end else + if (RD_CLK_POLARITY[i] == 1) begin:rd_posclk + always @(posedge WR_CLK[i]) + if (WR_EN[i]) begin + data[ WR_ADDR[ (i+1)*ABITS-1 : i*ABITS ] ] <= WR_DATA[ (i+1)*WIDTH-1 : i*WIDTH ]; + #1 -> update_async_rd; + end + end else begin:rd_negclk + always @(negedge WR_CLK[i]) + if (WR_EN[i]) begin + data[ WR_ADDR[ (i+1)*ABITS-1 : i*ABITS ] ] <= WR_DATA[ (i+1)*WIDTH-1 : i*WIDTH ]; + #1 -> update_async_rd; + end + end + end + +endgenerate + +endmodule + +`endif +// -------------------------------------------------------- diff --git a/techlibs/common/stdcells.v b/techlibs/common/stdcells.v new file mode 100644 index 00000000..d861d796 --- /dev/null +++ b/techlibs/common/stdcells.v @@ -0,0 +1,1522 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * 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. + * + * --- + * + * 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 $_INV_ + * gate). Usually this logic network is then mapped to the actual technology + * using e.g. the "abc" pass. + * + * Note that this library does not map $mem cells. They must be mapped to logic + * and $dff cells using the "memory_map" pass first. (Or map it to custom cells, + * which is of course highly recommended for larger memories.) + * + */ + +// -------------------------------------------------------- + +module \$not (A, Y); + +parameter A_SIGNED = 0; +parameter A_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +output [Y_WIDTH-1:0] Y; + +wire [Y_WIDTH-1:0] A_buf; +\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); + +genvar i; +generate + for (i = 0; i < Y_WIDTH; i = i + 1) begin:V + \$_INV_ gate ( + .A(A_buf[i]), + .Y(Y[i]) + ); + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$pos (A, Y); + +parameter A_SIGNED = 0; +parameter A_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +output [Y_WIDTH-1:0] Y; + +genvar i; +generate + for (i = 0; i < Y_WIDTH; i = i + 1) begin:V + if (i < A_WIDTH) begin + assign Y[i] = A[i]; + end else if (A_SIGNED) begin + assign Y[i] = A[A_WIDTH-1]; + end else begin + assign Y[i] = 0; + end + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$neg (A, Y); + +parameter A_SIGNED = 0; +parameter A_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +output [Y_WIDTH-1:0] Y; + +\$sub #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(A_SIGNED), + .A_WIDTH(1), + .B_WIDTH(A_WIDTH), + .Y_WIDTH(Y_WIDTH) +) sub ( + .A(0), + .B(A), + .Y(Y) +); + +endmodule + +// -------------------------------------------------------- + +module \$and (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +wire [Y_WIDTH-1:0] A_buf, B_buf; +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + +genvar i; +generate + for (i = 0; i < Y_WIDTH; i = i + 1) begin:V + \$_AND_ gate ( + .A(A_buf[i]), + .B(B_buf[i]), + .Y(Y[i]) + ); + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$or (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +wire [Y_WIDTH-1:0] A_buf, B_buf; +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + +genvar i; +generate + for (i = 0; i < Y_WIDTH; i = i + 1) begin:V + \$_OR_ gate ( + .A(A_buf[i]), + .B(B_buf[i]), + .Y(Y[i]) + ); + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$xor (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +wire [Y_WIDTH-1:0] A_buf, B_buf; +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + +genvar i; +generate + for (i = 0; i < Y_WIDTH; i = i + 1) begin:V + \$_XOR_ gate ( + .A(A_buf[i]), + .B(B_buf[i]), + .Y(Y[i]) + ); + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$xnor (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +wire [Y_WIDTH-1:0] A_buf, B_buf; +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + +genvar i; +generate + for (i = 0; i < Y_WIDTH; i = i + 1) begin:V + wire tmp; + \$_XOR_ gate1 ( + .A(A_buf[i]), + .B(B_buf[i]), + .Y(tmp) + ); + \$_INV_ gate2 ( + .A(tmp), + .Y(Y[i]) + ); + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$reduce_and (A, Y); + +parameter A_SIGNED = 0; +parameter A_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +output Y; + +wire [A_WIDTH-1:0] buffer; + +genvar i; +generate + for (i = 1; i < A_WIDTH; i = i + 1) begin:V + \$_AND_ gate ( + .A(A[i]), + .B(buffer[i-1]), + .Y(buffer[i]) + ); + end +endgenerate + +assign buffer[0] = A[0]; +assign Y = buffer[A_WIDTH-1]; + +endmodule + +// -------------------------------------------------------- + +module \$reduce_or (A, Y); + +parameter A_SIGNED = 0; +parameter A_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +output Y; + +wire [A_WIDTH-1:0] buffer; + +genvar i; +generate + for (i = 1; i < A_WIDTH; i = i + 1) begin:V + \$_OR_ gate ( + .A(A[i]), + .B(buffer[i-1]), + .Y(buffer[i]) + ); + end +endgenerate + +assign buffer[0] = A[0]; +assign Y = buffer[A_WIDTH-1]; + +endmodule + +// -------------------------------------------------------- + +module \$reduce_xor (A, Y); + +parameter A_SIGNED = 0; +parameter A_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +output Y; + +wire [A_WIDTH-1:0] buffer; + +genvar i; +generate + for (i = 1; i < A_WIDTH; i = i + 1) begin:V + \$_XOR_ gate ( + .A(A[i]), + .B(buffer[i-1]), + .Y(buffer[i]) + ); + end +endgenerate + +assign buffer[0] = A[0]; +assign Y = buffer[A_WIDTH-1]; + +endmodule + + +// -------------------------------------------------------- + +module \$reduce_xnor (A, Y); + +parameter A_SIGNED = 0; +parameter A_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +output Y; + +wire [A_WIDTH-1:0] buffer; + +genvar i; +generate + for (i = 1; i < A_WIDTH; i = i + 1) begin:V + \$_XOR_ gate ( + .A(A[i]), + .B(buffer[i-1]), + .Y(buffer[i]) + ); + end +endgenerate + +assign buffer[0] = A[0]; + \$_INV_ gate_inv ( + .A(buffer[A_WIDTH-1]), + .Y(Y) +); + +endmodule + +// -------------------------------------------------------- + +module \$reduce_bool (A, Y); + +parameter A_SIGNED = 0; +parameter A_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +output Y; + +wire [A_WIDTH-1:0] buffer; + +genvar i; +generate + for (i = 1; i < A_WIDTH; i = i + 1) begin:V + \$_OR_ gate ( + .A(A[i]), + .B(buffer[i-1]), + .Y(buffer[i]) + ); + end +endgenerate + +assign buffer[0] = A[0]; +assign Y = buffer[A_WIDTH-1]; + +endmodule + +// -------------------------------------------------------- + +module \$shift (X, A, Y); + +parameter WIDTH = 1; +parameter SHIFT = 0; + +input X; +input [WIDTH-1:0] A; +output [WIDTH-1:0] Y; + +genvar i; +generate + for (i = 0; i < WIDTH; i = i + 1) begin:V + if (i+SHIFT < 0) begin + assign Y[i] = 0; + end else + if (i+SHIFT < WIDTH) begin + assign Y[i] = A[i+SHIFT]; + end else begin + assign Y[i] = X; + end + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$shl (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +parameter WIDTH = Y_WIDTH; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +genvar i; +generate + wire [WIDTH*(B_WIDTH+1)-1:0] chain; + \$pos #( + .A_SIGNED(A_SIGNED), + .A_WIDTH(A_WIDTH), + .Y_WIDTH(WIDTH) + ) expand ( + .A(A), + .Y(chain[WIDTH-1:0]) + ); + assign Y = chain[WIDTH*(B_WIDTH+1)-1 : WIDTH*B_WIDTH]; + for (i = 0; i < B_WIDTH; i = i + 1) begin:V + wire [WIDTH-1:0] unshifted, shifted, result; + assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; + assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; + \$shift #( + .WIDTH(WIDTH), + .SHIFT(0 - (2 ** (i > 30 ? 30 : i))) + ) sh ( + .X(0), + .A(unshifted), + .Y(shifted) + ); + \$mux #( + .WIDTH(WIDTH) + ) mux ( + .A(unshifted), + .B(shifted), + .Y(result), + .S(B[i]) + ); + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$shr (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +parameter WIDTH = A_WIDTH > Y_WIDTH ? A_WIDTH : Y_WIDTH; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +genvar i; +generate + wire [WIDTH*(B_WIDTH+1)-1:0] chain; + \$pos #( + .A_SIGNED(A_SIGNED), + .A_WIDTH(A_WIDTH), + .Y_WIDTH(WIDTH) + ) expand ( + .A(A), + .Y(chain[WIDTH-1:0]) + ); + assign Y = chain[WIDTH*(B_WIDTH+1)-1 : WIDTH*B_WIDTH]; + for (i = 0; i < B_WIDTH; i = i + 1) begin:V + wire [WIDTH-1:0] unshifted, shifted, result; + assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; + assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; + \$shift #( + .WIDTH(WIDTH), + .SHIFT(2 ** (i > 30 ? 30 : i)) + ) sh ( + .X(0), + .A(unshifted), + .Y(shifted) + ); + \$mux #( + .WIDTH(WIDTH) + ) mux ( + .A(unshifted), + .B(shifted), + .Y(result), + .S(B[i]) + ); + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$sshl (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +parameter WIDTH = Y_WIDTH; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +genvar i; +generate + wire [WIDTH*(B_WIDTH+1)-1:0] chain; + \$pos #( + .A_SIGNED(A_SIGNED), + .A_WIDTH(A_WIDTH), + .Y_WIDTH(WIDTH) + ) expand ( + .A(A), + .Y(chain[WIDTH-1:0]) + ); + assign Y = chain[WIDTH*(B_WIDTH+1)-1 : WIDTH*B_WIDTH]; + for (i = 0; i < B_WIDTH; i = i + 1) begin:V + wire [WIDTH-1:0] unshifted, shifted, result; + assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; + assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; + \$shift #( + .WIDTH(WIDTH), + .SHIFT(0 - (2 ** (i > 30 ? 30 : i))) + ) sh ( + .X(0), + .A(unshifted), + .Y(shifted) + ); + \$mux #( + .WIDTH(WIDTH) + ) mux ( + .A(unshifted), + .B(shifted), + .Y(result), + .S(B[i]) + ); + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$sshr (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +parameter WIDTH = A_WIDTH > Y_WIDTH ? A_WIDTH : Y_WIDTH; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +genvar i; +generate + wire [WIDTH*(B_WIDTH+1)-1:0] chain; + \$pos #( + .A_SIGNED(A_SIGNED), + .A_WIDTH(A_WIDTH), + .Y_WIDTH(WIDTH) + ) expand ( + .A(A), + .Y(chain[WIDTH-1:0]) + ); + for (i = 0; i < Y_WIDTH; i = i + 1) begin:Y + if (i < WIDTH) begin + assign Y[i] = chain[WIDTH*B_WIDTH + i]; + end else + if (A_SIGNED) begin + assign Y[i] = chain[WIDTH*B_WIDTH + WIDTH-1]; + end else begin + assign Y[i] = 0; + end + end + for (i = 0; i < B_WIDTH; i = i + 1) begin:V + wire [WIDTH-1:0] unshifted, shifted, result; + assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; + assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; + \$shift #( + .WIDTH(WIDTH), + .SHIFT(2 ** (i > 30 ? 30 : i)) + ) sh ( + .X(A_SIGNED && A[A_WIDTH-1]), + .A(unshifted), + .Y(shifted) + ); + \$mux #( + .WIDTH(WIDTH) + ) mux ( + .A(unshifted), + .B(shifted), + .Y(result), + .S(B[i]) + ); + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$fulladd (A, B, C, X, Y); + +// {X, Y} = A + B + C +input A, B, C; +output X, Y; + +// {t1, t2} = A + B +wire t1, t2, t3; + + \$_AND_ gate1 ( .A(A), .B(B), .Y(t1) ); + \$_XOR_ gate2 ( .A(A), .B(B), .Y(t2) ); + \$_AND_ gate3 ( .A(t2), .B(C), .Y(t3) ); + \$_XOR_ gate4 ( .A(t2), .B(C), .Y(Y) ); + \$_OR_ gate5 ( .A(t1), .B(t3), .Y(X) ); + +endmodule + + +// -------------------------------------------------------- + +module \$alu (A, B, Cin, Y, Cout, Csign); + +parameter WIDTH = 1; + +input [WIDTH-1:0] A, B; +input Cin; + +output [WIDTH-1:0] Y; +output Cout, Csign; + +wire [WIDTH:0] carry; +assign carry[0] = Cin; +assign Cout = carry[WIDTH]; +assign Csign = carry[WIDTH-1]; + +genvar i; +generate + for (i = 0; i < WIDTH; i = i + 1) begin:V + \$fulladd adder ( + .A(A[i]), + .B(B[i]), + .C(carry[i]), + .X(carry[i+1]), + .Y(Y[i]) + ); + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$lt (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +parameter WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output Y; + +wire carry, carry_sign; +wire [WIDTH-1:0] A_buf, B_buf, Y_buf; +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); + +\$alu #( + .WIDTH(WIDTH) +) alu ( + .A(A_buf), + .B(~B_buf), + .Cin(1'b1), + .Y(Y_buf), + .Cout(carry), + .Csign(carry_sign), +); + +// ALU flags +wire cf, of, zf, sf; +assign cf = !carry; +assign of = carry ^ carry_sign; +assign zf = ~|Y_buf; +assign sf = Y_buf[WIDTH-1]; + +generate + if (A_SIGNED && B_SIGNED) begin + assign Y = of != sf; + end else begin + assign Y = cf; + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$le (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +parameter WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output Y; + +wire carry, carry_sign; +wire [WIDTH-1:0] A_buf, B_buf, Y_buf; +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); + +\$alu #( + .WIDTH(WIDTH) +) alu ( + .A(A_buf), + .B(~B_buf), + .Cin(1'b1), + .Y(Y_buf), + .Cout(carry), + .Csign(carry_sign), +); + +// ALU flags +wire cf, of, zf, sf; +assign cf = !carry; +assign of = carry ^ carry_sign; +assign zf = ~|Y_buf; +assign sf = Y_buf[WIDTH-1]; + +generate + if (A_SIGNED && B_SIGNED) begin + assign Y = zf || (of != sf); + end else begin + assign Y = zf || cf; + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$eq (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +parameter WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output Y; + +wire carry, carry_sign; +wire [WIDTH-1:0] A_buf, B_buf; +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); + +assign Y = ~|(A_buf ^ B_buf); + +endmodule + +// -------------------------------------------------------- + +module \$ne (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +parameter WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output Y; + +wire carry, carry_sign; +wire [WIDTH-1:0] A_buf, B_buf; +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); + +assign Y = |(A_buf ^ B_buf); + +endmodule + +// -------------------------------------------------------- + +module \$ge (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output Y; + +\$le #( + .A_SIGNED(B_SIGNED), + .B_SIGNED(A_SIGNED), + .A_WIDTH(B_WIDTH), + .B_WIDTH(A_WIDTH) +) ge_via_le ( + .A(B), + .B(A), + .Y(Y) +); + +endmodule + +// -------------------------------------------------------- + +module \$gt (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output Y; + +\$lt #( + .A_SIGNED(B_SIGNED), + .B_SIGNED(A_SIGNED), + .A_WIDTH(B_WIDTH), + .B_WIDTH(A_WIDTH) +) gt_via_lt ( + .A(B), + .B(A), + .Y(Y) +); + +endmodule + +// -------------------------------------------------------- + +module \$add (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +wire [Y_WIDTH-1:0] A_buf, B_buf; +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + +\$alu #( + .WIDTH(Y_WIDTH) +) alu ( + .A(A_buf), + .B(B_buf), + .Cin(1'b0), + .Y(Y) +); + +endmodule + +// -------------------------------------------------------- + +module \$sub (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +wire [Y_WIDTH-1:0] A_buf, B_buf; +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + +\$alu #( + .WIDTH(Y_WIDTH) +) alu ( + .A(A_buf), + .B(~B_buf), + .Cin(1'b1), + .Y(Y) +); + +endmodule + +// -------------------------------------------------------- + +module \$arraymul (A, B, Y); + +parameter WIDTH = 8; +input [WIDTH-1:0] A, B; +output [WIDTH-1:0] Y; + +wire [WIDTH*WIDTH-1:0] partials; + +genvar i; +assign partials[WIDTH-1 : 0] = A[0] ? B : 0; +generate for (i = 1; i < WIDTH; i = i+1) begin:gen + assign partials[WIDTH*(i+1)-1 : WIDTH*i] = (A[i] ? B << i : 0) + partials[WIDTH*i-1 : WIDTH*(i-1)]; +end endgenerate + +assign Y = partials[WIDTH*WIDTH-1 : WIDTH*(WIDTH-1)]; + +endmodule + +// -------------------------------------------------------- + +module \$mul (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +wire [Y_WIDTH-1:0] A_buf, B_buf; +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + +\$arraymul #( + .WIDTH(Y_WIDTH) +) arraymul ( + .A(A_buf), + .B(B_buf), + .Y(Y) +); + +endmodule + +// -------------------------------------------------------- + +module \$div_mod_u (A, B, Y, R); + +parameter WIDTH = 1; + +input [WIDTH-1:0] A, B; +output [WIDTH-1:0] Y, R; + +wire [WIDTH*WIDTH-1:0] chaindata; +assign R = chaindata[WIDTH*WIDTH-1:WIDTH*(WIDTH-1)]; + +genvar i; +generate begin + for (i = 0; i < WIDTH; i=i+1) begin:stage + wire [WIDTH-1:0] stage_in; + + if (i == 0) begin:cp + assign stage_in = A; + end else begin:cp + assign stage_in = chaindata[i*WIDTH-1:(i-1)*WIDTH]; + end + + assign Y[WIDTH-(i+1)] = stage_in >= {B, {WIDTH-(i+1){1'b0}}}; + assign chaindata[(i+1)*WIDTH-1:i*WIDTH] = Y[WIDTH-(i+1)] ? stage_in - {B, {WIDTH-(i+1){1'b0}}} : stage_in; + end +end endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$div_mod (A, B, Y, R); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +localparam WIDTH = + A_WIDTH >= B_WIDTH && A_WIDTH >= Y_WIDTH ? A_WIDTH : + B_WIDTH >= A_WIDTH && B_WIDTH >= Y_WIDTH ? B_WIDTH : Y_WIDTH; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y, R; + +wire [WIDTH-1:0] A_buf, B_buf; +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); +\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); + +wire [WIDTH-1:0] A_buf_u, B_buf_u, Y_u, R_u; +assign A_buf_u = A_SIGNED && B_SIGNED && A_buf[WIDTH-1] ? -A_buf : A_buf; +assign B_buf_u = A_SIGNED && B_SIGNED && B_buf[WIDTH-1] ? -B_buf : B_buf; + +\$div_mod_u #( + .WIDTH(WIDTH) +) div_mod_u ( + .A(A_buf_u), + .B(B_buf_u), + .Y(Y_u), + .R(R_u), +); + +assign Y = A_SIGNED && B_SIGNED && (A_buf[WIDTH-1] != B_buf[WIDTH-1]) ? -Y_u : Y_u; +assign R = A_SIGNED && B_SIGNED && A_buf[WIDTH-1] ? -R_u : R_u; + +endmodule + +// -------------------------------------------------------- + +module \$div (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +wire [Y_WIDTH-1:0] Y_buf; +wire [Y_WIDTH-1:0] Y_div_zero; + +\$div_mod #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(A_WIDTH), + .B_WIDTH(B_WIDTH), + .Y_WIDTH(Y_WIDTH) +) div_mod ( + .A(A), + .B(B), + .Y(Y_buf) +); + +// explicitly force the division-by-zero behavior found in other synthesis tools +generate begin + if (A_SIGNED && B_SIGNED) begin:make_div_zero + assign Y_div_zero = A[A_WIDTH-1] ? {Y_WIDTH{1'b0}} | 1'b1 : {Y_WIDTH{1'b1}}; + end else begin:make_div_zero + assign Y_div_zero = {A_WIDTH{1'b1}}; + end +end endgenerate + +assign Y = B ? Y_buf : Y_div_zero; + +endmodule + +// -------------------------------------------------------- + +module \$mod (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +wire [Y_WIDTH-1:0] Y_buf; +wire [Y_WIDTH-1:0] Y_div_zero; + +\$div_mod #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(A_WIDTH), + .B_WIDTH(B_WIDTH), + .Y_WIDTH(Y_WIDTH) +) div_mod ( + .A(A), + .B(B), + .R(Y_buf) +); + +// explicitly force the division-by-zero behavior found in other synthesis tools +localparam div_zero_copy_a_bits = A_WIDTH < B_WIDTH ? A_WIDTH : B_WIDTH; +generate begin + if (A_SIGNED && B_SIGNED) begin:make_div_zero + assign Y_div_zero = $signed(A[div_zero_copy_a_bits-1:0]); + end else begin:make_div_zero + assign Y_div_zero = $unsigned(A[div_zero_copy_a_bits-1:0]); + end +end endgenerate + +assign Y = B ? Y_buf : Y_div_zero; + +endmodule + +/**** +// -------------------------------------------------------- + +module \$pow (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +wire signed [A_WIDTH:0] buffer_a = A_SIGNED ? $signed(A) : A; +wire signed [B_WIDTH:0] buffer_b = B_SIGNED ? $signed(B) : B; + +assign Y = buffer_a ** buffer_b; + +endmodule + +// -------------------------------------------------------- +****/ + +module \$logic_not (A, Y); + +parameter A_SIGNED = 0; +parameter A_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +output [Y_WIDTH-1:0] Y; + +wire A_buf; + +\$reduce_bool #( + .A_SIGNED(A_SIGNED), + .A_WIDTH(A_WIDTH) +) A_logic ( + .A(A), + .Y(A_buf) +); + + \$_INV_ gate ( + .A(A_buf), + .Y(Y[0]) +); + +generate + if (Y_WIDTH > 1) begin:V + assign Y[Y_WIDTH-1:1] = 0; + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$logic_and (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +wire A_buf, B_buf; + +\$reduce_bool #( + .A_SIGNED(A_SIGNED), + .A_WIDTH(A_WIDTH) +) A_logic ( + .A(A), + .Y(A_buf) +); + +\$reduce_bool #( + .A_SIGNED(B_SIGNED), + .A_WIDTH(B_WIDTH) +) B_logic ( + .A(B), + .Y(B_buf) +); + + \$_AND_ gate ( + .A(A_buf), + .B(B_buf), + .Y(Y[0]) +); + +generate + if (Y_WIDTH > 1) begin:V + assign Y[Y_WIDTH-1:1] = 0; + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$logic_or (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +wire A_buf, B_buf; + +\$reduce_bool #( + .A_SIGNED(A_SIGNED), + .A_WIDTH(A_WIDTH) +) A_logic ( + .A(A), + .Y(A_buf) +); + +\$reduce_bool #( + .A_SIGNED(B_SIGNED), + .A_WIDTH(B_WIDTH) +) B_logic ( + .A(B), + .Y(B_buf) +); + + \$_OR_ gate ( + .A(A_buf), + .B(B_buf), + .Y(Y[0]) +); + +generate + if (Y_WIDTH > 1) begin:V + assign Y[Y_WIDTH-1:1] = 0; + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$mux (A, B, S, Y); + +parameter WIDTH = 1; + +input [WIDTH-1:0] A, B; +input S; +output [WIDTH-1:0] Y; + +genvar i; +generate + for (i = 0; i < WIDTH; i = i + 1) begin:V + \$_MUX_ gate ( + .A(A[i]), + .B(B[i]), + .S(S), + .Y(Y[i]) + ); + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$pmux (A, B, S, Y); + +parameter WIDTH = 1; +parameter S_WIDTH = 1; + +input [WIDTH-1:0] A; +input [WIDTH*S_WIDTH-1:0] B; +input [S_WIDTH-1:0] S; +output [WIDTH-1:0] Y; + +wire [WIDTH-1:0] Y_B; + +genvar i, j; +generate + wire [WIDTH*S_WIDTH-1:0] B_AND_S; + for (i = 0; i < S_WIDTH; i = i + 1) begin:B_AND + assign B_AND_S[WIDTH*(i+1)-1:WIDTH*i] = B[WIDTH*(i+1)-1:WIDTH*i] & {WIDTH{S[i]}}; + end:B_AND + for (i = 0; i < WIDTH; i = i + 1) begin:B_OR + wire [S_WIDTH-1:0] B_AND_BITS; + for (j = 0; j < S_WIDTH; j = j + 1) begin:B_AND_BITS_COLLECT + assign B_AND_BITS[j] = B_AND_S[WIDTH*j+i]; + end:B_AND_BITS_COLLECT + assign Y_B[i] = |B_AND_BITS; + end:B_OR +endgenerate + +assign Y = |S ? Y_B : A; + +endmodule + +// -------------------------------------------------------- + +module \$safe_pmux (A, B, S, Y); + +parameter WIDTH = 1; +parameter S_WIDTH = 1; + +input [WIDTH-1:0] A; +input [WIDTH*S_WIDTH-1:0] B; +input [S_WIDTH-1:0] S; +output [WIDTH-1:0] Y; + +wire [S_WIDTH-1:0] status_found_first; +wire [S_WIDTH-1:0] status_found_second; + +genvar i; +generate + for (i = 0; i < S_WIDTH; i = i + 1) begin:GEN1 + wire pre_first; + if (i > 0) begin:GEN2 + assign pre_first = status_found_first[i-1]; + end:GEN2 else begin:GEN3 + assign pre_first = 0; + end:GEN3 + assign status_found_first[i] = pre_first | S[i]; + assign status_found_second[i] = pre_first & S[i]; + end:GEN1 +endgenerate + +\$pmux #( + .WIDTH(WIDTH), + .S_WIDTH(S_WIDTH) +) pmux_cell ( + .A(A), + .B(B), + .S(S & {S_WIDTH{~|status_found_second}}), + .Y(Y) +); + +endmodule + +// -------------------------------------------------------- + +module \$dff (CLK, D, Q); + +parameter WIDTH = 1; +parameter CLK_POLARITY = 1'b1; + +input CLK; +input [WIDTH-1:0] D; +output [WIDTH-1:0] Q; + +genvar i; +generate + if (CLK_POLARITY == 0) + for (i = 0; i < WIDTH; i = i + 1) begin:V + \$_DFF_N_ ff ( + .D(D[i]), + .Q(Q[i]), + .C(CLK) + ); + end + if (CLK_POLARITY != 0) + for (i = 0; i < WIDTH; i = i + 1) begin:V + \$_DFF_P_ ff ( + .D(D[i]), + .Q(Q[i]), + .C(CLK) + ); + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$adff (CLK, ARST, D, Q); + +parameter WIDTH = 1; +parameter CLK_POLARITY = 1'b1; +parameter ARST_POLARITY = 1'b1; +parameter ARST_VALUE = 0; + +input CLK, ARST; +input [WIDTH-1:0] D; +output [WIDTH-1:0] Q; + +genvar i; +generate + for (i = 0; i < WIDTH; i = i + 1) begin:V + if (CLK_POLARITY == 0) begin:N + if (ARST_POLARITY == 0) begin:NN + if (ARST_VALUE[i] == 0) begin:NN0 + \$_DFF_NN0_ ff ( + .D(D[i]), + .Q(Q[i]), + .C(CLK), + .R(ARST) + ); + end else begin:NN1 + \$_DFF_NN1_ ff ( + .D(D[i]), + .Q(Q[i]), + .C(CLK), + .R(ARST) + ); + end + end else begin:NP + if (ARST_VALUE[i] == 0) begin:NP0 + \$_DFF_NP0_ ff ( + .D(D[i]), + .Q(Q[i]), + .C(CLK), + .R(ARST) + ); + end else begin:NP1 + \$_DFF_NP1_ ff ( + .D(D[i]), + .Q(Q[i]), + .C(CLK), + .R(ARST) + ); + end + end + end else begin:P + if (ARST_POLARITY == 0) begin:PN + if (ARST_VALUE[i] == 0) begin:PN0 + \$_DFF_PN0_ ff ( + .D(D[i]), + .Q(Q[i]), + .C(CLK), + .R(ARST) + ); + end else begin:PN1 + \$_DFF_PN1_ ff ( + .D(D[i]), + .Q(Q[i]), + .C(CLK), + .R(ARST) + ); + end + end else begin:PP + if (ARST_VALUE[i] == 0) begin:PP0 + \$_DFF_PP0_ ff ( + .D(D[i]), + .Q(Q[i]), + .C(CLK), + .R(ARST) + ); + end else begin:PP1 + \$_DFF_PP1_ ff ( + .D(D[i]), + .Q(Q[i]), + .C(CLK), + .R(ARST) + ); + end + end + end + end +endgenerate + +endmodule + +// -------------------------------------------------------- + diff --git a/techlibs/common/stdcells_sim.v b/techlibs/common/stdcells_sim.v new file mode 100644 index 00000000..6e5d2719 --- /dev/null +++ b/techlibs/common/stdcells_sim.v @@ -0,0 +1,166 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * 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. + * + * --- + * + * The internal logic cell simulation library. + * + * This verilog library contains simple simulation models for the internal + * logic cells ($_INV_ , $_AND_ , ...) that are generated by the default technology + * mapper (see "stdcells.v" in this directory) and expected by the "abc" pass. + * + */ + +module \$_INV_ (A, Y); +input A; +output Y; +assign Y = ~A; +endmodule + +module \$_AND_ (A, B, Y); +input A, B; +output Y; +assign Y = A & B; +endmodule + +module \$_OR_ (A, B, Y); +input A, B; +output Y; +assign Y = A | B; +endmodule + +module \$_XOR_ (A, B, Y); +input A, B; +output Y; +assign Y = A ^ B; +endmodule + +module \$_MUX_ (A, B, S, Y); +input A, B, S; +output reg Y; +always @* begin + if (S) + Y = B; + else + Y = A; +end +endmodule + +module \$_DFF_N_ (D, Q, C); +input D, C; +output reg Q; +always @(negedge C) begin + Q <= D; +end +endmodule + +module \$_DFF_P_ (D, Q, C); +input D, C; +output reg Q; +always @(posedge C) begin + Q <= D; +end +endmodule + +module \$_DFF_NN0_ (D, Q, C, R); +input D, C, R; +output reg Q; +always @(negedge C or negedge R) begin + if (R == 0) + Q <= 0; + else + Q <= D; +end +endmodule + +module \$_DFF_NN1_ (D, Q, C, R); +input D, C, R; +output reg Q; +always @(negedge C or negedge R) begin + if (R == 0) + Q <= 1; + else + Q <= D; +end +endmodule + +module \$_DFF_NP0_ (D, Q, C, R); +input D, C, R; +output reg Q; +always @(negedge C or posedge R) begin + if (R == 1) + Q <= 0; + else + Q <= D; +end +endmodule + +module \$_DFF_NP1_ (D, Q, C, R); +input D, C, R; +output reg Q; +always @(negedge C or posedge R) begin + if (R == 1) + Q <= 1; + else + Q <= D; +end +endmodule + +module \$_DFF_PN0_ (D, Q, C, R); +input D, C, R; +output reg Q; +always @(posedge C or negedge R) begin + if (R == 0) + Q <= 0; + else + Q <= D; +end +endmodule + +module \$_DFF_PN1_ (D, Q, C, R); +input D, C, R; +output reg Q; +always @(posedge C or negedge R) begin + if (R == 0) + Q <= 1; + else + Q <= D; +end +endmodule + +module \$_DFF_PP0_ (D, Q, C, R); +input D, C, R; +output reg Q; +always @(posedge C or posedge R) begin + if (R == 1) + Q <= 0; + else + Q <= D; +end +endmodule + +module \$_DFF_PP1_ (D, Q, C, R); +input D, C, R; +output reg Q; +always @(posedge C or posedge R) begin + if (R == 1) + Q <= 1; + else + Q <= D; +end +endmodule + diff --git a/techlibs/simlib.v b/techlibs/simlib.v deleted file mode 100644 index 7cd9906c..00000000 --- a/techlibs/simlib.v +++ /dev/null @@ -1,944 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf - * - * 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. - * - * --- - * - * The Simulation Library. - * - * 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 - * by the different frontends and passes. - * - * Note that memory can only be simulated when all $memrd and $memwr cells - * have been merged to stand-alone $mem cells (this is what the "memory_collect" - * pass is doing). - * - */ - -`define INPUT_A \ -input [A_WIDTH-1:0] A; \ -generate if (A_SIGNED) begin:A_BUF wire signed [A_WIDTH-1:0] val = A; end else begin:A_BUF wire [A_WIDTH-1:0] val = A; end endgenerate - -`define INPUT_B \ -input [B_WIDTH-1:0] B; \ -generate if (B_SIGNED) begin:B_BUF wire signed [B_WIDTH-1:0] val = B; end else begin:B_BUF wire [B_WIDTH-1:0] val = B; end endgenerate - -// -------------------------------------------------------- - -module \$not (A, Y); - -parameter A_SIGNED = 0; -parameter A_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -output [Y_WIDTH-1:0] Y; - -assign Y = ~A_BUF.val; - -endmodule - - -// -------------------------------------------------------- - -module \$pos (A, Y); - -parameter A_SIGNED = 0; -parameter A_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -output [Y_WIDTH-1:0] Y; - -assign Y = +A_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$neg (A, Y); - -parameter A_SIGNED = 0; -parameter A_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -output [Y_WIDTH-1:0] Y; - -assign Y = -A_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$and (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val & B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$or (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val | B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$xor (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val ^ B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$xnor (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val ~^ B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$reduce_and (A, Y); - -parameter A_SIGNED = 0; -parameter A_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -output Y; - -assign Y = &A_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$reduce_or (A, Y); - -parameter A_SIGNED = 0; -parameter A_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -output Y; - -assign Y = |A_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$reduce_xor (A, Y); - -parameter A_SIGNED = 0; -parameter A_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -output Y; - -assign Y = ^A_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$reduce_xnor (A, Y); - -parameter A_SIGNED = 0; -parameter A_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -output Y; - -assign Y = ~^A_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$reduce_bool (A, Y); - -parameter A_SIGNED = 0; -parameter A_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -output Y; - -assign Y = A_BUF.val != 0; - -endmodule - -// -------------------------------------------------------- - -module \$shl (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val << B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$shr (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val >> B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$sshl (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val <<< B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$sshr (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val >>> B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$lt (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val < B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$le (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val <= B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$eq (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val == B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$ne (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val != B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$ge (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val >= B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$gt (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val > B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$add (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val + B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$sub (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val - B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$mul (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val * B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$div (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val / B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$mod (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val % B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$pow (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val ** B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$logic_not (A, Y); - -parameter A_SIGNED = 0; -parameter A_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -output [Y_WIDTH-1:0] Y; - -assign Y = !A_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$logic_and (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val && B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$logic_or (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 0; -parameter B_WIDTH = 0; -parameter Y_WIDTH = 0; - -`INPUT_A -`INPUT_B -output [Y_WIDTH-1:0] Y; - -assign Y = A_BUF.val || B_BUF.val; - -endmodule - -// -------------------------------------------------------- - -module \$mux (A, B, S, Y); - -parameter WIDTH = 0; - -input [WIDTH-1:0] A, B; -input S; -output reg [WIDTH-1:0] Y; - -always @* begin - if (S) - Y = B; - else - Y = A; -end - -endmodule - -// -------------------------------------------------------- - -module \$pmux (A, B, S, Y); - -parameter WIDTH = 0; -parameter S_WIDTH = 0; - -input [WIDTH-1:0] A; -input [WIDTH*S_WIDTH-1:0] B; -input [S_WIDTH-1:0] S; -output reg [WIDTH-1:0] Y; - -integer i; - -always @* begin - Y = A; - for (i = 0; i < S_WIDTH; i = i+1) - if (S[i]) - Y = B >> (WIDTH*i); -end - -endmodule - -// -------------------------------------------------------- - -module \$safe_pmux (A, B, S, Y); - -parameter WIDTH = 0; -parameter S_WIDTH = 0; - -input [WIDTH-1:0] A; -input [WIDTH*S_WIDTH-1:0] B; -input [S_WIDTH-1:0] S; -output reg [WIDTH-1:0] Y; - -integer i, j; - -always @* begin - j = 0; - for (i = 0; i < S_WIDTH; i = i+1) - if (S[i]) begin - Y = B >> (WIDTH*i); - j = j + 1; - end - if (j != 1) - Y = A; -end - -endmodule - -// -------------------------------------------------------- - -module \$sr (S, R, Q); - -parameter WIDTH = 0; - -input [WIDTH-1:0] S, R; -output reg [WIDTH-1:0] Q; - -integer i; -always @(S, R) - for (i = 0; i < WIDTH; i = i+1) begin - if (R[i]) - Q[i] <= 0; - else if (S[i]) - Q[i] <= 1; - end - -endmodule - -// -------------------------------------------------------- - -module \$lut (I, O); - -parameter WIDTH = 0; -parameter LUT = 0; - -input [WIDTH-1:0] I; -output reg O; - -wire lut0_out, lut1_out; - -generate - if (WIDTH <= 1) begin:simple - assign {lut1_out, lut0_out} = LUT; - end else begin:complex - \$lut #( .WIDTH(WIDTH-1), .LUT(LUT ) ) lut0 ( .I(I[WIDTH-2:0]), .O(lut0_out) ); - \$lut #( .WIDTH(WIDTH-1), .LUT(LUT >> (2**(WIDTH-1))) ) lut1 ( .I(I[WIDTH-2:0]), .O(lut1_out) ); - end -endgenerate - -always @* - casez ({I[WIDTH-1], lut0_out, lut1_out}) - 3'b?11: O = 1'b1; - 3'b?00: O = 1'b0; - 3'b0??: O = lut0_out; - 3'b1??: O = lut1_out; - default: O = 1'bx; - endcase - -endmodule - -// -------------------------------------------------------- - -module \$dff (CLK, D, Q); - -parameter WIDTH = 0; -parameter CLK_POLARITY = 1'b1; - -input CLK; -input [WIDTH-1:0] D; -output reg [WIDTH-1:0] Q; -wire pos_clk = CLK == CLK_POLARITY; - -always @(posedge pos_clk) begin - Q <= D; -end - -endmodule - -// -------------------------------------------------------- - -module \$adff (CLK, ARST, D, Q); - -parameter WIDTH = 0; -parameter CLK_POLARITY = 1'b1; -parameter ARST_POLARITY = 1'b1; -parameter ARST_VALUE = 0; - -input CLK, ARST; -input [WIDTH-1:0] D; -output reg [WIDTH-1:0] Q; -wire pos_clk = CLK == CLK_POLARITY; -wire pos_arst = ARST == ARST_POLARITY; - -always @(posedge pos_clk, posedge pos_arst) begin - if (pos_arst) - Q <= ARST_VALUE; - else - Q <= D; -end - -endmodule - -// -------------------------------------------------------- - -module \$fsm (CLK, ARST, CTRL_IN, CTRL_OUT); - -parameter NAME = ""; - -parameter CLK_POLARITY = 1'b1; -parameter ARST_POLARITY = 1'b1; - -parameter CTRL_IN_WIDTH = 1; -parameter CTRL_OUT_WIDTH = 1; - -parameter STATE_BITS = 1; -parameter STATE_NUM = 1; -parameter STATE_NUM_LOG2 = 1; -parameter STATE_RST = 0; -parameter STATE_TABLE = 1'b0; - -parameter TRANS_NUM = 1; -parameter TRANS_TABLE = 4'b0x0x; - -input CLK, ARST; -input [CTRL_IN_WIDTH-1:0] CTRL_IN; -output reg [CTRL_OUT_WIDTH-1:0] CTRL_OUT; - -wire pos_clk = CLK == CLK_POLARITY; -wire pos_arst = ARST == ARST_POLARITY; - -reg [STATE_BITS-1:0] state; -reg [STATE_BITS-1:0] state_tmp; -reg [STATE_BITS-1:0] next_state; - -reg [STATE_BITS-1:0] tr_state_in; -reg [STATE_BITS-1:0] tr_state_out; -reg [CTRL_IN_WIDTH-1:0] tr_ctrl_in; -reg [CTRL_OUT_WIDTH-1:0] tr_ctrl_out; - -integer i; - -task tr_fetch; - input [31:0] tr_num; - reg [31:0] tr_pos; - reg [STATE_NUM_LOG2-1:0] state_num; - begin - tr_pos = (2*STATE_NUM_LOG2+CTRL_IN_WIDTH+CTRL_OUT_WIDTH)*tr_num; - tr_ctrl_out = TRANS_TABLE >> tr_pos; - tr_pos = tr_pos + CTRL_OUT_WIDTH; - state_num = TRANS_TABLE >> tr_pos; - tr_state_out = STATE_TABLE >> (STATE_BITS*state_num); - tr_pos = tr_pos + STATE_NUM_LOG2; - tr_ctrl_in = TRANS_TABLE >> tr_pos; - tr_pos = tr_pos + CTRL_IN_WIDTH; - state_num = TRANS_TABLE >> tr_pos; - tr_state_in = STATE_TABLE >> (STATE_BITS*state_num); - tr_pos = tr_pos + STATE_NUM_LOG2; - end -endtask - -always @(posedge pos_clk, posedge pos_arst) begin - if (pos_arst) - state_tmp = STATE_TABLE[STATE_BITS*(STATE_RST+1)-1:STATE_BITS*STATE_RST]; - else - state_tmp = next_state; - for (i = 0; i < STATE_BITS; i = i+1) - if (state_tmp[i] === 1'bz) - state_tmp[i] = 0; - state <= state_tmp; -end - -always @(state, CTRL_IN) begin - next_state <= STATE_TABLE[STATE_BITS*(STATE_RST+1)-1:STATE_BITS*STATE_RST]; - CTRL_OUT <= 'bx; - // $display("---"); - // $display("Q: %b %b", state, CTRL_IN); - for (i = 0; i < TRANS_NUM; i = i+1) begin - tr_fetch(i); - // $display("T: %b %b -> %b %b [%d]", tr_state_in, tr_ctrl_in, tr_state_out, tr_ctrl_out, i); - casez ({state, CTRL_IN}) - {tr_state_in, tr_ctrl_in}: begin - // $display("-> %b %b <- MATCH", state, CTRL_IN); - {next_state, CTRL_OUT} <= {tr_state_out, tr_ctrl_out}; - end - endcase - end -end - -endmodule - -// -------------------------------------------------------- -`ifndef SIMLIB_NOMEM - -module \$memrd (CLK, ADDR, DATA); - -parameter MEMID = ""; -parameter ABITS = 8; -parameter WIDTH = 8; - -parameter CLK_ENABLE = 0; -parameter CLK_POLARITY = 0; - -input CLK; -input [ABITS-1:0] ADDR; -output [WIDTH-1:0] DATA; - -initial begin - $display("ERROR: Found non-simulatable instance of $memrd!"); - $finish; -end - -endmodule - -// -------------------------------------------------------- - -module \$memwr (CLK, EN, ADDR, DATA); - -parameter MEMID = ""; -parameter ABITS = 8; -parameter WIDTH = 8; - -parameter CLK_ENABLE = 0; -parameter CLK_POLARITY = 0; - -input CLK, EN; -input [ABITS-1:0] ADDR; -input [WIDTH-1:0] DATA; - -initial begin - $display("ERROR: Found non-simulatable instance of $memwr!"); - $finish; -end - -endmodule - -// -------------------------------------------------------- - -module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA); - -parameter MEMID = ""; -parameter SIZE = 256; -parameter ABITS = 8; -parameter WIDTH = 8; - -parameter RD_PORTS = 1; -parameter RD_CLK_ENABLE = 1'b1; -parameter RD_CLK_POLARITY = 1'b1; - -parameter 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*ABITS-1:0] RD_ADDR; -output reg [RD_PORTS*WIDTH-1:0] RD_DATA; - -input [WR_PORTS-1:0] WR_CLK, WR_EN; -input [WR_PORTS*ABITS-1:0] WR_ADDR; -input [WR_PORTS*WIDTH-1:0] WR_DATA; - -reg [WIDTH-1:0] data [SIZE-1:0]; -event update_async_rd; - -genvar i; -generate - - for (i = 0; i < RD_PORTS; i = i+1) begin:rd - if (RD_CLK_ENABLE[i] == 0) begin:rd_noclk - always @(RD_ADDR or update_async_rd) - RD_DATA[ (i+1)*WIDTH-1 : i*WIDTH ] <= data[ RD_ADDR[ (i+1)*ABITS-1 : i*ABITS ] ]; - end else - if (RD_CLK_POLARITY[i] == 1) begin:rd_posclk - always @(posedge RD_CLK[i]) - RD_DATA[ (i+1)*WIDTH-1 : i*WIDTH ] <= data[ RD_ADDR[ (i+1)*ABITS-1 : i*ABITS ] ]; - end else begin:rd_negclk - always @(negedge RD_CLK[i]) - RD_DATA[ (i+1)*WIDTH-1 : i*WIDTH ] <= data[ RD_ADDR[ (i+1)*ABITS-1 : i*ABITS ] ]; - end - end - - for (i = 0; i < WR_PORTS; i = i+1) begin:wr - if (WR_CLK_ENABLE[i] == 0) begin:wr_noclk - always @(WR_ADDR or WR_DATA or WR_EN) begin - if (WR_EN[i]) begin - data[ WR_ADDR[ (i+1)*ABITS-1 : i*ABITS ] ] <= WR_DATA[ (i+1)*WIDTH-1 : i*WIDTH ]; - #1 -> update_async_rd; - end - end - end else - if (RD_CLK_POLARITY[i] == 1) begin:rd_posclk - always @(posedge WR_CLK[i]) - if (WR_EN[i]) begin - data[ WR_ADDR[ (i+1)*ABITS-1 : i*ABITS ] ] <= WR_DATA[ (i+1)*WIDTH-1 : i*WIDTH ]; - #1 -> update_async_rd; - end - end else begin:rd_negclk - always @(negedge WR_CLK[i]) - if (WR_EN[i]) begin - data[ WR_ADDR[ (i+1)*ABITS-1 : i*ABITS ] ] <= WR_DATA[ (i+1)*WIDTH-1 : i*WIDTH ]; - #1 -> update_async_rd; - end - end - end - -endgenerate - -endmodule - -`endif -// -------------------------------------------------------- diff --git a/techlibs/stdcells.v b/techlibs/stdcells.v deleted file mode 100644 index d861d796..00000000 --- a/techlibs/stdcells.v +++ /dev/null @@ -1,1522 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf - * - * 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. - * - * --- - * - * 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 $_INV_ - * gate). Usually this logic network is then mapped to the actual technology - * using e.g. the "abc" pass. - * - * Note that this library does not map $mem cells. They must be mapped to logic - * and $dff cells using the "memory_map" pass first. (Or map it to custom cells, - * which is of course highly recommended for larger memories.) - * - */ - -// -------------------------------------------------------- - -module \$not (A, Y); - -parameter A_SIGNED = 0; -parameter A_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -output [Y_WIDTH-1:0] Y; - -wire [Y_WIDTH-1:0] A_buf; -\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); - -genvar i; -generate - for (i = 0; i < Y_WIDTH; i = i + 1) begin:V - \$_INV_ gate ( - .A(A_buf[i]), - .Y(Y[i]) - ); - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$pos (A, Y); - -parameter A_SIGNED = 0; -parameter A_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -output [Y_WIDTH-1:0] Y; - -genvar i; -generate - for (i = 0; i < Y_WIDTH; i = i + 1) begin:V - if (i < A_WIDTH) begin - assign Y[i] = A[i]; - end else if (A_SIGNED) begin - assign Y[i] = A[A_WIDTH-1]; - end else begin - assign Y[i] = 0; - end - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$neg (A, Y); - -parameter A_SIGNED = 0; -parameter A_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -output [Y_WIDTH-1:0] Y; - -\$sub #( - .A_SIGNED(A_SIGNED), - .B_SIGNED(A_SIGNED), - .A_WIDTH(1), - .B_WIDTH(A_WIDTH), - .Y_WIDTH(Y_WIDTH) -) sub ( - .A(0), - .B(A), - .Y(Y) -); - -endmodule - -// -------------------------------------------------------- - -module \$and (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire [Y_WIDTH-1:0] A_buf, B_buf; -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); - -genvar i; -generate - for (i = 0; i < Y_WIDTH; i = i + 1) begin:V - \$_AND_ gate ( - .A(A_buf[i]), - .B(B_buf[i]), - .Y(Y[i]) - ); - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$or (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire [Y_WIDTH-1:0] A_buf, B_buf; -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); - -genvar i; -generate - for (i = 0; i < Y_WIDTH; i = i + 1) begin:V - \$_OR_ gate ( - .A(A_buf[i]), - .B(B_buf[i]), - .Y(Y[i]) - ); - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$xor (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire [Y_WIDTH-1:0] A_buf, B_buf; -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); - -genvar i; -generate - for (i = 0; i < Y_WIDTH; i = i + 1) begin:V - \$_XOR_ gate ( - .A(A_buf[i]), - .B(B_buf[i]), - .Y(Y[i]) - ); - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$xnor (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire [Y_WIDTH-1:0] A_buf, B_buf; -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); - -genvar i; -generate - for (i = 0; i < Y_WIDTH; i = i + 1) begin:V - wire tmp; - \$_XOR_ gate1 ( - .A(A_buf[i]), - .B(B_buf[i]), - .Y(tmp) - ); - \$_INV_ gate2 ( - .A(tmp), - .Y(Y[i]) - ); - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$reduce_and (A, Y); - -parameter A_SIGNED = 0; -parameter A_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -output Y; - -wire [A_WIDTH-1:0] buffer; - -genvar i; -generate - for (i = 1; i < A_WIDTH; i = i + 1) begin:V - \$_AND_ gate ( - .A(A[i]), - .B(buffer[i-1]), - .Y(buffer[i]) - ); - end -endgenerate - -assign buffer[0] = A[0]; -assign Y = buffer[A_WIDTH-1]; - -endmodule - -// -------------------------------------------------------- - -module \$reduce_or (A, Y); - -parameter A_SIGNED = 0; -parameter A_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -output Y; - -wire [A_WIDTH-1:0] buffer; - -genvar i; -generate - for (i = 1; i < A_WIDTH; i = i + 1) begin:V - \$_OR_ gate ( - .A(A[i]), - .B(buffer[i-1]), - .Y(buffer[i]) - ); - end -endgenerate - -assign buffer[0] = A[0]; -assign Y = buffer[A_WIDTH-1]; - -endmodule - -// -------------------------------------------------------- - -module \$reduce_xor (A, Y); - -parameter A_SIGNED = 0; -parameter A_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -output Y; - -wire [A_WIDTH-1:0] buffer; - -genvar i; -generate - for (i = 1; i < A_WIDTH; i = i + 1) begin:V - \$_XOR_ gate ( - .A(A[i]), - .B(buffer[i-1]), - .Y(buffer[i]) - ); - end -endgenerate - -assign buffer[0] = A[0]; -assign Y = buffer[A_WIDTH-1]; - -endmodule - - -// -------------------------------------------------------- - -module \$reduce_xnor (A, Y); - -parameter A_SIGNED = 0; -parameter A_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -output Y; - -wire [A_WIDTH-1:0] buffer; - -genvar i; -generate - for (i = 1; i < A_WIDTH; i = i + 1) begin:V - \$_XOR_ gate ( - .A(A[i]), - .B(buffer[i-1]), - .Y(buffer[i]) - ); - end -endgenerate - -assign buffer[0] = A[0]; - \$_INV_ gate_inv ( - .A(buffer[A_WIDTH-1]), - .Y(Y) -); - -endmodule - -// -------------------------------------------------------- - -module \$reduce_bool (A, Y); - -parameter A_SIGNED = 0; -parameter A_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -output Y; - -wire [A_WIDTH-1:0] buffer; - -genvar i; -generate - for (i = 1; i < A_WIDTH; i = i + 1) begin:V - \$_OR_ gate ( - .A(A[i]), - .B(buffer[i-1]), - .Y(buffer[i]) - ); - end -endgenerate - -assign buffer[0] = A[0]; -assign Y = buffer[A_WIDTH-1]; - -endmodule - -// -------------------------------------------------------- - -module \$shift (X, A, Y); - -parameter WIDTH = 1; -parameter SHIFT = 0; - -input X; -input [WIDTH-1:0] A; -output [WIDTH-1:0] Y; - -genvar i; -generate - for (i = 0; i < WIDTH; i = i + 1) begin:V - if (i+SHIFT < 0) begin - assign Y[i] = 0; - end else - if (i+SHIFT < WIDTH) begin - assign Y[i] = A[i+SHIFT]; - end else begin - assign Y[i] = X; - end - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$shl (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -parameter WIDTH = Y_WIDTH; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -genvar i; -generate - wire [WIDTH*(B_WIDTH+1)-1:0] chain; - \$pos #( - .A_SIGNED(A_SIGNED), - .A_WIDTH(A_WIDTH), - .Y_WIDTH(WIDTH) - ) expand ( - .A(A), - .Y(chain[WIDTH-1:0]) - ); - assign Y = chain[WIDTH*(B_WIDTH+1)-1 : WIDTH*B_WIDTH]; - for (i = 0; i < B_WIDTH; i = i + 1) begin:V - wire [WIDTH-1:0] unshifted, shifted, result; - assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; - assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; - \$shift #( - .WIDTH(WIDTH), - .SHIFT(0 - (2 ** (i > 30 ? 30 : i))) - ) sh ( - .X(0), - .A(unshifted), - .Y(shifted) - ); - \$mux #( - .WIDTH(WIDTH) - ) mux ( - .A(unshifted), - .B(shifted), - .Y(result), - .S(B[i]) - ); - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$shr (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -parameter WIDTH = A_WIDTH > Y_WIDTH ? A_WIDTH : Y_WIDTH; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -genvar i; -generate - wire [WIDTH*(B_WIDTH+1)-1:0] chain; - \$pos #( - .A_SIGNED(A_SIGNED), - .A_WIDTH(A_WIDTH), - .Y_WIDTH(WIDTH) - ) expand ( - .A(A), - .Y(chain[WIDTH-1:0]) - ); - assign Y = chain[WIDTH*(B_WIDTH+1)-1 : WIDTH*B_WIDTH]; - for (i = 0; i < B_WIDTH; i = i + 1) begin:V - wire [WIDTH-1:0] unshifted, shifted, result; - assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; - assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; - \$shift #( - .WIDTH(WIDTH), - .SHIFT(2 ** (i > 30 ? 30 : i)) - ) sh ( - .X(0), - .A(unshifted), - .Y(shifted) - ); - \$mux #( - .WIDTH(WIDTH) - ) mux ( - .A(unshifted), - .B(shifted), - .Y(result), - .S(B[i]) - ); - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$sshl (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -parameter WIDTH = Y_WIDTH; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -genvar i; -generate - wire [WIDTH*(B_WIDTH+1)-1:0] chain; - \$pos #( - .A_SIGNED(A_SIGNED), - .A_WIDTH(A_WIDTH), - .Y_WIDTH(WIDTH) - ) expand ( - .A(A), - .Y(chain[WIDTH-1:0]) - ); - assign Y = chain[WIDTH*(B_WIDTH+1)-1 : WIDTH*B_WIDTH]; - for (i = 0; i < B_WIDTH; i = i + 1) begin:V - wire [WIDTH-1:0] unshifted, shifted, result; - assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; - assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; - \$shift #( - .WIDTH(WIDTH), - .SHIFT(0 - (2 ** (i > 30 ? 30 : i))) - ) sh ( - .X(0), - .A(unshifted), - .Y(shifted) - ); - \$mux #( - .WIDTH(WIDTH) - ) mux ( - .A(unshifted), - .B(shifted), - .Y(result), - .S(B[i]) - ); - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$sshr (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -parameter WIDTH = A_WIDTH > Y_WIDTH ? A_WIDTH : Y_WIDTH; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -genvar i; -generate - wire [WIDTH*(B_WIDTH+1)-1:0] chain; - \$pos #( - .A_SIGNED(A_SIGNED), - .A_WIDTH(A_WIDTH), - .Y_WIDTH(WIDTH) - ) expand ( - .A(A), - .Y(chain[WIDTH-1:0]) - ); - for (i = 0; i < Y_WIDTH; i = i + 1) begin:Y - if (i < WIDTH) begin - assign Y[i] = chain[WIDTH*B_WIDTH + i]; - end else - if (A_SIGNED) begin - assign Y[i] = chain[WIDTH*B_WIDTH + WIDTH-1]; - end else begin - assign Y[i] = 0; - end - end - for (i = 0; i < B_WIDTH; i = i + 1) begin:V - wire [WIDTH-1:0] unshifted, shifted, result; - assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; - assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; - \$shift #( - .WIDTH(WIDTH), - .SHIFT(2 ** (i > 30 ? 30 : i)) - ) sh ( - .X(A_SIGNED && A[A_WIDTH-1]), - .A(unshifted), - .Y(shifted) - ); - \$mux #( - .WIDTH(WIDTH) - ) mux ( - .A(unshifted), - .B(shifted), - .Y(result), - .S(B[i]) - ); - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$fulladd (A, B, C, X, Y); - -// {X, Y} = A + B + C -input A, B, C; -output X, Y; - -// {t1, t2} = A + B -wire t1, t2, t3; - - \$_AND_ gate1 ( .A(A), .B(B), .Y(t1) ); - \$_XOR_ gate2 ( .A(A), .B(B), .Y(t2) ); - \$_AND_ gate3 ( .A(t2), .B(C), .Y(t3) ); - \$_XOR_ gate4 ( .A(t2), .B(C), .Y(Y) ); - \$_OR_ gate5 ( .A(t1), .B(t3), .Y(X) ); - -endmodule - - -// -------------------------------------------------------- - -module \$alu (A, B, Cin, Y, Cout, Csign); - -parameter WIDTH = 1; - -input [WIDTH-1:0] A, B; -input Cin; - -output [WIDTH-1:0] Y; -output Cout, Csign; - -wire [WIDTH:0] carry; -assign carry[0] = Cin; -assign Cout = carry[WIDTH]; -assign Csign = carry[WIDTH-1]; - -genvar i; -generate - for (i = 0; i < WIDTH; i = i + 1) begin:V - \$fulladd adder ( - .A(A[i]), - .B(B[i]), - .C(carry[i]), - .X(carry[i+1]), - .Y(Y[i]) - ); - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$lt (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -parameter WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output Y; - -wire carry, carry_sign; -wire [WIDTH-1:0] A_buf, B_buf, Y_buf; -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); - -\$alu #( - .WIDTH(WIDTH) -) alu ( - .A(A_buf), - .B(~B_buf), - .Cin(1'b1), - .Y(Y_buf), - .Cout(carry), - .Csign(carry_sign), -); - -// ALU flags -wire cf, of, zf, sf; -assign cf = !carry; -assign of = carry ^ carry_sign; -assign zf = ~|Y_buf; -assign sf = Y_buf[WIDTH-1]; - -generate - if (A_SIGNED && B_SIGNED) begin - assign Y = of != sf; - end else begin - assign Y = cf; - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$le (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -parameter WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output Y; - -wire carry, carry_sign; -wire [WIDTH-1:0] A_buf, B_buf, Y_buf; -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); - -\$alu #( - .WIDTH(WIDTH) -) alu ( - .A(A_buf), - .B(~B_buf), - .Cin(1'b1), - .Y(Y_buf), - .Cout(carry), - .Csign(carry_sign), -); - -// ALU flags -wire cf, of, zf, sf; -assign cf = !carry; -assign of = carry ^ carry_sign; -assign zf = ~|Y_buf; -assign sf = Y_buf[WIDTH-1]; - -generate - if (A_SIGNED && B_SIGNED) begin - assign Y = zf || (of != sf); - end else begin - assign Y = zf || cf; - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$eq (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -parameter WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output Y; - -wire carry, carry_sign; -wire [WIDTH-1:0] A_buf, B_buf; -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); - -assign Y = ~|(A_buf ^ B_buf); - -endmodule - -// -------------------------------------------------------- - -module \$ne (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -parameter WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output Y; - -wire carry, carry_sign; -wire [WIDTH-1:0] A_buf, B_buf; -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); - -assign Y = |(A_buf ^ B_buf); - -endmodule - -// -------------------------------------------------------- - -module \$ge (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output Y; - -\$le #( - .A_SIGNED(B_SIGNED), - .B_SIGNED(A_SIGNED), - .A_WIDTH(B_WIDTH), - .B_WIDTH(A_WIDTH) -) ge_via_le ( - .A(B), - .B(A), - .Y(Y) -); - -endmodule - -// -------------------------------------------------------- - -module \$gt (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output Y; - -\$lt #( - .A_SIGNED(B_SIGNED), - .B_SIGNED(A_SIGNED), - .A_WIDTH(B_WIDTH), - .B_WIDTH(A_WIDTH) -) gt_via_lt ( - .A(B), - .B(A), - .Y(Y) -); - -endmodule - -// -------------------------------------------------------- - -module \$add (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire [Y_WIDTH-1:0] A_buf, B_buf; -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); - -\$alu #( - .WIDTH(Y_WIDTH) -) alu ( - .A(A_buf), - .B(B_buf), - .Cin(1'b0), - .Y(Y) -); - -endmodule - -// -------------------------------------------------------- - -module \$sub (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire [Y_WIDTH-1:0] A_buf, B_buf; -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); - -\$alu #( - .WIDTH(Y_WIDTH) -) alu ( - .A(A_buf), - .B(~B_buf), - .Cin(1'b1), - .Y(Y) -); - -endmodule - -// -------------------------------------------------------- - -module \$arraymul (A, B, Y); - -parameter WIDTH = 8; -input [WIDTH-1:0] A, B; -output [WIDTH-1:0] Y; - -wire [WIDTH*WIDTH-1:0] partials; - -genvar i; -assign partials[WIDTH-1 : 0] = A[0] ? B : 0; -generate for (i = 1; i < WIDTH; i = i+1) begin:gen - assign partials[WIDTH*(i+1)-1 : WIDTH*i] = (A[i] ? B << i : 0) + partials[WIDTH*i-1 : WIDTH*(i-1)]; -end endgenerate - -assign Y = partials[WIDTH*WIDTH-1 : WIDTH*(WIDTH-1)]; - -endmodule - -// -------------------------------------------------------- - -module \$mul (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire [Y_WIDTH-1:0] A_buf, B_buf; -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); - -\$arraymul #( - .WIDTH(Y_WIDTH) -) arraymul ( - .A(A_buf), - .B(B_buf), - .Y(Y) -); - -endmodule - -// -------------------------------------------------------- - -module \$div_mod_u (A, B, Y, R); - -parameter WIDTH = 1; - -input [WIDTH-1:0] A, B; -output [WIDTH-1:0] Y, R; - -wire [WIDTH*WIDTH-1:0] chaindata; -assign R = chaindata[WIDTH*WIDTH-1:WIDTH*(WIDTH-1)]; - -genvar i; -generate begin - for (i = 0; i < WIDTH; i=i+1) begin:stage - wire [WIDTH-1:0] stage_in; - - if (i == 0) begin:cp - assign stage_in = A; - end else begin:cp - assign stage_in = chaindata[i*WIDTH-1:(i-1)*WIDTH]; - end - - assign Y[WIDTH-(i+1)] = stage_in >= {B, {WIDTH-(i+1){1'b0}}}; - assign chaindata[(i+1)*WIDTH-1:i*WIDTH] = Y[WIDTH-(i+1)] ? stage_in - {B, {WIDTH-(i+1){1'b0}}} : stage_in; - end -end endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$div_mod (A, B, Y, R); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -localparam WIDTH = - A_WIDTH >= B_WIDTH && A_WIDTH >= Y_WIDTH ? A_WIDTH : - B_WIDTH >= A_WIDTH && B_WIDTH >= Y_WIDTH ? B_WIDTH : Y_WIDTH; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y, R; - -wire [WIDTH-1:0] A_buf, B_buf; -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(A_SIGNED && B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); - -wire [WIDTH-1:0] A_buf_u, B_buf_u, Y_u, R_u; -assign A_buf_u = A_SIGNED && B_SIGNED && A_buf[WIDTH-1] ? -A_buf : A_buf; -assign B_buf_u = A_SIGNED && B_SIGNED && B_buf[WIDTH-1] ? -B_buf : B_buf; - -\$div_mod_u #( - .WIDTH(WIDTH) -) div_mod_u ( - .A(A_buf_u), - .B(B_buf_u), - .Y(Y_u), - .R(R_u), -); - -assign Y = A_SIGNED && B_SIGNED && (A_buf[WIDTH-1] != B_buf[WIDTH-1]) ? -Y_u : Y_u; -assign R = A_SIGNED && B_SIGNED && A_buf[WIDTH-1] ? -R_u : R_u; - -endmodule - -// -------------------------------------------------------- - -module \$div (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire [Y_WIDTH-1:0] Y_buf; -wire [Y_WIDTH-1:0] Y_div_zero; - -\$div_mod #( - .A_SIGNED(A_SIGNED), - .B_SIGNED(B_SIGNED), - .A_WIDTH(A_WIDTH), - .B_WIDTH(B_WIDTH), - .Y_WIDTH(Y_WIDTH) -) div_mod ( - .A(A), - .B(B), - .Y(Y_buf) -); - -// explicitly force the division-by-zero behavior found in other synthesis tools -generate begin - if (A_SIGNED && B_SIGNED) begin:make_div_zero - assign Y_div_zero = A[A_WIDTH-1] ? {Y_WIDTH{1'b0}} | 1'b1 : {Y_WIDTH{1'b1}}; - end else begin:make_div_zero - assign Y_div_zero = {A_WIDTH{1'b1}}; - end -end endgenerate - -assign Y = B ? Y_buf : Y_div_zero; - -endmodule - -// -------------------------------------------------------- - -module \$mod (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire [Y_WIDTH-1:0] Y_buf; -wire [Y_WIDTH-1:0] Y_div_zero; - -\$div_mod #( - .A_SIGNED(A_SIGNED), - .B_SIGNED(B_SIGNED), - .A_WIDTH(A_WIDTH), - .B_WIDTH(B_WIDTH), - .Y_WIDTH(Y_WIDTH) -) div_mod ( - .A(A), - .B(B), - .R(Y_buf) -); - -// explicitly force the division-by-zero behavior found in other synthesis tools -localparam div_zero_copy_a_bits = A_WIDTH < B_WIDTH ? A_WIDTH : B_WIDTH; -generate begin - if (A_SIGNED && B_SIGNED) begin:make_div_zero - assign Y_div_zero = $signed(A[div_zero_copy_a_bits-1:0]); - end else begin:make_div_zero - assign Y_div_zero = $unsigned(A[div_zero_copy_a_bits-1:0]); - end -end endgenerate - -assign Y = B ? Y_buf : Y_div_zero; - -endmodule - -/**** -// -------------------------------------------------------- - -module \$pow (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire signed [A_WIDTH:0] buffer_a = A_SIGNED ? $signed(A) : A; -wire signed [B_WIDTH:0] buffer_b = B_SIGNED ? $signed(B) : B; - -assign Y = buffer_a ** buffer_b; - -endmodule - -// -------------------------------------------------------- -****/ - -module \$logic_not (A, Y); - -parameter A_SIGNED = 0; -parameter A_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -output [Y_WIDTH-1:0] Y; - -wire A_buf; - -\$reduce_bool #( - .A_SIGNED(A_SIGNED), - .A_WIDTH(A_WIDTH) -) A_logic ( - .A(A), - .Y(A_buf) -); - - \$_INV_ gate ( - .A(A_buf), - .Y(Y[0]) -); - -generate - if (Y_WIDTH > 1) begin:V - assign Y[Y_WIDTH-1:1] = 0; - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$logic_and (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire A_buf, B_buf; - -\$reduce_bool #( - .A_SIGNED(A_SIGNED), - .A_WIDTH(A_WIDTH) -) A_logic ( - .A(A), - .Y(A_buf) -); - -\$reduce_bool #( - .A_SIGNED(B_SIGNED), - .A_WIDTH(B_WIDTH) -) B_logic ( - .A(B), - .Y(B_buf) -); - - \$_AND_ gate ( - .A(A_buf), - .B(B_buf), - .Y(Y[0]) -); - -generate - if (Y_WIDTH > 1) begin:V - assign Y[Y_WIDTH-1:1] = 0; - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$logic_or (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire A_buf, B_buf; - -\$reduce_bool #( - .A_SIGNED(A_SIGNED), - .A_WIDTH(A_WIDTH) -) A_logic ( - .A(A), - .Y(A_buf) -); - -\$reduce_bool #( - .A_SIGNED(B_SIGNED), - .A_WIDTH(B_WIDTH) -) B_logic ( - .A(B), - .Y(B_buf) -); - - \$_OR_ gate ( - .A(A_buf), - .B(B_buf), - .Y(Y[0]) -); - -generate - if (Y_WIDTH > 1) begin:V - assign Y[Y_WIDTH-1:1] = 0; - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$mux (A, B, S, Y); - -parameter WIDTH = 1; - -input [WIDTH-1:0] A, B; -input S; -output [WIDTH-1:0] Y; - -genvar i; -generate - for (i = 0; i < WIDTH; i = i + 1) begin:V - \$_MUX_ gate ( - .A(A[i]), - .B(B[i]), - .S(S), - .Y(Y[i]) - ); - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$pmux (A, B, S, Y); - -parameter WIDTH = 1; -parameter S_WIDTH = 1; - -input [WIDTH-1:0] A; -input [WIDTH*S_WIDTH-1:0] B; -input [S_WIDTH-1:0] S; -output [WIDTH-1:0] Y; - -wire [WIDTH-1:0] Y_B; - -genvar i, j; -generate - wire [WIDTH*S_WIDTH-1:0] B_AND_S; - for (i = 0; i < S_WIDTH; i = i + 1) begin:B_AND - assign B_AND_S[WIDTH*(i+1)-1:WIDTH*i] = B[WIDTH*(i+1)-1:WIDTH*i] & {WIDTH{S[i]}}; - end:B_AND - for (i = 0; i < WIDTH; i = i + 1) begin:B_OR - wire [S_WIDTH-1:0] B_AND_BITS; - for (j = 0; j < S_WIDTH; j = j + 1) begin:B_AND_BITS_COLLECT - assign B_AND_BITS[j] = B_AND_S[WIDTH*j+i]; - end:B_AND_BITS_COLLECT - assign Y_B[i] = |B_AND_BITS; - end:B_OR -endgenerate - -assign Y = |S ? Y_B : A; - -endmodule - -// -------------------------------------------------------- - -module \$safe_pmux (A, B, S, Y); - -parameter WIDTH = 1; -parameter S_WIDTH = 1; - -input [WIDTH-1:0] A; -input [WIDTH*S_WIDTH-1:0] B; -input [S_WIDTH-1:0] S; -output [WIDTH-1:0] Y; - -wire [S_WIDTH-1:0] status_found_first; -wire [S_WIDTH-1:0] status_found_second; - -genvar i; -generate - for (i = 0; i < S_WIDTH; i = i + 1) begin:GEN1 - wire pre_first; - if (i > 0) begin:GEN2 - assign pre_first = status_found_first[i-1]; - end:GEN2 else begin:GEN3 - assign pre_first = 0; - end:GEN3 - assign status_found_first[i] = pre_first | S[i]; - assign status_found_second[i] = pre_first & S[i]; - end:GEN1 -endgenerate - -\$pmux #( - .WIDTH(WIDTH), - .S_WIDTH(S_WIDTH) -) pmux_cell ( - .A(A), - .B(B), - .S(S & {S_WIDTH{~|status_found_second}}), - .Y(Y) -); - -endmodule - -// -------------------------------------------------------- - -module \$dff (CLK, D, Q); - -parameter WIDTH = 1; -parameter CLK_POLARITY = 1'b1; - -input CLK; -input [WIDTH-1:0] D; -output [WIDTH-1:0] Q; - -genvar i; -generate - if (CLK_POLARITY == 0) - for (i = 0; i < WIDTH; i = i + 1) begin:V - \$_DFF_N_ ff ( - .D(D[i]), - .Q(Q[i]), - .C(CLK) - ); - end - if (CLK_POLARITY != 0) - for (i = 0; i < WIDTH; i = i + 1) begin:V - \$_DFF_P_ ff ( - .D(D[i]), - .Q(Q[i]), - .C(CLK) - ); - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$adff (CLK, ARST, D, Q); - -parameter WIDTH = 1; -parameter CLK_POLARITY = 1'b1; -parameter ARST_POLARITY = 1'b1; -parameter ARST_VALUE = 0; - -input CLK, ARST; -input [WIDTH-1:0] D; -output [WIDTH-1:0] Q; - -genvar i; -generate - for (i = 0; i < WIDTH; i = i + 1) begin:V - if (CLK_POLARITY == 0) begin:N - if (ARST_POLARITY == 0) begin:NN - if (ARST_VALUE[i] == 0) begin:NN0 - \$_DFF_NN0_ ff ( - .D(D[i]), - .Q(Q[i]), - .C(CLK), - .R(ARST) - ); - end else begin:NN1 - \$_DFF_NN1_ ff ( - .D(D[i]), - .Q(Q[i]), - .C(CLK), - .R(ARST) - ); - end - end else begin:NP - if (ARST_VALUE[i] == 0) begin:NP0 - \$_DFF_NP0_ ff ( - .D(D[i]), - .Q(Q[i]), - .C(CLK), - .R(ARST) - ); - end else begin:NP1 - \$_DFF_NP1_ ff ( - .D(D[i]), - .Q(Q[i]), - .C(CLK), - .R(ARST) - ); - end - end - end else begin:P - if (ARST_POLARITY == 0) begin:PN - if (ARST_VALUE[i] == 0) begin:PN0 - \$_DFF_PN0_ ff ( - .D(D[i]), - .Q(Q[i]), - .C(CLK), - .R(ARST) - ); - end else begin:PN1 - \$_DFF_PN1_ ff ( - .D(D[i]), - .Q(Q[i]), - .C(CLK), - .R(ARST) - ); - end - end else begin:PP - if (ARST_VALUE[i] == 0) begin:PP0 - \$_DFF_PP0_ ff ( - .D(D[i]), - .Q(Q[i]), - .C(CLK), - .R(ARST) - ); - end else begin:PP1 - \$_DFF_PP1_ ff ( - .D(D[i]), - .Q(Q[i]), - .C(CLK), - .R(ARST) - ); - end - end - end - end -endgenerate - -endmodule - -// -------------------------------------------------------- - diff --git a/techlibs/stdcells_sim.v b/techlibs/stdcells_sim.v deleted file mode 100644 index 6e5d2719..00000000 --- a/techlibs/stdcells_sim.v +++ /dev/null @@ -1,166 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf - * - * 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. - * - * --- - * - * The internal logic cell simulation library. - * - * This verilog library contains simple simulation models for the internal - * logic cells ($_INV_ , $_AND_ , ...) that are generated by the default technology - * mapper (see "stdcells.v" in this directory) and expected by the "abc" pass. - * - */ - -module \$_INV_ (A, Y); -input A; -output Y; -assign Y = ~A; -endmodule - -module \$_AND_ (A, B, Y); -input A, B; -output Y; -assign Y = A & B; -endmodule - -module \$_OR_ (A, B, Y); -input A, B; -output Y; -assign Y = A | B; -endmodule - -module \$_XOR_ (A, B, Y); -input A, B; -output Y; -assign Y = A ^ B; -endmodule - -module \$_MUX_ (A, B, S, Y); -input A, B, S; -output reg Y; -always @* begin - if (S) - Y = B; - else - Y = A; -end -endmodule - -module \$_DFF_N_ (D, Q, C); -input D, C; -output reg Q; -always @(negedge C) begin - Q <= D; -end -endmodule - -module \$_DFF_P_ (D, Q, C); -input D, C; -output reg Q; -always @(posedge C) begin - Q <= D; -end -endmodule - -module \$_DFF_NN0_ (D, Q, C, R); -input D, C, R; -output reg Q; -always @(negedge C or negedge R) begin - if (R == 0) - Q <= 0; - else - Q <= D; -end -endmodule - -module \$_DFF_NN1_ (D, Q, C, R); -input D, C, R; -output reg Q; -always @(negedge C or negedge R) begin - if (R == 0) - Q <= 1; - else - Q <= D; -end -endmodule - -module \$_DFF_NP0_ (D, Q, C, R); -input D, C, R; -output reg Q; -always @(negedge C or posedge R) begin - if (R == 1) - Q <= 0; - else - Q <= D; -end -endmodule - -module \$_DFF_NP1_ (D, Q, C, R); -input D, C, R; -output reg Q; -always @(negedge C or posedge R) begin - if (R == 1) - Q <= 1; - else - Q <= D; -end -endmodule - -module \$_DFF_PN0_ (D, Q, C, R); -input D, C, R; -output reg Q; -always @(posedge C or negedge R) begin - if (R == 0) - Q <= 0; - else - Q <= D; -end -endmodule - -module \$_DFF_PN1_ (D, Q, C, R); -input D, C, R; -output reg Q; -always @(posedge C or negedge R) begin - if (R == 0) - Q <= 1; - else - Q <= D; -end -endmodule - -module \$_DFF_PP0_ (D, Q, C, R); -input D, C, R; -output reg Q; -always @(posedge C or posedge R) begin - if (R == 1) - Q <= 0; - else - Q <= D; -end -endmodule - -module \$_DFF_PP1_ (D, Q, C, R); -input D, C, R; -output reg Q; -always @(posedge C or posedge R) begin - if (R == 1) - Q <= 1; - else - Q <= D; -end -endmodule - diff --git a/tests/i2c_bench/run-test.sh b/tests/i2c_bench/run-test.sh index 5fdbb059..580ce4c0 100755 --- a/tests/i2c_bench/run-test.sh +++ b/tests/i2c_bench/run-test.sh @@ -27,8 +27,8 @@ EOT ./testbench_ref -tclbatch testbench_ref.tcl vlogcomp --work syn i2c_master_syn.v -vlogcomp --work syn ../../techlibs/simlib.v -vlogcomp --work syn ../../techlibs/stdcells_sim.v +vlogcomp --work syn ../../techlibs/common/simlib.v +vlogcomp --work syn ../../techlibs/common/stdcells_sim.v vlogcomp --work syn i2c_slave_model.v vlogcomp --work syn spi_slave_model.v vlogcomp --work syn tst_bench_top.v diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index cb1e3a96..992c8563 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -130,8 +130,8 @@ do "$toolsdir"/../../yosys -b "verilog $backend_opts" "$@" -o ${bn}_syn${test_count}.v $fn $scriptfiles compile_and_run ${bn}_tb_syn${test_count} ${bn}_out_syn${test_count} \ ${bn}_tb.v ${bn}_syn${test_count}.v $libs \ - "$toolsdir"/../../techlibs/simlib.v \ - "$toolsdir"/../../techlibs/stdcells_sim.v + "$toolsdir"/../../techlibs/common/simlib.v \ + "$toolsdir"/../../techlibs/common/stdcells_sim.v if $genvcd; then mv testbench.vcd ${bn}_syn${test_count}.vcd; fi $toolsdir/cmp_tbdata ${bn}_out_ref ${bn}_out_syn${test_count} test_count=$(( test_count + 1 )) diff --git a/tests/tools/rtlview.sh b/tests/tools/rtlview.sh index 6a4adcae..61fef802 100755 --- a/tests/tools/rtlview.sh +++ b/tests/tools/rtlview.sh @@ -11,7 +11,7 @@ prjdir="$(dirname $0)/rtlview.tmp" mkdir -p "$prjdir" cp "$1" "$prjdir"/schematic.v -cp "$(dirname $0)"/../../techlibs/blackbox.v "$prjdir"/blackbox.v +cp "$(dirname $0)"/../../techlibs/common/blackbox.v "$prjdir"/blackbox.v cd "$prjdir" if fuser -s ise.out; then -- cgit v1.2.3