Ejemplo n.º 1
0
    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 _add_defaults(self, fields):
     self.stmt.append(ast.Template(STRUCT_DEFAULT, {"name": CamelCase(self.name)}))
     self.stmt.append(ast.Template(STRUCT_MASK, {"name": CamelCase(self.name)}))
     _sum = 0
     for _, l in fields:
         _sum += l
     self.stmt.append(ast.Template(EXTRACT_TEMP, {"name": CamelCase(self.name), "lname": self.name, "width": _sum}))
Ejemplo n.º 3
0
    def buildRuleActionResponse(self):
        TMP1 = "let v <- toGet(bbRspFifo[readyChannel]).get;"
        TMP2 = "let meta <- toGet(metadata_ff).get;"
        TMP3 = "tagged %(name)sRspT {%(field)s}"
        TMP4 = "MetadataResponse rsp = tagged %(name)s%(action)sRspT {pkt: pkt, meta: meta};"
        TMP5 = "tx_info_%(name)s.enq(rsp);"
        TMP6 = "meta.%(name)s = tagged Valid %(name)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.get_members():
                action_stmt.append(ast.Template(TMP6 % {"name": field}))
            action_stmt.append(
                ast.Template(TMP4 % {
                    "name": CamelCase(self.name),
                    "action": CamelCase(action)
                }))
            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)

        rname = "rl_handle_action_response"
        cond = "interruptStatus"
        rule = ast.Rule(rname, cond, stmt)
        return rule
 def buildConnection(self):
     TMP1 = "Vector#(numClients, Server#(MetadataRequest, MetadataResponse)) mds = replicate(toServer(default_req_ff, default_rsp_ff));"
     TMP2 = "mkConnection(mds, mdc);"
     stmt = []
     stmt.append(ast.Template(TMP1))
     stmt.append(ast.Template(TMP2))
     return stmt
Ejemplo n.º 5
0
 def build_intf_decl_verbosity(self):
     stmt = []
     stmt.append(
         ast.Template("method Action set_verbosity (int verbosity);"))
     stmt.append(ast.Template("  cf_verbosity <= verbosity;"))
     stmt.append(ast.Template("endmethod"))
     return stmt
    def build_rule_parse_done(self):
        TMP1 = "let %(ktype)s <- toGet(%(ktype)s_out_ff).get;"
        stmt = []
        stmt += [ast.Template("MetadataT meta = defaultValue;")]
        pdict = {}
        pdict['ktype'] = set()
        for idx, s in enumerate(self.states.values()):
            keys = []
            for k in s.transition_keys:
                if k['type'] == 'lookahead':
                    print "WARNING: lookahead type not handled"
                    continue
                keys.append("%s.%s" % (k['value'][0], k['value'][1]))
                pdict['ktype'].add(k['value'][0])
            pdict['field'] = ",".join(keys)
        for ktype in pdict['ktype']:
            stmt += [ast.Template(TMP1, {'ktype': ktype})]

        for ktype in pdict['ktype']:
            if ktype in  self.metadata:
                stmt_if = []
                for f in self.metadata[ktype]:
                    stmt_if.append(ast.Template("meta.%(metafield)s = tagged Valid fromMaybe(?, %(ktype)s).%(field)s;" % {'metafield': "%s$%s" % (ktype, f[1]), 'ktype': ktype, 'field': f[1]}))
                stmt += [ast.If("isValid(%s)" % ktype, stmt_if)]

        stmt += [ast.Template("dbprint(3, $format(\"parse_done\"));")]
        stmt += [ast.Template("meta_in_ff.enq(meta);")]

        rcond = '(w_parse_done)' % pdict
        rname = 'rl_parse_done' % pdict
        rule = ast.Rule(rname, rcond, stmt, [])
        return [rule]
