Skip to content

Testbench description

Overview

The following figure depicts the Testbench:

Types

t_reg

A record type used to define register configurations for the testbench.

Property Description
Type Name t_reg
Purpose Register fields with address and default value
Fields - name : string - Register name identifier
- addr : std_logic_vector(7 downto 0) - 8-bit register address
- data : std_logic_vector(15 downto 0) - 16-bit reset value

Constants

General constants

The following constants are defined:

Name Type Value Description
C_FREQ_HZ positive 0d100_000_000 Clock frequency
C_CLK_PERIOD time 1 sec / C_FREQ_HZ Clock period
C_GIT_ID vector[31: 0] 0x12345678 Git identifier for DUT version tracking
C_UART_BAUD_RATE_BPS positive 0d115_200 UART baud rate in bits per second
C_UART_BIT_TIME time 1 sec / C_UART_BAUD_RATE_BPS Time duration for one UART bit
C_UART_BIT_TIME_ACCURACY time 0. 01 * C_UART_BIT_TIME UART bit timing tolerance (1%)
C_UART_WRITE_NB_BITS positive 10 * 8 Total bits for UART write command
C_UART_WRITE_CMD_TIME time C_UART_BIT_TIME * C_UART_WRITE_NB_BITS Total time for UART write command
C_READ_NB_BITS positive 10 * 9 Total bits for UART read command
C_UART_READ_CMD_TIME time C_UART_BIT_TIME * C_UART_READ_NB_BITS Total time for UART read command
C_SPI_FREQ_HZ positive 0d1_000_000 SPI SLCK frequency
C_SPI_BIT_TIME time 1 sec / C_SPI_FREQ_HZ SPI baud rate in bits per second
C_SPI_BIT_TIME_ACCURACY time 0.01 * C_SPI_BIT_TIME SPI bit timing tolerance (1%)
C_SPI_NB_DATA_BIS positive 8 Total bits in SPI transaction
C_SPI_TRANSACTION_TIME time (C_SPI_NB_DATA_BIS + 2) * C_SPI_BIT_TIME SPI transaction time
C_H_VGA_PIXEL_FREQUENCY integer 0d65_000_000 VGA pixel clock frequency
C_H_VGA_PIXEL_BIT_TIME time 1 sec / C_H_VGA_PIXEL_FREQUENCY VGA pixel clock period
C_H_PIXELS integer 0d1024 VGA active display width (pixels)
C_H_FRONT_PORCH integer 0d24 VGA horizontal front porch (pixels)
C_H_SYNC_PULSE integer 0d136 VGA horizontal sync pulse width (pixels)
C_H_BACK_PORCH integer 0d160 VGA horizontal back porch (pixels)
C_H_HSYNC_HIGH integer C_H_PIXELS + C_H_FRONT_PORCH + C_H_BACK_PORCH VGA horizontal sync high period (pixels)
C_H_WHOLE_LINE integer C_H_SYNC_PULSE + C_H_HSYNC_HIGH VGA total horizontal line (pixels)
C_H_SYNC_PULSE_TIME time C_H_SYNC_PULSE * C_H_VGA_PIXEL_BIT_TIME VGA horizontal sync pulse duration
C_H_SYNC_PULSE_TIME_ACCURACY time 0.01 * C_H_SYNC_PULSE * C_H_VGA_PIXEL_BIT_TIME VGA horizontal sync pulse tolerance
C_H_HSYNC_HIGH_TIME time C_H_HSYNC_HIGH * C_H_VGA_PIXEL_BIT_TIME VGA horizontal sync high duration
C_H_HSYNC_HIGH_TIME_ACCURACY time 0.01 * C_H_HSYNC_HIGH * C_H_VGA_PIXEL_BIT_TIME VGA horizontal sync high tolerance
C_H_WHOLE_LINE_TIME time C_H_SYNC_PULSE_TIME + C_H_HSYNC_HIGH_TIME VGA total horizontal line duration
C_H_WHOLE_LINE_TIME_ACCURACY time C_H_SYNC_PULSE_TIME_ACCURACY + C_H_HSYNC_HIGH_TIME_ACCURACY VGA total horizontal line tolerance
C_V_VGA_PIXEL_FREQUENCY integer C_H_VGA_PIXEL_FREQUENCY / C_H_WHOLE_LINE VGA line frequency (Hz)
C_V_VGA_PIXEL_BIT_TIME time 1 sec / C_V_VGA_PIXEL_FREQUENCY VGA line period
C_V_PIXELS integer 0d768 VGA active display height (lines)
C_V_FRONT_PORCH integer 0d3 VGA vertical front porch (lines)
C_V_SYNC_PULSE integer 0d6 VGA vertical sync pulse width (lines)
C_V_BACK_PORCH integer 0d29 VGA vertical back porch (lines)
C_V_HSYNC_HIGH integer C_V_PIXELS + C_V_FRONT_PORCH + C_V_BACK_PORCH VGA vertical sync high period (lines)
C_V_WHOLE_LINE integer C_V_SYNC_PULSE + C_V_HSYNC_HIGH VGA total vertical frame (lines)
C_V_SYNC_PULSE_TIME time C_V_SYNC_PULSE * C_V_VGA_PIXEL_BIT_TIME VGA vertical sync pulse duration
C_V_SYNC_PULSE_TIME_ACCURACY time 0.01 * C_V_SYNC_PULSE * C_V_VGA_PIXEL_BIT_TIME VGA vertical sync pulse tolerance
C_V_HSYNC_HIGH_TIME time C_V_HSYNC_HIGH * C_V_VGA_PIXEL_BIT_TIME VGA vertical sync high duration
C_V_HSYNC_HIGH_TIME_ACCURACY time 0.01 * C_V_HSYNC_HIGH * C_V_VGA_PIXEL_BIT_TIME VGA vertical sync high tolerance
C_V_WHOLE_LINE_TIME time C_V_SYNC_PULSE_TIME + C_V_HSYNC_HIGH_TIME VGA total vertical frame duration
C_V_WHOLE_LINE_TIME_ACCURACY time C_V_SYNC_PULSE_TIME_ACCURACY + C_V_HSYNC_HIGH_TIME_ACCURACY VGA total vertical frame tolerance

