Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Now clock/reset ports of all the subtiles can be merged in netlist #1377

Merged
merged 18 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion docs/source/manual/arch_lang/annotate_vpr_arch.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,37 @@ Here is an example:
.. code-block:: xml

<tile_annotations>
<merge_subtile_ports tile="<string>" port="<string>"/>
<global_port name="<string>" is_clock="<bool>" clock_arch_tree_name="<string>" is_reset="<bool>" is_set="<bool>" default_val="<int>">
<tile name="<string>" port="<string>" x="<int>" y="<int>"/>
...
</global_port>
</tile_annotations>

For subtile port merge support (see an illustrative example in :numref:`fig_subtile_port_merge`):

- ``tile="<string>"`` is the name of tile, that is defined in VPR architecture

- ``port="<string>"`` is the name of a port of the tile, that is defined in VPR architecture

.. warning:: This is an option for power users. Suggest to enable for those global input ports, such as clock and reset, whose ``Fc`` is set to 0 in VPR architecture!!!

.. note:: When defined, the given port of all the subtiles of a tile will be merged into one port. For example, a tile consists of 8 subtile ``A`` and 6 subtile ``B`` and all the subtiles have a port ``clk``, in the FPGA fabric, all the ``clk`` of the subtiles ``A`` and ``B`` will be wired to a common port ``clk`` at tile level.


.. note:: When merged, the port will have a default side of ``TOP`` and index of ``0`` on all the attributes, such as width, height etc.

.. _fig_subtile_port_merge:

.. figure:: ./figures/subtile_port_merge.png
:width: 100%
:alt: Difference in netlists with and without subtile port merging

Difference in netlists with and without subtile port merging


For global port support:

- ``name="<string>"`` is the port name to appear in the top-level FPGA fabric.

- ``is_clock="<bool>"`` define if the global port is a clock port at the top-level FPGA fabric. An operating clock port will be driven by proper signals in auto-generated testbenches.
Expand Down Expand Up @@ -111,7 +136,7 @@ A more illustrative example:
.. _fig_global_tile_ports:

.. figure:: ./figures/global_tile_ports.png
:scale: 100%
:width: 100%
:alt: Difference between global port definition through circuit model and tile annotation

Difference between global port definition through circuit model and tile annotation
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions libs/libarchopenfpga/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ set_target_properties(libarchopenfpga PROPERTIES PREFIX "") #Avoid extra 'lib' p
#Specify link-time dependancies
target_link_libraries(libarchopenfpga
libopenfpgautil
libopenfpgashell
libvtrutil
libarchfpga
libpugiutil)
Expand Down
30 changes: 26 additions & 4 deletions libs/libarchopenfpga/src/read_xml_tile_annotation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,22 @@ static void read_xml_tile_global_port_annotation(
}
}

/********************************************************************
* Parse XML description for an interconnection annotation
* under a <global_port> XML node
*******************************************************************/
static void read_xml_tile_merge_port_annotation(
pugi::xml_node& xml_tile, const pugiutil::loc_data& loc_data,
openfpga::TileAnnotation& tile_annotation) {
const std::string& tile_attr =
get_attribute(xml_tile, "tile", loc_data).as_string();

const std::string& port_attr =
get_attribute(xml_tile, "port", loc_data).as_string();

tile_annotation.add_merge_subtile_ports(tile_attr, port_attr);
}

