3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-07-01 13:08:54 +00:00

[core] add rf techlibs

This commit is contained in:
tangxifan 2026-05-14 17:33:24 -07:00
parent 54f8505045
commit d7cf53d86a
49 changed files with 34443 additions and 0 deletions

View file

@ -0,0 +1,154 @@
// Arithmetic units: adder
// Adapt from: https://github.com/chipsalliance/yosys-f4pga-plugins/blob/0ad1af26a29243a9e76379943d735e119dcd0cc6/ql-qlf-plugin/qlf_k6n10/cells_sim.v
// Many thanks to F4PGA for their contribution
(* techmap_celltype = "$alu" *)
module _80_quicklogic_alu (A, B, CI, BI, X, Y, CO);
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] X, Y;
input CI, BI;
output [Y_WIDTH-1:0] CO;
// The max. number of adders we can support in AlkaidS is (12x2-1)x4x16 = 1472
// Fail when resource limit exceeds
// Also fail when a low utilization rate is detected
// Originally prefer to defer carry mapping when < 2-bit adder is detected
// Due to a bug found in scalable seq detector, the bound is increased to 4-bit adder
wire _TECHMAP_FAIL_ = Y_WIDTH > 1472 || Y_WIDTH < 4;
generate
if ((A_WIDTH == 0 || B_WIDTH == 0) && Y_WIDTH > 0) begin
wire _TECHMAP_FAIL_ = 1;
end
endgenerate
wire [1024:0] _TECHMAP_DO_ = "splitnets CARRY; clean";
localparam Y_COL_WIDTH = 96 - 3;
localparam Y_MAX_WIDTH = 12 - 3;
(* force_downto *)
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
(* force_downto *)
wire [Y_WIDTH-1:0] AA = A_buf;
(* force_downto *)
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
wire [Y_WIDTH: 0] CARRY;
assign CO[Y_WIDTH-1:0] = CARRY[Y_WIDTH:1];
genvar i;
generate if (Y_WIDTH < Y_COL_WIDTH) begin
wire CARRY_end_buf;
wire [1024:0] _TECHMAP_DO_ = "insbuf CARRY[Y_WIDTH] CARRY_end_buf";
_fpga_adder intermediate_adder (
.cin ( ),
.cout (CARRY[0]),
.a (CI ),
.b (CI ),
.sumout ( )
);
_fpga_adder first_adder (
.cin (CARRY[0]),
.cout (CARRY[1]),
.a (AA[0] ),
.b (BB[0] ),
.sumout (Y[0] )
);
_fpga_adder pretaill_adder (
.cin (CARRY[Y_WIDTH-1] ),
.cout (CARRY_end_buf),
.a (AA[Y_WIDTH-1] ),
.b (BB[Y_WIDTH-1] ),
.sumout (Y[Y_WIDTH-1] )
);
_fpga_adder tail_adder (
.cin (CARRY_end_buf),
.cout (),
.a (1'b0),
.b (1'b0),
.sumout (CARRY[Y_WIDTH])
);
generate for (i = 1; i < Y_WIDTH-1 ; i = i+1) begin:gen3
_fpga_adder my_adder (
.cin (CARRY[i] ),
.cout (CARRY[i+1]),
.a (AA[i] ),
.b (BB[i] ),
.sumout (Y[i] )
);
end endgenerate
end else begin
generate for (i = 0; i < Y_WIDTH ; i = i+1) begin:gen4
// Due to VPR limitations regarding IO connexion to carry chain,
// we generate the carry chain input signal using an intermediate adder
// since we can connect a & b from io pads, but not cin & cout
if (i == 0) begin
_fpga_adder intermediate_adder (
.cin ( ),
.cout (CARRY[0]),
.a (CI ),
.b (CI ),
.sumout ( )
);
_fpga_adder first_adder (
.cin (CARRY[0]),
.cout (CARRY[1]),
.a (AA[0] ),
.b (BB[0] ),
.sumout (Y[0] )
);
end else if (i % (Y_MAX_WIDTH + 1) == 0) begin
wire CARRY_end_buf;
wire CARRY_start_buf;
wire [1024:0] _TECHMAP_DO_ = "insbuf CARRY[i+1] CARRY_end_buf; insbuf CARRY_end_buf CARRY_start_buf";
_fpga_adder tail_adder (
.cin (CARRY[i]),
.cout (),
.a (1'b0),
.b (1'b0),
.sumout (CARRY_end_buf)
);
_fpga_adder intermediate_adder (
.cin ( ),
.cout (CARRY_start_buf),
.a (CARRY_end_buf),
.b (1'b1),
.sumout ( )
);
_fpga_adder first_adder (
.cin (CARRY_start_buf),
.cout (CARRY[i+1]),
.a (AA[i] ),
.b (BB[i] ),
.sumout (Y[i] )
);
end else begin
_fpga_adder my_adder (
.cin (CARRY[i] ),
.cout (CARRY[i+1]),
.a (AA[i] ),
.b (BB[i] ),
.sumout (Y[i] )
);
end
end endgenerate
end endgenerate
assign X = AA ^ BB;
endmodule

View file

@ -0,0 +1,18 @@
bram $__FLEX_TDPRAM_256x36 # Name of the BRAM cell
init 0 # Set to '1' if BRAM can be initialized
abits 8 # Number of address bits
dbits 36 # Number of data bits
groups 2 # Number of port groups
ports 1 1 # Number of ports in each group
wrmode 0 1 # Set to '1' if this group is write ports
enable 1 1 # Number of enable bits
transp 0 0 # transparent (read ports)
clocks 2 3 # clock configuration
clkpol 1 1 # clock polarity configuration
endbram
match $__FLEX_TDPRAM_256x36
min efficiency 0 # Only use this bram is <=0 ram bits are used
make_transp # Add external circuitry to simulate 'transparent read' if necessary
endmatch

View file

@ -0,0 +1,38 @@
//-----------------------------
// This is a true dual-port RAM
// BUT without support on Byte-Write-Enable
// Due to limited support from Yosys
//-----------------------------
module \$__FLEX_TDPRAM_256x36 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter [0:0] CLKPOL2 = 1;
parameter [0:0] CLKPOL3 = 1;
input CLK2;
input CLK3;
input [0:7] A1ADDR;
input A1EN;
output [0:35] A1DATA;
input [0:7] B1ADDR;
input B1EN;
input [0:35] B1DATA;
generate
tdpram_core #(
.ADDR_WIDTH(8),
.BYTE_WIDTH(9),
.NUM_BYTES(4),
) _TECHMAP_REPLACE_ (
.rclk_i (CLK2),
.wclk_i (CLK3),
.bwen_ni (|1),
.wen_ni (B1EN),
.waddr_i (B1ADDR),
.data_i (B1DATA),
.ren_ni (A1EN),
.raddr_i (A1ADDR),
.q_o (A1DATA)
);
endgenerate
endmodule

View file

@ -0,0 +1,7 @@
//-------------------------------------------------
// Include all the primitives
//-------------------------------------------------
`include "cell_sim_arith.v"
`include "cell_sim_dsp.v"
`include "cell_sim_bram.v"
`include "cell_sim_ff.v"

View file

@ -0,0 +1,15 @@
//---------------------------------------
// 1-bit adder
//---------------------------------------
(* abc9_box, lib_whitebox *)
module _fpga_adder(
output sumout,
output cout,
input a,
input b,
input cin
);
assign sumout = a ^ b ^ cin;
assign cout = (a & b) | ((a | b) & cin);
endmodule

View file

@ -0,0 +1,876 @@
//-------------------------------------------------
// Block RAM Primitives
//-------------------------------------------------
//-------------------------------------------------
// True Dual-port RAM Core logic
// This module is written in a scalable way
// By default it is configured as 256x36 = 9k-bits
//
// IMPORTANT: Please do not use this module as a hard ip!!!
module tdpram_core (wclk_i,
bwen_ni,
wen_ni,
waddr_i,
data_i,
rclk_i,
ren_ni,
raddr_i,
q_o
);
// Parameters
parameter ADDR_WIDTH = 8;
parameter DEPTH = 2**ADDR_WIDTH;
parameter BYTE_WIDTH = 9;
parameter NUM_BYTES = 4;
parameter [0:0] IS_WCLK_N = 1'b0; // Indicate if the write clock is triggered at negative edge: 1 = Yes; 0 = No
parameter [0:0] IS_RCLK_N = 1'b0; // Indicate if the read clock is triggered at negative edge: 1 = Yes; 0 = No
input ren_ni;
input wen_ni;
input [0:ADDR_WIDTH-1] raddr_i;
input [0:ADDR_WIDTH-1] waddr_i;
input [0:BYTE_WIDTH*NUM_BYTES-1] bwen_ni;
input [0:BYTE_WIDTH*NUM_BYTES-1] data_i;
input wclk_i;
input rclk_i;
output [0:BYTE_WIDTH*NUM_BYTES-1] q_o;
reg [0:NUM_BYTES*BYTE_WIDTH-1] ram[0:DEPTH-1];
reg [0:NUM_BYTES*BYTE_WIDTH-1] q_reg;
integer i;
assign q_o = q_reg;
// Initial values are all random, to mimic the actual behavoir of a RAM
initial begin
for (i = 0; i < DEPTH; i = i + 1) begin
ram[i] = $random;
end
q_reg <= $random;
end
case(|IS_WCLK_N)
1'b0:
always @(posedge wclk_i) begin
if (~wen_ni) begin
for (i = 0; i < NUM_BYTES * BYTE_WIDTH; i = i + 1) begin
if (~bwen_ni[i]) begin
ram[waddr_i][i] <= data_i[i];
end
end
end
end
1'b1:
always @(negedge wclk_i) begin
if (~wen_ni) begin
for (i = 0; i < NUM_BYTES * BYTE_WIDTH; i = i + 1) begin
if (~bwen_ni[i]) begin
ram[waddr_i][i] <= data_i[i];
end
end
end
end
endcase
case(|IS_RCLK_N)
1'b0:
always @(posedge rclk_i) begin
if (~ren_ni) begin
q_reg <= ram[raddr_i];
end
end
1'b1:
always @(negedge rclk_i) begin
if (~ren_ni) begin
q_reg <= ram[raddr_i];
end
end
endcase
endmodule
//-------------------------------------------------
// True Dual-port RAM Core logic 256x36
// - read clock is triggered at
// - [x] positive edge
// - [ ] negative edge
// - write clock is triggered at
// - [x] positive edge
// - [ ] negative edge
module dpram256x36 (wclk_i,
bwen_ni,
wen_ni,
waddr_i,
data_i,
rclk_i,
ren_ni,
raddr_i,
q_o
);
input ren_ni;
input wen_ni;
input [0:7] raddr_i;
input [0:7] waddr_i;
input [0:35] bwen_ni;
input [0:35] data_i;
input wclk_i;
input rclk_i;
output [0:35] q_o;
tdpram_core #(
.ADDR_WIDTH(8),
.BYTE_WIDTH(9),
.NUM_BYTES(4),
.IS_WCLK_N(0),
.IS_RCLK_N(0)
) tdpram_core (
.rclk_i (rclk_i),
.wclk_i (wclk_i),
.bwen_ni (bwen_ni),
.wen_ni (wen_ni),
.waddr_i (waddr_i),
.data_i (data_i),
.ren_ni (ren_ni),
.raddr_i (raddr_i),
.q_o (q_o)
);
endmodule
//-------------------------------------------------
// True Dual-port RAM Core logic 256x36
// - read clock is triggered at
// - [x] positive edge
// - [ ] negative edge
// - write clock is triggered at
// - [ ] positive edge
// - [x] negative edge
module dpram256x36_wclkn (wclk_i,
bwen_ni,
wen_ni,
waddr_i,
data_i,
rclk_i,
ren_ni,
raddr_i,
q_o
);
input ren_ni;
input wen_ni;
input [0:7] raddr_i;
input [0:7] waddr_i;
input [0:35] bwen_ni;
input [0:35] data_i;
input wclk_i;
input rclk_i;
output [0:35] q_o;
tdpram_core #(
.ADDR_WIDTH(8),
.BYTE_WIDTH(9),
.NUM_BYTES(4),
.IS_WCLK_N(1),
.IS_RCLK_N(0)
) tdpram_core (
.rclk_i (rclk_i),
.wclk_i (wclk_i),
.bwen_ni (bwen_ni),
.wen_ni (wen_ni),
.waddr_i (waddr_i),
.data_i (data_i),
.ren_ni (ren_ni),
.raddr_i (raddr_i),
.q_o (q_o)
);
endmodule
//-------------------------------------------------
// True Dual-port RAM Core logic 256x36
// - read clock is triggered at
// - [ ] positive edge
// - [x] negative edge
// - write clock is triggered at
// - [x] positive edge
// - [ ] negative edge
module dpram256x36_rclkn (wclk_i,
bwen_ni,
wen_ni,
waddr_i,
data_i,
rclk_i,
ren_ni,
raddr_i,
q_o
);
input ren_ni;
input wen_ni;
input [0:7] raddr_i;
input [0:7] waddr_i;
input [0:35] bwen_ni;
input [0:35] data_i;
input wclk_i;
input rclk_i;
output [0:35] q_o;
tdpram_core #(
.ADDR_WIDTH(8),
.BYTE_WIDTH(9),
.NUM_BYTES(4),
.IS_WCLK_N(0),
.IS_RCLK_N(1)
) tdpram_core (
.rclk_i (rclk_i),
.wclk_i (wclk_i),
.bwen_ni (bwen_ni),
.wen_ni (wen_ni),
.waddr_i (waddr_i),
.data_i (data_i),
.ren_ni (ren_ni),
.raddr_i (raddr_i),
.q_o (q_o)
);
endmodule
//-------------------------------------------------
// True Dual-port RAM Core logic 256x36
// - read clock is triggered at
// - [ ] positive edge
// - [x] negative edge
// - write clock is triggered at
// - [ ] positive edge
// - [x] negative edge
module dpram256x36_rwclkn (wclk_i,
bwen_ni,
wen_ni,
waddr_i,
data_i,
rclk_i,
ren_ni,
raddr_i,
q_o
);
input ren_ni;
input wen_ni;
input [0:7] raddr_i;
input [0:7] waddr_i;
input [0:35] bwen_ni;
input [0:35] data_i;
input wclk_i;
input rclk_i;
output [0:35] q_o;
tdpram_core #(
.ADDR_WIDTH(8),
.BYTE_WIDTH(9),
.NUM_BYTES(4),
.IS_WCLK_N(1),
.IS_RCLK_N(1)
) tdpram_core (
.rclk_i (rclk_i),
.wclk_i (wclk_i),
.bwen_ni (bwen_ni),
.wen_ni (wen_ni),
.waddr_i (waddr_i),
.data_i (data_i),
.ren_ni (ren_ni),
.raddr_i (raddr_i),
.q_o (q_o)
);
endmodule
//-------------------------------------------------
// True Dual-port RAM Core logic 512x18
// - read clock is triggered at
// - [x] positive edge
// - [ ] negative edge
// - write clock is triggered at
// - [x] positive edge
// - [ ] negative edge
module dpram512x18 (wclk_i,
bwen_ni,
wen_ni,
waddr_i,
data_i,
rclk_i,
ren_ni,
raddr_i,
q_o
);
input ren_ni;
input wen_ni;
input [0:8] raddr_i;
input [0:8] waddr_i;
input [0:17] bwen_ni;
input [0:17] data_i;
input wclk_i;
input rclk_i;
output [0:17] q_o;
tdpram_core #(
.ADDR_WIDTH(9),
.BYTE_WIDTH(9),
.NUM_BYTES(2),
.IS_WCLK_N(0),
.IS_RCLK_N(0)
) tdpram_core (
.rclk_i (rclk_i),
.wclk_i (wclk_i),
.bwen_ni (bwen_ni),
.wen_ni (wen_ni),
.waddr_i (waddr_i),
.data_i (data_i),
.ren_ni (ren_ni),
.raddr_i (raddr_i),
.q_o (q_o)
);
endmodule
//-------------------------------------------------
// True Dual-port RAM Core logic 512x18
// - read clock is triggered at
// - [x] positive edge
// - [ ] negative edge
// - write clock is triggered at
// - [ ] positive edge
// - [x] negative edge
module dpram512x18_wclkn (wclk_i,
bwen_ni,
wen_ni,
waddr_i,
data_i,
rclk_i,
ren_ni,
raddr_i,
q_o
);
input ren_ni;
input wen_ni;
input [0:8] raddr_i;
input [0:8] waddr_i;
input [0:17] bwen_ni;
input [0:17] data_i;
input wclk_i;
input rclk_i;
output [0:17] q_o;
tdpram_core #(
.ADDR_WIDTH(9),
.BYTE_WIDTH(9),
.NUM_BYTES(2),
.IS_WCLK_N(1),
.IS_RCLK_N(0)
) tdpram_core (
.rclk_i (rclk_i),
.wclk_i (wclk_i),
.bwen_ni (bwen_ni),
.wen_ni (wen_ni),
.waddr_i (waddr_i),
.data_i (data_i),
.ren_ni (ren_ni),
.raddr_i (raddr_i),
.q_o (q_o)
);
endmodule
//-------------------------------------------------
// True Dual-port RAM Core logic 512x18
// - read clock is triggered at
// - [ ] positive edge
// - [x] negative edge
// - write clock is triggered at
// - [x] positive edge
// - [ ] negative edge
module dpram512x18_rclkn (wclk_i,
bwen_ni,
wen_ni,
waddr_i,
data_i,
rclk_i,
ren_ni,
raddr_i,
q_o
);
input ren_ni;
input wen_ni;
input [0:8] raddr_i;
input [0:8] waddr_i;
input [0:17] bwen_ni;
input [0:17] data_i;
input wclk_i;
input rclk_i;
output [0:17] q_o;
tdpram_core #(
.ADDR_WIDTH(9),
.BYTE_WIDTH(9),
.NUM_BYTES(2),
.IS_WCLK_N(0),
.IS_RCLK_N(1)
) tdpram_core (
.rclk_i (rclk_i),
.wclk_i (wclk_i),
.bwen_ni (bwen_ni),
.wen_ni (wen_ni),
.waddr_i (waddr_i),
.data_i (data_i),
.ren_ni (ren_ni),
.raddr_i (raddr_i),
.q_o (q_o)
);
endmodule
//-------------------------------------------------
// True Dual-port RAM Core logic 512x18
// - read clock is triggered at
// - [ ] positive edge
// - [x] negative edge
// - write clock is triggered at
// - [ ] positive edge
// - [x] negative edge
module dpram512x18_rwclkn (wclk_i,
bwen_ni,
wen_ni,
waddr_i,
data_i,
rclk_i,
ren_ni,
raddr_i,
q_o
);
input ren_ni;
input wen_ni;
input [0:8] raddr_i;
input [0:8] waddr_i;
input [0:17] bwen_ni;
input [0:17] data_i;
input wclk_i;
input rclk_i;
output [0:17] q_o;
tdpram_core #(
.ADDR_WIDTH(9),
.BYTE_WIDTH(9),
.NUM_BYTES(2),
.IS_WCLK_N(1),
.IS_RCLK_N(1)
) tdpram_core (
.rclk_i (rclk_i),
.wclk_i (wclk_i),
.bwen_ni (bwen_ni),
.wen_ni (wen_ni),
.waddr_i (waddr_i),
.data_i (data_i),
.ren_ni (ren_ni),
.raddr_i (raddr_i),
.q_o (q_o)
);
endmodule
//-------------------------------------------------
// True Dual-port RAM Core logic 1024x9
// - read clock is triggered at
// - [x] positive edge
// - [ ] negative edge
// - write clock is triggered at
// - [x] positive edge
// - [ ] negative edge
module dpram1024x9 (wclk_i,
bwen_ni,
wen_ni,
waddr_i,
data_i,
rclk_i,
ren_ni,
raddr_i,
q_o
);
input ren_ni;
input wen_ni;
input [0:9] raddr_i;
input [0:9] waddr_i;
input [0:8] bwen_ni;
input [0:8] data_i;
input wclk_i;
input rclk_i;
output [0:8] q_o;
tdpram_core #(
.ADDR_WIDTH(10),
.BYTE_WIDTH(9),
.NUM_BYTES(1),
.IS_WCLK_N(0),
.IS_RCLK_N(0)
) tdpram_core (
.rclk_i (rclk_i),
.wclk_i (wclk_i),
.bwen_ni (bwen_ni),
.wen_ni (wen_ni),
.waddr_i (waddr_i),
.data_i (data_i),
.ren_ni (ren_ni),
.raddr_i (raddr_i),
.q_o (q_o)
);
endmodule
//-------------------------------------------------
// True Dual-port RAM Core logic 1024x9
// - read clock is triggered at
// - [x] positive edge
// - [ ] negative edge
// - write clock is triggered at
// - [ ] positive edge
// - [x] negative edge
module dpram1024x9_wclkn (wclk_i,
bwen_ni,
wen_ni,
waddr_i,
data_i,
rclk_i,
ren_ni,
raddr_i,
q_o
);
input ren_ni;
input wen_ni;
input [0:9] raddr_i;
input [0:9] waddr_i;
input [0:8] bwen_ni;
input [0:8] data_i;
input wclk_i;
input rclk_i;
output [0:8] q_o;
tdpram_core #(
.ADDR_WIDTH(10),
.BYTE_WIDTH(9),
.NUM_BYTES(1),
.IS_WCLK_N(1),
.IS_RCLK_N(0)
) tdpram_core (
.rclk_i (rclk_i),
.wclk_i (wclk_i),
.bwen_ni (bwen_ni),
.wen_ni (wen_ni),
.waddr_i (waddr_i),
.data_i (data_i),
.ren_ni (ren_ni),
.raddr_i (raddr_i),
.q_o (q_o)
);
endmodule
//-------------------------------------------------
// True Dual-port RAM Core logic 1024x9
// - read clock is triggered at
// - [ ] positive edge
// - [x] negative edge
// - write clock is triggered at
// - [x] positive edge
// - [ ] negative edge
module dpram1024x9_rclkn (wclk_i,
bwen_ni,
wen_ni,
waddr_i,
data_i,
rclk_i,
ren_ni,
raddr_i,
q_o
);
input ren_ni;
input wen_ni;
input [0:9] raddr_i;
input [0:9] waddr_i;
input [0:8] bwen_ni;
input [0:8] data_i;
input wclk_i;
input rclk_i;
output [0:8] q_o;
tdpram_core #(
.ADDR_WIDTH(10),
.BYTE_WIDTH(9),
.NUM_BYTES(1),
.IS_WCLK_N(0),
.IS_RCLK_N(1)
) tdpram_core (
.rclk_i (rclk_i),
.wclk_i (wclk_i),
.bwen_ni (bwen_ni),
.wen_ni (wen_ni),
.waddr_i (waddr_i),
.data_i (data_i),
.ren_ni (ren_ni),
.raddr_i (raddr_i),
.q_o (q_o)
);
endmodule
//-------------------------------------------------
// True Dual-port RAM Core logic 1024x9
// - read clock is triggered at
// - [ ] positive edge
// - [x] negative edge
// - write clock is triggered at
// - [ ] positive edge
// - [x] negative edge
module dpram1024x9_rwclkn (wclk_i,
bwen_ni,
wen_ni,
waddr_i,
data_i,
rclk_i,
ren_ni,
raddr_i,
q_o
);
input ren_ni;
input wen_ni;
input [0:9] raddr_i;
input [0:9] waddr_i;
input [0:8] bwen_ni;
input [0:8] data_i;
input wclk_i;
input rclk_i;
output [0:8] q_o;
tdpram_core #(
.ADDR_WIDTH(10),
.BYTE_WIDTH(9),
.NUM_BYTES(1),
.IS_WCLK_N(1),
.IS_RCLK_N(1)
) tdpram_core (
.rclk_i (rclk_i),
.wclk_i (wclk_i),
.bwen_ni (bwen_ni),
.wen_ni (wen_ni),
.waddr_i (waddr_i),
.data_i (data_i),
.ren_ni (ren_ni),
.raddr_i (raddr_i),
.q_o (q_o)
);
endmodule
//-------------------------------------------------
// True Dual-port RAM Core logic 2048x4
// - read clock is triggered at
// - [x] positive edge
// - [ ] negative edge
// - write clock is triggered at
// - [x] positive edge
// - [ ] negative edge
module dpram2048x4 (wclk_i,
bwen_ni,
wen_ni,
waddr_i,
data_i,
rclk_i,
ren_ni,
raddr_i,
q_o
);
input ren_ni;
input wen_ni;
input [0:10] raddr_i;
input [0:10] waddr_i;
input [0:3] bwen_ni;
input [0:3] data_i;
input wclk_i;
input rclk_i;
output [0:3] q_o;
tdpram_core #(
.ADDR_WIDTH(11),
.BYTE_WIDTH(4),
.NUM_BYTES(1),
.IS_WCLK_N(0),
.IS_RCLK_N(0)
) tdpram_core (
.rclk_i (rclk_i),
.wclk_i (wclk_i),
.bwen_ni (bwen_ni),
.wen_ni (wen_ni),
.waddr_i (waddr_i),
.data_i (data_i),
.ren_ni (ren_ni),
.raddr_i (raddr_i),
.q_o (q_o)
);
endmodule
//-------------------------------------------------
// True Dual-port RAM Core logic 2048x4
// - read clock is triggered at
// - [x] positive edge
// - [ ] negative edge
// - write clock is triggered at
// - [ ] positive edge
// - [x] negative edge
module dpram2048x4_wclkn (wclk_i,
bwen_ni,
wen_ni,
waddr_i,
data_i,
rclk_i,
ren_ni,
raddr_i,
q_o
);
input ren_ni;
input wen_ni;
input [0:10] raddr_i;
input [0:10] waddr_i;
input [0:3] bwen_ni;
input [0:3] data_i;
input wclk_i;
input rclk_i;
output [0:3] q_o;
tdpram_core #(
.ADDR_WIDTH(11),
.BYTE_WIDTH(4),
.NUM_BYTES(1),
.IS_WCLK_N(1),
.IS_RCLK_N(0)
) tdpram_core (
.rclk_i (rclk_i),
.wclk_i (wclk_i),
.bwen_ni (bwen_ni),
.wen_ni (wen_ni),
.waddr_i (waddr_i),
.data_i (data_i),
.ren_ni (ren_ni),
.raddr_i (raddr_i),
.q_o (q_o)
);
endmodule
//-------------------------------------------------
// True Dual-port RAM Core logic 2048x4
// - read clock is triggered at
// - [ ] positive edge
// - [x] negative edge
// - write clock is triggered at
// - [x] positive edge
// - [ ] negative edge
module dpram2048x4_rclkn (wclk_i,
bwen_ni,
wen_ni,
waddr_i,
data_i,
rclk_i,
ren_ni,
raddr_i,
q_o
);
input ren_ni;
input wen_ni;
input [0:10] raddr_i;
input [0:10] waddr_i;
input [0:3] bwen_ni;
input [0:3] data_i;
input wclk_i;
input rclk_i;
output [0:3] q_o;
tdpram_core #(
.ADDR_WIDTH(11),
.BYTE_WIDTH(4),
.NUM_BYTES(1),
.IS_WCLK_N(0),
.IS_RCLK_N(1)
) tdpram_core (
.rclk_i (rclk_i),
.wclk_i (wclk_i),
.bwen_ni (bwen_ni),
.wen_ni (wen_ni),
.waddr_i (waddr_i),
.data_i (data_i),
.ren_ni (ren_ni),
.raddr_i (raddr_i),
.q_o (q_o)
);
endmodule
//-------------------------------------------------
// True Dual-port RAM Core logic 2048x4
// - read clock is triggered at
// - [ ] positive edge
// - [x] negative edge
// - write clock is triggered at
// - [ ] positive edge
// - [x] negative edge
module dpram2048x4_rwclkn (wclk_i,
bwen_ni,
wen_ni,
waddr_i,
data_i,
rclk_i,
ren_ni,
raddr_i,
q_o
);
input ren_ni;
input wen_ni;
input [0:10] raddr_i;
input [0:10] waddr_i;
input [0:3] bwen_ni;
input [0:3] data_i;
input wclk_i;
input rclk_i;
output [0:3] q_o;
tdpram_core #(
.ADDR_WIDTH(11),
.BYTE_WIDTH(4),
.NUM_BYTES(1),
.IS_WCLK_N(1),
.IS_RCLK_N(1)
) tdpram_core (
.rclk_i (rclk_i),
.wclk_i (wclk_i),
.bwen_ni (bwen_ni),
.wen_ni (wen_ni),
.waddr_i (waddr_i),
.data_i (data_i),
.ren_ni (ren_ni),
.raddr_i (raddr_i),
.q_o (q_o)
);
endmodule