Registers

The following registers are defined as t_reg:

Name Address Reset Value
C_REG_GIT_ID_MSB 0x00 0x1234
C_REG_GIT_ID_LSB 0x01 0x5678
C_REG_12 0x02 0x1212
C_REG_34 0x03 0x3434
C_REG_56 0x04 0x5656
C_REG_78 0x05 0x7878
C_REG_SPI_TX 0x06 0x0000
C_REG_SPI_RX 0x07 0x0000
C_REG_SPI_RX 0x07 0x0000
C_REG_VGA_CTRL 0x08 0x00F0
C_REG_9A 0xAB 0x9A9A
C_REG_CD 0xAC 0xCDCD
C_REG_EF 0xDC 0xEFEF
C_REG_SWITCHES 0xB1 0x0000
C_REG_LED 0xEF 0x0001
C_REG_16_BITS 0xFF 0x0000
C_REG_DEAD 0xCC 0xDEAD

Processes


Process p_check_uart_timings

Description

Verifies UART TX timings by transmitting test data 0x5555 and measuring bit durations.

Data Conversion:

  • Test data 0x5555 contains four '5' characters
  • Each '5' is converted to ASCII → 0x35 (binary: 00110101)

UART Frame Structure:

Each character is transmitted as a 10-bit frame:

[Start] [Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7] [Stop]
  0       1    0    1    0    1    1    0    0      1
          └─────────── LSB to MSB ───────────┘

The diagram below shows the waveform and which falling/rising edges are awaited:

In total, it is repeated four times.

Parameters

The process defines two variables:

Parameter Type Default Description
v_start_time time - The start time of the measurement
v_start_bit_time time - The start time of the measurement of a bit state

