/* player_stats - Holds two-digit score and one-digit lives counter. scoreboard_generator - Outputs video signal with score/lives digits. */ module player_stats(reset, score0, score1, lives, incscore, declives); input reset; output reg [3:0] score0; output reg [3:0] score1; input incscore; output reg [3:0] lives; input declives; always @(posedge incscore or posedge reset) begin if (reset) begin score0 <= 0; score1 <= 0; end else if (score0 == 9) begin score0 <= 0; score1 <= score1 + 1; end else begin score0 <= score0 + 1; end end always @(posedge declives or posedge reset) begin if (reset) lives <= 3; else if (lives != 0) lives <= lives - 1; end endmodule module scoreboard_generator(score0, score1, lives, vpos, hpos, board_gfx); input [3:0] score0; input [3:0] score1; input [3:0] lives; input [8:0] vpos; input [8:0] hpos; output board_gfx; reg [3:0] score_digit; reg [4:0] score_bits; always @(*) begin case (hpos[7:5]) 1: score_digit = score1; 2: score_digit = score0; 6: score_digit = lives; default: score_digit = 15; // no digit endcase end digits10_array digits( .digit(score_digit), .yofs(vpos[4:2]), .bits(score_bits) ); assign board_gfx = score_bits[hpos[4:2] ^ 3'b111]; endmodule /* ROM module with 5x5 bitmaps for the digits 0-9. digits10_case - Uses the case statement. digits10_array - Uses an array and initial block. These two modules are functionally equivalent. */ // module for 10-digit bitmap ROM module digits10_case(digit, yofs, bits); input [3:0] digit; // digit 0-9 input [2:0] yofs; // vertical offset (0-4) output reg [4:0] bits; // output (5 bits) // combine {digit,yofs} into single ROM address wire [6:0] caseexpr = {digit,yofs}; always @(*) case (caseexpr)/*{w:5,h:5,count:10}*/ 7'o00: bits = 5'b11111; 7'o01: bits = 5'b10001; 7'o02: bits = 5'b10001; 7'o03: bits = 5'b10001; 7'o04: bits = 5'b11111; 7'o10: bits = 5'b01100; 7'o11: bits = 5'b00100; 7'o12: bits = 5'b00100; 7'o13: bits = 5'b00100; 7'o14: bits = 5'b11111; 7'o20: bits = 5'b11111; 7'o21: bits = 5'b00001; 7'o22: bits = 5'b11111; 7'o23: bits = 5'b10000; 7'o24: bits = 5'b11111; 7'o30: bits = 5'b11111; 7'o31: bits = 5'b00001; 7'o32: bits = 5'b11111; 7'o33: bits = 5'b00001; 7'o34: bits = 5'b11111; 7'o40: bits = 5'b10001; 7'o41: bits = 5'b10001; 7'o42: bits = 5'b11111; 7'o43: bits = 5'b00001; 7'o44: bits = 5'b00001; 7'o50: bits = 5'b11111; 7'o51: bits = 5'b10000; 7'o52: bits = 5'b11111; 7'o53: bits = 5'b00001; 7'o54: bits = 5'b11111; 7'o60: bits = 5'b11111; 7'o61: bits = 5'b10000; 7'o62: bits = 5'b11111; 7'o63: bits = 5'b10001; 7'o64: bits = 5'b11111; 7'o70: bits = 5'b11111; 7'o71: bits = 5'b00001; 7'o72: bits = 5'b00001; 7'o73: bits = 5'b00001; 7'o74: bits = 5'b00001; 7'o100: bits = 5'b11111; 7'o101: bits = 5'b10001; 7'o102: bits = 5'b11111; 7'o103: bits = 5'b10001; 7'o104: bits = 5'b11111; 7'o110: bits = 5'b11111; 7'o111: bits = 5'b10001; 7'o112: bits = 5'b11111; 7'o113: bits = 5'b00001; 7'o114: bits = 5'b11111; default: bits = 0; endcase endmodule module digits10_array(digit, yofs, bits); input [3:0] digit; // digit 0-9 input [2:0] yofs; // vertical offset (0-4) output [4:0] bits; // output (5 bits) reg [4:0] bitarray[0:15][0:4]; // ROM array (16 x 5 x 5 bits) assign bits = bitarray[digit][yofs]; // assign module output integer i,j; initial begin/*{w:5,h:5,count:10}*/ bitarray[0][0] = 5'b11111; bitarray[0][1] = 5'b10001; bitarray[0][2] = 5'b10001; bitarray[0][3] = 5'b10001; bitarray[0][4] = 5'b11111; bitarray[1][0] = 5'b01100; bitarray[1][1] = 5'b00100; bitarray[1][2] = 5'b00100; bitarray[1][3] = 5'b00100; bitarray[1][4] = 5'b11111; bitarray[2][0] = 5'b11111; bitarray[2][1] = 5'b00001; bitarray[2][2] = 5'b11111; bitarray[2][3] = 5'b10000; bitarray[2][4] = 5'b11111; bitarray[3][0] = 5'b11111; bitarray[3][1] = 5'b00001; bitarray[3][2] = 5'b11111; bitarray[3][3] = 5'b00001; bitarray[3][4] = 5'b11111; bitarray[4][0] = 5'b10001; bitarray[4][1] = 5'b10001; bitarray[4][2] = 5'b11111; bitarray[4][3] = 5'b00001; bitarray[4][4] = 5'b00001; bitarray[5][0] = 5'b11111; bitarray[5][1] = 5'b10000; bitarray[5][2] = 5'b11111; bitarray[5][3] = 5'b00001; bitarray[5][4] = 5'b11111; bitarray[6][0] = 5'b11111; bitarray[6][1] = 5'b10000; bitarray[6][2] = 5'b11111; bitarray[6][3] = 5'b10001; bitarray[6][4] = 5'b11111; bitarray[7][0] = 5'b11111; bitarray[7][1] = 5'b00001; bitarray[7][2] = 5'b00001; bitarray[7][3] = 5'b00001; bitarray[7][4] = 5'b00001; bitarray[8][0] = 5'b11111; bitarray[8][1] = 5'b10001; bitarray[8][2] = 5'b11111; bitarray[8][3] = 5'b10001; bitarray[8][4] = 5'b11111; bitarray[9][0] = 5'b11111; bitarray[9][1] = 5'b10001; bitarray[9][2] = 5'b11111; bitarray[9][3] = 5'b00001; bitarray[9][4] = 5'b11111; // clear unused array entries for (i = 10; i <= 15; i++) for (j = 0; j <= 4; j++) bitarray[i][j] = 0; end endmodule /* Video sync generator, used to drive a simulated CRT. To use: - Wire the hsync and vsync signals to top level outputs - Add a 3-bit (or more) "rgb" output to the top level */ module hvsync_generator(clk, reset, hsync, vsync, display_on, hpos, vpos); input clk; input reset; output reg hsync, vsync; output display_on; output reg [8:0] hpos; output reg [8:0] vpos; // declarations for TV-simulator sync parameters // horizontal constants parameter H_DISPLAY = 256; // horizontal display width parameter H_BACK = 23; // horizontal left border (back porch) parameter H_FRONT = 7; // horizontal right border (front porch) parameter H_SYNC = 23; // horizontal sync width // vertical constants parameter V_DISPLAY = 240; // vertical display height parameter V_TOP = 5; // vertical top border parameter V_BOTTOM = 14; // vertical bottom border parameter V_SYNC = 3; // vertical sync # lines // derived constants parameter H_SYNC_START = H_DISPLAY + H_FRONT; parameter H_SYNC_END = H_DISPLAY + H_FRONT + H_SYNC - 1; parameter H_MAX = H_DISPLAY + H_BACK + H_FRONT + H_SYNC - 1; parameter V_SYNC_START = V_DISPLAY + V_BOTTOM; parameter V_SYNC_END = V_DISPLAY + V_BOTTOM + V_SYNC - 1; parameter V_MAX = V_DISPLAY + V_TOP + V_BOTTOM + V_SYNC - 1; wire hmaxxed = (hpos == H_MAX) || reset; // set when hpos is maximum wire vmaxxed = (vpos == V_MAX) || reset; // set when vpos is maximum // horizontal position counter always @(posedge clk) begin hsync <= (hpos>=H_SYNC_START && hpos<=H_SYNC_END); if(hmaxxed) hpos <= 0; else hpos <= hpos + 1; end // vertical position counter always @(posedge clk) begin vsync <= (vpos>=V_SYNC_START && vpos<=V_SYNC_END); if(hmaxxed) if (vmaxxed) vpos <= 0; else vpos <= vpos + 1; end // display_on is set when beam is in "safe" visible frame assign display_on = (hpos