Beispiel #1
0
def fifo_cdc(glbl, emesh_i, emesh_o):
    """
    map the packet interfaces to the FIOF interface
    """

    fifo_intf = FIFOBus(size=16, width=len(emesh_i.bits))

    @always_comb
    def rtl_assign():
        wr.next = emesh_i.access and not fifo_intf.full
        rd.next = not fifo_intf.empty and not emesh_i.wait
        emesh_o.wait.next = fifo_intf.full

    @always(emesh_o.clock.posedge)
    def rtl_access():
        if not emesh_i.wait:
            emesh_o.access.next = fifo_intf.rd

    # assign signals ot the FIFO interface
    fifo_intf.wdata = emesh_i.bits
    fifo_intf.rdata = emesh_o.bits

    g_fifo = cores.fifo.fifo_async(glbl.reset, emesh_i.clock, 
                                   emesh_o.clock, fifo_intf)

    return rtl_assign, rtl_access, g_fifo
Beispiel #2
0
def icestick(clock, led, pmod, uart_tx, uart_rx):
    """ Lattice Icestick example
    """

    glbl = Global(clock, None)
    gticks = glbl_timer_ticks(glbl, include_seconds=True)

    # get interfaces to the UART fifos
    fbustx = FIFOBus(width=8, size=8)
    fbusrx = FIFOBus(width=8, size=8)

    # get the UART comm from PC
    guart = uartlite(glbl, fbustx, fbusrx, uart_tx, uart_rx)

    @always_comb
    def beh_loopback():
        fbusrx.rd.next = not fbusrx.empty
        fbustx.wr.next = not fbusrx.empty
        fbustx.wdata.next = fbusrx.rdata

    lcnt = Signal(modbv(0, min=0, max=4))

    @always(clock.posedge)
    def beh_led_count():
        if glbl.tick_sec:
            lcnt.next = lcnt + 1
        led.next = (1 << lcnt)

    # system to test/interface

    # other stuff

    return instances()
Beispiel #3
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
Beispiel #4
0
def fifo_cdc(glbl, emesh_i, emesh_o):
    """
    map the packet interfaces to the FIFO interface
    """

    wr, rd = Signals(bool(0), 2)
    fifo_intf = FIFOBus(width=len(emesh_i.bits))

    @always_comb
    def beh_assign():
        wr.next = emesh_i.access and not fifo_intf.full
        rd.next = not fifo_intf.empty and not emesh_i.wait
        emesh_o.wait.next = fifo_intf.full

    @always(emesh_o.clock.posedge)
    def beh_access():
        if not emesh_i.wait:
            emesh_o.access.next = fifo_intf.read

    # assign signals ot the FIFO interface
    fifo_intf.write_data = emesh_i.bits
    fifo_intf.read_data = emesh_o.bits

    fifo_inst = cores.fifo.fifo_async(clock_write=emesh_i.clock,
                                      clock_read=emesh_o.clock,
                                      fifobus=fifo_intf,
                                      reset=glbl.reset,
                                      size=16)

    return beh_assign, beh_access, fifo_inst
Beispiel #5
0
def fifo_cdc(glbl, emesh_i, emesh_o):
    """
    map the packet interfaces to the FIFO interface
    """

    wr, rd = Signals(bool(0), 2)
    fifo_intf = FIFOBus(width=len(emesh_i.bits))

    @always_comb
    def beh_assign():
        wr.next = emesh_i.access and not fifo_intf.full
        rd.next = not fifo_intf.empty and not emesh_i.wait
        emesh_o.wait.next = fifo_intf.full

    @always(emesh_o.clock.posedge)
    def beh_access():
        if not emesh_i.wait:
            emesh_o.access.next = fifo_intf.read

    # assign signals ot the FIFO interface
    fifo_intf.write_data = emesh_i.bits
    fifo_intf.read_data = emesh_o.bits

    fifo_inst = cores.fifo.fifo_async(
        clock_write=emesh_i.clock, clock_read=emesh_o.clock,
        fifobus=fifo_intf, reset=glbl.reset, size=16
    )

    return beh_assign, beh_access, fifo_inst
Beispiel #6
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()
Beispiel #7
0
def fifo_cdc(glbl, emesh_i, emesh_o):
    """
    map the packet interfaces to the FIOF interface
    """

    fifo_intf = FIFOBus(size=16, width=len(emesh_i.bits))

    @always_comb
    def rtl_assign():
        wr.next = emesh_i.access and not fifo_intf.full
        rd.next = not fifo_intf.empty and not emesh_i.wait
        emesh_o.wait.next = fifo_intf.full

    @always(emesh_o.clock.posedge)
    def rtl_access():
        if not emesh_i.wait:
            emesh_o.access.next = fifo_intf.read

    # assign signals ot the FIFO interface
    fifo_intf.write_data = emesh_i.bits
    fifo_intf.read_data = emesh_o.bits

    g_fifo = cores.fifo.fifo_async(glbl.reset, emesh_i.clock, 
                                   emesh_o.clock, fifo_intf)

    return rtl_assign, rtl_access, g_fifo
Beispiel #8
0
def m_fifo_2clock_cascade(
    wclk,       # in:  write side clock
    datain,     # in:  write data
    src_rdy_i,  # in:  
    dst_rdy_o,  # out: 
    space,      # out: how many can be written
    
    rclk,       # in:  read side clock
    dataout,    # out: read data
    src_rdy_o,  # out: 
    dst_rdy_i,  # in:  
    occupied,   # out: number in the fifo

    reset,      # in:  system reset
):


    wr = Signal(bool(0))
    rd = Signal(bool(0))
    dataout_d = Signal(intbv(0, min=dataout.min, max=dataout.max))

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

    @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

    # the original was a chain:
    #    m_fifo_fast  (16)
    #    m_fifo_async (??)
    #    m_fifo_fast  (16)
    gfifo = fifo_async(reset, wclk, rclk, fbus)
    # @todo: calculate space and occupied based on fbus.count
        
    # @todo: the output is delayed two clock from the "read" strobe
    #   the m_fifo_async only has a delta of one (read valid strobe
    #   aligns with valid data).  Need to delay the data one more
    #   clock cycle???
    
    @always(rclk.posedge)
    def rtl_delay():
        dataout.next = dataout_d

    return rtl_assign1, rtl_assign2, gfifo, rtl_delay
