3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-07-02 13:36:08 +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,314 @@
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
or_next_if_better
endmatch
bram $__FLEX_TDPRAM_256x36_wclkn # 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 0 # clock polarity configuration
endbram
match $__FLEX_TDPRAM_256x36_wclkn
min efficiency 0 # Only use this bram is <=0 ram bits are used
make_transp # Add external circuitry to simulate 'transparent read' if necessary
min dbits 19
or_next_if_better
endmatch
bram $__FLEX_TDPRAM_256x36_rclkn # 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 0 1 # clock polarity configuration
endbram
match $__FLEX_TDPRAM_256x36_rclkn
min efficiency 0 # Only use this bram is <=0 ram bits are used
make_transp # Add external circuitry to simulate 'transparent read' if necessary
min dbits 19
or_next_if_better
endmatch
bram $__FLEX_TDPRAM_256x36_rwclkn # 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 0 0 # clock polarity configuration
endbram
match $__FLEX_TDPRAM_256x36_rwclkn
min efficiency 0 # Only use this bram is <=0 ram bits are used
make_transp # Add external circuitry to simulate 'transparent read' if necessary
min dbits 19
or_next_if_better
endmatch
bram $__FLEX_TDPRAM_512x18 # Name of the BRAM cell
init 0 # Set to '1' if BRAM can be initialized
abits 9 # Number of address bits
dbits 18 # 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_512x18
min efficiency 0 # Only use this bram is <=0 ram bits are used
make_transp # Add external circuitry to simulate 'transparent read' if necessary
min dbits 10
or_next_if_better
endmatch
bram $__FLEX_TDPRAM_512x18_wclkn # Name of the BRAM cell
init 0 # Set to '1' if BRAM can be initialized
abits 9 # Number of address bits
dbits 18 # 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 0 # clock polarity configuration
endbram
match $__FLEX_TDPRAM_512x18_wclkn
min efficiency 0 # Only use this bram is <=0 ram bits are used
make_transp # Add external circuitry to simulate 'transparent read' if necessary
min dbits 10
or_next_if_better
endmatch
bram $__FLEX_TDPRAM_512x18_rclkn # Name of the BRAM cell
init 0 # Set to '1' if BRAM can be initialized
abits 9 # Number of address bits
dbits 18 # 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 0 1 # clock polarity configuration
endbram
match $__FLEX_TDPRAM_512x18_rclkn
min efficiency 0 # Only use this bram is <=0 ram bits are used
make_transp # Add external circuitry to simulate 'transparent read' if necessary
min dbits 10
or_next_if_better
endmatch
bram $__FLEX_TDPRAM_512x18_rwclkn # Name of the BRAM cell
init 0 # Set to '1' if BRAM can be initialized
abits 9 # Number of address bits
dbits 18 # 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 0 0 # clock polarity configuration
endbram
match $__FLEX_TDPRAM_512x18_rwclkn
min efficiency 0 # Only use this bram is <=0 ram bits are used
make_transp # Add external circuitry to simulate 'transparent read' if necessary
min dbits 10
or_next_if_better
endmatch
bram $__FLEX_TDPRAM_1024x9 # Name of the BRAM cell
init 0 # Set to '1' if BRAM can be initialized
abits 10 # Number of address bits
dbits 9 # 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_1024x9
min efficiency 0 # Only use this bram is <=0 ram bits are used
make_transp # Add external circuitry to simulate 'transparent read' if necessary
min dbits 5
or_next_if_better
endmatch
bram $__FLEX_TDPRAM_1024x9_wclkn # Name of the BRAM cell
init 0 # Set to '1' if BRAM can be initialized
abits 10 # Number of address bits
dbits 9 # 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 0 # clock polarity configuration
endbram
match $__FLEX_TDPRAM_1024x9_wclkn
min efficiency 0 # Only use this bram is <=0 ram bits are used
make_transp # Add external circuitry to simulate 'transparent read' if necessary
min dbits 5
or_next_if_better
endmatch
bram $__FLEX_TDPRAM_1024x9_rclkn # Name of the BRAM cell
init 0 # Set to '1' if BRAM can be initialized
abits 10 # Number of address bits
dbits 9 # 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 0 1 # clock polarity configuration
endbram
match $__FLEX_TDPRAM_1024x9_rclkn
min efficiency 0 # Only use this bram is <=0 ram bits are used
make_transp # Add external circuitry to simulate 'transparent read' if necessary
min dbits 5
or_next_if_better
endmatch
bram $__FLEX_TDPRAM_1024x9_rwclkn # Name of the BRAM cell
init 0 # Set to '1' if BRAM can be initialized
abits 10 # Number of address bits
dbits 9 # 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 0 0 # clock polarity configuration
endbram
match $__FLEX_TDPRAM_1024x9_rwclkn
min efficiency 0 # Only use this bram is <=0 ram bits are used
make_transp # Add external circuitry to simulate 'transparent read' if necessary
min dbits 5
or_next_if_better
endmatch
bram $__FLEX_TDPRAM_2048x4 # Name of the BRAM cell
init 0 # Set to '1' if BRAM can be initialized
abits 11 # Number of address bits
dbits 4 # 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_2048x4
min efficiency 0 # Only use this bram is <=0 ram bits are used
make_transp # Add external circuitry to simulate 'transparent read' if necessary
or_next_if_better
endmatch
bram $__FLEX_TDPRAM_2048x4_wclkn # Name of the BRAM cell
init 0 # Set to '1' if BRAM can be initialized
abits 11 # Number of address bits
dbits 4 # 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 0 # clock polarity configuration
endbram
match $__FLEX_TDPRAM_2048x4_wclkn
min efficiency 0 # Only use this bram is <=0 ram bits are used
make_transp # Add external circuitry to simulate 'transparent read' if necessary
or_next_if_better
endmatch
bram $__FLEX_TDPRAM_2048x4_rclkn # Name of the BRAM cell
init 0 # Set to '1' if BRAM can be initialized
abits 11 # Number of address bits
dbits 4 # 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 0 1 # clock polarity configuration
endbram
match $__FLEX_TDPRAM_2048x4_rclkn
min efficiency 0 # Only use this bram is <=0 ram bits are used
make_transp # Add external circuitry to simulate 'transparent read' if necessary
or_next_if_better
endmatch
bram $__FLEX_TDPRAM_2048x4_rwclkn # Name of the BRAM cell
init 0 # Set to '1' if BRAM can be initialized
abits 11 # Number of address bits
dbits 4 # 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 0 0 # clock polarity configuration
endbram
match $__FLEX_TDPRAM_2048x4_rwclkn
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,575 @@
//-----------------------------
// 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
dpram256x36
_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
//-----------------------------
// This is a true dual-port RAM
// BUT without support on Byte-Write-Enable
// Due to limited support from Yosys
//-----------------------------
module \$__FLEX_TDPRAM_256x36_WCLKN (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter [0:0] CLKPOL2 = 1;
parameter [0:0] CLKPOL3 = 0;
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
dpram256x36_wclkn
_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
//-----------------------------
// This is a true dual-port RAM
// BUT without support on Byte-Write-Enable
// Due to limited support from Yosys
//-----------------------------
module \$__FLEX_TDPRAM_256x36_RCLKN (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter [0:0] CLKPOL2 = 0;
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
dpram256x36_rclkn
_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
//-----------------------------
// This is a true dual-port RAM
// BUT without support on Byte-Write-Enable
// Due to limited support from Yosys
//-----------------------------
module \$__FLEX_TDPRAM_256x36_RWCLKN (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter [0:0] CLKPOL2 = 0;
parameter [0:0] CLKPOL3 = 0;
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
dpram256x36_rwclkn
_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
//-----------------------------
// This is a true dual-port RAM
// BUT without support on Byte-Write-Enable
// Due to limited support from Yosys
//-----------------------------
module \$__FLEX_TDPRAM_512x18 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter [0:0] CLKPOL2 = 1;
parameter [0:0] CLKPOL3 = 1;
input CLK2;
input CLK3;
input [0:8] A1ADDR;
input A1EN;
output [0:17] A1DATA;
input [0:8] B1ADDR;
input B1EN;
input [0:17] B1DATA;
generate
dpram512x18
_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
//-----------------------------
// This is a true dual-port RAM
// BUT without support on Byte-Write-Enable
// Due to limited support from Yosys
//-----------------------------
module \$__FLEX_TDPRAM_512x18_WCLKN (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter [0:0] CLKPOL2 = 1;
parameter [0:0] CLKPOL3 = 0;
input CLK2;
input CLK3;
input [0:8] A1ADDR;
input A1EN;
output [0:17] A1DATA;
input [0:8] B1ADDR;
input B1EN;
input [0:17] B1DATA;
generate
dpram512x18_wclkn
_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
//-----------------------------
// This is a true dual-port RAM
// BUT without support on Byte-Write-Enable
// Due to limited support from Yosys
//-----------------------------
module \$__FLEX_TDPRAM_512x18_RCLKN (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter [0:0] CLKPOL2 = 0;
parameter [0:0] CLKPOL3 = 1;
input CLK2;
input CLK3;
input [0:8] A1ADDR;
input A1EN;
output [0:17] A1DATA;
input [0:8] B1ADDR;
input B1EN;
input [0:17] B1DATA;
generate
dpram512x18_rclkn
_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
//-----------------------------
// This is a true dual-port RAM
// BUT without support on Byte-Write-Enable
// Due to limited support from Yosys
//-----------------------------
module \$__FLEX_TDPRAM_512x18_RWCLKN (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter [0:0] CLKPOL2 = 0;
parameter [0:0] CLKPOL3 = 0;
input CLK2;
input CLK3;
input [0:8] A1ADDR;
input A1EN;
output [0:17] A1DATA;
input [0:8] B1ADDR;
input B1EN;
input [0:17] B1DATA;
generate
dpram512x18_rwclkn
_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
//-----------------------------
// This is a true dual-port RAM
// BUT without support on Byte-Write-Enable
// Due to limited support from Yosys
//-----------------------------
module \$__FLEX_TDPRAM_1024x9 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter [0:0] CLKPOL2 = 1;
parameter [0:0] CLKPOL3 = 1;
input CLK2;
input CLK3;
input [0:9] A1ADDR;
input A1EN;
output [0:8] A1DATA;
input [0:9] B1ADDR;
input B1EN;
input [0:8] B1DATA;
generate
dpram1024x9
_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
//-----------------------------
// This is a true dual-port RAM
// BUT without support on Byte-Write-Enable
// Due to limited support from Yosys
//-----------------------------
module \$__FLEX_TDPRAM_1024x9_WCLKN (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter [0:0] CLKPOL2 = 1;
parameter [0:0] CLKPOL3 = 0;
input CLK2;
input CLK3;
input [0:9] A1ADDR;
input A1EN;
output [0:8] A1DATA;
input [0:9] B1ADDR;
input B1EN;
input [0:8] B1DATA;
generate
dpram1024x9_wclkn
_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
//-----------------------------
// This is a true dual-port RAM
// BUT without support on Byte-Write-Enable
// Due to limited support from Yosys
//-----------------------------
module \$__FLEX_TDPRAM_1024x9_RCLKN (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter [0:0] CLKPOL2 = 0;
parameter [0:0] CLKPOL3 = 1;
input CLK2;
input CLK3;
input [0:9] A1ADDR;
input A1EN;
output [0:8] A1DATA;
input [0:9] B1ADDR;
input B1EN;
input [0:8] B1DATA;
generate
dpram1024x9_rclkn
_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
//-----------------------------
// This is a true dual-port RAM
// BUT without support on Byte-Write-Enable
// Due to limited support from Yosys
//-----------------------------
module \$__FLEX_TDPRAM_1024x9_RWCLKN (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter [0:0] CLKPOL2 = 0;
parameter [0:0] CLKPOL3 = 0;
input CLK2;
input CLK3;
input [0:9] A1ADDR;
input A1EN;
output [0:8] A1DATA;
input [0:9] B1ADDR;
input B1EN;
input [0:8] B1DATA;
generate
dpram1024x9_rwclkn
_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
//-----------------------------
// This is a true dual-port RAM
// BUT without support on Byte-Write-Enable
// Due to limited support from Yosys
//-----------------------------
module \$__FLEX_TDPRAM_2048x4 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter [0:0] CLKPOL2 = 1;
parameter [0:0] CLKPOL3 = 1;
input CLK2;
input CLK3;
input [0:10] A1ADDR;
input A1EN;
output [0:3] A1DATA;
input [0:10] B1ADDR;
input B1EN;
input [0:3] B1DATA;
generate
dpram2048x4
_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
//-----------------------------
// This is a true dual-port RAM
// BUT without support on Byte-Write-Enable
// Due to limited support from Yosys
//-----------------------------
module \$__FLEX_TDPRAM_2048x4_WCLKN (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter [0:0] CLKPOL2 = 1;
parameter [0:0] CLKPOL3 = 0;
input CLK2;
input CLK3;
input [0:10] A1ADDR;
input A1EN;
output [0:3] A1DATA;
input [0:10] B1ADDR;
input B1EN;
input [0:3] B1DATA;
generate
dpram2048x4_wclkn
_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
//-----------------------------
// This is a true dual-port RAM
// BUT without support on Byte-Write-Enable
// Due to limited support from Yosys
//-----------------------------
module \$__FLEX_TDPRAM_2048x4_RCLKN (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter [0:0] CLKPOL2 = 0;
parameter [0:0] CLKPOL3 = 1;
input CLK2;
input CLK3;
input [0:10] A1ADDR;
input A1EN;
output [0:3] A1DATA;
input [0:10] B1ADDR;
input B1EN;
input [0:3] B1DATA;
generate
dpram2048x4_rclkn
_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
//-----------------------------
// This is a true dual-port RAM
// BUT without support on Byte-Write-Enable
// Due to limited support from Yosys
//-----------------------------
module \$__FLEX_TDPRAM_2048x4_RWCLKN (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter [0:0] CLKPOL2 = 0;
parameter [0:0] CLKPOL3 = 0;
input CLK2;
input CLK3;
input [0:10] A1ADDR;
input A1EN;
output [0:3] A1DATA;
input [0:10] B1ADDR;
input B1EN;
input [0:3] B1DATA;
generate
dpram2048x4_rwclkn
_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,8 @@
//-------------------------------------------------
// Include all the primitives
//-------------------------------------------------
`include "cell_sim_arith.v"
`include "cell_sim_dsp.v"
`include "cell_sim_new_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,561 @@
//-------------------------------------------------
// 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
module mad12x10x22 (A0, B0, C0, 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:Y_WIDTH-1] C0;
output [0:Y_WIDTH-1] Y;
assign Y = A0 * B0 + C0;
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,385 @@
module mad12x10x22 (clk_i, rst_ni, a_i, b_i, d_i, out_o, mode_i, rst_acc, accsel, cas_g, overflow);
input [0:47] a_i;
input [0:39] b_i;
input [0:59] d_i;
input [0:12] mode_i;
output [0:59] out_o;
input clk_i;
input rst_ni;
input rst_acc;
input accsel;
input cas_g;
output overflow;
dsp #(
.N_SIZE (12),
.M_SIZE (10)
) u_dsp(
.a_i (a_i),
.b_i (b_i),
.out_o (out_o),
.clk_i (clk_i),
.rst_ni (rst_ni),
.d_i (d_i),
.mode_i (mode_i),
.rst_acc (rst_acc),
.accsel (accsel),
.cas_g (cas_g),
.overflow (overflow)
);
endmodule
module mad24x20x44 (clk_i, rst_ni, a_i, b_i, d_i, out_o, mode_i, rst_acc, accsel, cas_g, overflow);
input [0:95] a_i;
input [0:79] b_i;
input [0:103] d_i;
input [0:12] mode_i;
output [0:103] out_o;
input clk_i;
input rst_ni;
input rst_acc;
input accsel;
input cas_g;
output overflow;
dsp #(
.N_SIZE (24),
.M_SIZE (20)
) u_dsp(
.a_i (a_i),
.b_i (b_i),
.out_o (out_o),
.clk_i (clk_i),
.rst_ni (rst_ni),
.d_i (d_i),
.mode_i (mode_i),
.rst_acc (rst_acc),
.accsel (accsel),
.cas_g (cas_g),
.overflow (overflow)
);
endmodule
//-----------------------------------------------------
// Design Name : Parameterized DSP block
// File Name : dsp.v
// Function : A N*M-bit DSP block which can operate in fracturable modes:
// 1. four [N/4]*[M/4]-bit multiplication with accumulation
// 1.1 (combinational)
// 1.2 (with input registers triggered by rising edge)
// 1.3 (with output registers triggered by rising edge)
// 1.4 (with input and output registers triggered by rising edge)
// 1.5 (with input registers triggered by falling edge)
// 1.6 (with output registers triggered by falling edge)
// 1.7 (with input and output registers triggered by falling edge)
// 2. two [N/2]*[M/2]-bit multipliers
// 2.1 (combinational)
// 2.2 (with input registers triggered by rising edge)
// 2.3 (with output registers triggered by rising edge)
// 2.4 (with input and output registers triggered by rising edge)
// 2.5 (with input registers triggered by falling edge)
// 2.6 (with output registers triggered by falling edge)
// 2.7 (with input and output registers triggered by falling edge)
// 3. Single N*M-bit multipliers
// 3.1 (combinational)
// 3.2 (with input registers triggered by rising edge)
// 3.3 (with output registers triggered by rising edge)
// 3.4 (with input and output registers triggered by rising edge)
// 3.5 (with input registers triggered by falling edge)
// 3.6 (with output registers triggered by falling edge)
// 3.7 (with input and output registers triggered by falling edge)
// 4. Two [N/4]*[M/4]-bit multiply-accumulators
// 4.1 (combinational)
// 4.2 (with input registers triggered by rising edge)
// 4.3 (with output registers triggered by rising edge)
// 4.4 (with input and output registers triggered by rising edge)
// 4.5 (with input registers triggered by falling edge)
// 4.6 (with output registers triggered by falling edge)
// 4.7 (with input and output registers triggered by falling edge)
// 5. One [N/4]*[M/4]-bit multiplier + One [N/4]*[M/4]-bit MAC
// 5.1 (combinational)
// 5.2 (with input registers triggered by rising edge)
// 5.3 (with output registers triggered by rising edge)
// 5.4 (with input and output registers triggered by rising edge)
// 5.5 (with input registers triggered by falling edge)
// 5.6 (with output registers triggered by falling edge)
// 5.7 (with input and output registers triggered by falling edge)
// 6. One [N/4]*[M/4]-bit MAC + One [N/4]*[M/4]-bit multiply
// 6.1 (combinational)
// 6.2 (with input registers triggered by rising edge)
// 6.3 (with output registers triggered by rising edge)
// 6.4 (with input and output registers triggered by rising edge)
// 6.5 (with input registers triggered by falling edge)
// 6.6 (with output registers triggered by falling edge)
// 6.7 (with input and output registers triggered by falling edge)
// 7. MSB parts [N/2+M/2] of four multipliers
// 7.1 (combinational)
// 7.2 (with input registers triggered by rising edge)
// 7.3 (with output registers triggered by rising edge)
// 7.4 (with input and output registers triggered by rising edge)
// 7.5 (with input registers triggered by falling edge)
// 7.6 (with output registers triggered by falling edge)
// 7.7 (with input and output registers triggered by falling edge)
// 8. One [N/4]*[M/4]-bit multiply + MSB parts [N/2+M/2] of four multipliers
// 8.1 (combinational)
// 8.2 (with input registers triggered by rising edge)
// 8.3 (with output registers triggered by rising edge)
// 8.4 (with input and output registers triggered by rising edge)
// 8.5 (with input registers triggered by falling edge)
// 8.6 (with output registers triggered by falling edge)
// 8.7 (with input and output registers triggered by falling edge)
// 9. One [N/4]*[M/4]-bit MAC + MSB parts [N/2+M/2] of four multipliers
// 9.1 (combinational)
// 9.2 (with input registers triggered by rising edge)
// 9.3 (with output registers triggered by rising edge)
// 9.4 (with input and output registers triggered by rising edge)
// 9.5 (with input registers triggered by falling edge)
// 9.6 (with output registers triggered by falling edge)
// 9.7 (with input and output registers triggered by falling edge)
// - In all the above modes, clock edges can be either positive or negative triggered
// Coder : Xifan Tang
//-----------------------------------------------------
`default_nettype wire
module dsp (clk_i, rst_ni, a_i, b_i, d_i, out_o, mode_i, rst_acc, accsel, cas_g, overflow);
// Parameters that can pass through
parameter N_SIZE = 12; // Default parameter for N
parameter M_SIZE = 10; // Default parameter for M
// Local parameters
localparam A_WIDTH = 4 * N_SIZE; // Default parameter for a
localparam B_WIDTH = 4 * M_SIZE; // Default parameter for b
localparam C_WIDTH = N_SIZE + M_SIZE; // Default parameter for cin
localparam OUT_WIDTH = A_WIDTH / 2 + B_WIDTH / 2; // Default parameter for data output
parameter P_SIZE = OUT_WIDTH; // Default parameter for previous d
// Ensure that all the mode bit constants unique!!!
localparam MODE_BIT_CLK = 0; // Mode bit that controls polarity of the clock signals
localparam MODE_BIT_REGI_UPPER = 1; // Mode bit that controls the registering of upper part of the inputs
localparam MODE_BIT_REGI_LOWER = 2; // Mode bit that controls the registering of lower part of the inputs
localparam MODE_BIT_REGO_UPPER = 3; // Mode bit that controls the registering of upper part of the outputs
localparam MODE_BIT_REGO_LOWER = 4; // Mode bit that controls the registering of lower part of the outputs
localparam MODE_BIT_MAC_LSB = 5; // LSB of the mode bits that control the core computing units
localparam MODE_BIT_MAC_MSB = 8; // MSB of the mode bits that contorl the core computing units
localparam MODE_BIT_RST = 9; // MSB of the mode bits that contorl the polarity of reset signals
localparam MODE_BIT_SIGN = 10; //Mode bit that controls valid of the sign bit
// localparam MODE_BIT_CARRY = 11; //Mode bit that controls valid of the carry bit
localparam MODE_MUL_INPUT_REG = 11; // Mode bit that controls the registering of the inputs of the multipliers
localparam MODE_MUL_OUTPUT_REG = 12; // Mode bit that controls the registering of the outputs of the multipliers
localparam ADDER_REDUNDENT = 8; // Default parameter for adder redundancy
localparam ADD_ACC_WIDTH = OUT_WIDTH/2 + ADDER_REDUNDENT; // Default accumulating parameter for adder width
localparam ACC_OUT_WIDTH = OUT_WIDTH + 2*ADDER_REDUNDENT;
// Ports
input clk_i;
input rst_ni;
input [0:A_WIDTH-1] a_i;
input [0:B_WIDTH-1] b_i;
input [0:ACC_OUT_WIDTH-1] d_i;
output [0:ACC_OUT_WIDTH-1] out_o;
input [0:12] mode_i;
output overflow;
// input cin;
// output cout;
input rst_acc; //For accumulate resettable
input accsel; // Accumulate or add new data
input cas_g; // Global cascade mode for top level dsp
wire clk_core;
wire clr;
assign clk_core = mode_i[MODE_BIT_CLK] ? clk_i : ~clk_i;
assign clr = mode_i[MODE_BIT_RST] ? ~rst_ni : rst_ni;
// Control logic for registering inputs and outputs
wire [0:A_WIDTH-1] in_a;
wire [0:B_WIDTH-1] in_b;
wire [0:ACC_OUT_WIDTH-1] in_d;
wire [0:ACC_OUT_WIDTH-1] cas_out;
reg [0:A_WIDTH-1] a_i_reg;
reg [0:B_WIDTH-1] b_i_reg;
reg [0:ACC_OUT_WIDTH-1] d_i_reg;
reg [0:ACC_OUT_WIDTH-1] out_o_reg;
always @(posedge clk_core or negedge clr) begin
if (clr == 1'b0) begin
a_i_reg <= 0;
b_i_reg <= 0;
d_i_reg <= 0;
out_o_reg <= 0;
end else begin
a_i_reg <= a_i;
b_i_reg <= b_i;
d_i_reg <= d_i;
out_o_reg <= cas_out;
end
end
assign in_a[0:A_WIDTH/2-1] = mode_i[MODE_BIT_REGI_LOWER] ? a_i_reg[0:A_WIDTH/2-1] : a_i[0:A_WIDTH/2-1];
assign in_a[A_WIDTH/2:A_WIDTH-1] = mode_i[MODE_BIT_REGI_UPPER] ? a_i_reg[A_WIDTH/2:A_WIDTH-1] : a_i[A_WIDTH/2:A_WIDTH-1];
assign in_b[0:B_WIDTH/2-1] = mode_i[MODE_BIT_REGI_LOWER] ? b_i_reg[0:B_WIDTH/2-1] : b_i[0:B_WIDTH/2-1];
assign in_b[B_WIDTH/2:B_WIDTH-1] = mode_i[MODE_BIT_REGI_UPPER] ? b_i_reg[B_WIDTH/2:B_WIDTH-1] : b_i[B_WIDTH/2:B_WIDTH-1];
assign in_d[0:ACC_OUT_WIDTH/2-1] = mode_i[MODE_BIT_REGI_LOWER] ? d_i_reg[0:ACC_OUT_WIDTH/2-1] : d_i[0:ACC_OUT_WIDTH/2-1];
assign in_d[ACC_OUT_WIDTH/2:ACC_OUT_WIDTH-1] = mode_i[MODE_BIT_REGI_UPPER] ? d_i_reg[ACC_OUT_WIDTH/2:ACC_OUT_WIDTH-1] : d_i[ACC_OUT_WIDTH/2:ACC_OUT_WIDTH-1];
assign out_o[0:ACC_OUT_WIDTH/2-1] = mode_i[MODE_BIT_REGO_LOWER] ? out_o_reg[0:ACC_OUT_WIDTH/2-1] : cas_out[0:ACC_OUT_WIDTH/2-1];
assign out_o[ACC_OUT_WIDTH/2:ACC_OUT_WIDTH-1] = mode_i[MODE_BIT_REGO_UPPER] ? out_o_reg[ACC_OUT_WIDTH/2:ACC_OUT_WIDTH-1] : cas_out[ACC_OUT_WIDTH/2:ACC_OUT_WIDTH-1];
// Control logic for registering inputs and outputs of the multipliers
wire [0:A_WIDTH-1] mac_a;
wire [0:B_WIDTH-1] mac_b;
wire [0:ACC_OUT_WIDTH-1] mac_d;
wire [0:ACC_OUT_WIDTH-1] mac_out;
reg [0:A_WIDTH-1] in_a_reg;
reg [0:B_WIDTH-1] in_b_reg;
reg [0:ACC_OUT_WIDTH-1] in_d_reg;
wire [0:ACC_OUT_WIDTH/2-1] mul_out_0;
wire [0:ACC_OUT_WIDTH/2-1] mul_out_1;
wire [0:ACC_OUT_WIDTH/2-1] mul_out_2;
wire [0:ACC_OUT_WIDTH/2-1] mul_out_3;
reg [0:ACC_OUT_WIDTH/2-1] mul_out_0_reg;
reg [0:ACC_OUT_WIDTH/2-1] mul_out_1_reg;
reg [0:ACC_OUT_WIDTH/2-1] mul_out_2_reg;
reg [0:ACC_OUT_WIDTH/2-1] mul_out_3_reg;
wire [0:ACC_OUT_WIDTH/2-1] q_o_0;
wire [0:ACC_OUT_WIDTH/2-1] q_o_1;
wire [0:ACC_OUT_WIDTH/2-1] q_o_2;
wire [0:ACC_OUT_WIDTH/2-1] q_o_3;
always @(posedge clk_core or negedge clr) begin
if (clr == 1'b0) begin
in_a_reg <= 0;
in_b_reg <= 0;
in_d_reg <= 0;
mul_out_0_reg <= 0;
mul_out_1_reg <= 0;
mul_out_2_reg <= 0;
mul_out_3_reg <= 0;
end else begin
in_a_reg <= in_a;
in_b_reg <= in_b;
in_d_reg <= in_d;
mul_out_0_reg <= mul_out_0;
mul_out_1_reg <= mul_out_1;
mul_out_2_reg <= mul_out_2;
mul_out_3_reg <= mul_out_3;
end
end
assign mac_a = mode_i[MODE_MUL_INPUT_REG] ? in_a_reg : in_a;
assign mac_b = mode_i[MODE_MUL_INPUT_REG] ? in_b_reg : in_b;
assign mac_d = mode_i[MODE_MUL_INPUT_REG] ? in_d_reg : in_d;
assign q_o_0 = mode_i[MODE_MUL_OUTPUT_REG] ? mul_out_0_reg : mul_out_0;
assign q_o_1 = mode_i[MODE_MUL_OUTPUT_REG] ? mul_out_1_reg : mul_out_1;
assign q_o_2 = mode_i[MODE_MUL_OUTPUT_REG] ? mul_out_2_reg : mul_out_2;
assign q_o_3 = mode_i[MODE_MUL_OUTPUT_REG] ? mul_out_3_reg : mul_out_3;
// Control logic around the core computing units
always @(*) begin
case (mode_i[MODE_BIT_MAC_LSB:MODE_BIT_MAC_MSB])
4'b0000: begin
mul_out_0 = mac_a[0:A_WIDTH/4-1] * mac_b[0:B_WIDTH/4-1];
mul_out_1 = mac_a[A_WIDTH/4:A_WIDTH/2-1] * mac_b[B_WIDTH/4:B_WIDTH/2-1] + q_o_0;
mul_out_2 = mac_a[A_WIDTH/2:A_WIDTH/4*3-1] * mac_b[B_WIDTH/2:B_WIDTH/4*3-1] + q_o_1;
mul_out_3 = mac_a[A_WIDTH/4*3:A_WIDTH-1] * mac_b[B_WIDTH/4*3:B_WIDTH-1] + q_o_2;
mac_out = q_o_3;
end
4'b0001: begin
mul_out_0 = mac_a[0:A_WIDTH/4-1] * mac_b[0:B_WIDTH/4-1] + mac_d[0:ACC_OUT_WIDTH/2-1];
mul_out_2 = mac_a[A_WIDTH/2:A_WIDTH/4*3-1] * mac_b[B_WIDTH/2:B_WIDTH/4*3-1] + mac_d[ACC_OUT_WIDTH/2:ACC_OUT_WIDTH-1];
mul_out_3 = mac_a[A_WIDTH/4*3:A_WIDTH-1] * mac_b[B_WIDTH/4*3:B_WIDTH-1] + q_o_2;
mac_out = {q_o_0, q_o_3};
end
4'b0010: begin
mul_out_0 = mac_a[0:A_WIDTH/4-1] * mac_b[0:B_WIDTH/4-1];
mul_out_1 = mac_a[A_WIDTH/4:A_WIDTH/2-1] * mac_b[B_WIDTH/4:B_WIDTH/2-1] + q_o_0;
mul_out_3 = mac_a[A_WIDTH/2:A_WIDTH/4*3-1] * mac_b[B_WIDTH/2:B_WIDTH/4*3-1];
mac_out = {q_o_1, q_o_2};
end
4'b0011: begin
mul_out_0 = mac_a[0:A_WIDTH/4-1] * mac_b[0:B_WIDTH/4-1] + out_o_reg[0:ACC_OUT_WIDTH/2-1];
mul_out_1 = mac_a[A_WIDTH/4:A_WIDTH/2-1] * mac_b[B_WIDTH/4:B_WIDTH/2-1] + out_o_reg[ACC_OUT_WIDTH/2:ACC_OUT_WIDTH-1];
mac_out = {q_o_0, q_o_1};
end
4'b0100: begin
mac_out = mac_a[0:A_WIDTH/2-1] * mac_b[0:B_WIDTH/2-1];
end
4'b0101: begin
mul_out_0 = mac_a[0:A_WIDTH/4-1] * mac_b[0:B_WIDTH/4-1] + mac_d[0:ACC_OUT_WIDTH/2-1];
mul_out_1 = mac_a[A_WIDTH/4:A_WIDTH/2-1] * mac_b[B_WIDTH/4:B_WIDTH/2-1] + mac_d[ACC_OUT_WIDTH/2:ACC_OUT_WIDTH-1];
mac_out = {q_o_0, q_o_1};
end
4'b0110: begin
mul_out_0 = mac_a[0:A_WIDTH/4-1] * mac_b[0:B_WIDTH/4-1];
mul_out_1 = mac_a[A_WIDTH/4:A_WIDTH/2-1] * mac_b[B_WIDTH/4:B_WIDTH/2-1];
mul_out_2 = mac_a[A_WIDTH/2:A_WIDTH/4*3-1] * mac_b[B_WIDTH/2:B_WIDTH/4*3-1];
mul_out_3 = mac_a[A_WIDTH/4*3:A_WIDTH-1] * mac_b[B_WIDTH/4*3:B_WIDTH-1];
mac_out = {q_o_0[0:ACC_OUT_WIDTH/4-1], q_o_1[0:ACC_OUT_WIDTH/4-1], q_o_2[0:ACC_OUT_WIDTH/4-1], q_o_3[0:ACC_OUT_WIDTH/4-1]};
end
4'b1000: begin
mul_out_0 = mac_a[0:A_WIDTH/4-1] * mac_b[0:B_WIDTH/4-1];
mul_out_1 = mac_a[A_WIDTH/4:A_WIDTH/2-1] * mac_b[B_WIDTH/4:B_WIDTH/2-1];
mac_out = {q_o_0, q_o_1};
end
4'b1001: begin
mul_out_0 = mac_a[0:A_WIDTH/4-1] * mac_b[0:B_WIDTH/4-1] + mac_d[0:ACC_OUT_WIDTH/2-1];
mul_out_1 = mac_a[A_WIDTH/4:A_WIDTH/2-1] * mac_b[B_WIDTH/4:B_WIDTH/2-1] + q_o_0;
mul_out_2 = mac_a[A_WIDTH/2:A_WIDTH/4*3-1] * mac_b[B_WIDTH/2:B_WIDTH/4*3-1] + q_o_1;
mul_out_3 = mac_a[A_WIDTH/4*3:A_WIDTH-1] * mac_b[B_WIDTH/4*3:B_WIDTH-1] + q_o_2;
mac_out = {q_o_2, q_o_3};
end
4'b1010: begin
mul_out_0 = mac_a[0:A_WIDTH/4-1] * mac_b[0:B_WIDTH/4-1];
mul_out_1 = mac_a[A_WIDTH/4:A_WIDTH/2-1] * mac_b[B_WIDTH/4:B_WIDTH/2-1] + q_o_0;
mul_out_2 = mac_a[A_WIDTH/2:A_WIDTH/4*3-1] * mac_b[B_WIDTH/2:B_WIDTH/4*3-1] + q_o_1;
mul_out_3 = mac_a[A_WIDTH/4*3:A_WIDTH-1] * mac_b[B_WIDTH/4*3:B_WIDTH-1] + q_o_2;
mac_out = {q_o_1, q_o_3};
end
4'b1011: begin
mul_out_0 = mac_a[0:A_WIDTH/4-1] * mac_b[0:B_WIDTH/4-1];
mul_out_1 = mac_a[A_WIDTH/4:A_WIDTH/2-1] * mac_b[B_WIDTH/4:B_WIDTH/2-1] + q_o_0;
mul_out_2 = mac_a[A_WIDTH/2:A_WIDTH/4*3-1] * mac_b[B_WIDTH/2:B_WIDTH/4*3-1];
mul_out_3 = mac_a[A_WIDTH/4*3:A_WIDTH-1] * mac_b[B_WIDTH/4*3:B_WIDTH-1] + q_o_2;
mac_out = {q_o_1, q_o_3};
end
4'b1101: begin
mul_out_2 = mac_a[A_WIDTH/2:A_WIDTH/4*3-1] * mac_b[B_WIDTH/2:B_WIDTH/4*3-1] + mac_d[0:ACC_OUT_WIDTH/2-1];
mul_out_3 = mac_a[A_WIDTH/4*3:A_WIDTH-1] * mac_b[B_WIDTH/4*3:B_WIDTH-1] + mac_d[ACC_OUT_WIDTH/2:ACC_OUT_WIDTH-1];
mac_out = {q_o_2, q_o_3};
end
4'b1110: begin
mul_out_0 = mac_a[0:A_WIDTH/4-1] * mac_b[0:B_WIDTH/4-1];
mul_out_2 = mac_a[A_WIDTH/2:A_WIDTH/4*3-1] * mac_b[B_WIDTH/2:B_WIDTH/4*3-1];
mul_out_3 = mac_a[A_WIDTH/4*3:A_WIDTH-1] * mac_b[B_WIDTH/4*3:B_WIDTH-1];
mac_out = {q_o_0, q_o_2[0:ACC_OUT_WIDTH/4-1], q_o_3[0:ACC_OUT_WIDTH/4-1]};
end
default: begin
mul_out_0 = mac_a[0:A_WIDTH/4-1] * mac_b[0:B_WIDTH/4-1];
mul_out_2 = mac_a[A_WIDTH/2:A_WIDTH/4*3-1] * mac_b[B_WIDTH/2:B_WIDTH/4*3-1];
mul_out_3 = mac_a[A_WIDTH/4*3:A_WIDTH-1] * mac_b[B_WIDTH/4*3:B_WIDTH-1];
mac_out = {q_o_0, q_o_2[0:ACC_OUT_WIDTH/4-1], q_o_3[0:ACC_OUT_WIDTH/4-1]};
end
endcase
end
always @(*) begin
cas_out = cas_g ? mac_out + mac_d : mac_out;
end
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,35 @@
module mult_24x20_map (
input [0:23] A,
input [0:19] B,
output [0:43] Y
);
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;
parameter A_WIDTH = 0;
parameter B_WIDTH = 0;
parameter Y_WIDTH = 0;
mult24x20 #() _TECHMAP_REPLACE_ (
.A (A),
.B (B),
.Y (Y) );
endmodule
module mult_12x10_map (
input [0:11] A,
input [0:9] B,
output [0:21] Y
);
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;
parameter A_WIDTH = 0;
parameter B_WIDTH = 0;
parameter Y_WIDTH = 0;
mult12x10 #() _TECHMAP_REPLACE_ (
.A (A),
.B (B),
.Y (Y) );
endmodule

View file

@ -0,0 +1,123 @@
# 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
opt
#techmap -map +/techmap.v -map ${YOSYS_ADDER_MAP_VERILOG}
#share
#opt -nodffe
#fsm
# Run a quick follow-up optimization to sweep out unused nets/signals
#opt -fast -nodffe
# 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_AVG_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}