Merge pull request #1377 from lnis-uofu/xt_merge_tile_ports
Now clock/reset ports of all the subtiles can be merged in netlist
This commit is contained in:
commit
8928d45e46
|
@ -62,12 +62,37 @@ Here is an example:
|
||||||
.. code-block:: xml
|
.. code-block:: xml
|
||||||
|
|
||||||
<tile_annotations>
|
<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>">
|
<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>"/>
|
<tile name="<string>" port="<string>" x="<int>" y="<int>"/>
|
||||||
...
|
...
|
||||||
</global_port>
|
</global_port>
|
||||||
</tile_annotations>
|
</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.
|
- ``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.
|
- ``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.
|
||||||
|
@ -111,7 +136,7 @@ A more illustrative example:
|
||||||
.. _fig_global_tile_ports:
|
.. _fig_global_tile_ports:
|
||||||
|
|
||||||
.. figure:: ./figures/global_tile_ports.png
|
.. figure:: ./figures/global_tile_ports.png
|
||||||
:scale: 100%
|
:width: 100%
|
||||||
:alt: Difference between global port definition through circuit model and tile annotation
|
:alt: Difference between global port definition through circuit model and tile annotation
|
||||||
|
|
||||||
Difference between global port definition through circuit model and tile annotation
|
Difference between global port definition through circuit model and tile annotation
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 122 KiB |
|
@ -20,6 +20,7 @@ set_target_properties(libarchopenfpga PROPERTIES PREFIX "") #Avoid extra 'lib' p
|
||||||
#Specify link-time dependancies
|
#Specify link-time dependancies
|
||||||
target_link_libraries(libarchopenfpga
|
target_link_libraries(libarchopenfpga
|
||||||
libopenfpgautil
|
libopenfpgautil
|
||||||
|
libopenfpgashell
|
||||||
libvtrutil
|
libvtrutil
|
||||||
libarchfpga
|
libarchfpga
|
||||||
libpugiutil)
|
libpugiutil)
|
||||||
|
|
|
@ -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
|
* Top function to parse XML description about tile annotation
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
|
@ -146,11 +162,17 @@ openfpga::TileAnnotation read_xml_tile_annotations(
|
||||||
*/
|
*/
|
||||||
for (pugi::xml_node xml_tile_global_port : xml_annotations.children()) {
|
for (pugi::xml_node xml_tile_global_port : xml_annotations.children()) {
|
||||||
/* Error out if the XML child has an invalid name! */
|
/* Error out if the XML child has an invalid name! */
|
||||||
if (xml_tile_global_port.name() != std::string("global_port")) {
|
if (xml_tile_global_port.name() == std::string("global_port")) {
|
||||||
bad_tag(xml_tile_global_port, loc_data, xml_annotations, {"global_port"});
|
|
||||||
}
|
|
||||||
read_xml_tile_global_port_annotation(xml_tile_global_port, loc_data,
|
read_xml_tile_global_port_annotation(xml_tile_global_port, loc_data,
|
||||||
tile_annotations);
|
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"});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tile_annotations;
|
return tile_annotations;
|
||||||
|
|
|
@ -3,7 +3,11 @@
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
#include "tile_annotation.h"
|
#include "tile_annotation.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "command_exit_codes.h"
|
||||||
#include "vtr_assert.h"
|
#include "vtr_assert.h"
|
||||||
|
#include "vtr_log.h"
|
||||||
|
|
||||||
/* namespace openfpga begins */
|
/* namespace openfpga begins */
|
||||||
namespace openfpga {
|
namespace openfpga {
|
||||||
|
@ -20,6 +24,27 @@ TileAnnotation::global_port_range TileAnnotation::global_ports() const {
|
||||||
return vtr::make_range(global_port_ids_.begin(), global_port_ids_.end());
|
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
|
* Public Accessors
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
@ -77,6 +102,16 @@ std::string TileAnnotation::global_port_clock_arch_tree_name(
|
||||||
return global_port_clock_arch_tree_names_[global_port_id];
|
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
|
* Public Mutators
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
@ -178,4 +213,25 @@ bool TileAnnotation::valid_global_port_attributes(
|
||||||
return ((0 == attribute_counter) || (1 == attribute_counter));
|
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
|
} // namespace openfpga
|
||||||
|
|
|
@ -39,6 +39,9 @@ class TileAnnotation {
|
||||||
|
|
||||||
public: /* Public accessors: aggregators */
|
public: /* Public accessors: aggregators */
|
||||||
global_port_range global_ports() const;
|
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 */
|
public: /* Public accessors */
|
||||||
std::string global_port_name(const TileGlobalPortId& global_port_id) const;
|
std::string global_port_name(const TileGlobalPortId& global_port_id) const;
|
||||||
|
@ -56,6 +59,10 @@ class TileAnnotation {
|
||||||
size_t global_port_default_value(
|
size_t global_port_default_value(
|
||||||
const TileGlobalPortId& global_port_id) const;
|
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 */
|
public: /* Public mutators */
|
||||||
/* By default, we do not set it as a clock.
|
/* By default, we do not set it as a clock.
|
||||||
* Users should set it through the set_global_port_is_clock() function
|
* Users should set it through the set_global_port_is_clock() function
|
||||||
|
@ -77,6 +84,9 @@ class TileAnnotation {
|
||||||
void set_global_port_default_value(const TileGlobalPortId& global_port_id,
|
void set_global_port_default_value(const TileGlobalPortId& global_port_id,
|
||||||
const size_t& default_value);
|
const size_t& default_value);
|
||||||
|
|
||||||
|
int add_merge_subtile_ports(const std::string& tile_name,
|
||||||
|
const std::string& port_name);
|
||||||
|
|
||||||
public: /* Public validator */
|
public: /* Public validator */
|
||||||
bool valid_global_port_id(const TileGlobalPortId& global_port_id) const;
|
bool valid_global_port_id(const TileGlobalPortId& global_port_id) const;
|
||||||
/* Validate attributes of a given global port
|
/* Validate attributes of a given global port
|
||||||
|
@ -102,6 +112,10 @@ class TileAnnotation {
|
||||||
|
|
||||||
/* A fast lookup for port names */
|
/* A fast lookup for port names */
|
||||||
std::map<std::string, TileGlobalPortId> global_port_name2ids_;
|
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
|
} // namespace openfpga
|
||||||
|
|
|
@ -87,6 +87,24 @@ static void write_xml_tile_annotation_global_port(
|
||||||
<< "</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
|
* A writer to output tile annotations to XML format
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
|
@ -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,
|
write_xml_tile_annotation_global_port(fp, fname, tile_annotation,
|
||||||
global_port_id);
|
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 */
|
/* Write the root node for pb_type annotations */
|
||||||
fp << "\t"
|
fp << "\t"
|
||||||
|
|
|
@ -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
|
* We want a renamed version for fabric B is
|
||||||
* <module_name default="tile_2__2_" given="tile_big"/>
|
* <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& refA_module_names,
|
||||||
const openfpga::ModuleNameMap& renamedA_module_names,
|
const openfpga::ModuleNameMap& renamedA_module_names,
|
||||||
const openfpga::ModuleNameMap& refB_module_names,
|
const openfpga::ModuleNameMap& refB_module_names,
|
||||||
|
|
|
@ -130,6 +130,16 @@ int build_fabric_template(T& openfpga_ctx, const Command& cmd,
|
||||||
return CMD_EXEC_FATAL_ERROR;
|
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)) {
|
if (true == cmd_context.option_enable(cmd, opt_compress_routing)) {
|
||||||
compress_routing_hierarchy_template<T>(
|
compress_routing_hierarchy_template<T>(
|
||||||
|
|
|
@ -87,8 +87,9 @@ int build_device_module_graph(
|
||||||
status = build_grid_modules(
|
status = build_grid_modules(
|
||||||
module_manager, decoder_lib, vpr_device_ctx,
|
module_manager, decoder_lib, vpr_device_ctx,
|
||||||
openfpga_ctx.vpr_device_annotation(), openfpga_ctx.arch().circuit_lib,
|
openfpga_ctx.vpr_device_annotation(), openfpga_ctx.arch().circuit_lib,
|
||||||
openfpga_ctx.mux_lib(), openfpga_ctx.arch().config_protocol.type(),
|
openfpga_ctx.mux_lib(), openfpga_ctx.arch().tile_annotations,
|
||||||
sram_model, duplicate_grid_pin, group_config_block, verbose);
|
openfpga_ctx.arch().config_protocol.type(), sram_model, duplicate_grid_pin,
|
||||||
|
group_config_block, verbose);
|
||||||
if (CMD_EXEC_FATAL_ERROR == status) {
|
if (CMD_EXEC_FATAL_ERROR == status) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -120,12 +121,12 @@ int build_device_module_graph(
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
/* Build the modules */
|
/* Build the modules */
|
||||||
build_tile_modules(module_manager, decoder_lib, openfpga_ctx.fabric_tile(),
|
build_tile_modules(
|
||||||
vpr_device_ctx.grid,
|
module_manager, decoder_lib, openfpga_ctx.fabric_tile(),
|
||||||
openfpga_ctx.vpr_device_annotation(),
|
vpr_device_ctx.grid, openfpga_ctx.vpr_device_annotation(),
|
||||||
openfpga_ctx.device_rr_gsb(), vpr_device_ctx.rr_graph,
|
openfpga_ctx.device_rr_gsb(), vpr_device_ctx.rr_graph,
|
||||||
openfpga_ctx.arch().circuit_lib, sram_model,
|
openfpga_ctx.arch().tile_annotations, openfpga_ctx.arch().circuit_lib,
|
||||||
openfpga_ctx.arch().config_protocol.type(),
|
sram_model, openfpga_ctx.arch().config_protocol.type(),
|
||||||
name_module_using_index, frame_view, verbose);
|
name_module_using_index, frame_view, verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,8 @@ namespace openfpga {
|
||||||
void add_grid_module_duplicated_pb_type_ports(
|
void add_grid_module_duplicated_pb_type_ports(
|
||||||
ModuleManager& module_manager, const ModuleId& grid_module,
|
ModuleManager& module_manager, const ModuleId& grid_module,
|
||||||
const VprDeviceAnnotation& vpr_device_annotation,
|
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 */
|
/* Ensure that we have a valid grid_type_descriptor */
|
||||||
VTR_ASSERT(false == is_empty_type(grid_type_descriptor));
|
VTR_ASSERT(false == is_empty_type(grid_type_descriptor));
|
||||||
|
|
||||||
|
@ -109,6 +110,17 @@ void add_grid_module_duplicated_pb_type_ports(
|
||||||
(0. == find_physical_tile_pin_Fc(grid_type_descriptor, ipin)))) {
|
(0. == find_physical_tile_pin_Fc(grid_type_descriptor, ipin)))) {
|
||||||
std::string port_name = generate_grid_port_name(
|
std::string port_name = generate_grid_port_name(
|
||||||
iwidth, iheight, subtile_index, side, pin_info);
|
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);
|
BasicPort grid_port(port_name, 0, 0);
|
||||||
/* Add the port to the module */
|
/* Add the port to the module */
|
||||||
module_manager.add_port(grid_module, grid_port,
|
module_manager.add_port(grid_module, grid_port,
|
||||||
|
@ -297,7 +309,8 @@ void add_grid_module_nets_connect_duplicated_pb_type_ports(
|
||||||
ModuleManager& module_manager, const ModuleId& grid_module,
|
ModuleManager& module_manager, const ModuleId& grid_module,
|
||||||
const ModuleId& child_module, const size_t& child_instance,
|
const ModuleId& child_module, const size_t& child_instance,
|
||||||
const t_sub_tile& sub_tile, const VprDeviceAnnotation& vpr_device_annotation,
|
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 */
|
/* Ensure that we have a valid grid_type_descriptor */
|
||||||
VTR_ASSERT(false == is_empty_type(grid_type_descriptor));
|
VTR_ASSERT(false == is_empty_type(grid_type_descriptor));
|
||||||
|
|
||||||
|
@ -314,8 +327,8 @@ void add_grid_module_nets_connect_duplicated_pb_type_ports(
|
||||||
add_grid_module_net_connect_pb_graph_pin(
|
add_grid_module_net_connect_pb_graph_pin(
|
||||||
module_manager, grid_module, child_module, child_instance,
|
module_manager, grid_module, child_module, child_instance,
|
||||||
child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor,
|
child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor,
|
||||||
&(top_pb_graph_node->input_pins[iport][ipin]), border_side,
|
tile_annotation, &(top_pb_graph_node->input_pins[iport][ipin]),
|
||||||
INPUT2INPUT_INTERC);
|
border_side, INPUT2INPUT_INTERC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,8 +349,8 @@ void add_grid_module_nets_connect_duplicated_pb_type_ports(
|
||||||
add_grid_module_net_connect_pb_graph_pin(
|
add_grid_module_net_connect_pb_graph_pin(
|
||||||
module_manager, grid_module, child_module, child_instance,
|
module_manager, grid_module, child_module, child_instance,
|
||||||
child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor,
|
child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor,
|
||||||
&(top_pb_graph_node->clock_pins[iport][ipin]), border_side,
|
tile_annotation, &(top_pb_graph_node->clock_pins[iport][ipin]),
|
||||||
INPUT2INPUT_INTERC);
|
border_side, INPUT2INPUT_INTERC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "module_manager.h"
|
#include "module_manager.h"
|
||||||
#include "openfpga_side_manager.h"
|
#include "openfpga_side_manager.h"
|
||||||
#include "physical_types.h"
|
#include "physical_types.h"
|
||||||
|
#include "tile_annotation.h"
|
||||||
#include "vpr_device_annotation.h"
|
#include "vpr_device_annotation.h"
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
@ -19,13 +20,15 @@ namespace openfpga {
|
||||||
void add_grid_module_duplicated_pb_type_ports(
|
void add_grid_module_duplicated_pb_type_ports(
|
||||||
ModuleManager& module_manager, const ModuleId& grid_module,
|
ModuleManager& module_manager, const ModuleId& grid_module,
|
||||||
const VprDeviceAnnotation& vpr_device_annotation,
|
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);
|
||||||
|
|
||||||
void add_grid_module_nets_connect_duplicated_pb_type_ports(
|
void add_grid_module_nets_connect_duplicated_pb_type_ports(
|
||||||
ModuleManager& module_manager, const ModuleId& grid_module,
|
ModuleManager& module_manager, const ModuleId& grid_module,
|
||||||
const ModuleId& child_module, const size_t& child_instance,
|
const ModuleId& child_module, const size_t& child_instance,
|
||||||
const t_sub_tile& sub_tile, const VprDeviceAnnotation& vpr_device_annotation,
|
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);
|
||||||
|
|
||||||
} /* end namespace openfpga */
|
} /* end namespace openfpga */
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,8 @@ void add_grid_module_net_connect_pb_graph_pin(
|
||||||
const ModuleId& child_module, const size_t& child_instance,
|
const ModuleId& child_module, const size_t& child_instance,
|
||||||
const size_t& child_inst_subtile_index,
|
const size_t& child_inst_subtile_index,
|
||||||
const VprDeviceAnnotation& vpr_device_annotation,
|
const VprDeviceAnnotation& vpr_device_annotation,
|
||||||
t_physical_tile_type_ptr grid_type_descriptor, t_pb_graph_pin* pb_graph_pin,
|
t_physical_tile_type_ptr grid_type_descriptor,
|
||||||
|
const TileAnnotation& tile_annotation, t_pb_graph_pin* pb_graph_pin,
|
||||||
const e_side& border_side, const e_pin2pin_interc_type& pin2pin_interc_type) {
|
const e_side& border_side, const e_pin2pin_interc_type& pin2pin_interc_type) {
|
||||||
/* Find the pin side for I/O grids*/
|
/* Find the pin side for I/O grids*/
|
||||||
std::vector<e_side> grid_pin_sides;
|
std::vector<e_side> grid_pin_sides;
|
||||||
|
@ -91,6 +92,13 @@ void add_grid_module_net_connect_pb_graph_pin(
|
||||||
subtile_index < grid_type_descriptor->capacity);
|
subtile_index < grid_type_descriptor->capacity);
|
||||||
std::string grid_port_name = generate_grid_port_name(
|
std::string grid_port_name = generate_grid_port_name(
|
||||||
pin_width, pin_height, subtile_index, side, pin_info);
|
pin_width, pin_height, subtile_index, side, pin_info);
|
||||||
|
/* If the port is required to be merged, we only consider the source port to
|
||||||
|
* be the subtile index of 0 */
|
||||||
|
if (tile_annotation.is_tile_port_to_merge(
|
||||||
|
std::string(grid_type_descriptor->name), pin_info.get_name())) {
|
||||||
|
/* Exception: use top side for these merged ports */
|
||||||
|
grid_port_name = generate_grid_port_name(0, 0, 0, TOP, pin_info);
|
||||||
|
}
|
||||||
ModulePortId grid_module_port_id =
|
ModulePortId grid_module_port_id =
|
||||||
module_manager.find_module_port(grid_module, grid_port_name);
|
module_manager.find_module_port(grid_module, grid_port_name);
|
||||||
VTR_ASSERT(true == module_manager.valid_module_port_id(
|
VTR_ASSERT(true == module_manager.valid_module_port_id(
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "module_manager.h"
|
#include "module_manager.h"
|
||||||
#include "openfpga_interconnect_types.h"
|
#include "openfpga_interconnect_types.h"
|
||||||
#include "physical_types.h"
|
#include "physical_types.h"
|
||||||
|
#include "tile_annotation.h"
|
||||||
#include "vpr_device_annotation.h"
|
#include "vpr_device_annotation.h"
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
@ -25,7 +26,8 @@ void add_grid_module_net_connect_pb_graph_pin(
|
||||||
const ModuleId& child_module, const size_t& child_instance,
|
const ModuleId& child_module, const size_t& child_instance,
|
||||||
const size_t& child_inst_subtile_index,
|
const size_t& child_inst_subtile_index,
|
||||||
const VprDeviceAnnotation& vpr_device_annotation,
|
const VprDeviceAnnotation& vpr_device_annotation,
|
||||||
t_physical_tile_type_ptr grid_type_descriptor, t_pb_graph_pin* pb_graph_pin,
|
t_physical_tile_type_ptr grid_type_descriptor,
|
||||||
|
const TileAnnotation& tile_annotation, t_pb_graph_pin* pb_graph_pin,
|
||||||
const e_side& border_side,
|
const e_side& border_side,
|
||||||
const enum e_pin2pin_interc_type& pin2pin_interc_type);
|
const enum e_pin2pin_interc_type& pin2pin_interc_type);
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,8 @@ namespace openfpga {
|
||||||
static void add_grid_module_pb_type_ports(
|
static void add_grid_module_pb_type_ports(
|
||||||
ModuleManager& module_manager, const ModuleId& grid_module,
|
ModuleManager& module_manager, const ModuleId& grid_module,
|
||||||
const VprDeviceAnnotation& vpr_device_annotation,
|
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 */
|
/* Ensure that we have a valid grid_type_descriptor */
|
||||||
VTR_ASSERT(nullptr != grid_type_descriptor);
|
VTR_ASSERT(nullptr != grid_type_descriptor);
|
||||||
|
|
||||||
|
@ -90,6 +91,16 @@ static void add_grid_module_pb_type_ports(
|
||||||
subtile_index < grid_type_descriptor->capacity);
|
subtile_index < grid_type_descriptor->capacity);
|
||||||
std::string port_name = generate_grid_port_name(
|
std::string port_name = generate_grid_port_name(
|
||||||
iwidth, iheight, subtile_index, side, pin_info);
|
iwidth, iheight, subtile_index, side, pin_info);
|
||||||
|
/* If the port is required to be merged, we use a special index
|
||||||
|
* 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);
|
BasicPort grid_port(port_name, 0, 0);
|
||||||
/* Add the port to the module */
|
/* Add the port to the module */
|
||||||
module_manager.add_port(grid_module, grid_port,
|
module_manager.add_port(grid_module, grid_port,
|
||||||
|
@ -111,7 +122,8 @@ static void add_grid_module_nets_connect_pb_type_ports(
|
||||||
ModuleManager& module_manager, const ModuleId& grid_module,
|
ModuleManager& module_manager, const ModuleId& grid_module,
|
||||||
const ModuleId& child_module, const size_t& child_instance,
|
const ModuleId& child_module, const size_t& child_instance,
|
||||||
const t_sub_tile& sub_tile, const VprDeviceAnnotation& vpr_device_annotation,
|
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 */
|
/* Ensure that we have a valid grid_type_descriptor */
|
||||||
VTR_ASSERT(nullptr != grid_type_descriptor);
|
VTR_ASSERT(nullptr != grid_type_descriptor);
|
||||||
|
|
||||||
|
@ -129,8 +141,8 @@ static void add_grid_module_nets_connect_pb_type_ports(
|
||||||
add_grid_module_net_connect_pb_graph_pin(
|
add_grid_module_net_connect_pb_graph_pin(
|
||||||
module_manager, grid_module, child_module, child_instance,
|
module_manager, grid_module, child_module, child_instance,
|
||||||
child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor,
|
child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor,
|
||||||
&(top_pb_graph_node->input_pins[iport][ipin]), border_side,
|
tile_annotation, &(top_pb_graph_node->input_pins[iport][ipin]),
|
||||||
INPUT2INPUT_INTERC);
|
border_side, INPUT2INPUT_INTERC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,8 +152,8 @@ static void add_grid_module_nets_connect_pb_type_ports(
|
||||||
add_grid_module_net_connect_pb_graph_pin(
|
add_grid_module_net_connect_pb_graph_pin(
|
||||||
module_manager, grid_module, child_module, child_instance,
|
module_manager, grid_module, child_module, child_instance,
|
||||||
child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor,
|
child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor,
|
||||||
&(top_pb_graph_node->output_pins[iport][ipin]), border_side,
|
tile_annotation, &(top_pb_graph_node->output_pins[iport][ipin]),
|
||||||
OUTPUT2OUTPUT_INTERC);
|
border_side, OUTPUT2OUTPUT_INTERC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,8 +163,8 @@ static void add_grid_module_nets_connect_pb_type_ports(
|
||||||
add_grid_module_net_connect_pb_graph_pin(
|
add_grid_module_net_connect_pb_graph_pin(
|
||||||
module_manager, grid_module, child_module, child_instance,
|
module_manager, grid_module, child_module, child_instance,
|
||||||
child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor,
|
child_inst_subtile_index, vpr_device_annotation, grid_type_descriptor,
|
||||||
&(top_pb_graph_node->clock_pins[iport][ipin]), border_side,
|
tile_annotation, &(top_pb_graph_node->clock_pins[iport][ipin]),
|
||||||
INPUT2INPUT_INTERC);
|
border_side, INPUT2INPUT_INTERC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1151,8 +1163,9 @@ static int build_physical_tile_module(
|
||||||
const CircuitLibrary& circuit_lib,
|
const CircuitLibrary& circuit_lib,
|
||||||
const e_config_protocol_type& sram_orgz_type,
|
const e_config_protocol_type& sram_orgz_type,
|
||||||
const CircuitModelId& sram_model, t_physical_tile_type_ptr phy_block_type,
|
const CircuitModelId& sram_model, t_physical_tile_type_ptr phy_block_type,
|
||||||
const e_side& border_side, const bool& duplicate_grid_pin,
|
const TileAnnotation& tile_annotation, const e_side& border_side,
|
||||||
const bool& group_config_block, const bool& verbose) {
|
const bool& duplicate_grid_pin, const bool& group_config_block,
|
||||||
|
const bool& verbose) {
|
||||||
int status = CMD_EXEC_SUCCESS;
|
int status = CMD_EXEC_SUCCESS;
|
||||||
/* Create a Module for the top-level physical block, and add to module manager
|
/* Create a Module for the top-level physical block, and add to module manager
|
||||||
*/
|
*/
|
||||||
|
@ -1231,7 +1244,7 @@ static int build_physical_tile_module(
|
||||||
/* Default way to add these ports by following the definition in pb_types */
|
/* Default way to add these ports by following the definition in pb_types */
|
||||||
add_grid_module_pb_type_ports(module_manager, grid_module,
|
add_grid_module_pb_type_ports(module_manager, grid_module,
|
||||||
vpr_device_annotation, phy_block_type,
|
vpr_device_annotation, phy_block_type,
|
||||||
border_side);
|
tile_annotation, border_side);
|
||||||
/* Add module nets to connect the pb_type ports to sub modules */
|
/* Add module nets to connect the pb_type ports to sub modules */
|
||||||
for (const t_sub_tile& sub_tile : phy_block_type->sub_tiles) {
|
for (const t_sub_tile& sub_tile : phy_block_type->sub_tiles) {
|
||||||
VTR_ASSERT(sub_tile.equivalent_sites.size() == 1);
|
VTR_ASSERT(sub_tile.equivalent_sites.size() == 1);
|
||||||
|
@ -1248,15 +1261,15 @@ static int build_physical_tile_module(
|
||||||
module_manager.child_module_instances(grid_module, pb_module)) {
|
module_manager.child_module_instances(grid_module, pb_module)) {
|
||||||
add_grid_module_nets_connect_pb_type_ports(
|
add_grid_module_nets_connect_pb_type_ports(
|
||||||
module_manager, grid_module, pb_module, child_instance, sub_tile,
|
module_manager, grid_module, pb_module, child_instance, sub_tile,
|
||||||
vpr_device_annotation, phy_block_type, border_side);
|
vpr_device_annotation, phy_block_type, tile_annotation, border_side);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
VTR_ASSERT_SAFE(true == duplicate_grid_pin);
|
VTR_ASSERT_SAFE(true == duplicate_grid_pin);
|
||||||
/* Add these ports with duplication */
|
/* Add these ports with duplication */
|
||||||
add_grid_module_duplicated_pb_type_ports(module_manager, grid_module,
|
add_grid_module_duplicated_pb_type_ports(
|
||||||
vpr_device_annotation,
|
module_manager, grid_module, vpr_device_annotation, phy_block_type,
|
||||||
phy_block_type, border_side);
|
tile_annotation, border_side);
|
||||||
|
|
||||||
/* Add module nets to connect the duplicated pb_type ports to sub modules */
|
/* Add module nets to connect the duplicated pb_type ports to sub modules */
|
||||||
for (const t_sub_tile& sub_tile : phy_block_type->sub_tiles) {
|
for (const t_sub_tile& sub_tile : phy_block_type->sub_tiles) {
|
||||||
|
@ -1274,7 +1287,7 @@ static int build_physical_tile_module(
|
||||||
module_manager.child_module_instances(grid_module, pb_module)) {
|
module_manager.child_module_instances(grid_module, pb_module)) {
|
||||||
add_grid_module_nets_connect_duplicated_pb_type_ports(
|
add_grid_module_nets_connect_duplicated_pb_type_ports(
|
||||||
module_manager, grid_module, pb_module, child_instance, sub_tile,
|
module_manager, grid_module, pb_module, child_instance, sub_tile,
|
||||||
vpr_device_annotation, phy_block_type, border_side);
|
vpr_device_annotation, phy_block_type, tile_annotation, border_side);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1357,6 +1370,7 @@ int build_grid_modules(
|
||||||
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
|
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
|
||||||
const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation,
|
const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation,
|
||||||
const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib,
|
const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib,
|
||||||
|
const TileAnnotation& tile_annotation,
|
||||||
const e_config_protocol_type& sram_orgz_type,
|
const e_config_protocol_type& sram_orgz_type,
|
||||||
const CircuitModelId& sram_model, const bool& duplicate_grid_pin,
|
const CircuitModelId& sram_model, const bool& duplicate_grid_pin,
|
||||||
const bool& group_config_block, const bool& verbose) {
|
const bool& group_config_block, const bool& verbose) {
|
||||||
|
@ -1414,8 +1428,8 @@ int build_grid_modules(
|
||||||
for (const e_side& io_type_side : io_type_sides) {
|
for (const e_side& io_type_side : io_type_sides) {
|
||||||
status = build_physical_tile_module(
|
status = build_physical_tile_module(
|
||||||
module_manager, decoder_lib, device_annotation, circuit_lib,
|
module_manager, decoder_lib, device_annotation, circuit_lib,
|
||||||
sram_orgz_type, sram_model, &physical_tile, io_type_side,
|
sram_orgz_type, sram_model, &physical_tile, tile_annotation,
|
||||||
duplicate_grid_pin, group_config_block, verbose);
|
io_type_side, duplicate_grid_pin, group_config_block, verbose);
|
||||||
if (status != CMD_EXEC_SUCCESS) {
|
if (status != CMD_EXEC_SUCCESS) {
|
||||||
return CMD_EXEC_FATAL_ERROR;
|
return CMD_EXEC_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -1424,7 +1438,7 @@ int build_grid_modules(
|
||||||
/* For CLB and heterogenenous blocks */
|
/* For CLB and heterogenenous blocks */
|
||||||
status = build_physical_tile_module(
|
status = build_physical_tile_module(
|
||||||
module_manager, decoder_lib, device_annotation, circuit_lib,
|
module_manager, decoder_lib, device_annotation, circuit_lib,
|
||||||
sram_orgz_type, sram_model, &physical_tile, NUM_SIDES,
|
sram_orgz_type, sram_model, &physical_tile, tile_annotation, NUM_SIDES,
|
||||||
duplicate_grid_pin, group_config_block, verbose);
|
duplicate_grid_pin, group_config_block, verbose);
|
||||||
if (status != CMD_EXEC_SUCCESS) {
|
if (status != CMD_EXEC_SUCCESS) {
|
||||||
return CMD_EXEC_FATAL_ERROR;
|
return CMD_EXEC_FATAL_ERROR;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "decoder_library.h"
|
#include "decoder_library.h"
|
||||||
#include "module_manager.h"
|
#include "module_manager.h"
|
||||||
#include "mux_library.h"
|
#include "mux_library.h"
|
||||||
|
#include "tile_annotation.h"
|
||||||
#include "vpr_context.h"
|
#include "vpr_context.h"
|
||||||
#include "vpr_device_annotation.h"
|
#include "vpr_device_annotation.h"
|
||||||
|
|
||||||
|
@ -21,6 +22,7 @@ int build_grid_modules(
|
||||||
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
|
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
|
||||||
const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation,
|
const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation,
|
||||||
const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib,
|
const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib,
|
||||||
|
const TileAnnotation& tile_annotation,
|
||||||
const e_config_protocol_type& sram_orgz_type,
|
const e_config_protocol_type& sram_orgz_type,
|
||||||
const CircuitModelId& sram_model, const bool& duplicate_grid_pin,
|
const CircuitModelId& sram_model, const bool& duplicate_grid_pin,
|
||||||
const bool& group_config_block, const bool& verbose);
|
const bool& group_config_block, const bool& verbose);
|
||||||
|
|
|
@ -1004,9 +1004,10 @@ static int build_tile_port_and_nets_from_pb(
|
||||||
ModuleManager& module_manager, const ModuleId& tile_module,
|
ModuleManager& module_manager, const ModuleId& tile_module,
|
||||||
const DeviceGrid& grids, const size_t& layer,
|
const DeviceGrid& grids, const size_t& layer,
|
||||||
const VprDeviceAnnotation& vpr_device_annotation, const RRGraphView& rr_graph,
|
const VprDeviceAnnotation& vpr_device_annotation, const RRGraphView& rr_graph,
|
||||||
const vtr::Point<size_t>& pb_coord, const std::vector<size_t>& pb_instances,
|
const TileAnnotation& tile_annotation, const vtr::Point<size_t>& pb_coord,
|
||||||
const FabricTile& fabric_tile, const FabricTileId& curr_fabric_tile_id,
|
const std::vector<size_t>& pb_instances, const FabricTile& fabric_tile,
|
||||||
const size_t& ipb, const bool& frame_view, const bool& verbose) {
|
const FabricTileId& curr_fabric_tile_id, const size_t& ipb,
|
||||||
|
const bool& frame_view, const bool& verbose) {
|
||||||
size_t pb_instance = pb_instances[ipb];
|
size_t pb_instance = pb_instances[ipb];
|
||||||
t_physical_tile_type_ptr phy_tile = grids.get_physical_type(
|
t_physical_tile_type_ptr phy_tile = grids.get_physical_type(
|
||||||
t_physical_tile_loc(pb_coord.x(), pb_coord.y(), layer));
|
t_physical_tile_loc(pb_coord.x(), pb_coord.y(), layer));
|
||||||
|
@ -1065,6 +1066,14 @@ static int build_tile_port_and_nets_from_pb(
|
||||||
subtile_index < phy_tile->capacity);
|
subtile_index < phy_tile->capacity);
|
||||||
std::string port_name = generate_grid_port_name(
|
std::string port_name = generate_grid_port_name(
|
||||||
iwidth, iheight, subtile_index, side, pin_info);
|
iwidth, iheight, subtile_index, side, pin_info);
|
||||||
|
if (tile_annotation.is_tile_port_to_merge(std::string(phy_tile->name),
|
||||||
|
pin_info.get_name())) {
|
||||||
|
if (subtile_index == 0) {
|
||||||
|
port_name = generate_grid_port_name(0, 0, 0, TOP, pin_info);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
BasicPort pb_port(port_name, 0, 0);
|
BasicPort pb_port(port_name, 0, 0);
|
||||||
ModulePortId pb_module_port_id =
|
ModulePortId pb_module_port_id =
|
||||||
module_manager.find_module_port(pb_module, port_name);
|
module_manager.find_module_port(pb_module, port_name);
|
||||||
|
@ -1193,8 +1202,8 @@ static int build_tile_module_ports_and_nets(
|
||||||
const DeviceGrid& grids, const size_t& layer,
|
const DeviceGrid& grids, const size_t& layer,
|
||||||
const VprDeviceAnnotation& vpr_device_annotation,
|
const VprDeviceAnnotation& vpr_device_annotation,
|
||||||
const DeviceRRGSB& device_rr_gsb, const RRGraphView& rr_graph_view,
|
const DeviceRRGSB& device_rr_gsb, const RRGraphView& rr_graph_view,
|
||||||
const FabricTile& fabric_tile, const FabricTileId& fabric_tile_id,
|
const TileAnnotation& tile_annotation, const FabricTile& fabric_tile,
|
||||||
const std::vector<size_t>& pb_instances,
|
const FabricTileId& fabric_tile_id, const std::vector<size_t>& pb_instances,
|
||||||
const std::map<t_rr_type, std::vector<size_t>>& cb_instances,
|
const std::map<t_rr_type, std::vector<size_t>>& cb_instances,
|
||||||
const std::vector<size_t>& sb_instances, const bool& name_module_using_index,
|
const std::vector<size_t>& sb_instances, const bool& name_module_using_index,
|
||||||
const bool& frame_view, const bool& verbose) {
|
const bool& frame_view, const bool& verbose) {
|
||||||
|
@ -1259,8 +1268,8 @@ static int build_tile_module_ports_and_nets(
|
||||||
fabric_tile.pb_coordinates(fabric_tile_id)[ipb];
|
fabric_tile.pb_coordinates(fabric_tile_id)[ipb];
|
||||||
status_code = build_tile_port_and_nets_from_pb(
|
status_code = build_tile_port_and_nets_from_pb(
|
||||||
module_manager, tile_module, grids, layer, vpr_device_annotation,
|
module_manager, tile_module, grids, layer, vpr_device_annotation,
|
||||||
rr_graph_view, pb_coord, pb_instances, fabric_tile, fabric_tile_id, ipb,
|
rr_graph_view, tile_annotation, pb_coord, pb_instances, fabric_tile,
|
||||||
frame_view, verbose);
|
fabric_tile_id, ipb, frame_view, verbose);
|
||||||
if (status_code != CMD_EXEC_SUCCESS) {
|
if (status_code != CMD_EXEC_SUCCESS) {
|
||||||
return CMD_EXEC_FATAL_ERROR;
|
return CMD_EXEC_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -1303,7 +1312,8 @@ static int build_tile_module(
|
||||||
const DeviceGrid& grids, const size_t& layer,
|
const DeviceGrid& grids, const size_t& layer,
|
||||||
const VprDeviceAnnotation& vpr_device_annotation,
|
const VprDeviceAnnotation& vpr_device_annotation,
|
||||||
const DeviceRRGSB& device_rr_gsb, const RRGraphView& rr_graph_view,
|
const DeviceRRGSB& device_rr_gsb, const RRGraphView& rr_graph_view,
|
||||||
const CircuitLibrary& circuit_lib, const CircuitModelId& sram_model,
|
const TileAnnotation& tile_annotation, const CircuitLibrary& circuit_lib,
|
||||||
|
const CircuitModelId& sram_model,
|
||||||
const e_config_protocol_type& sram_orgz_type,
|
const e_config_protocol_type& sram_orgz_type,
|
||||||
const bool& name_module_using_index, const bool& frame_view,
|
const bool& name_module_using_index, const bool& frame_view,
|
||||||
const bool& verbose) {
|
const bool& verbose) {
|
||||||
|
@ -1451,8 +1461,9 @@ static int build_tile_module(
|
||||||
/* Add module nets and ports */
|
/* Add module nets and ports */
|
||||||
status_code = build_tile_module_ports_and_nets(
|
status_code = build_tile_module_ports_and_nets(
|
||||||
module_manager, tile_module, grids, layer, vpr_device_annotation,
|
module_manager, tile_module, grids, layer, vpr_device_annotation,
|
||||||
device_rr_gsb, rr_graph_view, fabric_tile, fabric_tile_id, pb_instances,
|
device_rr_gsb, rr_graph_view, tile_annotation, fabric_tile, fabric_tile_id,
|
||||||
cb_instances, sb_instances, name_module_using_index, frame_view, verbose);
|
pb_instances, cb_instances, sb_instances, name_module_using_index,
|
||||||
|
frame_view, verbose);
|
||||||
|
|
||||||
/* Add global ports to the pb_module:
|
/* Add global ports to the pb_module:
|
||||||
* This is a much easier job after adding sub modules (instances),
|
* This is a much easier job after adding sub modules (instances),
|
||||||
|
@ -1521,6 +1532,7 @@ int build_tile_modules(ModuleManager& module_manager,
|
||||||
const VprDeviceAnnotation& vpr_device_annotation,
|
const VprDeviceAnnotation& vpr_device_annotation,
|
||||||
const DeviceRRGSB& device_rr_gsb,
|
const DeviceRRGSB& device_rr_gsb,
|
||||||
const RRGraphView& rr_graph_view,
|
const RRGraphView& rr_graph_view,
|
||||||
|
const TileAnnotation& tile_annotation,
|
||||||
const CircuitLibrary& circuit_lib,
|
const CircuitLibrary& circuit_lib,
|
||||||
const CircuitModelId& sram_model,
|
const CircuitModelId& sram_model,
|
||||||
const e_config_protocol_type& sram_orgz_type,
|
const e_config_protocol_type& sram_orgz_type,
|
||||||
|
@ -1536,8 +1548,9 @@ int build_tile_modules(ModuleManager& module_manager,
|
||||||
for (FabricTileId fabric_tile_id : fabric_tile.unique_tiles()) {
|
for (FabricTileId fabric_tile_id : fabric_tile.unique_tiles()) {
|
||||||
status_code = build_tile_module(
|
status_code = build_tile_module(
|
||||||
module_manager, decoder_lib, fabric_tile, fabric_tile_id, grids, layer,
|
module_manager, decoder_lib, fabric_tile, fabric_tile_id, grids, layer,
|
||||||
vpr_device_annotation, device_rr_gsb, rr_graph_view, circuit_lib,
|
vpr_device_annotation, device_rr_gsb, rr_graph_view, tile_annotation,
|
||||||
sram_model, sram_orgz_type, name_module_using_index, frame_view, verbose);
|
circuit_lib, sram_model, sram_orgz_type, name_module_using_index,
|
||||||
|
frame_view, verbose);
|
||||||
if (status_code != CMD_EXEC_SUCCESS) {
|
if (status_code != CMD_EXEC_SUCCESS) {
|
||||||
return CMD_EXEC_FATAL_ERROR;
|
return CMD_EXEC_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "fabric_tile.h"
|
#include "fabric_tile.h"
|
||||||
#include "module_manager.h"
|
#include "module_manager.h"
|
||||||
#include "rr_graph_view.h"
|
#include "rr_graph_view.h"
|
||||||
|
#include "tile_annotation.h"
|
||||||
#include "vpr_device_annotation.h"
|
#include "vpr_device_annotation.h"
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
@ -30,6 +31,7 @@ int build_tile_modules(ModuleManager& module_manager,
|
||||||
const VprDeviceAnnotation& vpr_device_annotation,
|
const VprDeviceAnnotation& vpr_device_annotation,
|
||||||
const DeviceRRGSB& device_rr_gsb,
|
const DeviceRRGSB& device_rr_gsb,
|
||||||
const RRGraphView& rr_graph_view,
|
const RRGraphView& rr_graph_view,
|
||||||
|
const TileAnnotation& tile_annotation,
|
||||||
const CircuitLibrary& circuit_lib,
|
const CircuitLibrary& circuit_lib,
|
||||||
const CircuitModelId& sram_model,
|
const CircuitModelId& sram_model,
|
||||||
const e_config_protocol_type& sram_orgz_type,
|
const e_config_protocol_type& sram_orgz_type,
|
||||||
|
|
|
@ -1404,6 +1404,15 @@ static int build_top_module_global_net_for_given_tile_module(
|
||||||
std::string grid_port_name =
|
std::string grid_port_name =
|
||||||
generate_grid_port_name(grid_pin_width, grid_pin_height,
|
generate_grid_port_name(grid_pin_width, grid_pin_height,
|
||||||
subtile_index, pin_side, grid_pin_info);
|
subtile_index, pin_side, grid_pin_info);
|
||||||
|
if (tile_annotation.is_tile_port_to_merge(
|
||||||
|
std::string(physical_tile->name), grid_pin_info.get_name())) {
|
||||||
|
if (subtile_index == 0) {
|
||||||
|
grid_port_name =
|
||||||
|
generate_grid_port_name(0, 0, 0, TOP, grid_pin_info);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
std::string tile_grid_port_name =
|
std::string tile_grid_port_name =
|
||||||
generate_tile_module_port_name(grid_instance_name, grid_port_name);
|
generate_tile_module_port_name(grid_instance_name, grid_port_name);
|
||||||
ModulePortId tile_grid_port_id =
|
ModulePortId tile_grid_port_id =
|
||||||
|
|
|
@ -950,6 +950,16 @@ static int build_top_module_global_net_for_given_grid_module(
|
||||||
std::string grid_port_name =
|
std::string grid_port_name =
|
||||||
generate_grid_port_name(grid_pin_width, grid_pin_height,
|
generate_grid_port_name(grid_pin_width, grid_pin_height,
|
||||||
subtile_index, pin_side, grid_pin_info);
|
subtile_index, pin_side, grid_pin_info);
|
||||||
|
if (tile_annotation.is_tile_port_to_merge(
|
||||||
|
std::string(physical_tile->name), grid_pin_info.get_name())) {
|
||||||
|
if (subtile_index == 0) {
|
||||||
|
grid_port_name =
|
||||||
|
generate_grid_port_name(0, 0, 0, TOP, grid_pin_info);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ModulePortId grid_port_id =
|
ModulePortId grid_port_id =
|
||||||
module_manager.find_module_port(grid_module, grid_port_name);
|
module_manager.find_module_port(grid_module, grid_port_name);
|
||||||
VTR_ASSERT(true == module_manager.valid_module_port_id(grid_module,
|
VTR_ASSERT(true == module_manager.valid_module_port_id(grid_module,
|
||||||
|
|
|
@ -0,0 +1,215 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- Architecture annotation for OpenFPGA framework
|
||||||
|
This annotation supports the k6_N10_40nm.xml
|
||||||
|
- General purpose logic block
|
||||||
|
- K = 6, N = 10, I = 40
|
||||||
|
- Single mode
|
||||||
|
- Routing architecture
|
||||||
|
- L = 4, fc_in = 0.15, fc_out = 0.1
|
||||||
|
-->
|
||||||
|
<openfpga_architecture>
|
||||||
|
<technology_library>
|
||||||
|
<device_library>
|
||||||
|
<device_model name="logic" type="transistor">
|
||||||
|
<lib type="industry" corner="TOP_TT" ref="M" path="${OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.pm"/>
|
||||||
|
<design vdd="0.9" pn_ratio="2"/>
|
||||||
|
<pmos name="pch" chan_length="40e-9" min_width="140e-9" variation="logic_transistor_var"/>
|
||||||
|
<nmos name="nch" chan_length="40e-9" min_width="140e-9" variation="logic_transistor_var"/>
|
||||||
|
</device_model>
|
||||||
|
<device_model name="io" type="transistor">
|
||||||
|
<lib type="academia" ref="M" path="${OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.pm"/>
|
||||||
|
<design vdd="2.5" pn_ratio="3"/>
|
||||||
|
<pmos name="pch_25" chan_length="270e-9" min_width="320e-9" variation="io_transistor_var"/>
|
||||||
|
<nmos name="nch_25" chan_length="270e-9" min_width="320e-9" variation="io_transistor_var"/>
|
||||||
|
</device_model>
|
||||||
|
</device_library>
|
||||||
|
<variation_library>
|
||||||
|
<variation name="logic_transistor_var" abs_deviation="0.1" num_sigma="3"/>
|
||||||
|
<variation name="io_transistor_var" abs_deviation="0.1" num_sigma="3"/>
|
||||||
|
</variation_library>
|
||||||
|
</technology_library>
|
||||||
|
<circuit_library>
|
||||||
|
<circuit_model type="inv_buf" name="INVTX1" prefix="INVTX1" is_default="true">
|
||||||
|
<design_technology type="cmos" topology="inverter" size="1"/>
|
||||||
|
<device_technology device_model_name="logic"/>
|
||||||
|
<port type="input" prefix="in" size="1"/>
|
||||||
|
<port type="output" prefix="out" size="1"/>
|
||||||
|
<delay_matrix type="rise" in_port="in" out_port="out">
|
||||||
|
10e-12
|
||||||
|
</delay_matrix>
|
||||||
|
<delay_matrix type="fall" in_port="in" out_port="out">
|
||||||
|
10e-12
|
||||||
|
</delay_matrix>
|
||||||
|
</circuit_model>
|
||||||
|
<circuit_model type="inv_buf" name="buf4" prefix="buf4" is_default="false">
|
||||||
|
<design_technology type="cmos" topology="buffer" size="1" num_level="2" f_per_stage="4"/>
|
||||||
|
<device_technology device_model_name="logic"/>
|
||||||
|
<port type="input" prefix="in" size="1"/>
|
||||||
|
<port type="output" prefix="out" size="1"/>
|
||||||
|
<delay_matrix type="rise" in_port="in" out_port="out">
|
||||||
|
10e-12
|
||||||
|
</delay_matrix>
|
||||||
|
<delay_matrix type="fall" in_port="in" out_port="out">
|
||||||
|
10e-12
|
||||||
|
</delay_matrix>
|
||||||
|
</circuit_model>
|
||||||
|
<circuit_model type="inv_buf" name="tap_buf4" prefix="tap_buf4" is_default="false">
|
||||||
|
<design_technology type="cmos" topology="buffer" size="1" num_level="3" f_per_stage="4"/>
|
||||||
|
<device_technology device_model_name="logic"/>
|
||||||
|
<port type="input" prefix="in" size="1"/>
|
||||||
|
<port type="output" prefix="out" size="1"/>
|
||||||
|
<delay_matrix type="rise" in_port="in" out_port="out">
|
||||||
|
10e-12
|
||||||
|
</delay_matrix>
|
||||||
|
<delay_matrix type="fall" in_port="in" out_port="out">
|
||||||
|
10e-12
|
||||||
|
</delay_matrix>
|
||||||
|
</circuit_model>
|
||||||
|
<circuit_model type="pass_gate" name="TGATE" prefix="TGATE" is_default="true">
|
||||||
|
<design_technology type="cmos" topology="transmission_gate" nmos_size="1" pmos_size="2"/>
|
||||||
|
<device_technology device_model_name="logic"/>
|
||||||
|
<input_buffer exist="false"/>
|
||||||
|
<output_buffer exist="false"/>
|
||||||
|
<port type="input" prefix="in" size="1"/>
|
||||||
|
<port type="input" prefix="sel" size="1"/>
|
||||||
|
<port type="input" prefix="selb" size="1"/>
|
||||||
|
<port type="output" prefix="out" size="1"/>
|
||||||
|
<delay_matrix type="rise" in_port="in sel selb" out_port="out">
|
||||||
|
10e-12 5e-12 5e-12
|
||||||
|
</delay_matrix>
|
||||||
|
<delay_matrix type="fall" in_port="in sel selb" out_port="out">
|
||||||
|
10e-12 5e-12 5e-12
|
||||||
|
</delay_matrix>
|
||||||
|
</circuit_model>
|
||||||
|
<circuit_model type="chan_wire" name="chan_segment" prefix="track_seg" is_default="true">
|
||||||
|
<design_technology type="cmos"/>
|
||||||
|
<input_buffer exist="false"/>
|
||||||
|
<output_buffer exist="false"/>
|
||||||
|
<port type="input" prefix="in" size="1"/>
|
||||||
|
<port type="output" prefix="out" size="1"/>
|
||||||
|
<wire_param model_type="pi" R="101" C="22.5e-15" num_level="1"/>
|
||||||
|
<!-- model_type could be T, res_val and cap_val DON'T CARE -->
|
||||||
|
</circuit_model>
|
||||||
|
<circuit_model type="wire" name="direct_interc" prefix="direct_interc" is_default="true">
|
||||||
|
<design_technology type="cmos"/>
|
||||||
|
<input_buffer exist="false"/>
|
||||||
|
<output_buffer exist="false"/>
|
||||||
|
<port type="input" prefix="in" size="1"/>
|
||||||
|
<port type="output" prefix="out" size="1"/>
|
||||||
|
<wire_param model_type="pi" R="0" C="0" num_level="1"/>
|
||||||
|
<!-- model_type could be T, res_val cap_val should be defined -->
|
||||||
|
</circuit_model>
|
||||||
|
<circuit_model type="mux" name="mux_tree" prefix="mux_tree" dump_structural_verilog="true">
|
||||||
|
<design_technology type="cmos" structure="tree" add_const_input="true" const_input_val="1"/>
|
||||||
|
<input_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||||
|
<output_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||||
|
<pass_gate_logic circuit_model_name="TGATE"/>
|
||||||
|
<port type="input" prefix="in" size="1"/>
|
||||||
|
<port type="output" prefix="out" size="1"/>
|
||||||
|
<port type="sram" prefix="sram" size="1"/>
|
||||||
|
</circuit_model>
|
||||||
|
<circuit_model type="mux" name="mux_tree_tapbuf" prefix="mux_tree_tapbuf" is_default="true" dump_structural_verilog="true">
|
||||||
|
<design_technology type="cmos" structure="tree" add_const_input="true" const_input_val="1"/>
|
||||||
|
<input_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||||
|
<output_buffer exist="true" circuit_model_name="tap_buf4"/>
|
||||||
|
<pass_gate_logic circuit_model_name="TGATE"/>
|
||||||
|
<port type="input" prefix="in" size="1"/>
|
||||||
|
<port type="output" prefix="out" size="1"/>
|
||||||
|
<port type="sram" prefix="sram" size="1"/>
|
||||||
|
</circuit_model>
|
||||||
|
<!--DFF subckt ports should be defined as <D> <Q> <CLK> <RESET> <SET> -->
|
||||||
|
<circuit_model type="ff" name="DFFSRQ" prefix="DFFSRQ" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/spice/dff.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/verilog/dff.v">
|
||||||
|
<design_technology type="cmos"/>
|
||||||
|
<input_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||||
|
<output_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||||
|
<port type="input" prefix="D" size="1"/>
|
||||||
|
<port type="input" prefix="set" lib_name="SET" size="1" is_global="true" default_val="0" is_set="true"/>
|
||||||
|
<port type="input" prefix="reset" lib_name="RST" size="1" is_global="true" default_val="0" is_reset="true"/>
|
||||||
|
<port type="output" prefix="Q" size="1"/>
|
||||||
|
<port type="clock" prefix="clk" lib_name="CK" size="1" is_global="false" default_val="0"/>
|
||||||
|
</circuit_model>
|
||||||
|
<circuit_model type="lut" name="lut4" prefix="lut4" dump_structural_verilog="true">
|
||||||
|
<design_technology type="cmos"/>
|
||||||
|
<input_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||||
|
<output_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||||
|
<lut_input_inverter exist="true" circuit_model_name="INVTX1"/>
|
||||||
|
<lut_input_buffer exist="true" circuit_model_name="buf4"/>
|
||||||
|
<pass_gate_logic circuit_model_name="TGATE"/>
|
||||||
|
<port type="input" prefix="in" size="4"/>
|
||||||
|
<port type="output" prefix="out" size="1"/>
|
||||||
|
<port type="sram" prefix="sram" size="16"/>
|
||||||
|
</circuit_model>
|
||||||
|
<!--Scan-chain DFF subckt ports should be defined as <D> <Q> <Qb> <CLK> <RESET> <SET> -->
|
||||||
|
<circuit_model type="ccff" name="DFF" prefix="DFF" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/spice/dff.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/verilog/dff.v">
|
||||||
|
<design_technology type="cmos"/>
|
||||||
|
<input_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||||
|
<output_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||||
|
<port type="input" prefix="D" size="1"/>
|
||||||
|
<port type="output" prefix="Q" size="1"/>
|
||||||
|
<port type="output" prefix="QN" size="1"/>
|
||||||
|
<port type="clock" prefix="prog_clk" lib_name="CK" size="1" is_global="true" default_val="0" is_prog="true"/>
|
||||||
|
</circuit_model>
|
||||||
|
<circuit_model type="iopad" name="GPIO" prefix="GPIO" spice_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/spice/gpio.sp" verilog_netlist="${OPENFPGA_PATH}/openfpga_flow/openfpga_cell_library/verilog/gpio.v">
|
||||||
|
<design_technology type="cmos"/>
|
||||||
|
<input_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||||
|
<output_buffer exist="true" circuit_model_name="INVTX1"/>
|
||||||
|
<port type="inout" prefix="PAD" size="1" is_global="true" is_io="true" is_data_io="true"/>
|
||||||
|
<port type="sram" prefix="DIR" size="1" mode_select="true" circuit_model_name="DFF" default_val="1"/>
|
||||||
|
<port type="input" prefix="outpad" lib_name="A" size="1"/>
|
||||||
|
<port type="output" prefix="inpad" lib_name="Y" size="1"/>
|
||||||
|
</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>
|
||||||
|
<configuration_protocol>
|
||||||
|
<organization type="scan_chain" circuit_model_name="DFF"/>
|
||||||
|
</configuration_protocol>
|
||||||
|
<connection_block>
|
||||||
|
<switch name="ipin_cblock" circuit_model_name="mux_tree_tapbuf"/>
|
||||||
|
</connection_block>
|
||||||
|
<switch_block>
|
||||||
|
<switch name="0" circuit_model_name="mux_tree_tapbuf"/>
|
||||||
|
</switch_block>
|
||||||
|
<routing_segment>
|
||||||
|
<segment name="L4" circuit_model_name="chan_segment"/>
|
||||||
|
</routing_segment>
|
||||||
|
<tile_annotations>
|
||||||
|
<merge_subtile_ports tile="io_hybrid" port="clk"/>
|
||||||
|
<global_port name="clk" is_clock="true" default_val="0">
|
||||||
|
<tile name="clb" 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>
|
||||||
|
</tile_annotations>
|
||||||
|
<pb_type_annotations>
|
||||||
|
<!-- physical pb_type binding in complex block IO -->
|
||||||
|
<pb_type name="io" physical_mode_name="physical" idle_mode_name="inpad"/>
|
||||||
|
<pb_type name="io[physical].iopad" circuit_model_name="GPIO" mode_bits="1"/>
|
||||||
|
<pb_type name="io[physical].ff" circuit_model_name="DFFSRQ"/>
|
||||||
|
<pb_type name="io[inpad].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[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 -->
|
||||||
|
<!-- physical pb_type binding in complex block CLB -->
|
||||||
|
<!-- physical mode will be the default mode if not specified -->
|
||||||
|
<pb_type name="clb">
|
||||||
|
<!-- Binding interconnect to circuit models as their physical implementation, if not defined, we use the default model -->
|
||||||
|
<interconnect name="crossbar" circuit_model_name="mux_tree"/>
|
||||||
|
</pb_type>
|
||||||
|
<pb_type name="clb.fle[n1_lut4].ble4.lut4" circuit_model_name="lut4"/>
|
||||||
|
<pb_type name="clb.fle[n1_lut4].ble4.ff" circuit_model_name="DFFSRQ"/>
|
||||||
|
<!-- End physical pb_type binding in complex block IO -->
|
||||||
|
</pb_type_annotations>
|
||||||
|
</openfpga_architecture>
|
|
@ -0,0 +1,63 @@
|
||||||
|
# Run VPR for the 'and' design
|
||||||
|
# When the global clock is defined as a port of a tile, clock routing in VPR should be skipped
|
||||||
|
# This is due to the Fc_in of clock port is set to 0 for global wiring
|
||||||
|
#--write_rr_graph example_rr_graph.xml
|
||||||
|
vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --device ${OPENFPGA_VPR_DEVICE_LAYOUT}
|
||||||
|
|
||||||
|
# Read OpenFPGA architecture definition
|
||||||
|
read_openfpga_arch -f ${OPENFPGA_ARCH_FILE}
|
||||||
|
|
||||||
|
# Read OpenFPGA simulation settings
|
||||||
|
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
|
||||||
|
|
||||||
|
# Check and correct any naming conflicts in the BLIF netlist
|
||||||
|
check_netlist_naming_conflict --fix --report ./netlist_renaming.xml
|
||||||
|
|
||||||
|
# Apply fix-up to Look-Up Table truth tables based on packing results
|
||||||
|
lut_truth_table_fixup
|
||||||
|
|
||||||
|
# Build the module graph
|
||||||
|
# - Enabled compression on routing architecture modules
|
||||||
|
# - Enable pin duplication on grid modules
|
||||||
|
build_fabric --compress_routing ${OPENFPGA_GROUP_CONFIG_BLOCK_OPTIONS} ${OPENFPGA_GROUP_TILE_CONFIG_OPTIONS} #--verbose
|
||||||
|
|
||||||
|
# Write the fabric hierarchy of module graph to a file
|
||||||
|
# This is used by hierarchical PnR flows
|
||||||
|
write_fabric_hierarchy --file ./fabric_hierarchy.txt
|
||||||
|
|
||||||
|
# Repack the netlist to physical pbs
|
||||||
|
# This must be done before bitstream generator and testbench generation
|
||||||
|
# Strongly recommend it is done after all the fix-up have been applied
|
||||||
|
repack #--verbose
|
||||||
|
|
||||||
|
# Build the bitstream
|
||||||
|
# - Output the fabric-independent bitstream to a file
|
||||||
|
build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml
|
||||||
|
|
||||||
|
# Build fabric-dependent bitstream
|
||||||
|
build_fabric_bitstream --verbose
|
||||||
|
|
||||||
|
# Write fabric-dependent bitstream
|
||||||
|
write_fabric_bitstream --file fabric_bitstream.bit --format plain_text
|
||||||
|
|
||||||
|
# Write the Verilog netlist for FPGA fabric
|
||||||
|
# - Enable the use of explicit port mapping in Verilog netlist
|
||||||
|
write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --print_user_defined_template --verbose
|
||||||
|
|
||||||
|
# Write the Verilog testbench for FPGA fabric
|
||||||
|
# - We suggest the use of same output directory as fabric Verilog netlists
|
||||||
|
# - Must specify the reference benchmark file if you want to output any testbenches
|
||||||
|
# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA
|
||||||
|
# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase
|
||||||
|
# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts
|
||||||
|
write_full_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --explicit_port_mapping --include_signal_init --bitstream fabric_bitstream.bit
|
||||||
|
|
||||||
|
# Finish and exit OpenFPGA
|
||||||
|
exit
|
||||||
|
|
||||||
|
# Note :
|
||||||
|
# To run verification at the end of the flow maintain source in ./SRC directory
|
|
@ -211,6 +211,8 @@ run-task basic_tests/module_naming/renaming_rules_on_indexed_names $@
|
||||||
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_clock_subtile $@
|
||||||
|
run-task basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge $@
|
||||||
|
run-task basic_tests/global_tile_ports/global_tile_clock_subtile_port_merge_fabric_tile_group_config $@
|
||||||
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 $@
|
||||||
|
|
|
@ -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_GlobalTileClkMergeSubtilePort_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=
|
|
@ -0,0 +1,37 @@
|
||||||
|
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
|
||||||
|
# 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_options_full_testbench_example_script.openfpga
|
||||||
|
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_GlobalTileClkMergeSubtilePort_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
|
||||||
|
openfpga_group_tile_config_options=--group_tile ${PATH:TASK_DIR}/config/tile_config.xml
|
||||||
|
openfpga_group_config_block_options=--group_config_block
|
||||||
|
|
||||||
|
[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=
|
|
@ -0,0 +1 @@
|
||||||
|
<tiles style="top_left"/>
|
Loading…
Reference in New Issue