Example #1
0
def fifo_short(clock, reset, clear, datain, src_rdy_i, dst_rdy_o, dataout,
               src_rdy_o, dst_rdy_i):

    wr = Signal(bool(0))
    rd = Signal(bool(0))

    args = Namespace(width=36, size=16, name='fifo_2clock_cascade')
    fbus = FIFOBus(size=args.size, width=args.width)
    # need to update the fbus refernces to reference the Signals in
    # the module port list (function arguments).
    fbus.write = wr
    fbus.write_data = datain
    fbus.read = rd
    fbus.read_data = dataout

    @always_comb
    def rtl_assign1():
        wr.next = src_rdy_i & dst_rdy_o
        rd.next = dst_rdy_i & src_rdy_o

    @always_comb
    def rtl_assign2():
        dst_rdy_o.next = not fbus.full
        src_rdy_o.next = not fbus.empty

    gfifo = fifo_fast(reset, clock, fbus)

    return rtl_assign1, rtl_assign2, gfifo
Example #2
0
def m_fifo_short(clock, reset, clear, 
                 datain, src_rdy_i, dst_rdy_o,
                 dataout, src_rdy_o, dst_rdy_i):

    wr = Signal(bool(0))
    rd = Signal(bool(0))

    args = Namespace(width=36, size=16, name='fifo_2clock_cascade')
    fbus = FIFOBus(args=args)
    # need to update the fbus refernces to reference the Signals in
    # the module port list (function arguments).
    fbus.wr = wr
    fbus.wdata = datain
    fbus.rd = rd
    fbus.rdata = dataout

    @always_comb
    def rtl_assign1():
        wr.next = src_rdy_i & dst_rdy_o
        rd.next = dst_rdy_i & src_rdy_o

    @always_comb
    def rtl_assign2():
        dst_rdy_o.next = not fbus.full
        src_rdy_o.next = not fbus.empty

    gfifo = fifo_fast(clock, reset, fbus)

    return rtl_assign1, rtl_assign2, gfifo
Example #3
0
def fifo_short(clock, reset, clear,
               datain, src_rdy_i, dst_rdy_o,
               dataout, src_rdy_o, dst_rdy_i):

    glbl = Global(clock, reset)
    wr = Signal(bool(0))
    rd = Signal(bool(0))

    args = Namespace(width=36, size=16, name='fifo_2clock_cascade')
    fbus = FIFOBus(width=args.width)
    # need to update the fbus refernces to reference the Signals in
    # the module port list (function arguments).
    fbus.write = wr
    fbus.write_data = datain
    fbus.read = rd
    fbus.read_data = dataout

    @always_comb
    def beh_assign1():
        wr.next = src_rdy_i & dst_rdy_o
        rd.next = dst_rdy_i & src_rdy_o

    @always_comb
    def beh_assign2():
        dst_rdy_o.next = not fbus.full
        src_rdy_o.next = not fbus.empty

    fifo_inst = fifo_fast(glbl, fbus, size=args.size)

    return myhdl.instances()
