21void Stage::gen_configuration_cache(Target::JBay::mau_regs ®s,
json::vector &cfg_cache) {
22 Stage::gen_configuration_cache_common(regs, cfg_cache);
24 static unsigned i_pdddelay;
25 static unsigned e_pdddelay;
26 unsigned reg_width = 8;
27 std::string i_reg_value_str;
28 std::string e_reg_value_str;
29 std::string reg_fqname;
32 std::string reg_value_str;
35 if (i_pdddelay > regs.cfg_regs.amod_pre_drain_delay[INGRESS])
36 i_pdddelay = regs.cfg_regs.amod_pre_drain_delay[INGRESS];
37 if (e_pdddelay > regs.cfg_regs.amod_pre_drain_delay[EGRESS])
38 e_pdddelay = regs.cfg_regs.amod_pre_drain_delay[EGRESS];
40 if (stageno == AsmStage::numstages() - 1) {
42 i_pdddelay += (7 + 64);
43 i_reg_value_str = int_to_hex_string(i_pdddelay, reg_width);
44 e_pdddelay += (7 + 64);
45 e_reg_value_str = int_to_hex_string(e_pdddelay, reg_width);
47 add_cfg_reg(cfg_cache,
"pardereg.pgstnreg.parbreg.left.i_wb_ctrl",
"left_i_wb_ctrl",
49 add_cfg_reg(cfg_cache,
"pardereg.pgstnreg.parbreg.right.e_wb_ctrl",
"right_e_wb_ctrl",
55 auto &meter_ctl = regs.rams.map_alu.meter_group;
56 for (
int i = 0; i < 4; i++) {
57 reg_fqname =
"mau[" + std::to_string(stageno) +
"].rams.map_alu.meter_group[" +
58 std::to_string(i) +
"]" +
".meter.meter_ctl";
59 reg_name =
"stage_" + std::to_string(stageno) +
"_meter_ctl_" + std::to_string(i);
60 reg_value = meter_ctl[i].meter.meter_ctl;
61 if ((reg_value != 0) || (options.match_compiler)) {
62 reg_value_str = int_to_hex_string(reg_value, reg_width);
63 add_cfg_reg(cfg_cache, reg_fqname, reg_name, reg_value_str);
69 vec.push_back(val | extra);
71static void addvec(
json::vector &vec, uint32_t val, uint32_t extra = 0) {
72 vec.push_back(val | extra);
77 for (
auto &el : array) addvec(vec, el, extra);
80template <
class REGS,
class REG>
81static json::map make_reg_vec(REGS ®s, REG ®,
const char *name, uint32_t mask0,
82 uint32_t mask1, uint32_t mask2, uint32_t extra = 0) {
85 rv[
"offset"] = regs.binary_offset(®);
86 addvec(rv[
"value"], reg, extra);
92void Stage::gen_mau_stage_extension(REGS ®s,
json::map &extend) {
93 extend[
"last_programmed_stage"] = Target::NUM_MAU_STAGES() - 1;
94 json::vector ®isters = extend[
"registers"] = json::vector();
95 registers.push_back(make_reg_vec(regs, regs.dp.phv_ingress_thread,
"regs.dp.phv_ingress_thread",
97 registers.push_back(make_reg_vec(regs, regs.dp.phv_ingress_thread_imem,
98 "regs.dp.phv_ingress_thread_imem", 0, 0x3ff, 0x3ff));
99 registers.push_back(make_reg_vec(regs, regs.dp.phv_egress_thread,
"regs.dp.phv_egress_thread",
101 registers.push_back(make_reg_vec(regs, regs.dp.phv_egress_thread_imem,
102 "regs.dp.phv_egress_thread_imem", 0, 0x3ff, 0x3ff));
103 registers.push_back(make_reg_vec(regs, regs.rams.match.adrdist.adr_dist_pipe_delay,
104 "regs.rams.match.adrdist.adr_dist_pipe_delay", 0, 0xf, 0xf));
105 typename std::remove_reference<
106 decltype(regs.rams.match.adrdist.deferred_eop_bus_delay[0])>::type mask0,
108 mask0.eop_delay_fifo_en = mask1.eop_delay_fifo_en = 1;
109 mask0.eop_internal_delay_fifo = mask1.eop_internal_delay_fifo = 0x1f;
110 mask0.eop_output_delay_fifo = 0x1;
111 mask1.eop_output_delay_fifo = 0x1f;
112 BUG_CHECK(regs.rams.match.adrdist.deferred_eop_bus_delay[0].eop_output_delay_fifo &
113 regs.rams.match.adrdist.deferred_eop_bus_delay[1].eop_output_delay_fifo & 1,
115 registers.push_back(make_reg_vec(regs, regs.rams.match.adrdist.deferred_eop_bus_delay,
116 "regs.rams.match.adrdist.deferred_eop_bus_delay", mask0, mask0,
118 registers.push_back(make_reg_vec(regs, regs.dp.cur_stage_dependency_on_prev,
119 "regs.dp.cur_stage_dependency_on_prev", 0, 0x3, 0x3, 0x1));
120 registers.push_back(make_reg_vec(regs, regs.dp.next_stage_dependency_on_cur,
121 "regs.dp.next_stage_dependency_on_cur", 0x3, 0x3, 0, 0x1));
122 registers.push_back(make_reg_vec(regs, regs.rams.match.merge.mpr_bus_dep,
123 "regs.rams.match.merge.mpr_bus_dep", 0x3, 0x3, 0, 0x3));
124 registers.push_back(make_reg_vec(regs, regs.dp.pipelength_added_stages,
125 "regs.dp.pipelength_added_stages", 0, 0xf, 0xf));
126 registers.push_back(make_reg_vec(regs, regs.rams.match.merge.exact_match_delay_thread,
127 "regs.rams.match.merge.exact_match_delay_thread", 0, 0x3,
129 BUG_CHECK((regs.rams.match.merge.mpr_thread_delay[0] & 1) == 0,
"bad mask");
130 BUG_CHECK((regs.rams.match.merge.mpr_thread_delay[1] & 1) == 0,
"bad mask");
131 registers.push_back(make_reg_vec(regs, regs.rams.match.merge.mpr_thread_delay,
132 "regs.rams.match.merge.mpr_thread_delay", 1, 1, 0x1f));
140static void disable_jbay_power_gating(REGS ®s) {
141 for (gress_t gress : Range(INGRESS, EGRESS)) {
142 regs.dp.mau_match_input_xbar_exact_match_enable[gress] |= 0x1;
143 regs.dp.xbar_hash.xbar.mau_match_input_xbar_ternary_match_enable[gress] |= 0x1;
146 auto &xbar_power_ctl = regs.dp.match_input_xbar_din_power_ctl;
147 auto &actionmux_power_ctl = regs.dp.actionmux_din_power_ctl;
148 for (
int side = 0; side < 2; side++) {
149 for (
int reg = 0; reg < 16; reg++) {
150 xbar_power_ctl[side][reg] |= 0x3FF;
151 actionmux_power_ctl[side][reg] |= 0x3FF;
157void Stage::write_regs(Target::JBay::mau_regs ®s,
bool) {
158 write_common_regs<Target::JBay>(regs);
159 auto &merge = regs.rams.match.merge;
160 for (gress_t gress : Range(INGRESS, EGRESS)) {
162 merge.predication_ctl[gress].start_table_fifo_delay0 = pred_cycle(gress) - 2;
163 merge.predication_ctl[gress].start_table_fifo_enable = 1;
164 }
else if (stage_dep[gress] == MATCH_DEP) {
165 merge.predication_ctl[gress].start_table_fifo_delay0 =
166 this[-1].pipelength(gress) -
this[-1].pred_cycle(gress) + pred_cycle(gress) - 3;
167 merge.predication_ctl[gress].start_table_fifo_enable = 1;
169 BUG_CHECK(stage_dep[gress] == ACTION_DEP,
"bad stage dep");
170 merge.predication_ctl[gress].start_table_fifo_delay0 = 0;
171 merge.predication_ctl[gress].start_table_fifo_enable = 0;
175 regs.dp.cur_stage_dependency_on_prev[gress] = stage_dep[gress] != MATCH_DEP;
178 if (stageno == 0 && !options.stage_dependency_pattern.empty())
179 regs.dp.cur_stage_dependency_on_prev[gress] = stage_dep[gress] != MATCH_DEP;
181 if (stageno != AsmStage::numstages() - 1)
182 regs.dp.next_stage_dependency_on_cur[gress] =
this[1].stage_dep[gress] != MATCH_DEP;
183 else if (AsmStage::numstages() < Target::NUM_MAU_STAGES())
184 regs.dp.next_stage_dependency_on_cur[gress] = 1;
185 auto &deferred_eop_bus_delay = regs.rams.match.adrdist.deferred_eop_bus_delay[gress];
186 deferred_eop_bus_delay.eop_internal_delay_fifo = pred_cycle(gress) + 2;
188 if (stageno == AsmStage::numstages() - 1) {
189 if (AsmStage::numstages() < Target::NUM_MAU_STAGES())
190 deferred_eop_bus_delay.eop_output_delay_fifo = 1;
192 deferred_eop_bus_delay.eop_output_delay_fifo = pipelength(gress) - 2;
193 }
else if (
this[1].stage_dep[gress] == MATCH_DEP) {
194 deferred_eop_bus_delay.eop_output_delay_fifo = pipelength(gress) - 2;
196 deferred_eop_bus_delay.eop_output_delay_fifo = 1;
198 deferred_eop_bus_delay.eop_delay_fifo_en = 1;
199 if (stageno != AsmStage::numstages() - 1 &&
this[1].stage_dep[gress] == MATCH_DEP) {
200 merge.mpr_thread_delay[gress] = pipelength(gress) - pred_cycle(gress) - 4;
203 if (stageno == AsmStage::numstages() - 1) {
204 merge.mpr_thread_delay[gress] = pipelength(gress) - pred_cycle(gress) - 4;
206 merge.mpr_thread_delay[gress] = 0;
211 for (gress_t gress : Range(INGRESS, EGRESS))
212 if (table_use[gress] & USE_TCAM)
213 regs.tcams.tcam_piped |= options.match_compiler ? 3 : 1 << gress;
215 for (gress_t gress : Range(INGRESS, EGRESS)) {
216 regs.cfg_regs.amod_pre_drain_delay[gress] = pipelength(gress) - 9;
217 if (
this[1].stage_dep[gress] == MATCH_DEP)
218 regs.cfg_regs.amod_wide_bubble_rsp_delay[gress] = pipelength(gress) - 3;
220 regs.cfg_regs.amod_wide_bubble_rsp_delay[gress] = 0;
225 regs.cfg_regs.amod_req_interval = 6732;
226 regs.cfg_regs.amod_req_limit = 15;
233 regs.dp.match_ie_input_mux_sel |= 3;
236 merge.pred_stage_id = stageno;
237 if (long_branch_terminate) merge.pred_long_brch_terminate = long_branch_terminate;
238 for (gress_t gress : Range(INGRESS, GHOST)) {
239 if (long_branch_thread[gress])
240 merge.pred_long_brch_thread[gress] = long_branch_thread[gress];
243 for (gress_t gress : Range(INGRESS, GHOST)) {
244 merge.mpr_stage_id[gress] = mpr_stage_id[gress];
245 for (
int id = 0;
id < LOGICAL_TABLES_PER_STAGE; ++id) {
246 merge.mpr_next_table_lut[gress][id] = mpr_next_table_lut[gress][id];
249 for (
int id = 0;
id < LOGICAL_TABLES_PER_STAGE; ++id) {
250 merge.mpr_glob_exec_lut[id] = mpr_glob_exec_lut[id];
252 for (
int id = 0;
id < MAX_LONGBRANCH_TAGS; ++id) {
253 merge.mpr_long_brch_lut[id] = mpr_long_brch_lut[id];
255 merge.mpr_always_run = mpr_always_run;
257 if (stageno != AsmStage::numstages() - 1) {
258 merge.mpr_bus_dep.mpr_bus_dep_ingress =
this[1].stage_dep[INGRESS] != MATCH_DEP;
259 merge.mpr_bus_dep.mpr_bus_dep_egress =
this[1].stage_dep[EGRESS] != MATCH_DEP;
262 merge.mpr_bus_dep.mpr_bus_dep_glob_exec = mpr_bus_dep_glob_exec[INGRESS] |
263 mpr_bus_dep_glob_exec[EGRESS] |
264 mpr_bus_dep_glob_exec[GHOST];
265 merge.mpr_bus_dep.mpr_bus_dep_long_brch = mpr_bus_dep_long_branch[INGRESS] |
266 mpr_bus_dep_long_branch[EGRESS] |
267 mpr_bus_dep_long_branch[GHOST];
269 merge.mpr_long_brch_thread = long_branch_thread[EGRESS];
270 if (
auto conflict = (long_branch_thread[INGRESS] | long_branch_thread[GHOST]) &
271 long_branch_thread[EGRESS]) {
273 for (
auto tag : bitvec(conflict)) {
274 error(long_branch_use[tag]->lineno,
275 "Need one-stage turnaround before reusing "
276 "long_branch tag %d in a different thread",
281 bitvec in_use = match_use[INGRESS] | action_use[INGRESS] | action_set[INGRESS];
282 bitvec eg_use = match_use[EGRESS] | action_use[EGRESS] | action_set[EGRESS];
286 in_use |= Phv::use(INGRESS);
287 eg_use |= Phv::use(EGRESS);
288 static const int phv_use_transpose[2][14] = {
289 {0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21},
290 {4, 5, 6, 7, 12, 13, 14, 15, 22, 23, 24, 25, 26, 27}};
293 for (
int i = 0; i < 2; i++) {
294 for (
int j = 0; j < 14; j++) {
295 regs.dp.phv_ingress_thread[i][j] = regs.dp.phv_ingress_thread_imem[i][j] =
296 in_use.getrange(10 * phv_use_transpose[i][j], 10);
297 regs.dp.phv_egress_thread[i][j] = regs.dp.phv_egress_thread_imem[i][j] =
298 eg_use.getrange(10 * phv_use_transpose[i][j], 10);
304 if (options.disable_power_gating) {
305 disable_jbay_power_gating(regs);
308 write_teop_regs(regs);
311void AlwaysRunTable::write_regs(Target::JBay::mau_regs ®s) {
313 regs.dp.imem_word_read_override.imem_word_read_override_egress = 1;
315 regs.dp.imem_word_read_override.imem_word_read_override_ingress = 1;
316 actions->write_regs(regs,
this);
Definition checked_array.h:34
Definition backends/tofino/bf-asm/json.h:300
Definition backends/tofino/bf-asm/json.h:144
Definition backends/tofino/bf-asm/json.h:222
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:58