add save repacking results in physical pb
This commit is contained in:
parent
12f2888c7c
commit
926e429374
|
@ -36,6 +36,17 @@ PhysicalPbId PhysicalPb::parent(const PhysicalPbId& pb) const {
|
|||
return parent_pbs_[pb];
|
||||
}
|
||||
|
||||
AtomNetId PhysicalPb::pb_graph_pin_atom_net(const PhysicalPbId& pb,
|
||||
const t_pb_graph_pin* pb_graph_pin) const {
|
||||
VTR_ASSERT(true == valid_pb_id(pb));
|
||||
if (pin_atom_nets_[pb].find(pb_graph_pin) != pin_atom_nets_[pb].end()) {
|
||||
/* Find it, return the id */
|
||||
return pin_atom_nets_[pb].at(pb_graph_pin);
|
||||
}
|
||||
/* Not found, return an invalid id */
|
||||
return AtomNetId::INVALID();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Private Mutators
|
||||
******************************************************************************/
|
||||
|
@ -53,9 +64,12 @@ PhysicalPbId PhysicalPb::create_pb(const t_pb_graph_node* pb_graph_node) {
|
|||
/* Allocate other attributes */
|
||||
names_.emplace_back();
|
||||
pb_graph_nodes_.push_back(pb_graph_node);
|
||||
mapped_atoms_.emplace_back();
|
||||
atom_blocks_.emplace_back();
|
||||
pin_atom_nets_.emplace_back();
|
||||
|
||||
child_pbs_.emplace_back();
|
||||
parent_pbs_.emplace_back();
|
||||
|
||||
mode_bits_.emplace_back();
|
||||
|
||||
/* Register in the name2id map */
|
||||
|
@ -82,6 +96,34 @@ void PhysicalPb::add_child(const PhysicalPbId& parent,
|
|||
parent_pbs_[child] = parent;
|
||||
}
|
||||
|
||||
void PhysicalPb::set_mode_bits(const PhysicalPbId& pb,
|
||||
const std::vector<size_t>& mode_bits) {
|
||||
VTR_ASSERT(true == valid_pb_id(pb));
|
||||
|
||||
mode_bits_[pb] = mode_bits;
|
||||
}
|
||||
|
||||
void PhysicalPb::add_atom_block(const PhysicalPbId& pb,
|
||||
const AtomBlockId& atom_block) {
|
||||
VTR_ASSERT(true == valid_pb_id(pb));
|
||||
|
||||
atom_blocks_[pb].push_back(atom_block);
|
||||
}
|
||||
|
||||
void PhysicalPb::set_pb_graph_pin_atom_net(const PhysicalPbId& pb,
|
||||
const t_pb_graph_pin* pb_graph_pin,
|
||||
const AtomNetId& atom_net) {
|
||||
VTR_ASSERT(true == valid_pb_id(pb));
|
||||
if (pin_atom_nets_[pb].end() != pin_atom_nets_[pb].find(pb_graph_pin)) {
|
||||
VTR_LOG_WARN("Overwrite pb_graph_pin '%s[%d]' atom net '%lu' with '%lu'\n",
|
||||
pb_graph_pin->port->name, pb_graph_pin->pin_number,
|
||||
size_t(pin_atom_nets_[pb][pb_graph_pin]),
|
||||
size_t(atom_net));
|
||||
}
|
||||
|
||||
pin_atom_nets_[pb][pb_graph_pin] = atom_net;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Private validators/invalidators
|
||||
******************************************************************************/
|
||||
|
|
|
@ -42,11 +42,20 @@ class PhysicalPb {
|
|||
std::string name(const PhysicalPbId& pb) const;
|
||||
PhysicalPbId find_pb(const t_pb_graph_node* name) const;
|
||||
PhysicalPbId parent(const PhysicalPbId& pb) const;
|
||||
AtomNetId pb_graph_pin_atom_net(const PhysicalPbId& pb,
|
||||
const t_pb_graph_pin* pb_graph_pin) const;
|
||||
public: /* Public mutators */
|
||||
PhysicalPbId create_pb(const t_pb_graph_node* pb_graph_node);
|
||||
void add_child(const PhysicalPbId& parent,
|
||||
const PhysicalPbId& child,
|
||||
const t_pb_type* child_type);
|
||||
void add_atom_block(const PhysicalPbId& pb,
|
||||
const AtomBlockId& atom_block);
|
||||
void set_mode_bits(const PhysicalPbId& pb,
|
||||
const std::vector<size_t>& mode_bits);
|
||||
void set_pb_graph_pin_atom_net(const PhysicalPbId& pb,
|
||||
const t_pb_graph_pin* pb_graph_pin,
|
||||
const AtomNetId& atom_net);
|
||||
public: /* Public validators/invalidators */
|
||||
bool valid_pb_id(const PhysicalPbId& pb_id) const;
|
||||
bool empty() const;
|
||||
|
@ -54,7 +63,8 @@ class PhysicalPb {
|
|||
vtr::vector<PhysicalPbId, PhysicalPbId> pb_ids_;
|
||||
vtr::vector<PhysicalPbId, const t_pb_graph_node*> pb_graph_nodes_;
|
||||
vtr::vector<PhysicalPbId, std::string> names_;
|
||||
vtr::vector<PhysicalPbId, std::vector<AtomBlockId>> mapped_atoms_;
|
||||
vtr::vector<PhysicalPbId, std::vector<AtomBlockId>> atom_blocks_;
|
||||
vtr::vector<PhysicalPbId, std::map<const t_pb_graph_pin*, AtomNetId>> pin_atom_nets_;
|
||||
|
||||
/* Child pbs are organized as [0..num_child_pb_types-1][0..child_pb_type->num_pb-1] */
|
||||
vtr::vector<PhysicalPbId, std::map<const t_pb_type*, std::vector<PhysicalPbId>>> child_pbs_;
|
||||
|
|
|
@ -242,8 +242,7 @@ void add_lb_router_nets(LbRouter& lb_router,
|
|||
* - Output routing results to data structure PhysicalPb and store it in clustering annotation
|
||||
***************************************************************************************/
|
||||
static
|
||||
void repack_cluster(const DeviceContext& device_ctx,
|
||||
const AtomContext& atom_ctx,
|
||||
void repack_cluster(const AtomContext& atom_ctx,
|
||||
const ClusteringContext& clustering_ctx,
|
||||
const VprDeviceAnnotation& device_annotation,
|
||||
VprClusteringAnnotation& clustering_annotation,
|
||||
|
@ -288,7 +287,13 @@ void repack_cluster(const DeviceContext& device_ctx,
|
|||
/* Annotate routing results to physical pb */
|
||||
PhysicalPb phy_pb;
|
||||
alloc_physical_pb_from_pb_graph(phy_pb, pb_graph_head, device_annotation);
|
||||
rec_update_physical_pb_from_operating_pb(phy_pb, clustering_ctx.clb_nlist.block_pb(block_id));
|
||||
rec_update_physical_pb_from_operating_pb(phy_pb,
|
||||
clustering_ctx.clb_nlist.block_pb(block_id),
|
||||
clustering_ctx.clb_nlist.block_pb(block_id)->pb_route,
|
||||
atom_ctx,
|
||||
device_annotation);
|
||||
/* TODO: save routing results */
|
||||
VTR_LOGV(verbose, "Saved results in physical pb\n");
|
||||
|
||||
/* Add the pb to clustering context */
|
||||
clustering_annotation.add_physical_pb(block_id, phy_pb);
|
||||
|
@ -300,8 +305,7 @@ void repack_cluster(const DeviceContext& device_ctx,
|
|||
* Repack each clustered blocks in the clustering context
|
||||
***************************************************************************************/
|
||||
static
|
||||
void repack_clusters(const DeviceContext& device_ctx,
|
||||
const AtomContext& atom_ctx,
|
||||
void repack_clusters(const AtomContext& atom_ctx,
|
||||
const ClusteringContext& clustering_ctx,
|
||||
const VprDeviceAnnotation& device_annotation,
|
||||
VprClusteringAnnotation& clustering_annotation,
|
||||
|
@ -309,7 +313,7 @@ void repack_clusters(const DeviceContext& device_ctx,
|
|||
vtr::ScopedStartFinishTimer timer("Repack clustered blocks to physical implementation of logical tile");
|
||||
|
||||
for (auto blk_id : clustering_ctx.clb_nlist.blocks()) {
|
||||
repack_cluster(device_ctx, atom_ctx, clustering_ctx,
|
||||
repack_cluster(atom_ctx, clustering_ctx,
|
||||
device_annotation, clustering_annotation,
|
||||
blk_id, verbose);
|
||||
}
|
||||
|
@ -338,7 +342,7 @@ void pack_physical_pbs(const DeviceContext& device_ctx,
|
|||
verbose);
|
||||
|
||||
/* Call the LbRouter to re-pack each clustered block to physical implementation */
|
||||
repack_clusters(device_ctx, atom_ctx, clustering_ctx,
|
||||
repack_clusters(atom_ctx, clustering_ctx,
|
||||
const_cast<const VprDeviceAnnotation&>(device_annotation), clustering_annotation,
|
||||
verbose);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace openfpga {
|
|||
***********************************************************************/
|
||||
static
|
||||
void rec_alloc_physical_pb_from_pb_graph(PhysicalPb& phy_pb,
|
||||
t_pb_graph_node* pb_graph_node,
|
||||
const t_pb_graph_node* pb_graph_node,
|
||||
const VprDeviceAnnotation& device_annotation) {
|
||||
t_pb_type* pb_type = pb_graph_node->pb_type;
|
||||
|
||||
|
@ -57,7 +57,7 @@ void rec_alloc_physical_pb_from_pb_graph(PhysicalPb& phy_pb,
|
|||
***********************************************************************/
|
||||
static
|
||||
void rec_build_physical_pb_children_from_pb_graph(PhysicalPb& phy_pb,
|
||||
t_pb_graph_node* pb_graph_node,
|
||||
const t_pb_graph_node* pb_graph_node,
|
||||
const VprDeviceAnnotation& device_annotation) {
|
||||
t_pb_type* pb_type = pb_graph_node->pb_type;
|
||||
|
||||
|
@ -101,7 +101,7 @@ void rec_build_physical_pb_children_from_pb_graph(PhysicalPb& phy_pb,
|
|||
* VTR_ASSERT(true == phy_pb.empty());
|
||||
***********************************************************************/
|
||||
void alloc_physical_pb_from_pb_graph(PhysicalPb& phy_pb,
|
||||
t_pb_graph_node* pb_graph_head,
|
||||
const t_pb_graph_node* pb_graph_head,
|
||||
const VprDeviceAnnotation& device_annotation) {
|
||||
VTR_ASSERT(true == phy_pb.empty());
|
||||
|
||||
|
@ -109,11 +109,164 @@ void alloc_physical_pb_from_pb_graph(PhysicalPb& phy_pb,
|
|||
rec_build_physical_pb_children_from_pb_graph(phy_pb, pb_graph_head, device_annotation);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Update a mapping net from a pin of an operating primitive pb to a
|
||||
* physical pb data base
|
||||
***********************************************************************/
|
||||
static
|
||||
void update_primitive_physical_pb_pin_atom_net(PhysicalPb& phy_pb,
|
||||
const PhysicalPbId& primitive_pb,
|
||||
const t_pb_graph_pin* pb_graph_pin,
|
||||
const t_pb_routes& pb_route,
|
||||
const VprDeviceAnnotation& device_annotation) {
|
||||
int node_index = pb_graph_pin->pin_count_in_cluster;
|
||||
if (pb_route.count(node_index)) {
|
||||
/* The pin is mapped to a net, find the original pin in the atom netlist */
|
||||
AtomNetId atom_net = pb_route[node_index].atom_net_id;
|
||||
|
||||
VTR_ASSERT(atom_net);
|
||||
|
||||
/* Find the physical pb_graph_pin */
|
||||
t_pb_graph_pin* physical_pb_graph_pin = device_annotation.physical_pb_graph_pin((t_pb_graph_pin*)pb_graph_pin);
|
||||
VTR_ASSERT(nullptr != physical_pb_graph_pin);
|
||||
|
||||
/* Check if the pin has been mapped to a net.
|
||||
* If yes, the atom net must be the same
|
||||
*/
|
||||
if (AtomNetId::INVALID() == phy_pb.pb_graph_pin_atom_net(primitive_pb, physical_pb_graph_pin)) {
|
||||
phy_pb.set_pb_graph_pin_atom_net(primitive_pb, physical_pb_graph_pin, atom_net);
|
||||
} else {
|
||||
VTR_ASSERT(atom_net == phy_pb.pb_graph_pin_atom_net(primitive_pb, physical_pb_graph_pin));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Synchronize mapping nets from an operating primitive pb to a physical pb
|
||||
***********************************************************************/
|
||||
static
|
||||
void synchronize_primitive_physical_pb_atom_nets(PhysicalPb& phy_pb,
|
||||
const PhysicalPbId& primitive_pb,
|
||||
const t_pb_graph_node* pb_graph_node,
|
||||
const t_pb_routes& pb_route,
|
||||
const AtomContext& atom_ctx,
|
||||
const AtomBlockId& atom_blk,
|
||||
const VprDeviceAnnotation& device_annotation) {
|
||||
/* Iterate over all the ports: input, output and clock */
|
||||
for (int iport = 0; iport < pb_graph_node->num_input_ports; ++iport) {
|
||||
for (int ipin = 0; ipin < pb_graph_node->num_input_pins[iport]; ++ipin) {
|
||||
/* Port exists (some LUTs may have no input and hence no port in the atom netlist) */
|
||||
t_model_ports* model_port = pb_graph_node->input_pins[iport][ipin].port->model_port;
|
||||
if (nullptr == model_port) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AtomPortId atom_port = atom_ctx.nlist.find_atom_port(atom_blk, model_port);
|
||||
if (!atom_port) {
|
||||
continue;
|
||||
}
|
||||
/* Find the atom nets mapped to the pin
|
||||
* Note that some inputs may not be used, we set them to be open by default
|
||||
*/
|
||||
update_primitive_physical_pb_pin_atom_net(phy_pb, primitive_pb,
|
||||
&(pb_graph_node->input_pins[iport][ipin]),
|
||||
pb_route, device_annotation);
|
||||
}
|
||||
}
|
||||
|
||||
for (int iport = 0; iport < pb_graph_node->num_output_ports; ++iport) {
|
||||
for (int ipin = 0; ipin < pb_graph_node->num_output_pins[iport]; ++ipin) {
|
||||
/* Port exists (some LUTs may have no input and hence no port in the atom netlist) */
|
||||
t_model_ports* model_port = pb_graph_node->output_pins[iport][ipin].port->model_port;
|
||||
if (nullptr == model_port) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AtomPortId atom_port = atom_ctx.nlist.find_atom_port(atom_blk, model_port);
|
||||
if (!atom_port) {
|
||||
continue;
|
||||
}
|
||||
/* Find the atom nets mapped to the pin
|
||||
* Note that some inputs may not be used, we set them to be open by default
|
||||
*/
|
||||
update_primitive_physical_pb_pin_atom_net(phy_pb, primitive_pb,
|
||||
&(pb_graph_node->output_pins[iport][ipin]),
|
||||
pb_route, device_annotation);
|
||||
}
|
||||
}
|
||||
|
||||
for (int iport = 0; iport < pb_graph_node->num_clock_ports; ++iport) {
|
||||
for (int ipin = 0; ipin < pb_graph_node->num_clock_pins[iport]; ++ipin) {
|
||||
/* Port exists (some LUTs may have no input and hence no port in the atom netlist) */
|
||||
t_model_ports* model_port = pb_graph_node->clock_pins[iport][ipin].port->model_port;
|
||||
if (nullptr == model_port) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AtomPortId atom_port = atom_ctx.nlist.find_atom_port(atom_blk, model_port);
|
||||
if (!atom_port) {
|
||||
continue;
|
||||
}
|
||||
/* Find the atom nets mapped to the pin
|
||||
* Note that some inputs may not be used, we set them to be open by default
|
||||
*/
|
||||
update_primitive_physical_pb_pin_atom_net(phy_pb, primitive_pb,
|
||||
&(pb_graph_node->clock_pins[iport][ipin]),
|
||||
pb_route, device_annotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Synchronize mapping results from an operating pb to a physical pb
|
||||
***********************************************************************/
|
||||
void rec_update_physical_pb_from_operating_pb(PhysicalPb& phy_pb,
|
||||
t_pb* op_pb) {
|
||||
const t_pb* op_pb,
|
||||
const t_pb_routes& pb_route,
|
||||
const AtomContext& atom_ctx,
|
||||
const VprDeviceAnnotation& device_annotation) {
|
||||
t_pb_graph_node* pb_graph_node = op_pb->pb_graph_node;
|
||||
t_pb_type* pb_type = pb_graph_node->pb_type;
|
||||
|
||||
if (true == is_primitive_pb_type(pb_type)) {
|
||||
t_pb_graph_node* physical_pb_graph_node = device_annotation.physical_pb_graph_node(pb_graph_node);
|
||||
VTR_ASSERT(nullptr != physical_pb_graph_node);
|
||||
/* Find the physical pb */
|
||||
const PhysicalPbId& physical_pb = phy_pb.find_pb(physical_pb_graph_node);
|
||||
VTR_ASSERT(true == phy_pb.valid_pb_id(physical_pb));
|
||||
|
||||
/* Set the mode bits */
|
||||
phy_pb.set_mode_bits(physical_pb, device_annotation.pb_type_mode_bits(physical_pb_graph_node->pb_type));
|
||||
|
||||
/* Find mapped atom block and add to this physical pb */
|
||||
AtomBlockId atom_blk = atom_ctx.nlist.find_block(op_pb->name);
|
||||
VTR_ASSERT(atom_blk);
|
||||
|
||||
phy_pb.add_atom_block(physical_pb, atom_blk);
|
||||
|
||||
/* TODO: Iterate over ports and annotate the atom pins */
|
||||
synchronize_primitive_physical_pb_atom_nets(phy_pb, physical_pb,
|
||||
pb_graph_node,
|
||||
pb_route,
|
||||
atom_ctx, atom_blk,
|
||||
device_annotation);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Walk through the pb recursively but only visit the mapped modes and child pbs */
|
||||
t_mode* mapped_mode = &(pb_graph_node->pb_type->modes[op_pb->mode]);
|
||||
for (int ipb = 0; ipb < mapped_mode->num_pb_type_children; ++ipb) {
|
||||
/* Each child may exist multiple times in the hierarchy*/
|
||||
for (int jpb = 0; jpb < mapped_mode->pb_type_children[ipb].num_pb; ++jpb) {
|
||||
if ((nullptr != op_pb->child_pbs[ipb]) && (nullptr != op_pb->child_pbs[ipb][jpb].name)) {
|
||||
rec_update_physical_pb_from_operating_pb(phy_pb,
|
||||
&(op_pb->child_pbs[ipb][jpb]),
|
||||
pb_route,
|
||||
atom_ctx,
|
||||
device_annotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <vector>
|
||||
#include "physical_types.h"
|
||||
#include "vpr_device_annotation.h"
|
||||
#include "vpr_context.h"
|
||||
#include "physical_pb.h"
|
||||
|
||||
/********************************************************************
|
||||
|
@ -20,11 +21,14 @@
|
|||
namespace openfpga {
|
||||
|
||||
void alloc_physical_pb_from_pb_graph(PhysicalPb& phy_pb,
|
||||
t_pb_graph_node* pb_graph_head,
|
||||
const t_pb_graph_node* pb_graph_head,
|
||||
const VprDeviceAnnotation& device_annotation);
|
||||
|
||||
void rec_update_physical_pb_from_operating_pb(PhysicalPb& phy_pb,
|
||||
t_pb* op_pb);
|
||||
const t_pb* op_pb,
|
||||
const t_pb_routes& pb_route,
|
||||
const AtomContext& atom_ctx,
|
||||
const VprDeviceAnnotation& device_annotation);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
|
|
Loading…
Reference in New Issue