Example #4
0
    def _bench_command_bridge():
        tbclk = clock.gen()
        tbdut = memmap_command_bridge(glbl, fbtx, fbrx, memmap)
        tbfii = fifo_fast(clock, reset, fbtx)
        tbfio = fifo_fast(clock, reset, fbrx)
        # @todo: add other bus types
        tbmem = memmap_peripheral_bb(clock, reset, memmap)

        # save the data read ...
        read_value = []

        @instance
        def tbstim():
            yield reset.pulse(32)

            try:
                # test a single address
                pkt = CommandPacket(True, 0x0000)
                yield pkt.put(fbtx)
                yield pkt.get(fbrx, read_value, [0])
                pkt = CommandPacket(False, 0x0000, [0x5555AAAA])
                yield pkt.put(fbtx)
                yield pkt.get(fbrx, read_value, [0x5555AAAA])

                # test a bunch of random addresses
                for ii in range(nloops):
                    randaddr = randint(0, (2**20)-1)
                    randdata = randint(0, (2**32)-1)
                    pkt = CommandPacket(False, randaddr, [randdata])
                    yield pkt.put(fbtx)
                    yield pkt.get(fbrx, read_value, [randdata])

            except Exception as err:
                print("Error: {}".format(str(err)))
                traceback.print_exc()

            yield delay(2000)
            raise StopSimulation

        return tbclk, tbdut, tbfii, tbfio, tbmem, tbstim
    def _bench_command_bridge():
        tbclk = clock.gen()
        tbdut = memmap_command_bridge(glbl, fbtx, fbrx, memmap)
        tbfii = fifo_fast(clock, reset, fbtx)
        tbfio = fifo_fast(clock, reset, fbrx)
        # @todo: add other bus types
        tbmem = memmap_peripheral_bb(clock, reset, memmap)

        # save the data read ...
        read_value = []

        @instance
        def tbstim():
            yield reset.pulse(32)

            try:
                # test a single address
                pkt = CommandPacket(True, 0x0000)
                yield pkt.put(fbtx)
                yield pkt.get(fbrx, read_value, [0])
                pkt = CommandPacket(False, 0x0000, [0x5555AAAA])
                yield pkt.put(fbtx)
                yield pkt.get(fbrx, read_value, [0x5555AAAA])

                # test a bunch of random addresses
                for ii in range(nloops):
                    randaddr = randint(0, (2**20) - 1)
                    randdata = randint(0, (2**32) - 1)
                    pkt = CommandPacket(False, randaddr, [randdata])
                    yield pkt.put(fbtx)
                    yield pkt.get(fbrx, read_value, [randdata])

            except Exception as err:
                print("Error: {}".format(str(err)))
                traceback.print_exc()

            yield delay(2000)
            raise StopSimulation

        return tbclk, tbdut, tbfii, tbfio, tbmem, tbstim