/********************************************************************
* Top function to parse XML description about tile annotation
*******************************************************************/
Expand All @@ -146,11 +162,17 @@ openfpga::TileAnnotation read_xml_tile_annotations(
*/
for (pugi::xml_node xml_tile_global_port : xml_annotations.children()) {
/* Error out if the XML child has an invalid name! */
if (xml_tile_global_port.name() != std::string("global_port")) {
bad_tag(xml_tile_global_port, loc_data, xml_annotations, {"global_port"});
if (xml_tile_global_port.name() == std::string("global_port")) {
read_xml_tile_global_port_annotation(xml_tile_global_port, loc_data,
tile_annotations);
} else if (xml_tile_global_port.name() ==
std::string("merge_subtile_ports")) {
read_xml_tile_merge_port_annotation(xml_tile_global_port, loc_data,
tile_annotations);
} else {
bad_tag(xml_tile_global_port, loc_data, xml_annotations,
{"global_port or merge_subtile_ports"});
}
read_xml_tile_global_port_annotation(xml_tile_global_port, loc_data,
tile_annotations);
}

return tile_annotations;
Expand Down
56 changes: 56 additions & 0 deletions libs/libarchopenfpga/src/tile_annotation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
***********************************************************************/
#include "tile_annotation.h"

#include <algorithm>

#include "command_exit_codes.h"
#include "vtr_assert.h"
#include "vtr_log.h"

/* namespace openfpga begins */
namespace openfpga {
Expand All @@ -20,6 +24,27 @@ TileAnnotation::global_port_range TileAnnotation::global_ports() const {
return vtr::make_range(global_port_ids_.begin(), global_port_ids_.end());
}

std::vector<std::string> TileAnnotation::tiles_to_merge_ports() const {
std::vector<std::string> tile_names;
for (auto it = tile_ports_to_merge_.begin(); it != tile_ports_to_merge_.end();
it++) {
tile_names.push_back(it->first);
}
return tile_names;
}

std::vector<std::string> TileAnnotation::tile_ports_to_merge(
const std::string& tile_name) const {
std::vector<std::string> port_names;
const auto& result = tile_ports_to_merge_.find(tile_name);
if (result == tile_ports_to_merge_.end()) {
VTR_LOG_WARN("Tile '%s' does not contain any ports to merge!\n",
tile_name.c_str());
return port_names;
}
return result->second;
}

/************************************************************************
* Public Accessors
***********************************************************************/
Expand Down Expand Up @@ -77,6 +102,16 @@ std::string TileAnnotation::global_port_clock_arch_tree_name(
return global_port_clock_arch_tree_names_[global_port_id];
}

bool TileAnnotation::is_tile_port_to_merge(const std::string& tile_name,
const std::string& port_name) const {
const auto& result = tile_ports_to_merge_.find(tile_name);
if (result == tile_ports_to_merge_.end()) {
return false;
}
return result->second.end() !=
std::find(result->second.begin(), result->second.end(), port_name);
}

/************************************************************************
* Public Mutators
***********************************************************************/
Expand Down Expand Up @@ -178,4 +213,25 @@ bool TileAnnotation::valid_global_port_attributes(
return ((0 == attribute_counter) || (1 == attribute_counter));
}

int TileAnnotation::add_merge_subtile_ports(const std::string& tile_name,
const std::string& port_name) {
auto result = tile_ports_to_merge_.find(tile_name);
if (result == tile_ports_to_merge_.end()) {
/* Empty list: add a new element */
tile_ports_to_merge_[tile_name].push_back(port_name);
} else {
/* Check if the port name is already in the list, if yes, error out */
if (result->second.end() ==
std::find(result->second.begin(), result->second.end(), port_name)) {
tile_ports_to_merge_[tile_name].push_back(port_name);
} else {
VTR_LOG_ERROR(
"Port '%s' has already been defined twice for tile '%s' to be merged!",
port_name.c_str(), tile_name.c_str());
return CMD_EXEC_FATAL_ERROR;
}
}
return CMD_EXEC_SUCCESS;
}

} // namespace openfpga
14 changes: 14 additions & 0 deletions libs/libarchopenfpga/src/tile_annotation.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ class TileAnnotation {

public: /* Public accessors: aggregators */
global_port_range global_ports() const;
std::vector<std::string> tiles_to_merge_ports() const;
std::vector<std::string> tile_ports_to_merge(
const std::string& tile_name) const;

public: /* Public accessors */
std::string global_port_name(const TileGlobalPortId& global_port_id) const;
Expand All @@ -56,6 +59,10 @@ class TileAnnotation {
size_t global_port_default_value(
const TileGlobalPortId& global_port_id) const;

/** @brief Check if a given tile port should be merged or not */
bool is_tile_port_to_merge(const std::string& tile_name,
const std::string& port_name) const;

public: /* Public mutators */
/* By default, we do not set it as a clock.
* Users should set it through the set_global_port_is_clock() function
Expand All @@ -77,6 +84,9 @@ class TileAnnotation {
void set_global_port_default_value(const TileGlobalPortId& global_port_id,
const size_t& default_value);

int add_merge_subtile_ports(const std::string& tile_name,
const std::string& port_name);

public: /* Public validator */
bool valid_global_port_id(const TileGlobalPortId& global_port_id) const;
/* Validate attributes of a given global port
Expand All @@ -102,6 +112,10 @@ class TileAnnotation {

/* A fast lookup for port names */
std::map<std::string, TileGlobalPortId> global_port_name2ids_;

/* Merge port information for tiles */
std::map<std::string, std::vector<std::string>>
tile_ports_to_merge_; // tile_name -> port_name
};

} // namespace openfpga
Expand Down
25 changes: 25 additions & 0 deletions libs/libarchopenfpga/src/write_xml_tile_annotation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,24 @@ static void write_xml_tile_annotation_global_port(
<< "</global_port>";
}

/********************************************************************
* A writer to output a device variation in a technology library to XML format
*******************************************************************/
static void write_xml_tile_annotation_subtile_port_to_merge(
std::fstream& fp, const char* fname, const std::string& tile_name,
const std::string& port_name) {
/* Validate the file stream */
openfpga::check_file_stream(fname, fp);

fp << "\t\t"
<< "<merge_subtile_ports ";

write_xml_attribute(fp, "tile", tile_name.c_str());
write_xml_attribute(fp, "port", port_name.c_str());

fp << "/>";
}

/********************************************************************
* A writer to output tile annotations to XML format
*******************************************************************/
Expand All @@ -109,6 +127,13 @@ void write_xml_tile_annotations(std::fstream& fp, const char* fname,
write_xml_tile_annotation_global_port(fp, fname, tile_annotation,
global_port_id);
}
for (std::string tile_name : tile_annotation.tiles_to_merge_ports()) {
for (std::string port_name :
tile_annotation.tile_ports_to_merge(tile_name)) {
write_xml_tile_annotation_subtile_port_to_merge(fp, fname, tile_name,
port_name);
}
}

/* Write the root node for pb_type annotations */
fp << "\t"
Expand Down
2 changes: 1 addition & 1 deletion libs/libnamemanager/test/module_rename_assistant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ static std::vector<std::string> format_argv(const std::string& cmd_name,
* We want a renamed version for fabric B is
* <module_name default="tile_2__2_" given="tile_big"/>
*/
int rename_module_names_for_fabricB_from_fabricA(
static int rename_module_names_for_fabricB_from_fabricA(
const openfpga::ModuleNameMap& refA_module_names,
const openfpga::ModuleNameMap& renamedA_module_names,
const openfpga::ModuleNameMap& refB_module_names,
Expand Down
10 changes: 10 additions & 0 deletions openfpga/src/base/openfpga_build_fabric_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,16 @@ int build_fabric_template(T& openfpga_ctx, const Command& cmd,
return CMD_EXEC_FATAL_ERROR;
}
}
/* Conflicts: duplicate_grid_pin does not support any port merge */
if (cmd_context.option_enable(cmd, opt_duplicate_grid_pin)) {
if (openfpga_ctx.arch().tile_annotations.tiles_to_merge_ports().size() >
0) {
VTR_LOG_ERROR(
"Option '%s' requires no tile ports to be merged due to a conflict!\n",
cmd.option_name(opt_duplicate_grid_pin).c_str());
return CMD_EXEC_FATAL_ERROR;
}
}

if (true == cmd_context.option_enable(cmd, opt_compress_routing)) {
compress_routing_hierarchy_template<T>(
Expand Down
19 changes: 10 additions & 9 deletions openfpga/src/fabric/build_device_module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ int build_device_module_graph(
status = build_grid_modules(
module_manager, decoder_lib, vpr_device_ctx,
openfpga_ctx.vpr_device_annotation(), openfpga_ctx.arch().circuit_lib,
openfpga_ctx.mux_lib(), openfpga_ctx.arch().config_protocol.type(),
sram_model, duplicate_grid_pin, group_config_block, verbose);
openfpga_ctx.mux_lib(), openfpga_ctx.arch().tile_annotations,
openfpga_ctx.arch().config_protocol.type(), sram_model, duplicate_grid_pin,
group_config_block, verbose);
if (CMD_EXEC_FATAL_ERROR == status) {
return status;
}
Expand Down Expand Up @@ -120,13 +121,13 @@ int build_device_module_graph(
return status;
}
/* Build the modules */
build_tile_modules(module_manager, decoder_lib, openfpga_ctx.fabric_tile(),
vpr_device_ctx.grid,
openfpga_ctx.vpr_device_annotation(),
openfpga_ctx.device_rr_gsb(), vpr_device_ctx.rr_graph,
openfpga_ctx.arch().circuit_lib, sram_model,
openfpga_ctx.arch().config_protocol.type(),
name_module_using_index, frame_view, verbose);
build_tile_modules(
module_manager, decoder_lib, openfpga_ctx.fabric_tile(),
vpr_device_ctx.grid, openfpga_ctx.vpr_device_annotation(),
openfpga_ctx.device_rr_gsb(), vpr_device_ctx.rr_graph,
openfpga_ctx.arch().tile_annotations, openfpga_ctx.arch().circuit_lib,
sram_model, openfpga_ctx.arch().config_protocol.type(),
name_module_using_index, frame_view, verbose);
}

/* Build FPGA fabric top-level module */
Expand Down
25 changes: 19 additions & 6 deletions openfpga/src/fabric/build_grid_module_duplicated_pins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ namespace openfpga {
void add_grid_module_duplicated_pb_type_ports(
ModuleManager& module_manager, const ModuleId& grid_module,
const VprDeviceAnnotation& vpr_device_annotation,
t_physical_tile_type_ptr grid_type_descriptor, const e_side& border_side) {
t_physical_tile_type_ptr grid_type_descriptor,
const TileAnnotation& tile_annotation, const e_side& border_side) {
/* Ensure that we have a valid grid_type_descriptor */
VTR_ASSERT(false == is_empty_type(grid_type_descriptor));

Expand Down Expand Up @@ -109,6 +110,17 @@ void add_grid_module_duplicated_pb_type_ports(
(0. == find_physical_tile_pin_Fc(grid_type_descriptor, ipin)))) {
std::string port_name = generate_grid_port_name(
iwidth, iheight, subtile_index, side, pin_info);
/* If the port is required to be merged, we deposit zero as subtile
* index */
if (tile_annotation.is_tile_port_to_merge(
std::string(grid_type_descriptor->name),
pin_info.get_name())) {
if (subtile_index == 0) {
port_name = generate_grid_port_name(0, 0, 0, TOP, pin_info);
} else {
continue;
}
}
BasicPort grid_port(port_name, 0, 0);
/* Add the port to the module */
module_manager.add_port(grid_module, grid_port,
Expand Down Expand Up @@ -297,7 +309,8 @@ void add_grid_module_nets_connect_duplicated_pb_type_ports(
ModuleManager& module_manager, const ModuleId& grid_module,
const ModuleId& child_module, const size_t& child_instance,
const t_sub_tile& sub_tile, const VprDeviceAnnotation& vpr_device_annotation,
t_physical_tile_type_ptr grid_type_descriptor, const e_side& border_side) {
t_physical_tile_type_ptr grid_type_descriptor,
const TileAnnotation& tile_annotation, const e_side& border_side) {
/* Ensure that we have a valid grid_type_descriptor */
VTR_ASSERT(false == is_empty_type(grid_type_descriptor));

Expand All @@ -314,8 +327,8 @@ void add_grid_module_nets_connect_duplicated_pb_type_ports(
add_grid_module_net_connect_pb_graph_pin(
module_manager, grid_module, child_module, child_instance,
child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor,
&(top_pb_graph_node->input_pins[iport][ipin]), border_side,
INPUT2INPUT_INTERC);
tile_annotation, &(top_pb_graph_node->input_pins[iport][ipin]),
border_side, INPUT2INPUT_INTERC);
}
}

Expand All @@ -336,8 +349,8 @@ void add_grid_module_nets_connect_duplicated_pb_type_ports(
add_grid_module_net_connect_pb_graph_pin(
module_manager, grid_module, child_module, child_instance,
child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor,
&(top_pb_graph_node->clock_pins[iport][ipin]), border_side,
INPUT2INPUT_INTERC);
tile_annotation, &(top_pb_graph_node->clock_pins[iport][ipin]),
border_side, INPUT2INPUT_INTERC);
}
}
}
Expand Down
Loading
Loading