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.

Comments