VHDL Verification with GHDL

FPGA Serial ACL Tester Version 1 by Timothy Stotts

FPGA Serial ACL Tester Version 1 project and source code

Previous project posting on GitHub.io site


A small FPGA project of different implementations for testing Measurement and Activity Events of a SPI accelerometer. The design targets the Digilent Inc. Arty-A7-100T FPGA development board containing a Xilinx Artix-7 FPGA. Three peripherals are used: Digilent Inc. Pmod ACL2, Digilent Inc. Pmod CLS., Digilent Inc. Pmod SSD.

The design is broken into three groupings: Xilinx AXI subsystem, Verilog-Only, VHDL-Only.

The folder ACL-Tester-Design-Single-Clock-VHDL contains a Xilinx Vivado project with sources containing only VHDL-2002 and VHDL-2008 modules. Plain HDL without a soft CPU or C code is authored to talk with board components, an accelerometer peripheral, a 16x2 character LCD peripheral and a two-digit Seven Segment Display. The project is named “Single Clock” as clock enable pulses are used instead of clock dividers as much as possible throughout the design.

In addition to the project’s RTL and Xilinx Vivado project, a VHDL-2008 test-bench was added. This test-bench provides a beginning of a OS-VVM verification environment. Currently only one test is implemented, providing both manual and automated checking of the Measurement Mode operation of the VHDL DUT (Device Under Test). The folder Work_Dir_GHDL contains a script (ghdl-run.sh) for compiling and executing the behavioral simulation verification of the VHDL design. (It performs a pre-synthesis simulation.) Professional HDL simulation tools are cost-prohibitive for an individual. Fortunately the open source tool GHDL is capable of compiling and simulating a design that is VHDL-2008 with the most common 2008 features. This is something that the Xilinx Vivado 2020.2 tool is not capable to the same degree, due to not supporting several key VHDL-2008 features.

GHDL executes in batch mode. There are 3 backends to select from. I chose LLVM. When GHDL is compiled, installed, and run with this mode, the GHDL program will generate .o compile objects and then link them together when the elaborate command is issued. An executable is generated; and when executed from the command-line, this executable uses a low amount of system memory and an intense single-thread of execution to generate batch output to the command-line, and with OS-VVM, to a transcript text file. On my 2.3 GHz Intel i5 (6th gen): running the GHDL simulation under Windows Subsystem for Linux (WSL), took less than a day to simulate 3/4 of a second of FPGA run time. Note that the Ubuntu 20.04 package is broken as it is missing ieee.numeric_std in its VHDL-2008 data files. I built GHDL in LLVM mode from the nightly source code snapshot, and installed the tool under the prefix /usr/local .

The test-bench was authored to instantiate the FPGA design, and also instantiate test-bench components to emulate the peripherals that the FPGA is designed to interact with. These are:

  • Board User Interface
    • 4 Basic LEDs
    • 4 RGB LEDs
    • 4 Switches
    • 4 Buttons
  • Board UART
    • Monitoring and Scoreboarding of FPGA UART output as ASCII Text
  • Clock and Reset Generator
  • Pmod SSD (7SD)
    • Monitoring of the two digits displayed multiplexed on the Pmod SSD
  • Pmod CLS
    • Monitoring and Scoreboarding of received SPI data as ASCII Text with ANSI control sequences
  • Pmod ACL2
    • A model that emulates the ADXL362 accelerometer’s capability of Measurement Mode, where measurements are output via SPI at a data ready frequency

Note that each of these components can have additional VHDL architectures authored and selected at elaboration time. Each of the mentioned models can have a separate architecture authored and selected for an alternate test, allowing for substantial ability to configure a peripheral emulation differently for a different test. An alternate architecture could emulate the Linked Mode execution of the ACL2, with shared VHDL procedures in a VHDL package, making each architecture run the same procedures plus an amount of customization. An alternate architecture could emulate the Board UART, plus an alternate architecture could emulate the Pmod CLS; both expecting the ASCII text to be fixed-point conversion values of the ACL readings instead of raw 16-bit hexadecimal register values. The selection of the desired architecture for a given test is specified with a VHDL Configuration specification.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library osvvm;
context osvvm.OsvvmContext;

library work;
use work.all;

configuration test_default_fpga_regression of fpga_serial_acl_tester_testharness is
    for simulation
        for u_fpga_serial_acl_tester_testbench : fpga_serial_acl_tester_testbench
            use entity work.fpga_serial_acl_tester_testbench(simulation)
            generic map(
                -- specify simulation duration for this test
                parm_simulation_duration => 750 ms,

                -- specify log file name for this test
                parm_log_file_name => "log_test_default_fpga_regression.txt"

            for simulation
                for uut_fpga_serial_acl_tester : fpga_serial_acl_tester
                    use entity work.fpga_serial_acl_tester(rtl);
                end for;

                for u_tbc_clock_gen : tbc_clock_gen
                    -- specify the component architecture to generate
                    -- the clock and reset
                    use entity work.tbc_clock_gen(simulation_default);
                end for;

                for u_tbc_board_ui : tbc_board_ui
                    -- specify the component architecture to emulate/
                    -- monitor/check the user interface board components
                    use entity work.tbc_board_ui(simulation_default);
                end for;

                for u_tbc_pmod_acl2 : tbc_pmod_acl2
                    -- specify the component architecture to emulate/
                    -- monitor/check the accelerometer peripheral
                    use entity work.tbc_pmod_acl2(simulation_default);
                end for;

                for u_tbc_pmod_cls : tbc_pmod_cls
                    -- specify the component architecture to emulate/
                    -- monitor/check the 16x2 LCD peripheral
                    use entity work.tbc_pmod_cls(simulation_default);
                end for;

                for u_tbc_board_uart : tbc_board_uart
                    -- specify the component architecture to emulate/
                    -- monitor/check the UART terminal
                    use entity work.tbc_board_uart(simulation_default);
                end for;

                for u_tbc_pmod_7sd : tbc_pmod_7sd
                    -- specify the component architecture to emulate/
                    -- monitor/check the 2-digit 7-segment display
                    use entity work.tbc_pmod_7sd(simulation_default);
                end for;
            end for;
        end for;
    end for;
end configuration test_default_fpga_regression;

To acheive multiple tests with custom architectures of the test-bench components, each test is a VHDL Configuration declaration, selecting the desired behavior, and specifying a unique file name for the test log file. The VHDL Configuration(s) then become the elaboration and execution target of the VHDL simulator when invoked to start the simulation.