Ejemplo n.º 7
0
 def buildLoopback(self):
     TMP1 = "tagged %(type)s {%(field)s}"
     TMP2 = "let v = rx_info_prev_control_state.first;"
     TMP3 = "rx_info_prev_control_state.deq;"
     TMP4 = "BBResponse rsp = tagged %(type)s {pkt: pkt};"
     TMP5 = "tx_info_prev_control_state.enq(rsp);"
     rules = []
     stmt = []
     cname = CamelCase(self.name)
     ctype = "%sReqT"%(cname)
     pdict = {"type": ctype, "field": self.request.build_match_expr()}
     casePatStmts = []
     stmt.append(ast.Template(TMP2))
     stmt.append(ast.Template(TMP3))
     ctype = ast.Template(TMP1, pdict)
     case_stmt = ast.Case("v")
     case_stmt.casePatStmt[ctype] = casePatStmts
     rsp_prefix = CamelCase(self.name)
     casePatStmts.append(ast.Template(TMP4, {"type": "%sRspT"%(rsp_prefix)} ))
     casePatStmts.append(ast.Template(TMP5, {"name": self.name}))
     stmt.append(case_stmt)
     rname = self.name + "_loopback"
     rule = ast.Rule(rname, [], stmt)
     rules.append(rule)
     return rules
Ejemplo n.º 8
0
 def build_intf_decl_verbosity(self):
     stmt = []
     stmt.append(ast.Template("method Action set_verbosity (int verbosity);"))
     stmt.append(ast.Template("  cf_verbosity <= verbosity;"))
     if len(self.primitives) != 0:
         stmt.append(ast.Template("  cpu.set_verbosity(verbosity);"))
         stmt.append(ast.Template("  imem.set_verbosity(verbosity);"))
     stmt.append(ast.Template("endmethod"))
     return stmt
Ejemplo n.º 9
0
 def build_rules(self):
     stmt = []
     stmt.append(ast.Template('`ifdef DEPARSER_RULES\n'))
     for idx, s in enumerate(self.deparse_states):
         stmt.append(self.rule_state_next(s, GetHeaderWidth(s)))
         stmt.append(self.rule_state_load(s, GetHeaderWidth(s)))
         stmt.append(self.rule_state_send(s, GetHeaderWidth(s)))
     stmt.append(ast.Template('`endif // DEPARSER_RULES\n'))
     return stmt
Ejemplo n.º 10
0
 def build_state(self):
     stmt = []
     stmt.append(ast.Template("`ifdef DEPARSER_STATE\n"))
     for idx, state in enumerate(self.deparse_states):
         stmt.append(
             ast.Template(
                 "PulseWire w_deparse_%(name)s <- mkPulseWire();\n",
                 {'name': state.translate(None, "[]")}))
     stmt.append(ast.Template("`endif // DEPARSER_STATE\n"))
     return stmt
Ejemplo n.º 11
0
 def funct_compute_next_state(self, state):
     TMP1 = "DeparserState nextState = StateDeparseStart;"
     TMP2 = "return nextState;"
     stmt = []
     stmt.append(ast.Template(TMP1))
     stmt.append(ast.Template(TMP2))
     fname = "compute_next_state"
     rtype = "DeparserState"
     params = "DeparserState state"
     funct = ast.Function(fname, rtype, params, stmt)
     return funct
Ejemplo n.º 12
0
 def buildTXRX(self):
     TMP1 = "RX #(BBRequest) rx_%(name)s <- mkRX;"
     TMP2 = "TX #(BBResponse) tx_%(name)s <- mkTX;"
     TMP3 = "let rx_info_%(name)s = rx_%(name)s.u;"
     TMP4 = "let tx_info_%(name)s = tx_%(name)s.u;"
     stmt = []
     pdict = {'name': "prev_control_state"}
     stmt.append(ast.Template(TMP1, pdict))
     stmt.append(ast.Template(TMP2, pdict))
     stmt.append(ast.Template(TMP3, pdict))
     stmt.append(ast.Template(TMP4, pdict))
     return stmt
Ejemplo n.º 13
0
 def build_read_version(self):
     TMP1 = "let v = `NicVersion;"
     TMP2 = "indication.read_version_rsp(v);"
     name = "read_version"
     rtype = "Action"
     params = "Bit#(32) version"
     stmt = []
     stmt.append(ast.Template(TMP1))
     stmt.append(ast.Template(TMP2))
     req = ast.Method(name, rtype, stmt=stmt)
     rsp = ast.Method(name + "_rsp", rtype, params)
     return req, rsp
