Merge pull request #1307 from lnis-uofu/xt_subtile_strong

Fixed a bug on spotting pin index of subtiles
This commit is contained in:
tangxifan 2023-08-19 10:44:00 -07:00 committed by GitHub
commit ba827117a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 282 additions and 26 deletions

View File

@ -402,7 +402,6 @@ static void add_top_module_io_children(
/* Now walk through the coordinates */ /* Now walk through the coordinates */
for (vtr::Point<size_t> coord : coords) { for (vtr::Point<size_t> coord : coords) {
VTR_LOG("Adding coord [%lu][%lu]\n", coord.x(), coord.y());
t_physical_tile_loc phy_tile_loc(coord.x(), coord.y(), layer); t_physical_tile_loc phy_tile_loc(coord.x(), coord.y(), layer);
t_physical_tile_type_ptr grid_type = grids.get_physical_type(phy_tile_loc); t_physical_tile_type_ptr grid_type = grids.get_physical_type(phy_tile_loc);
/* Bypass EMPTY grid */ /* Bypass EMPTY grid */

View File

@ -1341,8 +1341,9 @@ static int build_top_module_global_net_for_given_tile_module(
return CMD_EXEC_FATAL_ERROR; return CMD_EXEC_FATAL_ERROR;
} }
grid_pin_start_index = grid_pin_start_index =
(subtile_index - sub_tile.capacity.low) * sub_tile_num_pins + sub_tile.sub_tile_to_tile_pin_indices
tile_port.absolute_first_pin_index; [(subtile_index - sub_tile.capacity.low) * sub_tile_num_pins +
tile_port.absolute_first_pin_index];
physical_tile_port = tile_port; physical_tile_port = tile_port;
break; break;
} }

View File

@ -128,7 +128,6 @@ static int check_tile_annotation_conflicts_with_physical_tile(
++tile_info_id) { ++tile_info_id) {
/* Must find a valid physical tile in the same name */ /* Must find a valid physical tile in the same name */
size_t found_matched_physical_tile = 0; size_t found_matched_physical_tile = 0;
size_t found_matched_physical_tile_port = 0;
std::string required_tile_name = std::string required_tile_name =
tile_annotation.global_port_tile_names(tile_global_port)[tile_info_id]; tile_annotation.global_port_tile_names(tile_global_port)[tile_info_id];
@ -146,6 +145,7 @@ static int check_tile_annotation_conflicts_with_physical_tile(
/* Must found a valid port where both port name and port size must /* Must found a valid port where both port name and port size must
* match!!! */ * match!!! */
for (const t_sub_tile& sub_tile : physical_tile.sub_tiles) { for (const t_sub_tile& sub_tile : physical_tile.sub_tiles) {
size_t found_matched_physical_tile_port = 0;
for (const t_physical_tile_port& tile_port : sub_tile.ports) { for (const t_physical_tile_port& tile_port : sub_tile.ports) {
if (std::string(tile_port.name) != required_tile_port.get_name()) { if (std::string(tile_port.name) != required_tile_port.get_name()) {
continue; continue;
@ -167,7 +167,8 @@ static int check_tile_annotation_conflicts_with_physical_tile(
} }
/* Check if port property matches */ /* Check if port property matches */
int grid_pin_index = tile_port.absolute_first_pin_index; int grid_pin_index = sub_tile.sub_tile_to_tile_pin_indices
[tile_port.absolute_first_pin_index];
if (tile_port.is_clock != if (tile_port.is_clock !=
tile_annotation.global_port_is_clock(tile_global_port)) { tile_annotation.global_port_is_clock(tile_global_port)) {
@ -215,6 +216,28 @@ static int check_tile_annotation_conflicts_with_physical_tile(
found_matched_physical_tile_port++; found_matched_physical_tile_port++;
} }
if (0 == found_matched_physical_tile_port) {
VTR_LOGF_ERROR(
__FILE__, __LINE__,
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' does not "
"match "
"any physical tile port!\n",
required_tile_name.c_str(), required_tile_port.get_name().c_str(),
required_tile_port.get_lsb(), required_tile_port.get_msb(),
tile_annotation.global_port_name(tile_global_port).c_str());
num_err++;
}
if (1 < found_matched_physical_tile_port) {
VTR_LOGF_ERROR(
__FILE__, __LINE__,
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match more "
"than "
"1 physical tile port!\n",
required_tile_name.c_str(), required_tile_port.get_name().c_str(),
required_tile_port.get_lsb(), required_tile_port.get_msb(),
tile_annotation.global_port_name(tile_global_port).c_str());
num_err++;
}
} }
} }
@ -228,17 +251,6 @@ static int check_tile_annotation_conflicts_with_physical_tile(
tile_annotation.global_port_name(tile_global_port).c_str()); tile_annotation.global_port_name(tile_global_port).c_str());
num_err++; num_err++;
} }
if (0 == found_matched_physical_tile_port) {
VTR_LOGF_ERROR(
__FILE__, __LINE__,
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' does not match "
"any physical tile port!\n",
required_tile_name.c_str(), required_tile_port.get_name().c_str(),
required_tile_port.get_lsb(), required_tile_port.get_msb(),
tile_annotation.global_port_name(tile_global_port).c_str());
num_err++;
}
/* If we found more than 1 match, error out */ /* If we found more than 1 match, error out */
if (1 < found_matched_physical_tile) { if (1 < found_matched_physical_tile) {
VTR_LOGF_ERROR( VTR_LOGF_ERROR(
@ -249,16 +261,6 @@ static int check_tile_annotation_conflicts_with_physical_tile(
tile_annotation.global_port_name(tile_global_port).c_str()); tile_annotation.global_port_name(tile_global_port).c_str());
num_err++; num_err++;
} }
if (1 < found_matched_physical_tile_port) {
VTR_LOGF_ERROR(
__FILE__, __LINE__,
"Tile port '%s.%s[%ld:%ld]' in tile annotation '%s' match more than "
"1 physical tile port!\n",
required_tile_name.c_str(), required_tile_port.get_name().c_str(),
required_tile_port.get_lsb(), required_tile_port.get_msb(),
tile_annotation.global_port_name(tile_global_port).c_str());
num_err++;
}
} }
} }