Beispiel #9
0
def catboard_blinky_host(clock, led, uart_tx, uart_rx):
    """
    The LEDs are controlled from the RPi over the UART
    to the FPGA.
    """

    glbl = Global(clock, None)
    ledreg = Signal(intbv(0)[8:])

    # create the timer tick instance
    tick_inst = glbl_timer_ticks(glbl, include_seconds=True)

    # create the interfaces to the UART
    fbustx = FIFOBus(width=8, size=4)
    fbusrx = FIFOBus(width=8, size=4)
    uart_fifo = FIFOBus(width=8, size=4)

    # create the memmap (CSR) interface
    memmap = Barebone(glbl, data_width=32, address_width=32)

    # create the UART instance.
    uart_inst = uartlite(glbl, uart_fifo,
                         serial_in=uart_rx,
                         serial_out=uart_tx)
    
    #map uart_fifo to separate readpath and writepath
    assign_rw = uart_fifo.assign_read_write_paths(fbusrx,fbustx)

    # create the packet command instance
    cmd_inst = command_bridge(glbl, fbusrx, fbustx, memmap)

    @always_seq(clock.posedge, reset=None)
    def beh_led_control():
        memmap.done.next = not (memmap.write or memmap.read)
        if memmap.write and memmap.mem_addr == 0x20:
            ledreg.next = memmap.write_data

    @always_comb
    def beh_led_read():
        if memmap.read and memmap.mem_addr == 0x20:
            memmap.read_data.next = ledreg
        else:
            memmap.read_data.next = 0

    # blink one of the LEDs
    tone = Signal(intbv(0)[8:])

    @always_seq(clock.posedge, reset=None)
    def beh_assign():
        if glbl.tick_sec:
            tone.next = (~tone) & 0x1
        led.next = ledreg | tone[5:] 
            
    return (tick_inst, uart_inst, cmd_inst, assign_rw,
            beh_led_control, beh_led_read, beh_assign)
Beispiel #10
0
def test_memmap_command_bridge(args=None):
    nloops = 37
    args = tb_default_args(args)
    clock = Clock(0, frequency=50e6)
    reset = Reset(0, active=1, async=False)
    glbl = Global(clock, reset)
    fbtx, fbrx = FIFOBus(), FIFOBus()
    memmap = Barebone(glbl, data_width=32, address_width=28)

    fbtx.clock = clock
    fbrx.clock = clock

    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

    run_testbench(_bench_command_bridge, args=args)
def test_memmap_command_bridge(args=None):
    nloops = 37
    args = tb_default_args(args)
    clock = Clock(0, frequency=50e6)
    reset = Reset(0, active=1, async=False)
    glbl = Global(clock, reset)
    fbtx, fbrx = FIFOBus(), FIFOBus()
    memmap = Barebone(glbl, data_width=32, address_width=28)

    fbtx.clock = clock
    fbrx.clock = clock

    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

    run_testbench(_bench_command_bridge, args=args)
Beispiel #12
0
def catboard_blinky_host(clock, led, uart_tx, uart_rx):
    """
    The LEDs are controlled from the RPi over the UART
    to the FPGA.
    """

    glbl = Global(clock, None)
    ledreg = Signal(intbv(0)[8:])

    # create the timer tick instance
    tick_inst = glbl_timer_ticks(glbl, include_seconds=True)

    # create the interfaces to the UART
    fbustx = FIFOBus(width=8, size=4)
    fbusrx = FIFOBus(width=8, size=4)

    # create the memmap (CSR) interface
    memmap = Barebone(glbl, data_width=32, address_width=32)

    # create the UART instance.
    uart_inst = uartlite(glbl,
                         fbustx,
                         fbusrx,
                         serial_in=uart_rx,
                         serial_out=uart_tx)

    # create the packet command instance
    cmd_inst = command_bridge(glbl, fbusrx, fbustx, memmap)

    @always_seq(clock.posedge, reset=None)
    def beh_led_control():
        memmap.done.next = not (memmap.write or memmap.read)
        if memmap.write and memmap.mem_addr == 0x20:
            ledreg.next = memmap.write_data

    @always_comb
    def beh_led_read():
        if memmap.read and memmap.mem_addr == 0x20:
            memmap.read_data.next = ledreg
        else:
            memmap.read_data.next = 0

    # blink one of the LEDs
    tone = Signal(intbv(0)[8:])

    @always_seq(clock.posedge, reset=None)
    def beh_assign():
        if glbl.tick_sec:
            tone.next = (~tone) & 0x1
        led.next = ledreg | tone[5:]

    return (tick_inst, uart_inst, cmd_inst, beh_led_control, beh_led_read,
            beh_assign)
Beispiel #13
0
def testbench_uart(args=None):
    # @todo: get numbytes from args
    numbytes = 7
    clock = Clock(0, frequency=50e6)
    reset = Reset(0, active=0, async=True)
    glbl = Global(clock, reset)
    mdlsi, mdlso = Signal(bool(1)), Signal(bool(1))
    uartmdl = UARTModel()
    fifotx = FIFOBus()
    fiforx = FIFOBus()

    def _bench_uart():
        tbmdl = uartmdl.process(glbl, mdlsi, mdlso)
        tbdut = uartlite(glbl, fifotx, fiforx, mdlso, mdlsi)
        tbclk = clock.gen()

        @always_comb
        def tblpbk():
            fifotx.wdata.next = fiforx.rdata
            fifotx.wr.next = not fiforx.empty
            fiforx.rd.next = not fiforx.empty

        @instance
        def tbstim():
            yield reset.pulse(33)
            yield delay(1000)
            yield clock.posedge

            for ii in range(numbytes):
                wb = randint(0, 255)
                print("send {:02X}".format(wb))
                uartmdl.write(wb)
                timeout = ((clock.frequency / uartmdl.baudrate) * 40)
                rb = uartmdl.read()
                while rb is None and timeout > 0:
                    yield clock.posedge
                    rb = uartmdl.read()
                    timeout -= 1
                if rb is None:
                    raise TimeoutError
                print("received {:02X}".format(rb))
                assert rb == wb, "{:02X} != {:02X}".format(rb, wb)

            yield delay(100)

            raise StopSimulation

        return tbdut, tbmdl, tbclk, tblpbk, tbstim

    run_testbench(_bench_uart, args=args)
Beispiel #14
0
def icestick(clock, led, pmod, uart_tx, uart_rx):
    """ Lattice Icestick example
    """

    glbl = Global(clock, None)
    tick_inst = glbl_timer_ticks(glbl, include_seconds=True)

    # get interfaces to the UART fifos
    fbusrtx = FIFOBus(width=8)

    # get the UART comm from PC
    uart_inst = uartlite(glbl, fbusrtx, uart_tx, uart_rx)

    @always_comb
    def beh_loopback():
        fbusrtx.write_data.next = fbusrtx.read_data
        fbusrtx.write.next = (not fbusrtx.full) & fbusrtx.read

    lcnt = Signal(modbv(0, min=0, max=4))

    @always(clock.posedge)
    def beh_led_count():
        if glbl.tick_sec:
            lcnt.next = lcnt + 1
        led.next = (1 << lcnt)

    # system to test/interface

    # other stuff

    return myhdl.instances()
Beispiel #15
0
def spi_slave_led(clock, sck, mosi, miso, cs, leds ,out):
    glbl = Global(clock)
    spibus = SPIBus(sck=sck, mosi=mosi, miso=miso, ss=cs)
    fifobus = FIFOBus()
    div = divisor (clock, clk_div, 10)
    fifobus.write_clock=clock
    fifobus.read_clock=clock

    rtl = recv_to_led(clock, fifobus, leds,out)
    tbdut = spi_slave_fifo(glbl, spibus, fifobus)

    @always_comb
    def map():
        spibus.csn.next = cs

    return myhdl.instances()
