P4C
The P4 Compiler
Loading...
Searching...
No Matches
jbay/counter.h
1
17
18#ifndef BACKENDS_TOFINO_BF_ASM_JBAY_COUNTER_H_
19#define BACKENDS_TOFINO_BF_ASM_JBAY_COUNTER_H_
20
21template <typename REGS>
22void CounterTable::setup_teop_regs_2(REGS &regs, int stats_group_index) {
23 BUG_CHECK(teop >= 0 && teop < 4, "Invalid teop: %d", teop);
24 BUG_CHECK(gress == EGRESS, "Invalid gress: %d", gress);
25
26 auto &adrdist = regs.rams.match.adrdist;
27
28 if (!teop_initialized) {
29 // assume this stage driving teop
30 auto delay = stage->pipelength(gress) - stage->pred_cycle(gress) - 7;
31 adrdist.teop_bus_ctl[teop].teop_bus_ctl_delay = delay;
32 adrdist.teop_bus_ctl[teop].teop_bus_ctl_delay_en = 1;
33 adrdist.teop_bus_ctl[teop].teop_bus_ctl_stats_en = 1;
34
35 adrdist.stats_to_teop_adr_oxbar_ctl[teop].enabled_2bit_muxctl_select = stats_group_index;
36 adrdist.stats_to_teop_adr_oxbar_ctl[teop].enabled_2bit_muxctl_enable = 1;
37 teop_initialized = true;
38 }
39
40 adrdist.teop_to_stats_adr_oxbar_ctl[stats_group_index].enabled_2bit_muxctl_select = teop;
41 adrdist.teop_to_stats_adr_oxbar_ctl[stats_group_index].enabled_2bit_muxctl_enable = 1;
42
43 // count all tEOP events
44 adrdist.dp_teop_stats_ctl[stats_group_index].dp_teop_stats_ctl_err = 0;
45 // XXX is this always 2?
46 adrdist.dp_teop_stats_ctl[stats_group_index].dp_teop_stats_ctl_rx_shift = 2;
47 adrdist.dp_teop_stats_ctl[stats_group_index].dp_teop_stats_ctl_rx_en = 1;
48
49 auto &stats = regs.rams.map_alu.stats_wrap[stats_group_index].stats;
50 stats.statistics_ctl_teop_en = 1;
51}
52
53template <typename REGS>
54void CounterTable::write_alu_vpn_range_2(REGS &regs) {
55 auto &adrdist = regs.rams.match.adrdist;
56 int minvpn, sparevpn;
57
58 // Used to validate the BFA VPN configuration
59 std::set<int> vpn_processed;
60 bitvec vpn_range;
61
62 // Get Spare VPN
63 layout_vpn_bounds(minvpn, sparevpn, false);
64
65 for (int home_row : home_rows) {
66 bool block_start = false;
67 bool block_end = false;
68 int min = 1000000;
69 int max = -1;
70 for (Layout &logical_row : layout) {
71 // Block Start with the home row and End with the Spare VPN
72 if (logical_row.row == home_row) block_start = true;
73
74 if (block_start) {
75 for (auto v : logical_row.vpns) {
76 if (v == sparevpn) {
77 block_end = true;
78 break;
79 }
80 if (vpn_processed.count(v))
81 error(home_lineno, "Multiple instance of the VPN %d detected", v);
82 else
83 vpn_processed.insert(v);
84
85 if (v < min) min = v;
86 if (v > max) max = v;
87 }
88 }
89 if (block_end) {
90 BUG_CHECK(min != 1000000 && max != -1, " Invalid VPN range");
91
92 bitvec block_range(min, max - min + 1);
93 if (vpn_range.intersects(block_range))
94 error(home_lineno, "Overlapping of VPN range detected");
95 else
96 vpn_range |= block_range;
97
98 adrdist.mau_stats_alu_vpn_range[home_row / 4].stats_vpn_base = min;
99 adrdist.mau_stats_alu_vpn_range[home_row / 4].stats_vpn_limit = max;
100 adrdist.mau_stats_alu_vpn_range[home_row / 4].stats_vpn_range_check_enable = 1;
101 break;
102 }
103 }
104 BUG_CHECK(block_start && block_end, "Invalid VPN range");
105 }
106
107 if (vpn_range != bitvec(minvpn, sparevpn - minvpn))
108 error(home_lineno, "VPN range not entirely covered");
109}
110
111template <>
112void CounterTable::setup_teop_regs(Target::JBay::mau_regs &regs, int stats_group_index) {
113 setup_teop_regs_2(regs, stats_group_index);
114}
115
116template <>
117void CounterTable::write_alu_vpn_range(Target::JBay::mau_regs &regs) {
118 write_alu_vpn_range_2(regs);
119}
120
121#endif /* BACKENDS_TOFINO_BF_ASM_JBAY_COUNTER_H_ */
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:58