From 671394ec2c49a4d317ad7a930875ec3cd71b33bf Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 23 Apr 2021 20:33:43 -0600 Subject: [PATCH 01/17] [Benchmark] Add microbenchmarks for mac with different sizes for DSP testing --- .../benchmarks/micro_benchmark/mac_2/mac_2.v | 22 +++++++++++++++++++ .../benchmarks/micro_benchmark/mac_4/mac_4.v | 22 +++++++++++++++++++ .../benchmarks/micro_benchmark/mac_6/mac_6.v | 22 +++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 openfpga_flow/benchmarks/micro_benchmark/mac_2/mac_2.v create mode 100644 openfpga_flow/benchmarks/micro_benchmark/mac_4/mac_4.v create mode 100644 openfpga_flow/benchmarks/micro_benchmark/mac_6/mac_6.v diff --git a/openfpga_flow/benchmarks/micro_benchmark/mac_2/mac_2.v b/openfpga_flow/benchmarks/micro_benchmark/mac_2/mac_2.v new file mode 100644 index 000000000..457a94deb --- /dev/null +++ b/openfpga_flow/benchmarks/micro_benchmark/mac_2/mac_2.v @@ -0,0 +1,22 @@ +//------------------------------------------------------- +// Functionality: A 2-bit multiply-acculumate circuit +// Author: Xifan Tang +//------------------------------------------------------- + +module mac_2(a, b, c, out); +parameter DATA_WIDTH = 2; /* declare a parameter. default required */ +input [DATA_WIDTH - 1 : 0] a, b, c; +output [DATA_WIDTH - 1 : 0] out; + +assign out = a * b + c; + +endmodule + + + + + + + + + diff --git a/openfpga_flow/benchmarks/micro_benchmark/mac_4/mac_4.v b/openfpga_flow/benchmarks/micro_benchmark/mac_4/mac_4.v new file mode 100644 index 000000000..c07495eb5 --- /dev/null +++ b/openfpga_flow/benchmarks/micro_benchmark/mac_4/mac_4.v @@ -0,0 +1,22 @@ +//------------------------------------------------------- +// Functionality: A 4-bit multiply-acculumate circuit +// Author: Xifan Tang +//------------------------------------------------------- + +module mac_4(a, b, c, out); +parameter DATA_WIDTH = 4; /* declare a parameter. default required */ +input [DATA_WIDTH - 1 : 0] a, b, c; +output [DATA_WIDTH - 1 : 0] out; + +assign out = a * b + c; + +endmodule + + + + + + + + + diff --git a/openfpga_flow/benchmarks/micro_benchmark/mac_6/mac_6.v b/openfpga_flow/benchmarks/micro_benchmark/mac_6/mac_6.v new file mode 100644 index 000000000..1909c2d30 --- /dev/null +++ b/openfpga_flow/benchmarks/micro_benchmark/mac_6/mac_6.v @@ -0,0 +1,22 @@ +//------------------------------------------------------- +// Functionality: A 6-bit multiply-acculumate circuit +// Author: Xifan Tang +//------------------------------------------------------- + +module mac_6(a, b, c, out); +parameter DATA_WIDTH = 6; /* declare a parameter. default required */ +input [DATA_WIDTH - 1 : 0] a, b, c; +output [DATA_WIDTH - 1 : 0] out; + +assign out = a * b + c; + +endmodule + + + + + + + + + From 200b6d39a6f17fda3e95c836960a4b7ba123f401 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 23 Apr 2021 20:36:28 -0600 Subject: [PATCH 02/17] [Benchmark] Add more micro benchmarks for mac ranging from 8 bit to 32 bit --- .../micro_benchmark/mac/mac_12/mac_12.v | 22 +++++++++++++++++++ .../micro_benchmark/mac/mac_16/mac_16.v | 22 +++++++++++++++++++ .../micro_benchmark/{ => mac}/mac_2/mac_2.v | 0 .../micro_benchmark/mac/mac_32/mac_32.v | 22 +++++++++++++++++++ .../micro_benchmark/{ => mac}/mac_4/mac_4.v | 0 .../micro_benchmark/{ => mac}/mac_6/mac_6.v | 0 .../micro_benchmark/{ => mac}/mac_8/mac_8.v | 0 7 files changed, 66 insertions(+) create mode 100644 openfpga_flow/benchmarks/micro_benchmark/mac/mac_12/mac_12.v create mode 100644 openfpga_flow/benchmarks/micro_benchmark/mac/mac_16/mac_16.v rename openfpga_flow/benchmarks/micro_benchmark/{ => mac}/mac_2/mac_2.v (100%) create mode 100644 openfpga_flow/benchmarks/micro_benchmark/mac/mac_32/mac_32.v rename openfpga_flow/benchmarks/micro_benchmark/{ => mac}/mac_4/mac_4.v (100%) rename openfpga_flow/benchmarks/micro_benchmark/{ => mac}/mac_6/mac_6.v (100%) rename openfpga_flow/benchmarks/micro_benchmark/{ => mac}/mac_8/mac_8.v (100%) diff --git a/openfpga_flow/benchmarks/micro_benchmark/mac/mac_12/mac_12.v b/openfpga_flow/benchmarks/micro_benchmark/mac/mac_12/mac_12.v new file mode 100644 index 000000000..ccbade6c0 --- /dev/null +++ b/openfpga_flow/benchmarks/micro_benchmark/mac/mac_12/mac_12.v @@ -0,0 +1,22 @@ +//------------------------------------------------------- +// Functionality: A 12-bit multiply-acculumate circuit +// Author: Xifan Tang +//------------------------------------------------------- + +module mac_12(a, b, c, out); +parameter DATA_WIDTH = 12; /* declare a parameter. default required */ +input [DATA_WIDTH - 1 : 0] a, b, c; +output [DATA_WIDTH - 1 : 0] out; + +assign out = a * b + c; + +endmodule + + + + + + + + + diff --git a/openfpga_flow/benchmarks/micro_benchmark/mac/mac_16/mac_16.v b/openfpga_flow/benchmarks/micro_benchmark/mac/mac_16/mac_16.v new file mode 100644 index 000000000..3fc2270e5 --- /dev/null +++ b/openfpga_flow/benchmarks/micro_benchmark/mac/mac_16/mac_16.v @@ -0,0 +1,22 @@ +//------------------------------------------------------- +// Functionality: A 16-bit multiply-acculumate circuit +// Author: Xifan Tang +//------------------------------------------------------- + +module mac_16(a, b, c, out); +parameter DATA_WIDTH = 16; /* declare a parameter. default required */ +input [DATA_WIDTH - 1 : 0] a, b, c; +output [DATA_WIDTH - 1 : 0] out; + +assign out = a * b + c; + +endmodule + + + + + + + + + diff --git a/openfpga_flow/benchmarks/micro_benchmark/mac_2/mac_2.v b/openfpga_flow/benchmarks/micro_benchmark/mac/mac_2/mac_2.v similarity index 100% rename from openfpga_flow/benchmarks/micro_benchmark/mac_2/mac_2.v rename to openfpga_flow/benchmarks/micro_benchmark/mac/mac_2/mac_2.v diff --git a/openfpga_flow/benchmarks/micro_benchmark/mac/mac_32/mac_32.v b/openfpga_flow/benchmarks/micro_benchmark/mac/mac_32/mac_32.v new file mode 100644 index 000000000..e22fd596c --- /dev/null +++ b/openfpga_flow/benchmarks/micro_benchmark/mac/mac_32/mac_32.v @@ -0,0 +1,22 @@ +//------------------------------------------------------- +// Functionality: A 32-bit multiply-acculumate circuit +// Author: Xifan Tang +//------------------------------------------------------- + +module mac_32(a, b, c, out); +parameter DATA_WIDTH = 32; /* declare a parameter. default required */ +input [DATA_WIDTH - 1 : 0] a, b, c; +output [DATA_WIDTH - 1 : 0] out; + +assign out = a * b + c; + +endmodule + + + + + + + + + diff --git a/openfpga_flow/benchmarks/micro_benchmark/mac_4/mac_4.v b/openfpga_flow/benchmarks/micro_benchmark/mac/mac_4/mac_4.v similarity index 100% rename from openfpga_flow/benchmarks/micro_benchmark/mac_4/mac_4.v rename to openfpga_flow/benchmarks/micro_benchmark/mac/mac_4/mac_4.v diff --git a/openfpga_flow/benchmarks/micro_benchmark/mac_6/mac_6.v b/openfpga_flow/benchmarks/micro_benchmark/mac/mac_6/mac_6.v similarity index 100% rename from openfpga_flow/benchmarks/micro_benchmark/mac_6/mac_6.v rename to openfpga_flow/benchmarks/micro_benchmark/mac/mac_6/mac_6.v diff --git a/openfpga_flow/benchmarks/micro_benchmark/mac_8/mac_8.v b/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v similarity index 100% rename from openfpga_flow/benchmarks/micro_benchmark/mac_8/mac_8.v rename to openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v From 189c94ff196474c2aee3215bc52bb51f7da49e73 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 23 Apr 2021 20:44:14 -0600 Subject: [PATCH 03/17] [Test] Deploy new mac benchmarks to tests --- .../dsp/single_mode_mult_8x8/config/task.conf | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/openfpga_flow/tasks/fpga_verilog/dsp/single_mode_mult_8x8/config/task.conf b/openfpga_flow/tasks/fpga_verilog/dsp/single_mode_mult_8x8/config/task.conf index 1c84a02f7..a03071351 100644 --- a/openfpga_flow/tasks/fpga_verilog/dsp/single_mode_mult_8x8/config/task.conf +++ b/openfpga_flow/tasks/fpga_verilog/dsp/single_mode_mult_8x8/config/task.conf @@ -30,13 +30,19 @@ openfpga_vpr_device_layout=3x2 arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_dsp8_nonLR_caravel_io_skywater130nm.xml [BENCHMARKS] -bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac_8/mac_8.v +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_2/mac_2.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_4/mac_4.v +bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_6/mac_6.v +bench3=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v [SYNTHESIS_PARAM] bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_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 -bench0_top = mac_8 +bench0_top = mac_2 +bench1_top = mac_4 +bench2_top = mac_6 +bench3_top = mac_8 [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] end_flow_with_test= From 09cc7f0007775b996ce8b2d78de99ce745a7de15 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 23 Apr 2021 20:44:36 -0600 Subject: [PATCH 04/17] [Script] Enable constant net routing for heterogeneous FPGAs --- .../fix_heterogeneous_device_example_script.openfpga | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfpga_flow/openfpga_shell_scripts/fix_heterogeneous_device_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/fix_heterogeneous_device_example_script.openfpga index 10ed5f17a..1d6cca82f 100644 --- a/openfpga_flow/openfpga_shell_scripts/fix_heterogeneous_device_example_script.openfpga +++ b/openfpga_flow/openfpga_shell_scripts/fix_heterogeneous_device_example_script.openfpga @@ -1,6 +1,6 @@ # Run VPR for the 'and' design #--write_rr_graph example_rr_graph.xml -vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling route --device ${OPENFPGA_VPR_DEVICE_LAYOUT} +vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --device ${OPENFPGA_VPR_DEVICE_LAYOUT} --constant_net_method route # Read OpenFPGA architecture definition read_openfpga_arch -f ${OPENFPGA_ARCH_FILE} From c44688739d4833337bf33e38935b7646ec593b60 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 23 Apr 2021 22:12:26 -0600 Subject: [PATCH 05/17] [HDL] Add verilog netlist for the fracturable 16-bit multiplier blocks --- .../verilog/frac_mult_16x16.v | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 openfpga_flow/openfpga_cell_library/verilog/frac_mult_16x16.v diff --git a/openfpga_flow/openfpga_cell_library/verilog/frac_mult_16x16.v b/openfpga_flow/openfpga_cell_library/verilog/frac_mult_16x16.v new file mode 100644 index 000000000..7fedc711c --- /dev/null +++ b/openfpga_flow/openfpga_cell_library/verilog/frac_mult_16x16.v @@ -0,0 +1,29 @@ +//----------------------------------------------------- +// Design Name : frac_mult_16x16 +// File Name : frac_mult_16x16.v +// Function : A 16-bit multiplier which can operate in fracturable modes: +// 1. two 8-bit multipliers +// 2. one 16-bit multipliers +// Coder : Xifan Tang +//----------------------------------------------------- + +module frac_mult_16x16 ( + input [0:15] a, + input [0:15] b, + output [0:31] out, + input [0:0] mode); + + reg [0:63] out_reg; + + always @(mode, a, b) begin + if (1'b1 == mode) begin + out_reg[0:15] <= a[0:7] * b[0:7]; + out_reg[16:31] <= a[8:15] * b[8:15]; + end else begin + out_reg <= a * b; + end + end + + assign out = out_reg; + +endmodule From 0709e5bb81eb38e3c137a113da75b64b502c4ecb Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 24 Apr 2021 13:27:44 -0600 Subject: [PATCH 06/17] [Tool] Fixed a bug in the routing trace finder for direct connections inside repacker --- openfpga/src/repack/repack.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openfpga/src/repack/repack.cpp b/openfpga/src/repack/repack.cpp index 5e25179a5..d6cb669bc 100644 --- a/openfpga/src/repack/repack.cpp +++ b/openfpga/src/repack/repack.cpp @@ -28,6 +28,8 @@ namespace openfpga { * - sink is an input of a primitive pb_type * * Note: + * - This function is applicable ONLY to single-mode pb_types!!! Because their routing traces + * are deterministic: there is only 1 valid path from a source pin to a sink pin!!! * - If there is a fan-out of the current source pb graph pin is not a direct interconnection * the direct search should stop. * - This function is designed for pb graph without local routing @@ -58,6 +60,11 @@ bool rec_direct_search_sink_pb_graph_pins(const t_pb_graph_pin* source_pb_pin, std::vector sink_pb_pins_to_search; + /* Only support single-mode pb_type!!! */ + if (1 != source_pb_pin->parent_node->pb_type->num_modes) { + return false; + } + for (int iedge = 0; iedge < source_pb_pin->num_output_edges; ++iedge) { if (DIRECT_INTERC != source_pb_pin->output_edges[iedge]->interconnect->type) { return false; From 1c6b9a23d78cc1498582b588f122d262b9bae21e Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 24 Apr 2021 13:29:29 -0600 Subject: [PATCH 07/17] [Test] Add new test for multi-mode 16-bit DSP blocks --- .../multi_mode_mult_16x16/config/task.conf | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 openfpga_flow/tasks/fpga_verilog/dsp/multi_mode_mult_16x16/config/task.conf diff --git a/openfpga_flow/tasks/fpga_verilog/dsp/multi_mode_mult_16x16/config/task.conf b/openfpga_flow/tasks/fpga_verilog/dsp/multi_mode_mult_16x16/config/task.conf new file mode 100644 index 000000000..0db63ef8b --- /dev/null +++ b/openfpga_flow/tasks/fpga_verilog/dsp/multi_mode_mult_16x16/config/task.conf @@ -0,0 +1,47 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# Configuration file for running experiments +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs +# Each job execute fpga_flow script on combination of architecture & benchmark +# timeout_each_job is timeout for each job +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +[GENERAL] +run_engine=openfpga_shell +power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml +power_analysis = false +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/fix_heterogeneous_device_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_frac_dsp16_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml +# Yosys script parameters +yosys_cell_sim_verilog=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm_cell_sim.v +yosys_dsp_map_verilog=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm_dsp_map.v +yosys_dsp_map_parameters=-D DSP_A_MAXWIDTH=8 -D DSP_B_MAXWIDTH=8 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_8x8 +# VPR parameter +openfpga_vpr_device_layout=3x2 + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_4/mac_4.v +bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v +bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_16/mac_16.v + +[SYNTHESIS_PARAM] +bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_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 + +bench0_top = mac_4 +bench1_top = mac_8 +bench2_top = mac_16 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= +vpr_fpga_verilog_formal_verification_top_netlist= From ddcdb35b280c1bda4cd4fd9cbc4a17f9418cc7da Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 24 Apr 2021 13:30:03 -0600 Subject: [PATCH 08/17] [Arch] Bug fix in single-mode 8-bit DSP architectures --- ...scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml b/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml index ebef951da..1114d0071 100644 --- a/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +++ b/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_dsp8_caravel_io_skywater130nm_fdhd_cc_openfpga.xml @@ -262,7 +262,6 @@ - From 272d1fffb70fb6a02c4eb4d27f28b9b6b2b4a338 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 24 Apr 2021 13:30:46 -0600 Subject: [PATCH 09/17] [HDL] Add tech library for architecture using multi-mode 16-bit DSP blocks --- ..._nonLR_caravel_io_skywater130nm_cell_sim.v | 25 +++++++++++ ...6_nonLR_caravel_io_skywater130nm_dsp_map.v | 41 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm_cell_sim.v create mode 100644 openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm_dsp_map.v diff --git a/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm_cell_sim.v b/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm_cell_sim.v new file mode 100644 index 000000000..d455c79d0 --- /dev/null +++ b/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm_cell_sim.v @@ -0,0 +1,25 @@ +//----------------------------- +// 8-bit multiplier +//----------------------------- +module mult_8( + input [0:7] A, + input [0:7] B, + output [0:15] Y +); + +assign Y = A * B; + +endmodule + +//----------------------------- +// 16-bit multiplier +//----------------------------- +module mult_16( + input [0:15] A, + input [0:15] B, + output [0:31] Y +); + +assign Y = A * B; + +endmodule diff --git a/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm_dsp_map.v b/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm_dsp_map.v new file mode 100644 index 000000000..035e6f7eb --- /dev/null +++ b/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm_dsp_map.v @@ -0,0 +1,41 @@ +//----------------------------- +// 8-bit multiplier +//----------------------------- +module mult_8x8 ( + input [0:7] A, + input [0:7] B, + output [0:15] Y +); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 0; + parameter B_WIDTH = 0; + parameter Y_WIDTH = 0; + + mult_8 #() _TECHMAP_REPLACE_ ( + .A (A), + .B (B), + .Y (Y) ); + +endmodule + +//----------------------------- +// 16-bit multiplier +//----------------------------- +module mult_16x16 ( + input [0:15] A, + input [0:15] B, + output [0:31] Y +); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 0; + parameter B_WIDTH = 0; + parameter Y_WIDTH = 0; + + mult_16 #() _TECHMAP_REPLACE_ ( + .A (A), + .B (B), + .Y (Y) ); + +endmodule From 4f454abfde2ad6693be9dc422dee48a40fe9ed6a Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 24 Apr 2021 14:01:42 -0600 Subject: [PATCH 10/17] [Arch] Add a new architecture using fracturable 16-bit DSP blocks --- ...avel_io_skywater130nm_fdhd_cc_openfpga.xml | 295 ++++++ ...c_dsp16_nonLR_caravel_io_skywater130nm.xml | 962 ++++++++++++++++++ 2 files changed, 1257 insertions(+) create mode 100644 openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_frac_dsp16_caravel_io_skywater130nm_fdhd_cc_openfpga.xml create mode 100644 openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm.xml diff --git a/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_frac_dsp16_caravel_io_skywater130nm_fdhd_cc_openfpga.xml b/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_frac_dsp16_caravel_io_skywater130nm_fdhd_cc_openfpga.xml new file mode 100644 index 000000000..7ce8c5c28 --- /dev/null +++ b/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_frac_dsp16_caravel_io_skywater130nm_fdhd_cc_openfpga.xml @@ -0,0 +1,295 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + 10e-12 + + + 10e-12 + + + + + + + + + + + + 10e-12 5e-12 + + + 10e-12 5e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm.xml b/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm.xml new file mode 100644 index 000000000..98bae4fa2 --- /dev/null +++ b/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm.xml @@ -0,0 +1,962 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + io_top.outpad io_top.inpad + + + + + + + + + + + + io_right.outpad io_right.inpad + + + + + + + + + + + + io_bottom.outpad io_bottom.inpad + + + + + + + + + + + + io_left.outpad io_left.inpad + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + clb.clk clb.reset + clb.reg_in clb.sc_in clb.cin clb.O[7:0] clb.I0 clb.I0i clb.I1 clb.I1i clb.I2 clb.I2i clb.I3 clb.I3i + clb.O[15:8] clb.I4 clb.I4i clb.I5 clb.I5i clb.I6 clb.I6i clb.I7 clb.I7i + clb.reg_out clb.sc_out clb.cout + + + + + + + + + + + + + + mult_16.a[0:5] mult_16.b[0:5] mult_16.out[0:10] + mult_16.a[6:7] mult_16.b[6:7] mult_16.out[11:15] + mult_16.a[8:13] mult_16.b[8:13] mult_16.out[16:26] + mult_16.a[14:15] mult_16.b[14:15] mult_16.out[27:31] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 1 + 1 + + + + 1 1 1 + 1 1 + + + + 1 1 1 1 1 + 1 1 1 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 235e-12 + 235e-12 + 235e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 261e-12 + 261e-12 + 261e-12 + 261e-12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 148da80869b020aba0c73ccd6dbbc3ab982be15c Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 24 Apr 2021 14:53:29 -0600 Subject: [PATCH 11/17] [Tool] Add new syntax about physical_pb_port_rotate_offset to support fracturable heterogeneous block mapping between operating modes and physical modes --- .../src/pb_type_annotation.cpp | 40 +++++++++++--- .../libarchopenfpga/src/pb_type_annotation.h | 24 ++++++--- .../src/read_xml_pb_type_annotation.cpp | 25 +++++++++ .../src/write_xml_pb_type_annotation.cpp | 9 +++- openfpga/src/annotation/annotate_pb_graph.cpp | 26 +++++++++- openfpga/src/annotation/annotate_pb_types.cpp | 3 +- .../src/annotation/vpr_device_annotation.cpp | 52 +++++++++++++++++++ .../src/annotation/vpr_device_annotation.h | 15 +++++- openfpga/src/repack/repack.cpp | 6 +-- 9 files changed, 178 insertions(+), 22 deletions(-) diff --git a/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp b/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp index 9a369e742..1a1a7ea31 100644 --- a/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp +++ b/libopenfpga/libarchopenfpga/src/pb_type_annotation.cpp @@ -86,11 +86,11 @@ std::vector PbTypeAnnotation::port_names() const { return keys; } -std::map> PbTypeAnnotation::physical_pb_type_port(const std::string& port_name) const { - std::map>>::const_iterator it = operating_pb_type_ports_.find(port_name); +std::map> PbTypeAnnotation::physical_pb_type_port(const std::string& port_name) const { + std::map>>::const_iterator it = operating_pb_type_ports_.find(port_name); if (it == operating_pb_type_ports_.end()) { /* Return an empty port */ - return std::map>(); + return std::map>(); } return operating_pb_type_ports_.at(port_name); } @@ -169,25 +169,25 @@ void PbTypeAnnotation::set_physical_pb_type_index_offset(const int& value) { void PbTypeAnnotation::add_pb_type_port_pair(const std::string& operating_pb_port_name, const BasicPort& physical_pb_port) { /* Give a warning if the operating_pb_port_name already exist */ - std::map>>::const_iterator it = operating_pb_type_ports_.find(operating_pb_port_name); + std::map>>::const_iterator it = operating_pb_type_ports_.find(operating_pb_port_name); /* If not exist, initialize and set a default value */ if (it == operating_pb_type_ports_.end()) { - operating_pb_type_ports_[operating_pb_port_name][physical_pb_port] = {0, 0}; + operating_pb_type_ports_[operating_pb_port_name][physical_pb_port] = {0, 0, 0}; /* We can return early */ return; } /* If the physical port is not in the list, we create one and set a default value */ if (0 == operating_pb_type_ports_[operating_pb_port_name].count(physical_pb_port)) { - operating_pb_type_ports_[operating_pb_port_name][physical_pb_port] = {0, 0}; + operating_pb_type_ports_[operating_pb_port_name][physical_pb_port] = {0, 0, 0}; } } void PbTypeAnnotation::set_physical_pin_initial_offset(const std::string& operating_pb_port_name, const BasicPort& physical_pb_port, const int& physical_pin_initial_offset) { - std::map>>::const_iterator it = operating_pb_type_ports_.find(operating_pb_port_name); + std::map>>::const_iterator it = operating_pb_type_ports_.find(operating_pb_port_name); if (it == operating_pb_type_ports_.end()) { VTR_LOG_ERROR("The operating pb_type port '%s' is not valid!\n", @@ -210,7 +210,7 @@ void PbTypeAnnotation::set_physical_pin_initial_offset(const std::string& operat void PbTypeAnnotation::set_physical_pin_rotate_offset(const std::string& operating_pb_port_name, const BasicPort& physical_pb_port, const int& physical_pin_rotate_offset) { - std::map>>::const_iterator it = operating_pb_type_ports_.find(operating_pb_port_name); + std::map>>::const_iterator it = operating_pb_type_ports_.find(operating_pb_port_name); if (it == operating_pb_type_ports_.end()) { VTR_LOG_ERROR("The operating pb_type port '%s' is not valid!\n", @@ -230,6 +230,30 @@ void PbTypeAnnotation::set_physical_pin_rotate_offset(const std::string& operati operating_pb_type_ports_[operating_pb_port_name][physical_pb_port][1] = physical_pin_rotate_offset; } +void PbTypeAnnotation::set_physical_port_rotate_offset(const std::string& operating_pb_port_name, + const BasicPort& physical_pb_port, + const int& physical_port_rotate_offset) { + std::map>>::const_iterator it = operating_pb_type_ports_.find(operating_pb_port_name); + + if (it == operating_pb_type_ports_.end()) { + VTR_LOG_ERROR("The operating pb_type port '%s' is not valid!\n", + operating_pb_port_name.c_str()); + exit(1); + } + + if (operating_pb_type_ports_[operating_pb_port_name].end() == operating_pb_type_ports_[operating_pb_port_name].find(physical_pb_port)) { + VTR_LOG_ERROR("The physical pb_type port '%s[%lu:%lu]' definition for operating pb_type port '%s' is not valid!\n", + physical_pb_port.get_name().c_str(), + physical_pb_port.get_lsb(), + physical_pb_port.get_msb(), + operating_pb_port_name.c_str()); + exit(1); + } + + operating_pb_type_ports_[operating_pb_port_name][physical_pb_port][2] = physical_port_rotate_offset; +} + + void PbTypeAnnotation::add_interconnect_circuit_model_pair(const std::string& interc_name, const std::string& circuit_model_name) { std::map::const_iterator it = interconnect_circuit_model_names_.find(interc_name); diff --git a/libopenfpga/libarchopenfpga/src/pb_type_annotation.h b/libopenfpga/libarchopenfpga/src/pb_type_annotation.h index 96383679d..2a0b8804e 100644 --- a/libopenfpga/libarchopenfpga/src/pb_type_annotation.h +++ b/libopenfpga/libarchopenfpga/src/pb_type_annotation.h @@ -49,7 +49,7 @@ class PbTypeAnnotation { float physical_pb_type_index_factor() const; int physical_pb_type_index_offset() const; std::vector port_names() const; - std::map> physical_pb_type_port(const std::string& port_name) const; + std::map> physical_pb_type_port(const std::string& port_name) const; std::vector interconnect_names() const; std::string interconnect_circuit_model_name(const std::string& interc_name) const; public: /* Public mutators */ @@ -73,6 +73,9 @@ class PbTypeAnnotation { void set_physical_pin_rotate_offset(const std::string& operating_pb_port_name, const BasicPort& physical_pb_port, const int& physical_pin_rotate_offset); + void set_physical_port_rotate_offset(const std::string& operating_pb_port_name, + const BasicPort& physical_pb_port, + const int& physical_port_rotate_offset); void add_interconnect_circuit_model_pair(const std::string& interc_name, const std::string& circuit_model_name); private: /* Internal data */ @@ -138,10 +141,10 @@ class PbTypeAnnotation { int physical_pb_type_index_offset_; /* Link from the pins under an operating pb_type to pairs of - * its physical pb_type and its pin initial & rotating offset - * - * Note that initial offset is the first element of the std::array - * Note that rotating offset is the second element of the std::array + * its physical pb_type and + * - its pin initial offset: the first element of the std::array + * - pin-level rotating offset: the second element of the std::array + * - port-level rotating offset: the third element of the std::array * * The offsets aim to align the pin indices for port of pb_type * between operating and physical modes, especially when an operating @@ -158,14 +161,21 @@ class PbTypeAnnotation { * physical pb_type bram[0].dout_a[0] with a full path memory[physical].bram[0] * physical pb_type bram[0].dout_a[1] with a full path memory[physical].bram[0] * - * For example, a rotating offset of 9 is used to map + * For example, a pin-level rotating offset of 9 is used to map + * operating pb_type mult_9x9[0].a[0] with a full path mult[frac].mult_9x9[0] + * operating pb_type mult_9x9[0].a[1] with a full path mult[frac].mult_9x9[1] + * to + * physical pb_type mult_36x36.a[0] with a full path mult[physical].mult_36x36[0] + * physical pb_type mult_36x36.a[9] with a full path mult[physical].mult_36x36[0] + * + * For example, a port-level rotating offset of 9 is used to map * operating pb_type mult_9x9[0].a[0:8] with a full path mult[frac].mult_9x9[0] * operating pb_type mult_9x9[1].a[0:8] with a full path mult[frac].mult_9x9[1] * to * physical pb_type mult_36x36.a[0:8] with a full path mult[physical].mult_36x36[0] * physical pb_type mult_36x36.a[9:17] with a full path mult[physical].mult_36x36[0] */ - std::map>> operating_pb_type_ports_; + std::map>> operating_pb_type_ports_; /* Link between the interconnects under this pb_type and circuit model names */ std::map interconnect_circuit_model_names_; diff --git a/libopenfpga/libarchopenfpga/src/read_xml_pb_type_annotation.cpp b/libopenfpga/libarchopenfpga/src/read_xml_pb_type_annotation.cpp index 9831f6e23..f91dc99a8 100644 --- a/libopenfpga/libarchopenfpga/src/read_xml_pb_type_annotation.cpp +++ b/libopenfpga/libarchopenfpga/src/read_xml_pb_type_annotation.cpp @@ -114,6 +114,31 @@ void read_xml_pb_port_annotation(pugi::xml_node& xml_port, std::stoi(rotate_offsets[iport])); } } + + /* We have an optional attribute: physical_mode_port_rotate_offset + * Split based on the number of physical pb_type ports that have been defined + */ + const std::string& physical_port_rotate_offset_attr = get_attribute(xml_port, "physical_mode_port_rotate_offset", loc_data, pugiutil::ReqOpt::OPTIONAL).as_string(); + + if (false == physical_port_rotate_offset_attr.empty()) { + /* Split the physical mode port attributes with space */ + openfpga::StringToken offset_tokenizer(physical_port_rotate_offset_attr); + const std::vector rotate_offsets = offset_tokenizer.split(); + + /* Error out if the offset does not match the port definition */ + if (physical_mode_ports.size() != rotate_offsets.size()) { + archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_port), + "Defined %lu physical mode ports but only %lu physical port rotate offset are defined! Expect size matching.\n", + physical_mode_ports.size(), rotate_offsets.size()); + } + + for (size_t iport = 0; iport < physical_mode_ports.size(); ++iport) { + openfpga::PortParser port_parser(physical_mode_ports[iport]); + pb_type_annotation.set_physical_port_rotate_offset(name_attr, + port_parser.port(), + std::stoi(rotate_offsets[iport])); + } + } } /******************************************************************** diff --git a/libopenfpga/libarchopenfpga/src/write_xml_pb_type_annotation.cpp b/libopenfpga/libarchopenfpga/src/write_xml_pb_type_annotation.cpp index e9b36522c..b401f6ca8 100644 --- a/libopenfpga/libarchopenfpga/src/write_xml_pb_type_annotation.cpp +++ b/libopenfpga/libarchopenfpga/src/write_xml_pb_type_annotation.cpp @@ -144,7 +144,14 @@ void write_xml_pb_port_annotation(std::fstream& fp, physical_mode_pin_rotate_offset_attr += std::to_string(physical_pb_port_pair.second[1]); } write_xml_attribute(fp, "physical_mode_pin_rotate_offset", physical_mode_pin_rotate_offset_attr.c_str()); - + std::string physical_mode_port_rotate_offset_attr; + for (const auto& physical_pb_port_pair : pb_type_annotation.physical_pb_type_port(port_name)) { + if (false == physical_mode_port_rotate_offset_attr.empty()) { + physical_mode_port_rotate_offset_attr += " "; + } + physical_mode_port_rotate_offset_attr += std::to_string(physical_pb_port_pair.second[2]); + } + write_xml_attribute(fp, "physical_mode_port_rotate_offset", physical_mode_port_rotate_offset_attr.c_str()); fp << "/>" << "\n"; } diff --git a/openfpga/src/annotation/annotate_pb_graph.cpp b/openfpga/src/annotation/annotate_pb_graph.cpp index 67a1baba8..bed7997cc 100644 --- a/openfpga/src/annotation/annotate_pb_graph.cpp +++ b/openfpga/src/annotation/annotate_pb_graph.cpp @@ -333,7 +333,7 @@ bool try_match_pb_graph_pin(t_pb_graph_pin* operating_pb_graph_pin, * by the pin rotate offset value * The accumulated offset will be reset to 0 when it exceeds the msb() of the physical port */ - int acc_offset = vpr_device_annotation.physical_pb_pin_offset(operating_pb_graph_pin->port, candidate_port); + int acc_offset = vpr_device_annotation.physical_pb_pin_offset(operating_pb_graph_pin->port, candidate_port) + vpr_device_annotation.physical_pb_port_offset(operating_pb_graph_pin->port, candidate_port); int init_offset = vpr_device_annotation.physical_pb_pin_initial_offset(operating_pb_graph_pin->port, candidate_port); const BasicPort& physical_port_range = vpr_device_annotation.physical_pb_port_range(operating_pb_graph_pin->port, candidate_port); if (physical_pb_graph_pin->pin_number != operating_pb_graph_pin->pin_number @@ -463,6 +463,14 @@ void annotate_physical_pb_graph_node_pins(t_pb_graph_node* operating_pb_graph_no physical_pb_graph_node, vpr_device_annotation, verbose_output); } + /* Finish a port, accumulate the port-level offset affiliated to the port */ + if (0 == operating_pb_graph_node->num_input_pins[iport]) { + continue; + } + t_pb_graph_pin* operating_pb_graph_pin = &(operating_pb_graph_node->input_pins[iport][0]); + for (t_port* candidate_port : vpr_device_annotation.physical_pb_port(operating_pb_graph_pin->port)) { + vpr_device_annotation.accumulate_physical_pb_port_rotate_offset(operating_pb_graph_pin->port, candidate_port); + } } for (int iport = 0; iport < operating_pb_graph_node->num_output_ports; ++iport) { @@ -471,6 +479,14 @@ void annotate_physical_pb_graph_node_pins(t_pb_graph_node* operating_pb_graph_no physical_pb_graph_node, vpr_device_annotation, verbose_output); } + /* Finish a port, accumulate the port-level offset affiliated to the port */ + if (0 == operating_pb_graph_node->num_output_pins[iport]) { + continue; + } + t_pb_graph_pin* operating_pb_graph_pin = &(operating_pb_graph_node->output_pins[iport][0]); + for (t_port* candidate_port : vpr_device_annotation.physical_pb_port(operating_pb_graph_pin->port)) { + vpr_device_annotation.accumulate_physical_pb_port_rotate_offset(operating_pb_graph_pin->port, candidate_port); + } } for (int iport = 0; iport < operating_pb_graph_node->num_clock_ports; ++iport) { @@ -479,6 +495,14 @@ void annotate_physical_pb_graph_node_pins(t_pb_graph_node* operating_pb_graph_no physical_pb_graph_node, vpr_device_annotation, verbose_output); } + /* Finish a port, accumulate the port-level offset affiliated to the port */ + if (0 == operating_pb_graph_node->num_clock_pins[iport]) { + continue; + } + t_pb_graph_pin* operating_pb_graph_pin = &(operating_pb_graph_node->clock_pins[iport][0]); + for (t_port* candidate_port : vpr_device_annotation.physical_pb_port(operating_pb_graph_pin->port)) { + vpr_device_annotation.accumulate_physical_pb_port_rotate_offset(operating_pb_graph_pin->port, candidate_port); + } } } diff --git a/openfpga/src/annotation/annotate_pb_types.cpp b/openfpga/src/annotation/annotate_pb_types.cpp index 92a6f6560..e4b5f972c 100644 --- a/openfpga/src/annotation/annotate_pb_types.cpp +++ b/openfpga/src/annotation/annotate_pb_types.cpp @@ -211,7 +211,7 @@ bool pair_operating_and_physical_pb_types(t_pb_type* operating_pb_type, * if not found, we assume that the physical port is the same as the operating pb_port */ for (t_port* operating_pb_port : pb_type_ports(operating_pb_type)) { - std::map> expected_physical_pb_ports = pb_type_annotation.physical_pb_type_port(std::string(operating_pb_port->name)); + std::map> expected_physical_pb_ports = pb_type_annotation.physical_pb_type_port(std::string(operating_pb_port->name)); /* If not defined in the annotation, set the default pair: * rotate_offset is 0 by default! @@ -243,6 +243,7 @@ bool pair_operating_and_physical_pb_types(t_pb_type* operating_pb_type, vpr_device_annotation.add_physical_pb_port_range(operating_pb_port, physical_pb_port, expected_physical_pb_port.first); vpr_device_annotation.add_physical_pb_pin_initial_offset(operating_pb_port, physical_pb_port, expected_physical_pb_port.second[0]); vpr_device_annotation.add_physical_pb_pin_rotate_offset(operating_pb_port, physical_pb_port, expected_physical_pb_port.second[1]); + vpr_device_annotation.add_physical_pb_port_rotate_offset(operating_pb_port, physical_pb_port, expected_physical_pb_port.second[2]); } } diff --git a/openfpga/src/annotation/vpr_device_annotation.cpp b/openfpga/src/annotation/vpr_device_annotation.cpp index c2eed00ab..eef4fafbb 100644 --- a/openfpga/src/annotation/vpr_device_annotation.cpp +++ b/openfpga/src/annotation/vpr_device_annotation.cpp @@ -220,6 +220,21 @@ int VprDeviceAnnotation::physical_pb_pin_rotate_offset(t_port* operating_pb_port return physical_pb_pin_rotate_offsets_.at(operating_pb_port).at(physical_pb_port); } +int VprDeviceAnnotation::physical_pb_port_rotate_offset(t_port* operating_pb_port, + t_port* physical_pb_port) const { + /* Ensure that the pb_type is in the list */ + std::map>::const_iterator it = physical_pb_port_rotate_offsets_.find(operating_pb_port); + if (it == physical_pb_port_rotate_offsets_.end()) { + /* Default value is 0 */ + return 0; + } + if (0 == physical_pb_port_rotate_offsets_.at(operating_pb_port).count(physical_pb_port)) { + /* Default value is 0 */ + return 0; + } + return physical_pb_port_rotate_offsets_.at(operating_pb_port).at(physical_pb_port); +} + int VprDeviceAnnotation::physical_pb_pin_offset(t_port* operating_pb_port, t_port* physical_pb_port) const { /* Ensure that the pb_type is in the list */ @@ -235,6 +250,21 @@ int VprDeviceAnnotation::physical_pb_pin_offset(t_port* operating_pb_port, return physical_pb_pin_offsets_.at(operating_pb_port).at(physical_pb_port); } +int VprDeviceAnnotation::physical_pb_port_offset(t_port* operating_pb_port, + t_port* physical_pb_port) const { + /* Ensure that the pb_type is in the list */ + std::map>::const_iterator it = physical_pb_port_offsets_.find(operating_pb_port); + if (it == physical_pb_port_offsets_.end()) { + /* Default value is 0 */ + return 0; + } + if (0 == physical_pb_port_offsets_.at(operating_pb_port).count(physical_pb_port)) { + /* Default value is 0 */ + return 0; + } + return physical_pb_port_offsets_.at(operating_pb_port).at(physical_pb_port); +} + t_pb_graph_pin* VprDeviceAnnotation::physical_pb_graph_pin(const t_pb_graph_pin* pb_graph_pin) const { /* Ensure that the pb_type is in the list */ std::map::const_iterator it = physical_pb_graph_pins_.find(pb_graph_pin); @@ -478,6 +508,28 @@ void VprDeviceAnnotation::add_physical_pb_pin_initial_offset(t_port* operating_p physical_pb_pin_initial_offsets_[operating_pb_port][physical_pb_port] = offset; } +void VprDeviceAnnotation::add_physical_pb_port_rotate_offset(t_port* operating_pb_port, + t_port* physical_pb_port, + const int& offset) { + /* Warn any override attempt */ + std::map>::const_iterator it = physical_pb_port_rotate_offsets_.find(operating_pb_port); + if ( (it != physical_pb_port_rotate_offsets_.end()) + && (0 < physical_pb_port_rotate_offsets_[operating_pb_port].count(physical_pb_port)) ) { + VTR_LOG_WARN("Override the annotation between operating pb_port '%s' and it physical pb_port '%s' port rotate offset '%d'!\n", + operating_pb_port->name, offset); + } + + physical_pb_port_rotate_offsets_[operating_pb_port][physical_pb_port] = offset; + /* We initialize the accumulated offset to 0 */ + physical_pb_port_offsets_[operating_pb_port][physical_pb_port] = 0; +} + + +void VprDeviceAnnotation::accumulate_physical_pb_port_rotate_offset(t_port* operating_pb_port, + t_port* physical_pb_port) { + physical_pb_port_offsets_[operating_pb_port][physical_pb_port] += physical_pb_port_rotate_offsets_[operating_pb_port][physical_pb_port]; +} + void VprDeviceAnnotation::add_physical_pb_pin_rotate_offset(t_port* operating_pb_port, t_port* physical_pb_port, const int& offset) { diff --git a/openfpga/src/annotation/vpr_device_annotation.h b/openfpga/src/annotation/vpr_device_annotation.h index b5afbda00..d1a0f8e99 100644 --- a/openfpga/src/annotation/vpr_device_annotation.h +++ b/openfpga/src/annotation/vpr_device_annotation.h @@ -67,6 +67,9 @@ class VprDeviceAnnotation { int physical_pb_pin_rotate_offset(t_port* operating_pb_port, t_port* physical_pb_port) const; + int physical_pb_port_rotate_offset(t_port* operating_pb_port, + t_port* physical_pb_port) const; + /**This function returns an accumulated offset. Note that the * accumulated offset is NOT the pin rotate offset specified by users * It is an aggregation of the offset during pin pairing @@ -76,6 +79,8 @@ class VprDeviceAnnotation { */ int physical_pb_pin_offset(t_port* operating_pb_port, t_port* physical_pb_port) const; + int physical_pb_port_offset(t_port* operating_pb_port, + t_port* physical_pb_port) const; t_pb_graph_pin* physical_pb_graph_pin(const t_pb_graph_pin* pb_graph_pin) const; CircuitModelId rr_switch_circuit_model(const RRSwitchId& rr_switch) const; CircuitModelId rr_segment_circuit_model(const RRSegmentId& rr_segment) const; @@ -106,6 +111,11 @@ class VprDeviceAnnotation { void add_physical_pb_pin_initial_offset(t_port* operating_pb_port, t_port* physical_pb_port, const int& offset); + void add_physical_pb_port_rotate_offset(t_port* operating_pb_port, + t_port* physical_pb_port, + const int& offset); + void accumulate_physical_pb_port_rotate_offset(t_port* operating_pb_port, + t_port* physical_pb_port); void add_physical_pb_pin_rotate_offset(t_port* operating_pb_port, t_port* physical_pb_port, const int& offset); @@ -166,8 +176,11 @@ class VprDeviceAnnotation { std::map> physical_pb_ports_; std::map> physical_pb_pin_initial_offsets_; std::map> physical_pb_pin_rotate_offsets_; + std::map> physical_pb_port_rotate_offsets_; - /* Accumulated offsets for a physical pb_type port, just for internal usage */ + /* Accumulated offsets for a physical pb port, just for internal usage */ + std::map> physical_pb_port_offsets_; + /* Accumulated offsets for a physical pb_graph_pin, just for internal usage */ std::map> physical_pb_pin_offsets_; /* Pair a pb_port to its LSB and MSB of a physical pb_port diff --git a/openfpga/src/repack/repack.cpp b/openfpga/src/repack/repack.cpp index d6cb669bc..7538c675a 100644 --- a/openfpga/src/repack/repack.cpp +++ b/openfpga/src/repack/repack.cpp @@ -61,9 +61,9 @@ bool rec_direct_search_sink_pb_graph_pins(const t_pb_graph_pin* source_pb_pin, std::vector sink_pb_pins_to_search; /* Only support single-mode pb_type!!! */ - if (1 != source_pb_pin->parent_node->pb_type->num_modes) { - return false; - } + //if (1 != source_pb_pin->parent_node->pb_type->num_modes) { + // return false; + //} for (int iedge = 0; iedge < source_pb_pin->num_output_edges; ++iedge) { if (DIRECT_INTERC != source_pb_pin->output_edges[iedge]->interconnect->type) { From a3a98fa21d6365a67f57db0c1ef2ae11a9237df8 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 24 Apr 2021 14:56:10 -0600 Subject: [PATCH 12/17] [Arch] Bug fix for port name mismatching between openfpga cell library and architecture definition --- ...frac_dsp16_caravel_io_skywater130nm_fdhd_cc_openfpga.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_frac_dsp16_caravel_io_skywater130nm_fdhd_cc_openfpga.xml b/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_frac_dsp16_caravel_io_skywater130nm_fdhd_cc_openfpga.xml index 7ce8c5c28..78978c2c7 100644 --- a/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_frac_dsp16_caravel_io_skywater130nm_fdhd_cc_openfpga.xml +++ b/openfpga_flow/openfpga_arch/k4_frac_N8_reset_softadder_register_scan_chain_frac_dsp16_caravel_io_skywater130nm_fdhd_cc_openfpga.xml @@ -210,9 +210,9 @@ - - - + + + From 8b8096f3a860e655ebebd644f8673a3b5c2e11cc Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 24 Apr 2021 14:57:09 -0600 Subject: [PATCH 13/17] [HDL] Bug fix in HDL modeling of multi-mode 16-bit DSP block --- openfpga_flow/openfpga_cell_library/verilog/frac_mult_16x16.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfpga_flow/openfpga_cell_library/verilog/frac_mult_16x16.v b/openfpga_flow/openfpga_cell_library/verilog/frac_mult_16x16.v index 7fedc711c..d73a1c7e1 100644 --- a/openfpga_flow/openfpga_cell_library/verilog/frac_mult_16x16.v +++ b/openfpga_flow/openfpga_cell_library/verilog/frac_mult_16x16.v @@ -13,7 +13,7 @@ module frac_mult_16x16 ( output [0:31] out, input [0:0] mode); - reg [0:63] out_reg; + reg [0:31] out_reg; always @(mode, a, b) begin if (1'b1 == mode) begin From 80f98328df34411a6baaaf6b4ac57ee59a79c762 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 24 Apr 2021 15:16:50 -0600 Subject: [PATCH 14/17] [Test] Update test settings for architecture with fracturable DSP blocks --- .../dsp/multi_mode_mult_16x16/config/task.conf | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/openfpga_flow/tasks/fpga_verilog/dsp/multi_mode_mult_16x16/config/task.conf b/openfpga_flow/tasks/fpga_verilog/dsp/multi_mode_mult_16x16/config/task.conf index 0db63ef8b..b9e2c957b 100644 --- a/openfpga_flow/tasks/fpga_verilog/dsp/multi_mode_mult_16x16/config/task.conf +++ b/openfpga_flow/tasks/fpga_verilog/dsp/multi_mode_mult_16x16/config/task.conf @@ -24,7 +24,7 @@ yosys_cell_sim_verilog=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techli yosys_dsp_map_verilog=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm_dsp_map.v yosys_dsp_map_parameters=-D DSP_A_MAXWIDTH=8 -D DSP_B_MAXWIDTH=8 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=mult_8x8 # VPR parameter -openfpga_vpr_device_layout=3x2 +openfpga_vpr_device_layout=3x4 [ARCHITECTURES] arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm.xml @@ -32,7 +32,8 @@ arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_sof [BENCHMARKS] bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_4/mac_4.v bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_8/mac_8.v -bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_16/mac_16.v +bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_12/mac_12.v +bench3=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/mac/mac_16/mac_16.v [SYNTHESIS_PARAM] bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_dsp_flow.ys @@ -40,7 +41,8 @@ bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosy bench0_top = mac_4 bench1_top = mac_8 -bench2_top = mac_16 +bench2_top = mac_12 +bench3_top = mac_16 [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] end_flow_with_test= From 5adffad6023b8dad5bbbc75a9ab2de21b794e836 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 24 Apr 2021 15:49:53 -0600 Subject: [PATCH 15/17] [Arch] Changes to the arch to avoid a bug where the rr_nodes at top side of a heterogenenous block have no fan-in!!! --- ...ac_dsp16_nonLR_caravel_io_skywater130nm.xml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm.xml b/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm.xml index 98bae4fa2..2d817e7cd 100644 --- a/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm.xml +++ b/openfpga_flow/vpr_arch/k4_frac_N8_tileable_reset_softadder_register_scan_chain_frac_dsp16_nonLR_caravel_io_skywater130nm.xml @@ -111,7 +111,7 @@ These clocks can be handled in back-end --> - + @@ -123,7 +123,7 @@ - + @@ -147,7 +147,7 @@ - + @@ -217,10 +217,12 @@ - mult_16.a[0:5] mult_16.b[0:5] mult_16.out[0:10] - mult_16.a[6:7] mult_16.b[6:7] mult_16.out[11:15] - mult_16.a[8:13] mult_16.b[8:13] mult_16.out[16:26] - mult_16.a[14:15] mult_16.b[14:15] mult_16.out[27:31] + mult_16.a[0:2] mult_16.b[0:2] mult_16.out[0:5] + mult_16.a[3:5] mult_16.b[3:5] mult_16.out[6:10] + + mult_16.a[8:10] mult_16.b[8:10] mult_16.out[16:21] + mult_16.a[11:13] mult_16.b[11:13] mult_16.out[22:26] + mult_16.a[6:7] mult_16.b[6:7] mult_16.out[11:15] mult_16.a[14:15] mult_16.b[14:15] mult_16.out[27:31] @@ -239,7 +241,7 @@ - + From b7da22501c4ff35e56b6af623aceadaad967331f Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 24 Apr 2021 15:55:05 -0600 Subject: [PATCH 16/17] [Test] Deply new test to regression test --- openfpga_flow/regression_test_scripts/fpga_verilog_reg_test.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openfpga_flow/regression_test_scripts/fpga_verilog_reg_test.sh b/openfpga_flow/regression_test_scripts/fpga_verilog_reg_test.sh index 0033ad8ac..9168cbd1e 100755 --- a/openfpga_flow/regression_test_scripts/fpga_verilog_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/fpga_verilog_reg_test.sh @@ -47,6 +47,9 @@ run-task fpga_verilog/bram/wide_dpram16k --debug --show_thread_logs echo -e "Testing Verilog generation with heterogeneous fabric using 8-bit single-mode multipliers "; run-task fpga_verilog/dsp/single_mode_mult_8x8 --debug --show_thread_logs +echo -e "Testing Verilog generation with heterogeneous fabric using 16-bit multi-mode multipliers "; +run-task fpga_verilog/dsp/multi_mode_mult_16x16 --debug --show_thread_logs + echo -e "Testing Verilog generation with different I/O capacities on each side of an FPGA "; run-task fpga_verilog/io/multi_io_capacity --debug --show_thread_logs From 62dc5a3856035a009363f3862a0053b66908b72d Mon Sep 17 00:00:00 2001 From: tangxifan Date: Sat, 24 Apr 2021 16:02:24 -0600 Subject: [PATCH 17/17] [Doc] Update documentation about the new syntax introduced for pin binding between operating modes and physical modes --- .../manual/arch_lang/annotate_vpr_arch.rst | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/docs/source/manual/arch_lang/annotate_vpr_arch.rst b/docs/source/manual/arch_lang/annotate_vpr_arch.rst index 239d10dfb..f4767c938 100644 --- a/docs/source/manual/arch_lang/annotate_vpr_arch.rst +++ b/docs/source/manual/arch_lang/annotate_vpr_arch.rst @@ -223,7 +223,9 @@ The ``circuit_model_name`` should match the given name of a ``circuit_model`` de .. note:: A ```` parent XML node is required for the interconnect-to-circuit bindings whose interconnects are defined under the ``pb_type`` in VPR architecture description. .. option:: + physical_mode_pin_initial_offset="" + physical_mode_pin_rotate_offset=""/> + physical_mode_port_rotate_offset=""/> Link a port of an operating ``pb_type`` to a port of a physical ``pb_type`` @@ -233,7 +235,6 @@ The ``circuit_model_name`` should match the given name of a ``circuit_model`` de .. note:: Users can define multiple ports. For example: ``physical_mode_pin="a[0:1] b[2:2]"``. When multiple ports are used, the ``physical_mode_pin_initial_offset`` and ``physical_mode_pin_rotate_offset`` should also be adapt. For example: ``physical_mode_pin_rotate_offset="1 0"``) - - ``physical_mode_pin_initial_offset=""`` aims to align the pin indices for ``port`` of ``pb_type`` between operating and physical modes, especially when part of port of operating mode is mapped to a port in physical ``pb_type``. When ``physical_mode_pin_initial_offset`` is larger than zero, the pin index of ``pb_type`` (whose index is large than 1) will be shifted by the given offset. .. note:: A quick example to understand the initial offset @@ -249,7 +250,24 @@ The ``circuit_model_name`` should match the given name of a ``circuit_model`` de .. note:: If not defined, the default value of ``physical_mode_pin_initial_offset`` is set to ``0``. - - ``physical_mode_pin_rotate_offset=""`` aims to align the pin indices for ``port`` of ``pb_type`` between operating and physical modes, especially when an operating mode contains multiple ``pb_type`` (``num_pb``>1) that are linked to the same physical ``pb_type``. When ``physical_mode_pin_rotate_offset`` is larger than zero, the pin index of ``pb_type`` (whose index is large than 1) will be shifted by the given offset. + - ``physical_mode_pin_rotate_offset=""`` aims to align the pin indices for ``port`` of ``pb_type`` between operating and physical modes, especially when an operating mode contains multiple ``pb_type`` (``num_pb``>1) that are linked to the same physical ``pb_type``. When ``physical_mode_pin_rotate_offset`` is larger than zero, the pin index of ``pb_type`` (whose index is large than 1) will be shifted by the given offset, **each time a pin in the operating mode is binded to a pin in the physical mode**. + + .. note:: A quick example to understand the rotate offset + For example, a rotating offset of 9 is used to map + + - operating pb_type ``mult_9x9[0].a[0]`` with a full path ``mult[frac].mult_9x9[0]`` + - operating pb_type ``mult_9x9[1].a[1]`` with a full path ``mult[frac].mult_9x9[1]`` + + to + + - physical pb_type ``mult_36x36.a[0]`` with a full path ``mult[physical].mult_36x36[0]`` + - physical pb_type ``mult_36x36.a[9]`` with a full path ``mult[physical].mult_36x36[0]`` + + .. note:: If not defined, the default value of ``physical_mode_pin_rotate_offset`` is set to ``0``. + + .. warning:: The result of using ``physical_mode_pin_rotate_offset`` is fundementally different than ``physical_mode_port_rotate_offset``!!! Please read the examples carefully and pick the one fitting your needs. + + - ``physical_mode_port_rotate_offset=""`` aims to align the port indices for ``port`` of ``pb_type`` between operating and physical modes, especially when an operating mode contains multiple ``pb_type`` (``num_pb``>1) that are linked to the same physical ``pb_type``. When ``physical_mode_port_rotate_offset`` is larger than zero, the pin index of ``pb_type`` (whose index is large than 1) will be shifted by the given offset, **only when all the pins of a port in the operating mode is binded to all the pins of a port in the physical mode**. .. note:: A quick example to understand the rotate offset For example, a rotating offset of 9 is used to map @@ -262,7 +280,8 @@ The ``circuit_model_name`` should match the given name of a ``circuit_model`` de - physical pb_type ``mult_36x36.a[0:8]`` with a full path ``mult[physical].mult_36x36[0]`` - physical pb_type ``mult_36x36.a[9:17]`` with a full path ``mult[physical].mult_36x36[0]`` - .. note:: If not defined, the default value of ``physical_mode_pin_rotate_offset`` is set to ``0``. + .. note:: If not defined, the default value of ``physical_mode_port_rotate_offset`` is set to ``0``. + .. note:: It is highly recommended that only one physical mode is defined for a multi-mode configurable block. Try not to use nested physical mode definition. This will ease the debugging and lead to clean XML description.