blob: ce06ba0f2e68e986eea5d2130f5d9d66a30a44f9 [file] [log] [blame]
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
import logging
import re
import pytest
from .. import config, utils
log = logging.getLogger(__name__)
@pytest.fixture(scope="module")
def localconf_nexysvideo(localconf):
assert 'boards' in localconf
assert 'nexysvideo' in localconf['boards']
boardconf = localconf['boards']['nexysvideo']
assert 'uart_device' in boardconf
assert 'uart_speed' in boardconf
return boardconf
@pytest.fixture(scope="module")
def uart_persistent(localconf_nexysvideo, tmp_path_factory):
"""
A UART device connected to the FPGA board, which is kept active for
for multiple tests.
Use the `uart` fixture for per-test access to the UART device.
"""
uart_device = localconf_nexysvideo['uart_device']
uart_speed = localconf_nexysvideo['uart_speed']
log_dir_path = tmp_path_factory.mktemp('uart')
log.debug("Opening UART on device {} ({} baud)".format(
uart_device, uart_speed))
with utils.LoggingSerial(uart_device,
uart_speed,
timeout=1,
log_dir_path=log_dir_path,
default_filter_func=utils.
filter_remove_device_sw_log_prefix) as uart:
yield uart
@pytest.fixture
def uart(uart_persistent, request):
""" A UART device connected to the FPGA board.
The UART is drained between test runs to give better isolation between the
tests.
"""
uart_persistent.log_add_marker("===== TEST {} START =====\n".format(
request.node.name))
yield uart_persistent
# Read all remaining data from UART to have it available in the log file.
uart_persistent.drain_in()
uart_persistent.log_add_marker("===== TEST {} DONE =====\n\n".format(
request.node.name))
@pytest.fixture(scope="module")
def nexysvideo_earlgrey(tmp_path_factory, topsrcdir, bin_dir, localconf_nexysvideo):
""" A Nexys Video board flashed with an Earl Grey bitstream """
bitstream = bin_dir / "hw/top_earlgrey/lowrisc_systems_top_earlgrey_nexysvideo_0.1.bit"
assert bitstream.is_file(), ("Bitstream not found at %s." % str(bitstream))
cmd_pgm = [
topsrcdir / 'util/opentitan-pgm-fpga/opentitan-pgm-fpga',
'xc7a200tsbg484-1',
bitstream,
]
# Explicitly use a certain hardware server (if set)
if 'hw_server_url' in localconf_nexysvideo:
cmd_pgm += [
'--hw-server-url',
localconf_nexysvideo['hw_server_url'],
]
log.debug("Flashing Nexys Video board with bitstream {}".format(
str(bitstream)))
tmp_path = tmp_path_factory.mktemp('nexysvideo_earlgrey')
p_pgm = utils.Process(cmd_pgm, logdir=tmp_path, cwd=tmp_path)
p_pgm.run()
p_pgm.proc.wait(timeout=300)
assert p_pgm.proc.returncode == 0
@pytest.fixture(params=config.TEST_APPS_SELFCHECKING)
def app_selfchecking_bin(request, bin_dir):
test_filename = request.param + '_fpga_nexysvideo.bin'
bin_path = bin_dir / 'sw/device/tests' / test_filename
assert bin_path.is_file()
return bin_path
def test_apps_selfchecking(tmp_path, localconf_nexysvideo, nexysvideo_earlgrey,
app_selfchecking_bin, bin_dir, uart):
""" Load a simple application, and check its output. """
spiflash = bin_dir / 'sw/host/spiflash/spiflash'
utils.load_sw_over_spi(tmp_path, spiflash, app_selfchecking_bin)
# We need to wait for this message to ensure we are asserting on the output
# of the newly flashed software, not the software which might be already on
# the chip (which might get re-executed when running spiflash).
bootstrap_done_exp = b'Bootstrap: DONE!'
assert uart.find_in_output(bootstrap_done_exp, timeout=60)
bootmsg_exp = b'Boot ROM initialisation has completed, jump into flash!'
assert uart.find_in_output(bootmsg_exp,
timeout=10), "End-of-bootrom string not found."
log.debug("Waiting for pass string from device test")
result_match = uart.find_in_output(re.compile(br'^(PASS|FAIL)!$'),
timeout=60)
assert result_match is not None, "PASS/FAIL indication not found in test output."
result_msg = result_match.group(1)
log.info("Test ended with {}".format(result_msg))
assert result_msg == b'PASS'