Beispiel #16
0
def test_adc128s022():

    clock = Clock(0, frequency=50e6)
    reset = Reset(0, active=0, async=False)
    glbl = Global(clock, reset)
    fifobus = FIFOBus(width=16)
    spibus = SPIBus()
    channel = Signal(intbv(0, min=0, max=8))
    step = 3.3 / 7
    analog_channels = [Signal(3.3 - step * ii) for ii in range(0, 8)]
    print(analog_channels)
    assert len(analog_channels) == 8

    def check_empty(clock, fifo):
        for ii in range(4000):
            if not fifo.empty:
                break
            yield clock.posedge

    @myhdl.block
    def bench_adc128s022():
        tbdut = adc128s022(glbl, fifobus, spibus, channel)
        tbmdl = adc128s022_model(spibus,
                                 analog_channels,
                                 vref_pos=3.3,
                                 vref_neg=0.)
        tbclk = clock.gen()

        @instance
        def tbstim():
            sample = intbv(0)[16:]
            yield reset.pulse(33)
            yield clock.posedge

            # check the conversion value for each channel, should  get
            # smaller and smaller
            for ch in range(0, 8):
                channel.next = (ch + 1) % 8  # next channel
                yield check_empty(clock, fifobus)
                # should have a new sample
                if not fifobus.empty:
                    fifobus.read.next = True
                    sample[:] = fifobus.read_data
                    yield clock.posedge
                    fifobus.read.next = False
                    yield clock.posedge
                    print("sample {:1X}:{:4d}, fifobus {} \n".format(
                        int(sample[16:12]), int(sample[12:0]), str(fifobus)))
                    assert fifobus.empty
                else:
                    print("No sample!")

            yield delay(100)
            raise StopSimulation

        return tbdut, tbmdl, tbclk, tbstim

    run_testbench(bench_adc128s022)
Beispiel #17
0
def test_spi_slave(args=None):
    args = tb_default_args(args)
    clock = Clock(0, frequency=50e6)
    reset = Reset(0, active=1, async=False)
    glbl = Global(clock, reset)
    spibus, fifobus = SPIBus(), FIFOBus()

    # monitor the FIFOBus signals
    data = Signal(intbv(0)[8:])
    rd, wr, full, empty = Signals(bool(0), 4)

    @myhdl.block
    def bench_spi_slave():
        tbdut = spi_slave_fifo(glbl, spibus, fifobus)
        tbclk = clock.gen()

        @instance
        def tbstim():
            yield reset.pulse(40)
            yield delay(1000)
            yield clock.posedge

            # @todo: make generic
            # @todo: random_sequence = [randint(0, fifobus.write_data.max) for _ in range(ntx)]
            yield spibus.writeread(0x55)
            yield spibus.writeread(0xAA)
            yield spibus.writeread(0xCE)
            assert spibus.get_read_data() == 0x55
            yield spibus.writeread(0x01)
            assert spibus.get_read_data() == 0xAA
            yield spibus.writeread(0x01)
            assert spibus.get_read_data() == 0xCE

            raise StopSimulation

        @always_comb
        def tb_fifo_loopback():
            if not fifobus.full:
                fifobus.write.next = not fifobus.empty
                fifobus.read.next = not fifobus.empty
            fifobus.write_data.next = fifobus.read_data

        # monitors
        @always_comb
        def tbmon():
            data.next = fifobus.read_data
            rd.next = fifobus.read
            wr.next = fifobus.write
            full.next = fifobus.full
            empty.next = fifobus.empty

        return tbdut, tbclk, tbstim, tb_fifo_loopback, tbmon

    run_testbench(bench_spi_slave, args=args)
Beispiel #18
0
def spi_slave_pulsegen(clock, sck, mosi, miso, cs, leds, out):
    clk_div = Signal(False)
    clk_pulse = Signal(False)
    glbl = Global(clock)
    spibus = SPIBus(sck=sck, mosi=mosi, miso=miso, ss=cs)
    fifobus = FIFOBus()
    fifobus.write_clock = clock
    fifobus.read_clock = clock
    div = divisor(clock, clk_div, 1)
    divp = divisor(clock, clk_pulse, 1)

    rtl = recv_to_plsgen(clk_div, clk_pulse, fifobus, leds, out)
    #rtl = recv_to_led(clk_div, fifobus, leds)

    tbdut = spi_slave_fifo_async(glbl, spibus, fifobus)

    @always_comb
    def map():
        spibus.csn.next = cs

    return myhdl.instances()
Beispiel #19
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
Beispiel #20
0
def fifo_2clock_cascade(
    wclk,       # in:  write side clock
    datain,     # in:  write data
    src_rdy_i,  # in:  
    dst_rdy_o,  # out: 
    space,      # out: how many can be written
    
    rclk,       # in:  read side clock
    dataout,    # out: read data
    src_rdy_o,  # out: 
    dst_rdy_i,  # in:  
    occupied,   # out: number in the fifo

    reset,      # in:  system reset
):
    """ """
    wr = Signal(bool(0))
    rd = Signal(bool(0))
    dataout_d = Signal(intbv(0, min=dataout.min, max=dataout.max))

    args = Namespace(width=36, size=128, name='fifo_2clock_cascade')
    fbus = FIFOBus(width=args.width)
    # need to update the fbus references 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_d

    @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

    # the original was a chain:
    #    fifo_fast  (16)
    #    fifo_async (??)
    #    fifo_fast  (16)
    fifo_inst = fifo_async(wclk, rclk, fbus, reset=reset, size=args.size)

    # @todo: calculate space and occupied based on fbus.count
        
    # @todo: the output is delayed two clock from the "read" strobe
    #   the m_fifo_async only has a delta of one (read valid strobe
    #   aligns with valid data).  Need to delay the data one more
    #   clock cycle???
    
    @always(rclk.posedge)
    def beh_delay():
        dataout.next = dataout_d

    return myhdl.instances()
Beispiel #21
0
    def bench_doublebuffer_conversion():
        """test bench for conversion"""

        clock = Signal(bool(0))
        reset = ResetSignal(0, active=1, async=True)

        buffer_sel = Signal(bool(0))

        width_data = 20
        width_depth = 64
        # instantiation of fifo-bus, clock and rledoublefifo
        dfifo_bus = FIFOBus(width=width_data)

        inst = doublefifo(clock,
                          reset,
                          dfifo_bus,
                          buffer_sel,
                          depth=width_depth)

        inst_clock = clock_driver(clock)
        inst_reset = reset_on_start(reset, clock)

        @instance
        def tbstim():
            """some tests for conversion purpose"""

            # select first buffer
            buffer_sel.next = False
            yield clock.posedge

            # write first data into double buffer
            dfifo_bus.write.next = True

            # convert signed number to unsigned
            dfifo_bus.write_data.next = 3
            yield clock.posedge
            dfifo_bus.write.next = False
            yield clock.posedge
            assert dfifo_bus.empty

            yield clock.posedge
            print("Conversion done!!")
            raise StopSimulation

        return tbstim, inst, inst_clock, inst_reset
