algofoogle / tt07-raybox-zero

TT07 resub of tt04-raybox-zero "3D" VGA ray caster demo (like Wolf3D)
Apache License 2.0
1 stars 0 forks source link

How to run Gate level test and output rendering frames? #2

Open pongsagon opened 5 months ago

pongsagon commented 5 months ago

Hi, I have read your recent journal but cannot really understand the step to do the GL test and get the output render frames. I am quite novice in the ASIC workflow. To be able to do this test would be super helpful. The tutorial should be added on the TinyTapeout official website! The best thing I can do is only to test my design on the FPGA and hope that it would work on the ASIC.

Thanks a lot for your write up.

algofoogle commented 4 months ago

Sorry, I overlooked this earlier. I'll try to do a better write-up soon (and I'm planning on creating a bit of a proposal for how to formalise this for Tiny Tapeout). For now though I can give you these pointers:

  1. My frame-rendering test code works for both RTL (behavioural Verilog code) and GL (sky130 gate-level code) simulation. RTL is fast, GL is slow (but fairly accurate for actual expected silicon results, but not for timing for things like setup/hold violations).
  2. Running this locally (which is a great idea) depends on you being able to harden your TT design locally, and there's a new TT08 guide for that -- TT07 and below had slightly different instructions, which I cover in my various recent journal entries. I can share that too, if you want to prove something prior to TT08. NOTE: For GL simulation, after you harden, you need to copy the gate-level netlist (Verilog) file into the test directory, if using my test. This is referenced here. The GitHub Action (described below) does this copying automatically.
  3. There is an existing gate-level GitHub Action as part of TT projects (I haven't checked whether this has changed for TT08+) and this just runs whatever configured cocotb test(s) you already have. In my case the action includes the extra FRAMES: 5 environment variable that my cocotb test is able to use (and there are others available in my test).
  4. My actual test that renders frames is found in test/test.py -- it just runs a 25MHz clock, resets the design, samples video signal outputs on each clock cycle (i.e. each pixel), and then writes out an old-fashioned uncompressed PPM file for each frame. It keeps track of the current pixel (clock) count, to know that when 800 cycles have elapsed, that's the equivalent of one full VGA line (at 640x480 resolution), and 525 lines equal 1 frame. There is also code that runs in parallel (coroutine) to twiddle inputs to my SPI interfaces, which my design uses for controlling the state/view of what I want it to render, and I've got an if/else chain that decides which feature I want to exercise for each frame. Note that there is also code to sense when an output is in a simulation-unknown state or Hi-Z, and in my case I've decided to count those as "bad" pixels, and render them as bright green or magenta (respectively) to make them stand out. I ended up having to add a lot of extra reset logic that I didn't expect I'd need, in order to weed out these unknown states, and that was where GL simulation was vital.
  5. Finally, having a test/tb.v that assigns meaningful variable/signal names to your TT ports is important both to ensure they're available to cocotb, and that their names make sense to you when writing the tests. Note two more things in my case: (1) I've also got an SPI ROM simulator hooked up to my design in this file; and (2) I disable VCD dumps because these end up being MASSIVE (gigabytes) when simulating entire VGA frames at gate-level.
algofoogle commented 4 months ago

See also: https://github.com/algofoogle/tt07-raybox-zero/blob/main/test/README.md

pongsagon commented 4 months ago

Thank you for your detail explanation. It would be a valuable resource for the TT community.