Skip to content

Commit

Permalink
Merge pull request #2733 from AlexandreSinger/feature-ap-upstreaming
Browse files Browse the repository at this point in the history
[AP] Created The APNetlist Class
  • Loading branch information
vaughnbetz authored Sep 23, 2024
2 parents f92efd7 + 4bcb6d6 commit 2c2af51
Show file tree
Hide file tree
Showing 4 changed files with 570 additions and 0 deletions.
200 changes: 200 additions & 0 deletions vpr/src/analytical_place/ap_netlist.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
/**
* @file
* @author Alex Singer
* @date September 2024
* @brief The definitions of the APNetlist methods
*/

#include "ap_netlist.h"
#include <string>
#include "netlist_fwd.h"
#include "netlist_utils.h"
#include "vpr_types.h"
#include "vtr_assert.h"

/*
* Blocks
*/
const t_pack_molecule* APNetlist::block_molecule(const APBlockId id) const {
VTR_ASSERT_SAFE(valid_block_id(id));

return block_molecules_[id];
}

APBlockMobility APNetlist::block_mobility(const APBlockId id) const {
VTR_ASSERT_SAFE(valid_block_id(id));

return block_mobilities_[id];
}

const APFixedBlockLoc& APNetlist::block_loc(const APBlockId id) const {
VTR_ASSERT_SAFE(valid_block_id(id));
VTR_ASSERT(block_mobility(id) == APBlockMobility::FIXED);

return block_locs_[id];
}

/*
* Mutators
*/
APBlockId APNetlist::create_block(const std::string& name, const t_pack_molecule* mol) {
APBlockId blk_id = Netlist::create_block(name);

// Initialize the data
block_molecules_.insert(blk_id, mol);
block_mobilities_.insert(blk_id, APBlockMobility::MOVEABLE);
block_locs_.insert(blk_id, APFixedBlockLoc());

// Check post-conditions: size
VTR_ASSERT(validate_block_sizes());

// Check post-conditions: values
VTR_ASSERT(block_molecule(blk_id) == mol);
VTR_ASSERT(block_mobility(blk_id) == APBlockMobility::MOVEABLE);

return blk_id;
}

void APNetlist::set_block_loc(const APBlockId id, const APFixedBlockLoc& loc) {
VTR_ASSERT_SAFE(valid_block_id(id));

// Check that the location is fixed, if all values are -1 then it is not fixed.
if (loc.x == -1 && loc.y == -1 && loc.sub_tile == -1 && loc.layer_num == -1)
return;

block_locs_[id] = loc;
block_mobilities_[id] = APBlockMobility::FIXED;
}

APPortId APNetlist::create_port(const APBlockId blk_id, const std::string& name, BitIndex width, PortType type) {
APPortId port_id = find_port(blk_id, name);
if (!port_id) {
port_id = Netlist::create_port(blk_id, name, width, type);
associate_port_with_block(port_id, type, blk_id);
}

// Check post-conditions: size
VTR_ASSERT(validate_port_sizes());

// Check post-conditions: values
VTR_ASSERT(port_name(port_id) == name);
VTR_ASSERT(find_port(blk_id, name) == port_id);

return port_id;
}

APPinId APNetlist::create_pin(const APPortId port_id, BitIndex port_bit, const APNetId net_id, const PinType pin_type_, bool is_const) {
APPinId pin_id = Netlist::create_pin(port_id, port_bit, net_id, pin_type_, is_const);

// Check post-conditions: size
VTR_ASSERT(validate_pin_sizes());

// Check post-conditions: values
VTR_ASSERT(pin_type(pin_id) == pin_type_);
VTR_ASSERT(pin_port(pin_id) == port_id);
VTR_ASSERT(pin_port_type(pin_id) == port_type(port_id));

return pin_id;
}

APNetId APNetlist::create_net(const std::string& name) {
APNetId net_id = Netlist::create_net(name);

// Check post-conditions: size
VTR_ASSERT(validate_net_sizes());

return net_id;
}

/*
* Internal utilities
*/
void APNetlist::clean_blocks_impl(const vtr::vector_map<APBlockId, APBlockId>& block_id_map) {
// Update all the block molecules
block_molecules_ = clean_and_reorder_values(block_molecules_, block_id_map);
// Update all the block mobilities
block_mobilities_ = clean_and_reorder_values(block_mobilities_, block_id_map);
// Update the fixed block locations
block_locs_ = clean_and_reorder_values(block_locs_, block_id_map);
}

void APNetlist::clean_ports_impl(const vtr::vector_map<APPortId, APPortId>& /*port_id_map*/) {
// Unused
}

