[test] reworking adder mapping flow to validate carry chain mapping

This commit is contained in:
tangxifan 2023-06-20 16:57:08 -07:00
parent ce71f097b4
commit dba48fb171
6 changed files with 125 additions and 164 deletions

View File

@ -0,0 +1,48 @@
# 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
# Map Adders
techmap -map +/techmap.v -map ${YOSYS_ADDER_MAP_VERILOG}
opt -fast -nodffe -nosdff
opt_expr
opt_merge
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
# LUT mapping
abc -lut ${LUT_SIZE}
# Check
synth -run check
# Clean and output blif
opt_clean -purge
write_blif ${OUTPUT_BLIF}

View File

@ -1,6 +1,7 @@
//--------------------------------------- //---------------------------------------
// 1-bit adder // 1-bit adder
//--------------------------------------- //---------------------------------------
(* abc9_box, lib_whitebox *)
module adder( module adder(
input cin, input cin,
input a, input a,

View File

@ -1,8 +1,9 @@
////////////////////////// // Arithmetic units: adder
// arithmetic // // 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
module \$alu (A, B, CI, BI, X, Y, CO); (* techmap_celltype = "$alu" *)
module _openfpga_alu (A, B, CI, BI, X, Y, CO);
parameter A_SIGNED = 0; parameter A_SIGNED = 0;
parameter B_SIGNED = 0; parameter B_SIGNED = 0;
@ -12,27 +13,48 @@ parameter Y_WIDTH = 1;
input [A_WIDTH-1:0] A; input [A_WIDTH-1:0] A;
input [B_WIDTH-1:0] B; input [B_WIDTH-1:0] B;
output [Y_WIDTH:0] X, Y; output [Y_WIDTH-1:0] X, Y;
input CI, BI; input CI, BI;
output [Y_WIDTH:0] CO; output [Y_WIDTH-1:0] CO;
wire [Y_WIDTH-1:0] AA, BB;
wire [1024:0] _TECHMAP_DO_ = "splitnets CARRY; clean"; wire [1024:0] _TECHMAP_DO_ = "splitnets CARRY; clean";
(* 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];
// 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
generate generate
if (A_SIGNED && B_SIGNED) begin:BLOCK1 adder intermediate_adder (
assign AA = $signed(A), BB = BI ? ~$signed(B) : $signed(B); .cin ( ),
end else begin:BLOCK2 .cout (CARRY[0]),
assign AA = $unsigned(A), BB = BI ? ~$unsigned(B) : $unsigned(B); .a (CI ),
end .b (CI ),
.sumout ( )
);
adder first_adder (
.cin (CARRY[0]),
.cout (CARRY[1]),
.a (AA[0] ),
.b (BB[0] ),
.sumout (Y[0] )
);
endgenerate endgenerate
wire [Y_WIDTH: 0 ] CARRY;
assign CARRY[0] = CI;
genvar i; genvar i;
generate for (i = 0; i < Y_WIDTH - 1; i = i+1) begin:gen3 generate for (i = 1; i < Y_WIDTH ; i = i+1) begin:gen3
adder my_adder ( adder my_adder (
.cin (CARRY[i] ), .cin (CARRY[i] ),
.cout (CARRY[i+1]), .cout (CARRY[i+1]),
@ -41,124 +63,5 @@ endgenerate
.sumout (Y[i] ) .sumout (Y[i] )
); );
end endgenerate end endgenerate
assign X = AA ^ BB;
generate if ((Y_WIDTH -1) % 20 == 0) begin:gen4
assign Y[Y_WIDTH-1] = CARRY[Y_WIDTH-1];
end else begin:gen5
adder my_adder (
.cin (CARRY[Y_WIDTH - 1]),
.cout (CARRY[Y_WIDTH]),
.a (1'b0),
.b (1'b0),
.sumout (Y[Y_WIDTH -1])
);
end
endgenerate
endmodule
//---------------------------------------------------------
module \$fa (A, B, C, X, Y);
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;
parameter A_WIDTH = 1;
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
input [A_WIDTH-1:0] A;
input [B_WIDTH-1:0] B;
input C;
output [Y_WIDTH:0] X, Y;
wire [Y_WIDTH-1:0] AA, BB;
wire [1024:0] _TECHMAP_DO_ = "splitnets CARRY; clean";
generate
if (A_SIGNED && B_SIGNED) begin:BLOCK1
assign AA = $signed(A), BB = $signed(B);
end else begin:BLOCK2
assign AA = $unsigned(A), BB = $unsigned(B);
end
endgenerate
wire [Y_WIDTH: 0 ] CARRY;
assign CARRY[0] = C;
genvar i;
generate for (i = 0; i < Y_WIDTH - 1; i = i+1) begin:gen3
adder my_adder (
.cin (CARRY[i]),
.cout (CARRY[i+1]),
.a (AA[i]),
.b (BB[i]),
.sumout (Y[i])
);
end endgenerate
generate if ((Y_WIDTH -1) % 20 == 0) begin:gen4
assign Y[Y_WIDTH-1] = CARRY[Y_WIDTH-1];
end else begin:gen5
adder my_adder (
.cin (CARRY[Y_WIDTH - 1]),
.cout (CARRY[Y_WIDTH]),
.a (1'b0),
.b (1'b0),
.sumout (Y[Y_WIDTH -1])
);
end
endgenerate
endmodule
//---------------------------------------------------------
module \$add (A, B, Y);
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;
parameter A_WIDTH = 1;
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
input [A_WIDTH-1:0] A;
input [B_WIDTH-1:0] B;
output [Y_WIDTH:0] Y;
wire [Y_WIDTH-1:0] AA, BB;
wire [1024:0] _TECHMAP_DO_ = "splitnets CARRY; clean";
generate
if (A_SIGNED && B_SIGNED) begin:BLOCK1
assign AA = $signed(A), BB = $signed(B);
end else begin:BLOCK2
assign AA = $unsigned(A), BB = $unsigned(B);
end
endgenerate
wire [Y_WIDTH: 0 ] CARRY;
assign CARRY[0] = 1'b0;
genvar i;
generate for (i = 0; i < Y_WIDTH - 1; i = i+1) begin:gen3
adder my_adder (
.cin (CARRY[i]),
.cout (CARRY[i+1]),
.a (AA[i]),
.b (BB[i]),
.sumout (Y[i])
);
end endgenerate
generate if ((Y_WIDTH -1) % 20 == 0) begin:gen4
assign Y[Y_WIDTH-1] = CARRY[Y_WIDTH-1];
end else begin:gen5
adder my_adder (
.cin (CARRY[Y_WIDTH - 1]),
.cout (CARRY[Y_WIDTH]),
.a (1'b0),
.b (1'b0),
.sumout (Y[Y_WIDTH -1])
);
end
endgenerate
endmodule endmodule

View File

@ -294,6 +294,7 @@ def generate_each_task_actions(taskname):
yosys_params = [ yosys_params = [
"read_verilog_options", "read_verilog_options",
"yosys_args", "yosys_args",
"yosys_adder_map_verilog",
"yosys_bram_map_rules", "yosys_bram_map_rules",
"yosys_bram_map_verilog", "yosys_bram_map_verilog",
"yosys_cell_sim_verilog", "yosys_cell_sim_verilog",

View File

@ -0,0 +1,4 @@
<pin_constraints>
<!-- Intend to be empty -->
</pin_constraints>

View File

@ -9,29 +9,33 @@
[GENERAL] [GENERAL]
run_engine=openfpga_shell run_engine=openfpga_shell
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = true power_analysis = false
spice_output=false spice_output=false
verilog_output=true verilog_output=true
timeout_each_job = 20*60 timeout_each_job = 20*60
fpga_flow=vpr_blif fpga_flow=yosys_vpr
[OpenFPGA_SHELL] [OpenFPGA_SHELL]
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/fix_device_example_script.openfpga openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/example_without_ace_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_40nm_openfpga.xml openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_40nm_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
openfpga_vpr_device_layout=2x2 openfpga_pin_constraints_file=${PATH:TASK_DIR}/config/dummy_pin_constraints.xml
[ARCHITECTURES] [ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_40nm.xml arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_40nm.xml
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/adder/adder_8/adder_8.v
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench0_top = and2 # Yosys script parameters
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_adders_sim.v
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v bench_yosys_adder_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_arith_map.v
bench0_chan_width = 300 bench_read_verilog_options_common = -nolatches
bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_adder_flow.ys
# Benchmark information
bench0_top = adder_8
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test= end_flow_with_test=