A few days ago I worked a lot on the t08c-opt1
branch of test08c
. It remains in that separate branch only, and it shows a simple ball-and-paddle setup:
- Left-hand wall is missing, and this is where the paddle can be moved up and down using the two buttons.
- The ball will bounce off the walls and paddle. It only needs to touch the paddle anywhere, without touching the left-hand edge of the screen, in order to rebound.
- Wall bounces play a low-pitch tone.
- Paddle bounces play a high-pitch tone, but it's a bit noisy/modulated.
- If the ball touches the left edge of the screen, it will disappear (actually wrapping around into the HBLANK area, probably), while the low-pitch "bounce" tone plays in cycles. There will also be a moment where there is cyan stripe (i.e. the ball colour) that goes across the screen. This isn't really by design: I just haven't yet been able to fit in proper "you lose" game reset logic.
Getting the design to fit has been tricky. Here are some of the things I worked out:
- For fitting a tight design, sometimes XST Speed/Normal optimisation gives better results than Area, and sometimes even "Optimize Speed" for Fitting!
- The settings I used to fit this design are:
- XST:
- Speed/Normal
- Keep Hierarchy: No
- FSM Encoding: Compact
- Case Implementation: Full-Parallel
- Clock Enable: No
- Macro Preserve: No
- XOR Preserve: No
- Fitting:
- Optimize Speed
- Input Limit: 54
- Pterm Limit: 18
- XST:
- I tended to find that I needed Pterms around 26..16 for this design.
- I often also found that I could just test different Pterm figures (with Input Limit: 54) one-by-one on the "Fit" step, instead of using Exhaustive Fit Mode.
- I guess this all works out because most of my "equations" are pretty simple.
- I had the revelation that if
paddleInY
andballInY
ever coincide whileballx
is less than the paddle width, then this means they have collided. This reduced the logic for paddle bounces, and added the benefit of rebounds being possible even if the ball touches the top or bottom edge of the paddle (though not rebounding in a completely realistic way).
Bugs:
- There is a little glitch where the left-most column of the paddle is 1 row lower than the rest of the paddle.
- This is probably related to how the registers being tested haven't yet been updated when we hit
posedge hclk
: It's probably a mix betweenpaddleInY
(as a register insideposedge clk
),border
(a wire), and thergb
register setter inside anotherposedge hclk
block. - I figure this means the point where
rgb
gets set is getting the delayedborder
wire value that is only asserted afterpaddleInY
has been updated. - The fix might be to change the definition of
animate
to trigger somewhere in the HBLANK area of VBLANK so thatpaddleInY
is already set before the line starts rendering. - Anything we can do involving maybe a
negedge hclk
?
- This is probably related to how the registers being tested haven't yet been updated when we hit
- The modulated speaker tone when the ball hits the paddle is a bit annoying. I haven't quite figured that one out yet.
- When the ball goes off the left edge of the screen, things get weird. If we can fit more logic in, it would be good to have a proper game reset condition, though I do actually like how the ball ends up appearing at a "random" location off the right-hand edge of the screen with the current behaviour.
- Paddle starts at 0, but should start within its limit region (
16 <= paddle < 192
). Can we synthesize aninitial
block with this CPLD?
Other improvement ideas:
- Narrower paddle.
ballxd
andballyd
both should flip if there is a collision when (say)ballx[3]
is 0 (because this means the ball has sunk halfway into the paddle, meaning it must surely be hitting the top or bottom rather than right-hand face). Could that screw up top/bottom collisions, or would it be fine?- More colour? Get red channel involved properly?
- Faster ball.
- Is there a way to optimise wall bounces by looking for overlaps again, or is it already as efficient as it can be?