void APNetlist::clean_pins_impl(const vtr::vector_map<APPinId, APPinId>& /*pin_id_map*/) {
// Unused
}

void APNetlist::clean_nets_impl(const vtr::vector_map<APNetId, APNetId>& /*net_id_map*/) {
// Unused
}

void APNetlist::rebuild_block_refs_impl(const vtr::vector_map<APPinId, APPinId>& /*pin_id_map*/,
const vtr::vector_map<APPortId, APPortId>& /*port_id_map*/) {
// Unused
}

void APNetlist::rebuild_port_refs_impl(const vtr::vector_map<APBlockId, APBlockId>& /*block_id_map*/, const vtr::vector_map<APPinId, APPinId>& /*pin_id_map*/) {
// Unused
}

void APNetlist::rebuild_pin_refs_impl(const vtr::vector_map<APPortId, APPortId>& /*port_id_map*/, const vtr::vector_map<APNetId, APNetId>& /*net_id_map*/) {
// Unused
}

void APNetlist::rebuild_net_refs_impl(const vtr::vector_map<APPinId, APPinId>& /*pin_id_map*/) {
// Unused
}

void APNetlist::shrink_to_fit_impl() {
// Block data
block_molecules_.shrink_to_fit();
block_mobilities_.shrink_to_fit();
block_locs_.shrink_to_fit();
}

void APNetlist::remove_block_impl(const APBlockId /*blk_id*/) {
// Unused
}

void APNetlist::remove_port_impl(const APPortId /*port_id*/) {
// Unused
}

void APNetlist::remove_pin_impl(const APPinId /*pin_id*/) {
// Unused
}

void APNetlist::remove_net_impl(const APNetId /*net_id*/) {
// Unused
}

/*
* Sanity Checks
*/
bool APNetlist::validate_block_sizes_impl(size_t num_blocks) const {
if (block_molecules_.size() != num_blocks)
return false;
if (block_mobilities_.size() != num_blocks)
return false;
if (block_locs_.size() != num_blocks)
return false;
return true;
}

bool APNetlist::validate_port_sizes_impl(size_t /*num_ports*/) const {
// No AP-specific port data to check
return true;
}

bool APNetlist::validate_pin_sizes_impl(size_t /*num_pins*/) const {
// No AP-specific pin data to check
return true;
}

bool APNetlist::validate_net_sizes_impl(size_t /*num_nets*/) const {
// No AP-specific net data to check
return true;
}

189 changes: 189 additions & 0 deletions vpr/src/analytical_place/ap_netlist.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/**
* @file
* @author Alex Singer
* @date September 2024
* @brief Defines the APNetlist class used to store the connectivity of
* primitives in the Analytical Placement context.
*
* In the context of Analytical Placement, a block is a collection of atoms
* (primitives) which want to move together. For example, if one atom in a block
* should be moved one unit to the left, all atoms in the block want to move one
* unit to the left.
*
* An example of a block is pack molecules, which are atoms which were prepacked
* together.
*
* The nets in the netlist represent the logical connections between AP
* blocks (inferred from the atom block connectivity), where nets which are
* unused by Analytical Placement are ignored.
*/

#pragma once

#include <string>
#include "netlist.h"
#include "ap_netlist_fwd.h"

// Forward declarations
class t_pack_molecule;

/**
* @brief Struct to store fixed block location information
*
* Currently assumes that blocks are fixed to single locations (not ranges).
* TODO: This assumption could be relaxed and allow fixing a range of locations.
*
* -1 implies that the block is not fixed in that dimension.
*/
struct APFixedBlockLoc {
int x = -1;
int y = -1;
int layer_num = -1;
int sub_tile = -1;
};

/**
* @brief The mobility of a block in the APNetlist
* TODO: It would be nice if the netlist contained lists of moveable and fixed
* block ids.
*/
enum class APBlockMobility : bool {
MOVEABLE, // The block is not constrained in any dimension.
FIXED // The block is fixed.
};