Beispiel #22
0
def spi_controller_top(clock, reset, sck, mosi, miso, ss):
    """SPI top-level for conversion testing"""
    glbl = Global(clock, reset)
    spibus = SPIBus(sck, mosi, miso, ss)
    fifobus = FIFOBus()

    cso = spi_controller.cso()
    cso.isstatic = True
    cfg_inst = cso.instances()

    spi_controller.debug = False
    spi_inst = spi_controller(glbl, spibus, fifobus, cso=cso)

    @always_comb
    def fifo_loopback():
        fifobus.write_data.next = fifobus.read_data
        fifobus.write.next = fifobus.read_valid
        fifobus.read.next = not fifobus.empty

    return myhdl.instances()
Beispiel #23
0
def test_(args=None):

    if args is None:
        args = Namespace(width=8, size=16, name='test')

    reset = ResetSignal(0, active=1, async=True)
    wclk = Clock(0, frequency=22e6)
    rclk = Clock(0, frequency=50e6)
    fbus = FIFOBus(width=args.width)
    start = Signal(bool(0))

    @myhdl.block
    def bench_():
        tbclkw = wclk.gen()
        tbclkr = rclk.gen()
        tbdut = fifo_async(wclk, rclk, fbus, reset)
        tbpr = procuder_consumer(wclk, rclk, fbus, start)

        @instance
        def tbstim():
            print("start test 2")
            fbus.write_data.next = 0xFE
            reset.next = reset.active
            yield delay(3 * 33)
            reset.next = not reset.active

            yield delay(44)
            start.next = True

            for ii in range(2048):
                yield delay(100)

            raise StopSimulation

        return myhdl.instances()

    run_testbench(bench_)
Beispiel #24
0
def atlys_blinky_host(clock, reset, led, sw, pmod, uart_tx, uart_rx):
    """
    This example is similar to the other examples in this directory but
    the LEDs are controlled externally via command packets sent from a
    host via the UART on the icestick.

    """
    glbl = Global(clock, reset)
    ledreg = Signal(intbv(0)[8:])

    # create the timer tick instance
    tick_inst = glbl_timer_ticks(glbl, include_seconds=True)

    # create the interfaces to the UART
    fbustx = FIFOBus(width=8, size=32)
    fbusrx = FIFOBus(width=8, size=32)

    # create the memmap (CSR) interface
    memmap = Barebone(glbl, data_width=32, address_width=32)

    # create the UART instance.
    cmd_tx = Signal(bool(0))
    uart_inst = uartlite(glbl, fbustx, fbusrx, uart_rx, cmd_tx)

    # create the packet command instance
    cmd_inst = memmap_command_bridge(glbl, fbusrx, fbustx, memmap)

    @always_seq(clock.posedge, reset=reset)
    def beh_led_control():
        memmap.done.next = not (memmap.write or memmap.read)
        if memmap.write:  # and memmap.mem_addr == 0x20:
            ledreg.next = memmap.write_data

    @always_comb
    def beh_led_read():
        if memmap.read and memmap.mem_addr == 0x20:
            memmap.read_data.next = ledreg
        else:
            memmap.read_data.next = 0

    # blink one of the LEDs
    status = [Signal(bool(0)) for _ in range(8)]
    statusbv = ConcatSignal(*reversed(status))

    @always_seq(clock.posedge, reset=reset)
    def beh_assign():
        # status / debug signals
        if glbl.tick_sec:
            status[0].next = not status[0]
        status[1].next = memmap.mem_addr == 0x20
        status[2].next = uart_rx
        status[3].next = uart_tx
        led.next = ledreg | statusbv | sw

        pmod.next = 0

        if sw[0]:
            uart_tx.next = uart_rx
        else:
            uart_tx.next = cmd_tx

    # @todo: PMOD OLED memmap control

    return (tick_inst, uart_inst, cmd_inst, beh_led_control, beh_led_read,
            beh_assign)
Beispiel #25
0
def icestick_blinky_host(clock, led, pmod, uart_tx, uart_rx,
                         uart_dtr, uart_rts):
    """
    This example is similar to the other examples in this directory but
    the LEDs are controlled externally via command packets sent from a
    host via the UART on the icestick.

    Ports:
      clock:
      led:
      pmod:
      uart_tx:
      uart_rx:
    """

    glbl = Global(clock, None)
    ledreg = Signal(intbv(0)[8:])

    # create the timer tick instance
    tick_inst = glbl_timer_ticks(glbl, include_seconds=True)

    # create the interfaces to the UART
    fbustx = FIFOBus(width=8, size=4)
    fbusrx = FIFOBus(width=8, size=4)
    uart_fifo = FIFOBus(width=8, size=4)

    # create the memmap (CSR) interface
    memmap = Barebone(glbl, data_width=32, address_width=32)

    # create the UART instance.
    uart_inst = uartlite(glbl, uart_fifo, uart_rx, uart_tx)
    
    #map uart_fifo to separate readpath and writepath
    assign_rw = uart_fifo.assign_read_write_paths(fbusrx,fbustx)
        
    # create the packet command instance
    cmd_inst = command_bridge(glbl, fbusrx, fbustx, memmap)

    @always_seq(clock.posedge, reset=None)
    def beh_led_control():
        memmap.done.next = not (memmap.write or memmap.read)
        if memmap.write and memmap.mem_addr == 0x20:
            ledreg.next = memmap.write_data

    @always_comb
    def beh_led_read():
        if memmap.read and memmap.mem_addr == 0x20:
            memmap.read_data.next = ledreg
        else:
            memmap.read_data.next = 0

    # blink one of the LEDs
    tone = Signal(intbv(0)[8:])

    @always_seq(clock.posedge, reset=None)
    def beh_assign():
        if glbl.tick_sec:
            tone.next = (~tone) & 0x1
        led.next = ledreg | tone[5:] 
            
        pmod.next = 0

    # @todo: PMOD OLED memmap control

    return (tick_inst, uart_inst, assign_rw, cmd_inst, 
            beh_led_control, beh_led_read, beh_assign)
def test_memmap_command_bridge(args=None):
    nloops = 37
    args = tb_default_args(args)
    clock = Clock(0, frequency=50e6)
    reset = Reset(0, active=1, async=False)
    glbl = Global(clock, reset)
    fifobus = FIFOBus()
    memmap = Barebone(glbl, data_width=32, address_width=28)

    fifobus.clock = clock

    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

    run_testbench(bench_command_bridge, args=args)
