⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd_test_pongball_crosshair.v

📁 PS2的源代码VHDL语言实现
💻 V
字号:
//-------------------------------------------------------------------------------------
//
// Author: John Clayton
// Date  : Mar. 29, 2001
// Update: April 4, 2001  Copied this file from "lcd_3.v"
// Update: May   3, 2001  Re-copied from "lcd_2.v" (better logic)
//                        Stripped out extraneous stuff.
// Update: May   3, 2001  Added synchronous reset signals, also added
//                        "ball_x_enable" and "ball_y_enable" signals.
//                        Changed all occurrences of "block" in code to "ball"
//-------------------------------------------------------------------------------------
// This module exercises an LCD display panel (from an IBM 700C Thinkpad laptop)
//
// The LCD panel requires 16 signals to be driven.
// There are four signals each for red, green and blue.
// There is one sync signal.
// There is one clock signal.
// And there are two control signals: backlight_on and backlight_bright.
//
// The clock used for the "pongball" is "sys_clk" of 32.000 MHz, present on GCLK1
// The clock used for the LCD is "lcd_clk" of 49.152 MHz clock, present on GCLK0
//-------------------------------------------------------------------------------------


`resetall
`timescale 1ns/100ps

`define COUNTER1_MODULO 80000

`define H_MODULO 704
`define V_MODULO 540
`define H_PIXELS 640
`define V_PIXELS 480

`define COORDINATES_SIZE 10     // Size of coordinates in bits
`define BALL_SIZE 16            // Size of moving ball in pixels
`define CROSSHAIR_SIZE 15       // Size of crosshair "leg" in pixels
                                // (not including central pixel)

module lcd_test_pongball_crosshair (
  sys_clk,
  lcd_clk,
  sys_reset,
  lcd_reset,
  ball_x_enable,
  ball_y_enable,
  crosshair_x_pos,
  crosshair_y_pos,
  crosshair_color,
  lcd_drive
  );
  
// I/O declarations
input sys_clk;            // 32.000 MHz
input lcd_clk;            // 49.152 MHz
input sys_reset;          // synchronous reset
input lcd_reset;          // synchronous reset
input ball_x_enable;      // when high, allows x movement of pongball
input ball_y_enable;      // when high, allows y movement of pongball
input [9:0] crosshair_x_pos;   // 0 to 639
input [9:0] crosshair_y_pos;   // 0 to 479
input [2:0] crosshair_color;   // [0] = red, [1] = blue, [2] = green
output [15:0] lcd_drive;  // Signals used to drive LCD panel


// Internal signal declarations

// For the LEDs and switches part
reg [19:0] counter1;  // Used to divide by 1 million
wire clk_128hz;       // Cout of counter1

reg [7:0] counter2;

// For the LCD part

reg [3:0] lcd_red;
reg [3:0] lcd_green;
reg [3:0] lcd_blue;
wire lcd_sync;
wire lcd_backlight_on = 1;
wire lcd_backlight_bright = 1;
wire v_clk;
wire h_pulse;
wire v_pulse;

reg lcd_pixel_clk;
reg [9:0] v_count;
reg [9:0] h_count;

reg [9:0] ball_x_pos;
reg [9:0] ball_y_pos;
reg [9:0] ball_x_increment;
reg [9:0] ball_y_increment;

//--------------------------------------------------------------------------
// Module code


//----------LED and switches part----------------------
always @(posedge sys_clk)
begin
  if (sys_reset) counter1 <= 0;
  else if (counter1 == (`COUNTER1_MODULO-1)) counter1 <=0;
  else counter1 <= counter1 + 1;
end
assign clk_128hz = (counter1 == (`COUNTER1_MODULO-1));

always @(posedge sys_clk)
begin
  if (sys_reset) counter2 <= 0;
  else if (clk_128hz) counter2 <= counter2 + 1;
end


//----------LCD part-----------------------------------

// This "Rubber bands" together the output signals. (concatenation).
assign lcd_drive = {lcd_backlight_bright,
                    lcd_backlight_on,
                    lcd_sync,
                    lcd_pixel_clk,
                    ~lcd_blue,             // Values are active low.
                    ~lcd_green,            // Values are active low.
                    ~lcd_red};             // Values are active low.