Example #6
0
def spi_slave_fifo(glbl, spibus, fifobus):
    """
    This is an SPI slave peripheral, when the master starts clocking
    any data in the TX FIFO (fifobus.write) will be sent (the next
    byte) and the received byte will be copied to RX FIFO
    (fifobus.read).  The `cso` interface can be used to configure
    how the SPI slave peripheral behaves.

    (Arguments == Ports)
    Arguments:
        glbl (Global): global clock and reset
        spibus  (SPIBus): the external SPI interface
        fifobus (FIFOBus): the fifo interface
        cso (ControlStatus): the control status signals
    """
    fifosize = 8

    # Use an async FIFO to transfer from the SPI SCK clock domain and
    # the internal clock domain.  This allows for high-speed SCK.
    clock, reset = glbl.clock, glbl.reset
    assert isinstance(spibus, SPIBus)
    assert isinstance(fifobus, FIFOBus)

    sck, csn = spibus.sck, spibus.csn
    # the FIFOs for the receive and transmit (external perspective)
    readpath = FIFOBus(width=fifobus.width)
    writepath = FIFOBus(width=fifobus.width)

    # the FIFO instances
    tx_fifo_inst = fifo_fast(glbl, writepath, size=fifosize)
    rx_fifo_inst = fifo_fast(glbl, readpath, size=fifosize)
    mp_fifo_inst = fifobus.assign_read_write_paths(readpath, writepath)

    spi_start = Signal(bool(0))
    ireg, icap, icaps = Signals(intbv(0)[8:], 3)
    oreg, ocap = Signals(intbv(0)[8:], 2)
    bitcnt, b2, b3 = Signals(intbv(0, min=0, max=10), 3)

    @always(sck.posedge, csn.negedge)
    def csn_falls():
        if sck:
            spi_start.next = False
        elif not csn:
            spi_start.next = True

    # SCK clock domain, this allows high SCK rates
    @always(sck.posedge, csn.posedge)
    def sck_capture_send():
        if csn:
            b2.next = 0
            bitcnt.next = 0
        else:
            if bitcnt == 0 or spi_start:
                spibus.miso.next = ocap[7]
                oreg.next = (ocap << 1) & 0xFF
            else:
                spibus.miso.next = oreg[7]
                oreg.next = (oreg << 1) & 0xFF

            ireg.next = concat(ireg[7:0], spibus.mosi)
            bitcnt.next = bitcnt + 1
            if bitcnt == (8 - 1):
                bitcnt.next = 0
                b2.next = 8
                icap.next = concat(ireg[7:0], spibus.mosi)
            else:
                b2.next = 0

    # synchronize the SCK domain to the clock domain
    syncro(clock, icap, icaps)
    syncro(clock, b2, b3)

    gotit = Signal(bool(0))

    @always(clock.posedge)
    def beh_io_capture():
        # default no writes
        readpath.write.next = False
        writepath.read.next = False

        if b3 == 0:
            gotit.next = False
        elif b3 == 8 and not gotit:
            readpath.write.next = True
            readpath.write_data.next = icaps
            gotit.next = True
            ocap.next = writepath.read_data
            if not writepath.empty:
                writepath.read.next = True

    return myhdl.instances()
    def bench_command_bridge():
        tbclk = clock.gen()
        tbdut = command_bridge(glbl, fifobus, memmap)

        readpath, writepath = FIFOBus(), FIFOBus()
        readpath.clock = writepath.clock = clock
        tbmap = fifobus.assign_read_write_paths(readpath, writepath)
        tbftx = fifo_fast(reset, clock, writepath)   # user write path
        tbfrx = fifo_fast(reset, clock, readpath)    # user read path

        # @todo: add other bus types
        tbmem = memmap_peripheral_bb(clock, reset, memmap)

        # save the data read ...
        read_value = []

        @instance
        def tbstim():
            yield reset.pulse(32)
            fifobus.read.next = False
            fifobus.write.next = False
            assert not fifobus.full
            assert fifobus.empty
            assert fifobus.read_data == 0
            fifobus.write_data.next = 0

            try:
                # test a single address
                pkt = CommandPacket(True, 0x0000)
                yield pkt.put(readpath)
                yield pkt.get(writepath, read_value, [0])

                pkt = CommandPacket(False, 0x0000, [0x5555AAAA])
                yield pkt.put(readpath)
                yield pkt.get(writepath, read_value, [0x5555AAAA])

                # test a bunch of random addresses
                for ii in range(nloops):
                    randaddr = randint(0, (2**20)-1)
                    randdata = randint(0, (2**32)-1)
                    pkt = CommandPacket(False, randaddr, [randdata])
                    yield pkt.put(readpath)
                    yield pkt.get(writepath, read_value, [randdata])

            except Exception as err:
                print("Error: {}".format(str(err)))
                traceback.print_exc()

            yield delay(2000)
            raise StopSimulation

        wp_read, wp_valid = Signals(bool(0), 2)
        wp_read_data = Signal(intbv(0)[8:])
        wp_empty, wp_full = Signals(bool(0), 2)

        @always_comb
        def tbmon():
            wp_read.next = writepath.read
            wp_read_data.next = writepath.read_data
            wp_valid.next = writepath.read_valid
            wp_full.next = writepath.full
            wp_empty.next = writepath.empty

        return tbclk, tbdut, tbmap, tbftx, tbfrx, tbmem, tbstim, tbmon