Steps

  1. Wait for the start of UART timings check

    • Wait for a rising edge on signal tb_check_uart_timings
    • Log info message: "Checking UART timings on TX with value 0x5555"
  2. For each byte (1 to 4)

    • Wait for start bit
      • Wait for falling edge on tb_pad_o_uart_tx (a)
      • Set v_start_bit_time to current time
      • If first byte, set v_start_time to current time
    • Wait for a rising edge on signal tb_pad_o_uart_tx (b)
    • Check that (now - v_start_bit_time) is in time range C_UART_BIT_TIME ± C_UART_BIT_TIME_ACCURACY with procedure proc_check_time_in_range
    • Set v_start_bit_time to current time
    • Wait for a falling edge on signal tb_pad_o_uart_tx (c)
    • Check that (now - v_start_bit_time) is in time range C_UART_BIT_TIME ± C_UART_BIT_TIME_ACCURACY with procedure proc_check_time_in_range
    • Set v_start_bit_time to current time
    • Wait for a rising edge on signal tb_pad_o_uart_tx (d)
    • Check that (now - v_start_bit_time) is in time range C_UART_BIT_TIME ± C_UART_BIT_TIME_ACCURACY with procedure proc_check_time_in_range
    • Set v_start_bit_time to current time
    • Wait for a falling edge on signal tb_pad_o_uart_tx (e)
    • Check that (now - v_start_bit_time) is in time range C_UART_BIT_TIME ± C_UART_BIT_TIME_ACCURACY with procedure proc_check_time_in_range
    • Set v_start_bit_time to current time
    • Wait for a rising edge on signal tb_pad_o_uart_tx (f)
    • Check that (now - v_start_bit_time) is in time range C_UART_BIT_TIME ± C_UART_BIT_TIME_ACCURACY with procedure proc_check_time_in_range
    • Set v_start_bit_time to current time
    • Wait for a falling edge on signal tb_pad_o_uart_tx (g)
    • Check that (now - v_start_bit_time) is in time range 2. 0 * C_UART_BIT_TIME ± 2.0 * C_UART_BIT_TIME_ACCURACY with procedure proc_check_time_in_range
    • Set v_start_bit_time to current time
    • Wait for a rising edge on signal tb_pad_o_uart_tx (h)
    • Check that (now - v_start_bit_time) is in time range 2.0 * C_UART_BIT_TIME ± 2.0 * C_UART_BIT_TIME_ACCURACY with procedure proc_check_time_in_range
    • Set v_start_bit_time to current time
  3. Verify total elapsed time

    • Check that (now - v_start_time) is in time range 9 * 4 C_UART_BIT_TIME ± C_UART_BIT_TIME_ACCURACY with procedure proc_check_time_in_range

Process p_check_spi_timings

Description

Verifies SPI clock timings.

Currently only verifies SPI clock timings.

The diagram below shows the waveform and which rising edges are awaited:

Parameters

The process defines two variables:

Parameter Type Default Description
v_start_time time - The start time of the measurement
v_start_bit_time time - The start time of the measurement of a bit state

Steps

  1. Wait for the start of SPI timings check

    • Wait for a rising edge on signal tb_check_spi_timings
  2. For each bit (1 to 8)

    • Wait for a rising edge on signal tb_pad_o_sclk (a to h)
    • If first bit (bits = 1):
      • Set v_start_time to current time
      • Set v_start_bit_time to current time
    • Else:
      • Check that (now - v_start_bit_time) is in time range C_SPI_BIT_TIME ± C_SPI_BIT_TIME_ACCURACY with procedure proc_check_time_in_range
      • Set v_start_bit_time to current time
  3. Verify total elapsed time

    • Check that (now - v_start_time) is in time range 7 * C_SPI_BIT_TIME ± 7 * C_SPI_BIT_TIME_ACCURACY with procedure proc_check_time_in_range

Process p_check_hsync_timings

Description

This process verifies the VGA horizontal synchronization (HSYNC) timing.

Parameters

The process defines two variables:

Parameter Type Default Description
v_start_time time - The start time of the measurement
v_start_bit_time time - The start time of the measurement of a bit state

Steps

  1. Wait for the start of HSYNC timings check

    • Wait for a rising edge on signal tb_check_hsync_timings
  2. Measure HSYNC pulse width (sync pulse duration)

    • Wait for falling edge on tb_pad_o_vga_hsync (start of sync pulse)
    • Capture both v_start_time and v_start_bit_time as baseline
    • Wait for rising edge on tb_pad_o_vga_hsync (end of sync pulse)
    • Validate sync pulse duration against C_H_SYNC_PULSE_TIME ± C_H_SYNC_PULSE_TIME_ACCURACY
    • Update v_start_bit_time to current time
  3. Measure HSYNC high period and total line time

    • Wait for next falling edge on tb_pad_o_vga_hsync (completion of one horizontal line)
    • Validate high period: Check time since last edge against C_H_HSYNC_HIGH_TIME ± C_H_HSYNC_HIGH_TIME_ACCURACY
    • Validate complete line time: Check time since initial v_start_time against C_H_WHOLE_LINE_TIME ± C_H_WHOLE_LINE_TIME_ACCURACY

