def add_decode_wb(root, module, isigs): "Generate internal signals used by decoder/processes from WB bus." isigs.rd_int = HDLSignal('rd_int') # Read access isigs.wr_int = HDLSignal('wr_int') # Write access isigs.rd_ack = HDLSignal('rd_ack_int') # Ack for read isigs.wr_ack = HDLSignal('wr_ack_int') # Ack for write # Internal signals for wb. isigs.wb_en = HDLSignal('wb_en') isigs.ack_int = HDLSignal('ack_int') # Ack module.decls.extend([ isigs.wb_en, isigs.rd_int, isigs.wr_int, isigs.ack_int, isigs.rd_ack, isigs.wr_ack ]) module.stmts.append( HDLAssign(isigs.wb_en, HDLAnd(root.h_bus['cyc'], root.h_bus['stb']))) module.stmts.append( HDLAssign(isigs.rd_int, HDLAnd(isigs.wb_en, HDLNot(root.h_bus['we'])))) module.stmts.append( HDLAssign(isigs.wr_int, HDLAnd(isigs.wb_en, root.h_bus['we']))) module.stmts.append( HDLAssign(isigs.ack_int, HDLOr(isigs.rd_ack, isigs.wr_ack))) module.stmts.append(HDLAssign(root.h_bus['ack'], isigs.ack_int)) module.stmts.append( HDLAssign(root.h_bus['stall'], HDLAnd(HDLNot(isigs.ack_int), isigs.wb_en)))
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_regdone(root, module, isigs, root_isigs, rd_delay, wr_delay): asgn = HDLAssign( isigs.RegRdDone, HDLAnd(HDLIndex(root_isigs.Loc_VMERdMem, rd_delay), isigs.RegRdOK)) module.stmts.append(asgn) asgn = HDLAssign( isigs.RegWrDone, HDLAnd(HDLIndex(root_isigs.Loc_VMEWrMem, wr_delay), isigs.CRegWrOK)) module.stmts.append(asgn) module.stmts.append(HDLComment(None)) if root.c_buserr: asgn = HDLAssign( isigs.RegRdError, HDLAnd(HDLIndex(root_isigs.Loc_VMERdMem, rd_delay), HDLNot(isigs.RegRdOK))) module.stmts.append(asgn) asgn = HDLAssign( isigs.RegWrError, HDLAnd(HDLIndex(root_isigs.Loc_VMEWrMem, wr_delay), HDLNot(isigs.CRegWrOK))) module.stmts.append(asgn) 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 add_read_reg_process(root, module, isigs): # Register read rd_data = root.h_reg_rdat_int rd_ack = root.h_rd_ack1_int rdproc = HDLSync(root.h_bus['clk'], root.h_bus['rst']) module.stmts.append(rdproc) rdproc.rst_stmts.append(HDLAssign(rd_ack, bit_0)) rdproc.rst_stmts.append( HDLAssign(rd_data, HDLReplicate(bit_x, root.c_word_bits))) rdproc.sync_stmts.append( HDLAssign(rd_data, HDLReplicate(bit_x, root.c_word_bits))) rd_if = HDLIfElse(HDLAnd(HDLEq(isigs.rd_int, bit_1), HDLEq(rd_ack, bit_0))) rdproc.sync_stmts.append(rd_if) rd_if.then_stmts.append(HDLAssign(rd_ack, bit_1)) rd_if.else_stmts.append(HDLAssign(rd_ack, bit_0)) def add_read_reg(s, n, off): for f in n.children: if n.access in ['wo', 'rw']: src = f.h_reg elif n.access == 'ro': src = f.h_iport elif n.access == 'cst': src = HDLConst(f.preset, f.c_rwidth) else: raise AssertionError reg, dat = field_decode(root, n, f, off, src, rd_data) if reg is None: continue s.append(HDLAssign(dat, reg)) def add_read(s, n, off): if n is not None: if isinstance(n, tree.Reg): s.append(HDLComment(n.name)) if n.access != 'wo': add_read_reg(s, n, off) elif isinstance(n, tree.Submap): pass elif isinstance(n, tree.Array): s.append(HDLComment("RAM {}".format(n.name))) else: # Blocks have been handled. raise AssertionError then_stmts = [] add_decoder(root, then_stmts, root.h_bus.get('adr', None), root, add_read) rd_if.then_stmts.extend(then_stmts)
def add_write_process(root, module, isigs): # Register write wrproc = HDLSync(root.h_bus['clk'], root.h_bus['rst']) module.stmts.append(wrproc) if root.h_ram_wr_dly is not None: wrproc.rst_stmts.append(HDLAssign(root.h_ram_wr_dly, bit_0)) wr_if = HDLIfElse( HDLAnd(HDLEq(isigs.wr_int, bit_1), HDLEq(isigs.wr_ack, bit_0))) wr_if.else_stmts.append(HDLAssign(isigs.wr_ack, bit_0)) wr_data = root.h_bus['dati'] def add_write_reg(s, n, off): for f in n.children: # Reset code if f.h_reg is not None: v = 0 if f.preset is None else f.preset cst = HDLConst(v, f.c_iowidth if f.c_iowidth != 1 else None) wrproc.rst_stmts.append(HDLAssign(f.h_reg, cst)) # Assign code if f.hdl_type == 'reg': r = f.h_reg elif f.hdl_type == 'wire': r = f.h_oport else: raise AssertionError reg, dat = field_decode(root, n, f, off, r, wr_data) if reg is None: continue s.append(HDLAssign(reg, dat)) if f.h_wport is not None: s.append(HDLAssign(f.h_wport, bit_1)) wrproc.rst_stmts.append(HDLAssign(f.h_wport, bit_0)) wrproc.sync_stmts.append(HDLAssign(f.h_wport, bit_0)) def add_write(s, n, off): if n is not None: if isinstance(n, tree.Reg): s.append(HDLComment(n.name)) if n.access in ['wo', 'rw']: add_write_reg(s, n, off) elif isinstance(n, tree.Submap): s.append(HDLComment("Submap {}".format(n.name))) if n.c_interface == 'wb-32-be': wrproc.rst_stmts.append(HDLAssign(n.h_wr, bit_0)) wr_if.then_stmts.append(HDLAssign(n.h_wr, bit_0)) s.append(HDLAssign(n.h_wr, bit_1)) s.append(HDLAssign(isigs.wr_ack, n.h_bus['ack'])) return elif n.c_interface == 'sram': s.append(HDLAssign(n.h_wr_o, bit_1)) return else: raise AssertionError elif isinstance(n, tree.Array): # TODO: handle list of registers! r = n.children[0] wrproc.rst_stmts.append(HDLAssign(r.h_sig_wr, bit_0)) wr_if.else_stmts.append(HDLAssign(r.h_sig_wr, bit_0)) s2 = HDLIfElse(HDLEq(root.h_ram_wr_dly, bit_0)) s.append(s2) s2.then_stmts.append(HDLAssign(r.h_sig_wr, bit_1)) s2.then_stmts.append(HDLAssign(root.h_ram_wr_dly, bit_1)) s2.else_stmts.append(HDLAssign(root.h_ram_wr_dly, bit_0)) s2.else_stmts.append(HDLAssign(isigs.wr_ack, bit_1)) return else: # Including blocks. raise AssertionError # All the write are ack'ed (including the write to unassigned # addresses) s.append(HDLAssign(isigs.wr_ack, bit_1)) then_stmts = [] add_decoder(root, then_stmts, root.h_bus.get('adr', None), root, add_write) wr_if.then_stmts.extend(then_stmts) wrproc.sync_stmts.append(wr_if)
def gen_hdl_reg_stmts(reg, pfx, root, module, isigs): if reg.h_SRFF: module.stmts.append(HDLAssign(reg.h_SRFF, reg.h_loc_SRFF)) if get_gena_gen(reg, 'no-split'): for i in range(len(reg.h_mux.codelist)): if reg.access in ('ro'): src = reg.h_port[i] src = gen_reg_resize(reg, src, reg.c_iowidth, reg.c_rwidth) module.stmts.append(HDLAssign(reg.h_loc_mux[i], src)) else: src = reg.h_loc_mux[i] src = gen_reg_resize(reg, src, reg.c_rwidth, reg.c_iowidth) module.stmts.append(HDLAssign(reg.h_port[i], src)) elif get_gena_gen(reg, 'ext-creg'): if reg.access in READ_ACCESS: module.stmts.append(HDLAssign(reg.h_loc, reg.h_port)) if reg.access in WRITE_ACCESS: for i in reversed(range(reg.c_nwords)): module.stmts.append(HDLAssign(reg.h_portsel[i], reg.h_wrsel[i])) elif reg.access in ('ro'): if reg.h_busout is not None: module.stmts.append(HDLAssign(reg.h_busout, reg.h_loc)) # Create bitlist, a list of ordered (lo + width, lo, field) # Fill gaps with (lo + width, lo, None) bitlist = [] nbit = 0 # Next bit (used for padding) for f in sorted(reg.children, key=(lambda x: x.lo)): if f.lo > nbit: bitlist.append((f.lo, nbit, None)) nbit = f.lo + f.c_rwidth bitlist.append((nbit, f.lo, f)) if nbit != reg.c_rwidth: bitlist.append((reg.c_rwidth, nbit, None)) # Assign Loc_ from inputs; assign outputs from Loc_ for hi, lo, f in reversed(bitlist): for m in range(len(reg.h_loc_mux)): tgt = reg.h_loc_mux[m] if f is None: idx = (hi - 1) // root.c_word_bits while True: l = max(idx * root.c_word_bits, lo) if hi == l + 1: src = HDLIndex(reg.h_gena_psm[idx], l) t = HDLIndex(tgt, l) else: src = HDLSlice(reg.h_gena_psm[idx], l, hi - l) t = HDLSlice(tgt, l, hi - l) module.stmts.append(HDLAssign(t, src)) if l == lo: break hi = idx * root.c_word_bits idx -= 1 else: if hi == lo + 1: tgt = HDLIndex(tgt, lo) elif lo == 0 and hi == reg.c_rwidth: pass else: tgt = HDLSlice(tgt, lo, hi - lo) src = f.h_port[m] src = gen_reg_resize(reg, src, f.c_iowidth, f.c_rwidth) module.stmts.append(HDLAssign(tgt, src)) else: for m in range(len(reg.h_loc_mux)): for f in reg.children: src = reg.h_loc_mux[m] if f.hi is None: src = HDLIndex(src, f.lo) elif f.lo == 0 and f.hi == reg.c_rwidth - 1: pass else: src = HDLSlice(src, f.lo, f.hi - f.lo + 1) src = gen_reg_resize(reg, src, f.c_rwidth, f.c_iowidth) module.stmts.append(HDLAssign(f.h_port[m], src)) if reg.h_rdstrobe: for i in reversed(range(reg.c_nwords)): module.stmts.append( HDLAssign(reg.h_rdstrobe[i], HDLAnd(reg.h_rdsel[i], isigs.RegRdDone))) if reg.h_wrstrobe: for i in reversed(range(reg.c_nwords)): for j in range(len(reg.h_mux.codelist)): module.stmts.append( HDLAssign(reg.h_wrstrobe[i][j], HDLAnd(reg.h_wrsel_mux[i][j], isigs.RegWrDone))) module.stmts.append(HDLComment(None)) if reg.h_has_mux: if reg.access in WRITE_ACCESS: gen_hdl_reg_wrseldec(reg, pfx, root, module, isigs) gen_hdl_reg_rdmux(reg, pfx, root, module, isigs)