def gen_submap_addr(n, root, decls, name, pfx): decls.append(HDLComment('Submap Addresses : {}'.format(name), nl=False)) # word_width = ilog2(root.c_word_size) for e in n.children: if isinstance(e, tree.Submap): block_width = ilog2(e.c_size) addr_width = ilog2(n.c_size) - block_width addr = e.c_address >> block_width cst = gen_addr_cst(decls, addr, 'C_Submap_{}_{}'.format(pfx, e.name), addr_width, block_width, 1) e.h_gena_area = cst
def gen_memory_data(n, root, decls, name, pfx): decls.append(HDLComment('Memory Data : {}'.format(name), nl=False)) word_width = ilog2(root.c_word_size) addr_width = ilog2(n.c_size) - word_width for e in n.children: if isinstance(e, tree.Array): addr = e.c_address >> word_width e.h_gena_sta = gen_addr_cst(decls, addr, 'C_Mem_{}_{}_Sta'.format(pfx, e.name), addr_width, word_width, 1) addr = (e.c_address + e.c_size - 1) >> word_width e.h_gena_end = gen_addr_cst(decls, addr, 'C_Mem_{}_{}_End'.format(pfx, e.name), addr_width, word_width, 1)
def gen_areas_address(areas, root, decls): # decls.append(HDLComment('Memory Areas.')) cpfx = 'C_Area_{}'.format(root.name) addr_width = ilog2(root.c_size) for e in areas: area_width = ilog2(e.c_size) sz = addr_width - area_width cst = HDLConstant(cpfx + '_' + e.name, sz, lo_idx=area_width, value=HDLBinConst(e.c_address >> area_width, sz)) e.h_gena_area = cst #cst.eol_comment = '{} : Word Address : X"{:X}"; Byte Address : 0x{:x}'.format( # get_note(e), e.c_address // root.c_word_size, e.c_address) decls.append(cst)
def gen_hdl_header(root, isigs=None): module = HDLModule() module.name = root.name # Number of bits in the address used by a word root.c_addr_word_bits = ilog2(root.c_word_size) # Number of bits in a word root.c_word_bits = root.c_word_size * tree.BYTE_SIZE # Create the bus if root.bus == 'wb-32-be': expand_wishbone(root, module, isigs) elif root.bus.startswith('cern-be-vme-'): names = root.bus[12:].split('-') err = names[0] == 'err' if err: del names[0] split = names[0] == 'split' if split: del names[0] assert len(names) == 1 expand_cern_be_vme(root, module, isigs, err, split) else: raise HdlError("Unhandled bus '{}'".format(root.bus)) return module
def gen_hdl_ext_bus_asgn(n, acc, root, module): adr_sz = ilog2(n.c_size) - root.c_addr_word_bits adr_lo = root.c_addr_word_bits if not root.h_bussplit: module.stmts.append( HDLAssign(n.h_addr, HDLSlice(root.h_bus['adr'], adr_lo, adr_sz))) module.stmts.append(HDLAssign(n.h_sel, n.h_sel_sig)) if acc in READ_ACCESS: if root.h_bussplit: module.stmts.append( HDLAssign(n.h_rdaddr, HDLSlice(root.h_bus['adro'], adr_lo, adr_sz))) module.stmts.append(HDLAssign(n.h_rdsel, n.h_rdsel_sig)) module.stmts.append( HDLAssign(n.h_rdmem, HDLAnd(n.h_rdsel_sig, root.h_bus['rd']))) if acc in WRITE_ACCESS: if root.h_bussplit: module.stmts.append( HDLAssign(n.h_wraddr, HDLSlice(root.h_bus['adri'], adr_lo, adr_sz))) module.stmts.append(HDLAssign(n.h_wrsel, n.h_wrsel_sig)) module.stmts.append( HDLAssign(n.h_wrmem, HDLAnd(n.h_wrsel_sig, root.h_bus['wr']))) module.stmts.append(HDLAssign(n.h_wrdata, root.h_bus['dati'])) module.stmts.append(HDLComment(None))
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_reg_addr(n, root, decls, name, pfx): decls.append(HDLComment('Register Addresses : {}'.format(name), nl=False)) word_width = ilog2(root.c_word_size) addr_width = ilog2(n.c_size) - word_width for reg in n.children: if isinstance(reg, tree.Reg): addr = reg.c_address // root.c_word_size # FIXME: Gena looks to use 1 instead of word_width num = reg.c_nwords reg.h_gena_regaddr = [] for i in range(num): cst = gen_addr_cst( decls, addr + i, 'C_Reg_{}_{}{}'.format(pfx, reg.name, subsuffix(num - i - 1, num)), addr_width, word_width, 1) reg.h_gena_regaddr.insert(0, cst)
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_memrdmux(root, module, isigs, area, pfx, mems): proc = HDLComb() proc.name = pfx + 'MemRdMux' bus_addr = root.h_bus['adro'] proc.sensitivity.extend([bus_addr, isigs.RegRdData, isigs.RegRdDone]) if root.c_buserr: proc.sensitivity.append(isigs.RegRdError) adr_sz = ilog2(area.c_size) - root.c_addr_word_bits adr_lo = root.c_addr_word_bits first = [] last = first for m in mems: data = m.children[0] if data.access in READ_ACCESS: proc.sensitivity.extend([m.h_rddata, m.h_rddone]) if root.c_buserr: proc.sensitivity.append(m.h_rderror) proc.stmts.append(HDLAssign(m.h_rdsel_sig, bit_0)) cond = HDLAnd(HDLGe(HDLSlice(bus_addr, adr_lo, adr_sz), m.h_gena_sta), HDLLe(HDLSlice(bus_addr, adr_lo, adr_sz), m.h_gena_end)) stmt = HDLIfElse(cond) if data.access in READ_ACCESS: stmt.then_stmts.append(HDLAssign(m.h_rdsel_sig, bit_1)) stmt.then_stmts.append(HDLAssign(isigs.Loc_MemRdData, m.h_rddata)) stmt.then_stmts.append(HDLAssign(isigs.Loc_MemRdDone, m.h_rddone)) if root.c_buserr: stmt.then_stmts.append( HDLAssign(isigs.Loc_MemRdError, m.h_rderror)) else: stmt.then_stmts.append( HDLAssign(isigs.Loc_MemRdData, HDLReplicate(bit_0, data.width))) stmt.then_stmts.append(HDLAssign(isigs.Loc_MemRdDone, bit_0)) if root.c_buserr: stmt.then_stmts.append( HDLAssign(isigs.Loc_MemRdError, root.h_bus['rd'])) last.append(stmt) last = stmt.else_stmts gen_hdl_reg2locmem_rd(root, module, isigs, last) if isinstance(area, (tree.Block, tree.Submap)): stmt = gen_hdl_area_decode(root, module, area, bus_addr) stmt.then_stmts.extend(first) gen_hdl_reg2locmem_rd(root, module, isigs, stmt.else_stmts) proc.stmts.append(stmt) else: proc.stmts.extend(first) module.stmts.append(proc) module.stmts.append(HDLComment(None))
def gen_hdl_memwrmux(root, module, isigs, area, pfx, mems): proc = HDLComb() proc.name = pfx + 'MemWrMux' bus_addr = root.h_bus['adri'] proc.sensitivity.extend([bus_addr, isigs.RegWrDone]) if root.c_buserr: proc.sensitivity.append(isigs.RegWrError) adr_sz = ilog2(area.c_size) - root.c_addr_word_bits adr_lo = root.c_addr_word_bits first = [] last = first for m in mems: data = m.children[0] set_wrsel = data.access == 'wo' or (data.access == 'rw' and root.c_bussplit) if set_wrsel: proc.stmts.append(HDLAssign(m.h_wrsel_sig, bit_0)) cond = HDLAnd(HDLGe(HDLSlice(bus_addr, adr_lo, adr_sz), m.h_gena_sta), HDLLe(HDLSlice(bus_addr, adr_lo, adr_sz), m.h_gena_end)) stmt = HDLIfElse(cond) if set_wrsel: stmt.then_stmts.append(HDLAssign(m.h_wrsel_sig, bit_1)) if data.access in WRITE_ACCESS: proc.sensitivity.append(m.h_wrdone) done = m.h_wrdone else: done = bit_0 stmt.then_stmts.append(HDLAssign(isigs.Loc_MemWrDone, done)) if root.c_buserr: if data.access in WRITE_ACCESS: proc.sensitivity.append(m.h_wrerror) err = m.h_wrerror else: err = root.h_bus['wr'] stmt.then_stmts.append(HDLAssign(isigs.Loc_MemWrError, err)) last.append(stmt) last = stmt.else_stmts gen_hdl_reg2locmem_wr(root, module, isigs, last) if isinstance(area, (tree.Block, tree.Submap)): stmt = gen_hdl_area_decode(root, module, area, bus_addr) stmt.then_stmts.extend(first) gen_hdl_reg2locmem_wr(root, module, isigs, stmt.else_stmts) proc.stmts.append(stmt) else: proc.stmts.extend(first) 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_ports_array_reg(root, module, reg): # Compute width # Create ports reg.h_addr_width = ilog2(reg._parent.repeat) reg.h_addr = add_module_port(root, module, reg.name + '_adr', reg.h_addr_width, 'IN') reg.h_addr.comment = "RAM port for {}".format(reg.name) if reg.access == 'ro': reg.h_we = add_module_port(root, module, reg.name + '_we', None, 'IN') reg.h_dat = add_module_port(root, module, reg.name + '_dat', reg.c_rwidth, 'IN') else: reg.h_rd = add_module_port(root, module, reg.name + '_rd', None, 'IN') reg.h_dat = add_module_port(root, module, reg.name + '_dat', reg.c_rwidth, 'OUT')
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_area_decode(root, module, area, bus_addr): parent_width = ilog2(area._parent.c_size) a_width = ilog2(area.c_size) cond = HDLEq(HDLSlice(bus_addr, a_width, parent_width - a_width), area.h_gena_area) return HDLIfElse(cond)
def gen_hdl_ext_bus(n, bwidth, acc, pfx, root, module): # Generate ports dwidth = min(bwidth, root.c_word_bits) adr_sz = ilog2(n.c_size) - root.c_addr_word_bits adr_lo = root.c_addr_word_bits if not root.h_bussplit: n.h_sel = HDLPort('{}{}_Sel'.format(pfx, n.name), dir='OUT') n.h_addr = HDLPort('{}{}_Addr'.format(pfx, n.name), size=adr_sz, lo_idx=adr_lo, dir='OUT') module.ports.extend([n.h_sel, n.h_addr]) # Sel_ signal n.h_sel_sig = HDLSignal('Sel_{}{}'.format(pfx, n.name)) module.decls.append(n.h_sel_sig) n.h_rdsel_sig, n.h_wrsel_sig = n.h_sel_sig, n.h_sel_sig if acc in READ_ACCESS: if root.h_bussplit: n.h_rdsel = HDLPort('{}{}_RdSel'.format(pfx, n.name), dir='OUT') n.h_rdaddr = HDLPort('{}{}_RdAddr'.format(pfx, n.name), size=adr_sz, lo_idx=adr_lo, dir='OUT') module.ports.extend([n.h_rdsel, n.h_rdaddr]) n.h_rdsel_sig = HDLSignal('RdSel_{}{}'.format(pfx, n.name)) module.decls.append(n.h_rdsel_sig) else: n.h_rdsel = n.h_sel n.h_rdaddr = n.h_addr n.h_rdsel_sig = n.h_sel_sig n.h_rddata = HDLPort('{}{}_RdData'.format(pfx, n.name), size=dwidth) module.ports.append(n.h_rddata) if acc in WRITE_ACCESS: if root.h_bussplit: n.h_wrsel = HDLPort('{}{}_WrSel'.format(pfx, n.name), dir='OUT') n.h_wraddr = HDLPort('{}{}_WrAddr'.format(pfx, n.name), size=adr_sz, lo_idx=adr_lo, dir='OUT') module.ports.extend([n.h_wrsel, n.h_wraddr]) n.h_wrsel_sig = HDLSignal('WrSel_{}{}'.format(pfx, n.name)) module.decls.append(n.h_wrsel_sig) else: n.h_wrsel = n.h_sel n.h_wraddr = n.h_addr n.h_wrsel_sig = n.h_sel_sig n.h_wrdata = HDLPort('{}{}_WrData'.format(pfx, n.name), size=dwidth, dir='OUT') module.ports.append(n.h_wrdata) if acc in READ_ACCESS: n.h_rdmem = HDLPort('{}{}_RdMem'.format(pfx, n.name), dir='OUT') module.ports.append(n.h_rdmem) if acc in WRITE_ACCESS: n.h_wrmem = HDLPort('{}{}_WrMem'.format(pfx, n.name), dir='OUT') module.ports.append(n.h_wrmem) if acc in READ_ACCESS: n.h_rddone = HDLPort('{}{}_RdDone'.format(pfx, n.name)) module.ports.append(n.h_rddone) if acc in WRITE_ACCESS: n.h_wrdone = HDLPort('{}{}_WrDone'.format(pfx, n.name)) module.ports.append(n.h_wrdone) if acc in READ_ACCESS and root.c_buserr: n.h_rderror = HDLPort('{}{}_RdError'.format(pfx, n.name), default=bit_0) module.ports.append(n.h_rderror) if acc in WRITE_ACCESS and root.c_buserr: n.h_wrerror = HDLPort('{}{}_WrError'.format(pfx, n.name), default=bit_0) module.ports.append(n.h_wrerror)