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]
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
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
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