Example #8
0
def spi_slave_fifo(glbl, spibus, fifobus):
    """
    This is an SPI slave peripheral, when the master starts clocking
    any data in the TX FIFO (fifobus.write) will be sent (the next
    byte) and the received byte will be copied to RX FIFO
    (fifobus.read).  The `cso` interface can be used to configure
    how the SPI slave peripheral behaves.

    (Arguments == Ports)
    Arguments:
        glbl (Global): global clock and reset
        spibus  (SPIBus): the external SPI interface
        fifobus (FIFOBus): the fifo interface
        cso (ControlStatus): the control status signals
    """
    fifosize = 8

    # Use an async FIFO to transfer from the SPI SCK clock domain and
    # the internal clock domain.  This allows for high-speed SCK.
    clock, reset = glbl.clock, glbl.reset
    assert isinstance(spibus, SPIBus)
    assert isinstance(fifobus, FIFOBus)

    sck, csn = spibus.sck, spibus.csn
    # the FIFOs for the receive and transmit (external perspective)
    readpath = FIFOBus(width=fifobus.width)
    writepath = FIFOBus(width=fifobus.width)

    # the FIFO instances
    tx_fifo_inst = fifo_fast(glbl, writepath, size=fifosize)
    rx_fifo_inst = fifo_fast(glbl, readpath, size=fifosize)
    mp_fifo_inst = fifobus.assign_read_write_paths(readpath, writepath)

    spi_start = Signal(bool(0))
    ireg, icap, icaps = Signals(intbv(0)[8:], 3)
    oreg, ocap = Signals(intbv(0)[8:], 2)
    bitcnt, b2, b3 = Signals(intbv(0, min=0, max=10), 3)

    @always(sck.posedge, csn.negedge)
    def csn_falls():
        if sck:
            spi_start.next = False
        elif not csn:
            spi_start.next = True

    # SCK clock domain, this allows high SCK rates
    @always(sck.posedge, csn.posedge)
    def sck_capture_send():
        if csn:
            b2.next = 0
            bitcnt.next = 0
        else:
            if bitcnt == 0 or spi_start:
                spibus.miso.next = ocap[7]
                oreg.next = (ocap << 1) & 0xFF
            else:
                spibus.miso.next = oreg[7]
                oreg.next = (oreg << 1) & 0xFF

            ireg.next = concat(ireg[7:0], spibus.mosi)
            bitcnt.next = bitcnt + 1
            if bitcnt == (8-1):
                bitcnt.next = 0
                b2.next = 8
                icap.next = concat(ireg[7:0], spibus.mosi)
            else:
                b2.next = 0

    # synchronize the SCK domain to the clock domain
    syncro(clock, icap, icaps)
    syncro(clock, b2, b3)

    gotit = Signal(bool(0))

    @always(clock.posedge)
    def beh_io_capture():
        # default no writes
        readpath.write.next = False
        writepath.read.next = False

        if b3 == 0:
            gotit.next = False
        elif b3 == 8 and not gotit:
            readpath.write.next = True
            readpath.write_data.next = icaps
            gotit.next = True
            ocap.next = writepath.read_data
            if not writepath.empty:
                writepath.read.next = True

    return myhdl.instances()
    def bench_command_bridge():
        tbclk = clock.gen()
        tbdut = command_bridge(glbl, fifobus, memmap)

        readpath, writepath = FIFOBus(), FIFOBus()
        readpath.clock = writepath.clock = clock
        tbmap = fifobus.assign_read_write_paths(readpath, writepath)
        tbftx = fifo_fast(reset, clock, writepath)  # user write path
        tbfrx = fifo_fast(reset, clock, readpath)  # user read path

        # @todo: add other bus types
        tbmem = memmap_peripheral_bb(clock, reset, memmap)

        # save the data read ...
        read_value = []

        @instance
        def tbstim():
            yield reset.pulse(32)
            fifobus.read.next = False
            fifobus.write.next = False
            assert not fifobus.full
            assert fifobus.empty
            assert fifobus.read_data == 0
            fifobus.write_data.next = 0

            try:
                # test a single address
                pkt = CommandPacket(True, 0x0000)
                yield pkt.put(readpath)
                yield pkt.get(writepath, read_value, [0])

                pkt = CommandPacket(False, 0x0000, [0x5555AAAA])
                yield pkt.put(readpath)
                yield pkt.get(writepath, read_value, [0x5555AAAA])

                # test a bunch of random addresses
                for ii in range(nloops):
                    randaddr = randint(0, (2**20) - 1)
                    randdata = randint(0, (2**32) - 1)
                    pkt = CommandPacket(False, randaddr, [randdata])
                    yield pkt.put(readpath)
                    yield pkt.get(writepath, read_value, [randdata])

            except Exception as err:
                print("Error: {}".format(str(err)))
                traceback.print_exc()

            yield delay(2000)
            raise StopSimulation

        wp_read, wp_valid = Signals(bool(0), 2)
        wp_read_data = Signal(intbv(0)[8:])
        wp_empty, wp_full = Signals(bool(0), 2)

        @always_comb
        def tbmon():
            wp_read.next = writepath.read
            wp_read_data.next = writepath.read_data
            wp_valid.next = writepath.read_valid
            wp_full.next = writepath.full
            wp_empty.next = writepath.empty

        return tbclk, tbdut, tbmap, tbftx, tbfrx, tbmem, tbstim, tbmon