diff --git a/docs/source/manual/arch_lang/annotate_vpr_arch.rst b/docs/source/manual/arch_lang/annotate_vpr_arch.rst
index f4767c938..a9e423f7c 100644
--- a/docs/source/manual/arch_lang/annotate_vpr_arch.rst
+++ b/docs/source/manual/arch_lang/annotate_vpr_arch.rst
@@ -134,6 +134,16 @@ When a global port, e.g., ``clk``, is defined in ``tile_annotation`` using the f
+Note that a global port can also be defined to drive only a partial bit of a port of a physical tile.
+
+.. code-block:: xml
+
+
+
+
+
+
+
Clock port ``clk`` of each ``clb`` tile will be connected to a common clock port of the top module, while local clock network is customizable through VPR's architecture description language. For instance, the local clock network can be a programmable clock network.
.. _annotate_vpr_arch_pb_type_annotation:
diff --git a/openfpga/src/fabric/build_top_module_connection.cpp b/openfpga/src/fabric/build_top_module_connection.cpp
index 03b04cd03..16f2520a0 100644
--- a/openfpga/src/fabric/build_top_module_connection.cpp
+++ b/openfpga/src/fabric/build_top_module_connection.cpp
@@ -782,11 +782,19 @@ int build_top_module_global_net_for_given_grid_module(ModuleManager& module_mana
/* Ensure port width is in range */
BasicPort src_port = module_manager.module_port(top_module, top_module_port);
- VTR_ASSERT(src_port.get_width() >= size_t(physical_tile_port.num_pins));
+ VTR_ASSERT(src_port.get_width() == tile_port_to_connect.get_width());
+
+ /* Create a pin id mapping between the source port (top module) and the sink port (grid module) */
+ std::map sink2src_pin_map;
+ for (size_t ipin = 0; ipin < tile_port_to_connect.get_width(); ++ipin) {
+ size_t sink_pin = tile_port_to_connect.pins()[ipin];
+ size_t src_pin = src_port.pins()[ipin];
+ sink2src_pin_map[sink_pin] = src_pin;
+ }
/* A tile may consist of multiple subtile, connect to all the pins from sub tiles */
for (int iz = 0; iz < physical_tile->capacity; ++iz) {
- for (size_t pin_id = 0; pin_id < size_t(physical_tile_port.num_pins); ++pin_id) {
+ for (size_t pin_id = tile_port_to_connect.get_lsb(); pin_id < tile_port_to_connect.get_msb() + 1; ++pin_id) {
/* TODO: This should be replaced by using a pin mapping data structure from physical tile! */
int grid_pin_index = grid_pin_start_index + iz * physical_tile->equivalent_sites[0]->pb_type->num_pins + pin_id;
/* Find the module pin */
@@ -811,7 +819,7 @@ int build_top_module_global_net_for_given_grid_module(ModuleManager& module_mana
ModuleNetId net = create_module_source_pin_net(module_manager, top_module,
top_module, 0,
- top_module_port, src_port.pins()[pin_id]);
+ top_module_port, src_port.pins()[sink2src_pin_map[pin_id]]);
VTR_ASSERT(ModuleNetId::INVALID() != net);
/* Configure the net sink */
diff --git a/openfpga_flow/openfpga_arch/README.md b/openfpga_flow/openfpga_arch/README.md
index ed4a17815..36fb95acd 100644
--- a/openfpga_flow/openfpga_arch/README.md
+++ b/openfpga_flow/openfpga_arch/README.md
@@ -31,6 +31,8 @@ Note that an OpenFPGA architecture can be applied to multiple VPR architecture f
- tree\_mux: If routing multiplexers are built with a tree-like structure
- : The technology node which the delay numbers are extracted from.
- powergate : The FPGA has power-gating techniques applied. If not defined, there is no power-gating.
-- GlobalTileClk: How many clocks are defined through global ports from physical tiles. is the number of clocks
+- GlobalTileClk: How many clocks are defined through global ports from physical tiles.
+ * is the number of clocks
+ * When specified, multiple clocks are in separated pins with different names
Other features are used in naming should be listed here.
diff --git a/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTile4ClkPin_cc_openfpga.xml b/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTile4ClkPin_cc_openfpga.xml
new file mode 100644
index 000000000..f79a10250
--- /dev/null
+++ b/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTile4ClkPin_cc_openfpga.xml
@@ -0,0 +1,207 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10e-12
+
+
+ 10e-12
+
+
+
+
+
+
+
+
+ 10e-12
+
+
+ 10e-12
+
+
+
+
+
+
+
+
+ 10e-12
+
+
+ 10e-12
+
+
+
+
+
+
+
+
+
+
+
+
+ 10e-12 5e-12 5e-12
+
+
+ 10e-12 5e-12 5e-12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openfpga_flow/openfpga_shell_scripts/global_tile_multiclock_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/global_tile_multiclock_example_script.openfpga
index 1b1daae4d..de2ca6cbd 100644
--- a/openfpga_flow/openfpga_shell_scripts/global_tile_multiclock_example_script.openfpga
+++ b/openfpga_flow/openfpga_shell_scripts/global_tile_multiclock_example_script.openfpga
@@ -72,7 +72,9 @@ write_pnr_sdc --file ./SDC
write_sdc_disable_timing_configure_ports --file ./SDC/disable_configure_ports.sdc
# Write the SDC to run timing analysis for a mapped FPGA fabric
-write_analysis_sdc --file ./SDC_analysis
+# TODO: Currently SDC writer only supports 1 operating clock due to
+# - Missing information about which I/O is constrained by which clock
+#write_analysis_sdc --file ./SDC_analysis
# Finish and exit OpenFPGA
exit
diff --git a/openfpga_flow/regression_test_scripts/basic_reg_test.sh b/openfpga_flow/regression_test_scripts/basic_reg_test.sh
index 2fa69fb87..b3a6a7193 100755
--- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh
+++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh
@@ -139,6 +139,7 @@ echo -e "Testing global port definition from tiles";
run-task basic_tests/global_tile_ports/global_tile_clock --debug --show_thread_logs
run-task basic_tests/global_tile_ports/global_tile_reset --debug --show_thread_logs
run-task basic_tests/global_tile_ports/global_tile_4clock --debug --show_thread_logs
+run-task basic_tests/global_tile_ports/global_tile_4clock_pin --debug --show_thread_logs
echo -e "Testing configuration chain of a K4N4 FPGA using .blif generated by yosys+verific";
run-task basic_tests/verific_test --debug --show_thread_logs
diff --git a/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock_pin/config/and2_latch_pin_constraints.xml b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock_pin/config/and2_latch_pin_constraints.xml
new file mode 100644
index 000000000..b4c931f20
--- /dev/null
+++ b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock_pin/config/and2_latch_pin_constraints.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
diff --git a/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock_pin/config/and2_latch_repack_pin_constraints.xml b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock_pin/config/and2_latch_repack_pin_constraints.xml
new file mode 100644
index 000000000..d695cf85e
--- /dev/null
+++ b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock_pin/config/and2_latch_repack_pin_constraints.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock_pin/config/counter_2clock_pin_constraints.xml b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock_pin/config/counter_2clock_pin_constraints.xml
new file mode 100644
index 000000000..fe949b306
--- /dev/null
+++ b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock_pin/config/counter_2clock_pin_constraints.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
diff --git a/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock_pin/config/counter_2clock_repack_pin_constraints.xml b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock_pin/config/counter_2clock_repack_pin_constraints.xml
new file mode 100644
index 000000000..9966d5a25
--- /dev/null
+++ b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock_pin/config/counter_2clock_repack_pin_constraints.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock_pin/config/task.conf b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock_pin/config/task.conf
new file mode 100644
index 000000000..3c9d6e83a
--- /dev/null
+++ b/openfpga_flow/tasks/basic_tests/global_tile_ports/global_tile_4clock_pin/config/task.conf
@@ -0,0 +1,43 @@
+# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+# 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/global_tile_multiclock_example_script.openfpga
+openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTile4ClkPin_cc_openfpga.xml
+openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_4clock_sim_openfpga.xml
+
+[ARCHITECTURES]
+arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_GlobalTile4Clk_40nm.xml
+
+[BENCHMARKS]
+bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/counters/counter_4bit_2clock/counter_4bit_2clock.v
+bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_latch_2clock/and2_latch_2clock.v
+
+[SYNTHESIS_PARAM]
+bench_read_verilog_options_common = -nolatches
+
+bench0_top = counter_4bit_2clock
+bench0_openfpga_pin_constraints_file=${PATH:TASK_DIR}/config/counter_2clock_pin_constraints.xml
+bench0_openfpga_repack_design_constraints_file=${PATH:TASK_DIR}/config/counter_2clock_repack_pin_constraints.xml
+
+bench1_top = and2_latch_2clock
+bench1_openfpga_pin_constraints_file=${PATH:TASK_DIR}/config/and2_latch_pin_constraints.xml
+bench1_openfpga_repack_design_constraints_file=${PATH:TASK_DIR}/config/and2_latch_repack_pin_constraints.xml
+
+[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
+end_flow_with_test=
+vpr_fpga_verilog_formal_verification_top_netlist=