Pac-Man: user guide
From the repo to a game on your board, and everything you can do with it afterwards. Every command runs from the
repo's root folder in the env virtualenv; the chat does them for you if you ask.
Contents
- What you need
- Build and load it
- Play
- Play and test over USB
- Keep it after power-off
- Run the simulation
- Change it
- When something looks wrong
What you need
- A DE10-Lite with the LCD / game-pad shield on its Arduino header (the game needs the screen and the joystick).
- Quartus Prime Lite 17.1 installed as in stage 1 of the BKM (
python scripts/doctor.pyshows no FAIL). - The repo cloned,
envcreated (setup-my-computerdoes this), the board on the USB cable.
Build and load it
The sources are in the repo; one build makes the bitstream (the repo keeps none, they are 3 MB each):
python scripts/de10.py build projects/pacman # about 4 minutes; ends with the resource and timing summary
python scripts/de10.py program projects/pacman # loads it over the USB-Blaster; runs until power-off
From the archive instead (for example in the Quartus GUI): Project → Restore Archived Project → pacman.qar,
then Processing → Start Compilation, then Tools → Programmer with output_files/pacman.sof. The archive
holds the sources, the settings, the wall picture and the maze generator.
What you should see right after loading: the maze with all its dots, the four ghosts in and above the house, PUSH START in the middle, 00 on the 7-segment digits, two LEDs lit.
Play
| Control | Does |
|---|---|
| Start (shield) or KEY0 | starts a game; after GAME OVER, starts the next one |
| Joystick | steers. The last direction you pushed is remembered: push it before the corner and Pac-Man turns when he reaches it. Pushing the opposite way turns him round at once. |
| 7-segment | your score |
| LEDR0..4 | spare lives; LEDR8 lit = paused, LEDR9 lit = invincible (test modes, set over USB) |
| Buzzer | the intro tune, waka on dots, a low warble while the ghosts are blue, a sweep when you eat one, the death sound |
Rules, briefly: 10 points a dot, 50 a power pellet. A power pellet turns the ghosts blue for a few seconds: eat them for 200, 400, 800, 1600. Eat all 244 dots and the maze flashes: the next level is faster and the blue time shorter. Three lives, one more at 10,000. The high score stays until the board loses power.
Play and test over USB
The game listens on the JTAG UART, the same link the BKM uses for logs. Each letter is one command:
python scripts/de10.py send s # Start
python scripts/de10.py send u # up; also l, d, r (left, down, right)
python scripts/de10.py send p # pause / resume
python scripts/de10.py send i # invincible on / off (the ghosts cannot catch you)
python scripts/de10.py send m # mute / unmute
python scripts/de10.py send "?" # the debug link's status line (buttons, switches, frame counter)
python scripts/de10.py screen x.png # the screen as the board shows it, 320 x 240 (about 6 s)
python scripts/de10.py cam x.jpg # a webcam still of the board, if a camera is set up
This is how the AI tested the game without hands, and how you can script a test of your own: send letters, capture, look.
Keep it after power-off
Loading with program lasts until the power goes; to make Pac-Man the design the board starts with:
python scripts/de10.py flash projects/pacman # writes and verifies output_files/pacman.pof, about 15 s
It replaces whatever was in the flash before (the chat asks first). Loading other designs with program afterwards
does not touch it; Pac-Man returns at the next power-up. The library's flash-design skill and example 13 explain
the .pof.
Run the simulation
python scripts/sim.py projects/pacman/sim/tb_pacman.sv # Icarus, about 2.5 minutes, ends with PASS
python scripts/sim.py projects/pacman/sim/tb_pacman.sv --gui # the same, then GTKWave with the waveform
It plays a scripted game and writes frames next to the testbench: attract.ppm, ready.ppm,
play.ppm, mid.ppm, dying.ppm. Open them with any image viewer, or convert with Pillow
(Image.open("x.ppm").save("x.png")). The checks it makes are listed on the overview.
Change it
| You want | Where |
|---|---|
| another maze | edit the 31-line picture in assets/make_maze.py (# wall, . dot, o power, - door, space open), run python projects/pacman/assets/make_maze.py, check assets/maze_preview.png, rebuild. Keep 28 × 31 and the tunnel on row 14, or adjust the fixed points in pac_logic.sv. |
| easier or harder | speed_of, fright_frames and mode_frames in pac_logic.sv |
| other colours | the ghost colours are parameters in pac_draw.sv; the maze and text colours are constants there |
| a different tune | the intro() table in pac_sound.sv: {half period, frames}; half = 25,000,000 / (2 × Hz) |
| fruit, pop-up points | not built yet: a timer in pac_logic that places a bonus on the dot RAM's spare value (3), and a small sprite in pac_draw. The chat can add them. |
After any change: simulation (PASS), build (timing OK), program, play. The testbench renders the frames, so most
mistakes show up as a picture before the board is involved.
When something looks wrong
| You see | Likely | Do |
|---|---|---|
| White bars at the left and right of the LCD | normal: the panel is 800 wide, the picture 640 | nothing |
| Nothing on the screen, LEDs dark | the board is not programmed, or the PLL did not lock | python scripts/de10.py jtag to see the board, then program again |
| The joystick does nothing but USB letters work | the shield is not seated, or the ADC pins are not the shield's | power off, reseat the shield; run example 04 to see the raw readings |
| Pac-Man ignores a turn | he was not at a tile centre yet; a push is remembered until the next centre | hold the direction a little longer |
| No sound | muted over USB ('m'), or the buzzer is on another shield line | send m; check ARDUINO_IO[12] in pacman_top.sv against your shield |
| Build fails | a changed source | run the simulation first: Icarus points at the line; then logs/build.log |
| Timing not met after a change | a long combinational path in the draw module | python scripts/de10.py report projects/pacman; register the new signal once per frame or per pixel |