add mapped block fast look-up as placement annotation

This commit is contained in:
tangxifan 2020-02-24 16:09:29 -07:00
parent 712eeb1340
commit 8e9660b816
7 changed files with 177 additions and 29 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 */
@ -109,8 +110,14 @@ void link_arch(OpenfpgaContext& openfpga_ctx,
const_cast<const 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);
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 */

View File

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