示例#1
0
def test_spi_models(args=None):
    args = tb_default_args(args)
    clock = Clock(0, frequency=125e6)
    glbl = Global(clock)
    ibus = Barebone(glbl)
    spibus = SPIBus()

    def bench():

        tbdut = spi_controller_model(clock, ibus, spibus)
        tbspi = SPISlave().process(spibus)
        tbclk = clock.gen()

        @instance
        def tbstim():
            yield clock.posedge

            yield ibus.writetrans(0x00, 0xBE)
            yield delay(100)
            yield ibus.readtrans(0x00)

            raise StopSimulation

        return tbdut, tbspi, tbclk, tbstim

    run_testbench(bench, args=args)
示例#2
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)
示例#3
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)
示例#4
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()
示例#5
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()
示例#6
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()
示例#7
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)
示例#8
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)
示例#9
0
from rhea.cores.spi import SPIBus

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()
示例#10
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
示例#11
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