Process p_check_vsync_timings

Description

This process verifies the VGA vertical synchronization (VSYNC) timing.

Parameters

The process defines two variables:

Parameter Type Default Description
v_start_time time - The start time of the measurement
v_start_bit_time time - The start time of the measurement of a bit state

Steps

  1. Wait for the start of HSYNC timings check

    • Wait for a rising edge on signal tb_check_vsync_timings
  2. Measure HSYNC pulse width (sync pulse duration)

    • Wait for falling edge on tb_pad_o_vga_vsync (start of sync pulse)
    • Capture both v_start_time and v_start_bit_time as baseline
    • Wait for rising edge on tb_pad_o_vga_vsync (end of sync pulse)
    • Validate sync pulse duration against C_V_SYNC_PULSE_TIME ± C_V_SYNC_PULSE_TIME_ACCURACY
    • Update v_start_bit_time to current time
  3. Measure HSYNC high period and total line time

    • Wait for next falling edge on tb_pad_o_vga_vsync
    • Validate high period: Check time since last edge against C_V_HSYNC_HIGH_TIME ± C_V_HSYNC_HIGH_TIME_ACCURACY
    • Validate complete frame time: Check time since initial v_start_time against C_V_WHOLE_LINE_TIME ± C_V_WHOLE_LINE_TIME_ACCURACY

Procedures


Procedure proc_check_time_in_range

Description

This procedure performs a range check to verify that time_to_check is within expected_time ± accuracy.

Parameters

Parameter Type Default Description
time_to_check time - The actual time value to be validated
expected_time time - The target/expected time value
accuracy time - The acceptable deviation (tolerance) from the expected time
message string "" Optional custom message prefix for the assertion output

Steps

  1. Perform Range Check
    • Check that abs(time_to_check - expected_time) <= accuracy with procedure check

Procedure proc_reset_dut

Description

This procedure puts all the testbench signals into a known state.

Parameters

Parameter Type Default Description
c_clock_cycles positive 50 Number of clock cycles to wait

Steps

  1. Reset the DUT by Setting Input State to All Zeros

    • Set tb_pad_i_rst_h to 1
    • Set tb_i_uart_select to 0
    • Set tb_i_uart_rx_manual to 0
    • Set tb_pad_i_switch_0 to 0
    • Set tb_pad_i_switch_1 to 0
    • Set tb_pad_i_switch_2 to 0
    • Set tb_i_read_address to 0x00
    • Set tb_i_read_address_valid to 0
    • Set tb_i_write_address to 0x00
    • Set tb_i_write_data to 0x0000
    • Set tb_i_write_valid to 0
    • Set tb_check_uart_timings to 0
    • Set tb_check_spi_timings to 0
  2. Wait for the Specified Number of Clock Cycles

    • Wait for c_clock_cycles * C_CLK_PERIOD
  3. De-assert Reset

    • Set tb_pad_i_rst_h to 0
  4. Wait for the DUT to Settle

    • Wait for 5 ns

Procedure proc_uart_send_byte

Description

This procedure sends a byte via UART using the manually driven line.

Parameters

Parameter Type Default Description
uart_rx std_logic - The UART line to drive
byte_to_send vector[7:0] - The byte to send

Steps

  1. Ensure the Manual UART is Selected

    • If tb_i_uart_select = 0:
      • Set tb_i_uart_select to 1
      • Wait for 200 ns
  2. Send the Start Bit

    • Set uart_rx to 0
    • Wait for C_UART_BIT_TIME
  3. Send the Data Bits (LSB to MSB)

    • For bit_idx in byte_to_send'low to byte_to_send'high:
      • Set uart_rx to byte_to_send(bit_idx)
      • Wait for C_UART_BIT_TIME
  4. Send the Stop Bit

    • Set uart_rx to 1
    • Wait for 1. 1 × C_UART_BIT_TIME

Procedure proc_uart_write

Description

This procedure writes a value to a specified UART register.

Parameters

