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:
tangxifan 2023-09-26 21:19:53 -07:00 committed by GitHub
commit 8928d45e46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 639 additions and 56 deletions

View File

@ -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.
@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

View File

@ -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)

View File

@ -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
*******************************************************************/
@ -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;

View File

@ -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 {
@ -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
***********************************************************************/
@ -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
***********************************************************************/
@ -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

View File

@ -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;
@ -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
@ -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
@ -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

View File

@ -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
*******************************************************************/
@ -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"

View File

@ -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,

View File

@ -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>(

View File

@ -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;
}
@ -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 */

View File

@ -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));
@ -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,
@ -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));
@ -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);
}
}
@ -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);
}
}
}

View File

@ -7,6 +7,7 @@
#include "module_manager.h"
#include "openfpga_side_manager.h"
#include "physical_types.h"
#include "tile_annotation.h"
#include "vpr_device_annotation.h"
/********************************************************************
@ -19,13 +20,15 @@ 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);
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);
} /* end namespace openfpga */

View File

@ -45,7 +45,8 @@ void add_grid_module_net_connect_pb_graph_pin(
const ModuleId& child_module, const size_t& child_instance,
const size_t& child_inst_subtile_index,
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) {
/* Find the pin side for I/O grids*/
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);
std::string grid_port_name = generate_grid_port_name(
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 =
module_manager.find_module_port(grid_module, grid_port_name);
VTR_ASSERT(true == module_manager.valid_module_port_id(

View File

@ -8,6 +8,7 @@
#include "module_manager.h"
#include "openfpga_interconnect_types.h"
#include "physical_types.h"
#include "tile_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 size_t& child_inst_subtile_index,
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 enum e_pin2pin_interc_type& pin2pin_interc_type);

View File

@ -41,7 +41,8 @@ namespace openfpga {
static void add_grid_module_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(nullptr != grid_type_descriptor);
@ -90,6 +91,16 @@ static void add_grid_module_pb_type_ports(
subtile_index < grid_type_descriptor->capacity);
std::string port_name = generate_grid_port_name(
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);
/* Add the port to the module */
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,
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(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(
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);
}
}
@ -140,8 +152,8 @@ static void add_grid_module_nets_connect_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->output_pins[iport][ipin]), border_side,
OUTPUT2OUTPUT_INTERC);
tile_annotation, &(top_pb_graph_node->output_pins[iport][ipin]),
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(
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);
}
}
}
@ -1151,8 +1163,9 @@ static int build_physical_tile_module(
const CircuitLibrary& circuit_lib,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model, t_physical_tile_type_ptr phy_block_type,
const e_side& border_side, const bool& duplicate_grid_pin,
const bool& group_config_block, const bool& verbose) {
const TileAnnotation& tile_annotation, const e_side& border_side,
const bool& duplicate_grid_pin, const bool& group_config_block,
const bool& verbose) {
int status = CMD_EXEC_SUCCESS;
/* 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 */
add_grid_module_pb_type_ports(module_manager, grid_module,
vpr_device_annotation, phy_block_type,
border_side);
tile_annotation, border_side);
/* Add module nets to connect the pb_type ports to sub modules */
for (const t_sub_tile& sub_tile : phy_block_type->sub_tiles) {
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)) {
add_grid_module_nets_connect_pb_type_ports(
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 {
VTR_ASSERT_SAFE(true == duplicate_grid_pin);
/* Add these ports with duplication */
add_grid_module_duplicated_pb_type_ports(module_manager, grid_module,
vpr_device_annotation,
phy_block_type, border_side);
add_grid_module_duplicated_pb_type_ports(
module_manager, grid_module, vpr_device_annotation, phy_block_type,
tile_annotation, border_side);
/* 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) {
@ -1274,7 +1287,7 @@ static int build_physical_tile_module(
module_manager.child_module_instances(grid_module, pb_module)) {
add_grid_module_nets_connect_duplicated_pb_type_ports(
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,
const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation,
const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib,
const TileAnnotation& tile_annotation,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model, const bool& duplicate_grid_pin,
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) {
status = build_physical_tile_module(
module_manager, decoder_lib, device_annotation, circuit_lib,
sram_orgz_type, sram_model, &physical_tile, io_type_side,
duplicate_grid_pin, group_config_block, verbose);
sram_orgz_type, sram_model, &physical_tile, tile_annotation,
io_type_side, duplicate_grid_pin, group_config_block, verbose);
if (status != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
@ -1424,7 +1438,7 @@ int build_grid_modules(
/* For CLB and heterogenenous blocks */
status = build_physical_tile_module(
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);
if (status != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;

View File

@ -7,6 +7,7 @@
#include "decoder_library.h"
#include "module_manager.h"
#include "mux_library.h"
#include "tile_annotation.h"
#include "vpr_context.h"
#include "vpr_device_annotation.h"
@ -21,6 +22,7 @@ int build_grid_modules(
ModuleManager& module_manager, DecoderLibrary& decoder_lib,
const DeviceContext& device_ctx, const VprDeviceAnnotation& device_annotation,
const CircuitLibrary& circuit_lib, const MuxLibrary& mux_lib,
const TileAnnotation& tile_annotation,
const e_config_protocol_type& sram_orgz_type,
const CircuitModelId& sram_model, const bool& duplicate_grid_pin,
const bool& group_config_block, const bool& verbose);

View File

@ -1004,9 +1004,10 @@ static int build_tile_port_and_nets_from_pb(
ModuleManager& module_manager, const ModuleId& tile_module,
const DeviceGrid& grids, const size_t& layer,
const VprDeviceAnnotation& vpr_device_annotation, const RRGraphView& rr_graph,
const vtr::Point<size_t>& pb_coord, const std::vector<size_t>& pb_instances,
const FabricTile& fabric_tile, const FabricTileId& curr_fabric_tile_id,
const size_t& ipb, const bool& frame_view, const bool& verbose) {
const TileAnnotation& tile_annotation, const vtr::Point<size_t>& pb_coord,
const std::vector<size_t>& pb_instances, const FabricTile& fabric_tile,
const FabricTileId& curr_fabric_tile_id, const size_t& ipb,
const bool& frame_view, const bool& verbose) {
size_t pb_instance = pb_instances[ipb];
t_physical_tile_type_ptr phy_tile = grids.get_physical_type(
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);
std::string port_name = generate_grid_port_name(
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);
ModulePortId pb_module_port_id =
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 VprDeviceAnnotation& vpr_device_annotation,
const DeviceRRGSB& device_rr_gsb, const RRGraphView& rr_graph_view,
const FabricTile& fabric_tile, const FabricTileId& fabric_tile_id,
const std::vector<size_t>& pb_instances,
const TileAnnotation& tile_annotation, const FabricTile& fabric_tile,
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::vector<size_t>& sb_instances, const bool& name_module_using_index,
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];
status_code = build_tile_port_and_nets_from_pb(
module_manager, tile_module, grids, layer, vpr_device_annotation,
rr_graph_view, pb_coord, pb_instances, fabric_tile, fabric_tile_id, ipb,
frame_view, verbose);
rr_graph_view, tile_annotation, pb_coord, pb_instances, fabric_tile,
fabric_tile_id, ipb, frame_view, verbose);
if (status_code != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}
@ -1303,7 +1312,8 @@ static int build_tile_module(
const DeviceGrid& grids, const size_t& layer,
const VprDeviceAnnotation& vpr_device_annotation,
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 bool& name_module_using_index, const bool& frame_view,
const bool& verbose) {
@ -1451,8 +1461,9 @@ static int build_tile_module(
/* Add module nets and ports */
status_code = build_tile_module_ports_and_nets(
module_manager, tile_module, grids, layer, vpr_device_annotation,
device_rr_gsb, rr_graph_view, fabric_tile, fabric_tile_id, pb_instances,
cb_instances, sb_instances, name_module_using_index, frame_view, verbose);
device_rr_gsb, rr_graph_view, tile_annotation, fabric_tile, fabric_tile_id,
pb_instances, cb_instances, sb_instances, name_module_using_index,
frame_view, verbose);
/* Add global ports to the pb_module:
* 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 DeviceRRGSB& device_rr_gsb,
const RRGraphView& rr_graph_view,
const TileAnnotation& tile_annotation,
const CircuitLibrary& circuit_lib,
const CircuitModelId& sram_model,
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()) {
status_code = build_tile_module(
module_manager, decoder_lib, fabric_tile, fabric_tile_id, grids, layer,
vpr_device_annotation, device_rr_gsb, rr_graph_view, circuit_lib,
sram_model, sram_orgz_type, name_module_using_index, frame_view, verbose);
vpr_device_annotation, device_rr_gsb, rr_graph_view, tile_annotation,
circuit_lib, sram_model, sram_orgz_type, name_module_using_index,
frame_view, verbose);
if (status_code != CMD_EXEC_SUCCESS) {
return CMD_EXEC_FATAL_ERROR;
}

View File

@ -15,6 +15,7 @@
#include "fabric_tile.h"
#include "module_manager.h"
#include "rr_graph_view.h"
#include "tile_annotation.h"
#include "vpr_device_annotation.h"
/********************************************************************
@ -30,6 +31,7 @@ int build_tile_modules(ModuleManager& module_manager,
const VprDeviceAnnotation& vpr_device_annotation,
const DeviceRRGSB& device_rr_gsb,
const RRGraphView& rr_graph_view,
const TileAnnotation& tile_annotation,
const CircuitLibrary& circuit_lib,
const CircuitModelId& sram_model,
const e_config_protocol_type& sram_orgz_type,

View File

@ -1404,6 +1404,15 @@ static int build_top_module_global_net_for_given_tile_module(
std::string grid_port_name =
generate_grid_port_name(grid_pin_width, grid_pin_height,
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 =
generate_tile_module_port_name(grid_instance_name, grid_port_name);
ModulePortId tile_grid_port_id =

View File

@ -950,6 +950,16 @@ static int build_top_module_global_net_for_given_grid_module(
std::string grid_port_name =
generate_grid_port_name(grid_pin_width, grid_pin_height,
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 =
module_manager.find_module_port(grid_module, grid_port_name);
VTR_ASSERT(true == module_manager.valid_module_port_id(grid_module,

View File

@ -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>

View File

@ -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

View File

@ -211,6 +211,8 @@ run-task basic_tests/module_naming/renaming_rules_on_indexed_names $@
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_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_4clock $@
run-task basic_tests/global_tile_ports/global_tile_4clock_pin $@

View File

@ -0,0 +1,35 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configuration file for running experiments
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
# Each job execute fpga_flow script on combination of architecture & benchmark
# timeout_each_job is timeout for each job
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
[GENERAL]
run_engine=openfpga_shell
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = true
spice_output=false
verilog_output=true
timeout_each_job = 20*60
fpga_flow=yosys_vpr
[OpenFPGA_SHELL]
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/global_tile_clock_full_testbench_example_script.openfpga
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_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=

View File

@ -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=