Beispiel #27
0
def test_fifo_sync(args=None):
    """ verify the synchronous FIFO
    """

    if args is None:
        args = Namespace(width=8, size=16, name='test')
    else:
        # @todo: verify args has the attributes needed for the FIFOBus
        pass

    reset = ResetSignal(0, active=1, async=True)
    clock = Signal(bool(0))
    fbus = FIFOBus(width=args.width, size=args.size)

    def bench_fifo_sync():

        # @todo: use args.fast, args.use_srl_prim
        tbdut = fifo_sync(clock, reset, fbus)

        @always(delay(10))
        def tbclk():
            clock.next = not clock

        @instance
        def tbstim():
            fbus.write_data.next = 0xFE
            reset.next = reset.active
            yield delay(33)
            reset.next = not reset.active
            for ii in range(5):
                yield clock.posedge

            # test the normal cases
            for num_bytes in range(1, args.size + 1):

                # write some bytes
                for ii in range(num_bytes):
                    yield clock.posedge
                    fbus.write_data.next = ii
                    fbus.write.next = True

                yield clock.posedge
                fbus.write.next = False
                fbus.write_data.next = 0xFE

                # if 16 bytes written make sure FIFO is full
                yield clock.posedge
                if num_bytes == args.size:
                    assert fbus.full, "FIFO should be full!"
                    assert not fbus.empty, "FIFO should not be empty"

                fbus.read.next = True
                yield clock.posedge
                for ii in range(num_bytes):
                    yield clock.posedge
                    fbus.read.next = True
                    assert fbus.read_valid
                    assert fbus.read_data == ii, "rdata %x ii %x " % (
                        fbus.read_data, ii)

                fbus.read.next = False
                yield clock.posedge
                assert fbus.empty

            # Test overflows
            # Test underflows
            # Test write / read same time

            raise StopSimulation

        return tbdut, tbclk, tbstim

    run_testbench(bench_fifo_sync)
Beispiel #28
0
    def bench():
        reset = ResetSignal(0, active=1, async=True)
        clock = Signal(bool(0))
        fbus = FIFOBus(width=args.width, size=args.size)

        tbdut = fifo_sync(clock, reset, fbus)

        @instance
        def tbclk():
            clock.next = False
            while True:
                yield delay(5)
                clock.next = not clock

        @instance
        def tbstim():
            print("start simulation")
            fbus.read.next = False
            fbus.write.next = False
            fbus.clear.next = False
            reset.next = True
            yield delay(20)
            reset.next = False
            yield clock.posedge

            print("r, w, e, f")
            print("%d, %d, %d, %d, should be empty" % (
                fbus.read,
                fbus.write,
                fbus.empty,
                fbus.full,
            ))
            assert fbus.empty

            fbus.write.next = True
            fbus.write_data.next = 0xAA
            yield clock.posedge
            fbus.write.next = False
            yield clock.posedge
            print("%d, %d, %d, %d, should not be empty" % (
                fbus.read,
                fbus.write,
                fbus.empty,
                fbus.full,
            ))
            assert not fbus.empty
            print("FIFO count %d  (%d%d%d%d)" %
                  (fbus.count, fbus.read, fbus.write, fbus.empty, fbus.full))

            print("more writes")
            fbus.write.next = True
            fbus.write_data.next = 1
            for ii in range(15):
                yield clock.posedge
                print(
                    "FIFO count %d  (%d%d%d%d)" %
                    (fbus.count, fbus.read, fbus.write, fbus.empty, fbus.full))
                fbus.write_data.next = ii + 2
            fbus.write.next = False
            yield clock.posedge
            print("FIFO count %d  (%d%d%d%d)" %
                  (fbus.count, fbus.read, fbus.write, fbus.empty, fbus.full))
            yield clock.posedge
            print("%d, %d, %d, %d, should be full" % (
                fbus.read,
                fbus.write,
                fbus.empty,
                fbus.full,
            ))
            # assert fbus.full

            fbus.read.next = True
            assert fbus.read_data == 0xAA
            yield fbus.read_valid.posedge
            fbus.read.next = False
            yield delay(1)
            print("%d, %d, %d, %d" % (
                fbus.read,
                fbus.write,
                fbus.empty,
                fbus.full,
            ))
            yield clock.posedge
            yield clock.posedge

            fbus.read.next = True
            for ii in range(15):
                print("FIFO count %d  data %d (%d%d%d%d)" %
                      (fbus.count, fbus.read_data, fbus.read, fbus.write,
                       fbus.empty, fbus.full))
                yield clock.posedge

            fbus.read.next = False
            yield clock.posedge
            print("%d, %d, %d, %d" % (
                fbus.read,
                fbus.write,
                fbus.empty,
                fbus.full,
            ))

            print("end simulation")
            raise StopSimulation

        return tbdut, tbclk, tbstim
Beispiel #29
0
def test_spi_controller_cso(args=None):
    args = tb_default_args(args)

    clock = Clock(0, frequency=50e6)
    reset = Reset(0, active=1, isasync=False)
    glbl = Global(clock, reset)
    spibus = SPIBus()

    # a FIFOBus to push-pull data from the SPI controller
    fifobus = FIFOBus(width=8)
    # control-status object for the SPI controller
    cso = spi_controller.cso()

    spiee = SPIEEPROM()
    asserr = Signal(bool(0))

    @myhdl.block
    def bench_spi_cso():
        spi_controller.debug = True  # enable debug monitors
        tbdut = spi_controller(glbl, spibus, fifobus, cso=cso)
        tbeep = spiee.process(clock, reset, spibus)
        tbclk = clock.gen(hticks=5)

        @instance
        def tbstim():
            yield reset.pulse(33)
            yield delay(100)
            yield clock.posedge

            try:
                # enable the SPI core
                cso.enable.next = True
                cso.bypass_fifo.next = True
                cso.loopback.next = True

                # write to the transmit FIFO
                values = (0x02, 0x00, 0x00, 0x00, 0x55)
                for data in values:
                    cso.tx_byte.next = data
                    cso.tx_write.next = True
                    yield clock.posedge
                cso.tx_write.next = False

                while cso.tx_fifo_count > 0:
                    yield delay(100)

                while cso.rx_fifo_count < 5:
                    yield delay(100)

                ii, nticks = 0, 0
                while ii < len(values):
                    if cso.rx_empty:
                        cso.rx_read.next = False
                    else:
                        cso.rx_read.next = True
                    if cso.rx_byte_valid:
                        assert values[ii] == cso.rx_byte, \
                            "{:<4d}: data mismatch, {:02X} != {:02X}".format(
                                ii, int(values[ii]), int(cso.rx_byte))
                        ii += 1
                        nticks = 0
                    yield clock.posedge, cso.rx_empty.posedge
                    cso.rx_read.next = False

                    if nticks > 30:
                        raise TimeoutError
                    nticks += 1

                cso.rx_read.next = False
                yield clock.posedge

            except AssertionError as err:
                asserr.next = True
                print("@E: assertion {}".format(err))
                yield delay(100)
                traceback.print_exc()
                raise err

            raise StopSimulation

        # monitor signals for debugging
        tx_write, rx_read = Signals(bool(0), 2)

        @always_comb
        def tbmon():
            rx_read.next = cso.rx_read
            tx_write.next = cso.tx_write

        return tbdut, tbeep, tbclk, tbstim, tbmon

    run_testbench(bench_spi_cso, args=args)
