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]
Beispiel #2
0
 def rule_state_next(self, state, width):
     tmpl = []
     tmpl.append("deparse_state_ff.enq(StateDeparse%s);" % CamelCase(state))
     tmpl.append("fetch_next_header(%d);" % width)
     rname = "rl_deparse_%s_next" % (state.translate(None, "[]"))
     rcond = "w_deparse_%s" % (state.translate(None, "[]"))
     stmt = apply_pdict(tmpl, {})
     rule = ast.Rule(rname, rcond, stmt)
     return rule
Beispiel #3
0
 def rule_state_send(self, state, width):
     tmpl = []
     tmpl.append("succeed_and_next(%d);" % width)
     tmpl.append("deparse_state_ff.deq;")
     rname = "rl_deparse_%s_send" % (state.translate(None, "[]"))
     rcond = "(deparse_state_ff.first == StateDeparse%s) && (rg_buffered[0] >= %d)" % (
         CamelCase(state), width)
     stmt = apply_pdict(tmpl, {})
     rule = ast.Rule(rname, rcond, stmt)
     return rule
Beispiel #4
0
 def rule_state_load(self, state, width):
     tmpl = []
     tmpl.append(
         "rg_tmp[0] <= zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];"
     )
     tmpl.append(
         "UInt#(NumBytes) n_bytes_used = countOnes(mask_this_cycle);")
     tmpl.append("UInt#(NumBits) n_bits_used = cExtend(n_bytes_used) << 3;")
     tmpl.append("move_buffered_amt(cExtend(n_bits_used));")
     rname = "rl_deparse_%s_load" % (state.translate(None, "[]"))
     rcond = "(deparse_state_ff.first == StateDeparse%s) && (rg_buffered[0] < %d)" % (
         CamelCase(state), width)
     stmt = apply_pdict(tmpl, {})
     rule = ast.Rule(rname, rcond, stmt)
     return rule
 def build_rule_state_load(self, state):
     tmpl = []
     tmpl.append("data_ff.deq;")
     tmpl.append("let data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];")
     tmpl.append("rg_tmp[0] <= zeroExtend(data);")
     tmpl.append("move_shift_amt(%d);" % (config.DP_WIDTH))
     pdict = {}
     pdict['name'] = state.name
     pdict['CurrState'] = 'State%s' % (CamelCase(state.name))
     pdict['len'] = state.len
     stmt = apply_pdict(tmpl, pdict)
     expr = "isValid(data_ff.first)"
     ifstmt = []
     ifstmt.append(ast.Template("report_parse_action(parse_state_ff.first, rg_buffered[0], data_this_cycle, rg_tmp[0]);"))
     ifstmt.append(ast.If(expr, stmt))
     rcond = '(parse_state_ff.first == %(CurrState)s) && (rg_buffered[0] < %(len)s)' % pdict
     attr = ['fire_when_enabled']
     rule = ast.Rule('rl_%(name)s_load' % pdict, rcond, ifstmt, attr)
     return [rule]
        def build_rule_state_transition(cregIdx, state, next_state):
            # skip duplicated transition rule
            transition = "%s_%s" % (state.name, next_state.name)
            if transition in self.state_transitions_generated:
                return
            self.state_transitions_generated.add(transition)

            # forward transition
            tmpl_forward_flow = []
            tmpl_forward_flow.append("parse_state_ff.enq(%(NextState)s);")
            tmpl_forward_flow.append("dbprint(3, $format(\"%%s -> %%s\", \"%(name)s\", \"%(next_state)s\"));")
            tmpl_forward_flow.append("fetch_next_header%(cregIdx)s(%(length)s);")

            # back to start
            tmpl_to_start = []
            tmpl_to_start.append("parse_done[0] <= True;")
            tmpl_to_start.append("w_parse_done.send();")
            tmpl_to_start.append("dbprint(3, $format(\"%%s -> %%s\", \"%(name)s\", \"%(next_state)s\"));")
            tmpl_to_start.append("fetch_next_header%(cregIdx)s(0);")

            # transition with lookahead
            tmpl_lookahead = []
            tmpl_lookahead.append("Vector#(512, Bit#(1)) buffer = unpack(rg_tmp[1]);")
            tmpl_lookahead.append("Bit#(%(lookahead)s) lookahead = pack(takeAt(0, buffer));")
            tmpl_lookahead.append("dbprint(3, $format(\"look ahead %%h, %%h\", lookahead, rg_tmp[1]));")
            tmpl_lookahead.append("compute_next_state_%(next_state)s(%(field)s);")
            tmpl_lookahead.append("dbprint(3, $format(\"counter\", %(field)s ));")
            tmpl_lookahead.append("dbprint(3, $format(\"%%s -> %%s\", \"%(name)s\", \"%(next_state)s\"));")
            tmpl_lookahead.append('fetch_next_header%(cregIdx)s(0);')

            pdict = {}
            pdict['name'] = state.name
            pdict['CurrState'] = "State%s" % (CamelCase(state.name))
            pdict['next_state'] = next_state.name
            pdict['NextState'] = "State%s" % (CamelCase(next_state.name))
            pdict['length'] = GetHeaderWidthInState(next_state.name)
            pdict['cregIdx'] = cregIdx
            pdict['lookahead'] = 8 #FIXME
            keys = []
            for k in next_state.transition_keys:
                if k['type'] == 'lookahead':
                    keys.append("lookahead")
                else:
                    field = k['value'][0]
                    if field[0].isupper():
                        field = field[0].lower() + field
                    keys.append("%s$%s[1]" % (field, k['value'][1]))
            pdict['field'] = ", ".join(keys)

            #print state.name, state.state_type
            if next_state.id == 0:
                stmt = apply_pdict(tmpl_to_start, pdict)
            elif state.id > next_state.id and state.state_type == ParseState.EMPTY:
                stmt = apply_pdict(tmpl_lookahead, pdict)
            elif next_state.state_type == ParseState.EMPTY:
                stmt = apply_pdict(tmpl_lookahead, pdict)
            else:
                stmt = apply_pdict(tmpl_forward_flow, pdict)
            rname = 'rl_%(name)s_%(next_state)s' % pdict
            rcond = "(w_%(name)s_%(next_state)s)" % pdict
            rule = ast.Rule(rname, rcond, stmt)
            return rule