Parameter Type Default Description
reg t_reg - The register to write to
value vector[15:0] - The value to write to the register

Steps

  1. Ensure the Model UART is Selected

    • If tb_i_uart_select = 1:
      • Set tb_i_uart_select to 0
      • Wait for 200 ns
  2. Set Up the Write Operation

    • Set tb_i_write_address to reg.addr
    • Set tb_i_write_data to value
    • Set tb_i_write_valid to 1
  3. Wait and De-assert the Valid Flag

    • Wait for 200 ns
    • Set tb_i_write_valid to 0
  4. Wait for the Write Operation to Complete

    • Wait for 1.1 × C_UART_WRITE_CMD_TIME

Procedure proc_uart_read

Description

This procedure reads a value from a specified UART register.

Parameters

Parameter Type Default Description
reg t_reg - The register to read from

Steps

  1. Ensure the Model UART is Selected

    • If tb_i_uart_select = 1:
      • Set tb_i_uart_select to 0
      • Wait for 200 ns
  2. Wait Before Starting the Read

    • Wait for 500 ns (to avoid simulation stuck)
  3. Set Up the Read Operation

    • Set tb_i_read_address to reg.addr
    • Set tb_i_read_address_valid to 1
  4. Wait for the Read Operation to Complete

    • Wait for a rising edge on signal tb_o_read_data_valid
  5. De-assert the Read Valid Signal

    • Set tb_i_read_address_valid to 0

Procedure proc_uart_check

Description

This procedure checks if the read value from a specified UART register matches the expected value.

Parameters

Parameter Type Default Description
reg t_reg - The register to check
expected_value vector[15:0] - The expected value to compare against

Steps

  1. Read the Register Value

  2. Check the Returned Value

    • Check that the returned value tb_o_read_data equals expected_value with the procedure check_equal

Procedure proc_uart_check_default_value

Description

This procedure checks if the default value of a specified UART register matches the expected reset value.

Parameters

Parameter Type Default Description
reg t_reg - The register to check

Steps

  1. Check the Default Value Against the Register's Reset Value
    • Check that the value after reset is equal to the one specified in reg.data with the procedure proc_uart_check

Procedure proc_uart_check_read_only

Description

This procedure checks if a specified UART register is read-only by attempting to write to it and verifying that the value remains unchanged.

Parameters

Parameter Type Default Description
reg t_reg - The register to check

Steps

  1. Attempt to Write an Incorrect Value to the Register

    • Write the data not(reg.data) to the register address reg.addr with procedure proc_uart_write
  2. Check if the Register Value Remains Unchanged

    • Read back the register and check if the register value remains unchanged with procedure proc_uart_check

Procedure proc_uart_check_read_write

Description

This procedure checks if a specified UART register is read-write by writing a value to it and verifying that the value is correctly updated.

Parameters

Parameter Type Default Description
reg t_reg - The register to check
expected_value vector[15:0] - The expected value to compare against after writing

Steps

  1. Write the Inverted Default Value to the Register

    • Write the data not(reg.data) to the register address reg.addr with procedure proc_uart_write
  2. Check if the Register Value is Updated Correctly

    • Read back the register and check if the register value is matching expected_value with procedure proc_uart_check

Procedure proc_spi_write

Description

Writes a byte value to the SPI master module via UART register interface.

Parameters

Parameter Type Default Description
value vector[7:0] - 8-bit data to transmit via SPI

Steps

  1. Reset C_REG_SPI_TX for Rising Edge Detection

  2. Write the Data with Valid Flag Set

    • Write (7b0 & 1b1 & value) to the register C_REG_SPI_TX with procedure proc_uart_write

Procedure proc_spi_check

Description

Writes a value to SPI master and verifies correct transmission and reception.

Parameters

Parameter Type Default Description
value vector[7:0] - 8-bit data to transmit and verify

Steps

  1. Write Data to SPI

  2. Retrieve Data from SPI Slave Stream

    • Pop data from C_SLAVE_STREAM into v_spi_slave_data (MOSI path verification)
  3. Verify MOSI Path

    • Check that v_spi_slave_data equals value with procedure check_equal
  4. Read and Verify MISO Register Data

    • Check that sampled SPI data from slave is matching the one decoded in the REG_SPI_RX register with procedure proc_uart_check