def bypass_RAW(self): """ if register is read after write in the same action block, rename the source register in read inst to the value in write inst. """ def check_raw(wset, p): for s in wset: dst_reg = s.parameters[0] dst_idx = s.parameters[1] dst_field = s.parameters[2] src_reg = p.parameters[1] src_idx = p.parameters[2] if dst_reg == src_reg and dst_idx == src_idx: return dst_field return None newPrimitives = [] bypass_map = OrderedDict() rset = set() wset = set() for p in self.primitives: if type(p) == prm.RegisterRead: rset.add(p) dst_field = check_raw(wset, p) if dst_field: # RAW exists, forward logger.debug("DEBUG: execute RAW bypass") param = [] param.append(p.parameters[0]) param.append(dst_field) _p = prm.ModifyField("modify_field", param) _src = p4name(dst_field['value']) _dst = p4name(p.parameters[0]['value']) bypass_map[_dst] = _src logger.info("BYPASS: %s", _p) newPrimitives.append(_p) else: newPrimitives.append(p) elif type(p) == prm.RegisterWrite: wset.add(p) newPrimitives.append(p) else: newPrimitives.append(p) self.primitives = newPrimitives self.bypass_map = bypass_map
def buildRuleMatchResponseStmt(self): TMP1 = "let v <- toGet(bbRspFifo[readyChannel]).get;" TMP2 = "let meta <- toGet(metadata_ff[1]).get;" TMP3 = "tagged %(name)sRspT {%(field)s}" TMP4 = "%(ty_metadata)s rsp = tagged %(name)s {pkt: pkt, meta: meta};" TMP5 = "tx_info_%(name)s.enq(rsp);" TMP6 = "meta.%(mname)s = tagged Valid %(mname)s;" stmt = [] case_stmt = ast.Case("v") for idx, action in enumerate(self.actions): basic_block = self.basic_block_map[action] fields = basic_block.response.build_match_expr() action_stmt = [] for field in basic_block.response.members: mname = p4name(field) action_stmt.append(ast.Template(TMP6 % {"mname": mname})) tagname = "%s%sRspT" % (CamelCase(self.name), CamelCase(action)) action_stmt.append( ast.Template( TMP4 % { "name": tagname, "ty_metadata": CamelCase(self.name) + "Response" })) action_stmt.append(ast.Template(TMP5 % {"name": "metadata"})) action = TMP3 % {"name": CamelCase(action), "field": fields} case_stmt.casePatStmt[action] = action_stmt stmt.append(ast.Template(TMP1)) stmt.append(ast.Template(TMP2)) stmt.append(case_stmt) return stmt
def build_match_expr(self): e = ["pkt: .pkt"] for m in self.members: _m = p4name(m) e.append("%s: .%s" % (_m, _m)) for m in self.runtime_data: e.append("runtime_%s_%d: .runtime_%s" % (m[1], m[0], m[1])) return ", ".join(e)
def build_case_expr(self): e = ["pkt: pkt"] for m in self.members: fullname = p4name(m) field = m[1] e.append("%s: %s" % (fullname, field)) for m in self.runtime_data: e.append("runtime_%s_%d: resp.runtime_%s" % (m[1], m[0], m[1])) return ", ".join(e)
def buildRuleMatchRequest(self): TMP1 = "let data = rx_info_%(name)s.first;" TMP2 = "let meta = data.meta;" TMP8 = "let pkt = data.pkt;" TMP3 = "%(type)s req = %(type)s {%(field)s};" TMP4 = "matchTable.lookupPort.request.put(pack(req));" TMP5 = "let %(name)s = fromMaybe(?, meta.%(name)s);" TMP6 = "{%(field)s}" TMP7 = "rx_info_%(name)s.deq;" rname = "rl_handle_request" stmt = [] stmt.append(ast.Template(TMP1, {"name": "metadata"})) stmt.append(ast.Template(TMP7, {"name": "metadata"})) stmt.append(ast.Template(TMP2)) stmt.append(ast.Template(TMP8)) keys = self.buildMatchKey() fields = [] total_width = 0 for k in keys: if type(k) != list: total_width += 1 name = 'valid_%s' % k fields.append("%s: %s" % (p4name(name), p4name(name))) else: width = GetFieldWidth(k) total_width += width stmt.append(ast.Template(TMP5, {"name": p4name(k)})) fields.append("%s: %s" % (p4name(k), p4name(k))) if (total_width % 9): fields.insert(0, "padding: 0") stmt.append( ast.Template(TMP3, { "type": self.req_name, "field": ", ".join(fields) })) stmt.append(ast.Template(TMP4)) stmt.append(ast.Template("packet_ff.enq(pkt);")) stmt.append(ast.Template("metadata_ff[0].enq(meta);")) cond = [] rule = ast.Rule(rname, cond, stmt) return rule
def __init__(self, name, members, runtime_data=[], bypass_map=None): self.name = name self.members = members self.runtime_data = runtime_data self.bypass_map = bypass_map e = [] e.append(ast.StructMember("PacketInstance", "pkt")) for m in members: _m = p4name(m) e.append(ast.StructMember("Bit#(%s)"%(GetFieldWidth(m)), _m)) for r in runtime_data: e.append(ast.StructMember("Bit#(%s)"%(r[0]), "runtime_%s_%d"%(r[1], r[0]))) self.struct = ast.Struct(name, e)
def build_phv(self): metadata = set() fields = [] for it in config.ir.basic_blocks.values(): for f in it.request.members: if f not in metadata: width = GetFieldWidth(f) name = p4name(f) fields.append((width, name)) metadata.add(f) for f in config.ir.controls.values(): for _, v in f.tables.items(): for k in v.key: d = tuple(k['target']) if d not in metadata: width = GetFieldWidth(k['target']) name = p4name(k['target']) fields.append((width, name)) metadata.add(d) #for it in config.ir.parsers.values(): # for h in it.header_instances.values(): # name = "valid_%s" % (camelCase(h)) # fields.append((0, name)) return fields
def __init__(self, name, key): self.name = name fields = [] total_width = 0 pad_width = 0 for k in key: if k['match_type'] == 'valid': total_width += 1 name = 'valid_%s' % (k['target'].translate(None, "[]")) fields.append(ast.StructMember("Bool", name)) else: width = GetFieldWidth(k['target']) total_width += width name = p4name(k['target']) fields.append(ast.StructMember("Bit#(%s)" %(width), name)) if (total_width % 9): pad_width = 9 - total_width % 9 fields.insert(0, ast.StructMember("Bit#(%s)" %(pad_width), "padding")) self.struct = ast.Struct("%sReqT"%(CamelCase(self.name)), fields) self.width = total_width + pad_width
def buildRuleActionRequest(self): TMP1 = "let data = rx_info_%(name)s.first;" TMP2 = "rx_info_%(name)s.deq;" TMP3 = "let meta = data.meta;" TMP4 = "let pkt = data.pkt;" TMP5 = "let %(field)s = fromMaybe(?, meta.%(field)s);" TMP8 = "BBRequest req = tagged %(type)sReqT {%(field)s};" TMP9 = "bbReqFifo[%(id)s].enq(req); //FIXME: replace with RXTX." stmt = [] stmt.append(ast.Template(TMP1, {"name": "metadata"})) stmt.append(ast.Template(TMP2, {"name": "metadata"})) stmt.append(ast.Template(TMP3)) stmt.append(ast.Template(TMP4)) stmt.append(ast.Template("packet_ff.enq(pkt);")) stmt.append(ast.Template("metadata_ff.enq(meta);")) for idx, action in enumerate(self.actions): basic_block = self.basic_block_map[action] for f in basic_block.request.members: stmt.append(ast.Template(TMP5, {"field": p4name(f)})) for idx, action in enumerate(self.actions): basic_block = self.basic_block_map[action] fields = basic_block.request.build_case_expr() stmt.append( ast.Template(TMP8, { "type": CamelCase(action), "field": fields })) stmt.append(ast.Template(TMP9, {"id": idx})) rname = "rl_handle_action_request" cond = [] rule = ast.Rule(rname, cond, stmt) return rule
def buildTableRuleStmt(self, tblName): TMP1 = "%(tblName)s_rsp_ff.deq;" TMP2 = "let _rsp = %(tblName)s_rsp_ff.first;" TMP3 = "let meta = _req.meta;" TMP4 = "let pkt = _req.pkt;" TMP5 = "let %(name)s = fromMaybe(?, meta.%(name)s);" TMP6 = "tagged %(type)s {%(field)s}" stmt = [] stmt.append(ast.Template(TMP1, {"tblName": tblName})) stmt.append(ast.Template(TMP2, {"tblName": tblName})) case_stmt = ast.Case("_rsp") for action, next_table in self.tables[tblName].next_tables.items(): ctype = "%s%sRspT" % (CamelCase(tblName), CamelCase(action)) pdict = {"type": ctype, "field": "meta: .meta, pkt: .pkt"} _ctype = ast.Template(TMP6, pdict) #case_stmt.casePatItem[ctype] = ast.Template(TMP6, pdict) _stmt, _meta, metadata = [], [], set() self.buildConditionalStmt(next_table, _stmt, metadata) for m in metadata: if type(m) is tuple: _meta.append(ast.Template(TMP5, {"name": p4name(m)})) case_stmt.casePatStmt[_ctype] = _meta + _stmt stmt.append(case_stmt) return stmt
def get_members(self): e = [] for m in self.members: e.append(p4name(m)) return e