Skip to content

Commit 24732b6

Browse files
[AP] Created The APNetlist Class
The APNetlist class holds the blocks and nets used during the AP flow. In the AP context, a block is a collection of primitives which would want to be placed in the same location (i.e. they want to move together). Currently, each block represents a pack molecule (created by the Prepacker). The nets are logical connections between blocks. The APNetlist will not contain any nets which are not needed for AP. The APNetlist is tested using a Unit Test which tests its basic functionality (features that differ from the base Netlist class). This is the first of many commits which will bring Analytical Placement into VPR.
1 parent 859198c commit 24732b6

File tree

4 files changed

+569
-0
lines changed

4 files changed

+569
-0
lines changed
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
/**
2+
* @file
3+
* @author Alex Singer
4+
* @date September 2024
5+
* @brief The definitions of the APNetlist methods
6+
*/
7+
8+
#include "ap_netlist.h"
9+
#include <string>
10+
#include "netlist_fwd.h"
11+
#include "netlist_utils.h"
12+
#include "vpr_types.h"
13+
#include "vtr_assert.h"
14+
15+
/*
16+
* Blocks
17+
*/
18+
const t_pack_molecule* APNetlist::block_molecule(const APBlockId id) const {
19+
VTR_ASSERT_SAFE(valid_block_id(id));
20+
21+
return block_molecules_[id];
22+
}
23+
24+
APBlockType APNetlist::block_type(const APBlockId id) const {
25+
VTR_ASSERT_SAFE(valid_block_id(id));
26+
27+
return block_types_[id];
28+
}
29+
30+
const APFixedBlockLoc& APNetlist::block_loc(const APBlockId id) const {
31+
VTR_ASSERT_SAFE(valid_block_id(id));
32+
VTR_ASSERT(block_type(id) == APBlockType::FIXED);
33+
34+
return block_locs_[id];
35+
}
36+
37+
/*
38+
* Mutators
39+
*/
40+
APBlockId APNetlist::create_block(const std::string& name, const t_pack_molecule* mol) {
41+
APBlockId blk_id = Netlist::create_block(name);
42+
43+
// Initialize the data
44+
block_molecules_.insert(blk_id, mol);
45+
block_types_.insert(blk_id, APBlockType::MOVEABLE);
46+
block_locs_.insert(blk_id, APFixedBlockLoc());
47+
48+
// Check post-conditions: size
49+
VTR_ASSERT(validate_block_sizes());
50+
51+
// Check post-conditions: values
52+
VTR_ASSERT(block_molecule(blk_id) == mol);
53+
VTR_ASSERT(block_type(blk_id) == APBlockType::MOVEABLE);
54+
55+
return blk_id;
56+
}
57+
58+
void APNetlist::set_block_loc(const APBlockId id, const APFixedBlockLoc& loc) {
59+
VTR_ASSERT_SAFE(valid_block_id(id));
60+
61+
// Check that the location is fixed, if all values are -1 then it is not fixed.
62+
if (loc.x == -1 && loc.y == -1 && loc.sub_tile == -1 && loc.layer_num == -1)
63+
return;
64+
65+
block_locs_[id] = loc;
66+
block_types_[id] = APBlockType::FIXED;
67+
}
68+
69+
APPortId APNetlist::create_port(const APBlockId blk_id, const std::string& name, BitIndex width, PortType type) {
70+
APPortId port_id = find_port(blk_id, name);
71+
if (!port_id) {
72+
port_id = Netlist::create_port(blk_id, name, width, type);
73+
associate_port_with_block(port_id, type, blk_id);
74+
}
75+
76+
// Check post-conditions: size
77+
VTR_ASSERT(validate_port_sizes());
78+
79+
// Check post-conditions: values
80+
VTR_ASSERT(port_name(port_id) == name);
81+
VTR_ASSERT(find_port(blk_id, name) == port_id);
82+
83+
return port_id;
84+
}
85+
86+
APPinId APNetlist::create_pin(const APPortId port_id, BitIndex port_bit, const APNetId net_id, const PinType pin_type_, bool is_const) {
87+
APPinId pin_id = Netlist::create_pin(port_id, port_bit, net_id, pin_type_, is_const);
88+
89+
// Check post-conditions: size
90+
VTR_ASSERT(validate_pin_sizes());
91+
92+
// Check post-conditions: values
93+
VTR_ASSERT(pin_type(pin_id) == pin_type_);
94+
VTR_ASSERT(pin_port(pin_id) == port_id);
95+
VTR_ASSERT(pin_port_type(pin_id) == port_type(port_id));
96+
97+
return pin_id;
98+
}
99+
100+
APNetId APNetlist::create_net(const std::string& name) {
101+
APNetId net_id = Netlist::create_net(name);
102+
103+
// Check post-conditions: size
104+
VTR_ASSERT(validate_net_sizes());
105+
106+
return net_id;
107+
}
108+
109+
/*
110+
* Internal utilities
111+
*/
112+
void APNetlist::clean_blocks_impl(const vtr::vector_map<APBlockId, APBlockId>& block_id_map) {
113+
// Update all the block molecules
114+
block_molecules_ = clean_and_reorder_values(block_molecules_, block_id_map);
115+
// Update all the block types
116+
block_types_ = clean_and_reorder_values(block_types_, block_id_map);
117+
// Update the fixed block locations
118+
block_locs_ = clean_and_reorder_values(block_locs_, block_id_map);
119+
}
120+
121+
void APNetlist::clean_ports_impl(const vtr::vector_map<APPortId, APPortId>& /*port_id_map*/) {
122+
// Unused
123+
}
124+
125+
void APNetlist::clean_pins_impl(const vtr::vector_map<APPinId, APPinId>& /*pin_id_map*/) {
126+
// Unused
127+
}
128+
129+
void APNetlist::clean_nets_impl(const vtr::vector_map<APNetId, APNetId>& /*net_id_map*/) {
130+
// Unused
131+
}
132+
133+
void APNetlist::rebuild_block_refs_impl(const vtr::vector_map<APPinId, APPinId>& /*pin_id_map*/,
134+
const vtr::vector_map<APPortId, APPortId>& /*port_id_map*/) {
135+
// Unused
136+
}
137+
138+
void APNetlist::rebuild_port_refs_impl(const vtr::vector_map<APBlockId, APBlockId>& /*block_id_map*/, const vtr::vector_map<APPinId, APPinId>& /*pin_id_map*/) {
139+
// Unused
140+
}
141+
142+
void APNetlist::rebuild_pin_refs_impl(const vtr::vector_map<APPortId, APPortId>& /*port_id_map*/, const vtr::vector_map<APNetId, APNetId>& /*net_id_map*/) {
143+
// Unused
144+
}
145+
146+
void APNetlist::rebuild_net_refs_impl(const vtr::vector_map<APPinId, APPinId>& /*pin_id_map*/) {
147+
// Unused
148+
}
149+
150+
void APNetlist::shrink_to_fit_impl() {
151+
// Block data
152+
block_molecules_.shrink_to_fit();
153+
block_types_.shrink_to_fit();
154+
block_locs_.shrink_to_fit();
155+
}
156+
157+
void APNetlist::remove_block_impl(const APBlockId /*blk_id*/) {
158+
// Unused
159+
}
160+
161+
void APNetlist::remove_port_impl(const APPortId /*port_id*/) {
162+
// Unused
163+
}
164+
165+
void APNetlist::remove_pin_impl(const APPinId /*pin_id*/) {
166+
// Unused
167+
}
168+
169+
void APNetlist::remove_net_impl(const APNetId /*net_id*/) {
170+
// Unused
171+
}
172+
173+
/*
174+
* Sanity Checks
175+
*/
176+
bool APNetlist::validate_block_sizes_impl(size_t num_blocks) const {
177+
if (block_molecules_.size() != num_blocks)
178+
return false;
179+
if (block_types_.size() != num_blocks)
180+
return false;
181+
if (block_locs_.size() != num_blocks)
182+
return false;
183+
return true;
184+
}
185+
186+
bool APNetlist::validate_port_sizes_impl(size_t /*num_ports*/) const {
187+
// No AP-specific port data to check
188+
return true;
189+
}
190+
191+
bool APNetlist::validate_pin_sizes_impl(size_t /*num_pins*/) const {
192+
// No AP-specific pin data to check
193+
return true;
194+
}
195+
196+
bool APNetlist::validate_net_sizes_impl(size_t /*num_nets*/) const {
197+
// No AP-specific net data to check
198+
return true;
199+
}
200+

vpr/src/analytical_place/ap_netlist.h

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/**
2+
* @file
3+
* @author Alex Singer
4+
* @date September 2024
5+
* @brief Defines the APNetlist class used to store the connectivity of
6+
* primitives in the Analytical Placement context.
7+
*
8+
* In the context of Analytical Placement, a block is a collection of atoms
9+
* (primitives) which want to move together. For example, if one atom in a block
10+
* should be moved one unit to the left, all atoms in the block want to move one
11+
* unit to the left.
12+
*
13+
* An example of a block is pack molecules, which are atoms which were prepacked
14+
* together.
15+
*
16+
* The nets in the netlist represent the logical connections between atom
17+
* blocks, where nets which are unused by Analytical Placement are ignored.
18+
*/
19+
20+
#pragma once
21+
22+
#include <string>
23+
#include "netlist.h"
24+
#include "ap_netlist_fwd.h"
25+
26+
// Forward declarations
27+
class t_pack_molecule;
28+
29+
/**
30+
* @brief Struct to store fixed block location information
31+
*
32+
* Currently assumes that blocks are fixed to single locations (not ranges).
33+
* TODO: This assumption could be relaxed and allow fixing a range of locations.
34+
*
35+
* -1 implies that the block is not fixed in that dimension.
36+
*/
37+
struct APFixedBlockLoc {
38+
int x = -1;
39+
int y = -1;
40+
int layer_num = -1;
41+
int sub_tile = -1;
42+
};
43+
44+
/**
45+
* @brief The type of a block in the APNetlist
46+
* TODO: It would be nice if the netlist contained lists of moveable and fixed
47+
* block ids.
48+
*/
49+
enum class APBlockType : bool {
50+
MOVEABLE, // The block is not constrained in any dimension.
51+
FIXED // The block is fixed.
52+
};
53+
54+
/**
55+
* @brief The netlist used during Analytical Placement
56+
*
57+
* This class abstracts the placeable blocks and connections between the blocks
58+
* away from the atom netlist. An APBlock is assumed to be some collection of
59+
* primitive blocks and an APNet is assumed to be some connection between the
60+
* APBlocks. These need not have physical meaning.
61+
*/
62+
class APNetlist : public Netlist<APBlockId, APPortId, APPinId, APNetId> {
63+
public:
64+
/**
65+
* @brief Constructs a netlist
66+
*
67+
* @param name The name of the netlist (e.g. top-level module)
68+
* @param id A unique identifier for the netlist (e.g. a secure digest of
69+
* the input file)
70+
*/
71+
APNetlist(std::string name = "", std::string id = "") : Netlist(name, id) {}
72+
73+
APNetlist(const APNetlist& rhs) = default;
74+
APNetlist& operator=(const APNetlist& rhs) = default;
75+
76+
public: // Public Accessors
77+
/*
78+
* Blocks
79+
*/
80+
81+
/// @brief Returns the molecule that this block represents.
82+
const t_pack_molecule* block_molecule(const APBlockId id) const;
83+
84+
/// @brief Returns the type of this block.
85+
APBlockType block_type(const APBlockId id) const;
86+
87+
/// @brief Returns the location of this block, if the block is fixed.
88+
/// This method should not be used if the block is moveable.
89+
const APFixedBlockLoc& block_loc(const APBlockId id) const;
90+
91+
public: // Public Mutators
92+
/*
93+
* Note: all create_*() functions will silently return the appropriate ID
94+
* if it has already been created.
95+
*/
96+
97+
/**
98+
* @brief Create or return an existing block in the netlist
99+
*
100+
* @param name The unique name of the block
101+
* @param mol The molecule the block represents
102+
*/
103+
APBlockId create_block(const std::string& name, const t_pack_molecule* mol);
104+
105+
/**
106+
* @brief Fixes a block at the given location
107+
*
108+
* @param id The block to fix
109+
* @param loc The location to fix the block to
110+
*/
111+
void set_block_loc(const APBlockId id, const APFixedBlockLoc& loc);
112+
113+
/**
114+
* @brief Create or return an existing port in the netlist
115+
*
116+
* @param blk_id The block the port is associated with
117+
* @param name The name of the port
118+
* @param width The width (number of bits) of the port
119+
* @param type The type of the port (INPUT, OUTPUT, or CLOCK)
120+
*/
121+
APPortId create_port(const APBlockId blk_id, const std::string& name, BitIndex width, PortType type);
122+
123+
/**
124+
* @brief Create or return an existing pin in the netlist
125+
*
126+
* @param port_id The port this pin is associated with
127+
* @param port_bit The bit index of the pin in the port
128+
* @param net_id The net the pin drives/sinks
129+
* @param pin_type The type of the pin (driver/sink)
130+
* @param is_const Indicates whether the pin holds a constant value (e.g.
131+
* vcc/gnd)
132+
*/
133+
APPinId create_pin(const APPortId port_id, BitIndex port_bit, const APNetId net_id, const PinType pin_type, bool is_const = false);
134+
135+
/**
136+
* @brief Create an empty, or return an existing net in the netlist
137+
*
138+
* @param name The unique name of the net
139+
*/
140+
APNetId create_net(const std::string& name);
141+
142+
private: // Private Members
143+
/*
144+
* Netlist compression / optimization
145+
*/
146+
147+
/// @brief Removes invalid components and reorders them
148+
void clean_blocks_impl(const vtr::vector_map<APBlockId, APBlockId>& block_id_map) override;
149+
void clean_ports_impl(const vtr::vector_map<APPortId, APPortId>& port_id_map) override;
150+
void clean_pins_impl(const vtr::vector_map<APPinId, APPinId>& pin_id_map) override;
151+
void clean_nets_impl(const vtr::vector_map<APNetId, APNetId>& net_id_map) override;
152+
153+
void rebuild_block_refs_impl(const vtr::vector_map<APPinId, APPinId>& pin_id_map, const vtr::vector_map<APPortId, APPortId>& port_id_map) override;
154+
void rebuild_port_refs_impl(const vtr::vector_map<APBlockId, APBlockId>& block_id_map, const vtr::vector_map<APPinId, APPinId>& pin_id_map) override;
155+
void rebuild_pin_refs_impl(const vtr::vector_map<APPortId, APPortId>& port_id_map, const vtr::vector_map<APNetId, APNetId>& net_id_map) override;
156+
void rebuild_net_refs_impl(const vtr::vector_map<APPinId, APPinId>& pin_id_map) override;
157+
158+
/// @brief Shrinks internal data structures to required size to reduce
159+
/// memory consumption
160+
void shrink_to_fit_impl() override;
161+
162+
/*
163+
* Component removal
164+
*/
165+
void remove_block_impl(const APBlockId blk_id) override;
166+
void remove_port_impl(const APPortId port_id) override;
167+
void remove_pin_impl(const APPinId pin_id) override;
168+
void remove_net_impl(const APNetId net_id) override;
169+
170+
/*
171+
* Sanity checks
172+
*/
173+
// Verify the internal data structure sizes match
174+
bool validate_block_sizes_impl(size_t num_blocks) const override;
175+
bool validate_port_sizes_impl(size_t num_ports) const override;
176+
bool validate_pin_sizes_impl(size_t num_pins) const override;
177+
bool validate_net_sizes_impl(size_t num_nets) const override;
178+
179+
private: // Private Data
180+
/// @brief Molecule of each block
181+
vtr::vector_map<APBlockId, const t_pack_molecule*> block_molecules_;
182+
/// @brief Type of each block
183+
vtr::vector_map<APBlockId, APBlockType> block_types_;
184+
/// @brief Location of each block (if fixed).
185+
/// NOTE: This vector will likely be quite sparse.
186+
vtr::vector_map<APBlockId, APFixedBlockLoc> block_locs_;
187+
};
188+

0 commit comments

Comments
 (0)