def test_type():
    data_width = 32
    apb_16_32 = APBMaster(16, data_width)()
    assert isinstance(apb_16_32.PCLK, m.ClockType)
    assert apb_16_32.PCLK.isoutput()
    assert isinstance(apb_16_32.PRESETn, m.ResetType)
    assert apb_16_32.PRESETn.isoutput()
    assert isinstance(apb_16_32.PADDR, m.BitsType)
    assert apb_16_32.PADDR.isoutput()
    assert isinstance(apb_16_32.PPROT, m.BitType)
    assert apb_16_32.PPROT.isoutput()
    assert isinstance(apb_16_32.PSEL0, m.BitType)
    assert apb_16_32.PSEL0.isoutput()
    assert isinstance(apb_16_32.PENABLE, m.BitType)
    assert apb_16_32.PENABLE.isoutput()
    assert isinstance(apb_16_32.PWRITE, m.BitType)
    assert apb_16_32.PWRITE.isoutput()
    assert isinstance(apb_16_32.PWDATA, m.BitsType)
    assert apb_16_32.PWDATA.isoutput()
    assert isinstance(apb_16_32.PSTRB, m.BitsType)
    assert apb_16_32.PSTRB.isoutput()
    assert len(apb_16_32.PSTRB) == data_width / 8
    assert isinstance(apb_16_32.PREADY, m.BitType)
    assert apb_16_32.PREADY.isinput()
    assert isinstance(apb_16_32.PRDATA, m.BitsType)
    assert apb_16_32.PRDATA.isinput()
    assert isinstance(apb_16_32.PSLVERR, m.BitType)
    assert apb_16_32.PSLVERR.isinput()

    apb_slave_16_32 = APBSlave(16, data_width, 0)()
    assert isinstance(apb_slave_16_32.PCLK, m.ClockType)
    assert apb_slave_16_32.PCLK.isinput()
    assert isinstance(apb_slave_16_32.PRESETn, m.ResetType)
    assert apb_slave_16_32.PRESETn.isinput()
    assert isinstance(apb_slave_16_32.PADDR, m.BitsType)
    assert apb_slave_16_32.PADDR.isinput()
    assert isinstance(apb_slave_16_32.PPROT, m.BitType)
    assert apb_slave_16_32.PPROT.isinput()
    assert isinstance(apb_slave_16_32.PSEL0, m.BitType)
    assert apb_slave_16_32.PSEL0.isinput()
    assert isinstance(apb_slave_16_32.PENABLE, m.BitType)
    assert apb_slave_16_32.PENABLE.isinput()
    assert isinstance(apb_slave_16_32.PWRITE, m.BitType)
    assert apb_slave_16_32.PWRITE.isinput()
    assert isinstance(apb_slave_16_32.PWDATA, m.BitsType)
    assert apb_slave_16_32.PWDATA.isinput()
    assert isinstance(apb_slave_16_32.PSTRB, m.BitsType)
    assert apb_slave_16_32.PSTRB.isinput()
    assert len(apb_slave_16_32.PSTRB) == data_width / 8
    assert isinstance(apb_slave_16_32.PREADY, m.BitType)
    assert apb_slave_16_32.PREADY.isoutput()
    assert isinstance(apb_slave_16_32.PRDATA, m.BitsType)
    assert apb_slave_16_32.PRDATA.isoutput()
    assert isinstance(apb_slave_16_32.PSLVERR, m.BitType)
    assert apb_slave_16_32.PSLVERR.isoutput()

    assert APBSlave(16, 32, 0).flip() == APBMaster(16, 32)
