Errata: Designing Video Game Hardware in Verilog#
Chapter 9: The constants in the book differ from what’s in the
hvsync_generator.v
file, which are:
parameter V_TOP = 5; // vertical top border
parameter V_BOTTOM = 14; // vertical bottom border
parameter V_SYNC = 3; // vertical sync # lines
The simulated CRT values are based on NTSC, the goal being to get a 256x240 pixel display like a NES. NTSC needs 262 lines, and 3 lines of VSYNC. I chose the top and bottom borders to center the frame on my TV when using the FPGA.
In the simulator, the horizontal scanlines are shortened (23 + 7 + 23 cycles) to save CPU time, while still being long enough to do stuff (read RAM etc.) between scanlines. The FPGA examples use a full 381-cycle scanline, but have the same vertical timing.
The Digits and 7 Segment Decoder examples use arrays of 5-bit words.
The expression used to index them is (xofs ^ 3'b111)
which reverses
the bits left-to-right, but also indexes bit indices 5-7 which are out of
range. Verilator returns 0 for this case, but some FPGA toolchains return
undefined values. To fix this, replace the g
assignment with this:
wire g = display_on && (xofs >= 3'b011) && bits[xofs ^ 3'b111];
In the RAM Text Display example, the cells are updating improperly when the beam is offscreen. This change to line 75 fixes it:
ram_writeenable <= display_on && rom_yofs == 7;
In the Sprite Rotation example, some 3rd party toolchains may have issues with the syntax. You may have to make these sorts of changes:
function [3:0] trunc_int_to_4(input integer val);
trunc_int_to_4 = val[3:0];
endfunction
0: sin_16x4 = trunc_int_to_4(y);
player_x_fixed <= player_x_fixed + 12'(sin_16x4(player_rot+8));
Some of the examples that trigger on derived clocks might exhibit instability when synthesized to FPGA, for example the bouncing ball example:
always @(posedge ball_vert_collide)
begin
ball_vert_move <= -ball_vert_move;
end
See this Github issue for potential fixes.