From f9f7d42d930c45acf817bae6619689024e96dbce Mon Sep 17 00:00:00 2001 From: tangxifan Date: Wed, 10 Apr 2024 17:10:06 -0700 Subject: [PATCH] [core] add port side attribute and set them when buidling grid/cb/sb modules --- openfpga/src/base/openfpga_naming.cpp | 28 +++++++++++++++++++ openfpga/src/base/openfpga_naming.h | 3 ++ .../build_grid_module_duplicated_pins.cpp | 2 ++ openfpga/src/fabric/build_grid_modules.cpp | 2 ++ openfpga/src/fabric/build_routing_modules.cpp | 18 +++++++++++- openfpga/src/fabric/module_manager.cpp | 23 ++++----------- openfpga/src/fabric/module_manager.h | 13 ++++----- ...write_xml_fabric_pin_physical_location.cpp | 2 +- 8 files changed, 64 insertions(+), 27 deletions(-) diff --git a/openfpga/src/base/openfpga_naming.cpp b/openfpga/src/base/openfpga_naming.cpp index b80c3ba36..daae8ede0 100644 --- a/openfpga/src/base/openfpga_naming.cpp +++ b/openfpga/src/base/openfpga_naming.cpp @@ -413,6 +413,34 @@ std::string generate_sb_module_track_port_name(const t_rr_type& chan_type, return port_name; } +/********************************************************************* + * Get the physical side for a routing track in a Connection Block module + * Upper_location: specify if an upper/lower prefix to be added. + * The location indicates where the bus port should be + * placed on the perimeter of the connection block + * - For X-directional CB: + * - upper is the left side + * - lower is the right side + * - For Y-directional CB: + * - upper is the bottom side + * - lower is the top side + *********************************************************************/ +e_side get_cb_module_track_port_side(const t_rr_type& chan_type, + const bool& upper_location) { + /* Channel must be either CHANX or CHANY */ + VTR_ASSERT((CHANX == chan_type) || (CHANY == chan_type)); + + /* Create a map between chan_type and module_prefix */ + std::map> port_side_map; + /* TODO: use a constexpr string to replace the fixed name? */ + /* IMPORTANT: This part must be consistent with the mapping in the generate_cb_module_track_port_name() !!! */ + port_side_map[CHANX][true] = LEFT; + port_side_map[CHANX][false] = RIGHT; + port_side_map[CHANY][true] = BOTTOM; + port_side_map[CHANY][false] = TOP; + return port_side_map[chan_type][upper_location]; +} + /********************************************************************* * Generate the port name for a routing track in a Connection Block module * This function is created to ease the PnR for each unique routing module diff --git a/openfpga/src/base/openfpga_naming.h b/openfpga/src/base/openfpga_naming.h index 378a2836a..bbad6e510 100644 --- a/openfpga/src/base/openfpga_naming.h +++ b/openfpga/src/base/openfpga_naming.h @@ -97,6 +97,9 @@ std::string generate_sb_module_track_port_name(const t_rr_type& chan_type, const e_side& module_side, const PORTS& port_direction); +e_side get_cb_module_track_port_side(const t_rr_type& chan_type, + const bool& upper_location); + std::string generate_cb_module_track_port_name(const t_rr_type& chan_type, const PORTS& port_direction, const bool& upper_location); diff --git a/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp b/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp index cae215259..debc71b6e 100644 --- a/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp +++ b/openfpga/src/fabric/build_grid_module_duplicated_pins.cpp @@ -146,6 +146,8 @@ void add_grid_module_duplicated_pb_type_ports( module_manager.add_port(grid_module, grid_lower_port, pin_type2type_map[pin_class_type]); } + /* Set port side */ + module_manager.set_port_side(grid_module, grid_port, side); } } } diff --git a/openfpga/src/fabric/build_grid_modules.cpp b/openfpga/src/fabric/build_grid_modules.cpp index 94b9d884c..14e573367 100644 --- a/openfpga/src/fabric/build_grid_modules.cpp +++ b/openfpga/src/fabric/build_grid_modules.cpp @@ -105,6 +105,8 @@ static void add_grid_module_pb_type_ports( /* Add the port to the module */ module_manager.add_port(grid_module, grid_port, pin_type2type_map[pin_class_type]); + /* Set port side */ + module_manager.set_port_side(grid_module, grid_port, side); } } } diff --git a/openfpga/src/fabric/build_routing_modules.cpp b/openfpga/src/fabric/build_routing_modules.cpp index d552a611c..73363746e 100644 --- a/openfpga/src/fabric/build_routing_modules.cpp +++ b/openfpga/src/fabric/build_routing_modules.cpp @@ -435,6 +435,8 @@ static void build_switch_block_module( BasicPort chan_input_port(chan_input_port_name, chan_input_port_size); ModulePortId chan_input_port_id = module_manager.add_port( sb_module, chan_input_port, ModuleManager::MODULE_INPUT_PORT); + /* Add side to the port */ + module_manager.set_port_side(sb_module, chan_input_port_id, side_manager.get_side()) /* Cache the input net */ for (const size_t& pin : chan_input_port.pins()) { @@ -446,8 +448,10 @@ static void build_switch_block_module( std::string chan_output_port_name = generate_sb_module_track_port_name( chan_type, side_manager.get_side(), OUT_PORT); BasicPort chan_output_port(chan_output_port_name, chan_output_port_size); - module_manager.add_port(sb_module, chan_output_port, + ModulePortId chan_output_port_id = module_manager.add_port(sb_module, chan_output_port, ModuleManager::MODULE_OUTPUT_PORT); + /* Add side to the port */ + module_manager.set_port_side(sb_module, chan_output_port_id, side_manager.get_side()) } /* Dump OPINs of adjacent CLBs */ @@ -468,6 +472,8 @@ static void build_switch_block_module( /* Grid outputs are inputs of switch blocks */ ModulePortId input_port_id = module_manager.add_port( sb_module, module_port, ModuleManager::MODULE_INPUT_PORT); + /* Add side to the port */ + module_manager.set_port_side(sb_module, module_port, side_manager.get_side()) /* Cache the input net */ ModuleNetId net = create_module_source_pin_net( @@ -925,6 +931,8 @@ static void build_connection_block_module( rr_gsb.get_cb_chan_width(cb_type) / 2); ModulePortId chan_upper_input_port_id = module_manager.add_port( cb_module, chan_upper_input_port, ModuleManager::MODULE_INPUT_PORT); + /* Add side to the port */ + module_manager.set_port_side(cb_module, chan_upper_input_port_id, get_cb_module_track_port_side(cb_type, true)); /* Lower input port: W/2 == 1 tracks */ std::string chan_lower_input_port_name = @@ -933,6 +941,8 @@ static void build_connection_block_module( rr_gsb.get_cb_chan_width(cb_type) / 2); ModulePortId chan_lower_input_port_id = module_manager.add_port( cb_module, chan_lower_input_port, ModuleManager::MODULE_INPUT_PORT); + /* Add side to the port */ + module_manager.set_port_side(cb_module, chan_lower_input_port_id, get_cb_module_track_port_side(cb_type, false)); /* Upper output port: W/2 == 0 tracks */ std::string chan_upper_output_port_name = @@ -941,6 +951,8 @@ static void build_connection_block_module( rr_gsb.get_cb_chan_width(cb_type) / 2); ModulePortId chan_upper_output_port_id = module_manager.add_port( cb_module, chan_upper_output_port, ModuleManager::MODULE_OUTPUT_PORT); + /* Add side to the port */ + module_manager.set_port_side(cb_module, chan_upper_output_port_id, get_cb_module_track_port_side(cb_type, true)); /* Lower output port: W/2 == 1 tracks */ std::string chan_lower_output_port_name = @@ -949,6 +961,8 @@ static void build_connection_block_module( rr_gsb.get_cb_chan_width(cb_type) / 2); ModulePortId chan_lower_output_port_id = module_manager.add_port( cb_module, chan_lower_output_port, ModuleManager::MODULE_OUTPUT_PORT); + /* Add side to the port */ + module_manager.set_port_side(cb_module, chan_lower_output_port_id, get_cb_module_track_port_side(cb_type, false)); /* Add the input pins of grids, which are output ports of the connection block */ @@ -967,6 +981,8 @@ static void build_connection_block_module( /* Grid outputs are inputs of switch blocks */ module_manager.add_port(cb_module, module_port, ModuleManager::MODULE_OUTPUT_PORT); + /* Add side to the port */ + module_manager.set_port_side(cb_module, module_port, cb_ipin_side) } } diff --git a/openfpga/src/fabric/module_manager.cpp b/openfpga/src/fabric/module_manager.cpp index d1616e63d..86177c417 100644 --- a/openfpga/src/fabric/module_manager.cpp +++ b/openfpga/src/fabric/module_manager.cpp @@ -304,17 +304,10 @@ std::vector ModuleManager::module_ports_by_type( return ports; } -e_side ModuleManager::pin_side( - const ModuleId& module_id, const ModulePortId& port_id, const size_t& pin_id) const { +e_side ModuleManager::port_side( + const ModuleId& module_id, const ModulePortId& port_id) const { VTR_ASSERT(valid_module_port_id(module_id, port_id)); - BasicPort curr_port = module_manager.module_port(module_id, port_id); - BasicPort curr_pin(curr_port.get_name(), pin_id, pin_id); - /* Not a valid pin id, return invalid side */ - if (!curr_port.contained(curr_pin)) { - return NUM_SIDES; - } - /* Reach here, return a valid value */ - return port_sides_[module_id][port_id][pin_id] + return port_sides_[module_id][port_id] } /* Find a list of port ids of a module by a given types */ @@ -803,7 +796,7 @@ ModulePortId ModuleManager::add_port(const ModuleId& module, ports_[module].push_back(port_info); port_types_[module].push_back(port_type); /* Deposit invalid value for each side */ - port_sides_[module].push_back(std::vector(port_info.get_width(), NUM_SIDES)); + port_sides_[module].push_back(NUM_SIDES); port_is_wire_[module].push_back(false); port_is_mappable_io_[module].push_back(false); port_is_register_[module].push_back(false); @@ -911,18 +904,12 @@ void ModuleManager::set_port_preproc_flag(const ModuleId& module, /* Set the side for a pin of a port port */ void ModuleManager::set_pin_side(const ModuleId& module, const ModulePortId& port, - const size_t& pin, const e_side& pin_side) { /* Must find something, otherwise drop an error */ VTR_ASSERT(valid_module_port_id(module, port)); - if (pin > port_sides_[module][port].size() - 1) { - VTR_LOG_ERROR("Invalid pin '%ld' for module '%s' port '%s'!\n", pin, module_name(module).c_str(), module_port(module, port).to_verilog_string().c_str()); - VTR_ASSERT(pin < port_sides_[module][port].size()); - } - port_sides_[module][port][pin] = pin_side; + port_sides_[module][port] = pin_side; } - /* Add a child module to a parent module */ void ModuleManager::add_child_module(const ModuleId& parent_module, const ModuleId& child_module, diff --git a/openfpga/src/fabric/module_manager.h b/openfpga/src/fabric/module_manager.h index d9e3eceac..69b889e02 100644 --- a/openfpga/src/fabric/module_manager.h +++ b/openfpga/src/fabric/module_manager.h @@ -273,10 +273,9 @@ class ModuleManager { /* Find the type of a port */ ModuleManager::e_module_port_type port_type(const ModuleId& module, const ModulePortId& port) const; - /* Get the physical side of a pin of a port. Note that not every pin has a valid side. An invalid value NUM_SIDES will be returned when the pin does not has a specific physical location */ - e_side pin_side(const ModuleId& module, - const ModulePortId& port, - const size_t& pin_id) const; + /* Get the physical side of a port. Note that not every pin has a valid side. An invalid value NUM_SIDES will be returned when the pin does not has a specific physical location */ + e_side port_side(const ModuleId& module, + const ModulePortId& port) const; /* Find if a port is a wire connection */ bool port_is_wire(const ModuleId& module, const ModulePortId& port) const; /* Find if a port is mappable to an I/O from users' implementations */ @@ -374,8 +373,8 @@ class ModuleManager { void set_port_preproc_flag(const ModuleId& module, const ModulePortId& port, const std::string& preproc_flag); /* Set side to a given pin of a module port. Note that the pin id must be a valid one. Otherwise, abort and error out. The valid pin range can be get from module_port().pins() */ - void set_pin_side(const ModuleId& module, const ModulePortId& port, - const size_t& pin, const e_side& pin_side); + void set_port_side(const ModuleId& module, const ModulePortId& port, + const e_side& pin_side); /** @brief Add a child module to a parent module. * By default, it considers the child module as an I/O child, and update the * children list of I/O modules inside It not needed, just turn it off. Then @@ -633,7 +632,7 @@ class ModuleManager { ports_; /* List of ports for each Module */ vtr::vector> port_types_; /* Type of ports */ - vtr::vector>> + vtr::vector> port_sides_; /* Type of ports */ vtr::vector> port_is_mappable_io_; /* If the port is mappable to an I/O for user's diff --git a/openfpga/src/fabric/write_xml_fabric_pin_physical_location.cpp b/openfpga/src/fabric/write_xml_fabric_pin_physical_location.cpp index d8abd3ae4..f01951f24 100644 --- a/openfpga/src/fabric/write_xml_fabric_pin_physical_location.cpp +++ b/openfpga/src/fabric/write_xml_fabric_pin_physical_location.cpp @@ -63,10 +63,10 @@ static int write_xml_fabric_module_pin_phy_loc( for (ModulePortId curr_port_id : module_manager.module_ports(curr_module)) { BasicPort curr_port = module_manager.module_port(curr_module, curr_port_id); + SideManager side_mgr(module_manager.port_side(curr_module, curr_port_id)); for (int curr_pin_id : curr_port.pins()) { BasicPort curr_pin(curr_port.get_name(), curr_pin_id, curr_pin_id); std::string curr_port_str = generate_xml_port_name(curr_pin); - SideManager side_mgr(module_manager.pin_side(curr_module, curr_port_id, curr_pin_id)); write_tab_to_file(fp, 2); fp << "<" << XML_MODULE_PINLOC_NODE_NAME; write_xml_attribute(fp, XML_MODULE_PINLOC_ATTRIBUTE_PIN, curr_port_str.c_str());