GLS verification documentation · dig_top_tb

Structured Testbench Verification Flow

1. Architecture overview

This is the static structure of the testbench. The temporal order is shown in the next section.

Infrastructure
Clockalways #10ns clk = !clk; generates the 50 MHz clock.
Resetarst_n is held low for 40 ns, then released.
Timeout#15s; $fatal(...); $finish; prevents GLS deadlock from running forever.
Reference / golden data
tft_init_memExpected TFT initialization sequence: command, data and delay entries.
tft_sidebarExpected sidebar TFT stream: CASET, RASET, RAMWR and pixel bytes.
tft_active_areaExpected active-area TFT stream. Its byte-by-byte SPI checker is now active.
tb_sramGolden SRAM image initialized from tft_active_area and updated by each drawing task before comparing against CY7C1049GN_i.mem.
Stimulus path
Main stimulus threadRuns the ordered scenario after reset.
uart_write_mem()Encodes command, address and 32-bit data into UART bytes.
UART BFMuart_bfm_i.uart_send_byte() serializes data into the DUT RX path.
Drawing tasksdraw_horizontal_type(), draw_vertical_type(), draw_graph_type(), and draw_mask_type() are now executed sequentially.
Verification logic
Dedicated checker threadChecks TFT init stream/delays, sidebar SPI stream, and active-area SPI stream.
Inline assertions / task checksCheck flags, color-map writes, busy windows, MASK_GEN_PATH.done, and SRAM consistency after each object draw.
SRAM modelCY7C1049GN_i holds actual writes from the DUT.
Active-area stream checkerNow active: compares tnsm_data and tft_dc against tft_active_area.

2. Temporal verification flow for GLS

Each row is one simulation phase. The columns keep their meaning from start to finish. The drawing phase was updated to include all object-type tasks and the golden SRAM comparison performed after each task.

Phase Stimulus / action Expected reference Active verification GLS purpose
0
Reference setup
The TB initializes internal reference arrays before the main scenario starts.
  • tft_init_mem
  • tft_sidebar
  • tft_active_area
  • tb_sram, initialized from tft_active_area