Ejemplo n.º 14
0
 def build_bdpi(self, tid, ksz, vsz):
     global generated_table_sim
     TMP1 = "`ifndef SVDPI"
     TMP2 = "import \"BDPI\" function ActionValue#(Bit#(%s)) matchtable_read_%s(Bit#(%s) msgtype);"
     TMP3 = "import \"BDPI\" function Action matchtable_write_%s(Bit#(%s) msgtype, Bit#(%s) data);"
     TMP4 = "`endif"
     stmt = []
     stmt.append(ast.Template(TMP1))
     stmt.append(ast.Template(TMP2 % (vsz, self.name, ksz)))
     stmt.append(ast.Template(TMP3 % (self.name, ksz, vsz)))
     stmt.append(ast.Template(TMP4))
     return stmt
    def build_rule_state_extract(self, state):
        tmpl = []
        tmpl.append("let data = rg_tmp[0];")
        tmpl.append("if (isValid(data_ff.first)) begin")
        tmpl.append("  data_ff.deq;")
        tmpl.append("  data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];")
        tmpl.append("end")
        tmpl.append("report_parse_action(parse_state_ff.first, rg_buffered[0], data_this_cycle, data);")
        TMP = "let %(header)s = extract_%(ktype)s(truncate(data));"
        tmpl2 = []
        tmpl2.append("compute_next_state_%(name)s(%(field)s);")
        tmpl2.append("rg_tmp[0] <= zeroExtend(data >> %(len)s);")
        tmpl2.append("succeed_and_next(%(len)s);")
        tmpl2.append("dbprint(3, $format(\"extract %%s\", \"%(name)s\"));")
        tmpl2.append("parse_state_ff.deq;")

        TMP3 = "%(header)s_out_ff.enq(tagged Valid %(header)s);"

        pdict = {}
        pdict['name'] = state.name
        pdict['CurrState'] = 'State%s' % (CamelCase(state.name))
        pdict['len'] = state.len
        keys = []
        pdict['ktype'] = set()
        for k in state.transition_keys:
            if k['type'] == 'lookahead':
                print "WARNING: lookahead type not handled"
                continue
            header_type = GetHeaderType(k['value'][0])
            header = k['value'][0]
            keys.append("%s.%s" % (header, k['value'][1]))
            pdict['ktype'].add((header, header_type))
        pdict['field'] = ",".join(keys)

        stmt = apply_pdict(tmpl, pdict)
        for hdr, ktype in pdict['ktype']:
            stmt += [ast.Template(TMP, {'header': hdr, 'ktype': ktype})]
        stmt += apply_pdict(tmpl2, pdict)
        for hdr, ktype in pdict['ktype']:
            stmt += [ast.Template(TMP3, {'header': hdr, 'ktype': ktype})]

        # build expression
        setexpr = GetExpressionInState(state.name)
        if setexpr[2] != None and setexpr[1] != None:
            dst = "".join(setexpr[1])+"[0]"
            src = "".join(setexpr[2])
            stmt += [ast.Template(dst + " <= " + src.replace("0x", "'h") + ";")]

        rcond = '(parse_state_ff.first == %(CurrState)s) && (rg_buffered[0] >= %(len)s)' % pdict
        rname = 'rl_%(name)s_extract' % pdict
        attr = ['fire_when_enabled']
        rule = ast.Rule(rname, rcond, stmt, attr)
        return [rule]
Ejemplo n.º 16
0
 def build_read_function(self, tid, ksz, vsz):
     TMP1 = "let v <- matchtable_read_%s(key);" % (self.name)
     TMP2 = "return v;"
     name = "matchtable_read"
     type = "ActionValue#(Bit#(%s))" % (vsz)
     params = "Bit#(%s) id, Bit#(%s) key" % (tid, ksz)
     stmt = []
     stmt.append(ast.Template(TMP1))
     stmt.append(ast.Template(TMP2))
     action_block = ast.ActionValueBlock(stmt)
     funct = ast.Function(name, type, params, stmt=[action_block])
     return funct
