Пример #1
0
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)))
Пример #2
0
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))
Пример #3
0
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))
Пример #4
0
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))
Пример #5
0
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))
Пример #6
0
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)
Пример #7
0
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)
Пример #8
0
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)