P4C
The P4 Compiler
Loading...
Searching...
No Matches
parser-tofino-jbay.h
1
17
18#ifndef BACKENDS_TOFINO_BF_ASM_PARSER_TOFINO_JBAY_H_
19#define BACKENDS_TOFINO_BF_ASM_PARSER_TOFINO_JBAY_H_
20
21#include <map>
22#include <set>
23#include <vector>
24
25#include "backends/tofino/bf-asm/target.h"
26#include "lib/bitvec.h"
27#include "parser.h"
28#include "phv.h"
29#include "sections.h"
30#include "ubits.h"
31
32enum {
33 /* global constants related to parser */
34 PARSER_STATE_MASK = 0xff,
35 PARSER_TCAM_DEPTH = 256,
36 PARSER_CHECKSUM_ROWS = 32,
37 PARSER_CTRINIT_ROWS = 16,
38 PARSER_INPUT_BUFFER_SIZE = 32,
39 PARSER_SRC_MAX_IDX = 63,
40 PARSER_MAX_CLOTS = 64,
41 PARSER_MAX_CLOT_LENGTH = 64,
42};
43
48class Parser : public BaseParser, public Contextable {
49 void write_config(RegisterSetBase &regs, json::map &json, bool legacy = true) override;
50 template <class REGS>
51 void write_config(REGS &, json::map &, bool legacy = true);
52 struct CounterInit {
53 gress_t gress;
54 int lineno = -1, addr = -1;
55 int add = 0, mask = 255, rot = 0, max = 255, src = -1;
56 CounterInit(gress_t, pair_t);
57 void pass1(Parser *) {}
58 void pass2(Parser *);
59 template <class REGS>
60 void write_config(REGS &, gress_t, int);
61 bool equiv(const CounterInit &) const;
62 };
63 struct PriorityUpdate {
64 int lineno = -1, offset = -1, shift = -1, mask = -1;
65 PriorityUpdate() {}
66 explicit PriorityUpdate(const value_t &data);
67 bool parse(const value_t &exp, int what = 0);
68 explicit operator bool() const { return lineno >= 0; }
69 template <class REGS>
70 void write_config(REGS &);
71 };
72 struct RateLimit {
73 int lineno = -1;
74 int inc = -1, dec = -1, max = -1, interval = -1;
75 void parse(const VECTOR(pair_t) &);
76 explicit operator bool() const { return lineno >= 0; }
77 template <class REGS>
78 void write_config(REGS &, gress_t);
79 };
80
81 public:
82 struct Checksum;
83
84 struct State {
85 struct Ref {
86 int lineno;
87 std::string name;
88 match_t pattern;
89 std::vector<State *> ptr;
90 Ref() : lineno(-1) { pattern.word0 = pattern.word1 = 0; }
91 Ref &operator=(const value_t &);
92 explicit Ref(value_t &v) { *this = v; }
93 operator bool() const { return ptr.size() > 0; }
94 State *operator->() const {
95 BUG_CHECK(ptr.size() == 1, "pointer size must be 1, got %d", ptr.size());
96 return ptr[0];
97 }
98 State *operator*() const {
99 BUG_CHECK(ptr.size() == 1, "pointer size must be 1, got %d", ptr.size());
100 return ptr[0];
101 }
102 bool operator==(const Ref &a) const { return name == a.name && pattern == a.pattern; }
103 void check(gress_t, Parser *, State *);
104 std::vector<State *>::const_iterator begin() const { return ptr.begin(); }
105 std::vector<State *>::const_iterator end() const { return ptr.end(); }
106 };
107 struct MatchKey {
108 int lineno;
109 struct {
110 short bit, byte;
111 } data[4];
112 enum { USE_SAVED = 0x7fff }; /* magic number can be stored in 'byte' field */
113 short specified;
114 short ctr_zero, ctr_neg;
115 short width;
116 short save = 0;
117 MatchKey() : lineno(0), specified(0), ctr_zero(-1), ctr_neg(-1), width(0) {
118 for (auto &a : data) a.bit = a.byte = -1;
119 }
120 void setup(value_t &);
121 int setup_match_el(int, value_t &);
122 void preserve_saved(unsigned mask);
123 template <class REGS>
124 void write_config(REGS &, json::vector &);
125
126 private:
127 int add_byte(int, int, bool use_saved = false);
128 int move_down(int);
129 };
130 struct OutputUse {
131 unsigned b8 = 0, b16 = 0, b32 = 0;
132 OutputUse &operator+=(const OutputUse &a) {
133 b8 += a.b8;
134 b16 += a.b16;
135 b32 += a.b32;
136 return *this;
137 }
138 };
139 struct Match {
140 int lineno;
141 State *state = nullptr;
142 match_t match;
143 std::string value_set_name;
144 int value_set_size = 0;
145 int value_set_handle = -1;
146 int offset_inc = 0, shift = 0, buf_req = -1;
147 int disable_partial_hdr_err = -1, partial_hdr_err_proc = -1;
148 bool offset_rst = false;
149 int intr_md_bits = 0;
150
151 int ctr_imm_amt = 0, ctr_ld_src = 0, ctr_load = 0;
152 bool ctr_stack_push = false, ctr_stack_upd_w_top = false, ctr_stack_pop = false;
153
154 CounterInit *ctr_instr = nullptr;
155
156 PriorityUpdate priority;
157
158 Ref next;
159 MatchKey load;
160
161 int row = -1;
165 // 32b narrow to wide extractions using 2x16 extractions
166 std::vector<const Phv::Ref *> narrow_to_wide_32b_16;
167 // 32b narrow to wide extractions using 4x8 extractions
168 std::vector<const Phv::Ref *> narrow_to_wide_32b_8;
169 // 16b narrow to wide extractions using 2x8 extractions
170 std::vector<const Phv::Ref *> narrow_to_wide_16b_8;
171
172 enum flags_t { OFFSET = 1, ROTATE = 2 };
173
174 struct Save {
175 Match *match;
176 int lo, hi;
177 Phv::Ref where, second;
178 int flags;
179 Save(gress_t, Match *m, int l, int h, value_t &data, int flgs = 0);
180 template <class REGS>
181 int write_output_config(REGS &, void *, unsigned &, int, int) const;
182 };
183 std::vector<Save *> save;
184
185 struct Set {
186 Match *match = nullptr;
187 Phv::Ref where;
188 unsigned what;
189 int flags;
190 Set(gress_t gress, Match *m, value_t &data, int v, int flgs = 0);
191 template <class REGS>
192 void write_output_config(REGS &, void *, unsigned &, int, int) const;
193 bool merge(gress_t, const Set &a);
194 bool operator==(const Set &a) const {
195 return where == a.where && what == a.what && flags == a.flags;
196 }
197 };
198 std::vector<Set *> set;
199
200 struct Clot {
201 int lineno, tag;
202 std::string name;
203 bool load_length = false;
204 int start = -1, length = -1, length_shift = -1, length_mask = -1;
205 int max_length = -1;
206 int csum_unit = -1;
207 int stack_depth = 1;
208 int stack_inc = 1;
209 Clot(gress_t gress, const value_t &tag, const value_t &data);
210 Clot(const Clot &) = delete;
211 Clot(Clot &&) = delete;
212 bool parse_length(const value_t &exp, int what = 0);
213 template <class PO_ROW>
214 void write_config(PO_ROW &, int, bool) const;
215
216 private:
217 Clot(gress_t, const Clot &, int);
218 };
219 std::vector<Clot *> clots;
220 std::vector<Checksum> csum;
221
222 struct FieldMapping {
223 Phv::Ref where;
224 std::string container_id;
225 int lo = -1;
226 int hi = -1;
227 FieldMapping(Phv::Ref &ref, const value_t &a);
228 };
229 std::vector<FieldMapping> field_mapping;
230
231 struct HdrLenIncStop {
232 int lineno = -1;
233 unsigned final_amt = 0;
234 HdrLenIncStop() {}
235 explicit HdrLenIncStop(const value_t &data);
236 explicit operator bool() const { return lineno >= 0; }
237 template <class PO_ROW>
238 void write_config(PO_ROW &) const;
239 } hdr_len_inc_stop;
240
241 Match(int lineno, gress_t, State *s, match_t m, VECTOR(pair_t) & data);
242 Match(int lineno, gress_t, State *n);
243 ~Match() {
244 if (ctr_instr) delete ctr_instr;
245 }
246 void unmark_reachable(Parser *, State *state, bitvec &unreach);
247 void pass1(Parser *pa, State *state);
248 void pass2(Parser *pa, State *state);
249 template <class REGS>
250 int write_load_config(REGS &, Parser *, State *, int) const;
251 template <class REGS>
252 void write_lookup_config(REGS &, State *, int) const;
253 template <class EA_REGS>
254 void write_counter_config(EA_REGS &) const;
255 template <class REGS>
256 void write_common_row_config(REGS &, Parser *, State *, int, Match *, json::map &);
257 template <class REGS>
258 void write_row_config(REGS &, Parser *, State *, int, Match *, json::map &);
259 template <class REGS>
260 void write_config(REGS &, Parser *, State *, Match *, json::map &);
261 template <class REGS>
262 void write_config(REGS &, json::vector &);
263
264 template <class REGS>
265 void write_saves(REGS &regs, Match *def, void *output_map, int &max_off, unsigned &used,
266 int csum_8b, int csum_16b);
267 template <class REGS>
268 void write_sets(REGS &regs, Match *def, void *output_map, unsigned &used, int csum_8b,
269 int csum_16b);
270
271 std::set<Match *> get_all_preds();
272 std::set<Match *> get_all_preds_impl(std::set<Match *> &visited);
273 };
274
275 std::string name;
276 gress_t gress;
277 match_t stateno;
278 MatchKey key;
279 std::vector<Match *> match;
280 Match *def;
281 std::set<Match *> pred;
282 bool ignore_max_depth = false;
283 int lineno = -1;
284 int all_idx = -1;
285
286 State(State &&) = default;
287 State(int lineno, const char *name, gress_t, match_t stateno, const VECTOR(pair_t) & data);
288 bool can_be_start();
289 void unmark_reachable(Parser *, bitvec &);
290 void pass1(Parser *);
291 void pass2(Parser *);
292 template <class REGS>
293 int write_lookup_config(REGS &, Parser *, State *, int, const std::vector<State *> &);
294 template <class REGS>
295 void write_config(REGS &, Parser *, json::vector &);
296 };
297
298 struct Checksum {
299 int lineno = -1, addr = -1, unit = -1;
300 gress_t gress;
301 Phv::Ref dest;
302 int tag = -1;
303 unsigned add = 0, mask = 0, swap = 0, mul_2 = 0;
304 unsigned dst_bit_hdr_end_pos = 0;
305 bool start = false, end = false, shift = false;
306 unsigned type = 0; // 0 = verify, 1 = residual, 2 = clot
307 Checksum(gress_t, pair_t);
308 bool equiv(const Checksum &) const;
309 void pass1(Parser *);
310 void pass2(Parser *);
311 template <class REGS>
312 void write_config(REGS &, Parser *);
313 template <class REGS>
314 void write_output_config(REGS &, Parser *, State::Match *, void *, unsigned &) const;
315
316 private:
317 template <typename ROW>
318 void write_tofino_row_config(ROW &row);
319 template <typename ROW>
320 void write_row_config(ROW &row);
321 };
322
323 public:
324 void input(VECTOR(value_t) args, value_t data);
325 void process();
326 void output(json::map &) override;
327 void output_legacy(json::map &);
328 gress_t gress;
329 std::string name;
330 std::map<std::string, State *> states;
331 std::vector<State *> all;
332 std::map<State::Match *, int> match_to_row;
333 bitvec port_use;
334 int parser_no; // used to print cfg.json
335 bitvec state_use;
336 State::Ref start_state[4];
337 int priority[4] = {0};
338 int pri_thresh[4] = {0, 0, 0, 0};
339 int tcam_row_use = 0;
340 Phv::Ref parser_error;
341 // the ghost "parser" extracts 32-bit value
342 // this information is first extracted in AsmParser and passed to
343 // individual Parser, because currently parse_merge register is programmed
344 // in Parser class.
345 // FIXME -- should move all merge reg handling into AsmParser.
346 std::vector<Phv::Ref> ghost_parser;
347 unsigned ghost_pipe_mask = 0xf; // only set for JBAY
348 bitvec (&phv_use)[2];
349 bitvec phv_allow_bitwise_or, phv_allow_clear_on_write;
350 bitvec phv_init_valid;
351 int hdr_len_adj = 0, meta_opt = 0;
352 std::vector<std::array<Checksum *, PARSER_CHECKSUM_ROWS>> checksum_use;
353 std::array<CounterInit *, PARSER_CTRINIT_ROWS> counter_init = {};
354 static std::map<gress_t, std::map<std::string, std::vector<State::Match::Clot *>>> clots;
355 static std::array<std::vector<State::Match::Clot *>, PARSER_MAX_CLOTS> clot_use;
356 static unsigned max_handle;
357 int parser_handle = -1;
358 RateLimit rate_limit;
359
360 Parser(bitvec (&phv_use)[2], gress_t gr, int idx)
361 : gress(gr), parser_no(idx), phv_use(phv_use) {
362 if (gress == INGRESS) {
363 parser_depth_max_bytes = Target::PARSER_DEPTH_MAX_BYTES_INGRESS();
364 parser_depth_min_bytes = Target::PARSER_DEPTH_MIN_BYTES_INGRESS();
365 } else {
366 parser_depth_max_bytes = Target::PARSER_DEPTH_MAX_BYTES_EGRESS();
367 parser_depth_min_bytes = Target::PARSER_DEPTH_MIN_BYTES_EGRESS();
368 }
369 }
370
371 template <class REGS>
372 void gen_configuration_cache(REGS &, json::vector &cfg_cache);
373 static int clot_maxlen(gress_t gress, unsigned tag) {
374 auto &vec = clot_use[tag];
375 return vec.empty() ? -1 : vec.at(0)->max_length;
376 }
377 static int clot_maxlen(gress_t gress, std::string tag) {
378 if (clots.count(gress) && clots.at(gress).count(tag))
379 return clots.at(gress).at(tag).at(0)->max_length;
380 return -1;
381 }
382 static int clot_tag(gress_t gress, std::string tag) {
383 if (clots.count(gress) && clots.at(gress).count(tag))
384 return clots.at(gress).at(tag).at(0)->tag;
385 return -1;
386 }
387
388 static const char *match_key_loc_name(int loc);
389 static int match_key_loc(const char *key);
390 static int match_key_loc(value_t &key, bool errchk = true);
391 static int match_key_size(const char *key);
392
393 // Parser Handle Setup
394 // ____________________________________________________
395 // | Table Type | Pipe Id | Parser Handle | PVS Handle |
396 // 31 24 20 12 0
397 // PVS Handle = 12 bits
398 // Parser Handle = 8 bits
399 // Pipe ID = 4 bits
400 // Table Type = 8 bits (Parser type is 15)
401 static unsigned next_handle() {
402 // unique_table_offset is to support multiple pipe.
403 // assume parser type is 15, table type used 0 - 6
404 return max_handle++ << 12 | unique_table_offset << 20 | 15 << 24;
405 }
406 // Store parser names to their handles. Used by phase0 match tables to link
407 // parser handle
408 static std::map<std::string, unsigned> parser_handles;
409 static unsigned get_parser_handle(std::string phase0Table) {
410 for (auto p : Parser::parser_handles) {
411 auto parser_name = p.first;
412 if (phase0Table.find(parser_name) != std::string::npos) return p.second;
413 }
414 return 0;
415 }
416
417 template <class REGS>
418 void *setup_phv_output_map(REGS &, gress_t, int);
419
420 State *get_start_state() {
421 std::vector<std::string> startNames = {"start", "START", "$entry_point.start",
422 "$entry_point"};
423 for (auto n : startNames) {
424 if (states.count(n)) return states.at(n);
425 }
426 return nullptr;
427 }
428
429 int get_prsr_max_dph();
430 int get_header_stack_size_from_valid_bits(std::vector<State::Match::Set *> sets);
431
432 // Debug
433 void print_all_paths();
434
435 private:
436 template <class REGS>
437 void mark_unused_output_map(REGS &, void *, unsigned);
438 void define_state(gress_t gress, pair_t &kv);
439 void output_default_ports(json::vector &vec, bitvec port_use);
440 int state_prsr_dph_max(const State *s);
441 int state_prsr_dph_max(const State *s, std::map<const State *, std::pair<int, int>> &visited,
442 int curr_dph_bits);
443 int parser_depth_max_bytes, parser_depth_min_bytes;
444};
445
446class AsmParser : public BaseAsmParser {
447 std::vector<Parser *> parser[2]; // INGRESS, EGRESS
448 bitvec phv_use[2]; // ingress/egress only
449 std::vector<Phv::Ref> ghost_parser; // the ghost "parser" extracts 32-bit value. This 32-bit
450 // can be from a single 32-bit container or multiple
451 // smaller one.
452 unsigned ghost_pipe_mask = 0xf; // only set for JBAY
453 void start(int lineno, VECTOR(value_t) args) override;
454 void input(VECTOR(value_t) args, value_t data) override;
455 void process() override;
456 void output(json::map &) override;
457 void init_port_use(bitvec &port_use, const value_t &arg);
458
459 public:
460 AsmParser() : BaseAsmParser("parser") {};
461 ~AsmParser() {}
462
463 // For gtest
464 std::vector<Parser *> test_get_parser(gress_t gress);
465};
466
467template <class REGS>
468void Parser::PriorityUpdate::write_config(REGS &action_row) {
469 if (offset >= 0) {
470 action_row.pri_upd_type = 1;
471 action_row.pri_upd_src = offset;
472 action_row.pri_upd_en_shr = shift;
473 action_row.pri_upd_val_mask = mask;
474 } else {
475 action_row.pri_upd_type = 0;
476 action_row.pri_upd_en_shr = 1;
477 action_row.pri_upd_val_mask = mask;
478 }
479}
480
481// for jbay (tofino1 is specialized)
482template <>
483void Parser::RateLimit::write_config(::Tofino::regs_pipe &regs, gress_t gress);
484template <class REGS>
485void Parser::RateLimit::write_config(REGS &regs, gress_t gress) {
486 if (gress == INGRESS) {
487 auto &ctrl = regs.pardereg.pgstnreg.parbreg.left.i_phv_rate_ctrl;
488 ctrl.inc = inc;
489 ctrl.interval = interval;
490 ctrl.max = max;
491 } else if (gress == EGRESS) {
492 auto &ctrl = regs.pardereg.pgstnreg.parbreg.right.e_phv_rate_ctrl;
493 ctrl.inc = inc;
494 ctrl.interval = interval;
495 ctrl.max = max;
496 }
497}
498
499template <class REGS>
500void Parser::State::MatchKey::write_config(REGS &, json::vector &) {
501 // FIXME -- TBD -- probably needs to be different for tofino/jbay, so there will be
502 // FIXME -- template specializations for this in those files
503}
504
505template <class REGS>
506void Parser::State::Match::write_saves(REGS &regs, Match *def, void *output_map, int &max_off,
507 unsigned &used, int csum_8b, int csum_16b) {
508 if (offset_inc)
509 for (auto s : save) s->flags |= OFFSET;
510 for (auto s : save)
511 max_off =
512 std::max(max_off, s->write_output_config(regs, output_map, used, csum_8b, csum_16b));
513 if (def)
514 for (auto &s : def->save)
515 max_off = std::max(max_off,
516 s->write_output_config(regs, output_map, used, csum_8b, csum_16b));
517}
518
519template <class REGS>
520void Parser::State::Match::write_sets(REGS &regs, Match *def, void *output_map, unsigned &used,
521 int csum_8b, int csum_16b) {
522 if (offset_inc)
523 for (auto s : set) s->flags |= ROTATE;
524 for (auto s : set) s->write_output_config(regs, output_map, used, csum_8b, csum_16b);
525 if (def)
526 for (auto s : def->set) s->write_output_config(regs, output_map, used, csum_8b, csum_16b);
527}
528
529template <class REGS>
530void Parser::State::Match::write_common_row_config(REGS &regs, Parser *pa, State *state, int row,
531 Match *def, json::map &ctxt_json) {
532 int max_off = -1;
533 write_lookup_config(regs, state, row);
534
535 auto &ea_row = regs.memory[state->gress].ml_ea_row[row];
536 if (ctr_instr || ctr_load || ctr_imm_amt || ctr_stack_pop) {
537 write_counter_config(ea_row);
538 } else if (def) {
539 def->write_counter_config(ea_row);
540 }
541 if (shift)
542 max_off = std::max(max_off, int(ea_row.shift_amt = shift) - 1);
543 else if (def)
544 max_off = std::max(max_off, int(ea_row.shift_amt = def->shift) - 1);
545 max_off = std::max(max_off, write_load_config(regs, pa, state, row));
546 if (auto &next = (!this->next && def) ? def->next : this->next) {
547 std::vector<State *> prev;
548 for (auto n : next) {
549 max_off = std::max(max_off, n->write_lookup_config(regs, pa, state, row, prev));
550 prev.push_back(n);
551 }
552 const match_t &n = next.pattern ? next.pattern : next->stateno;
553 ea_row.nxt_state = n.word1;
554 ea_row.nxt_state_mask = ~(n.word0 & n.word1) & PARSER_STATE_MASK;
555 } else {
556 ea_row.done = 1;
557 }
558
559 auto &action_row = regs.memory[state->gress].po_action_row[row];
560 for (auto &c : csum) {
561 action_row.csum_en[c.unit] = 1;
562 action_row.csum_addr[c.unit] = c.addr;
563 }
564 if (offset_inc || offset_rst) {
565 action_row.dst_offset_inc = offset_inc;
566 action_row.dst_offset_rst = offset_rst;
567 } else if (def) {
568 action_row.dst_offset_inc = def->offset_inc;
569 action_row.dst_offset_rst = def->offset_rst;
570 }
571 if (priority) priority.write_config(action_row);
572 if (hdr_len_inc_stop) hdr_len_inc_stop.write_config(action_row);
573
574 void *output_map = pa->setup_phv_output_map(regs, state->gress, row);
575 unsigned used = 0;
576 int csum_8b = 0;
577 int csum_16b = 0;
578 for (auto &c : csum) {
579 c.write_output_config(regs, pa, this, output_map, used);
580 if (c.type == 0 && c.dest) {
581 if (c.dest->reg.size == 8)
582 ++csum_8b;
583 else if (c.dest->reg.size == 16)
584 ++csum_16b;
585 }
586 }
587
588 if (options.target == TOFINO) {
589 write_sets(regs, def, output_map, used, csum_8b, csum_16b);
590 write_saves(regs, def, output_map, max_off, used, csum_8b, csum_16b);
591 } else {
592 write_sets(regs, def, output_map, used, 0, 0);
593 write_saves(regs, def, output_map, max_off, used, 0, 0);
594 }
595
596 int clot_unit = 0;
597 for (auto *c : clots) c->write_config(action_row, clot_unit++, offset_inc > 0);
598 if (def)
599 for (auto *c : def->clots) c->write_config(action_row, clot_unit++, offset_inc > 0);
600 pa->mark_unused_output_map(regs, output_map, used);
601
602 if (buf_req < 0) {
603 buf_req = max_off + 1;
604 BUG_CHECK(buf_req <= 32, "Buffer requirement too large: %d", buf_req);
605 }
606 ea_row.buf_req = buf_req;
607}
608
609template <class REGS>
610void Parser::State::Match::write_row_config(REGS &regs, Parser *pa, State *state, int row,
611 Match *def, json::map &ctxt_json) {
612 write_common_row_config(regs, pa, state, row, def, ctxt_json);
613}
614
615template <class REGS>
616void Parser::State::Match::write_config(REGS &regs, Parser *pa, State *state, Match *def,
617 json::map &ctxt_json) {
618 int row, count = 0;
619 do {
620 if ((row = --pa->tcam_row_use) < 0) {
621 if (row == -1)
622 error(state->lineno, "Ran out of tcam space in %sgress parser",
623 state->gress ? "e" : "in");
624 return;
625 }
626 ctxt_json["tcam_rows"].to<json::vector>().push_back(row);
627 write_row_config(regs, pa, state, row, def, ctxt_json);
628 pa->match_to_row[this] = row;
629 } while (++count < value_set_size);
630}
631
632template <class REGS>
633void Parser::State::Match::write_config(REGS &regs, json::vector &vec) {
634 int select_statement_bit = 0;
635 for (auto f : field_mapping) {
636 json::map container_cjson;
637 container_cjson["container_width"] = Parser::match_key_size(f.container_id.c_str());
638
639 int container_hardware_id = Parser::match_key_loc(f.container_id.c_str());
640 container_cjson["container_hardware_id"] = container_hardware_id;
641
642 container_cjson["mask"] = (1 << (f.hi - f.lo + 1)) - 1;
643 json::vector field_mapping_cjson;
644 for (auto i = f.lo; i <= f.hi; i++) {
645 json::map field_map;
646 field_map["register_bit"] = i;
647 field_map["field_name"] = f.where.name();
648 field_map["start_bit"] = i;
649 field_map["select_statement_bit"] = select_statement_bit++;
650 field_mapping_cjson.push_back(field_map.clone());
651 }
652 container_cjson["field_mapping"] = field_mapping_cjson.clone();
653 vec.push_back(container_cjson.clone());
654 }
655}
656
657template <class REGS>
658void Parser::State::write_config(REGS &regs, Parser *pa, json::vector &ctxt_json) {
659 LOG2(gress << " state " << name << " (" << stateno << ')');
660 for (auto i : match) {
661 bool uses_pvs = false;
662 json::map state_cjson;
663 state_cjson["parser_name"] = name;
664 i->write_config(regs, state_cjson["match_registers"]);
665 if (i->value_set_size > 0) uses_pvs = true;
666 i->write_config(regs, pa, this, def, state_cjson);
667 state_cjson["uses_pvs"] = uses_pvs;
668 if (def) def->write_config(regs, pa, this, 0, state_cjson);
669 if (uses_pvs) {
670 state_cjson["pvs_name"] = i->value_set_name;
671 if (i->value_set_handle < 0)
672 error(lineno, "Invalid handle for parser value set %s", i->value_set_name.c_str());
673 auto pvs_handle_full = i->value_set_handle;
674 state_cjson["pvs_handle"] = pvs_handle_full;
675 }
676 for (auto idx : MatchIter(stateno)) {
677 state_cjson["parser_state_id"] = idx;
678 ctxt_json.push_back(state_cjson.clone());
679 }
680 }
681}
682
683template <typename ROW>
684void Parser::Checksum::write_tofino_row_config(ROW &row) {
685 row.add = add;
686 if (dest)
687 row.dst = dest->reg.parser_id();
688 else if (tag >= 0)
689 row.dst = tag;
690 row.dst_bit_hdr_end_pos = dst_bit_hdr_end_pos;
691 row.hdr_end = end;
692 int rsh = 0;
693 for (auto &el : row.mask) el = (mask >> rsh++) & 1;
694 row.shr = shift;
695 row.start = start;
696 rsh = 0;
697 for (auto &el : row.swap) el = (swap >> rsh++) & 1;
698 row.type = type;
699}
700
701template <class ROW>
702void Parser::Checksum::write_row_config(ROW &row) {
703 write_tofino_row_config(row);
704 int rsh = 0;
705 for (auto &el : row.mul_2) el = (mul_2 >> rsh++) & 1;
706}
707
708// Used with JBay
709bitvec expand_parser_groups(bitvec phvs);
710bitvec remove_nonparser(bitvec phvs);
711void setup_jbay_ownership(bitvec phv_use[2], checked_array<128, ubits<1>> &left,
712 checked_array<128, ubits<1>> &right, checked_array<256, ubits<1>> &main_i,
713 checked_array<256, ubits<1>> &main_e);
714void setup_jbay_no_multi_write(bitvec phv_allow_bitwise_or, bitvec phv_allow_clear_on_write,
715 checked_array<256, ubits<1>> &nmw_i,
716 checked_array<256, ubits<1>> &nmw_e);
717void setup_jbay_clear_on_write(bitvec phv_allow_clear_on_write, checked_array<128, ubits<1>> &left,
718 checked_array<128, ubits<1>> &right,
719 checked_array<256, ubits<1>> &main_i,
720 checked_array<256, ubits<1>> &main_e);
721
722#endif /* BACKENDS_TOFINO_BF_ASM_PARSER_TOFINO_JBAY_H_ */
Base class of Tofino parser in assembler.
Definition tofino/bf-asm/parser.h:32
Definition bitvec.h:120
Definition bf-asm/phv.h:186
Definition backends/tofino/bf-asm/json.h:300
Definition backends/tofino/bf-asm/json.h:222
Representation of the Tofino 1/2 parser in assembler.
Definition parser-tofino-jbay.h:48
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:58
Definition bson.cpp:69
Definition tables.h:1466
Definition match.h:36
Definition parser-tofino-jbay.h:139
std::set< Match * > get_all_preds()
Definition parser-tofino-jbay.cpp:1851
bool has_narrow_to_wide_extract
Definition parser-tofino-jbay.h:164
Definition parser-tofino-jbay.h:107
Definition parser-tofino-jbay.h:130
Definition parser-tofino-jbay.h:85
Definition parser-tofino-jbay.h:84
Definition asm-types.h:150
Definition asm-types.h:114