def gen_hdl_wrseldec(root, module, isigs, area, pfx, wrseldec): proc = HDLComb() proc.name = '{}WrSelDec'.format(pfx) bus_addr = root.h_bus['adri'] proc.sensitivity.append(bus_addr) for r in wrseldec: for i in reversed(range(r.c_nwords)): proc.stmts.append(HDLAssign(r.h_wrsel[i], bit_0)) sw = HDLSwitch( HDLSlice(bus_addr, root.c_addr_word_bits, ilog2(area.c_size) - root.c_addr_word_bits)) if isinstance(area, (tree.Block, tree.Submap)): stmt = gen_hdl_area_decode(root, module, area, bus_addr) stmt.then_stmts.append(sw) stmt.else_stmts.append(HDLAssign(isigs.Loc_CRegWrOK, bit_0)) proc.stmts.append(stmt) else: proc.stmts.append(sw) for reg in wrseldec: if reg.h_has_mux: proc.sensitivity.append(reg.h_regok) regok = reg.h_regok else: regok = bit_1 for i in reversed(range(reg.c_nwords)): ch = HDLChoiceExpr(reg.h_gena_regaddr[i]) ch.stmts.append(HDLAssign(reg.h_wrsel[i], bit_1)) ch.stmts.append(HDLAssign(isigs.Loc_CRegWrOK, regok)) sw.choices.append(ch) ch = HDLChoiceDefault() ch.stmts.append(HDLAssign(isigs.Loc_CRegWrOK, bit_0)) sw.choices.append(ch) module.stmts.append(proc) module.stmts.append(HDLComment(None))
def gen_hdl_regrdmux(root, module, isigs, area, pfx, rd_reg): proc = HDLComb() proc.name = '{}RegRdMux'.format(pfx) bus_addr = root.h_bus['adro'] proc.sensitivity.append(bus_addr) proc.sensitivity.append(isigs.CRegRdData) proc.sensitivity.append(isigs.CRegRdOK) for reg in rd_reg: if reg.h_rdsel: for i in reversed(range(reg.c_nwords)): proc.stmts.append(HDLAssign(reg.h_rdsel[i], bit_0)) sw = HDLSwitch( HDLSlice(bus_addr, root.c_addr_word_bits, ilog2(area.c_size) - root.c_addr_word_bits)) if isinstance(area, (tree.Block, tree.Submap)): stmt = gen_hdl_area_decode(root, module, area, bus_addr) stmt.then_stmts.append(sw) stmt.else_stmts.append(HDLAssign(isigs.Loc_RegRdData, isigs.CRegRdData)) stmt.else_stmts.append(HDLAssign(isigs.Loc_RegRdOK, isigs.CRegRdOK)) proc.stmts.append(stmt) else: proc.stmts.append(sw) regok_sensitivity = [] for reg in rd_reg: loc = reg.h_loc_SRFF or reg.h_loc proc.sensitivity.append(loc) if reg.h_has_mux: regok_sensitivity.append(reg.h_regok) regok = reg.h_regok else: regok = bit_1 for i in reversed(range(reg.c_nwords)): ch = HDLChoiceExpr(reg.h_gena_regaddr[i]) val = loc vwidth = reg.c_rwidth // reg.c_nwords val = HDLSlice(val, i * root.c_word_bits, vwidth) if vwidth < root.c_word_bits: val = HDLZext(val, vwidth) ch.stmts.append(HDLAssign(isigs.Loc_RegRdData, val)) ch.stmts.append(HDLAssign(isigs.Loc_RegRdOK, regok)) if reg.h_rdsel: ch.stmts.append(HDLAssign(reg.h_rdsel[i], bit_1)) sw.choices.append(ch) ch = HDLChoiceDefault() ch.stmts.append(HDLAssign(isigs.Loc_RegRdData, isigs.CRegRdData)) ch.stmts.append(HDLAssign(isigs.Loc_RegRdOK, isigs.CRegRdOK)) proc.sensitivity.extend(regok_sensitivity) sw.choices.append(ch) module.stmts.append(proc) module.stmts.append(HDLComment(None))
def gen_hdl_cregrdmux(root, module, isigs, area, pfx, wrseldec): proc = HDLComb() proc.name = '{}CRegRdMux'.format(pfx) bus_addr = root.h_bus['adro'] proc.sensitivity.append(bus_addr) sw = HDLSwitch( HDLSlice(bus_addr, root.c_addr_word_bits, ilog2(area.c_size) - root.c_addr_word_bits)) if isinstance(area, (tree.Block, tree.Submap)): stmt = gen_hdl_area_decode(root, module, area, bus_addr) stmt.then_stmts.append(sw) stmt.else_stmts.append( HDLAssign(isigs.Loc_CRegRdData, HDLReplicate(bit_0, None))) stmt.else_stmts.append(HDLAssign(isigs.Loc_CRegRdOK, bit_0)) proc.stmts.append(stmt) else: proc.stmts.append(sw) regok_sensitivity = [] for reg in wrseldec: if reg.h_loc: # NOTE: not needed for WO registers! proc.sensitivity.append(reg.h_loc) for i in reversed(range(reg.c_nwords)): ch = HDLChoiceExpr(reg.h_gena_regaddr[i]) if reg.access == 'wo': val = HDLReplicate(bit_0, None) ok = bit_0 else: val = reg.h_loc regw = reg.c_rwidth // reg.c_nwords val = HDLSlice(val, i * regw, regw) if regw < root.c_word_bits: val = HDLZext(val, root.c_word_bits) if reg.h_has_mux: if i == 0: regok_sensitivity.append(reg.h_regok) ok = reg.h_regok else: ok = bit_1 ch.stmts.append(HDLAssign(isigs.Loc_CRegRdData, val)) ch.stmts.append(HDLAssign(isigs.Loc_CRegRdOK, ok)) sw.choices.append(ch) ch = HDLChoiceDefault() ch.stmts.append(HDLAssign(isigs.Loc_CRegRdData, HDLReplicate(bit_0, None))) ch.stmts.append(HDLAssign(isigs.Loc_CRegRdOK, bit_0)) proc.sensitivity.extend(regok_sensitivity) sw.choices.append(ch) module.stmts.append(proc) module.stmts.append(HDLComment(None))
def add_block_decoder(root, stmts, addr, children, hi, func): if False: print("add_block_decoder: hi={}".format(hi)) for i in children: print("{}: {:08x}".format(i.name, i.c_address)) print("----") if len(children) == 1: el = children[0] if isinstance(el, tree.Reg): add_reg_decoder(root, stmts, addr, func, children, hi) else: func(stmts, el, 0) return maxsz = max([e.c_size for e in children]) maxszl2 = ilog2(maxsz) assert maxsz == 1 << maxszl2 mask = (1 << hi) - maxsz assert maxszl2 < hi # Note: addr has a word granularity. sw = HDLSwitch( HDLSlice(addr, maxszl2 - root.c_addr_word_bits, hi - maxszl2)) stmts.append(sw) while len(children) > 0: first = children[0] children = children[1:] l = [first] base = first.c_address & mask if False: print("hi={} szl2={} first: {:08x}, base: {:08x}, mask: {:08x}". format(hi, maxszl2, first.c_address, base, mask)) while len(children) > 0: el = children[0] if (el.c_address & mask) != base: break if False: print(" {} c_addr={:08x}".format(el.name, el.c_address)) l.append(el) children = children[1:] ch = HDLChoiceExpr(HDLConst(base >> maxszl2, hi - maxszl2)) sw.choices.append(ch) add_block_decoder(root, ch.stmts, addr, l, maxszl2, func) sw.choices.append(HDLChoiceDefault())
def gen_hdl_reg_rdmux(reg, pfx, root, module, isigs): proc = HDLComb() proc.name = 'Reg_{}{}_RdMux'.format(pfx, reg.name) sel_field = reg.h_mux.sel proc.sensitivity.append(sel_field._parent.h_loc) sel_val, sel_width = gen_hdl_field(sel_field._parent.h_loc, sel_field) sw = HDLSwitch(sel_val) proc.stmts.append(sw) m = 0 for suff, val in reg.h_mux.codelist: ch = HDLChoiceExpr(HDLBinConst(val, sel_width)) ch.stmts.append(HDLAssign(reg.h_loc, reg.h_loc_mux[m])) proc.sensitivity.append(reg.h_loc_mux[m]) ch.stmts.append(HDLAssign(reg.h_regok, bit_1)) sw.choices.append(ch) m += 1 ch = HDLChoiceDefault() ch.stmts.append( HDLAssign(reg.h_loc, HDLReplicate(bit_0, sel_field.c_rwidth))) ch.stmts.append(HDLAssign(reg.h_regok, bit_0)) sw.choices.append(ch) module.stmts.append(proc) module.stmts.append(HDLComment(None))
def add_reg_decoder(root, stmts, addr, func, els, blk_bits): """Call :param func: for each element of :param n:. :param func: can also be called with None when a decoder is generated and could handle an address that has no corresponding children.""" # Decode directly all the children width = blk_bits - root.c_addr_word_bits if width == 0: # There is only one register, handle it directly assert len(els) <= 1 for el in els: func(stmts, el, 0) else: sw = HDLSwitch(HDLSlice(addr, 0, width)) stmts.append(sw) for el in els: suboff = 0 while suboff < el.c_size: cstmts = [] if True: # Big endian foff = el.c_size - root.c_word_size - suboff else: # Little endian foff = suboff func(cstmts, el, foff * tree.BYTE_SIZE) if cstmts: # Only create the choice is there are statements. addr = el.c_address + suboff ch = HDLChoiceExpr( HDLConst(addr >> root.c_addr_word_bits, width)) sw.choices.append(ch) ch.stmts = cstmts suboff += root.c_word_size ch = HDLChoiceDefault() sw.choices.append(ch) func(ch.stmts, None, 0)
def gen_hdl_reg_wrseldec(reg, pfx, root, module, isigs): proc = HDLComb() proc.name = 'Reg_{}{}_WrSelDec'.format(pfx, reg.name) sel_field = reg.h_mux.sel proc.sensitivity.append(sel_field._parent.h_loc) sel_val, sel_width = gen_hdl_field(sel_field._parent.h_loc, sel_field) sw = HDLSwitch(sel_val) for i in reversed(range(reg.c_nwords)): proc.sensitivity.append(reg.h_wrsel[i]) for i in reversed(range(reg.c_nwords)): for m in range(len(reg.h_mux.codelist)): proc.stmts.append(HDLAssign(reg.h_wrsel_mux[i][m], bit_0)) m = 0 for _, val in reg.h_mux.codelist: ch = HDLChoiceExpr(HDLBinConst(val, sel_width)) for i in reversed(range(reg.c_nwords)): ch.stmts.append(HDLAssign(reg.h_wrsel_mux[i][m], reg.h_wrsel[i])) m += 1 sw.choices.append(ch) ch = HDLChoiceDefault() sw.choices.append(ch) proc.stmts.append(sw) module.stmts.append(proc) module.stmts.append(HDLComment(None))