This repository has been archived on 2023-10-25. You can view files and clone it, but cannot push or open issues or pull requests.
Arkanoid2PDE1/Arkanoid.v
Kirill Kirilenko fedfad1352 First commit.
2012-05-21 20:59:39 +04:00

326 lines
7.4 KiB
Verilog

module Arkanoid
#(
// Parameters
parameter SCREEN_WIDTH = 640, // Horizontal screen resolution (in pixels)
parameter SCREEN_HEIGHT = 480, // Vertical screen resolution (in pixels)
parameter CELL_SIZE = 20, // 1 cell has size of 20x20 pixels.
parameter BALL_SIZE = 1, // Game ball is a square of side 1 cell
parameter BALL_SPEED = 2, // Number of cells per second
parameter PLATFORM_WIDTH = 8, // Game platform width
parameter PLATFORM_SPEED = 1, // Number of cells per second
parameter [3:0] BK_COLOR_R = 4'b1111, // Red background
parameter [3:0] BK_COLOR_G = 4'b0000,
parameter [3:0] BK_COLOR_B = 4'b0000,
parameter [3:0] STABLE_COLOR_R = 4'b0011, // ??? color :)
parameter [3:0] STABLE_COLOR_G = 4'b1100,
parameter [3:0] STABLE_COLOR_B = 4'b0110,
parameter [3:0] BALL_COLOR_R = 4'b0000, // Blue ball
parameter [3:0] BALL_COLOR_G = 4'b0000,
parameter [3:0] BALL_COLOR_B = 4'b1111,
parameter [3:0] PLATFORM_COLOR_R = 4'b1111, // Red platforms
parameter [3:0] PLATFORM_COLOR_G = 4'b0000,
parameter [3:0] PLATFORM_COLOR_B = 4'b0000
)
(
// Input Ports
input clk50MHz, // 50 MHz clock on DE1
input button1, button2, button3, button4, // 4 buttons on DE1 (left<->right for 2 players)
// Output Ports
output h_sync,
output v_sync,
output [3:0] red, green, blue, // Current pixel color (4096 colors = 12 bit)
output [6:0] num1, num2, num3, num4, // Digital LED's on DE1
output [7:0] led
);
//////////////////////////////////////
// **** BEGIN OF MODULE HEADER **** //
//////////////////////////////////////
// Output registers
reg [3:0] red_, green_, blue_;
reg [6:0] num1_, num2_, num3_, num4_;
reg [7:0] led_;
localparam FIELD_WIDTH = SCREEN_WIDTH/CELL_SIZE; // Horizontal screen resolution (in cells)
localparam FIELD_HEIGHT = SCREEN_HEIGHT/CELL_SIZE; // Vertical screen resolution (in cells)
// VGA Module
localparam line = 799;
localparam frame = 524;
// 25 MHz clock
reg clk25MHz_;
wire clk25MHz;
// 2D array of cells, stores game field state
reg [1:0] field[0:FIELD_HEIGHT-1][0:FIELD_WIDTH-1];
// Possible cell values: (no comments)
localparam [1:0] EMPTY_CELL = 2'b00;
localparam [1:0] STABLE_CELL = 2'b11;
localparam [1:0] BALL_CELL = 2'b01;
localparam [1:0] PLATFORM_CELL = 2'b10;
// ATTENTION!!!
// All definitions below are in cells only.
//
// Informaton about game ball
integer ball_position_x; // Current coordinates
integer ball_position_y;
reg ball_state; // Current state (0 - stopped, 1 - moving)
reg [1:0] ball_direction; // Current moving direction
// Possible ball directions:
localparam [1:0] LEFT_UP = 2'b00;
localparam [1:0] RIGHT_UP = 2'b01;
localparam [1:0] LEFT_DOWN = 2'b10;
localparam [1:0] RIGHT_DOWN = 2'b11;
// Information about game platforms
integer platform1_position; // Current position (X axis, left border coordinate)
integer platform2_position;
// VGA variables
integer h_counter; // Horizontal pixel counter
integer v_counter; // Vertical pixel counter
integer h_cell; // Horizontal cell counter
integer v_cell; // Vertical cell counter
reg [1:0] current_cell; // Current cell value
// Loops variables
integer i, j;
// Last buttons state
reg button1_state;
reg button2_state;
reg button3_state;
reg button4_state;
////////////////////////////////////
// **** END OF MODULE HEADER **** //
////////////////////////////////////
// Initialization of all module variables
initial
begin
// Place ball to the center of the screen
ball_position_x = FIELD_WIDTH/2;
ball_position_y = FIELD_HEIGHT/2;
ball_state = 0;
// Place platforms at the center of the borders
platform1_position = (FIELD_WIDTH-PLATFORM_WIDTH)/2; // central position
platform2_position = platform1_position;
button1_state = 1'b0;
button2_state = 1'b0;
button3_state = 1'b0;
button4_state = 1'b0;
h_counter = 0;
v_counter = 0;
for (i = 0; i < FIELD_HEIGHT; i = i + 1)
for (j = 0; j< FIELD_WIDTH; j = j + 1)
field[i][j] = EMPTY_CELL;
field[ball_position_y][ball_position_x] = BALL_CELL;
num1_ = 7'b0000000;
num2_ = 7'b0000000;
num3_ = 7'b0000000;
num4_ = 7'b0000000;
end
// Frequency divider (50 MHz to 25 MHz, needed for VGA)
always @ (posedge clk50MHz)
begin
clk25MHz_ = ~clk25MHz_;
end
// VGA sync
always @ (posedge clk25MHz)
begin
if(h_counter == line)
h_counter <= 0;
else
h_counter <= (h_counter + 1);
end
always @ (posedge clk25MHz)
begin
if (v_counter == frame)
v_counter <= 0;
else if (h_counter == line)
v_counter <= (v_counter + 1);
end
always @ (posedge clk25MHz)
begin
if (button1 != button1_state)
begin
if (button1 == 1'b1)
begin
led_[7] = 1'b1;
led_[6] = 1'b1;
if (platform1_position > 0)
platform1_position = platform1_position - 1;
end
else
begin
led_[7] = 1'b0;
led_[6] = 1'b0;
end
button1_state = button1;
end
if (button2 != button2_state)
begin
if (button2 == 1'b1)
begin
led_[5] = 1'b1;
led_[4] = 1'b1;
if (platform1_position < FIELD_WIDTH-PLATFORM_WIDTH-1)
platform1_position = platform1_position + 1;
end
else
begin
led_[5] = 1'b0;
led_[4] = 1'b0;
end
button2_state = button2;
end
if (button3 != button3_state)
begin
if (button3 == 1'b1)
begin
led_[3] = 1'b1;
led_[2] = 1'b1;
if (platform2_position > 0)
platform2_position = platform2_position - 1;
end
else
begin
led_[3] = 1'b0;
led_[2] = 1'b0;
end
button3_state = button3;
end
if (button4 != button4_state)
begin
if (button4 == 1'b1)
begin
led_[1] = 1'b1;
led_[0] = 1'b1;
if (platform2_position < FIELD_WIDTH-PLATFORM_WIDTH-1)
platform2_position = platform2_position + 1;
end
else
begin
led_[1] = 1'b0;
led_[0] = 1'b0;
end
button4_state = button4;
end
for (i = 0; i < FIELD_WIDTH; i = i + 1)
begin
if ((i >= platform2_position) && (i <= platform2_position+PLATFORM_WIDTH))
field[0][i] = PLATFORM_CELL;
else
field[0][i] = EMPTY_CELL;
if ((i >= platform1_position) && (i <= platform1_position+PLATFORM_WIDTH))
field[FIELD_HEIGHT-1][i] = PLATFORM_CELL;
else
field[FIELD_HEIGHT-1][i] = EMPTY_CELL;
end
// VGA output
h_cell = (h_counter-143)/CELL_SIZE;
v_cell = (v_counter-34)/CELL_SIZE;
if ((v_counter > 34) && (v_counter < 514) && (h_counter > 143) && (h_counter < 783))
begin
current_cell = field[v_cell][h_cell];
case(current_cell)
EMPTY_CELL:
begin
red_ = BK_COLOR_R;
green_ = BK_COLOR_G;
blue_ = BK_COLOR_B;
end
STABLE_CELL:
begin
red_ = STABLE_COLOR_R;
green_ = STABLE_COLOR_G;
blue_ = STABLE_COLOR_B;
end
BALL_CELL:
begin
red_ = BALL_COLOR_R;
green_ = BALL_COLOR_G;
blue_ = BALL_COLOR_B;
end
PLATFORM_CELL:
begin
red_ = PLATFORM_COLOR_R;
green_ = PLATFORM_COLOR_G;
blue_ = PLATFORM_COLOR_B;
end
endcase
end
else
begin
red_ = 4'b0000;
green_ = 4'b0000;
blue_ = 4'b0000;
end
end
assign clk25MHz = clk25MHz_;
assign h_sync = ~((h_counter > 0) && (h_counter < 95));
assign v_sync = ~((v_counter == 0) || (v_counter == 1));
assign red = red_;
assign green = green_;
assign blue = blue_;
assign led = led_;
assign num1 = num1_;
assign num2 = num2_;
assign num3 = num3_;
assign num4 = num4_;
endmodule