[core] adding rr spatial lookup for clock nodes only
This commit is contained in:
parent
db36f87dfa
commit
87a9146082
|
@ -38,6 +38,36 @@ std::vector<ClockLevelId> ClockNetwork::levels(
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<ClockTreePinId> ClockNetwork::pins(const ClockTreeId& tree_id,
|
||||||
|
const ClockLevelId& level,
|
||||||
|
const t_rr_type& track_type,
|
||||||
|
const Direction& direction) const {
|
||||||
|
std::vector<ClockTreePinId> ret;
|
||||||
|
/* Avoid to repeatedly count the tracks which can be shared by spines
|
||||||
|
* For two or more spines that locate in different coordinates, they can share
|
||||||
|
* the same routing tracks. Therefore, we only ensure that routing tracks in
|
||||||
|
* their demanding direction (INC and DEC) are satisfied
|
||||||
|
*/
|
||||||
|
bool dir_flags = false;
|
||||||
|
for (ClockSpineId curr_spine : spines(tree_id)) {
|
||||||
|
if (spine_levels_[curr_spine] != size_t(level)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (spine_track_type(curr_spine) == track_type) {
|
||||||
|
if (!dir_flags && spine_direction(curr_spine) == direction) {
|
||||||
|
ret.reserve(ret.size() + tree_width(spine_parent_trees_[curr_spine]));
|
||||||
|
for (size_t i = 0; i < tree_width(spine_parent_trees_[curr_spine]); ++i) {
|
||||||
|
ret.push_back(ClockTreePinId(i));
|
||||||
|
}
|
||||||
|
dir_flags = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Public Accessors : Basic data query
|
* Public Accessors : Basic data query
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
|
@ -53,6 +53,10 @@ class ClockNetwork {
|
||||||
std::vector<ClockLevelId> levels(const ClockTreeId& tree_id) const;
|
std::vector<ClockLevelId> levels(const ClockTreeId& tree_id) const;
|
||||||
/* Return a list of spine id under a clock tree */
|
/* Return a list of spine id under a clock tree */
|
||||||
std::vector<ClockSpineId> spines(const ClockTreeId& tree_id) const;
|
std::vector<ClockSpineId> spines(const ClockTreeId& tree_id) const;
|
||||||
|
/* Return a list of clock pins in a bus of clock tree at a given level and direction */
|
||||||
|
std::vector<ClockTreePinId> pins(const ClockTreeId& tree_id, const ClockLevelId& level,
|
||||||
|
const t_rr_type& track_type,
|
||||||
|
const Direction& direction) const;
|
||||||
|
|
||||||
public: /* Public Accessors: Basic data query */
|
public: /* Public Accessors: Basic data query */
|
||||||
/* Return the number of routing tracks required by a selected clock tree at a
|
/* Return the number of routing tracks required by a selected clock tree at a
|
||||||
|
|
|
@ -16,11 +16,13 @@ namespace openfpga { // Begin namespace openfpga
|
||||||
|
|
||||||
struct clock_level_id_tag;
|
struct clock_level_id_tag;
|
||||||
struct clock_tree_id_tag;
|
struct clock_tree_id_tag;
|
||||||
|
struct clock_tree_pin_id_tag;
|
||||||
struct clock_spine_id_tag;
|
struct clock_spine_id_tag;
|
||||||
struct clock_switch_point_id_tag;
|
struct clock_switch_point_id_tag;
|
||||||
|
|
||||||
typedef vtr::StrongId<clock_level_id_tag> ClockLevelId;
|
typedef vtr::StrongId<clock_level_id_tag> ClockLevelId;
|
||||||
typedef vtr::StrongId<clock_tree_id_tag> ClockTreeId;
|
typedef vtr::StrongId<clock_tree_id_tag> ClockTreeId;
|
||||||
|
typedef vtr::StrongId<clock_tree_pin_id_tag> ClockTreePinId;
|
||||||
typedef vtr::StrongId<clock_spine_id_tag> ClockSpineId;
|
typedef vtr::StrongId<clock_spine_id_tag> ClockSpineId;
|
||||||
typedef vtr::StrongId<clock_switch_point_id_tag> ClockSwitchPointId;
|
typedef vtr::StrongId<clock_switch_point_id_tag> ClockSwitchPointId;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
#include "vtr_assert.h"
|
||||||
|
#include "vtr_log.h"
|
||||||
|
#include "rr_clock_spatial_lookup.h"
|
||||||
|
|
||||||
|
namespace openfpga { // begin namespace openfpga
|
||||||
|
|
||||||
|
RRClockSpatialLookup::RRClockSpatialLookup() {
|
||||||
|
}
|
||||||
|
|
||||||
|
RRNodeId RRClockSpatialLookup::find_node(int x,
|
||||||
|
int y,
|
||||||
|
const ClockTreeId& tree,
|
||||||
|
const ClockLevelId& lvl,
|
||||||
|
const ClockTreePinId& pin,
|
||||||
|
const Direction& direction) const {
|
||||||
|
size_t dir = size_t(direction);
|
||||||
|
/* Pre-check: the x, y, side and ptc should be non negative numbers! Otherwise, return an invalid id */
|
||||||
|
if ((x < 0) || (y < 0) || (direction != Direction::INC && direction != Direction::DEC)) {
|
||||||
|
return RRNodeId::INVALID();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sanity check to ensure the x, y, side and ptc are in range
|
||||||
|
* - Return an valid id by searching in look-up when all the parameters are in range
|
||||||
|
* - Return an invalid id if any out-of-range is detected
|
||||||
|
*/
|
||||||
|
if (size_t(dir) >= rr_node_indices_.size()) {
|
||||||
|
return RRNodeId::INVALID();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size_t(x) >= rr_node_indices_[dir].dim_size(0)) {
|
||||||
|
return RRNodeId::INVALID();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size_t(y) >= rr_node_indices_[dir].dim_size(1)) {
|
||||||
|
return RRNodeId::INVALID();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result_tree = rr_node_indices_[dir][x][y].find(tree);
|
||||||
|
if (result_tree == rr_node_indices_[dir][x][y].end()) {
|
||||||
|
return RRNodeId::INVALID();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result_lvl = result_tree->second.find(lvl);
|
||||||
|
if (result_lvl == result_tree->second.end()) {
|
||||||
|
return RRNodeId::INVALID();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result_pin = result_lvl->second.find(pin);
|
||||||
|
if (result_pin == result_lvl->second.end()) {
|
||||||
|
return RRNodeId::INVALID();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result_pin->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RRClockSpatialLookup::add_node(RRNodeId node,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
const ClockTreeId& tree,
|
||||||
|
const ClockLevelId& lvl,
|
||||||
|
const ClockTreePinId& pin,
|
||||||
|
const Direction& direction) {
|
||||||
|
size_t dir = size_t(direction);
|
||||||
|
VTR_ASSERT(node); /* Must have a valid node id to be added */
|
||||||
|
VTR_ASSERT_SAFE(2 == rr_node_indices_[dir].ndims());
|
||||||
|
|
||||||
|
resize_nodes(x, y, direction);
|
||||||
|
|
||||||
|
/* Resize on demand finished; Register the node */
|
||||||
|
rr_node_indices_[dir][x][y][tree][lvl][pin] = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RRClockSpatialLookup::resize_nodes(int x,
|
||||||
|
int y,
|
||||||
|
const Direction& direction) {
|
||||||
|
/* Expand the fast look-up if the new node is out-of-range
|
||||||
|
* This may seldom happen because the rr_graph building function
|
||||||
|
* should ensure the fast look-up well organized
|
||||||
|
*/
|
||||||
|
size_t dir = size_t(direction);
|
||||||
|
VTR_ASSERT(dir < rr_node_indices_.size());
|
||||||
|
VTR_ASSERT(x >= 0);
|
||||||
|
VTR_ASSERT(y >= 0);
|
||||||
|
|
||||||
|
if ((x >= int(rr_node_indices_[dir].dim_size(0)))
|
||||||
|
|| (y >= int(rr_node_indices_[dir].dim_size(1)))) {
|
||||||
|
rr_node_indices_[dir].resize({std::max(rr_node_indices_[dir].dim_size(0), size_t(x) + 1),
|
||||||
|
std::max(rr_node_indices_[dir].dim_size(1), size_t(y) + 1)});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RRClockSpatialLookup::clear() {
|
||||||
|
for (auto& data : rr_node_indices_) {
|
||||||
|
data.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace openfpga
|
|
@ -0,0 +1,102 @@
|
||||||
|
#ifndef RR_CLOCK_SPATIAL_LOOKUP_H
|
||||||
|
#define RR_CLOCK_SPATIAL_LOOKUP_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief This RRClockSpatialLookup class encapsulates
|
||||||
|
* the node-lookup for clock nodes in a routing resource graph
|
||||||
|
*
|
||||||
|
* A data structure built to find the id of an routing resource node
|
||||||
|
* (rr_node) given information about its physical position and type in a clock network
|
||||||
|
* The data structure is mostly needed during building the clock part of a routing resource graph
|
||||||
|
*
|
||||||
|
* The data structure allows users to
|
||||||
|
*
|
||||||
|
* - Update the look-up with new nodes
|
||||||
|
* - Find the id of a node with given information, e.g., x, y, type etc.
|
||||||
|
*/
|
||||||
|
#include "vtr_geometry.h"
|
||||||
|
#include "vtr_vector.h"
|
||||||
|
#include "physical_types.h"
|
||||||
|
#include "rr_node_types.h"
|
||||||
|
#include "rr_graph_fwd.h"
|
||||||
|
#include "clock_network_fwd.h"
|
||||||
|
|
||||||
|
namespace openfpga { // begin namespace openfpga
|
||||||
|
|
||||||
|
class RRClockSpatialLookup {
|
||||||
|
/* -- Constructors -- */
|
||||||
|
public:
|
||||||
|
/* Explicitly define the only way to create an object */
|
||||||
|
explicit RRClockSpatialLookup();
|
||||||
|
|
||||||
|
/* Disable copy constructors and copy assignment operator
|
||||||
|
* This is to avoid accidental copy because it could be an expensive operation considering that the
|
||||||
|
* memory footprint of the data structure could ~ Gb
|
||||||
|
* Using the following syntax, we prohibit accidental 'pass-by-value' which can be immediately caught
|
||||||
|
* by compiler
|
||||||
|
*/
|
||||||
|
RRClockSpatialLookup(const RRClockSpatialLookup&) = delete;
|
||||||
|
void operator=(const RRClockSpatialLookup&) = delete;
|
||||||
|
|
||||||
|
/* -- Accessors -- */
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Returns the index of the specified routing resource node.
|
||||||
|
*
|
||||||
|
* @param (x, y) are the grid location within the FPGA
|
||||||
|
* @param clk_tree specifies the id of the clock tree in a clock network,
|
||||||
|
* @param clk_level specifies the level of the clock node in a clock network (typically multi-level),
|
||||||
|
* @param clk_pin specifies the pin id of the clock node in a bus of clock tree (consider multiple clock in a tree)
|
||||||
|
* @param direction specifies how the clock node will propagate the signal (either in a horizental or a vertical way)
|
||||||
|
*
|
||||||
|
* @note An invalid id will be returned if the node does not exist
|
||||||
|
*/
|
||||||
|
RRNodeId find_node(int x,
|
||||||
|
int y,
|
||||||
|
const ClockTreeId& tree,
|
||||||
|
const ClockLevelId& lvl,
|
||||||
|
const ClockTreePinId& pin,
|
||||||
|
const Direction& direction) const;
|
||||||
|
|
||||||
|
/* -- Mutators -- */
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Register a node in the fast look-up
|
||||||
|
*
|
||||||
|
* @note You must have a valid node id to register the node in the lookup
|
||||||
|
*
|
||||||
|
* @param (x, y) are the grid location within the FPGA
|
||||||
|
* @param clk_tree specifies the id of the clock tree in a clock network,
|
||||||
|
* @param clk_level specifies the level of the clock node in a clock network (typically multi-level),
|
||||||
|
* @param clk_pin specifies the pin id of the clock node in a bus of clock tree (consider multiple clock in a tree)
|
||||||
|
* @param direction specifies how the clock node will propagate the signal (either in a horizental or a vertical way)
|
||||||
|
|
||||||
|
*
|
||||||
|
* @note a node added with this call will not create a node in the rr_graph node list
|
||||||
|
* You MUST add the node in the rr_graph so that the node is valid
|
||||||
|
*/
|
||||||
|
void add_node(RRNodeId node,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
const ClockTreeId& clk_tree,
|
||||||
|
const ClockLevelId& clk_lvl,
|
||||||
|
const ClockTreePinId& clk_pin,
|
||||||
|
const Direction& direction);
|
||||||
|
|
||||||
|
/** @brief Clear all the data inside */
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
private: /* Private mutators */
|
||||||
|
/** @brief Resize the nodes upon needs */
|
||||||
|
void resize_nodes(int x, int y, const Direction& direction);
|
||||||
|
|
||||||
|
/* -- Internal data storage -- */
|
||||||
|
private:
|
||||||
|
/* Fast look-up: [INC|DEC][0..grid_width][0..grid_height][tree_id][level_id][clock_pin_id] */
|
||||||
|
std::array<vtr::NdMatrix<std::map<ClockTreeId, std::map<ClockLevelId, std::map<ClockTreePinId, RRNodeId>>>, 2>, 2> rr_node_indices_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace openfpga
|
||||||
|
|
||||||
|
#endif
|
|
@ -84,6 +84,7 @@ static size_t estimate_clock_rr_graph_num_nodes(const DeviceGrid& grids,
|
||||||
* with direction, ptc and coordinates etc.
|
* with direction, ptc and coordinates etc.
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
static void add_rr_graph_block_clock_nodes(RRGraphBuilder& rr_graph_builder,
|
static void add_rr_graph_block_clock_nodes(RRGraphBuilder& rr_graph_builder,
|
||||||
|
RRClockSpatialLookup& clk_rr_lookup,
|
||||||
const RRGraphView& rr_graph_view,
|
const RRGraphView& rr_graph_view,
|
||||||
const ClockNetwork& clk_ntwk,
|
const ClockNetwork& clk_ntwk,
|
||||||
const vtr::Point<size_t> chan_coord,
|
const vtr::Point<size_t> chan_coord,
|
||||||
|
@ -98,9 +99,7 @@ static void add_rr_graph_block_clock_nodes(RRGraphBuilder& rr_graph_builder,
|
||||||
for (auto itree : clk_ntwk.trees()) {
|
for (auto itree : clk_ntwk.trees()) {
|
||||||
for (auto ilvl : clk_ntwk.levels(itree)) {
|
for (auto ilvl : clk_ntwk.levels(itree)) {
|
||||||
for (auto node_dir : {Direction::INC, Direction::DEC}) {
|
for (auto node_dir : {Direction::INC, Direction::DEC}) {
|
||||||
for (size_t itrack = 0;
|
for (auto ipin : clk_ntwk.pins(itree, ilvl, chan_type, node_dir)) {
|
||||||
itrack < clk_ntwk.num_tracks(itree, ilvl, chan_type, node_dir);
|
|
||||||
++itrack) {
|
|
||||||
RRNodeId clk_node = rr_graph_builder.create_node(
|
RRNodeId clk_node = rr_graph_builder.create_node(
|
||||||
chan_coord.x(), chan_coord.y(), chan_type, curr_node_ptc);
|
chan_coord.x(), chan_coord.y(), chan_type, curr_node_ptc);
|
||||||
rr_graph_builder.set_node_direction(clk_node, node_dir);
|
rr_graph_builder.set_node_direction(clk_node, node_dir);
|
||||||
|
@ -111,8 +110,8 @@ static void add_rr_graph_block_clock_nodes(RRGraphBuilder& rr_graph_builder,
|
||||||
size_t(clk_ntwk.default_segment())));
|
size_t(clk_ntwk.default_segment())));
|
||||||
/* FIXME: need to set rc_index and cost_index when building the graph
|
/* FIXME: need to set rc_index and cost_index when building the graph
|
||||||
* in VTR */
|
* in VTR */
|
||||||
/* TODO: register the node to a dedicated lookup for clock nodes only
|
/* register the node to a dedicated lookup */
|
||||||
*/
|
clk_rr_lookup.add_node(clk_node, chan_coord.x(), chan_coord.y(), itree, ilvl, ipin, node_dir);
|
||||||
/* Update ptc count and go to next */
|
/* Update ptc count and go to next */
|
||||||
curr_node_ptc++;
|
curr_node_ptc++;
|
||||||
}
|
}
|
||||||
|
@ -123,11 +122,10 @@ static void add_rr_graph_block_clock_nodes(RRGraphBuilder& rr_graph_builder,
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Add clock nodes one by one to the routing resource graph.
|
* Add clock nodes one by one to the routing resource graph.
|
||||||
* Assign node-level attributes properly
|
* Assign node-level attributes properly and register in dedicated lookup
|
||||||
* TODO: consider to have a fast lookup for clock nodes. For example,
|
|
||||||
*find_clock_node(tree_id, level_id, clock_id)
|
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
static void add_rr_graph_clock_nodes(RRGraphBuilder& rr_graph_builder,
|
static void add_rr_graph_clock_nodes(RRGraphBuilder& rr_graph_builder,
|
||||||
|
RRClockSpatialLookup& clk_rr_lookup,
|
||||||
const RRGraphView& rr_graph_view,
|
const RRGraphView& rr_graph_view,
|
||||||
const DeviceGrid& grids,
|
const DeviceGrid& grids,
|
||||||
const bool& through_channel,
|
const bool& through_channel,
|
||||||
|
@ -142,7 +140,7 @@ static void add_rr_graph_clock_nodes(RRGraphBuilder& rr_graph_builder,
|
||||||
(false == is_chanx_exist(grids, chanx_coord))) {
|
(false == is_chanx_exist(grids, chanx_coord))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
add_rr_graph_block_clock_nodes(rr_graph_builder, rr_graph_view, clk_ntwk,
|
add_rr_graph_block_clock_nodes(rr_graph_builder, clk_rr_lookup, rr_graph_view, clk_ntwk,
|
||||||
chanx_coord, CHANX,
|
chanx_coord, CHANX,
|
||||||
CHANX_COST_INDEX_START);
|
CHANX_COST_INDEX_START);
|
||||||
}
|
}
|
||||||
|
@ -159,7 +157,7 @@ static void add_rr_graph_clock_nodes(RRGraphBuilder& rr_graph_builder,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
add_rr_graph_block_clock_nodes(
|
add_rr_graph_block_clock_nodes(
|
||||||
rr_graph_builder, rr_graph_view, clk_ntwk, chany_coord, CHANY,
|
rr_graph_builder, clk_rr_lookup, rr_graph_view, clk_ntwk, chany_coord, CHANY,
|
||||||
CHANX_COST_INDEX_START + rr_graph_view.num_rr_segments());
|
CHANX_COST_INDEX_START + rr_graph_view.num_rr_segments());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,7 +166,9 @@ static void add_rr_graph_clock_nodes(RRGraphBuilder& rr_graph_builder,
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* Add edges for the clock nodes in a given connection block
|
* Add edges for the clock nodes in a given connection block
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
|
static
|
||||||
void add_rr_graph_block_clock_edges(RRGraphBuilder& rr_graph_builder,
|
void add_rr_graph_block_clock_edges(RRGraphBuilder& rr_graph_builder,
|
||||||
|
const RRClockSpatialLookup& clk_rr_lookup,
|
||||||
const RRGraphView& rr_graph_view,
|
const RRGraphView& rr_graph_view,
|
||||||
const ClockNetwork& clk_ntwk,
|
const ClockNetwork& clk_ntwk,
|
||||||
const vtr::Point<size_t> chan_coord,
|
const vtr::Point<size_t> chan_coord,
|
||||||
|
@ -176,10 +176,10 @@ void add_rr_graph_block_clock_edges(RRGraphBuilder& rr_graph_builder,
|
||||||
for (auto itree : clk_ntwk.trees()) {
|
for (auto itree : clk_ntwk.trees()) {
|
||||||
for (auto ilvl : clk_ntwk.levels(itree)) {
|
for (auto ilvl : clk_ntwk.levels(itree)) {
|
||||||
for (auto node_dir : {Direction::INC, Direction::DEC}) {
|
for (auto node_dir : {Direction::INC, Direction::DEC}) {
|
||||||
for (size_t itrack = 0;
|
for (auto ipin : clk_ntwk.pins(itree, ilvl, chan_type, node_dir)) {
|
||||||
itrack < clk_ntwk.num_tracks(itree, ilvl, chan_type, node_dir);
|
/* find the driver clock node through lookup */
|
||||||
++itrack) {
|
RRNodeId driver_node = clk_rr_lookup.find_node(chan_coord.x(), chan_coord.y(), itree, ilvl, ipin, node_dir);
|
||||||
/* TODO: find the driver clock node through lookup */
|
VTR_ASSERT(driver_node);
|
||||||
/* TODO: find the fan-out clock node through lookup */
|
/* TODO: find the fan-out clock node through lookup */
|
||||||
/* TODO: Create edges */
|
/* TODO: Create edges */
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,9 @@ void add_rr_graph_block_clock_edges(RRGraphBuilder& rr_graph_builder,
|
||||||
* v
|
* v
|
||||||
* clk0_lvl1_chany[1][1]
|
* clk0_lvl1_chany[1][1]
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
|
static
|
||||||
void add_rr_graph_clock_edges(RRGraphBuilder& rr_graph_builder,
|
void add_rr_graph_clock_edges(RRGraphBuilder& rr_graph_builder,
|
||||||
|
const RRClockSpatialLookup& clk_rr_lookup,
|
||||||
const RRGraphView& rr_graph_view,
|
const RRGraphView& rr_graph_view,
|
||||||
const DeviceGrid& grids,
|
const DeviceGrid& grids,
|
||||||
const bool& through_channel,
|
const bool& through_channel,
|
||||||
|
@ -223,7 +225,7 @@ void add_rr_graph_clock_edges(RRGraphBuilder& rr_graph_builder,
|
||||||
(false == is_chanx_exist(grids, chanx_coord))) {
|
(false == is_chanx_exist(grids, chanx_coord))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
add_rr_graph_block_clock_edges(rr_graph_builder, rr_graph_view, clk_ntwk,
|
add_rr_graph_block_clock_edges(rr_graph_builder, clk_rr_lookup, rr_graph_view, clk_ntwk,
|
||||||
chanx_coord, CHANX);
|
chanx_coord, CHANX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,7 +240,7 @@ void add_rr_graph_clock_edges(RRGraphBuilder& rr_graph_builder,
|
||||||
(false == is_chany_exist(grids, chany_coord))) {
|
(false == is_chany_exist(grids, chany_coord))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
add_rr_graph_block_clock_edges(rr_graph_builder, rr_graph_view, clk_ntwk,
|
add_rr_graph_block_clock_edges(rr_graph_builder, clk_rr_lookup, rr_graph_view, clk_ntwk,
|
||||||
chany_coord, CHANY);
|
chany_coord, CHANY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,7 +255,9 @@ void add_rr_graph_clock_edges(RRGraphBuilder& rr_graph_builder,
|
||||||
* - Sanity checks
|
* - Sanity checks
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
int append_clock_rr_graph(DeviceContext& vpr_device_ctx,
|
int append_clock_rr_graph(DeviceContext& vpr_device_ctx,
|
||||||
const ClockNetwork& clk_ntwk, const bool& verbose) {
|
RRClockSpatialLookup& clk_rr_lookup,
|
||||||
|
const ClockNetwork& clk_ntwk,
|
||||||
|
const bool& verbose) {
|
||||||
vtr::ScopedStartFinishTimer timer(
|
vtr::ScopedStartFinishTimer timer(
|
||||||
"Appending programmable clock network to routing resource graph");
|
"Appending programmable clock network to routing resource graph");
|
||||||
|
|
||||||
|
@ -282,6 +286,7 @@ int append_clock_rr_graph(DeviceContext& vpr_device_ctx,
|
||||||
|
|
||||||
/* Add clock nodes */
|
/* Add clock nodes */
|
||||||
add_rr_graph_clock_nodes(vpr_device_ctx.rr_graph_builder,
|
add_rr_graph_clock_nodes(vpr_device_ctx.rr_graph_builder,
|
||||||
|
clk_rr_lookup,
|
||||||
vpr_device_ctx.rr_graph, vpr_device_ctx.grid,
|
vpr_device_ctx.rr_graph, vpr_device_ctx.grid,
|
||||||
vpr_device_ctx.arch->through_channel, clk_ntwk);
|
vpr_device_ctx.arch->through_channel, clk_ntwk);
|
||||||
VTR_ASSERT(num_clock_nodes + orig_num_nodes ==
|
VTR_ASSERT(num_clock_nodes + orig_num_nodes ==
|
||||||
|
@ -290,6 +295,7 @@ int append_clock_rr_graph(DeviceContext& vpr_device_ctx,
|
||||||
/* TODO: Add edges between clock nodes*/
|
/* TODO: Add edges between clock nodes*/
|
||||||
size_t num_clock_edges = 0;
|
size_t num_clock_edges = 0;
|
||||||
add_rr_graph_clock_edges(vpr_device_ctx.rr_graph_builder,
|
add_rr_graph_clock_edges(vpr_device_ctx.rr_graph_builder,
|
||||||
|
static_cast<const RRClockSpatialLookup&>(clk_rr_lookup),
|
||||||
vpr_device_ctx.rr_graph, vpr_device_ctx.grid,
|
vpr_device_ctx.rr_graph, vpr_device_ctx.grid,
|
||||||
vpr_device_ctx.arch->through_channel, clk_ntwk);
|
vpr_device_ctx.arch->through_channel, clk_ntwk);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* Include header files that are required by function declaration
|
* Include header files that are required by function declaration
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
#include "clock_network.h"
|
#include "clock_network.h"
|
||||||
|
#include "rr_clock_spatial_lookup.h"
|
||||||
#include "vpr_context.h"
|
#include "vpr_context.h"
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
@ -15,7 +16,9 @@
|
||||||
namespace openfpga {
|
namespace openfpga {
|
||||||
|
|
||||||
int append_clock_rr_graph(DeviceContext& vpr_device_ctx,
|
int append_clock_rr_graph(DeviceContext& vpr_device_ctx,
|
||||||
const ClockNetwork& clk_ntwk, const bool& verbose);
|
RRClockSpatialLookup& clk_rr_lookup,
|
||||||
|
const ClockNetwork& clk_ntwk,
|
||||||
|
const bool& verbose);
|
||||||
|
|
||||||
} /* end namespace openfpga */
|
} /* end namespace openfpga */
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "bitstream_manager.h"
|
#include "bitstream_manager.h"
|
||||||
#include "bitstream_setting.h"
|
#include "bitstream_setting.h"
|
||||||
#include "clock_network.h"
|
#include "clock_network.h"
|
||||||
|
#include "rr_clock_spatial_lookup.h"
|
||||||
#include "decoder_library.h"
|
#include "decoder_library.h"
|
||||||
#include "device_rr_gsb.h"
|
#include "device_rr_gsb.h"
|
||||||
#include "fabric_bitstream.h"
|
#include "fabric_bitstream.h"
|
||||||
|
@ -63,6 +64,7 @@ class OpenfpgaContext : public Context {
|
||||||
return bitstream_setting_;
|
return bitstream_setting_;
|
||||||
}
|
}
|
||||||
const openfpga::ClockNetwork& clock_arch() const { return clock_arch_; }
|
const openfpga::ClockNetwork& clock_arch() const { return clock_arch_; }
|
||||||
|
const openfpga::RRClockSpatialLookup& clock_rr_lookup() const { return clock_rr_lookup_; }
|
||||||
const openfpga::VprDeviceAnnotation& vpr_device_annotation() const {
|
const openfpga::VprDeviceAnnotation& vpr_device_annotation() const {
|
||||||
return vpr_device_annotation_;
|
return vpr_device_annotation_;
|
||||||
}
|
}
|
||||||
|
@ -119,6 +121,7 @@ class OpenfpgaContext : public Context {
|
||||||
return bitstream_setting_;
|
return bitstream_setting_;
|
||||||
}
|
}
|
||||||
openfpga::ClockNetwork& mutable_clock_arch() { return clock_arch_; }
|
openfpga::ClockNetwork& mutable_clock_arch() { return clock_arch_; }
|
||||||
|
openfpga::RRClockSpatialLookup& mutable_clock_rr_lookup() { return clock_rr_lookup_; }
|
||||||
openfpga::VprDeviceAnnotation& mutable_vpr_device_annotation() {
|
openfpga::VprDeviceAnnotation& mutable_vpr_device_annotation() {
|
||||||
return vpr_device_annotation_;
|
return vpr_device_annotation_;
|
||||||
}
|
}
|
||||||
|
@ -169,6 +172,7 @@ class OpenfpgaContext : public Context {
|
||||||
openfpga::SimulationSetting sim_setting_;
|
openfpga::SimulationSetting sim_setting_;
|
||||||
openfpga::BitstreamSetting bitstream_setting_;
|
openfpga::BitstreamSetting bitstream_setting_;
|
||||||
openfpga::ClockNetwork clock_arch_;
|
openfpga::ClockNetwork clock_arch_;
|
||||||
|
openfpga::RRClockSpatialLookup clock_rr_lookup_;
|
||||||
|
|
||||||
/* Annotation to pb_type of VPR */
|
/* Annotation to pb_type of VPR */
|
||||||
openfpga::VprDeviceAnnotation vpr_device_annotation_;
|
openfpga::VprDeviceAnnotation vpr_device_annotation_;
|
||||||
|
|
|
@ -199,6 +199,7 @@ int append_clock_rr_graph_template(T& openfpga_ctx, const Command& cmd,
|
||||||
CommandOptionId opt_verbose = cmd.option("verbose");
|
CommandOptionId opt_verbose = cmd.option("verbose");
|
||||||
|
|
||||||
return append_clock_rr_graph(g_vpr_ctx.mutable_device(),
|
return append_clock_rr_graph(g_vpr_ctx.mutable_device(),
|
||||||
|
openfpga_ctx.mutable_clock_rr_lookup(),
|
||||||
openfpga_ctx.clock_arch(),
|
openfpga_ctx.clock_arch(),
|
||||||
cmd_context.option_enable(cmd, opt_verbose));
|
cmd_context.option_enable(cmd, opt_verbose));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue