diff --git a/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst b/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst index 9bc9c6334..2722dc46d 100644 --- a/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst +++ b/docs/source/manual/openfpga_shell/openfpga_commands/setup_commands.rst @@ -111,6 +111,10 @@ write_gsb_to_xml Specify the output directory of the XML files. Each GSB will be written to an indepedent XML file For example, ``--file /temp/gsb_output`` + .. option:: --unique + + Only output unique GSBs to XML files + .. option:: --verbose Show verbose log diff --git a/openfpga/src/annotation/device_rr_gsb.cpp b/openfpga/src/annotation/device_rr_gsb.cpp index c10a9df9c..9abbea351 100644 --- a/openfpga/src/annotation/device_rr_gsb.cpp +++ b/openfpga/src/annotation/device_rr_gsb.cpp @@ -86,6 +86,13 @@ size_t DeviceRRGSB::get_num_gsb_unique_module() const { return gsb_unique_module_.size(); } +/* Get a rr switch block which a unique mirror */ +const RRGSB& DeviceRRGSB::get_gsb_unique_module(const size_t& index) const { + VTR_ASSERT (validate_gsb_unique_module_index(index)); + + return rr_gsb_[gsb_unique_module_[index].x()][gsb_unique_module_[index].y()]; +} + /* Get a rr switch block which a unique mirror */ const RRGSB& DeviceRRGSB::get_sb_unique_module(const size_t& index) const { VTR_ASSERT (validate_sb_unique_module_index(index)); @@ -461,6 +468,11 @@ bool DeviceRRGSB::validate_coordinate(const vtr::Point& coordinate) cons return (coordinate.y() < rr_gsb_[coordinate.x()].capacity()); } +/* Validate if the index in the range of unique_mirror vector*/ +bool DeviceRRGSB::validate_gsb_unique_module_index(const size_t& index) const { + return (index < gsb_unique_module_.size()); +} + /* Validate if the index in the range of unique_mirror vector*/ bool DeviceRRGSB::validate_sb_unique_module_index(const size_t& index) const { return (index < sb_unique_module_.size()); diff --git a/openfpga/src/annotation/device_rr_gsb.h b/openfpga/src/annotation/device_rr_gsb.h index 4d8aad401..290322079 100644 --- a/openfpga/src/annotation/device_rr_gsb.h +++ b/openfpga/src/annotation/device_rr_gsb.h @@ -32,6 +32,7 @@ class DeviceRRGSB { const RRGSB& get_gsb(const size_t& x, const size_t& y) const; /* Get a rr switch block in the array with a coordinate */ size_t get_num_gsb_unique_module() const; /* get the number of unique mirrors of GSB */ size_t get_num_sb_unique_module() const; /* get the number of unique mirrors of switch blocks */ + const RRGSB& get_gsb_unique_module(const size_t& index) const; /* Get a rr-gsb which is a unique mirror */ const RRGSB& get_sb_unique_module(const size_t& index) const; /* Get a rr switch block which a unique mirror */ const RRGSB& get_sb_unique_module(const vtr::Point& coordinate) const; /* Get a rr switch block which a unique mirror */ const RRGSB& get_cb_unique_module(const t_rr_type& cb_type, const size_t& index) const; /* Get a rr switch block which a unique mirror */ @@ -58,6 +59,7 @@ class DeviceRRGSB { private: /* Validators */ bool validate_coordinate(const vtr::Point& coordinate) const; /* Validate if the (x,y) is the range of this device */ bool validate_side(const e_side& side) const; /* validate if side is in the range of unique_side_module_ */ + bool validate_gsb_unique_module_index(const size_t& index) const; /* Validate if the index in the range of unique_mirror vector*/ bool validate_sb_unique_module_index(const size_t& index) const; /* Validate if the index in the range of unique_mirror vector*/ bool validate_cb_unique_module_index(const t_rr_type& cb_type, const size_t& index) const; /* Validate if the index in the range of unique_mirror vector*/ bool validate_cb_type(const t_rr_type& cb_type) const; diff --git a/openfpga/src/annotation/write_xml_device_rr_gsb.cpp b/openfpga/src/annotation/write_xml_device_rr_gsb.cpp index 8aa8fb3b6..566d706a8 100644 --- a/openfpga/src/annotation/write_xml_device_rr_gsb.cpp +++ b/openfpga/src/annotation/write_xml_device_rr_gsb.cpp @@ -184,6 +184,7 @@ void write_rr_switch_block_to_xml(const std::string fname_prefix, void write_device_rr_gsb_to_xml(const char* sb_xml_dir, const RRGraph& rr_graph, const DeviceRRGSB& device_rr_gsb, + const bool& unique, const bool& verbose) { std::string xml_dir_name = format_dir_path(std::string(sb_xml_dir)); @@ -195,11 +196,22 @@ void write_device_rr_gsb_to_xml(const char* sb_xml_dir, size_t gsb_counter = 0; /* For each switch block, an XML file will be outputted */ - for (size_t ix = 0; ix < sb_range.x(); ++ix) { - for (size_t iy = 0; iy < sb_range.y(); ++iy) { - const RRGSB& rr_gsb = device_rr_gsb.get_gsb(ix, iy); + if (unique) { + /* Only output unique GSB modules */ + VTR_LOG("Only output unique GSB modules to XML\n"); + for (size_t igsb = 0; igsb < device_rr_gsb.get_num_gsb_unique_module(); ++igsb) { + const RRGSB& rr_gsb = device_rr_gsb.get_gsb_unique_module(igsb); write_rr_switch_block_to_xml(xml_dir_name, rr_graph, rr_gsb, verbose); gsb_counter++; + } + } else { + /* Output all GSB instances in the fabric (some instances may share the same module) */ + for (size_t ix = 0; ix < sb_range.x(); ++ix) { + for (size_t iy = 0; iy < sb_range.y(); ++iy) { + const RRGSB& rr_gsb = device_rr_gsb.get_gsb(ix, iy); + write_rr_switch_block_to_xml(xml_dir_name, rr_graph, rr_gsb, verbose); + gsb_counter++; + } } } diff --git a/openfpga/src/annotation/write_xml_device_rr_gsb.h b/openfpga/src/annotation/write_xml_device_rr_gsb.h index a6655ab22..9d558d1f1 100644 --- a/openfpga/src/annotation/write_xml_device_rr_gsb.h +++ b/openfpga/src/annotation/write_xml_device_rr_gsb.h @@ -18,6 +18,7 @@ namespace openfpga { void write_device_rr_gsb_to_xml(const char* sb_xml_dir, const RRGraph& rr_graph, const DeviceRRGSB& device_rr_gsb, + const bool& unique, const bool& verbose); } /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_setup_command.cpp b/openfpga/src/base/openfpga_setup_command.cpp index 517ed364a..7293c82e7 100644 --- a/openfpga/src/base/openfpga_setup_command.cpp +++ b/openfpga/src/base/openfpga_setup_command.cpp @@ -209,6 +209,9 @@ ShellCommandId add_openfpga_write_gsb_command(openfpga::Shell& shell_cmd.set_option_short_name(opt_file, "f"); shell_cmd.set_option_require_value(opt_file, openfpga::OPT_STRING); + /* Add an option '--unique' */ + shell_cmd.add_option("unique", false, "Only output unique GSB blocks"); + /* Add an option '--verbose' */ shell_cmd.add_option("verbose", false, "Show verbose outputs"); diff --git a/openfpga/src/base/openfpga_write_gsb.cpp b/openfpga/src/base/openfpga_write_gsb.cpp index cdb833c75..0a783cc01 100644 --- a/openfpga/src/base/openfpga_write_gsb.cpp +++ b/openfpga/src/base/openfpga_write_gsb.cpp @@ -33,6 +33,7 @@ int write_gsb(const OpenfpgaContext& openfpga_ctx, VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_file)); VTR_ASSERT(false == cmd_context.option_value(cmd, opt_file).empty()); + CommandOptionId opt_unique = cmd.option("unique"); CommandOptionId opt_verbose = cmd.option("verbose"); std::string sb_file_name = cmd_context.option_value(cmd, opt_file); @@ -40,6 +41,7 @@ int write_gsb(const OpenfpgaContext& openfpga_ctx, write_device_rr_gsb_to_xml(sb_file_name.c_str(), g_vpr_ctx.device().rr_graph, openfpga_ctx.device_rr_gsb(), + cmd_context.option_enable(cmd, opt_unique), cmd_context.option_enable(cmd, opt_verbose)); /* TODO: should identify the error code from internal function execution */ diff --git a/openfpga_flow/openfpga_shell_scripts/write_gsb_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/write_gsb_example_script.openfpga new file mode 100644 index 000000000..8a3ef21ad --- /dev/null +++ b/openfpga_flow/openfpga_shell_scripts/write_gsb_example_script.openfpga @@ -0,0 +1,36 @@ +# Run VPR for the 'and' design +#--write_rr_graph example_rr_graph.xml +vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling ideal --device ${OPENFPGA_VPR_DEVICE_LAYOUT} + +# Read OpenFPGA architecture definition +read_openfpga_arch -f ${OPENFPGA_ARCH_FILE} + +# Read OpenFPGA simulation settings +read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE} + +# Annotate the OpenFPGA architecture to VPR data base +# to debug use --verbose options +link_openfpga_arch --activity_file ${ACTIVITY_FILE} --sort_gsb_chan_node_in_edges + +# Check and correct any naming conflicts in the BLIF netlist +check_netlist_naming_conflict --fix --report ./netlist_renaming.xml + +# Apply fix-up to clustering nets based on routing results +pb_pin_fixup --verbose + +# Apply fix-up to Look-Up Table truth tables based on packing results +lut_truth_table_fixup + +# Build the module graph +# - Enabled compression on routing architecture modules +# - Enable pin duplication on grid modules +build_fabric ${OPENFPGA_BUILD_FABRIC_OPTION} #--verbose + +# Write gsb to XML +write_gsb_to_xml --file gsb_xml --verbose ${OPENFPGA_WRITE_GSB_OPTION} + +# Finish and exit OpenFPGA +exit + +# Note : +# To run verification at the end of the flow maintain source in ./SRC directory diff --git a/openfpga_flow/regression_test_scripts/basic_reg_test.sh b/openfpga_flow/regression_test_scripts/basic_reg_test.sh index 9708fdaba..b8261b501 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -160,3 +160,9 @@ run-task basic_tests/explicit_multi_verilog_files --debug --show_thread_logs --r # Repgression test to test multi-user enviroment cp -r */*/basic_tests/full_testbench/configuration_chain /tmp/ cd /tmp/ && run-task configuration_chain --debug --show_thread_logs + +echo -e "Testing write GSB to files"; +run-task basic_tests/write_gsb/write_gsb_to_xml --debug --show_thread_logs +run-task basic_tests/write_gsb/write_gsb_to_xml_compress_routing --debug --show_thread_logs +run-task basic_tests/write_gsb/write_unique_gsb_to_xml --debug --show_thread_logs +run-task basic_tests/write_gsb/write_unique_gsb_to_xml_compress_routing --debug --show_thread_logs diff --git a/openfpga_flow/tasks/basic_tests/write_gsb/write_gsb_to_xml/config/task.conf b/openfpga_flow/tasks/basic_tests/write_gsb/write_gsb_to_xml/config/task.conf new file mode 100644 index 000000000..a8e41330d --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/write_gsb/write_gsb_to_xml/config/task.conf @@ -0,0 +1,36 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = true +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/write_gsb_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml +openfpga_vpr_device_layout=4x4 +openfpga_build_fabric_option= +openfpga_write_gsb_option= + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v + +[SYNTHESIS_PARAM] +bench_read_verilog_options_common = -nolatches +bench0_top = and2 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] diff --git a/openfpga_flow/tasks/basic_tests/write_gsb/write_gsb_to_xml_compress_routing/config/task.conf b/openfpga_flow/tasks/basic_tests/write_gsb/write_gsb_to_xml_compress_routing/config/task.conf new file mode 100644 index 000000000..05c3cfca0 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/write_gsb/write_gsb_to_xml_compress_routing/config/task.conf @@ -0,0 +1,36 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = true +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/write_gsb_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml +openfpga_vpr_device_layout=4x4 +openfpga_build_fabric_option=--compress_routing +openfpga_write_gsb_option= + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v + +[SYNTHESIS_PARAM] +bench_read_verilog_options_common = -nolatches +bench0_top = and2 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] diff --git a/openfpga_flow/tasks/basic_tests/write_gsb/write_unique_gsb_to_xml/config/task.conf b/openfpga_flow/tasks/basic_tests/write_gsb/write_unique_gsb_to_xml/config/task.conf new file mode 100644 index 000000000..96b57eb0c --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/write_gsb/write_unique_gsb_to_xml/config/task.conf @@ -0,0 +1,36 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = true +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/write_gsb_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml +openfpga_vpr_device_layout=4x4 +openfpga_build_fabric_option= +openfpga_write_gsb_option=--unique + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v + +[SYNTHESIS_PARAM] +bench_read_verilog_options_common = -nolatches +bench0_top = and2 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] diff --git a/openfpga_flow/tasks/basic_tests/write_gsb/write_unique_gsb_to_xml_compress_routing/config/task.conf b/openfpga_flow/tasks/basic_tests/write_gsb/write_unique_gsb_to_xml_compress_routing/config/task.conf new file mode 100644 index 000000000..3f9fed5e9 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/write_gsb/write_unique_gsb_to_xml_compress_routing/config/task.conf @@ -0,0 +1,36 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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 = true +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/write_gsb_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml +openfpga_vpr_device_layout=4x4 +openfpga_build_fabric_option=--compress_routing +openfpga_write_gsb_option=--unique + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v + +[SYNTHESIS_PARAM] +bench_read_verilog_options_common = -nolatches +bench0_top = and2 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] diff --git a/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml b/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml index 214e81e9a..2caa8b1ba 100644 --- a/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml +++ b/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml @@ -77,6 +77,13 @@ + + + + + + +