Ejemplo n.º 17
0
 def build_struct(self):
     stmt = []
     stmt.append(ast.Template('`ifdef DEPARSER_STRUCT\n'))
     elem = []
     elem.append(ast.EnumElement("StateDeparseStart", None, None))
     for state in self.deparse_states:
         elem.append(
             ast.EnumElement("StateDeparse%s" % (CamelCase(state)), None,
                             None))
     state = ast.Enum("DeparserState", elem)
     stmt.append(state)
     stmt.append(ast.Template('`endif // DEPARSER_STRUCT\n'))
     return stmt
 def build_types(self):
     stmt = []
     stmt.append(ast.Template("\n"))
     stmt.append(ast.Template("`ifdef PARSER_STRUCT\n"))
     elem = []
     if self.initial_state == 'default':
         elem.append(ast.EnumElement("StateDefault", None, None))
     for s in self.states.values():
         elem.append(ast.EnumElement("State%s" % (CamelCase(s.name)), None, None))
     state = ast.Enum("ParserState", elem)
     stmt.append(state)
     stmt.append(ast.Template("`endif //PARSER_STRUCT\n"))
     return stmt
 def build_funct_push_phv(self, phv):
     TMP1 = "MetadataT meta = defaultValue;"
     TMP2 = "meta.%(field)s = tagged Valid rg_tmp_%(field)s;"
     TMP3 = "meta_in_ff.enq(meta);"
     params = "ParserState ty"
     stmt = []
     stmt.append(ast.Template(TMP1))
     for _, p in phv:
         stmt.append(ast.Template(TMP2, {"field": p}))
     stmt.append(ast.Template(TMP3))
     ablock = apply_action_block(stmt)
     funct = ast.Function("push_phv", 'Action', params, ablock)
     return funct
 def buildTableInstance(self):
     TMP1 = "%(tblType)s %(tblName)s <- mk%(tblType)s();"
     TMP2 = "mkConnection(toClient(%(tblName)s_req_ff, %(tblName)s_rsp_ff), %(tblName)s.prev_control_state_%(id)s);"
     stmt = []
     for t in self.tables.values():
         stmt.append(
             ast.Template(TMP1, {
                 "tblType": CamelCase(t.name),
                 "tblName": t.name
             }))
     for t in self.tables.values():
         stmt.append(ast.Template(TMP2, {"tblName": t.name, "id": 0}))
     return stmt
 def build_transition(name, transition):
     TMP1 = "w_%(curr_state)s_%(next_state)s.send();"
     key = transition['value'].replace("0x", "'h")
     if transition['mask'] is not None:
         mask = transition['mask'].replace("0x", "'h")
     else:
         mask = None
     next_state = transition['next_state']
     next_name = "%s" % (next_state) if next_state != None else self.initial_state
     stmt = []
     stmt.append(ast.Template("dbprint(3, $format(\"transit to %s\"));", next_name))
     stmt.append(ast.Template(TMP1 % {'curr_state': name, 'next_state': next_name}))
     return key, mask, stmt
 def buildDefaultRuleStmt(self, tblName):
     TMP1 = "default_req_ff.deq;"
     TMP2 = "let _req = default_req_ff.first;"
     TMP3 = "let meta = _req.meta;"
     TMP4 = "let pkt = _req.pkt;"
     TMP5 = "MetadataRequest req = MetadataRequest {pkt: pkt, meta: meta};"
     TMP6 = "%(name)s_req_ff.enq(req);"
     stmt = []
     stmt.append(ast.Template(TMP1))
     stmt.append(ast.Template(TMP2))
     stmt.append(ast.Template(TMP3))
     stmt.append(ast.Template(TMP4))
     if tblName in self.tables:
         stmt.append(ast.Template(TMP5))
         stmt.append(ast.Template(TMP6, {"name": tblName}))
     elif tblName in self.conditionals:
         _stmt = []
         self.buildConditionalStmt(tblName, _stmt)
         stmt += _stmt
     else:
         stmt.append(
             ast.Template(
                 "MetadataRequest req = MetadataRequest {pkt: pkt, meta: meta};"
             ))
         stmt.append(ast.Template("next_req_ff.enq(req);"))
     return stmt