// lcd_pixel_clock counter
always @(posedge lcd_clk)
begin
  if (lcd_reset) lcd_pixel_clk <= 0;
  else lcd_pixel_clk <= ~lcd_pixel_clk;
end

// Horizontal counter
always @(posedge lcd_clk)
begin
  if (lcd_reset) h_count <= 0;
  else if (lcd_pixel_clk)
  begin
    if (h_count == `H_MODULO-1) h_count <=0;
    else h_count <= h_count + 1;
  end
end
assign v_clk = ((h_count == `H_MODULO-1) && lcd_pixel_clk);

// Vertical counter
always @(posedge lcd_clk)
begin
  if (lcd_reset) v_count <=0;
  else if (v_clk)
  begin
    if (v_count == `V_MODULO-1) v_count <= 0;
    else v_count <= v_count + 1;
  end
end

// Create horizontal sync pulses, punctuated by periods of "high"
//   which corresponds to "vertical retrace time."
assign lcd_sync = ((h_count >= `H_PIXELS) || (v_count >= `V_PIXELS));


// A "roving" ball of color
always @(posedge sys_clk)
begin
  if (sys_reset)
  begin
    ball_x_pos <= 0;
    ball_y_pos <= 0;
    ball_x_increment <= 1;
    ball_y_increment <= 1;
  end
  else if (clk_128hz)
  begin
    if (ball_x_enable) ball_x_pos <= ball_x_pos + ball_x_increment;
    if (ball_y_enable) ball_y_pos <= ball_y_pos + ball_y_increment;
    if (ball_x_pos == (`H_PIXELS - `BALL_SIZE)) ball_x_increment <= -1;
    else if (ball_x_pos == 0) ball_x_increment <= 1;
    if (ball_y_pos == (`V_PIXELS - `BALL_SIZE)) ball_y_increment <= -1;
    else if (ball_y_pos == 0) ball_y_increment <= 1;
  end
end

// Color testing pattern
always @(
         h_count
         or v_count
         or ball_x_pos
         or ball_y_pos
         or crosshair_x_pos
         or crosshair_y_pos
         or crosshair_color
         )
begin
  // Start with black background as default.
  lcd_red <= 0;
  lcd_green <= 0;
  lcd_blue <= 0;
  // Fixed block of color
  if ((h_count <= 63) && (v_count <= 63)) lcd_green <= 10;
  // "Graph paper" pattern
  if (h_count[4:0] == 0) lcd_blue <= 15;
  if (v_count[4:0] == 0) lcd_red <= 15;
  // PONG type "net" (vertical line)
  if ((h_count < 322) && (h_count >= 318))
    begin
      lcd_blue <= 8;
      lcd_red <= 8;
      lcd_green <=8;
    end
  // PONG type "ball" (square)
  if (
        (h_count >= ball_x_pos) && (h_count < (ball_x_pos + `BALL_SIZE))
     && (v_count >= ball_y_pos) && (v_count < (ball_y_pos + `BALL_SIZE))
     )
    begin
      lcd_blue <= 15;
      lcd_red <= 15;
      lcd_green <= 15;
    end
  // Crosshairs -- highest priority
  if (
        (
            (h_count >= (crosshair_x_pos - `CROSSHAIR_SIZE))
         && (h_count <= (crosshair_x_pos + `CROSSHAIR_SIZE))
         && (v_count == crosshair_y_pos)
         )
      ||
        (
            (v_count >= (crosshair_y_pos - `CROSSHAIR_SIZE))
         && (v_count <= (crosshair_y_pos + `CROSSHAIR_SIZE))
         && (h_count == crosshair_x_pos)
         )
     )
    begin
      lcd_red <= {4{crosshair_color[0]}};
      lcd_green <= {4{crosshair_color[1]}};
      lcd_blue <= {4{crosshair_color[2]}};
    end
end


endmodule

//`undef COUNTER1_MODULO
//`undef H_MODULO
//`undef V_MODULO
//`undef H_PIXELS
//`undef V_PIXELS
//`undef BALL_SIZE

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -