add mapped block fast look-up as placement annotation
This commit is contained in:
parent
712eeb1340
commit
8e9660b816
|
@ -0,0 +1,34 @@
|
|||
/********************************************************************
|
||||
* This file includes functions that are used to annotate pb_graph_node
|
||||
* and pb_graph_pins from VPR to OpenFPGA
|
||||
*******************************************************************/
|
||||
/* Headers from vtrutil library */
|
||||
#include "vtr_assert.h"
|
||||
#include "vtr_log.h"
|
||||
#include "vtr_geometry.h"
|
||||
|
||||
#include "annotate_placement.h"
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* Assign mapped blocks to grid locations
|
||||
* This is used by bitstream generator mainly as a fast look-up to
|
||||
* get mapped blocks with a given coordinate
|
||||
*******************************************************************/
|
||||
void annotate_mapped_blocks(const DeviceContext& device_ctx,
|
||||
const ClusteringContext& cluster_ctx,
|
||||
const PlacementContext& place_ctx,
|
||||
VprPlacementAnnotation& place_annotation) {
|
||||
VTR_LOG("Building annotation for mapped blocks on grid locations...");
|
||||
|
||||
place_annotation.init_mapped_blocks(device_ctx.grid);
|
||||
for (const ClusterBlockId& blk_id : cluster_ctx.clb_nlist.blocks()) {
|
||||
vtr::Point<size_t> grid_coord(place_ctx.block_locs[blk_id].loc.x, place_ctx.block_locs[blk_id].loc.y);
|
||||
place_annotation.add_mapped_block(grid_coord, place_ctx.block_locs[blk_id].loc.z, blk_id);
|
||||
}
|
||||
VTR_LOG("Done\n");
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef ANNOTATE_PLACEMENT_H
|
||||
#define ANNOTATE_PLACEMENT_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files that are required by function declaration
|
||||
*******************************************************************/
|
||||
#include "vpr_context.h"
|
||||
#include "vpr_placement_annotation.h"
|
||||
|
||||
/********************************************************************
|
||||
* Function declaration
|
||||
*******************************************************************/
|
||||
|
||||
/* begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
void annotate_mapped_blocks(const DeviceContext& device_ctx,
|
||||
const ClusteringContext& cluster_ctx,
|
||||
const PlacementContext& place_ctx,
|
||||
VprPlacementAnnotation& place_annotation);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,49 @@
|
|||
/************************************************************************
|
||||
* Member functions for class VprPlacementAnnotation
|
||||
***********************************************************************/
|
||||
#include "vtr_log.h"
|
||||
#include "vtr_assert.h"
|
||||
#include "vpr_placement_annotation.h"
|
||||
|
||||
/* namespace openfpga begins */
|
||||
namespace openfpga {
|
||||
|
||||
/************************************************************************
|
||||
* Constructors
|
||||
***********************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Public accessors
|
||||
***********************************************************************/
|
||||
std::vector<ClusterBlockId> VprPlacementAnnotation::grid_blocks(const vtr::Point<size_t>& grid_coord) const {
|
||||
return blocks_[grid_coord.x()][grid_coord.y()];
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Public mutators
|
||||
***********************************************************************/
|
||||
void VprPlacementAnnotation::init_mapped_blocks(const DeviceGrid& grids) {
|
||||
/* Size the block array with grid sizes */
|
||||
blocks_.resize({grids.width(), grids.height()});
|
||||
|
||||
/* Resize the number of blocks allowed per grid by the capacity of the type */
|
||||
for (size_t x = 0; x < grids.width(); ++x) {
|
||||
for (size_t y = 0; y < grids.height(); ++y) {
|
||||
/* Deposit invalid ids and we will fill later */
|
||||
blocks_[x][y].resize(grids[x][y].type->capacity, ClusterBlockId::INVALID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VprPlacementAnnotation::add_mapped_block(const vtr::Point<size_t>& grid_coord,
|
||||
const size_t& z,
|
||||
const ClusterBlockId& mapped_block) {
|
||||
VTR_ASSERT(z < grid_blocks(grid_coord).size());
|
||||
if (ClusterBlockId::INVALID() != blocks_[grid_coord.x()][grid_coord.y()][z]) {
|
||||
VTR_LOG("Override mapped blocks at grid[%lu][%lu][%lu]!\n",
|
||||
grid_coord.x(), grid_coord.y(), z);
|
||||
}
|
||||
blocks_[grid_coord.x()][grid_coord.y()][z] = mapped_block;
|
||||
}
|
||||
|
||||
} /* End namespace openfpga*/
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef VPR_PLACEMENT_ANNOTATION_H
|
||||
#define VPR_PLACEMENT_ANNOTATION_H
|
||||
|
||||
/********************************************************************
|
||||
* Include header files required by the data structure definition
|
||||
*******************************************************************/
|
||||
#include <map>
|
||||
|
||||
/* Header from vtrutil library */
|
||||
#include "vtr_geometry.h"
|
||||
|
||||
/* Header from vpr library */
|
||||
#include "device_grid.h"
|
||||
#include "clustered_netlist.h"
|
||||
|
||||
/* Begin namespace openfpga */
|
||||
namespace openfpga {
|
||||
|
||||
/********************************************************************
|
||||
* This is the critical data structure to annotate placement results
|
||||
* in VPR context
|
||||
*******************************************************************/
|
||||
class VprPlacementAnnotation {
|
||||
public: /* Public accessors */
|
||||
std::vector<ClusterBlockId> grid_blocks(const vtr::Point<size_t>& grid_coord) const;
|
||||
public: /* Public mutators */
|
||||
void init_mapped_blocks(const DeviceGrid& grids);
|
||||
void add_mapped_block(const vtr::Point<size_t>& grid_coord,
|
||||
const size_t& z, const ClusterBlockId& mapped_block);
|
||||
private: /* Internal data */
|
||||
/* A direct mapping show each mapped/unmapped blocks in grids
|
||||
* The blocks_ array represents each grid on the FPGA fabric
|
||||
* For example, block_[x][y] showed the mapped/unmapped blocks
|
||||
* at grid[x][y]. The third coordinate 'z' is the index of the same
|
||||
* type of blocks in the grids. This is mainly applied to I/O
|
||||
* blocks where you may have >1 I/O in a grid
|
||||
*
|
||||
* Note that this is different from the grid blocks in PlacementContext
|
||||
* VPR considers only mapped blocks while this annotation
|
||||
* considers both unmapped and mapped blocks
|
||||
* Unmapped blocks will be labelled as an invalid id in the vector
|
||||
*/
|
||||
vtr::Matrix<std::vector<ClusterBlockId>> blocks_;
|
||||
};
|
||||
|
||||
} /* End namespace openfpga*/
|
||||
|
||||
#endif
|
|
@ -6,6 +6,7 @@
|
|||
#include "vpr_netlist_annotation.h"
|
||||
#include "vpr_device_annotation.h"
|
||||
#include "vpr_clustering_annotation.h"
|
||||
#include "vpr_placement_annotation.h"
|
||||
#include "vpr_routing_annotation.h"
|
||||
#include "mux_library.h"
|
||||
#include "tile_direct.h"
|
||||
|
@ -47,6 +48,7 @@ class OpenfpgaContext : public Context {
|
|||
const openfpga::VprDeviceAnnotation& vpr_device_annotation() const { return vpr_device_annotation_; }
|
||||
const openfpga::VprNetlistAnnotation& vpr_netlist_annotation() const { return vpr_netlist_annotation_; }
|
||||
const openfpga::VprClusteringAnnotation& vpr_clustering_annotation() const { return vpr_clustering_annotation_; }
|
||||
const openfpga::VprPlacementAnnotation& vpr_placement_annotation() const { return vpr_placement_annotation_; }
|
||||
const openfpga::VprRoutingAnnotation& vpr_routing_annotation() const { return vpr_routing_annotation_; }
|
||||
const openfpga::DeviceRRGSB& device_rr_gsb() const { return device_rr_gsb_; }
|
||||
const openfpga::MuxLibrary& mux_lib() const { return mux_lib_; }
|
||||
|
@ -59,6 +61,7 @@ class OpenfpgaContext : public Context {
|
|||
openfpga::VprDeviceAnnotation& mutable_vpr_device_annotation() { return vpr_device_annotation_; }
|
||||
openfpga::VprNetlistAnnotation& mutable_vpr_netlist_annotation() { return vpr_netlist_annotation_; }
|
||||
openfpga::VprClusteringAnnotation& mutable_vpr_clustering_annotation() { return vpr_clustering_annotation_; }
|
||||
openfpga::VprPlacementAnnotation& mutable_vpr_placement_annotation() { return vpr_placement_annotation_; }
|
||||
openfpga::VprRoutingAnnotation& mutable_vpr_routing_annotation() { return vpr_routing_annotation_; }
|
||||
openfpga::DeviceRRGSB& mutable_device_rr_gsb() { return device_rr_gsb_; }
|
||||
openfpga::MuxLibrary& mutable_mux_lib() { return mux_lib_; }
|
||||
|
@ -79,6 +82,9 @@ class OpenfpgaContext : public Context {
|
|||
/* Pin net fix to cluster results */
|
||||
openfpga::VprClusteringAnnotation vpr_clustering_annotation_;
|
||||
|
||||
/* Placement results */
|
||||
openfpga::VprPlacementAnnotation vpr_placement_annotation_;
|
||||
|
||||
/* Routing results annotation */
|
||||
openfpga::VprRoutingAnnotation vpr_routing_annotation_;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "annotate_rr_graph.h"
|
||||
#include "mux_library_builder.h"
|
||||
#include "build_tile_direct.h"
|
||||
#include "annotate_placement.h"
|
||||
#include "openfpga_link_arch.h"
|
||||
|
||||
/* Include global variables of VPR */
|
||||
|
@ -111,6 +112,12 @@ void link_arch(OpenfpgaContext& openfpga_ctx,
|
|||
/* Build tile direct annotation */
|
||||
openfpga_ctx.mutable_tile_direct() = build_device_tile_direct(g_vpr_ctx.device(),
|
||||
openfpga_ctx.arch().arch_direct);
|
||||
|
||||
/* Annotate placement results */
|
||||
annotate_mapped_blocks(g_vpr_ctx.device(),
|
||||
g_vpr_ctx.clustering(),
|
||||
g_vpr_ctx.placement(),
|
||||
openfpga_ctx.mutable_vpr_placement_annotation());
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -914,35 +914,15 @@ void build_physical_tile_module(ModuleManager& module_manager,
|
|||
ModuleId grid_module = module_manager.add_module(grid_module_name);
|
||||
VTR_ASSERT(true == module_manager.valid_module_id(grid_module));
|
||||
|
||||
/* Now each physical tile may have a number of diffrent logical blocks
|
||||
* We assume the following organization:
|
||||
*
|
||||
* Physical tile
|
||||
* +-----------------------
|
||||
* |
|
||||
* | pb_typeA[0] - from equivalent site[A]
|
||||
* | +--------------------
|
||||
* | |
|
||||
* | +--------------------
|
||||
* |
|
||||
* | pb_typeB[0] - from equivalent site[B]
|
||||
* | +--------------------
|
||||
* | |
|
||||
* | +--------------------
|
||||
* ... ...
|
||||
* | pb_typeA[capacity - 1] - from equivalent site[A]
|
||||
* | +--------------------
|
||||
* | |
|
||||
* | +--------------------
|
||||
* |
|
||||
* | pb_typeB[capacity - 1] - from equivalent site[B]
|
||||
* | +--------------------
|
||||
* | |
|
||||
* | +--------------------
|
||||
* |
|
||||
* +-----------------------
|
||||
/* Now each physical tile may have a number of logical blocks
|
||||
* OpenFPGA only considers the physical implementation of the tiles.
|
||||
* So, we do not allow multiple equivalent sites to be defined
|
||||
* under a physical tile type.
|
||||
* If you need different equivalent sites, you can always define
|
||||
* it as a mode under a <pb_type>
|
||||
*/
|
||||
for (int iz = 0; iz < phy_block_type->capacity; ++iz) {
|
||||
VTR_ASSERT(1 == phy_block_type->equivalent_sites.size());
|
||||
for (t_logical_block_type_ptr lb_type : phy_block_type->equivalent_sites) {
|
||||
/* Bypass empty pb_graph */
|
||||
if (nullptr == lb_type->pb_graph_head) {
|
||||
|
|
Loading…
Reference in New Issue