Ejemplo n.º 23
0
 def buildCPU (self):
     tmpl = []
     reglist = []
     for p in self.primitives:
         for param in p.parameters:
             if (param['type'] == 'field'):
                 reglist.append("cons(" + "$".join(param['value']))
     #note: use cons to form a list of registers to ALU
     if len(reglist) != 0: 
         regs = ",".join(reglist) + ", nil" + ")" * len(reglist)
         tmpl.append(ast.Template("CPU cpu <- mkCPU(%s);" % regs))
         tmpl.append(ast.Template("IMem imem <- mkIMem(\"%s.hex\");" % self.name))
         tmpl.append(ast.Template("mkConnection(cpu.imem_client, imem.cpu_server);\n"))
     return tmpl
 def build_states(self):
     stmt = []
     stmt.append(ast.Template("\n"))
     stmt.append(ast.Template("`ifdef PARSER_STATE\n"))
     for transition in self.state_transitions:
         stmt.append(ast.Template("PulseWire w_%(name)s <- mkPulseWireOR();\n", {'name': transition}))
     for _, s in self.states.items():
         for op in s.parse_ops:
             if (op['op'] == 'extract'):
                 for param in op['parameters']:
                     if (param['type'] == 'regular'):
                         htype = GetHeaderType(param['value'])
                         stmt.append(ast.Template("FIFOF#(Maybe#(%(Type)s)) %(type)s_out_ff <- mkDFIFOF(tagged Invalid);\n", {'type': param['value'], 'Type': CamelCase(htype)}))
     stmt.append(ast.Template("`endif"))
     return stmt
Ejemplo n.º 25
0
 def buildTXRX(self, pname):
     TMP1 = "RX #(%(type)sRequest) rx_%(name)s <- mkRX;"
     TMP3 = "TX #(%(tblname)sResponse) tx_%(name)s <- mkTX;"
     TMP2 = "let rx_info_%(name)s = rx_%(name)s.u;"
     TMP4 = "let tx_info_%(name)s = tx_%(name)s.u;"
     stmt = []
     pdict = {
         'type': CamelCase(pname),
         'name': pname,
         'tblname': CamelCase(self.name)
     }
     stmt.append(ast.Template(TMP1, pdict))
     stmt.append(ast.Template(TMP2, pdict))
     stmt.append(ast.Template(TMP3, pdict))
     stmt.append(ast.Template(TMP4, pdict))
     return stmt
def build_funct_dbg3():
    stmt = []
    stmt.append(ast.Template("$display(\"(%%0d) \", $time, msg);"))
    ifstmt = apply_if_verbosity(3, stmt)
    ablock = apply_action_block(ifstmt)
    funct = ast.Function("dbg3", 'Action', 'Fmt msg', ablock)
    return funct
 def buildBasicBlocks(self):
     TMP1 = "%(type)s %(name)s <- mk%(type)s();"
     stmt = []
     stmt.append(ast.Template("// Basic Blocks"))
     basic_block_set = dict()  # to ensure unique name
     for b in self.basic_blocks:
         btype = CamelCase(b.name)
         bname = b.name
         if bname in basic_block_set:
             basic_block_set[bname] += 1
             name = b.name + "_%s" % (basic_block_set[b.name])
         else:
             basic_block_set[bname] = 0
             name = b.name + "_0"
         stmt.append(ast.Template(TMP1, {"type": btype, "name": name}))
     return stmt
