Skip to content

Commit 2c2af51

Browse files
authored
Merge pull request #2733 from AlexandreSinger/feature-ap-upstreaming
[AP] Created The APNetlist Class
2 parents f92efd7 + 4bcb6d6 commit 2c2af51

File tree

4 files changed

+570
-0
lines changed

4 files changed

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

0 commit comments

Comments
 (0)