Exemple #2
0
    class Top(m.Circuit):
        if mode == "pack":
            IO = ["apb", APBSlave(addr_width, data_width, 0)]
        else:
            IO = ["apb", APBSlave(addr_width, data_width, [0, 1])]

        @classmethod
        def definition(io):
            dmas = [DMA(name=f"dma{i}") for i in range(2)]
            if mode == "pack":
                regs = [
                    Register(name + str(i)) for i in range(2)
                    for name in fields
                ]
                reg_file = DefineRegFile(regs, data_width=32)(name="reg_file")
                for i in range(2):
                    for name in fields:
                        m.wire(getattr(reg_file, name + str(i) + "_q"),
                               getattr(dmas[i], name))
                m.wire(io.apb, reg_file.apb)
                for i in range(2):
                    for name in fields:
                        m.wire(getattr(reg_file, name + str(i) + "_q"),
                               getattr(reg_file, name + str(i) + "_d"))
            else:
                apb_outputs = {}
                for key, type_ in APBBase(addr_width, data_width).items():
                    if type_.isinput():
                        apb_outputs[key] = []
                for i in range(2):
                    regs = [Register(name) for name in fields]
                    reg_file = DefineRegFile(
                        regs, data_width=32,
                        apb_slave_id=i)(name=f"reg_file{i}")
                    for name in fields:
                        m.wire(getattr(reg_file, name + "_q"),
                               getattr(dmas[i], name))
                    for key, type_ in APBBase(addr_width, data_width).items():
                        if type_.isoutput():
                            m.wire(getattr(io.apb, key),
                                   getattr(reg_file.apb, key))
                        else:
                            apb_outputs[key].append(getattr(reg_file.apb, key))
                    m.wire(getattr(io.apb, f"PSEL{i}"),
                           getattr(reg_file.apb, f"PSEL{i}"))
                    for name in fields:
                        m.wire(getattr(reg_file, name + "_q"),
                               getattr(reg_file, name + "_d"))
                for key, values in apb_outputs.items():
                    m.wire(getattr(io.apb, key),
                           mantle.mux(values, io.apb.PSEL1))
Exemple #3
0
    def __init__(self, mode="pack"):
        """
        Simple example that instances two stub DMA modules and is paramtrizable
        over distributed versus packed register file
        """

        if mode not in ["pack", "distribute"]:
            raise ValueError(f"Unexpected mode {mode}")

        fields = ["csr", "src_addr", "dst_addr", "txfr_len"]
        data_width = 32
		
        addr_width = math.ceil(math.log2(len(fields) * 2))

        self.name = "Top_" + mode
        
        self.io = io = m.IO(apb=APBSlave(addr_width, data_width, 0))

        dmas = [DMA(name=f"dma{i}") for i in range(2)]
        regs = tuple(Register(name + str(i)) for i in range(2) for name in
                     fields)
        reg_file = RegisterFileGenerator(regs, data_width=32)(name="reg_file")
        for i in range(2):
            for name in fields:
                m.wire(getattr(reg_file, name + str(i) + "_q"),
                       getattr(dmas[i], name))
        m.wire(io.apb, reg_file.apb)
        for i in range(2):
            for name in fields:
                m.wire(getattr(reg_file, name + str(i) + "_q"),
                       getattr(reg_file, name + str(i) + "_d"))
def make_reg_file_interface(reg_list: Tuple[Register], data_width: int,
                            apb_slave_id: int):
    # magma provides various helper functions in m.bitutils,
    # here we use clog2 to derive the number of bits required
    # to store the address space described by number of Registers
    # in `reg_list`
    addr_width = m.bitutils.clog2(len(reg_list))

    Data = m.Bits[data_width]

    io = m.IO(apb=APBSlave(addr_width, data_width, apb_slave_id))
    for reg in reg_list:
        io += m.IO(**{f"{reg.name}_d": m.In(Data)})
        if reg.has_ce:
            io += m.IO(**{f"{reg.name}_en": m.In(m.Enable)})
        io += m.IO(**{f"{reg.name}_q": m.Out(Data)})
    return io
