From dba48fb17132da971ac9574037ac566ca51d03ab Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 20 Jun 2023 16:57:08 -0700 Subject: [PATCH 1/2] [test] reworking adder mapping flow to validate carry chain mapping --- .../misc/ys_tmpl_yosys_vpr_adder_flow.ys | 48 ++++ .../openfpga_adders_sim.v | 1 + .../openfpga_arith_map.v | 211 +++++------------- openfpga_flow/scripts/run_fpga_task.py | 1 + .../config/dummy_pin_constraints.xml | 4 + .../adder/hard_adder/config/task.conf | 24 +- 6 files changed, 125 insertions(+), 164 deletions(-) create mode 100644 openfpga_flow/misc/ys_tmpl_yosys_vpr_adder_flow.ys create mode 100644 openfpga_flow/tasks/fpga_verilog/adder/hard_adder/config/dummy_pin_constraints.xml diff --git a/openfpga_flow/misc/ys_tmpl_yosys_vpr_adder_flow.ys b/openfpga_flow/misc/ys_tmpl_yosys_vpr_adder_flow.ys new file mode 100644 index 000000000..092aeea3b --- /dev/null +++ b/openfpga_flow/misc/ys_tmpl_yosys_vpr_adder_flow.ys @@ -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} diff --git a/openfpga_flow/openfpga_yosys_techlib/openfpga_adders_sim.v b/openfpga_flow/openfpga_yosys_techlib/openfpga_adders_sim.v index 9d82dc715..da3baa337 100644 --- a/openfpga_flow/openfpga_yosys_techlib/openfpga_adders_sim.v +++ b/openfpga_flow/openfpga_yosys_techlib/openfpga_adders_sim.v @@ -1,6 +1,7 @@ //--------------------------------------- // 1-bit adder //--------------------------------------- +(* abc9_box, lib_whitebox *) module adder( input cin, input a, diff --git a/openfpga_flow/openfpga_yosys_techlib/openfpga_arith_map.v b/openfpga_flow/openfpga_yosys_techlib/openfpga_arith_map.v index d5227c16a..8763d6ced 100644 --- a/openfpga_flow/openfpga_yosys_techlib/openfpga_arith_map.v +++ b/openfpga_flow/openfpga_yosys_techlib/openfpga_arith_map.v @@ -1,164 +1,67 @@ -////////////////////////// -// arithmetic // -////////////////////////// +// 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 -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 B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; + 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] X, Y; + 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:0] CO; + input CI, BI; + 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"; -generate - if (A_SIGNED && B_SIGNED) begin:BLOCK1 - assign AA = $signed(A), BB = BI ? ~$signed(B) : $signed(B); - end else begin:BLOCK2 - assign AA = $unsigned(A), BB = BI ? ~$unsigned(B) : $unsigned(B); - end -endgenerate + (* 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)); - wire [Y_WIDTH: 0 ] CARRY; - assign CARRY[0] = CI; + (* 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; - 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 + 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 + adder intermediate_adder ( + .cin ( ), + .cout (CARRY[0]), + .a (CI ), + .b (CI ), + .sumout ( ) + ); - 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 + adder first_adder ( + .cin (CARRY[0]), + .cout (CARRY[1]), + .a (AA[0] ), + .b (BB[0] ), + .sumout (Y[0] ) + ); + endgenerate -//--------------------------------------------------------- - -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 + genvar i; + generate for (i = 1; i < Y_WIDTH ; 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 + assign X = AA ^ BB; +endmodule diff --git a/openfpga_flow/scripts/run_fpga_task.py b/openfpga_flow/scripts/run_fpga_task.py index e215a3f50..c021eebf7 100644 --- a/openfpga_flow/scripts/run_fpga_task.py +++ b/openfpga_flow/scripts/run_fpga_task.py @@ -294,6 +294,7 @@ def generate_each_task_actions(taskname): yosys_params = [ "read_verilog_options", "yosys_args", + "yosys_adder_map_verilog", "yosys_bram_map_rules", "yosys_bram_map_verilog", "yosys_cell_sim_verilog", diff --git a/openfpga_flow/tasks/fpga_verilog/adder/hard_adder/config/dummy_pin_constraints.xml b/openfpga_flow/tasks/fpga_verilog/adder/hard_adder/config/dummy_pin_constraints.xml new file mode 100644 index 000000000..c7bb833ec --- /dev/null +++ b/openfpga_flow/tasks/fpga_verilog/adder/hard_adder/config/dummy_pin_constraints.xml @@ -0,0 +1,4 @@ + + + + diff --git a/openfpga_flow/tasks/fpga_verilog/adder/hard_adder/config/task.conf b/openfpga_flow/tasks/fpga_verilog/adder/hard_adder/config/task.conf index 839bd3e09..54f0901c9 100644 --- a/openfpga_flow/tasks/fpga_verilog/adder/hard_adder/config/task.conf +++ b/openfpga_flow/tasks/fpga_verilog/adder/hard_adder/config/task.conf @@ -9,29 +9,33 @@ [GENERAL] run_engine=openfpga_shell power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml -power_analysis = true +power_analysis = false spice_output=false verilog_output=true timeout_each_job = 20*60 -fpga_flow=vpr_blif +fpga_flow=yosys_vpr [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_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml -openfpga_vpr_device_layout=2x2 +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +openfpga_pin_constraints_file=${PATH:TASK_DIR}/config/dummy_pin_constraints.xml [ARCHITECTURES] arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_40nm.xml [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] -bench0_top = and2 -bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act -bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v -bench0_chan_width = 300 +# Yosys script parameters +bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_adders_sim.v +bench_yosys_adder_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_arith_map.v +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] end_flow_with_test= From 84edd41342c811c7adafb9bcf13a4c2dcec315e2 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 20 Jun 2023 17:09:31 -0700 Subject: [PATCH 2/2] [test] fixed the bug in adder mapping --- .../misc/ys_tmpl_yosys_vpr_adder_flow.ys | 2 +- .../openfpga_adders_sim.v | 17 ++++++++--------- .../openfpga_yosys_techlib/openfpga_arith_map.v | 2 +- .../adder/hard_adder/config/task.conf | 1 + 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/openfpga_flow/misc/ys_tmpl_yosys_vpr_adder_flow.ys b/openfpga_flow/misc/ys_tmpl_yosys_vpr_adder_flow.ys index 092aeea3b..3d3acb5a5 100644 --- a/openfpga_flow/misc/ys_tmpl_yosys_vpr_adder_flow.ys +++ b/openfpga_flow/misc/ys_tmpl_yosys_vpr_adder_flow.ys @@ -41,7 +41,7 @@ clean abc -lut ${LUT_SIZE} # Check -synth -run check +#synth -run check # Clean and output blif opt_clean -purge diff --git a/openfpga_flow/openfpga_yosys_techlib/openfpga_adders_sim.v b/openfpga_flow/openfpga_yosys_techlib/openfpga_adders_sim.v index da3baa337..953ddf685 100644 --- a/openfpga_flow/openfpga_yosys_techlib/openfpga_adders_sim.v +++ b/openfpga_flow/openfpga_yosys_techlib/openfpga_adders_sim.v @@ -3,14 +3,13 @@ //--------------------------------------- (* abc9_box, lib_whitebox *) module adder( - input cin, - input a, - input b, - output cout, - output sumout ); - - - assign sumout = a ^ b ^ cin; - assign cout = (a & b) | ((a | b) & cin); + output sumout, + output cout, + input a, + input b, + input cin +); + assign sumout = a ^ b ^ cin; + assign cout = (a & b) | ((a | b) & cin); endmodule diff --git a/openfpga_flow/openfpga_yosys_techlib/openfpga_arith_map.v b/openfpga_flow/openfpga_yosys_techlib/openfpga_arith_map.v index 8763d6ced..d363226fa 100644 --- a/openfpga_flow/openfpga_yosys_techlib/openfpga_arith_map.v +++ b/openfpga_flow/openfpga_yosys_techlib/openfpga_arith_map.v @@ -3,7 +3,7 @@ // Many thanks to F4PGA for their contribution (* techmap_celltype = "$alu" *) -module _openfpga_alu (A, B, CI, BI, X, Y, CO); +module _80_quicklogic_alu (A, B, CI, BI, X, Y, CO); parameter A_SIGNED = 0; parameter B_SIGNED = 0; diff --git a/openfpga_flow/tasks/fpga_verilog/adder/hard_adder/config/task.conf b/openfpga_flow/tasks/fpga_verilog/adder/hard_adder/config/task.conf index 54f0901c9..d9a5f151a 100644 --- a/openfpga_flow/tasks/fpga_verilog/adder/hard_adder/config/task.conf +++ b/openfpga_flow/tasks/fpga_verilog/adder/hard_adder/config/task.conf @@ -33,6 +33,7 @@ bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga bench_yosys_adder_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_arith_map.v bench_read_verilog_options_common = -nolatches bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_adder_flow.ys +bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys # Benchmark information bench0_top = adder_8