P4C
The P4 Compiler
Loading...
Searching...
No Matches
action_bus.h
1
17
18#ifndef BACKENDS_TOFINO_BF_ASM_ACTION_BUS_H_
19#define BACKENDS_TOFINO_BF_ASM_ACTION_BUS_H_
20
21#include <array>
22
23#include "backends/tofino/bf-asm/tables.h"
24
25// static struct MeterBus_t {} MeterBus;
26struct MeterBus_t {};
27
28struct ActionBusSource {
29 enum {
30 None,
31 Field,
32 HashDist,
33 HashDistPair,
34 RandomGen,
35 TableOutput,
36 TableColor,
37 TableAddress,
38 Ealu,
39 XcmpData,
40 NameRef,
41 ColorRef,
42 AddressRef
43 } type;
44 union {
47 struct {
48 HashDistribution *hd1, *hd2;
49 } hd_tuple;
50 Table *table;
51 Table::Ref *name_ref;
53 struct {
54 short xcmp_group, xcmp_byte;
55 } xcmp_data;
56 };
57 ActionBusSource() : type(None) { field = nullptr; }
58 ActionBusSource(Table::Format::Field *f) : type(Field) { // NOLINT(runtime/explicit)
59 field = f;
60 }
61 ActionBusSource(HashDistribution *h) : type(HashDist) { hd = h; } // NOLINT(runtime/explicit)
62 ActionBusSource(HashDistribution *h1, HashDistribution *h2) : type(HashDistPair) {
63 hd_tuple.hd1 = h1;
64 hd_tuple.hd2 = h2;
65 }
66 ActionBusSource(Table *t,
67 TableOutputModifier m = TableOutputModifier::NONE) // NOLINT(runtime/explicit)
68 : type(TableOutput) {
69 switch (m) {
70 case TableOutputModifier::Color:
71 type = TableColor;
72 break;
73 case TableOutputModifier::Address:
74 type = TableAddress;
75 break;
76 default:
77 break;
78 }
79 table = t;
80 }
81 ActionBusSource(Table::Ref *t,
82 TableOutputModifier m = TableOutputModifier::NONE) // NOLINT(runtime/explicit)
83 : type(NameRef) {
84 switch (m) {
85 case TableOutputModifier::Color:
86 type = ColorRef;
87 break;
88 case TableOutputModifier::Address:
89 type = AddressRef;
90 break;
91 default:
92 break;
93 }
94 name_ref = t;
95 }
96 ActionBusSource(MeterBus_t,
97 TableOutputModifier m = TableOutputModifier::NONE) // NOLINT(runtime/explicit)
98 : type(NameRef) {
99 switch (m) {
100 case TableOutputModifier::Color:
101 type = ColorRef;
102 break;
103 case TableOutputModifier::Address:
104 type = AddressRef;
105 break;
106 default:
107 break;
108 }
109 name_ref = nullptr;
110 }
111 ActionBusSource(RandomNumberGen r) : type(RandomGen) { // NOLINT(runtime/explicit)
112 field = nullptr;
113 rng = r;
114 }
115 ActionBusSource(InputXbar::Group grp, int byte) : type(XcmpData) {
116 BUG_CHECK(grp.type == InputXbar::Group::XCMP, "Not xcmp ixbar");
117 field = nullptr;
118 xcmp_data.xcmp_group = grp.index;
119 xcmp_data.xcmp_byte = byte;
120 }
121 bool operator==(const ActionBusSource &a) const {
122 if (type == XcmpData)
123 return a.type == XcmpData && xcmp_data.xcmp_group == a.xcmp_data.xcmp_group &&
124 xcmp_data.xcmp_byte == a.xcmp_data.xcmp_byte;
125 if (type == HashDistPair && hd_tuple.hd2 != a.hd_tuple.hd2) return false;
126 return type == a.type && field == a.field;
127 }
128 bool operator<(const ActionBusSource &a) const {
129 if (type != a.type) return type < a.type;
130 switch (type) {
131 case HashDistPair:
132 return hd_tuple.hd1 == a.hd_tuple.hd1 ? hd_tuple.hd2 < a.hd_tuple.hd2
133 : hd_tuple.hd1 < a.hd_tuple.hd1;
134 case XcmpData:
135 return xcmp_data.xcmp_group == a.xcmp_data.xcmp_group
136 ? xcmp_data.xcmp_byte < a.xcmp_data.xcmp_byte
137 : xcmp_data.xcmp_group < a.xcmp_data.xcmp_group;
138 default:
139 return field < a.field;
140 }
141 }
142 std::string name(Table *tbl) const;
143 std::string toString(Table *tbl) const;
144 friend std::ostream &operator<<(std::ostream &, const ActionBusSource &);
145};
146
147class ActionBus {
148 protected:
149 // Check two ActionBusSource refs to ensure that they are compatible (can be at the same
150 // location on the aciton bus -- basically the same data)
151 static bool compatible(const ActionBusSource &a, unsigned a_off, const ActionBusSource &b,
152 unsigned b_off);
153 struct Slot {
154 std::string name;
155 unsigned byte, size; // size in bits
157 // offset in the specified source is in this slot -- corresponding bytes for different
158 // action data formats will go into the same slot.
159 Slot(std::string n, unsigned b, unsigned s) : name(n), byte(b), size(s) {}
160 Slot(std::string n, unsigned b, unsigned s, ActionBusSource src, unsigned off)
161 : name(n), byte(b), size(s) {
162 data.emplace(src, off);
163 }
164 unsigned lo(Table *tbl) const; // low bit on the action data bus
165 bool is_table_output() const {
166 for (auto &d : data) {
167 BUG_CHECK(d.first.type != ActionBusSource::NameRef, "Unexpected name ref");
168 if (d.first.type == ActionBusSource::TableOutput) return true;
169 }
170 return false;
171 }
172 };
173 friend std::ostream &operator<<(std::ostream &, const Slot &);
174 friend std::ostream &operator<<(std::ostream &, const ActionBus &);
177 // bytes from the given sources are needed on the action bus -- the pairs in the map
178 // are (offset,use) where offset is offset in bits, and use is a bitset of the needed
179 // uses (bit index == log2 of the access size in bytes)
180
181 std::vector<std::array<unsigned, ACTION_HV_XBAR_SLICES>> action_hv_slice_use;
182 // which bytes of input to the ixbar are used in each action_hv_xbar slice, for each
183 // 128-bit slice of the action bus.
184 bitvec byte_use; // bytes on the action data (input) bus or immediate bus in use
185 // for wide action tables, this may be >16 bytes...
186
187 void setup_slot(int lineno, Table *tbl, const char *name, unsigned idx, ActionBusSource src,
188 unsigned sz, unsigned off);
189
190 int find_free(Table *tbl, unsigned min, unsigned max, unsigned step, unsigned lobyte,
191 unsigned bytes);
192 int find_merge(Table *tbl, int offset, int bytes, int use);
193 bool check_atcam_sharing(Table *tbl1, Table *tbl2);
194 bool check_slot_sharing(ActionBus::Slot &slot, bitvec &action_bus);
195
196 ActionBus() : lineno(-1) {}
197 ActionBus(Table *, VECTOR(pair_t) &);
198
199 public:
200 int lineno;
201 static std::unique_ptr<ActionBus> create();
202 static std::unique_ptr<ActionBus> create(Table *, VECTOR(pair_t) &);
203
204 void pass1(Table *tbl);
205 void pass2(Table *tbl) {}
206 void pass3(Table *tbl);
207 template <class REGS>
208 void write_immed_regs(REGS &regs, Table *tbl);
209 template <class REGS>
210 void write_action_regs(REGS &regs, Table *tbl, int homerow, unsigned action_slice);
211
212 void do_alloc(Table *tbl, ActionBusSource src, unsigned use, int lobyte, int bytes,
213 unsigned offset);
214 static const unsigned size_masks[8];
215 virtual void alloc_field(Table *, ActionBusSource src, unsigned offset, unsigned sizes_needed);
216 void need_alloc(Table *tbl, const ActionBusSource &src, unsigned lo, unsigned hi,
217 unsigned size);
218 void need_alloc(Table *tbl, Table *attached, TableOutputModifier mod, unsigned lo, unsigned hi,
219 unsigned size) {
220 need_alloc(tbl, ActionBusSource(attached, mod), lo, hi, size);
221 }
222
223 int find(const char *name, TableOutputModifier mod, int lo, int hi, int size, int *len = 0);
224 int find(const char *name, int lo, int hi, int size, int *len = 0) {
225 return find(name, TableOutputModifier::NONE, lo, hi, size, len);
226 }
227 int find(const std::string &name, TableOutputModifier mod, int lo, int hi, int size,
228 int *len = 0) {
229 return find(name.c_str(), mod, lo, hi, size, len);
230 }
231 int find(const std::string &name, int lo, int hi, int size, int *len = 0) {
232 return find(name.c_str(), lo, hi, size, len);
233 }
234 int find(const ActionBusSource &src, int lo, int hi, int size, int pos = -1, int *len = 0);
235 int find(Table *attached, TableOutputModifier mod, int lo, int hi, int size, int *len = 0) {
236 return find(ActionBusSource(attached, mod), lo, hi, size, -1, len);
237 }
238 static int find(Stage *stage, ActionBusSource src, int lo, int hi, int size, int *len = 0);
239 unsigned size() {
240 unsigned rv = 0;
241 for (auto &slot : by_byte) rv += slot.second.size;
242 return rv;
243 }
244 auto slots() const { return Values(by_byte); }
245};
246
247#endif /* BACKENDS_TOFINO_BF_ASM_ACTION_BUS_H_ */
Definition action_bus.h:147
int find_free(Table *tbl, unsigned min, unsigned max, unsigned step, unsigned lobyte, unsigned bytes)
Definition action_bus.cpp:545
int find(const char *name, TableOutputModifier mod, int lo, int hi, int size, int *len=0)
find an action bus slot that contains the requested thing.
Definition action_bus.cpp:786
int find_merge(Table *tbl, int offset, int bytes, int use)
Definition action_bus.cpp:595
Definition bitvec.h:120
Definition ordered_map.h:32
Definition tables.h:98
Definition action_bus.h:153
Definition action_bus.h:28
Definition hash_dist.h:32
Definition action_bus.h:26
Definition tables.h:61
Definition tables.h:287
Definition tables.h:183
Definition asm-types.h:150