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_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 wire_bus_slave_wb32(root, stmts, n): stmts.append(HDLComment("Assignments for submap {}".format(n.name))) stmts.append(HDLAssign(n.h_bus['cyc'], HDLOr(n.h_wr, n.h_rd))) stmts.append(HDLAssign(n.h_bus['stb'], HDLOr(n.h_wr, n.h_rd))) stmts.append(HDLAssign(n.h_bus['adr'], root.h_bus['adr'])) stmts.append(HDLAssign(n.h_bus['sel'], HDLReplicate(bit_1, 4))) stmts.append(HDLAssign(n.h_bus['we'], n.h_wr)) stmts.append(HDLAssign(n.h_bus['dati'], root.h_bus['dati']))
def gen_hdl_no_cregrdmux_dff(root, module, isigs): module.stmts.append( HDLAssign(isigs.Loc_CRegRdData, HDLReplicate(bit_0, None))) module.stmts.append(HDLAssign(isigs.Loc_CRegRdOK, bit_0)) module.stmts.append(HDLAssign(isigs.Loc_CRegWrOK, bit_0)) module.stmts.append(HDLComment(None)) gen_hdl_cregrdmux_asgn(module.stmts, isigs) module.stmts.append(HDLComment(None))
def add_read_process(root, module, isigs): # Register read rd_data = root.h_bus['dato'] rd_ack = isigs.rd_ack rd_adr = root.h_bus.get('adr', None) rdproc = HDLComb() if rd_adr is not None: rdproc.sensitivity.append(rd_adr) if root.h_max_delay >= 1: rdproc.sensitivity.extend( [root.h_reg_rdat_int, root.h_rd_ack1_int, isigs.rd_int]) module.stmts.append(rdproc) # All the read are ack'ed (including the read to unassigned addresses). rdproc.stmts.append(HDLComment("By default ack read requests")) rdproc.stmts.append( HDLAssign(rd_data, HDLReplicate(bit_0, root.c_word_bits))) rdproc.stmts.append(HDLAssign(rd_ack, bit_1)) def add_read(s, n, off): if n is not None: if isinstance(n, tree.Reg): s.append(HDLComment(n.name)) s.append(HDLAssign(rd_data, root.h_reg_rdat_int)) s.append(HDLAssign(rd_ack, root.h_rd_ack1_int)) elif isinstance(n, tree.Submap): s.append(HDLComment("Submap {}".format(n.name))) if n.c_interface == 'wb-32-be': s.append(HDLAssign(rd_data, n.h_bus['dato'])) rdproc.stmts.append(HDLAssign(n.h_rd, bit_0)) s.append(HDLAssign(n.h_rd, isigs.rd_int)) s.append(HDLAssign(isigs.rd_ack, n.h_bus['ack'])) return elif n.c_interface == 'sram': return else: raise AssertionError elif isinstance(n, tree.Array): s.append(HDLComment("RAM {}".format(n.name))) # TODO: handle list of registers! r = n.children[0] rdproc.sensitivity.append(r.h_sig_dato) # Output ram data s.append(HDLAssign(rd_data, r.h_sig_dato)) # Set rd signal to ram s.append(HDLAssign(r.h_sig_rd, isigs.rd_int)) # But set it to 0 when the ram is not selected. rdproc.stmts.append(HDLAssign(r.h_sig_rd, bit_0)) # Use delayed ack as ack. s.append(HDLAssign(rd_ack, root.h_rd_ack1_int)) return else: # Blocks have been handled. raise AssertionError stmts = [] add_decoder(root, stmts, rd_adr, root, add_read) rdproc.stmts.extend(stmts)
def wire_array_reg(root, module, reg): if root.h_ram is None: module.deps.append(('work', 'wbgen2_pkg')) root.h_ram = True root.h_ram_wr_dly = HDLSignal("wr_dly_int") module.decls.append(root.h_ram_wr_dly) inst = HDLInstance(reg.name + "_raminst", "wbgen2_dpssram") module.stmts.append(inst) inst.params.append(("g_data_width", HDLNumber(reg.c_rwidth))) inst.params.append(("g_size", HDLNumber(1 << reg.h_addr_width))) inst.params.append(("g_addr_width", HDLNumber(reg.h_addr_width))) inst.params.append(("g_dual_clock", HDLBool(False))) inst.params.append(("g_use_bwsel", HDLBool(False))) inst.conns.append(("clk_a_i", root.h_bus['clk'])) inst.conns.append(("clk_b_i", root.h_bus['clk'])) inst.conns.append( ("addr_a_i", HDLSlice(root.h_bus['adr'], 0, reg.h_addr_width))) inst.conns.append(("addr_b_i", reg.h_addr)) nbr_bytes = reg.c_rwidth // tree.BYTE_SIZE reg.h_sig_bwsel = HDLSignal(reg.name + '_int_bwsel', nbr_bytes) module.decls.append(reg.h_sig_bwsel) inst.conns.append(("bwsel_b_i", reg.h_sig_bwsel)) inst.conns.append(("bwsel_a_i", reg.h_sig_bwsel)) if reg.access == 'ro': raise AssertionError # TODO inst.conns.append(("data_a_o", reg.h_dat)) inst.conns.append(("rd_a_i", rd_sig)) else: # External port is RO. reg.h_sig_dato = HDLSignal(reg.name + '_int_dato', reg.c_rwidth) module.decls.append(reg.h_sig_dato) reg.h_dat_ign = HDLSignal(reg.name + '_ext_dat', reg.c_rwidth) module.decls.append(reg.h_dat_ign) reg.h_sig_rd = HDLSignal(reg.name + '_int_rd') module.decls.append(reg.h_sig_rd) reg.h_sig_wr = HDLSignal(reg.name + '_int_wr') module.decls.append(reg.h_sig_wr) reg.h_ext_wr = HDLSignal(reg.name + '_ext_wr') module.decls.append(reg.h_ext_wr) module.stmts.append(HDLAssign(reg.h_ext_wr, bit_0)) inst.conns.append(("data_a_i", root.h_bus['dati'])) inst.conns.append(("data_a_o", reg.h_sig_dato)) inst.conns.append(("rd_a_i", reg.h_sig_rd)) inst.conns.append(("wr_a_i", reg.h_sig_wr)) inst.conns.append(("data_b_i", reg.h_dat_ign)) inst.conns.append(("data_b_o", reg.h_dat)) inst.conns.append(("rd_b_i", reg.h_rd)) inst.conns.append(("wr_b_i", reg.h_ext_wr)) module.stmts.append( HDLAssign(reg.h_sig_bwsel, HDLReplicate(bit_1, nbr_bytes)))
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_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))