No DUT check yet. This phase prepares the expected behavior used later by stream and memory checkers. Provides an independent reference so the GLS result is not trusted blindly.
1
Clock / reset
Clock starts. Reset is released after #40ns. Stimulus waits for arst_n and 10 extra clock cycles. Known reset state expected from DUT. Checker thread is already alive but blocked on internal FSM events. Timeout guard is active. Catches reset/timing deadlocks through timeout or missing later events.
2
TFT init programming
For each entry:
uart_write_mem(8'h13, {tft_init_mem[i], i[5:0]})
tft_init_mem[i] is the expected content of the DUT TFT initialization memory. No SPI comparison yet. This phase loads the DUT-side initialization memory through UART. Exercises UART receive/decode/register-write paths before functional screen activity.
3
TFT initialization
Configure SPI divider with 8'h11, trigger initialization with 8'h12, then wait #500ms. Expected stream is tft_init_mem: command/data entries and delay entries. Dedicated checker waits for initialize state and checks:
  • {rom_type, tnsm_data} == tft_init_mem[i]
  • delay count ≥ expected cycles
Finds wrong FSM sequencing, wrong SPI payload, delay counter issues, or handshake failures.
4
Init completion
After the 500 ms wait, the stimulus samples the TFT control FSM status. Initialization sequence should be complete. assert(initialization_done) Detects stalled initialization due to gate-level timing/control problems.
5
Sidebar load
Configure WPG, write SIDEBAR_SIZE*2 bytes through 8'h06, then trigger ss_ld_sidebar with 8'h16. tft_sidebar[i+11] is used as the payload written through UART. Inline check confirms sidebar_ongoing asserts after trigger. Exercises memory write path and screen-system start control.
6
Sidebar SPI stream
Stimulus waits #20ms and then expects sidebar transfer to finish. Full expected TFT stream is tft_sidebar:
  • CASET bytes
  • RASET bytes
  • RAMWR
  • sidebar pixel bytes
Dedicated checker waits for tnsm and checks:
  • tnsm_data == tft_sidebar[i]
  • tft_dc is command for indices 0, 5, 10 and data otherwise
  • sidebar_ongoing later deasserts
Catches wrong SPI byte ordering, wrong command/data framing, bad SRAM readout, or stuck TFT FSM.
7
Color map
For each color map entry:
uart_write_mem(8'h15, {color, i[3:0]})
The random color generated by the TB is the expected table value. After propagation clocks:
assert(color_map[i] == color)
Verifies UART decode to internal register/table write path.
8
Active screen
Configure width, height, base address and origin. Trigger screen system with 8'h14. Then write active-area bytes through 8'h06. tft_active_area exists as expected stream. Its payload is also used to initialize tb_sram, which becomes the golden SRAM image before drawing. Active checks:
  • assert(busy) after trigger
  • assert(!busy) after #105ms
  • Dedicated checker waits for fetch_frame, then checks each tnsm_data byte against tft_active_area[i]
  • tft_dc is checked as command for indices 0, 5, 10 and data otherwise
Confirms that full-screen operation starts, finishes, and emits the expected active-area TFT command/data stream.
9
Draw horizontal object
Execute:
draw_horizontal_type(100, 100, 50, 0, 0)
Expected update on tb_sram:
tb_sram[addr][7] = x <= obj_value
Task waits for `MASK_GEN_PATH.done, updates the golden SRAM image, then calls check_sram_consistency(). Verifies horizontal drawing behavior, SRAM addressing, write enable timing, and completion handshake.
10
Draw vertical object
After #5ms, execute:
draw_vertical_type(30, 50, 20, 150, 100)
Expected update on tb_sram:
tb_sram[addr][7] = y <= obj_value
Task waits for `MASK_GEN_PATH.done, updates tb_sram, then compares against CY7C1049GN_i.mem. Checks a second drawing mode and helps catch axis/addressing mistakes not visible in the horizontal case.
11
Draw graph object
After #5ms, execute:
draw_graph_type(200, 20, 18, 10, 200)
Expected graph behavior: previous graph data is shifted left and the newest column is generated using y <= obj_value. Task waits for `MASK_GEN_PATH.done, updates the shadow SRAM with the expected shifted image, then calls check_sram_consistency(). Exercises sequential image update behavior, not only direct pixel overwrite. Useful for catching read-modify/write or shift-order bugs.
12
Draw mask object
After #5ms, execute:
draw_mask_type(7, 10, 260, 115, ACTIVE_SCREEN_WIDTH*SCREEN_HEIGHT)
Expected update uses mask data starting at st_mask and applies it to the target object region in tb_sram. Task waits for `MASK_GEN_PATH.done, updates the golden SRAM image using the expected mask behavior, then compares the full SRAM image. Exercises mask-based drawing and stresses address calculation across source mask and destination object regions.
13
Per-object SRAM comparisons
No separate global comparison phase is needed; each draw task performs its own comparison immediately after completion. tb_sram[i] after each object update. assert(tb_sram[i] === CY7C1049GN_i.mem[i]) over the active-screen address range. Localizes failures to the object type that was just executed, making debug cleaner than one final comparison at the end.
14
Finish
After the mask task, stimulus waits #1ms and calls $finish. No pending expected transaction should remain. If a checker is blocked or DUT hangs earlier, timeout produces $fatal. Separates passing completion from deadlocked simulation.

3. Checker status summary

Checker / verification itemStatusWhat it comparesWhy it matters
TFT init stream checker Active {rom_type, tnsm_data} vs tft_init_mem[i] Verifies the initialization bytes reaching SPI.
TFT init delay checker Active Measured delay cycles vs expected delay_ms * CLK_CYCLES_PER_MS Verifies delay behavior, not only data behavior.
Sidebar SPI stream checker Active tnsm_data and tft_dc vs tft_sidebar[i] and command/data position Verifies TFT protocol content and framing.
Color map checker Active color_map[i] vs random TB color Verifies internal table programming through UART.
Active screen busy checker Active busy high/low window Verifies operation start/completion. Byte correctness is covered by the active-area SPI byte checker.
Active-area SPI byte checker Active Compares tnsm_data/tft_dc vs tft_active_area[i] and expected command/data positions. Closes active-screen stream coverage by checking the actual TFT byte sequence, not only the busy window.
Horizontal object SRAM checker Active tb_sram[addr][7] = x <= obj_value vs CY7C1049GN_i.mem Verifies horizontal object drawing and memory writes.
Vertical object SRAM checker Active tb_sram[addr][7] = y <= obj_value vs CY7C1049GN_i.mem Verifies vertical object drawing and catches axis/addressing issues.
Graph object SRAM checker Active Expected shifted graph image in tb_sram vs actual SRAM model Verifies graph update behavior, including shift-like memory update semantics.
Mask object SRAM checker Active Expected mask-applied image in tb_sram vs actual SRAM model Verifies mask-based drawing and source/destination address interaction.
SRAM consistency function Active tb_sram[i] vs CY7C1049GN_i.mem[i] across the active-screen range Runs after each drawing task, making object-level debug easier.
Timeout checker Active Simulation progress vs 15 s limit Turns GLS hangs into explicit failures.