
This project implements a hardware triangle rasterizer that renders filled triangles to a VGA display at 640×480 @ 60 Hz.
The design uses the edge-equation (half-plane) method: for each edge of the triangle, a linear equation e = A·x + B·y + C is evaluated across the screen. A pixel is inside the triangle when all three edge equations are non-negative. To avoid per-pixel multiplications, the rasterizer uses incremental evaluation — edge values are updated with a single addition as the scan moves horizontally (add A) or advances a row (add B).
ui_in[7:0] (data_byte) + uio_in[0] (valid)
→ triangle_receiver — collects 7 serial bytes: x0, y0, x1, y1, x2, y2, color
→ triangle_setup — FSM computes edge coefficients A, B, C for all 3 edges
→ rasterizer — incremental per-pixel edge evaluation, outputs pixel_on + color
→ vga_timing — 640×480 @ 60 Hz sync generation
→ uo_out[7:0] — VGA PMOD output
Triangle vertices are specified in an 8-bit (0–255) coordinate space that maps to a centered 256×256 viewport on the 640×480 display (x offset 192, y offset 112). The surrounding area is a pink background.
The 8-bit color byte is packed as [7:6]=R, [5:4]=G, [3:2]=B, [1:0]=unused. Each channel has 2 bits (0–3 intensity). Example: 0xFC = white, 0x0C = blue, 0xC0 = red.
Connect a VGA monitor via the TinyTapeout VGA PMOD. To draw a triangle:
rst_n low then release to reset the design.ui_in[7:0], pulsing uio_in[0] (valid) high for one clock cycle per byte:
0xFC = white, 0x0C = blue, 0xC0 = red)Coordinates (0,0) = top-left of viewport; (255,255) = bottom-right.
ui_in / uio_in[0]| # | Input | Output | Bidirectional |
|---|---|---|---|
| 0 | data_byte[0] | hsync | valid (triangle data byte strobe, input) |
| 1 | data_byte[1] | blue[0] | |
| 2 | data_byte[2] | green[0] | |
| 3 | data_byte[3] | red[0] | |
| 4 | data_byte[4] | vsync | |
| 5 | data_byte[5] | blue[1] | |
| 6 | data_byte[6] | green[1] | |
| 7 | data_byte[7] | red[1] |