Beispiel #30
0
def de0nano_converters(
        clock,
        reset,
        led,
        # ADC signals
        adc_cs_n,
        adc_saddr,
        adc_sdat,
        adc_sclk,
        # Accelerometer and I2C signals
        i2c_sclk,
        i2c_sdat,
        g_sensor_cs_n,
        g_sensor_int,
        # LT24 LCD display signals
        lcd_on,
        lcd_resetn,
        lcd_csn,
        lcd_rs,
        lcd_wrn,
        lcd_rdn,
        lcd_data):
    """    
    The port names are the same as those in the board definition
    (names in the user manual) for automatic mapping by the 
    rhea.build automation.
    """
    # signals and interfaces
    glbl = Global(clock, reset)
    adcbus = SPIBus()
    adcbus.mosi, adcbus.miso, adcbus.csn, adcbus.sck = (adc_saddr, adc_sdat,
                                                        adc_cs_n, adc_sclk)
    fifobus = FIFOBus(width=16, size=16)
    channel = Signal(intbv(0, min=0, max=8))

    # ----------------------------------------------------------------
    # global ticks
    gtick = glbl_timer_ticks(glbl, include_seconds=True, user_timer=16)

    # ----------------------------------------------------------------
    # instantiate the ADC controller (retieves samples)
    gconv = adc128s022(glbl, fifobus, adcbus, channel)

    # read the samples out of the FIFO interface
    fiford = Signal(bool(0))

    @always(clock.posedge)
    def rtl_read():
        fiford = not fifobus.empty

    @always_comb
    def rtl_read_gate():
        fifobus.rd.next = fiford and not fifobus.empty

    # for now assign the samples to the  LEDs for viewing
    heartbeat = Signal(bool(0))

    @always_seq(clock.posedge, reset=reset)
    def rtl_leds():
        if glbl.tick_sec:
            heartbeat.next = not heartbeat
        led.next = concat(fifobus.rdata[12:5], heartbeat)

    # ----------------------------------------------------------------
    # LCD dislay
    lcd = LT24Interface()
    resolution, color_depth = lcd.resolution, lcd.color_depth
    lcd.assign(lcd_on, lcd_resetn, lcd_csn, lcd_rs, lcd_wrn, lcd_rdn, lcd_data)
    # color bars and the interface between video source-n-sink
    vmem = VideoMemory(resolution=resolution, color_depth=color_depth)
    gbar = color_bars(glbl,
                      vmem,
                      resolution=resolution,
                      color_depth=color_depth)
    # LCD video driver
    glcd = lt24lcd(glbl, vmem, lcd)

    gens = gtick, gconv, rtl_read, rtl_leds, gbar, glcd

    return gens
Beispiel #31
0
def test_spi_memory_mapped(args=None):
    args = tb_default_args(args)

    base_address = ba = 0x400
    clock = Clock(0, frequency=50e6)
    reset = Reset(0, active=1, isasync=False)
    glbl = Global(clock, reset)
    regbus = Wishbone(glbl)
    fifobus = FIFOBus(size=16)
    spiee = SPIEEPROM()
    spibus = SPIBus()
    asserr = Signal(bool(0))

    @myhdl.block
    def bench_spi():
        tbdut = spi_controller(glbl, spibus, fifobus=fifobus, mmbus=regbus)
        tbeep = spiee.gen(clock, reset, spibus)
        tbclk = clock.gen(hticks=5)
        # grab all the register file outputs
        tbmap = regbus.interconnect()

        # get a reference to the SPI register file
        rf = regbus.regfiles['SPI_000']
        # dumpy the registers for the SPI peripheral
        print("SPI register file")
        for name, reg in rf.registers.items():
            print("  {0} {1:04X} {2:04X}".format(name, reg.addr, int(reg)))
        print("")

        @instance
        def tbstim():
            yield reset.pulse(33)
            yield delay(100)
            yield clock.posedge

            try:
                # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                # loop through the registers and check the default
                # values, these are the offset values.
                for addr, sig in rf.roregs:
                    yield regbus.readtrans(addr + ba)
                    assert regbus.get_read_data() == int(sig), \
                        "Invalid read-only value"

                for addr, sig in rf.rwregs:
                    # need to skip the FIFO read / write
                    if addr in (
                            rf.sptx.addr,
                            rf.sprx.addr,
                    ):
                        pass
                    else:
                        yield regbus.readtrans(addr + ba)
                        assert regbus.get_read_data() == int(sig), \
                            "Invalid default value"

                # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                # enable the system
                print("enable the SPI core")
                yield regbus.writetrans(rf.spst.addr,
                                        0x02)  # register data drives fifo
                yield regbus.writetrans(rf.spcr.addr,
                                        0x9A)  # default plus enable (98 + 02)

                print("write to the transmit register")
                for data in (0x02, 0x00, 0x00, 0x00, 0x55):
                    print("\nwriting to sptx {:02x}".format(data))
                    yield regbus.writetrans(rf.sptx.addr, data)

                print("")
                yield regbus.readtrans(rf.sptc.addr)
                print("TX FIFO count {}".format(regbus.get_read_data()))

                yield regbus.readtrans(rf.sprc.addr)
                print("RX FIFO count {}".format(regbus.get_read_data()))

                yield delay(1000)

                print("wait for return bytes")
                for ii in range(1000):
                    yield regbus.readtrans(rf.sprc.addr)
                    if regbus.get_read_data() == 5:
                        break
                    yield delay(10)

                # verify bytes received and not timeout
                print("RX FIFO count {}".format(regbus.get_read_data()))
                assert regbus.get_read_data() == 5

                print("read the returned bytes")
                for ii in range(5):
                    yield regbus.readtrans(rf.sprx.addr)
                    print("spi readback {0}".format(regbus.get_read_data()))

            except Exception as err:
                print("@W: exception {0}".format(err))
                yield delay(100)
                traceback.print_exc()
                raise err

            yield delay(100)
            raise StopSimulation

        return tbstim, tbdut, tbeep, tbclk, tbmap

    run_testbench(bench_spi, args=args)
Beispiel #32
0
from rhea.models.spi import SPIEEPROM

from rhea.system import Global, Clock, Reset, Signals
from rhea.system import Wishbone
from rhea.system import FIFOBus

from rhea.utils.test import run_testbench, tb_convert, tb_args, tb_default_args

# global signals used by many
clock = Clock(0, frequency=100e6)
reset = Reset(0, active=1, isasync=True)
glbl = Global(clock, reset)
portmap = dict(glbl=glbl,
               spibus=SPIBus(),
               fifobus=FIFOBus(),
               cso=spi_controller.cso())


@myhdl.block
def spi_controller_top(clock, reset, sck, mosi, miso, ss):
    """SPI top-level for conversion testing"""
    glbl = Global(clock, reset)
    spibus = SPIBus(sck, mosi, miso, ss)
    fifobus = FIFOBus()

    cso = spi_controller.cso()
    cso.isstatic = True
    cfg_inst = cso.instances()

    spi_controller.debug = False