Ejemplo n.º 28
0
    def buildModuleStmt(self):
        TMP1 = "Vector#(%(num)s, FIFOF#(BBRequest)) bbReqFifo <- replicateM(mkFIFOF);"
        TMP2 = "Vector#(%(num)s, FIFOF#(BBResponse)) bbRspFifo <- replicateM(mkFIFOF);"
        TMP3 = "MatchTable#(%(tid)s, %(sz)s, SizeOf#(%(reqT)s), SizeOf#(%(rspT)s)) matchTable <- mkMatchTable(\"%(name)s\");"
        TMP4 = "interface next_control_state_%(id)s = toClient(bbReqFifo[%(id)s], bbRspFifo[%(id)s]);"
        TMP5 = "interface prev_control_state_%(id)s = toServer(rx_%(name)s.e, tx_%(name)s.e);"
        TMP6 = "Vector#(2, FIFOF#(MetadataT)) metadata_ff <- replicateM(mkFIFOF);"
        TMP8 = "FIFOF#(MetadataT) metadata_ff <- mkFIFOF;"
        TMP7 = "FIFOF#(PacketInstance) packet_ff <- mkFIFOF;"

        stmt = []
        stmt += build_funct_verbosity()
        stmt += self.buildTXRX("metadata")

        num = len(self.actions)
        stmt.append(ast.Template(TMP1, {"num": num}))
        stmt.append(ast.Template(TMP2, {"num": num}))
        stmt.append(ast.Template(TMP7))

        if len(self.key) != 0:
            reqT = "%sReqT" % (CamelCase(self.name))
            rspT = "%sRspT" % (CamelCase(self.name))
            # size must be 256 or multiple of 256
            size = int(256 * math.ceil(float(self.depth) / 256))
            tid = self.tid
            pdict = {
                "sz": size,
                "reqT": reqT,
                "rspT": rspT,
                "tid": tid,
                "name": self.name + '.dat'
            }
            stmt.append(ast.Template(TMP3, pdict))

        pdict = {"sz": num, "szminus1": num - 1, "fifo": "bbRspFifo"}
        stmt.append(ast.Template(IRQ_TEMPLATE, pdict))

        if len(self.key) != 0:
            stmt.append(ast.Template(TMP6))
            stmt.append(self.buildRuleMatchRequest())
            stmt.append(self.buildRuleExecuteAction())
            stmt.append(self.buildRuleMatchResponse())
        else:
            stmt.append(ast.Template(TMP8))
            stmt.append(self.buildRuleActionRequest())
            stmt.append(self.buildRuleActionResponse())

        stmt.append(ast.Template(TMP5 % {"name": "metadata", "id": 0}))
        for idx, _ in enumerate(self.actions):
            stmt.append(ast.Template(TMP4 % {"id": idx}))
        stmt += self.build_intf_decl_verbosity()
        return stmt
 def build_rules(self):
     self.decide_default_state()
     self.populate_state_transition()
     stmt = []
     stmt.append(ast.Template("\n"))
     stmt.append(ast.Template("`ifdef PARSER_RULES\n"))
     stmt += self.build_mutually_exclusive_attribute()
     stmt += self.build_rule_parse_done()
     for idx, s in enumerate(self.states.values()):
         if s.state_type == ParseState.REGULAR:
             stmt += self.build_rule_state_load(s)
             stmt += self.build_rule_state_extract(s)
             stmt += self.build_rule_state_transitions(0, s)
         else:
             stmt += self.build_rule_state_transitions(1, s)
     stmt.append(ast.Template("`endif // PARSER_RULES\n"))
     return stmt
    def buildConditionalStmt(self, tblName, stmt, metadata=set()):
        TMP1 = "MetadataRequest req = MetadataRequest {pkt: pkt, meta: meta};"
        TMP2 = "%(name)s_req_ff.enq(req);"
        toCurrPacketFifo = False

        def search_conditional(name):
            for key, cond in self.conditionals.items():
                print key, cond
                if key == name:
                    return cond
            return None

        if tblName is None:
            stmt.append(
                ast.Template(
                    "MetadataRequest req = MetadataRequest {pkt: pkt, meta: meta};"
                ))
            stmt.append(ast.Template("next_req_ff.enq(req);"))

        if tblName in self.tables:
            stmt.append(ast.Template(TMP1))
            stmt.append(ast.Template(TMP2, {"name": tblName}))

        if tblName in self.conditionals:
            cond = search_conditional(tblName)
            expr = cond['expression'].replace("0x", "'h")
            true_next = cond['true_next']
            false_next = cond['false_next']
            _meta = cond['metadata']
            for m in _meta:
                if type(m) is list:
                    metadata.add(tuple(m))
                else:
                    metadata.add(m)
            if true_next in self.tables:
                _stmt = []
                _stmt.append(ast.Template(TMP1,
                                          {"name": CamelCase(true_next)}))
                _stmt.append(ast.Template(TMP2, {"name": true_next}))
                stmt.append(ast.If(expr, _stmt))
            if true_next in self.conditionals:
                _stmt = []
                self.buildConditionalStmt(true_next, _stmt, metadata)
                stmt.append(ast.If(expr, _stmt))

            if false_next in self.tables:
                _stmt = []
                _stmt.append(
                    ast.Template(TMP1, {"name": CamelCase(false_next)}))
                _stmt.append(ast.Template(TMP2, {"name": false_next}))
                stmt.append(ast.Else(_stmt))
            if false_next in self.conditionals:
                _stmt = []
                self.buildConditionalStmt(false_next, _stmt, metadata)
                stmt.append(ast.Else(_stmt))