View File

@ -158,6 +158,13 @@
<port type="input" prefix="outpad" lib_name="A" size="1"/> <port type="input" prefix="outpad" lib_name="A" size="1"/>
<port type="output" prefix="inpad" lib_name="Y" size="1"/> <port type="output" prefix="inpad" lib_name="Y" size="1"/>
</circuit_model> </circuit_model>
<circuit_model type="iopad" name="GPIN" prefix="GPIN" is_default="true" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/verilog/gpio.v">
<design_technology type="cmos"/>
<input_buffer exist="true" circuit_model_name="sky130_fd_sc_hd__inv_1"/>
<output_buffer exist="true" circuit_model_name="sky130_fd_sc_hd__inv_1"/>
<port type="inout" prefix="PAD" lib_name="A" size="1" is_global="true" is_io="true" is_data_io="true"/>
<port type="output" prefix="inpad" lib_name="Y" size="1"/>
</circuit_model>
</circuit_library> </circuit_library>
<configuration_protocol> <configuration_protocol>
<organization type="scan_chain" circuit_model_name="DFF"/> <organization type="scan_chain" circuit_model_name="DFF"/>
@ -175,6 +182,7 @@
<global_port name="clk" is_clock="true" default_val="0"> <global_port name="clk" is_clock="true" default_val="0">
<tile name="clb" port="clk" x="-1" y="-1"/> <tile name="clb" port="clk" x="-1" y="-1"/>
<tile name="io" port="clk" x="-1" y="-1"/> <tile name="io" port="clk" x="-1" y="-1"/>
<tile name="io_hybrid" port="clk" x="-1" y="-1"/>
</global_port> </global_port>
</tile_annotations> </tile_annotations>
<pb_type_annotations> <pb_type_annotations>
@ -186,6 +194,12 @@
<pb_type name="io[inpad_registered].inpad" physical_pb_type_name="io[physical].iopad" mode_bits="1"/> <pb_type name="io[inpad_registered].inpad" physical_pb_type_name="io[physical].iopad" mode_bits="1"/>
<pb_type name="io[inpad_registered].ff" physical_pb_type_name="io[physical].ff"/> <pb_type name="io[inpad_registered].ff" physical_pb_type_name="io[physical].ff"/>
<pb_type name="io[outpad].outpad" physical_pb_type_name="io[physical].iopad" mode_bits="0"/> <pb_type name="io[outpad].outpad" physical_pb_type_name="io[physical].iopad" mode_bits="0"/>
<pb_type name="io_input" physical_mode_name="physical" idle_mode_name="inpad"/>
<pb_type name="io_input[physical].iopad" circuit_model_name="GPIN" mode_bits="1"/>
<pb_type name="io_input[physical].ff" circuit_model_name="DFFSRQ"/>
<pb_type name="io_input[inpad].inpad" physical_pb_type_name="io_input[physical].iopad" mode_bits="1"/>
<pb_type name="io_input[inpad_registered].inpad" physical_pb_type_name="io_input[physical].iopad" mode_bits="1"/>
<pb_type name="io_input[inpad_registered].ff" physical_pb_type_name="io_input[physical].ff"/>
<!-- End physical pb_type binding in complex block IO --> <!-- End physical pb_type binding in complex block IO -->
<!-- physical pb_type binding in complex block CLB --> <!-- physical pb_type binding in complex block CLB -->
<!-- physical mode will be the default mode if not specified --> <!-- physical mode will be the default mode if not specified -->

View File

@ -179,6 +179,7 @@ run-task basic_tests/tile_organization/io_subtile_strong $@
echo -e "Testing tile grouping on a homogeneous FPGA fabric (Full testbench)"; echo -e "Testing tile grouping on a homogeneous FPGA fabric (Full testbench)";
run-task basic_tests/tile_organization/homo_fabric_tile $@ run-task basic_tests/tile_organization/homo_fabric_tile $@
echo -e "Testing tile grouping on a homogeneous FPGA fabric (Preconfigured testbench)"; echo -e "Testing tile grouping on a homogeneous FPGA fabric (Preconfigured testbench)";
run-task basic_tests/tile_organization/fabric_tile_global_tile_clock_io_subtile $@
run-task basic_tests/tile_organization/homo_fabric_tile_preconfig $@ run-task basic_tests/tile_organization/homo_fabric_tile_preconfig $@
run-task basic_tests/tile_organization/homo_fabric_tile_2x2_preconfig $@ run-task basic_tests/tile_organization/homo_fabric_tile_2x2_preconfig $@
run-task basic_tests/tile_organization/homo_fabric_tile_4x4_preconfig $@ run-task basic_tests/tile_organization/homo_fabric_tile_4x4_preconfig $@
@ -195,9 +196,11 @@ run-task basic_tests/group_config_block/group_config_block_homo_fabric_tile_Lsha
run-task basic_tests/group_config_block/group_config_block_homo_fabric_tile_core_wrapper $@ run-task basic_tests/group_config_block/group_config_block_homo_fabric_tile_core_wrapper $@
run-task basic_tests/group_config_block/group_config_block_hetero_fabric_tile $@ run-task basic_tests/group_config_block/group_config_block_hetero_fabric_tile $@
run-task basic_tests/group_config_block/group_config_block_hetero_fabric_tile_Lshape $@ run-task basic_tests/group_config_block/group_config_block_hetero_fabric_tile_Lshape $@
run-task basic_tests/group_config_block/group_config_block_homo_fabric_tile_global_tile_clock_io_subtile $@
echo -e "Testing global port definition from tiles"; echo -e "Testing global port definition from tiles";
run-task basic_tests/global_tile_ports/global_tile_clock $@ run-task basic_tests/global_tile_ports/global_tile_clock $@
run-task basic_tests/global_tile_ports/global_tile_clock_subtile $@
run-task basic_tests/global_tile_ports/global_tile_reset $@ run-task basic_tests/global_tile_ports/global_tile_reset $@
run-task basic_tests/global_tile_ports/global_tile_4clock $@ run-task basic_tests/global_tile_ports/global_tile_4clock $@
run-task basic_tests/global_tile_ports/global_tile_4clock_pin $@ run-task basic_tests/global_tile_ports/global_tile_4clock_pin $@

