-
Notifications
You must be signed in to change notification settings - Fork 397
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2733 from AlexandreSinger/feature-ap-upstreaming
[AP] Created The APNetlist Class
- Loading branch information
Showing
4 changed files
with
570 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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_; | ||
}; | ||
|
Oops, something went wrong.