Pure Hardware Tetris on FPGA: Verilog Modular Design and Synthesis Verification

Implemented a complete Tetris game from scratch on FPGA using Verilog—including all seven standard tetrominoes (I/O/T/S/Z/J/L) with rotation, left/right movement, accelerated drop, line clearing with scoring, and real-time seven-segment display—all hardware logic, no CPU required.
1. Modular Hardware Architecture
The game logic was decomposed into five independent modules, each with a dedicated responsibility, coordinated through a Wrapper:
- Keydebounce: Uses a counter to filter out mechanical key bounce, outputting stable key states
- Bitmap (Grid Manager): Maintains a 32×16-bit grid, handling piece descent, landing detection and fixation, line clearing detection, and full-row scoring
- BlockController (Tetromino Controller): Generates random pieces, responds to directional inputs, executes rotation (4×4 bit matrix rearrangement)
- Segwrapper (Seven-Segment Driver): State machine polling 4-digit seven-segment display for dynamic score refreshing
- Wrapper (Top-Level Scheduler): Manages game state (pause/speed), dispatches key events, generates descent tick signals

2. Key Design Details
Tetromino Rotation: Pure Bit Manipulation
Tetromino rotation is essentially a clockwise transposition of a 4×4 matrix. No lookup table was used—implemented purely with bit rearrangement:
// 4×4 tetromino clockwise rotation by 90°
cur_blk_data <= {cur_blk_data[12], cur_blk_data[8], cur_blk_data[4], cur_blk_data[0],
cur_blk_data[13], cur_blk_data[9], cur_blk_data[5], cur_blk_data[1],
cur_blk_data[14], cur_blk_data[10], cur_blk_data[6], cur_blk_data[2],
cur_blk_data[15], cur_blk_data[11], cur_blk_data[7], cur_blk_data[3]};Dual-Layer Grid: Dynamic Tetromino + Static Background
The Bitmap module maintains two grid layers: bitmap_l (the dynamic layer for the currently falling piece) and bitmap_h (the static layer for settled pieces). During display, the two layers are OR-combined; upon landing, bitmap_l is merged into bitmap_h:
reg [15:0] bitmap_h [31:0]; // Static layer: settled pieces
reg [15:0] bitmap_l [31:0]; // Dynamic layer: currently falling piece
// Landing detection: bitwise AND of bitmap_l and bitmap_h for each row
assign cur_blk_act = (bitmap_l[31] == 16'b0) &&
((bitmap_h[1]&bitmap_l[0])==0) &&
((bitmap_h[2]&bitmap_l[1])==0) && ... ;Scoring System: Full-Row Detection
A 32-way parallel comparator detects the number of full rows, clearing and scoring in one pass—1 point for 1 line, 8 points for 4 lines (Tetris):
assign full_row_num = (bitmap_h[0]==16'hffff) + (bitmap_h[1]==16'hffff) + ... (bitmap_h[31]==16'hffff);
case(full_row_num)
3'd1: game_score_r <= game_score_r + 1;
3'd2: game_score_r <= game_score_r + 2;
3'd3: game_score_r <= game_score_r + 4;
3'd4: game_score_r <= game_score_r + 8; // Tetris!
endcase

3. From Simulation to Synthesis
All five modules passed ModelSim functional simulation—key debouncing, piece movement and rotation, landing and fixation, line clearing and scoring, and seven-segment scanning display were all verified error-free. Subsequently, synthesis and place-and-route were completed in Vivado, and the bitstream file was successfully generated.
What makes this project special: no CPU, no operating system—all game logic (state machines, collision detection, scoring) is implemented entirely by pure combinational and sequential logic circuits. This represents a complete paradigm shift from software thinking to hardware thinking.
Comments