From e1feebc96d24919bfe0b6565b00730519e3f8382 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Fri, 26 May 2023 21:54:08 -0700 Subject: [PATCH] [core] fixing bugs on pcf and bgf support for mock efpga wrapper --- .../verilog_mock_fpga_wrapper.cpp | 137 ++++++++++++++++-- .../mock_wrapper_example_script.openfpga | 4 +- .../regression_test_scripts/basic_reg_test.sh | 1 + .../mock_wrapper_pcf/config/task.conf | 4 +- 4 files changed, 130 insertions(+), 16 deletions(-) diff --git a/openfpga/src/fpga_verilog/verilog_mock_fpga_wrapper.cpp b/openfpga/src/fpga_verilog/verilog_mock_fpga_wrapper.cpp index 5d5acb535..0c3642092 100644 --- a/openfpga/src/fpga_verilog/verilog_mock_fpga_wrapper.cpp +++ b/openfpga/src/fpga_verilog/verilog_mock_fpga_wrapper.cpp @@ -178,18 +178,7 @@ static void print_verilog_mock_fpga_wrapper_connect_ios( */ BasicPort benchmark_io_port; - /* If this benchmark pin belongs to any bus group, use the bus pin instead - */ - BusGroupId bus_id = bus_group.find_pin_bus(block_name); - BusPinId bus_pin_id = bus_group.find_pin(block_name); - if (bus_id) { - block_name = bus_group.bus_port(bus_id).get_name(); - VTR_ASSERT_SAFE(bus_pin_id); - benchmark_io_port.set_width(bus_group.pin_index(bus_pin_id), - bus_group.pin_index(bus_pin_id)); - } else { - benchmark_io_port.set_width(1); - } + benchmark_io_port.set_width(1); if (AtomBlockType::INPAD == atom_ctx.nlist.block_type(atom_blk)) { /* If the port is a clock, skip it */ @@ -270,6 +259,121 @@ static void print_verilog_mock_fpga_wrapper_connect_ios( } } +/******************************************************************** + * Connect global ports of FPGA top module to constants except: + * 1. operating clock, which should be wired to the clock port of + * this pre-configured FPGA top module + *******************************************************************/ +static int print_verilog_mock_fpga_wrapper_connect_global_ports( + std::fstream &fp, const ModuleManager &module_manager, + const ModuleId &top_module, const PinConstraints &pin_constraints, + const FabricGlobalPortInfo &fabric_global_ports, + const std::vector &benchmark_clock_port_names) { + /* Validate the file stream */ + valid_file_stream(fp); + + print_verilog_comment( + fp, + std::string("----- Begin Connect Global ports to FPGA top-level interface -----")); + + for (const FabricGlobalPortId &global_port_id : + fabric_global_ports.global_ports()) { + ModulePortId module_global_port_id = + fabric_global_ports.global_module_port(global_port_id); + VTR_ASSERT(ModuleManager::MODULE_GLOBAL_PORT == + module_manager.port_type(top_module, module_global_port_id)); + BasicPort module_global_port = + module_manager.module_port(top_module, module_global_port_id); + /* Now, for operating clock port, we should wire it to the clock of + * benchmark! */ + if ((true == fabric_global_ports.global_port_is_clock(global_port_id)) && + (false == fabric_global_ports.global_port_is_prog(global_port_id))) { + /* Wiring to each pin of the global port: benchmark clock is always 1-bit + */ + for (size_t pin_id = 0; pin_id < module_global_port.pins().size(); + ++pin_id) { + BasicPort module_clock_pin( + module_global_port.get_name(), + module_global_port.pins()[pin_id], module_global_port.pins()[pin_id]); + + /* If the clock port name is in the pin constraints, we should wire it + * to the constrained pin */ + std::string constrained_net_name = pin_constraints.pin_net(BasicPort( + module_global_port.get_name(), module_global_port.pins()[pin_id], + module_global_port.pins()[pin_id])); + + /* If constrained to an open net or there is no clock in the benchmark, + * we assign it to a default value */ + if ((true == pin_constraints.unmapped_net(constrained_net_name)) || + (true == benchmark_clock_port_names.empty())) { + continue; + } + + std::string clock_name_to_connect; + if (!pin_constraints.unconstrained_net(constrained_net_name)) { + clock_name_to_connect = constrained_net_name; + } else { + /* Otherwise, we must have a clear one-to-one clock net + * corresponding!!! */ + if (benchmark_clock_port_names.size() != + module_global_port.get_width()) { + VTR_LOG_ERROR( + "Unable to map %lu benchmark clocks to %lu clock pins of " + "FPGA!\nRequire clear pin constraints!\n", + benchmark_clock_port_names.size(), + module_global_port.get_width()); + return CMD_EXEC_FATAL_ERROR; + } + clock_name_to_connect = benchmark_clock_port_names[pin_id]; + } + + BasicPort benchmark_clock_pin(clock_name_to_connect, 1); + print_verilog_wire_connection(fp, benchmark_clock_pin, module_clock_pin, + false); + } + /* Finish, go to the next */ + continue; + } + + /* For other ports, give an default value */ + for (size_t pin_id = 0; pin_id < module_global_port.pins().size(); + ++pin_id) { + BasicPort module_global_pin(module_global_port.get_name(), + module_global_port.pins()[pin_id], + module_global_port.pins()[pin_id]); + + /* If the global port name is in the pin constraints, we should wire it to + * the constrained pin */ + std::string constrained_net_name = + pin_constraints.pin_net(module_global_pin) + std::string(APPINST_PORT_POSTFIX); + + module_global_pin.set_name( + module_global_port.get_name()); + + /* - If constrained to a given net in the benchmark, we connect the global + * pin to the net + * - If constrained to an open net in the benchmark, we assign it to a + * default value + */ + if ((false == pin_constraints.unconstrained_net(constrained_net_name)) && + (false == pin_constraints.unmapped_net(constrained_net_name))) { + BasicPort benchmark_pin(constrained_net_name, 1); + print_verilog_wire_connection(fp, benchmark_pin, module_global_pin, + false); + } + } + } + + print_verilog_comment( + fp, std::string("----- End Connect Global ports to FPGA top-level interface -----")); + + /* Add an empty line as a splitter */ + fp << std::endl; + + return CMD_EXEC_SUCCESS; +} + + /******************************************************************** * Top-level function to generate a Verilog module of * a mock FPGA wrapper which contains an benchmark instance. @@ -354,6 +458,15 @@ int print_verilog_mock_fpga_wrapper( netlist_annotation, pin_constraints, bus_group, options.explicit_port_mapping()); + /* Connect FPGA top module global ports to constant or benchmark global + * signals! */ + status = print_verilog_mock_fpga_wrapper_connect_global_ports( + fp, module_manager, top_module, pin_constraints, global_ports, + benchmark_clock_port_names); + if (CMD_EXEC_FATAL_ERROR == status) { + return status; + } + /* Connect I/Os to benchmark I/Os or constant driver */ print_verilog_mock_fpga_wrapper_connect_ios( fp, module_manager, top_module, atom_ctx, place_ctx, io_location_map, diff --git a/openfpga_flow/openfpga_shell_scripts/mock_wrapper_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/mock_wrapper_example_script.openfpga index ae90178a7..636ac6e9d 100644 --- a/openfpga_flow/openfpga_shell_scripts/mock_wrapper_example_script.openfpga +++ b/openfpga_flow/openfpga_shell_scripts/mock_wrapper_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 +vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling ideal # Read OpenFPGA architecture definition read_openfpga_arch -f ${OPENFPGA_ARCH_FILE} @@ -10,7 +10,7 @@ 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 +link_openfpga_arch --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 diff --git a/openfpga_flow/regression_test_scripts/basic_reg_test.sh b/openfpga_flow/regression_test_scripts/basic_reg_test.sh index d9be3f249..489120590 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -116,6 +116,7 @@ run-task basic_tests/fabric_key/load_external_key_qlbanksr_multi_chain_fpga $@ #run-task basic_tests/fabric_key/load_external_key_multi_region_qlbanksr_fpga $@ echo -e "Testing mock wrapper" +run-task basic_tests/mock_wrapper/mock_wrapper_explicit_port_mapping $@ run-task basic_tests/mock_wrapper/mock_wrapper_implicit_port_mapping $@ run-task basic_tests/mock_wrapper/mock_wrapper_pcf $@ run-task basic_tests/mock_wrapper/mock_wrapper_bgf $@ diff --git a/openfpga_flow/tasks/basic_tests/mock_wrapper/mock_wrapper_pcf/config/task.conf b/openfpga_flow/tasks/basic_tests/mock_wrapper/mock_wrapper_pcf/config/task.conf index 5685d3ca4..93e225201 100644 --- a/openfpga_flow/tasks/basic_tests/mock_wrapper/mock_wrapper_pcf/config/task.conf +++ b/openfpga_flow/tasks/basic_tests/mock_wrapper/mock_wrapper_pcf/config/task.conf @@ -42,8 +42,8 @@ bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_df bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys bench0_top = counter -bench0_openfpga_mock_wrapper_pcf=${PATH:TASK_DIR}/config/pin_constraints_reset.xml -bench0_openfpga_mock_wrapper_bgf=${PATH:TASK_DIR}/config/counter8_bus_group.xml +bench0_openfpga_mock_wrapper_pcf=-pcf ${PATH:TASK_DIR}/config/pin_constraints_reset.xml +bench0_openfpga_mock_wrapper_bgf=-bgf ${PATH:TASK_DIR}/config/counter8_bus_group.xml [SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] end_flow_with_test=