text: # 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'
  