View File

@ -0,0 +1,35 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# 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/global_tile_clock_full_testbench_example_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClk_registerable_io_cc_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml
openfpga_vpr_device_layout=2x2_hybrid_io
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_GlobalTileClk_registerable_io_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_pipelined/and2_pipelined.v
[SYNTHESIS_PARAM]
bench_read_verilog_options_common = -nolatches
bench0_top = and2_pipelined
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=

View File

@ -0,0 +1,42 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# 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/group_config_block_preconfig_testbench_example_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClk_registerable_io_cc_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
openfpga_vpr_extra_options=
openfpga_pb_pin_fixup_command=
openfpga_vpr_device=2x2_hybrid_io
openfpga_vpr_route_chan_width=20
openfpga_group_tile_config_option=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml
openfpga_verilog_testbench_options=--explicit_port_mapping
openfpga_add_fpga_core_module=
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_GlobalTileClk_registerable_io_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_pipelined/and2_pipelined.v
[SYNTHESIS_PARAM]
bench_read_verilog_options_common = -nolatches
bench0_top = and2_pipelined
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=
vpr_fpga_verilog_formal_verification_top_netlist=

View File

@ -0,0 +1,42 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# 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/group_tile_preconfig_testbench_example_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClk_registerable_io_cc_openfpga.xml
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
openfpga_vpr_extra_options=
openfpga_pb_pin_fixup_command=
openfpga_vpr_device=2x2_hybrid_io
openfpga_vpr_route_chan_width=20
openfpga_group_tile_config_file=${PATH:TASK_DIR}/config/tile_config.xml
openfpga_verilog_testbench_options=--explicit_port_mapping
[ARCHITECTURES]
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_GlobalTileClk_registerable_io_40nm.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2_pipelined/and2_pipelined.v
[SYNTHESIS_PARAM]
bench_read_verilog_options_common = -nolatches
bench0_top = and2_pipelined
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
end_flow_with_test=
vpr_fpga_verilog_formal_verification_top_netlist=

View File