Beispiel #33
0
def uart_blinky(clock, led, uart_tx, uart_rx):
    """
    Uses UART module to control LEDs while blinking the first LED.
    LEDs used are pins 0-7 on wing A.
    Expected behavior after upload is that LED[0] blinks on/off.
    When sending 
    0xDE 0x02 0x00 0x00 0x00 0x20 0x04 0xCA 0x00 0x00 0x00 0xFF
    via serial connection, all LEDs should turn on.
    For details about the message format see
    /rhea/cores/memmap/command_bridge.py
    """
    reset = ResetSignal(0, active=0, async=True)

    glbl = Global(clock, reset)
    ledreg = Signal(intbv(0)[8:])

    # create the timer tick instance
    tick_inst = glbl_timer_ticks(glbl, include_seconds=True)

    # create the interfaces to the UART
    fifobus = FIFOBus(width=8)

    # create the memmap (CSR) interface
    memmap = Barebone(glbl, data_width=32, address_width=32)

    # create the UART instance.
    uart_inst = uartlite(glbl,
                         fifobus,
                         serial_in=uart_rx,
                         serial_out=uart_tx,
                         fifosize=4)

    # create the packet command instance
    cmd_inst = command_bridge(glbl, fifobus, memmap)

    @always_seq(clock.posedge, reset=reset)
    def beh_led_control():
        memmap.done.next = not (memmap.write or memmap.read)
        if memmap.write and memmap.mem_addr == 0x20:
            ledreg.next = memmap.write_data

    @always_comb
    def beh_led_read():
        if memmap.read and memmap.mem_addr == 0x20:
            memmap.read_data.next = ledreg
        else:
            memmap.read_data.next = 0

    # blink one of the LEDs
    tone = Signal(intbv(0)[8:])
    reset_dly_cnt = Signal(intbv(0)[5:])

    @always_seq(clock.posedge, reset=None)
    def beh_assign():
        if glbl.tick_sec:
            tone.next = (~tone) & 0x1
        led.next = ledreg | tone[5:]

    @always(clock.posedge)
    def reset_tst():
        '''
        For the first 4 clocks the reset is forced to lo
        for clock 6 to 31 the reset is set hi
        then the reset is lo
        '''
        if (reset_dly_cnt < 31):
            reset_dly_cnt.next = reset_dly_cnt + 1
            if (reset_dly_cnt <= 4):
                reset.next = 1
            if (reset_dly_cnt >= 5):
                reset.next = 0
        else:
            reset.next = 1

    return (tick_inst, cmd_inst, uart_inst, beh_led_control, beh_led_read,
            beh_assign, reset_tst)
Beispiel #34
0
def test_async_fifo(args=None):
    """ verify the asynchronous FIFO    
    """
    if args is None:
        args = Namespace(width=8, size=16, name='test')

    reset = ResetSignal(0, active=1, async=True)
    wclk = Clock(0, frequency=22e6)
    rclk = Clock(0, frequency=50e6)
    fbus = FIFOBus(width=args.width)
    start = Signal(bool(0))

    @myhdl.block
    def bench_async_fifo():

        tbclkw = wclk.gen()
        tbclkr = rclk.gen()
        tbdut = fifo_async(wclk, rclk, fbus, reset)
        tbpr = procuder_consumer(wclk, rclk, fbus, start)

        @instance
        def tbstim():
            print("start test 1")
            fbus.write_data.next = 0xFE
            reset.next = reset.active
            yield delay(3 * 33)
            reset.next = not reset.active

            # reset is delayed by at least two
            for ii in range(5):
                yield wclk.posedge

            # test normal cases
            for num_bytes in range(1, args.size + 1):

                # Write some byte
                for ii in range(num_bytes):
                    yield wclk.posedge
                    fbus.write_data.next = ii
                    fbus.write.next = True

                yield wclk.posedge
                fbus.write.next = False

                # If 16 bytes written make sure FIFO is full
                yield wclk.posedge
                if num_bytes == args.size:
                    assert fbus.full, "FIFO should be full!"

                while fbus.empty:
                    yield rclk.posedge

                fbus.read.next = True
                yield rclk.posedge
                for ii in range(num_bytes):
                    yield rclk.posedge
                    fbus.read.next = True
                    assert fbus.read_valid
                    assert fbus.read_data == ii, "rdata %x ii %x " % (
                        fbus.read_data, ii)

                yield rclk.posedge
                fbus.read.next = False
                yield rclk.posedge
                assert fbus.empty

            raise StopSimulation

        return myhdl.instances()
Beispiel #35
0
def bench_conversion_fifo_async():
    args = Namespace(width=8, size=32, fifosize=64, name='test')

    clock_write, clock_read = Signals(bool(0), 2)
    reset = ResetSignal(0, active=1, async=False)

    fbus = FIFOBus(width=args.width)
    fifosize = args.fifosize
    tbdut = fifo_async(clock_write, clock_read, fbus, reset, size=fifosize)

    @instance
    def tbclkr():
        clock_read.next = False
        while True:
            yield delay(5)
            clock_read.next = not clock_read

    @instance
    def tbclkw():
        clock_write.next = False
        while True:
            yield delay(5)
            clock_write.next = not clock_write

    @instance
    def tbstim():
        print("start simulation")
        fbus.write.next = False
        fbus.write_data.next = 0
        fbus.read.next = False
        fbus.clear.next = False

        print("reset")
        reset.next = reset.active
        yield delay(10)
        reset.next = not reset.active
        yield delay(10)

        print("some clock cycles")
        for ii in range(10):
            yield clock_write.posedge

        print("some writes")
        for ii in range(fifosize):
            fbus.write.next = True
            fbus.write_data.next = ii
            yield clock_write.posedge
        fbus.write.next = False
        yield clock_write.posedge

        for ii in range(fifosize):
            fbus.read.next = True
            yield clock_read.posedge
            print("%d %d %d %d" % (
                fbus.write,
                fbus.write_data,
                fbus.read,
                fbus.read_data,
            ))
        fbus.read.next = False

        print("end simulation")
        raise StopSimulation

    return myhdl.instances()
Beispiel #36
0
def uartlite(glbl, fifobus, serial_in, serial_out, baudrate=115200):
    """ The top-level for a minimal fixed baud UART

    The function instantiates the various components required for
    the UART. Uses an external FIFOBus interface to communicate 
    with other modules(provide the r/w stobe, data etc.).

    Arguments(Ports):
        glbl: rhea.Global interface, clock and reset from glbl
        fbustx: The transmit FIFO bus, interface to the TX FIFO (see fifo_fast.py)
        tbusrx: The receive FIFObus, interface to the RX FIFO
        serial_in: The UART external serial line in
        serial_out: The UART external serial line out

    Parameters:
        baudrate: the desired baudrate for the UART

    Returns:
        myhdl generators
          : syncs of external r/w line to the internal r/t
          : The actual TX and RX FIFOs
          : baud strobe instantiation
          : uart tx and rx generators
          : map internal FIFOBus to external user FIFOBus

    This module is myhdl convertible
    """
    clock, reset = glbl.clock, glbl.reset
    baudce, baudce16 = [Signal(bool(0)) for _ in range(2)]
    tx, rx = Signal(bool(1)), Signal(bool(1))

    # the FIFO interfaces for each FIFO path
    fbustx = FIFOBus(fifobus.size, fifobus.width)
    fbusrx = FIFOBus(fifobus.size, fifobus.width)

    # create synchronizers for the input signals, the output
    # are not needed, guarantee IO registers
    syncrx_inst = syncro(clock, serial_in, rx)
    synctx_inst = syncro(clock, tx, serial_out)

    # FIFOs for tx and rx
    fifo_tx_inst = fifo_fast(reset, clock, fbustx)
    fifo_rx_inst = fifo_fast(reset, clock, fbusrx)

    # generate a strobe for the desired baud rate
    baud_inst = uartbaud(glbl, baudce, baudce16, baudrate=baudrate)

    # instantiate the UART paths
    tx_inst = uarttx(glbl, fbustx, tx, baudce)
    rx_inst = uartrx(glbl, fbusrx, rx, baudce16)

    # separate the general fifobus into two for transmitting and receiving

    @always_comb
    def assign_read():
        """Map external UART FIFOBus interface to internal
        Map the external UART FIFOBus interface attribute signals to
        internal RX FIFO interface.
        """
        # fifobus.read_data is the channel that the UART
        # reads data on and fifobus.write_data is the one
        # it writes to.
        # read into the fifobus from the RX fifo queue
        # whenever available by checking the queue
        fbusrx.read.next = fifobus.read
        fifobus.empty.next = fbusrx.empty
        fifobus.read_data.next = fbusrx.read_data
        fifobus.read_valid.next = fbusrx.read_valid

    @always_comb
    def assign_write():
        """Map external UART FIFOBus interface to internal
        Map external UART FIFOBus interface attribute signals to
        internal TX FIFO interface.
        """
        # queue to TX fifo whenever given ext. strobe
        # which will auto. be transferred by uarttx()
        fbustx.write.next = fifobus.write & (not fbustx.full)
        fbustx.write_data.next = fifobus.write_data
        fifobus.full.next = fbustx.full

    return myhdl.instances()
