From 7688c0570f47adeb7d215cbb716d38b0fca9df83 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 21 Sep 2021 15:08:08 -0700 Subject: [PATCH 01/11] [Engine] Support coordinate definition in fabric key file format; Now QL memory bank can accept fabric key --- libopenfpga/libfabrickey/src/fabric_key.cpp | 20 +++++++++++++++++++ libopenfpga/libfabrickey/src/fabric_key.h | 12 +++++++++++ .../libfabrickey/src/read_xml_fabric_key.cpp | 13 ++++++++++++ .../libfabrickey/src/write_xml_fabric_key.cpp | 6 ++++++ .../src/fabric/build_top_module_memory.cpp | 3 ++- 5 files changed, 53 insertions(+), 1 deletion(-) diff --git a/libopenfpga/libfabrickey/src/fabric_key.cpp b/libopenfpga/libfabrickey/src/fabric_key.cpp index dfe445c75..d15c86e56 100644 --- a/libopenfpga/libfabrickey/src/fabric_key.cpp +++ b/libopenfpga/libfabrickey/src/fabric_key.cpp @@ -54,6 +54,12 @@ std::string FabricKey::key_alias(const FabricKeyId& key_id) const { return key_alias_[key_id]; } +vtr::Point FabricKey::key_coordinate(const FabricKeyId& key_id) const { + /* validate the key_id */ + VTR_ASSERT(valid_key_id(key_id)); + return key_coordinates_[key_id]; +} + bool FabricKey::empty() const { return 0 == key_ids_.size(); } @@ -124,6 +130,7 @@ void FabricKey::reserve_keys(const size_t& num_keys) { key_values_.reserve(num_keys); key_regions_.reserve(num_keys); key_alias_.reserve(num_keys); + key_coordinates_.reserve(num_keys); } FabricKeyId FabricKey::create_key() { @@ -134,6 +141,7 @@ FabricKeyId FabricKey::create_key() { key_values_.emplace_back(); key_regions_.emplace_back(FabricRegionId::INVALID()); key_alias_.emplace_back(); + key_coordinates_.emplace_back(vtr::Point(-1, -1)); return key; } @@ -162,6 +170,14 @@ void FabricKey::set_key_alias(const FabricKeyId& key_id, key_alias_[key_id] = alias; } +void FabricKey::set_key_coordinate(const FabricKeyId& key_id, + const vtr::Point& coord) { + /* validate the key_id */ + VTR_ASSERT(valid_key_id(key_id)); + + key_coordinates_[key_id] = coord; +} + /************************************************************************ * Internal invalidators/validators ***********************************************************************/ @@ -173,3 +189,7 @@ bool FabricKey::valid_region_id(const FabricRegionId& region_id) const { bool FabricKey::valid_key_id(const FabricKeyId& key_id) const { return ( size_t(key_id) < key_ids_.size() ) && ( key_id == key_ids_[key_id] ); } + +bool FabricKey::valid_key_coordinate(const vtr::Point& coord) const { + return coord.x() > -1 && coord.y() > -1; +} diff --git a/libopenfpga/libfabrickey/src/fabric_key.h b/libopenfpga/libfabrickey/src/fabric_key.h index 0ca1d252d..6e9025f9e 100644 --- a/libopenfpga/libfabrickey/src/fabric_key.h +++ b/libopenfpga/libfabrickey/src/fabric_key.h @@ -10,6 +10,7 @@ /* Headers from vtrutil library */ #include "vtr_vector.h" +#include "vtr_geometry.h" #include "fabric_key_fwd.h" @@ -58,6 +59,9 @@ class FabricKey { /* Access the alias of a key */ std::string key_alias(const FabricKeyId& key_id) const; + /* Access the coordinate of a key */ + vtr::Point key_coordinate(const FabricKeyId& key_id) const; + /* Check if there are any keys */ bool empty() const; @@ -93,9 +97,14 @@ class FabricKey { void set_key_alias(const FabricKeyId& key_id, const std::string& alias); + void set_key_coordinate(const FabricKeyId& key_id, + const vtr::Point& coord); + public: /* Public invalidators/validators */ bool valid_region_id(const FabricRegionId& region_id) const; bool valid_key_id(const FabricKeyId& key_id) const; + /* Identify if key coordinate is acceptable to fabric key convention */ + bool valid_key_coordinate(const vtr::Point& coord) const; private: /* Internal data */ /* Unique ids for each region */ vtr::vector region_ids_; @@ -112,6 +121,9 @@ class FabricKey { /* Values for each key */ vtr::vector key_values_; + /* Values for each key */ + vtr::vector> key_coordinates_; + /* Region for each key */ vtr::vector key_regions_; diff --git a/libopenfpga/libfabrickey/src/read_xml_fabric_key.cpp b/libopenfpga/libfabrickey/src/read_xml_fabric_key.cpp index 24e0d8255..b9e83787f 100644 --- a/libopenfpga/libfabrickey/src/read_xml_fabric_key.cpp +++ b/libopenfpga/libfabrickey/src/read_xml_fabric_key.cpp @@ -60,6 +60,19 @@ void read_xml_region_key(pugi::xml_node& xml_component_key, fabric_key.set_key_name(FabricKeyId(id), name); fabric_key.set_key_value(FabricKeyId(id), value); fabric_key.add_key_to_region(fabric_region, FabricKeyId(id)); + + /* Parse coordinates */ + vtr::Point coord; + coord.set_x(get_attribute(xml_component_key, "column", loc_data, pugiutil::ReqOpt::OPTIONAL).as_int(-1)); + coord.set_y(get_attribute(xml_component_key, "row", loc_data, pugiutil::ReqOpt::OPTIONAL).as_int(-1)); + /* Require positive coordinate all the time */ + if (!fabric_key.valid_key_coordinate(coord)) { + archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_component_key), + "Invalid coordinate '(%d, %d)' which contain negative numbers\n", + coord.x(), coord.y()); + } else { + fabric_key.set_key_coordinate(FabricKeyId(id), coord); + } } /******************************************************************** diff --git a/libopenfpga/libfabrickey/src/write_xml_fabric_key.cpp b/libopenfpga/libfabrickey/src/write_xml_fabric_key.cpp index ea12d75a1..aa38c8140 100644 --- a/libopenfpga/libfabrickey/src/write_xml_fabric_key.cpp +++ b/libopenfpga/libfabrickey/src/write_xml_fabric_key.cpp @@ -52,6 +52,12 @@ int write_xml_fabric_component_key(std::fstream& fp, write_xml_attribute(fp, "alias", fabric_key.key_alias(component_key).c_str()); } + vtr::Point coord = fabric_key.key_coordinate(component_key); + if (fabric_key.valid_key_coordinate(coord)) { + write_xml_attribute(fp, "column", coord.x()); + write_xml_attribute(fp, "row", coord.y()); + } + fp << "/>" << "\n"; return 0; diff --git a/openfpga/src/fabric/build_top_module_memory.cpp b/openfpga/src/fabric/build_top_module_memory.cpp index c9ee2b722..ca78f8e88 100644 --- a/openfpga/src/fabric/build_top_module_memory.cpp +++ b/openfpga/src/fabric/build_top_module_memory.cpp @@ -636,7 +636,8 @@ int load_top_module_memory_modules_from_fabric_key(ModuleManager& module_manager /* Now we can add the child to configurable children of the top module */ module_manager.add_configurable_child(top_module, instance_info.first, - instance_info.second); + instance_info.second, + fabric_key.key_coordinate(key)); module_manager.add_configurable_child_to_region(top_module, top_module_config_region, instance_info.first, From dc2d1d1c3cd5139f666dea770dfddbe71caf94aa Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 21 Sep 2021 15:42:20 -0700 Subject: [PATCH 02/11] [Test] Add a new test case to validate the correctness of fabric key file for ql memory bank --- .../config/task.conf | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 openfpga_flow/tasks/basic_tests/fabric_key/generate_random_key_ql_memory_bank/config/task.conf diff --git a/openfpga_flow/tasks/basic_tests/fabric_key/generate_random_key_ql_memory_bank/config/task.conf b/openfpga_flow/tasks/basic_tests/fabric_key/generate_random_key_ql_memory_bank/config/task.conf new file mode 100644 index 000000000..f7f308a77 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/fabric_key/generate_random_key_ql_memory_bank/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=vpr_blif + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/generate_secure_fabric_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_qlbank_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml + +[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.blif + +[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 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= From 7327850cf3d54a7123396e6c734cf56430bc7297 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 21 Sep 2021 15:43:54 -0700 Subject: [PATCH 03/11] [Test] Deploy the fabric key test case for ql memory bank to basic regression tests --- openfpga_flow/regression_test_scripts/basic_reg_test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/openfpga_flow/regression_test_scripts/basic_reg_test.sh b/openfpga_flow/regression_test_scripts/basic_reg_test.sh index 531ba5f42..ddb8317f9 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -84,6 +84,7 @@ echo -e "Testing Secured FPGA fabrics"; run-task basic_tests/fabric_key/generate_vanilla_key --debug --show_thread_logs run-task basic_tests/fabric_key/generate_multi_region_vanilla_key --debug --show_thread_logs run-task basic_tests/fabric_key/generate_random_key --debug --show_thread_logs +run-task basic_tests/fabric_key/generate_random_key_ql_memory_bank --debug --show_thread_logs run-task basic_tests/fabric_key/load_external_key --debug --show_thread_logs run-task basic_tests/fabric_key/load_external_key_cc_fpga --debug --show_thread_logs run-task basic_tests/fabric_key/load_external_key_multi_region_cc_fpga --debug --show_thread_logs From b0a471bdc9f2b9677ac10bdd6d809fed01869e16 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 21 Sep 2021 15:55:11 -0700 Subject: [PATCH 04/11] [Engine] Bug fix in outputting fabric key with coordinates --- openfpga/src/fabric/fabric_key_writer.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openfpga/src/fabric/fabric_key_writer.cpp b/openfpga/src/fabric/fabric_key_writer.cpp index 63202ea90..c099d5468 100644 --- a/openfpga/src/fabric/fabric_key_writer.cpp +++ b/openfpga/src/fabric/fabric_key_writer.cpp @@ -70,6 +70,7 @@ int write_fabric_key_to_xml_file(const ModuleManager& module_manager, for (size_t ichild = 0; ichild < module_manager.region_configurable_children(top_module, config_region).size(); ++ichild) { ModuleId child_module = module_manager.region_configurable_children(top_module, config_region)[ichild]; size_t child_instance = module_manager.region_configurable_child_instances(top_module, config_region)[ichild]; + vtr::Point child_coord = module_manager.region_configurable_child_coordinates(top_module, config_region)[ichild]; FabricKeyId key = fabric_key.create_key(); fabric_key.set_key_name(key, module_manager.module_name(child_module)); @@ -79,6 +80,9 @@ int write_fabric_key_to_xml_file(const ModuleManager& module_manager, fabric_key.set_key_alias(key, module_manager.instance_name(top_module, child_module, child_instance)); } + /* Add key coordinate */ + fabric_key.set_key_coordinate(key, child_coord); + /* Add keys to the region */ fabric_key.add_key_to_region(fabric_region, key); } From cd0d8b86fafb2460d2c09a46e7f38d663d5a7984 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 21 Sep 2021 15:55:34 -0700 Subject: [PATCH 05/11] [Test] Add a random fabric key generated by OpenFPGA which is designed for QL memory bank --- .../k4_N4_1x1_qlbank_sample_key.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 openfpga_flow/fabric_keys/k4_N4_1x1_qlbank_sample_key.xml diff --git a/openfpga_flow/fabric_keys/k4_N4_1x1_qlbank_sample_key.xml b/openfpga_flow/fabric_keys/k4_N4_1x1_qlbank_sample_key.xml new file mode 100644 index 000000000..80621791d --- /dev/null +++ b/openfpga_flow/fabric_keys/k4_N4_1x1_qlbank_sample_key.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + From 141212154100a5a431ba3912f4063f9ddedf14bc Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 21 Sep 2021 16:20:24 -0700 Subject: [PATCH 06/11] [Test] Added a new test to validate the fabric key parser for QL memory bank --- .../config/task.conf | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 openfpga_flow/tasks/basic_tests/fabric_key/load_external_key_qlbank_fpga/config/task.conf diff --git a/openfpga_flow/tasks/basic_tests/fabric_key/load_external_key_qlbank_fpga/config/task.conf b/openfpga_flow/tasks/basic_tests/fabric_key/load_external_key_qlbank_fpga/config/task.conf new file mode 100644 index 000000000..314c9c544 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/fabric_key/load_external_key_qlbank_fpga/config/task.conf @@ -0,0 +1,39 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# 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=vpr_blif + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/generate_secure_fabric_from_key_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_qlbank_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml +external_fabric_key_file=${PATH:OPENFPGA_PATH}/openfpga_flow/fabric_keys/k4_N4_2x2_qlbank_sample_key.xml +openfpga_vpr_device_layout=2x2 + +[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.blif + +[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 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= +#vpr_fpga_verilog_formal_verification_top_netlist= From aad47ffbc6ccd55d7d5760cddcf272fa52e34493 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 21 Sep 2021 16:22:50 -0700 Subject: [PATCH 07/11] [Test] Upgrade the sample fabric key to ql memory bank for a 2x2 fabric --- .../k4_N4_1x1_qlbank_sample_key.xml | 19 --------- .../k4_N4_2x2_qlbank_sample_key.xml | 39 +++++++++++++++++++ 2 files changed, 39 insertions(+), 19 deletions(-) delete mode 100644 openfpga_flow/fabric_keys/k4_N4_1x1_qlbank_sample_key.xml create mode 100644 openfpga_flow/fabric_keys/k4_N4_2x2_qlbank_sample_key.xml diff --git a/openfpga_flow/fabric_keys/k4_N4_1x1_qlbank_sample_key.xml b/openfpga_flow/fabric_keys/k4_N4_1x1_qlbank_sample_key.xml deleted file mode 100644 index 80621791d..000000000 --- a/openfpga_flow/fabric_keys/k4_N4_1x1_qlbank_sample_key.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/openfpga_flow/fabric_keys/k4_N4_2x2_qlbank_sample_key.xml b/openfpga_flow/fabric_keys/k4_N4_2x2_qlbank_sample_key.xml new file mode 100644 index 000000000..e27f5d97f --- /dev/null +++ b/openfpga_flow/fabric_keys/k4_N4_2x2_qlbank_sample_key.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From f57aceff877807e7084ffefb47a7769bf6db2f2c Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 21 Sep 2021 16:25:14 -0700 Subject: [PATCH 08/11] [Test] Deploy the load external key test case for ql memory bank to basic regression tests --- openfpga_flow/regression_test_scripts/basic_reg_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfpga_flow/regression_test_scripts/basic_reg_test.sh b/openfpga_flow/regression_test_scripts/basic_reg_test.sh index ddb8317f9..c9fd5e378 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -88,7 +88,7 @@ run-task basic_tests/fabric_key/generate_random_key_ql_memory_bank --debug --sho run-task basic_tests/fabric_key/load_external_key --debug --show_thread_logs run-task basic_tests/fabric_key/load_external_key_cc_fpga --debug --show_thread_logs run-task basic_tests/fabric_key/load_external_key_multi_region_cc_fpga --debug --show_thread_logs - +run-task basic_tests/fabric_key/load_external_key_qlbank_fpga --debug --show_thread_logs echo -e "Testing K4 series FPGA"; echo -e "Testing K4N4 with facturable LUTs"; From ab42239b944f2ef291bf0512db92a712d5caba90 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 21 Sep 2021 16:44:58 -0700 Subject: [PATCH 09/11] [Test] Bug fix in the fabric key --- openfpga_flow/fabric_keys/k4_N4_2x2_qlbank_sample_key.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/openfpga_flow/fabric_keys/k4_N4_2x2_qlbank_sample_key.xml b/openfpga_flow/fabric_keys/k4_N4_2x2_qlbank_sample_key.xml index e27f5d97f..1de56c747 100644 --- a/openfpga_flow/fabric_keys/k4_N4_2x2_qlbank_sample_key.xml +++ b/openfpga_flow/fabric_keys/k4_N4_2x2_qlbank_sample_key.xml @@ -33,7 +33,5 @@ - - From e09ab2298e296d3733bf86718219b3d83472008c Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 21 Sep 2021 16:45:14 -0700 Subject: [PATCH 10/11] [Engine] Bug fix in fabric key parser on identifying invalid coordinate --- libopenfpga/libfabrickey/src/read_xml_fabric_key.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/libopenfpga/libfabrickey/src/read_xml_fabric_key.cpp b/libopenfpga/libfabrickey/src/read_xml_fabric_key.cpp index b9e83787f..1c42b07bb 100644 --- a/libopenfpga/libfabrickey/src/read_xml_fabric_key.cpp +++ b/libopenfpga/libfabrickey/src/read_xml_fabric_key.cpp @@ -65,12 +65,7 @@ void read_xml_region_key(pugi::xml_node& xml_component_key, vtr::Point coord; coord.set_x(get_attribute(xml_component_key, "column", loc_data, pugiutil::ReqOpt::OPTIONAL).as_int(-1)); coord.set_y(get_attribute(xml_component_key, "row", loc_data, pugiutil::ReqOpt::OPTIONAL).as_int(-1)); - /* Require positive coordinate all the time */ - if (!fabric_key.valid_key_coordinate(coord)) { - archfpga_throw(loc_data.filename_c_str(), loc_data.line(xml_component_key), - "Invalid coordinate '(%d, %d)' which contain negative numbers\n", - coord.x(), coord.y()); - } else { + if (fabric_key.valid_key_coordinate(coord)) { fabric_key.set_key_coordinate(FabricKeyId(id), coord); } } From 10774dc15c8dff2ae2f35344148389edd8a14784 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 21 Sep 2021 17:01:52 -0700 Subject: [PATCH 11/11] [Doc] Updated documentation about new syntax in fabric key --- .../source/manual/file_formats/fabric_key.rst | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/docs/source/manual/file_formats/fabric_key.rst b/docs/source/manual/file_formats/fabric_key.rst index f87cf1b2e..185e1b40a 100644 --- a/docs/source/manual/file_formats/fabric_key.rst +++ b/docs/source/manual/file_formats/fabric_key.rst @@ -62,6 +62,14 @@ Each configurable block is defined as a key. There are two ways to define a key, - ``alias`` indicates the instance name of the configurable memory block in the top-level FPGA fabric. If a valid alias is specified, the ``name`` and ``value`` are not required. + - ``column`` indicates the relative x coordinate for a configurable memory in a configurable region at the top-level FPGA fabric. This is required when the memory bank protocol is selection. + + .. note:: The configurable memory blocks in the same column will share the same Bit Line (BL) bus + + - ``row`` indicates the relative y coordinate for a configurable memory in a configurable region at the top-level FPGA fabric. This is required when the memory bank protocol is selection. + + .. note:: The configurable memory blocks in the same row will share the same Word Line (WL) bus + .. warning:: For fast loading of fabric key, strongly recommend to use pairs ``name`` and ``alias`` or ``name`` and ``value`` in the fabric key file. Using only ``alias`` may cause long parsing time for fabric key. The following is an example of a fabric key generate by OpenFPGA for a 2 :math:`\times` 2 FPGA. @@ -149,3 +157,46 @@ This key contains only ``name`` and ``value`` which is fast to parse. + +The following shows another example of a fabric key generate by OpenFPGA for a 2 :math:`\times` 2 FPGA using memory bank. +This key contains only ``name``, ``value``, ``row`` and ``column``. + +.. code-block:: xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +