P4C
The P4 Compiler
Loading...
Searching...
No Matches
memories.h
1
19#ifndef BF_P4C_MAU_MEMORIES_H_
20#define BF_P4C_MAU_MEMORIES_H_
21
22#include <algorithm>
23
24#include "backends/tofino/bf-p4c/common/alloc.h"
25#include "backends/tofino/bf-p4c/mau/action_format.h"
26#include "backends/tofino/bf-p4c/mau/attached_entries.h"
27#include "backends/tofino/bf-p4c/mau/input_xbar.h"
28#include "ir/ir.h"
29#include "lib/safe_vector.h"
30
31using namespace P4;
32
33// FIXME -- should be in algorithm.h
34template <class C, class Pred>
35inline bool any_of(C c, Pred pred) {
36 return std::any_of(std::begin(c), std::end(c), pred);
37}
38
39struct Memories {
40 /* track memory allocations within a single stage */
41 static constexpr int SRAM_ROWS = 8;
42 static constexpr int SRAM_COLUMNS = 10;
43 static constexpr int STASH_UNITS = 2;
44 static constexpr int LOGICAL_TABLES = 16;
45 static constexpr int LEFT_SIDE_COLUMNS = 4;
46 static constexpr int RIGHT_SIDE_COLUMNS = SRAM_COLUMNS - LEFT_SIDE_COLUMNS;
47 static constexpr int LEFT_SIDE_RAMS = LEFT_SIDE_COLUMNS * SRAM_ROWS;
48 static constexpr int RIGHT_SIDE_RAMS = RIGHT_SIDE_COLUMNS * SRAM_ROWS;
49 static constexpr int TOTAL_SRAMS = SRAM_ROWS * SRAM_COLUMNS;
50 static constexpr int MAPRAM_COLUMNS = 6;
51 static constexpr int MAPRAM_MASK = (1U << MAPRAM_COLUMNS) - 1;
52 static constexpr int LAMB_DEPTH = 64;
53 static constexpr int TOTAL_LAMBS = 8;
54 static constexpr int SRAM_DEPTH = 1024;
55 // static constexpr int TCAM_ROWS = 12;
56 // static constexpr int TCAM_COLUMNS = 2;
57 static constexpr int TCAM_DEPTH = 512;
58 static constexpr int LOCAL_TIND_DEPTH = 64;
59 static constexpr int TOTAL_LOCAL_TIND = 16;
60 static constexpr int TABLES_MAX = 16;
61 static constexpr int TERNARY_TABLES_MAX = 8;
62 static constexpr int ACTION_TABLES_MAX = 16;
63 static constexpr int GATEWAYS_PER_ROW = 2;
64 static constexpr int BUS_COUNT = 2; // search/result busses per row
65 static constexpr int PAYLOAD_COUNT = 2; // payload per row
66 static constexpr int STATS_ALUS = 4;
67 static constexpr int METER_ALUS = 4;
68 static constexpr int MAX_DATA_SWBOX_ROWS = 5;
69 static constexpr int COLOR_MAPRAM_PER_ROW = 4;
70 static constexpr int IMEM_ADDRESS_BITS = 6;
71 static constexpr int IMEM_LOOKUP_BITS = 3;
72 static constexpr int NUM_IDLETIME_BUS = 10;
73 static constexpr int MAX_PARTITION_RAMS_PER_ROW = 5;
74 static constexpr int MATCH_CENTRAL_ROW = 4;
75 static constexpr int MAX_STATS_ROW_PER_ALU = 3;
76 static constexpr int MAX_STATS_RAM_PER_ALU = MAPRAM_COLUMNS * MAX_STATS_ROW_PER_ALU;
77
78 static constexpr int LOGICAL_ROW_MISSING_OFLOW = 8;
79
80 /* Memories::Use tracks memory use of a single table */
81 struct Use {
82 enum type_t {
83 EXACT,
84 ATCAM,
85 TERNARY,
86 GATEWAY,
87 TIND,
88 IDLETIME,
89 COUNTER,
90 METER,
91 SELECTOR,
92 STATEFUL,
93 ACTIONDATA
94 } type;
95 bool is_twoport() const {
96 return type == COUNTER || type == METER || type == SELECTOR || type == STATEFUL;
97 }
98 std::string used_by;
99 /* FIXME -- when tracking EXACT table memuse, do we need to track which way
100 * each memory is allocated to? For now, we do not. */
101 struct Row {
102 int row, bus, result_bus, word, alloc;
103 int stash_unit, stash_col;
104 safe_vector<int> col, mapcol, vpn;
105 Row()
106 : row(-1),
107 bus(-1),
108 result_bus(-1),
109 word(-1),
110 alloc(-1),
111 stash_unit(-1),
112 stash_col(-1) {}
113 explicit Row(int r, int b = -1, int w = -1, int a = -1)
114 : row(r),
115 bus(b),
116 result_bus(-1),
117 word(w),
118 alloc(a),
119 stash_unit(-1),
120 stash_col(-1) {}
121 void dbprint(std::ostream &out) const { out << "Row " << row << " with bus " << bus; }
122 };
123
124 struct Way {
125 int size;
126 unsigned select_mask;
129 explicit Way(int s, unsigned sm) : size(s), select_mask(sm) {}
130 };
131 friend std::ostream &operator<<(std::ostream &out, const Way &w);
132
133 struct Gateway {
134 uint64_t payload_value = 0ULL;
135 int payload_match_address = -1;
136 int payload_row = -1;
137 int payload_unit = -1;
138 int unit = -1;
139 type_t bus_type = EXACT;
140 void clear() {
141 payload_value = 0ULL;
142 payload_match_address = -1;
143 payload_row = -1;
144 payload_unit = -1;
145 unit = -1;
146 bus_type = EXACT;
147 }
148 };
149
151 safe_vector<Row> color_mapram;
153 safe_vector<Way> ways;
154 Gateway gateway;
155 int tind_result_bus = -1;
156 IR::MAU::ColorMapramAddress cma = IR::MAU::ColorMapramAddress::NOT_SET;
157
158 // SCM related data
159 enum h_bus_t { NONE, LEFT_HBUS1, LEFT_HBUS2, RIGHT_HBUS1, RIGHT_HBUS2 };
160 struct ScmLoc {
161 int stage;
162 // SCM TCAMs are located in row/column tuple but can be abstracted as a single
163 // column with more rows since the hardware really act like that.
164 int row;
165
166 bool operator==(const ScmLoc &scm_loc) const {
167 return stage == scm_loc.stage && row == scm_loc.row;
168 }
169 bool operator!=(const ScmLoc &scm_loc) const { return !(*this == scm_loc); }
170 bool operator<(const ScmLoc &scm_loc) const {
171 if (stage != scm_loc.stage) return stage < scm_loc.stage;
172 if (row != scm_loc.row) return row < scm_loc.row;
173 return false;
174 }
175 ScmLoc() : stage(-1), row(-1) {}
176 explicit ScmLoc(int s, int r) : stage(s), row(r) {}
177 };
178
179 // table_id (0..3) have STM tind capability, (0..7) have local tind capability
180 int table_id = -1;
181 safe_vector<int> local_tind;
182 std::map<ScmLoc, std::pair<int, h_bus_t>> loc_to_gb; // Location -> Group/Bus
183
195 std::map<UniqueId, ordered_set<UniqueId>> unattached_tables;
196 safe_vector<UniqueId> dleft_learn;
197 safe_vector<UniqueId> dleft_match;
198
199 int get_way(int row, int col) {
200 for (size_t i = 0; i < ways.size(); i++) {
201 auto w = ways[i];
202 for (auto ram : w.rams) {
203 if ((ram.first == row) && (ram.second == col)) return i;
204 }
205 }
206 return -1;
207 }
208
209 void clear_allocation() {
210 row.clear();
211 color_mapram.clear();
212 home_row.clear();
213 gateway.clear();
214 cma = IR::MAU::ColorMapramAddress::NOT_SET;
215 }
216
217 void clear_scm() {
218 table_id = -1;
219 local_tind.clear();
220 loc_to_gb.clear();
221 }
222
223 void clear() {
224 clear_allocation();
225 clear_scm();
226 unattached_tables.clear();
227 dleft_learn.clear();
228 dleft_match.clear();
229 }
230
231 int rams_required() const;
233 // depth in memory units + mask to use for memory selection per way
234 };
235
236 int local_stage = -1;
237
238 public:
239 virtual ~Memories() {}
240 virtual bool allocate_all() = 0;
241 virtual bool allocate_all_dummies() { return true; }
242 virtual void update(cstring table_name, const Use &alloc) = 0;
243 virtual void update(const std::map<UniqueId, Use> &alloc) = 0;
244 virtual void remove(cstring table_name, const Use &alloc) = 0;
245 virtual void remove(const std::map<UniqueId, Use> &alloc) = 0;
246 virtual void clear() = 0;
247 virtual void add_table(const IR::MAU::Table *t, const IR::MAU::Table *gw,
248 TableResourceAlloc *resources, const LayoutOption *lo,
250 int entries, int stage_table, attached_entries_t attached_entries) = 0;
251 virtual void shrink_allowed_lts() = 0;
252 virtual void fill_placed_scm_table(const IR::MAU::Table *, const TableResourceAlloc *) = 0;
253 virtual void printOn(std::ostream &) const = 0;
254 cstring last_failure() const { return failure_reason ? failure_reason : ""_cs; }
255 virtual void init_shared(int stage) { local_stage = stage; }
256 virtual const ordered_map<cstring, int> collect_sram_block_alloc_info() = 0;
257
258 protected:
259 enum update_type_t {
260 NONE,
261 UPDATE_RAM,
262 UPDATE_MAPRAM,
263 UPDATE_GATEWAY,
264 UPDATE_PAYLOAD,
265 UPDATE_SEARCH_BUS,
266 UPDATE_RESULT_BUS,
267 UPDATE_ACTION_BUS,
268 UPDATE_TIND_BUS,
269 UPDATE_STATEFUL_BUS
270 };
271 virtual void visitUse(const Use &, std::function<void(cstring &, update_type_t)> fn) = 0;
272 cstring failure_reason;
273
274 public:
275 static Memories *create();
276 friend std::ostream &operator<<(std::ostream &out, const Memories &m) {
277 m.printOn(out);
278 return out;
279 }
280};
281
282template <int R, int C>
283std::ostream &operator<<(std::ostream &out, const BFN::Alloc2D<cstring, R, C> &alloc2d) {
284 for (int i = 0; i < R; i++) {
285 for (int j = 0; j < C; j++) {
286 cstring val = alloc2d[i][j];
287 if (!val) val = "-"_cs;
288 out << std::setw(10) << val << " ";
289 }
290 out << Log::endl;
291 }
292 return out;
293}
294
295#endif /* BF_P4C_MAU_MEMORIES_H_ */
Definition attached_info.h:32
Definition alloc.h:152
Definition table_layout.h:34
Definition cstring.h:85
Definition ordered_map.h:32
Definition safe_vector.h:27
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
Definition action_format.h:979
Definition memories.h:133
Definition memories.h:101
Definition memories.h:160
Definition memories.h:124
Definition memories.h:81
bool separate_search_and_result_bus() const
Definition memories.cpp:45
std::map< UniqueId, ordered_set< UniqueId > > unattached_tables
Definition memories.h:195
Definition memories.h:39
static constexpr int SRAM_DEPTH
Definition memories.h:54
Definition resource.h:37