Beispiel #37
0
        nvacant = Signal(modbv(nitems, min=0, max=nitems))
        ntenant = Signal(modbv(0, min=0, max=nitems))

    if fifo_fast.debug:

        @always_seq(clock.posedge, reset=reset)
        def rtl_occupancy():
            if fbus.clear:
                nvacant.next = nitems
                ntenant.next = 0
            elif fbus.read and not fbus.write:
                nvacant.next = nvacant + 1
                ntenant.next = ntenant - 1
            elif fbus.write and not fbus.read:
                nvacant.next = nvacant - 1
                ntenant.next = ntenant + 1

    @always_comb
    def rtl_count():
        fbus.count.next = ntenant

    return myhdl.instances()


# fifo_fast block attributes, these will affect all instances
fifo_fast.portmap = dict(reset=ResetSignal(0, active=1, async=False),
                         clock=Signal(bool(0)),
                         fbus=FIFOBus())
fifo_fast.debug = True
fifo_fast.occupancy_assertions = True
Beispiel #38
0
def doublefifo(clock, reset, dfifo_bus, buffer_sel, depth=16):
    """
    I/O ports:

    dfifo_bus : A FIFOBus connection interace
    buffer_sel : select a buffer

    Constants :

    depth : depth of the fifo used
    width_data : width of the data to be stored in FIFO

    """

    # width of the input data
    width_data = len(dfifo_bus.write_data)

    # input to both the FIFO's
    fifo_data_in = Signal(intbv(0)[width_data:])

    # FIFOBus instantiation from rhea
    glbl = Global(clock, reset)
    fbus1 = FIFOBus(width=width_data)
    fbus2 = FIFOBus(width=width_data)

    assert isinstance(glbl, Global)
    assert isinstance(fbus1, FIFOBus)
    assert isinstance(fbus2, FIFOBus)

    # instantiate two sync FIFO's
    fifo_sync1 = fifo_sync(glbl, fbus1, depth)
    fifo_sync2 = fifo_sync(glbl, fbus2, depth)

    @always_comb
    def assign():
        """write data into FIFO's"""

        fbus1.write_data.next = fifo_data_in
        fbus2.write_data.next = fifo_data_in

    @always_seq(clock.posedge, reset=reset)
    def mux2_logic():
        """select buffer to pump data"""

        if not buffer_sel:
            fbus1.write.next = dfifo_bus.write

        else:
            fbus2.write.next = dfifo_bus.write

        fifo_data_in.next = dfifo_bus.write_data

    @always_comb
    def logic():
        """read or write into buffer"""

        fbus1.read.next = dfifo_bus.read if (
            buffer_sel) else False

        fbus2.read.next = dfifo_bus.read if (
            not buffer_sel) else False

        dfifo_bus.read_data.next = fbus1.read_data if (
            buffer_sel) else fbus2.read_data

        dfifo_bus.empty.next = fbus1.empty if (
            buffer_sel) else fbus2.empty

    return (
        fifo_sync1, fifo_sync2, assign, mux2_logic, logic)
Beispiel #39
0
def tb_fifo_ramp(args):

    clock = Clock(0, frequency=50e6)
    reset = Reset(0, active=1, async=False)
    glbl = Global(clock, reset)
    regbus = Wishbone(glbl)
    fifobus = FIFOBus()

    def _bench_fifo_ramp():
        tbdut = fifo_ramp(clock, reset, regbus, fifobus, base_address=0x0000)
        tbrbor = regbus.interconnect()
        tbclk = clock.gen()

        asserr = Signal(bool(0))

        @instance
        def tbstim():
            print("start fifo ramp test")
            try:
                yield delay(100)
                yield reset.pulse(111)

                # verify an incrementing pattern over the fifobus
                yield regbus.writetrans(0x07, 2)  # div of two
                yield regbus.readtrans(0x07)
                assert 2 == regbus.get_read_data()

                yield regbus.writetrans(0x00, 1)  # enable
                yield regbus.readtrans(0x00)
                assert 1 == regbus.get_read_data(), "cfg reg write failed"

                # monitor the bus until ?? ramps
                Nramps, rr, timeout = 128, 0, 0
                while rr < Nramps and timeout < (20 * Nramps):
                    cnt = 0
                    for ii, sh in enumerate((
                            24,
                            16,
                            8,
                            0,
                    )):
                        yield delay(1000)
                        yield regbus.readtrans(0x08 + ii)
                        cntpart = regbus.get_read_data()
                        cnt = cnt | (cntpart << sh)
                        print(
                            "{:<8d}: ramp count[{:<4d}, {:d}]: {:08X}, {:02X} - timeout {:d}"
                            .format(now(), rr, ii, cnt, cntpart, timeout))
                    timeout += 1
                    # @todo: add ramp check
                    if cnt != rr or (timeout % 1000) == 0:
                        print("   ramp {}  {}".format(
                            int(cnt),
                            int(rr),
                        ))
                    rr = int(cnt)
                print("{}, {}, {}".format(Nramps, rr, timeout))
            except AssertionError as err:
                asserr.next = True
                for _ in range(10):
                    yield clock.posedge
                raise err

            raise StopSimulation

        # monitor the values from the fifo bus, it should
        # be a simple "ramp" increasing values
        _mask = 0xFF
        _cval = Signal(modbv(0, min=0, max=256))

        @always(clock.posedge)
        def tbmon():
            if fifobus.write:
                assert _cval == fifobus.write_data
                _cval.next = _cval + 1

        return tbclk, tbdut, tbstim, tbmon, tbrbor

    run_testbench(_bench_fifo_ramp, args=args)