@ -34,6 +34,11 @@
<port name="inpad"/> <port name="inpad"/>
</output_ports> </output_ports>
</model> </model>
<model name="io_inpad">
<output_ports>
<port name="inpad"/>
</output_ports>
</model>
</models> </models>
<tiles> <tiles>
<tile name="io" area="0"> <tile name="io" area="0">
@ -55,6 +60,41 @@
</pinlocations> </pinlocations>
</sub_tile> </sub_tile>
</tile> </tile>
<tile name="io_hybrid" area="0">
<sub_tile name="io_input" capacity="2">
<equivalent_sites>
<site pb_type="io_input"/>
</equivalent_sites>
<output name="inpad" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10">
<fc_override port_name="clk" fc_type="frac" fc_val="0"/>
</fc>
<pinlocations pattern="custom">
<loc side="left">io_input.inpad io_input.clk</loc>
<loc side="top">io_input.inpad io_input.clk</loc>
<loc side="right">io_input.inpad io_input.clk</loc>
<loc side="bottom">io_input.inpad io_input.clk</loc>
</pinlocations>
</sub_tile>
<sub_tile name="io" capacity="6">
<equivalent_sites>
<site pb_type="io"/>
</equivalent_sites>
<input name="outpad" num_pins="1"/>
<output name="inpad" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<fc in_type="frac" in_val="0.15" out_type="frac" out_val="0.10">
<fc_override port_name="clk" fc_type="frac" fc_val="0"/>
</fc>
<pinlocations pattern="custom">
<loc side="left">io.outpad io.inpad io.clk</loc>
<loc side="top">io.outpad io.inpad io.clk</loc>
<loc side="right">io.outpad io.inpad io.clk</loc>
<loc side="bottom">io.outpad io.inpad io.clk</loc>
</pinlocations>
</sub_tile>
</tile>
<tile name="clb" area="53894"> <tile name="clb" area="53894">
<sub_tile name="clb"> <sub_tile name="clb">
<equivalent_sites> <equivalent_sites>
@ -87,6 +127,13 @@
<!--Fill with 'clb'--> <!--Fill with 'clb'-->
<fill type="clb" priority="10"/> <fill type="clb" priority="10"/>
</fixed_layout> </fixed_layout>
<fixed_layout name="2x2_hybrid_io" width="4" height="4">
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
<perimeter type="io_hybrid" priority="100"/>
<corners type="EMPTY" priority="101"/>
<!--Fill with 'clb'-->
<fill type="clb" priority="10"/>
</fixed_layout>
</layout> </layout>
<device> <device>
<!-- VB & JL: Using Ian Kuon's transistor sizing and drive strength data for routing, at 40 nm. Ian used BPTM <!-- VB & JL: Using Ian Kuon's transistor sizing and drive strength data for routing, at 40 nm. Ian used BPTM
@ -232,6 +279,75 @@
<!-- Place I/Os on the sides of the FPGA --> <!-- Place I/Os on the sides of the FPGA -->
<power method="ignore"/> <power method="ignore"/>
</pb_type> </pb_type>
<pb_type name="io_input">
<output name="inpad" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<!-- A mode denotes the physical implementation of an I/O
This mode will be not packable but is mainly used for fabric verilog generation
-->
<mode name="physical" disable_packing="true">
<pb_type name="iopad" blif_model=".subckt io_inpad" num_pb="1">
<output name="inpad" num_pins="1"/>
</pb_type>
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="clk" input="io_input.clk" output="ff.clk"/>
<!-- Create a selector between registered/combinational I/O -->
<direct name="inpad" input="iopad.inpad" output="ff.D"/>
<mux name="mux1" input="iopad.inpad ff.Q" output="io_input.inpad">
<delay_constant max="4.5e-11" in_port="iopad.inpad" out_port="io_input.inpad"/>
<delay_constant max="4.243e-11" in_port="ff.Q" out_port="io_input.inpad"/>
</mux>
</interconnect>
</mode>
<!-- IOs can operate as either inputs or outputs.
Delays below come from Ian Kuon. They are small, so they should be interpreted as
the delays to and from registers in the I/O (and generally I/Os are registered
today and that is when you timing analyze them.
-->
<mode name="inpad">
<pb_type name="inpad" blif_model=".input" num_pb="1">
<output name="inpad" num_pins="1"/>
</pb_type>
<interconnect>
<direct name="inpad" input="inpad.inpad" output="io_input.inpad">
<delay_constant max="4.243e-11" in_port="inpad.inpad" out_port="io_input.inpad"/>
</direct>
</interconnect>
</mode>
<mode name="inpad_registered">
<pb_type name="inpad" blif_model=".input" num_pb="1">
<output name="inpad" num_pins="1"/>
</pb_type>
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
</pb_type>
<interconnect>
<direct name="clk" input="io_input.clk" output="ff.clk"/>
<direct name="inpad" input="inpad.inpad" output="ff.D">
<pack_pattern name="registered_io" in_port="inpad.inpad" out_port="ff.D"/>
</direct>
<direct name="ff2inpad" input="ff.Q" output="io_input.inpad"/>
</interconnect>
</mode>
<!-- Every input pin is driven by 15% of the tracks in a channel, every output pin is driven by 10% of the tracks in a channel -->
<!-- IOs go on the periphery of the FPGA, for consistency,
make it physically equivalent on all sides so that only one definition of I/Os is needed.
If I do not make a physically equivalent definition, then I need to define 4 different I/Os, one for each side of the FPGA
-->
<!-- Place I/Os on the sides of the FPGA -->
<power method="ignore"/>
</pb_type>
<!-- Define I/O pads ends --> <!-- Define I/O pads ends -->
<!-- Define general purpose logic block (CLB) begin --> <!-- Define general purpose logic block (CLB) begin -->
<!--- Area calculation: Total Stratix IV tile area is about 8100 um^2, and a minimum width transistor <!--- Area calculation: Total Stratix IV tile area is about 8100 um^2, and a minimum width transistor