This is the static structure of the testbench. The temporal order is shown in the next section.
always #10ns clk = !clk; generates the 50 MHz clock.arst_n is held low for 40 ns, then released.#15s; $fatal(...); $finish; prevents GLS deadlock from running forever.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.uart_write_mem()Encodes command, address and 32-bit data into UART bytes.uart_bfm_i.uart_send_byte() serializes data into the DUT RX path.draw_horizontal_type(), draw_vertical_type(), draw_graph_type(), and draw_mask_type() are now executed sequentially.MASK_GEN_PATH.done, and SRAM consistency after each object draw.CY7C1049GN_i holds actual writes from the DUT.tnsm_data and tft_dc against tft_active_area.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. |
|
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:
|
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:
|
Dedicated checker waits for tnsm and checks:
|
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:
|
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. |
| Checker / verification item | Status | What it compares | Why 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. |