View file

@ -0,0 +1,545 @@
//-------------------------------------------------
// DSP Primitives
//-------------------------------------------------
//-------------------------------------------------
// Multiply accumulators
module quad_mac12x10 (A0, B0, A1, B1, A2, B2, A3, B3, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input [0:A_WIDTH-1] A0;
input [0:B_WIDTH-1] B0;
input [0:A_WIDTH-1] A1;
input [0:B_WIDTH-1] B1;
input [0:A_WIDTH-1] A2;
input [0:B_WIDTH-1] B2;
input [0:A_WIDTH-1] A3;
input [0:B_WIDTH-1] B3;
output [0:Y_WIDTH-1] Y;
assign Y = A0 * B0 + A1 * B1 + A2 * B2 + A3 * B3;
endmodule
//-------------------------------------------------
// Multiply accumulators with input registering
module quad_mac12x10_regi (CLK, RSTB, A0, B0, A1, B1, A2, B2, A3, B3, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A0;
input [0:B_WIDTH-1] B0;
input [0:A_WIDTH-1] A1;
input [0:B_WIDTH-1] B1;
input [0:A_WIDTH-1] A2;
input [0:B_WIDTH-1] B2;
input [0:A_WIDTH-1] A3;
input [0:B_WIDTH-1] B3;
output [0:Y_WIDTH-1] Y;
reg [0:A_WIDTH-1] A0_reg;
reg [0:B_WIDTH-1] B0_reg;
reg [0:A_WIDTH-1] A1_reg;
reg [0:B_WIDTH-1] B1_reg;
reg [0:A_WIDTH-1] A2_reg;
reg [0:B_WIDTH-1] B2_reg;
reg [0:A_WIDTH-1] A3_reg;
reg [0:B_WIDTH-1] B3_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
A0_reg <= 0;
B0_reg <= 0;
A1_reg <= 0;
B1_reg <= 0;
A2_reg <= 0;
B2_reg <= 0;
A3_reg <= 0;
B3_reg <= 0;
end else begin
A0_reg <= A0;
B0_reg <= B0;
A1_reg <= A1;
B1_reg <= B1;
A2_reg <= A2;
B2_reg <= B2;
A3_reg <= A3;
B3_reg <= B3;
end
end
assign Y = A0_reg * B0_reg + A1_reg * B1_reg + A2_reg * B2_reg + A3_reg * B3_reg;
endmodule
//-------------------------------------------------
// Multiply accumulators with output registering
module quad_mac12x10_rego (CLK, RSTB, A0, B0, A1, B1, A2, B2, A3, B3, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A0;
input [0:B_WIDTH-1] B0;
input [0:A_WIDTH-1] A1;
input [0:B_WIDTH-1] B1;
input [0:A_WIDTH-1] A2;
input [0:B_WIDTH-1] B2;
input [0:A_WIDTH-1] A3;
input [0:B_WIDTH-1] B3;
output [0:Y_WIDTH-1] Y;
reg [0:Y_WIDTH-1] Y_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
Y_reg <= 0;
end else begin
Y_reg <= A0 * B0 + A1 * B1 + A2 * B2 + A3 * B3;
end
end
assign Y = Y_reg;
endmodule
//-------------------------------------------------
// Multiply accumulators with input and output registering
module quad_mac12x10_regio (CLK, RSTB, A0, B0, A1, B1, A2, B2, A3, B3, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A0;
input [0:B_WIDTH-1] B0;
input [0:A_WIDTH-1] A1;
input [0:B_WIDTH-1] B1;
input [0:A_WIDTH-1] A2;
input [0:B_WIDTH-1] B2;
input [0:A_WIDTH-1] A3;
input [0:B_WIDTH-1] B3;
output [0:Y_WIDTH-1] Y;
reg [0:A_WIDTH-1] A0_reg;
reg [0:B_WIDTH-1] B0_reg;
reg [0:A_WIDTH-1] A1_reg;
reg [0:B_WIDTH-1] B1_reg;
reg [0:A_WIDTH-1] A2_reg;
reg [0:B_WIDTH-1] B2_reg;
reg [0:A_WIDTH-1] A3_reg;
reg [0:B_WIDTH-1] B3_reg;
reg [0:Y_WIDTH-1] Y_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
A0_reg <= 0;
B0_reg <= 0;
A1_reg <= 0;
B1_reg <= 0;
A2_reg <= 0;
B2_reg <= 0;
A3_reg <= 0;
B3_reg <= 0;
Y_reg <= 0;
end else begin
A0_reg <= A0;
B0_reg <= B0;
A1_reg <= A1;
B1_reg <= B1;
A2_reg <= A2;
B2_reg <= B2;
A3_reg <= A3;
B3_reg <= B3;
Y_reg <= A0_reg * B0_reg + A1_reg * B1_reg + A2_reg * B2_reg + A3_reg * B3_reg;
end
end
assign Y = Y_reg;
endmodule
module quad_mac12x10_dual_output (A0, B0, A1, B1, A2, B2, A3, B3, Y0, Y1);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input [0:A_WIDTH-1] A0;
input [0:B_WIDTH-1] B0;
input [0:A_WIDTH-1] A1;
input [0:B_WIDTH-1] B1;
input [0:A_WIDTH-1] A2;
input [0:B_WIDTH-1] B2;
input [0:A_WIDTH-1] A3;
input [0:B_WIDTH-1] B3;
output [0:Y_WIDTH-1] Y0;
output [0:Y_WIDTH-1] Y1;
assign Y0 = A0 * B0 + A1 * B1 + A2 * B2 + A3 * B3;
assign Y1 = A2 * B2 + A3 * B3;
endmodule
module mac12x10 (A0, B0, A1, B1, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input [0:A_WIDTH-1] A0;
input [0:B_WIDTH-1] B0;
input [0:A_WIDTH-1] A1;
input [0:B_WIDTH-1] B1;
output [0:Y_WIDTH-1] Y;
assign Y = A0 * B0 + A1 * B1;
endmodule
module mac12x10_regi (CLK, RSTB, A0, B0, A1, B1, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A0;
input [0:B_WIDTH-1] B0;
input [0:A_WIDTH-1] A1;
input [0:B_WIDTH-1] B1;
output [0:Y_WIDTH-1] Y;
reg [0:A_WIDTH-1] A0_reg;
reg [0:B_WIDTH-1] B0_reg;
reg [0:A_WIDTH-1] A1_reg;
reg [0:B_WIDTH-1] B1_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
A0_reg <= 0;
B0_reg <= 0;
A1_reg <= 0;
B1_reg <= 0;
end else begin
A0_reg <= A0;
B0_reg <= B0;
A1_reg <= A1;
B1_reg <= B1;
end
end
assign Y = A0_reg * B0_reg + A1_reg * B1_reg;
endmodule
module mac12x10_rego (CLK, RSTB, A0, B0, A1, B1, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A0;
input [0:B_WIDTH-1] B0;
input [0:A_WIDTH-1] A1;
input [0:B_WIDTH-1] B1;
output [0:Y_WIDTH-1] Y;
reg [0:Y_WIDTH-1] Y_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
Y_reg <= 0;
end else begin
Y_reg <= A0 * B0 + A1 * B1;
end
end
assign Y = Y_reg;
endmodule
module mac12x10_regio (CLK, RSTB, A0, B0, A1, B1, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A0;
input [0:B_WIDTH-1] B0;
input [0:A_WIDTH-1] A1;
input [0:B_WIDTH-1] B1;
output [0:Y_WIDTH-1] Y;
reg [0:A_WIDTH-1] A0_reg;
reg [0:B_WIDTH-1] B0_reg;
reg [0:A_WIDTH-1] A1_reg;
reg [0:B_WIDTH-1] B1_reg;
reg [0:Y_WIDTH-1] Y_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
A0_reg <= 0;
B0_reg <= 0;
A1_reg <= 0;
B1_reg <= 0;
Y_reg <= 0;
end else begin
A0_reg <= A0;
B0_reg <= B0;
A1_reg <= A1;
B1_reg <= B1;
Y_reg = A0_reg * B0_reg + A1_reg * B1_reg;
end
end
assign Y = Y_reg;
endmodule
//-------------------------------------------------
// Multipliers
module mult12x10 (A, B, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input [0:A_WIDTH-1] A;
input [0:B_WIDTH-1] B;
output [0:Y_WIDTH-1] Y;
assign Y = A * B;
endmodule
module mult12x10_regi (CLK, RSTB, A, B, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A;
input [0:B_WIDTH-1] B;
output [0:Y_WIDTH-1] Y;
reg [0:A_WIDTH-1] A_reg;
reg [0:B_WIDTH-1] B_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
A_reg <= 0;
B_reg <= 0;
end else begin
A_reg <= A;
B_reg <= B;
end
end
assign Y = A_reg * B_reg;
endmodule
module mult12x10_rego (CLK, RSTB, A, B, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A;
input [0:B_WIDTH-1] B;
output [0:Y_WIDTH-1] Y;
reg [0:Y_WIDTH-1] Y_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
Y_reg <= 0;
end else begin
Y_reg <= A * B;
end
end
assign Y = Y_reg;
endmodule
module mult12x10_regio (CLK, RSTB, A, B, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A;
input [0:B_WIDTH-1] B;
output [0:Y_WIDTH-1] Y;
reg [0:A_WIDTH-1] A_reg;
reg [0:B_WIDTH-1] B_reg;
reg [0:Y_WIDTH-1] Y_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
A_reg <= 0;
B_reg <= 0;
Y_reg <= 0;
end else begin
A_reg <= A;
B_reg <= B;
Y_reg <= A_reg * B_reg;
end
end
assign Y = Y_reg;
endmodule
module mult24x20 (A, B, Y);
// Parameters
parameter A_WIDTH = 24;
parameter B_WIDTH = 20;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input [0:A_WIDTH-1] A;
input [0:B_WIDTH-1] B;
output [0:Y_WIDTH-1] Y;
assign Y = A * B;
endmodule
module mult24x20_regi (CLK, RSTB, A, B, Y);
// Parameters
parameter A_WIDTH = 24;
parameter B_WIDTH = 20;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A;
input [0:B_WIDTH-1] B;
output [0:Y_WIDTH-1] Y;
reg [0:A_WIDTH-1] A_reg;
reg [0:B_WIDTH-1] B_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
A_reg <= 0;
B_reg <= 0;
end else begin
A_reg <= A;
B_reg <= B;
end
end
assign Y = A_reg * B_reg;
endmodule
module mult24x20_rego (CLK, RSTB, A, B, Y);
// Parameters
parameter A_WIDTH = 24;
parameter B_WIDTH = 20;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A;
input [0:B_WIDTH-1] B;
output [0:Y_WIDTH-1] Y;
reg [0:Y_WIDTH-1] Y_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
Y_reg <= 0;
end else begin
Y_reg <= A * B;
end
end
assign Y = Y_reg;
endmodule
module mult24x20_regio (CLK, RSTB, A, B, Y);
// Parameters
parameter A_WIDTH = 24;
parameter B_WIDTH = 20;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A;
input [0:B_WIDTH-1] B;
output [0:Y_WIDTH-1] Y;
reg [0:A_WIDTH-1] A_reg;
reg [0:B_WIDTH-1] B_reg;
reg [0:Y_WIDTH-1] Y_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
A_reg <= 0;
B_reg <= 0;
Y_reg <= 0;
end else begin
A_reg <= A;
B_reg <= B;
Y_reg <= A_reg * B_reg;
end
end
assign Y = Y_reg;
endmodule
// A half multiplier which only output the most significant 11 bit
module half_mult12x10 (A, B, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input [0:A_WIDTH-1] A;
input [0:B_WIDTH-1] B;
output [0:Y_WIDTH/2-1] Y;
wire [0:Y_WIDTH-1] mult_out;
mult12x10 FULL_MULT (.A(A),
.B(B),
.Y(mult_out)
);
assign Y = mult_out[0:Y_WIDTH/2-1];
endmodule

View file

@ -0,0 +1,586 @@
//-----------------------------
// Rising-edge D-type flip-flop
//-----------------------------
(* abc9_flop, lib_whitebox *)
module dff(
output reg Q,
input D,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b0;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C)
Q <= D;
1'b1:
always @(negedge C)
Q <= D;
endcase
endmodule
//-----------------------------
// Rising-edge D-type flip-flop with active-high asynchronous reset
//-----------------------------
(* abc9_flop, lib_whitebox *)
module dffr(
output reg Q,
input D,
input R,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b0;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C or posedge R)
if (R == 1'b1)
Q <= 1'b0;
else
Q <= D;
1'b1:
always @(negedge C or posedge R)
if (R == 1'b1)
Q <= 1'b0;
else
Q <= D;
endcase
endmodule
//-----------------------------
// Rising-edge D-type flip-flop with active-high asynchronous set
//-----------------------------
(* abc9_flop, lib_whitebox *)
module dffs(
output reg Q,
input D,
input S,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b0;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C or posedge S)
if (S == 1'b1)
Q <= 1'b1;
else
Q <= D;
1'b1:
always @(negedge C or posedge S)
if (S == 1'b1)
Q <= 1'b1;
else
Q <= D;
endcase
endmodule
//-----------------------------
// Rising-edge D-type flip-flop with active-low asynchronous reset
//-----------------------------
(* abc9_flop, lib_whitebox *)
module dffrn(
output reg Q,
input D,
input RN,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b0;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C or negedge RN)
if (RN == 1'b0)
Q <= 1'b0;
else
Q <= D;
1'b1:
always @(negedge C or negedge RN)
if (RN == 1'b0)
Q <= 1'b0;
else
Q <= D;
endcase
endmodule
//-----------------------------
// Rising-edge D-type flip-flop with active-low asynchronous set
//-----------------------------
(* abc9_flop, lib_whitebox *)
module dffsn(
output reg Q,
input D,
input SN,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b0;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C or negedge SN)
if (SN == 1'b0)
Q <= 1'b1;
else
Q <= D;
1'b1:
always @(negedge C or negedge SN)
if (SN == 1'b0)
Q <= 1'b1;
else
Q <= D;
endcase
endmodule
//-----------------------------
// Rising-edge D-type flip-flop with active-high synchronous reset
//-----------------------------
(* abc9_flop, lib_whitebox *)
module sdffr(
output reg Q,
input D,
input R,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b0;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C)
if (R == 1'b1)
Q <= 1'b0;
else
Q <= D;
1'b1:
always @(negedge C)
if (R == 1'b1)
Q <= 1'b0;
else
Q <= D;
endcase
endmodule
//-----------------------------
// Rising-edge D-type flip-flop with active-high synchronous set
//-----------------------------
(* abc9_flop, lib_whitebox *)
module sdffs(
output reg Q,
input D,
input S,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b0;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C)
if (S == 1'b1)
Q <= 1'b1;
else
Q <= D;
1'b1:
always @(negedge C)
if (S == 1'b1)
Q <= 1'b1;
else
Q <= D;
endcase
endmodule
//-----------------------------
// Rising-edge D-type flip-flop with active-low synchronous reset
//-----------------------------
(* abc9_flop, lib_whitebox *)
module sdffrn(
output reg Q,
input D,
input RN,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b0;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C)
if (RN == 1'b0)
Q <= 1'b0;
else
Q <= D;
1'b1:
always @(negedge C)
if (RN == 1'b0)
Q <= 1'b0;
else
Q <= D;
endcase
endmodule
//-----------------------------
// Rising-edge D-type flip-flop with active-low synchronous set
//-----------------------------
(* abc9_flop, lib_whitebox *)
module sdffsn(
output reg Q,
input D,
input SN,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b0;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C)
if (SN == 1'b0)
Q <= 1'b1;
else
Q <= D;
1'b1:
always @(negedge C)
if (SN == 1'b0)
Q <= 1'b1;
else
Q <= D;
endcase
endmodule
//-----------------------------
// Falling-edge D-type flip-flop
//-----------------------------
(* abc9_flop, lib_whitebox *)
module dffn(
output reg Q,
input D,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b1;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C)
Q <= D;
1'b1:
always @(negedge C)
Q <= D;
endcase
endmodule
//-----------------------------
// Falling-edge D-type flip-flop with active-high asynchronous reset
//-----------------------------
(* abc9_flop, lib_whitebox *)
module dffnr(
output reg Q,
input D,
input R,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b1;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C or posedge R)
if (R == 1'b1)
Q <= 1'b0;
else
Q <= D;
1'b1:
always @(negedge C or posedge R)
if (R == 1'b1)
Q <= 1'b0;
else
Q <= D;
endcase
endmodule
//-----------------------------
// Falling-edge D-type flip-flop with active-high asynchronous set
//-----------------------------
(* abc9_flop, lib_whitebox *)
module dffns(
output reg Q,
input D,
input S,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b1;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C or posedge S)
if (S == 1'b1)
Q <= 1'b1;
else
Q <= D;
1'b1:
always @(negedge C or posedge S)
if (S == 1'b1)
Q <= 1'b1;
else
Q <= D;
endcase
endmodule
//-----------------------------
// Falling-edge D-type flip-flop with active-low asynchronous reset
//-----------------------------
(* abc9_flop, lib_whitebox *)
module dffnrn(
output reg Q,
input D,
input RN,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b1;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C or negedge RN)
if (RN == 1'b0)
Q <= 1'b0;
else
Q <= D;
1'b1:
always @(negedge C or negedge RN)
if (RN == 1'b0)
Q <= 1'b0;
else
Q <= D;
endcase
endmodule
//-----------------------------
// Falling-edge D-type flip-flop with active-low asynchronous set
//-----------------------------
(* abc9_flop, lib_whitebox *)
module dffnsn(
output reg Q,
input D,
input SN,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b1;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C or negedge SN)
if (SN == 1'b0)
Q <= 1'b1;
else
Q <= D;
1'b1:
always @(negedge C or negedge SN)
if (SN == 1'b0)
Q <= 1'b1;
else
Q <= D;
endcase
endmodule
//-----------------------------
// Falling-edge D-type flip-flop with active-high synchronous reset
//-----------------------------
(* abc9_flop, lib_whitebox *)
module sdffnr(
output reg Q,
input D,
input R,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b1;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C)
if (R == 1'b1)
Q <= 1'b0;
else
Q <= D;
1'b1:
always @(negedge C)
if (R == 1'b1)
Q <= 1'b0;
else
Q <= D;
endcase
endmodule
//-----------------------------
// Falling-edge D-type flip-flop with active-high synchronous set
//-----------------------------
(* abc9_flop, lib_whitebox *)
module sdffns(
output reg Q,
input D,
input S,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b1;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C)
if (S == 1'b1)
Q <= 1'b1;
else
Q <= D;
1'b1:
always @(negedge C)
if (S == 1'b1)
Q <= 1'b1;
else
Q <= D;
endcase
endmodule
//-----------------------------
// Falling-edge D-type flip-flop with active-low synchronous reset
//-----------------------------
(* abc9_flop, lib_whitebox *)
module sdffnrn(
output reg Q,
input D,
input RN,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b1;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C)
if (RN == 1'b0)
Q <= 1'b0;
else
Q <= D;
1'b1:
always @(negedge C)
if (RN == 1'b0)
Q <= 1'b0;
else
Q <= D;
endcase
endmodule
//-----------------------------
// Falling-edge D-type flip-flop with active-low synchronous set
//-----------------------------
(* abc9_flop, lib_whitebox *)
module sdffnsn(
output reg Q,
input D,
input SN,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b1;
initial Q = INIT;
case(|IS_C_INVERTED)
1'b0:
always @(posedge C)
if (SN == 1'b0)
Q <= 1'b1;
else
Q <= D;
1'b1:
always @(negedge C)
if (SN == 1'b0)
Q <= 1'b1;
else
Q <= D;
endcase
endmodule
//-----------------------------
// Two-bit D-type flip-flop with active-high asynchronous reset
// 1st stage is positive-edge triggered
// 2nd stage is negative-edge triggered
//-----------------------------
// Do not allow ABC or other optimization to touch the ff!
//(* abc9_flop, lib_whitebox *)
module dffnr_dffr(
output Q,
input D,
input R,
input C
);
wire Q0;
dffnr FF_0 (.D(D), .C(C), .R(R), .Q(Q0));
dffr FF_1 (.D(Q0), .C(C), .R(R), .Q(Q));
endmodule
//-----------------------------
// Two-bit D-type flip-flop with active-high asynchronous reset
// 1st stage is positive-edge triggered
// 2nd stage is negative-edge triggered
//-----------------------------
// Do not allow ABC or other optimization to touch the ff!
//(* abc9_flop, lib_whitebox *)
module dffr_dffnr(
output Q,
input D,
input R,
input C
);
wire Q0;
dffr FF_0 (.D(D), .C(C), .R(R), .Q(Q0));
dffnr FF_1 (.D(Q0), .C(C), .R(R), .Q(Q));
endmodule

View file

@ -0,0 +1,177 @@
// Rising edge DFF
module \$_DFF_P_ (D, C, Q);
input D;
input C;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
dff _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C));
endmodule
// Rising edge DFF with async active-high reset
module \$_DFF_PP0_ (D, C, R, Q);
input D;
input C;
input R;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
dffr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R));
endmodule
// Rising edge DFF with async active-high set
module \$_DFF_PP1_ (D, C, R, Q);
input D;
input C;
input R;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
dffs _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .S(R));
endmodule
// Rising edge DFF with async active-low reset
module \$_DFF_PN0_ (D, C, R, Q);
input D;
input C;
input R;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
dffrn _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .RN(R));
endmodule
// Rising edge DFF with async active-low set
module \$_DFF_PN1_ (D, C, R, Q);
input D;
input C;
input R;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
dffsn _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .SN(R));
endmodule
// Rising edge DFF with sync active-high reset
module \$_SDFF_PP0_ (D, C, R, Q);
input D;
input C;
input R;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
sdffr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R));
endmodule
// Rising edge DFF with sync active-high set
module \$_SDFF_PP1_ (D, C, R, Q);
input D;
input C;
input R;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
sdffs _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .S(R));
endmodule
// Rising edge DFF with sync active-low reset
module \$_SDFF_PN0_ (D, C, R, Q);
input D;
input C;
input R;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
sdffrn _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .RN(R));
endmodule
// Rising edge DFF with sync active-low set
module \$_SDFF_PN1_ (D, C, R, Q);
input D;
input C;
input R;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
sdffsn _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .SN(R));
endmodule
// Falling edge DFF
module \$_DFF_N_ (D, C, Q);
input D;
input C;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
dffn _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C));
endmodule
// Falling edge DFF with async active-high reset
module \$_DFF_NP0_ (D, C, R, Q);
input D;
input C;
input R;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
dffnr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R));
endmodule
// Falling edge DFF with async active-high set
module \$_DFF_NP1_ (D, C, R, Q);
input D;
input C;
input R;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
dffns _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .S(R));
endmodule
// Falling edge DFF with async active-low reset
module \$_DFF_NN0_ (D, C, R, Q);
input D;
input C;
input R;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
dffnrn _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .RN(R));
endmodule
// Falling edge DFF with async active-low set
module \$_DFF_NN1_ (D, C, R, Q);
input D;
input C;
input R;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
dffnsn _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .SN(R));
endmodule
// Falling edge DFF with sync active-high reset
module \$_SDFF_NP0_ (D, C, R, Q);
input D;
input C;
input R;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
sdffnr _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .R(R));
endmodule
// Falling edge DFF with sync active-high set
module \$_SDFF_NP1_ (D, C, R, Q);
input D;
input C;
input R;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
sdffns _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .S(R));
endmodule
// Falling edge DFF with sync active-low reset
module \$_SDFF_NN0_ (D, C, R, Q);
input D;
input C;
input R;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
sdffnrn _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .RN(R));
endmodule
// Falling edge DFF with sync active-low set
module \$_SDFF_NN1_ (D, C, R, Q);
input D;
input C;
input R;
output Q;
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
sdffnsn _TECHMAP_REPLACE_ (.Q(Q), .D(D), .C(C), .SN(R));
endmodule

View file

@ -0,0 +1,17 @@
module mult_14x10_map (
input [0:13] A,
input [0:9] B,
output [0:23] Y
);
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;
parameter A_WIDTH = 0;
parameter B_WIDTH = 0;
parameter Y_WIDTH = 0;
mult_14x10 #() _TECHMAP_REPLACE_ (
.A (A),
.B (B),
.Y (Y) );
endmodule

View file

@ -0,0 +1,128 @@
# Yosys synthesis script for ${TOP_MODULE}
#########################
# Parse input files
#########################
# Read verilog files
read_verilog ${READ_VERILOG_OPTIONS} ${VERILOG_FILES}
# Read technology library
read_verilog -lib -specify ${YOSYS_CELL_SIM_VERILOG}
#########################
# Prepare for synthesis
#########################
# Identify top module from hierarchy
hierarchy -check -top ${TOP_MODULE}
# - Convert process blocks to AST
proc
# Flatten all the gates/primitives
flatten
# Identify tri-state buffers from 'z' signal in AST
# with follow-up optimizations to clean up AST
tribuf -logic
opt_expr
opt_clean
# demote inout ports to input or output port
# with follow-up optimizations to clean up AST
deminout
opt -nodffe
opt_expr
opt_clean
check
opt -nodffe
wreduce -keepdc
peepopt
pmuxtree
opt_clean
########################
# Map multipliers
# Inspired from synth_xilinx.cc
#########################
# Avoid merging any registers into DSP, reserve memory port registers first
#memory_dff
#wreduce t:$mul
#techmap -map +/mul2dsp.v -map ${YOSYS_DSP_MAP_VERILOG} ${YOSYS_DSP_MAP_PARAMETERS}
#select a:mul2dsp
#setattr -unset mul2dsp
#opt_expr -fine
#wreduce
#select -clear
#chtype -set $mul t:$__soft_mul# Extract arithmetic functions
#########################
# Run coarse synthesis
#########################
# Run a tech map with default library
alumacc
#techmap -map +/techmap.v -map ${YOSYS_ADDER_MAP_VERILOG}
#opt -fast -nodffe
#opt_expr
#opt_merge
#opt_clean
#opt -nodffe
#share
#opt -nodffe
#fsm
# Run a quick follow-up optimization to sweep out unused nets/signals
#opt -fast -nodffe
opt
# Optimize any memory cells by merging share-able ports and collecting all the ports belonging to memorcy cells
memory -nomap
opt_clean
#########################
# Map logics to BRAMs
#########################
#memory_bram -rules ${YOSYS_BRAM_MAP_RULES}
#techmap -map ${YOSYS_BRAM_MAP_VERILOG}
#opt -fast -mux_undef -undriven -fine -nodffe
#memory_map
#opt -undriven -fine -nodffe
########################
# Map Adders
techmap -map +/techmap.v -map ${YOSYS_ADDER_MAP_VERILOG}
opt -fast -nodffe
opt_expr
opt_merge
opt_clean
opt -nodffe
#########################
# Map flip-flops
#########################
memory
dfflegalize -cell $_DFF_?_ 01 -cell $_DFF_???_ 01 -cell $_SDFF_???_ 01
techmap -map +/techmap.v -map ${YOSYS_DFF_MAP_VERILOG}
dfflegalize -cell $_DFF_?_ 01 -cell $_DFF_???_ 01 -cell $_SDFF_???_ 01
techmap -map +/techmap.v -map ${YOSYS_DFF_MAP_VERILOG}
opt_expr -mux_undef
simplemap
opt_expr
opt_merge
opt_dff -nodffe
opt_clean
opt -nodffe
#########################
# Map LUTs
#########################
abc -lut ${LUT_SIZE}
# Map dff again since ABC may generate some new FFs
techmap -map ${YOSYS_DFF_MAP_VERILOG}
techmap -map ${YOSYS_ADDER_MAP_VERILOG}
#########################
# Check and show statisitics
#########################
hierarchy -check
stat
#########################
# Output netlists
#########################
opt_clean -purge
write_blif ${OUTPUT_BLIF}
write_verilog ${TOP_MODULE}_post_synth.v

View file

@ -0,0 +1,128 @@
# Yosys synthesis script for ${TOP_MODULE}
#########################
# Parse input files
#########################
# Read verilog files
read_verilog ${READ_VERILOG_OPTIONS} ${VERILOG_FILES}
# Read technology library
read_verilog -lib -specify ${YOSYS_CELL_SIM_VERILOG}
#########################
# Prepare for synthesis
#########################
# Identify top module from hierarchy
hierarchy -check -top ${TOP_MODULE}
# - Convert process blocks to AST
proc
# Flatten all the gates/primitives
flatten
# Identify tri-state buffers from 'z' signal in AST
# with follow-up optimizations to clean up AST
tribuf -logic
opt_expr
opt_clean
# demote inout ports to input or output port
# with follow-up optimizations to clean up AST
deminout
opt -nodffe
opt_expr
opt_clean
check
opt -nodffe
wreduce -keepdc
peepopt
pmuxtree
opt_clean
########################
# Map multipliers
# Inspired from synth_xilinx.cc
#########################
# Avoid merging any registers into DSP, reserve memory port registers first
#memory_dff
#wreduce t:$mul
#techmap -map +/mul2dsp.v -map ${YOSYS_DSP_MAP_VERILOG} ${YOSYS_DSP_MAP_PARAMETERS}
#select a:mul2dsp
#setattr -unset mul2dsp
#opt_expr -fine
#wreduce
#select -clear
#chtype -set $mul t:$__soft_mul# Extract arithmetic functions
#########################
# Run coarse synthesis
#########################
# Run a tech map with default library
alumacc
#techmap -map +/techmap.v -map ${YOSYS_ADDER_MAP_VERILOG}
#opt -fast -nodffe
#opt_expr
#opt_merge
#opt_clean
#opt -nodffe
#share
#opt -nodffe
#fsm
# Run a quick follow-up optimization to sweep out unused nets/signals
#opt -fast -nodffe
opt
# Optimize any memory cells by merging share-able ports and collecting all the ports belonging to memorcy cells
memory -nomap
opt_clean
#########################
# Map logics to BRAMs
#########################
#memory_bram -rules ${YOSYS_BRAM_MAP_RULES}
#techmap -map ${YOSYS_BRAM_MAP_VERILOG}
#opt -fast -mux_undef -undriven -fine -nodffe
#memory_map
#opt -undriven -fine -nodffe
########################
# Map Adders
#techmap -map +/techmap.v -map ${YOSYS_ADDER_MAP_VERILOG}
#opt -fast -nodffe
#opt_expr
#opt_merge
#opt_clean
#opt -nodffe
#########################
# Map flip-flops
#########################
memory
dfflegalize -cell $_DFF_?_ 01 -cell $_DFF_???_ 01 -cell $_SDFF_???_ 01
techmap -map +/techmap.v -map ${YOSYS_DFF_MAP_VERILOG}
dfflegalize -cell $_DFF_?_ 01 -cell $_DFF_???_ 01 -cell $_SDFF_???_ 01
techmap -map +/techmap.v -map ${YOSYS_DFF_MAP_VERILOG}
opt_expr -mux_undef
simplemap
opt_expr
opt_merge
opt_dff -nodffe
opt_clean
opt -nodffe
#########################
# Map LUTs
#########################
abc -lut ${LUT_SIZE}
# Map dff again since ABC may generate some new FFs
techmap -map ${YOSYS_DFF_MAP_VERILOG}
techmap -map ${YOSYS_ADDER_MAP_VERILOG}
#########################
# Check and show statisitics
#########################
hierarchy -check
stat
#########################
# Output netlists
#########################
opt_clean -purge
write_blif ${OUTPUT_BLIF}
write_verilog ${TOP_MODULE}_post_synth.v

View file

@ -0,0 +1,41 @@
# Yosys synthesis script for ${TOP_MODULE}
# Read verilog files
read_verilog ${READ_VERILOG_OPTIONS} ${VERILOG_FILES}
# Technology mapping
hierarchy -top ${TOP_MODULE}
proc
techmap -D NO_LUT -map +/adff2dff.v
# Synthesis
flatten
opt_expr
opt_clean
check
opt -nodffe -nosdff
fsm
opt -nodffe -nosdff
wreduce
peepopt
opt_clean
opt -nodffe -nosdff
memory -nomap
opt_clean
opt -fast -full -nodffe -nosdff
memory_map
opt -full -nodffe -nosdff
techmap
opt -fast -nodffe -nosdff
clean
clean
# LUT mapping
abc -lut ${LUT_SIZE}
# Check
synth -run check
# Clean and output blif
opt_clean -purge
write_verilog ${OUTPUT_VERILOG}