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

  1. What you need
  2. Build and load it
  3. Play
  4. Play and test over USB
  5. Keep it after power-off
  6. Run the simulation
  7. Change it
  8. When something looks wrong

What you need

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

ControlDoes
Start (shield) or KEY0starts a game; after GAME OVER, starts the next one
Joysticksteers. 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-segmentyour score
LEDR0..4spare lives; LEDR8 lit = paused, LEDR9 lit = invincible (test modes, set over USB)
Buzzerthe 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 wantWhere
another mazeedit 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 harderspeed_of, fright_frames and mode_frames in pac_logic.sv
other coloursthe ghost colours are parameters in pac_draw.sv; the maze and text colours are constants there
a different tunethe intro() table in pac_sound.sv: {half period, frames}; half = 25,000,000 / (2 × Hz)
fruit, pop-up pointsnot 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 seeLikelyDo
White bars at the left and right of the LCDnormal: the panel is 800 wide, the picture 640nothing
Nothing on the screen, LEDs darkthe board is not programmed, or the PLL did not lockpython scripts/de10.py jtag to see the board, then program again
The joystick does nothing but USB letters workthe shield is not seated, or the ADC pins are not the shield'spower off, reseat the shield; run example 04 to see the raw readings
Pac-Man ignores a turnhe was not at a tile centre yet; a push is remembered until the next centrehold the direction a little longer
No soundmuted over USB ('m'), or the buzzer is on another shield linesend m; check ARDUINO_IO[12] in pacman_top.sv against your shield
Build failsa changed sourcerun the simulation first: Icarus points at the line; then logs/build.log
Timing not met after a changea long combinational path in the draw modulepython scripts/de10.py report projects/pacman; register the new signal once per frame or per pixel