Exemple #5
0
    class RegFile(m.Circuit):
        IO = ["apb", APBSlave(addr_width, data_width, apb_slave_id)]
        for reg in reg_list:
            IO += [f"{reg.name}_d", m.In(Data)]
            if reg.has_ce:
                IO += [f"{reg.name}_en", m.In(m.Enable)]
            IO += [f"{reg.name}_q", m.Out(Data)]

        @classmethod
        def definition(io):
            PSEL = getattr(io.apb, f"PSEL{apb_slave_id}")
            registers = [
                mantle.Register(data_width,
                                init=reg.init,
                                has_ce=True,
                                has_reset=True,
                                name=reg.name) for reg in reg_list
            ]
            is_write = io.apb.PENABLE & io.apb.PWRITE & PSEL
            ready = None
            for i, reg in enumerate(registers):
                reg.I <= mantle.mux(
                    [getattr(io, reg.name + "_d"), io.apb.PWDATA], is_write)
                getattr(io, reg.name + "_q") <= reg.O
                reg.CLK <= io.apb.PCLK
                reg.RESET <= ~m.bit(io.apb.PRESETn)
                ce = is_write & (io.apb.PADDR == i)
                if reg_list[i].has_ce:
                    reg.CE <= ce | m.bit(getattr(io, reg.name + "_en"))
                else:
                    reg.CE <= ce
                if ready is not None:
                    ready |= ce
                else:
                    ready = ce
            is_read = io.apb.PENABLE & ~io.apb.PWRITE & PSEL
            io.apb.PREADY <= ready | is_read
            io.apb.PRDATA <= mantle.mux([reg.O
                                         for reg in registers], io.apb.PADDR)
            io.apb.PSLVERR <= 0

            # Unused
            CorebitTerm().I <= io.apb.PPROT
            Term(len(io.apb.PSTRB)).I <= io.apb.PSTRB
    def __init__(self, mode="pack"):
        """
        Simple example that instances two stub DMA modules and is paramtrizable
        over distributed versus packed register file
        """

        if mode not in ["pack", "distribute"]:
            raise ValueError(f"Unexpected mode {mode}")

        fields = ["csr", "src_addr", "dst_addr", "txfr_len"]
        data_width = 32
        if mode == "pack":
            addr_width = math.ceil(math.log2(len(fields) * 2))
        else:
            addr_width = math.ceil(math.log2(len(fields)))

        self.name = "Top_" + mode
        if mode == "pack":
            self.io = io = m.IO(apb=APBSlave(addr_width, data_width, 0))
        else:
            self.io = io = m.IO(apb=APBSlave(addr_width, data_width, [0, 1]))

        dmas = [DMA(name=f"dma{i}") for i in range(2)]
        if mode == "pack":
            regs = tuple(
                Register(name + str(i)) for i in range(2) for name in fields)
            reg_file = RegisterFileGenerator(regs,
                                             data_width=32)(name="reg_file")
            for i in range(2):
                for name in fields:
                    m.wire(getattr(reg_file, name + str(i) + "_q"),
                           getattr(dmas[i], name))
            m.wire(io.apb, reg_file.apb)
            for i in range(2):
                for name in fields:
                    m.wire(getattr(reg_file, name + str(i) + "_q"),
                           getattr(reg_file, name + str(i) + "_d"))
        else:
            apb_outputs = {}
            for key, type_ in APBBase(addr_width, data_width).items():
                if type_.is_input():
                    apb_outputs[key] = []
            for i in range(2):
                regs = tuple(Register(name) for name in fields)
                reg_file = RegisterFileGenerator(
                    regs, data_width=32, apb_slave_id=i)(name=f"reg_file{i}")
                for name in fields:
                    m.wire(getattr(reg_file, name + "_q"),
                           getattr(dmas[i], name))
                for key, type_ in APBBase(addr_width, data_width).items():
                    if type_.is_output():
                        m.wire(getattr(io.apb, key),
                               getattr(reg_file.apb, key))
                    else:
                        apb_outputs[key].append(getattr(reg_file.apb, key))
                m.wire(getattr(io.apb, f"PSEL{i}"),
                       getattr(reg_file.apb, f"PSEL{i}"))
                for name in fields:
                    m.wire(getattr(reg_file, name + "_q"),
                           getattr(reg_file, name + "_d"))
            for key, values in apb_outputs.items():
                m.wire(getattr(io.apb, key), mantle.mux(values, io.apb.PSEL1))