/**
* @brief The netlist used during Analytical Placement
*
* This class abstracts the placeable blocks and connections between the blocks
* away from the atom netlist. An APBlock is assumed to be some collection of
* primitive blocks and an APNet is assumed to be some connection between the
* APBlocks. These need not have physical meaning.
*/
class APNetlist : public Netlist<APBlockId, APPortId, APPinId, APNetId> {
public:
/**
* @brief Constructs a netlist
*
* @param name The name of the netlist (e.g. top-level module)
* @param id A unique identifier for the netlist (e.g. a secure digest of
* the input file)
*/
APNetlist(std::string name = "", std::string id = "") : Netlist(name, id) {}

APNetlist(const APNetlist& rhs) = default;
APNetlist& operator=(const APNetlist& rhs) = default;

public: // Public Accessors
/*
* Blocks
*/

/// @brief Returns the molecule that this block represents.
const t_pack_molecule* block_molecule(const APBlockId id) const;

/// @brief Returns the mobility of this block.
APBlockMobility block_mobility(const APBlockId id) const;

/// @brief Returns the location of this block, if the block is fixed.
/// This method should not be used if the block is moveable.
const APFixedBlockLoc& block_loc(const APBlockId id) const;

public: // Public Mutators
/*
* Note: all create_*() functions will silently return the appropriate ID
* if it has already been created.
*/

/**
* @brief Create or return an existing block in the netlist
*
* @param name The unique name of the block
* @param mol The molecule the block represents
*/
APBlockId create_block(const std::string& name, const t_pack_molecule* mol);

/**
* @brief Fixes a block at the given location
*
* @param id The block to fix
* @param loc The location to fix the block to
*/
void set_block_loc(const APBlockId id, const APFixedBlockLoc& loc);

/**
* @brief Create or return an existing port in the netlist
*
* @param blk_id The block the port is associated with
* @param name The name of the port
* @param width The width (number of bits) of the port
* @param type The type of the port (INPUT, OUTPUT, or CLOCK)
*/
APPortId create_port(const APBlockId blk_id, const std::string& name, BitIndex width, PortType type);

/**
* @brief Create or return an existing pin in the netlist
*
* @param port_id The port this pin is associated with
* @param port_bit The bit index of the pin in the port
* @param net_id The net the pin drives/sinks
* @param pin_type The type of the pin (driver/sink)
* @param is_const Indicates whether the pin holds a constant value (e.g.
* vcc/gnd)
*/
APPinId create_pin(const APPortId port_id, BitIndex port_bit, const APNetId net_id, const PinType pin_type, bool is_const = false);

/**
* @brief Create an empty, or return an existing net in the netlist
*
* @param name The unique name of the net
*/
APNetId create_net(const std::string& name);

private: // Private Members
/*
* Netlist compression / optimization
*/

/// @brief Removes invalid components and reorders them
void clean_blocks_impl(const vtr::vector_map<APBlockId, APBlockId>& block_id_map) override;
void clean_ports_impl(const vtr::vector_map<APPortId, APPortId>& port_id_map) override;
void clean_pins_impl(const vtr::vector_map<APPinId, APPinId>& pin_id_map) override;
void clean_nets_impl(const vtr::vector_map<APNetId, APNetId>& net_id_map) override;

void rebuild_block_refs_impl(const vtr::vector_map<APPinId, APPinId>& pin_id_map, const vtr::vector_map<APPortId, APPortId>& port_id_map) override;
void rebuild_port_refs_impl(const vtr::vector_map<APBlockId, APBlockId>& block_id_map, const vtr::vector_map<APPinId, APPinId>& pin_id_map) override;
void rebuild_pin_refs_impl(const vtr::vector_map<APPortId, APPortId>& port_id_map, const vtr::vector_map<APNetId, APNetId>& net_id_map) override;
void rebuild_net_refs_impl(const vtr::vector_map<APPinId, APPinId>& pin_id_map) override;

/// @brief Shrinks internal data structures to required size to reduce
/// memory consumption
void shrink_to_fit_impl() override;

/*
* Component removal
*/
void remove_block_impl(const APBlockId blk_id) override;
void remove_port_impl(const APPortId port_id) override;
void remove_pin_impl(const APPinId pin_id) override;
void remove_net_impl(const APNetId net_id) override;

/*
* Sanity checks
*/
// Verify the internal data structure sizes match
bool validate_block_sizes_impl(size_t num_blocks) const override;
bool validate_port_sizes_impl(size_t num_ports) const override;
bool validate_pin_sizes_impl(size_t num_pins) const override;
bool validate_net_sizes_impl(size_t num_nets) const override;

private: // Private Data
/// @brief Molecule of each block
vtr::vector_map<APBlockId, const t_pack_molecule*> block_molecules_;
/// @brief Type of each block
vtr::vector_map<APBlockId, APBlockMobility> block_mobilities_;
/// @brief Location of each block (if fixed).
/// NOTE: This vector will likely be quite sparse.
vtr::vector_map<APBlockId, APFixedBlockLoc> block_locs_;
};

Loading

0 comments on commit 2c2af51

Please sign in to comment.