Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- `define NUMOFENEMIES 2
- module Brick_Escape
- (
- CLOCK_50, // On Board 50 MHz
- // Your inputs and outputs here
- KEY,
- SW,
- // The ports below are for the VGA output. Do not change.
- VGA_CLK, // VGA Clock
- VGA_HS, // VGA H_SYNC
- VGA_VS, // VGA V_SYNC
- VGA_BLANK_N, // VGA BLANK
- VGA_SYNC_N, // VGA SYNC
- VGA_R, // VGA Red[9:0]
- VGA_G, // VGA Green[9:0]
- VGA_B // VGA Blue[9:0]
- );
- input CLOCK_50; // 50 MHz
- input [9:0] SW;
- input [3:0] KEY;
- // Declare your inputs and outputs here
- // Do not change the following outputs
- output VGA_CLK; // VGA Clock
- output VGA_HS; // VGA H_SYNC
- output VGA_VS; // VGA V_SYNC
- output VGA_BLANK_N; // VGA BLANK
- output VGA_SYNC_N; // VGA SYNC
- output [9:0] VGA_R; // VGA Red[9:0]
- output [9:0] VGA_G; // VGA Green[9:0]
- output [9:0] VGA_B; // VGA Blue[9:0]
- wire resetn;
- assign resetn = ~SW[0];
- // Create the colour, x, y and writeEn wires that are inputs to the controller.
- wire [2:0] colour;
- wire [6:0] x;
- wire [6:0] y;
- // writeEn will always be high
- wire writeEn = 1'b1;
- // Create an Instance of a VGA controller - there can be only one!
- // Define the number of colours as well as the initial background
- // image file (.MIF) for the controller.
- vga_adapter VGA(
- .resetn(resetn),
- .clock(CLOCK_50),
- .colour(colour),
- .x(x),
- .y(y),
- .plot(writeEn),
- /* Signals for the DAC to drive the monitor. */
- .VGA_R(VGA_R),
- .VGA_G(VGA_G),
- .VGA_B(VGA_B),
- .VGA_HS(VGA_HS),
- .VGA_VS(VGA_VS),
- .VGA_BLANK(VGA_BLANK_N),
- .VGA_SYNC(VGA_SYNC_N),
- .VGA_CLK(VGA_CLK));
- defparam VGA.RESOLUTION = "160x120";
- defparam VGA.MONOCHROME = "FALSE";
- defparam VGA.BITS_PER_COLOUR_CHANNEL = 1;
- defparam VGA.BACKGROUND_IMAGE = "black.mif";
- // RATE DIVIDER TO SLOW DOWN THE UPDATE PROCESS FOR PLAYER AND ENEMIES
- wire update; // Will be used to update position of player and enemies
- rateDivider ratedivider(CLOCK_50, update);
- // PLAYER PROPERTIES /////////////////////////////////////////////////////////////////
- wire [6:0] playerx; // x position of the player
- wire [6:0] playery; // y position of the player
- Player player(update, resetn, playerx, playery, KEY);
- // ENEMIES PROPERTIES ////////////////////////////////////////////////////////////////
- wire [6:0] enemyx;
- wire [6:0] enemyy;
- wire [3:0] enemyIterator;
- localparam [3:0] NUMOFENEMIES = 2;
- EnemyController enemies(update, resetn, enemyx, enemyy, enemyIterator);
- // CONTROL AND DATAPATH PROPERTIES ///////////////////////////////////
- wire go_next, clear_screen, update_player, update_enemy, wait_screen; // ENABLE SIGNALS
- Controller controller(CLOCK_50, resetn, go_next, clear_screen, update_player, update_enemy, wait_screen);
- Datapath datapath(CLOCK_50, resetn, go_next, clear_screen, update_player, update_enemy, wait_screen, playerx, playery, enemyx, enemyy, enemyIterator, x, y, colour);
- endmodule
- module Datapath(clk, resetn, go_next, clear_screen, update_player, update_enemy, wait_screen, playerx, playery, enemyx, enemyy, enemyIterator, x, y, colour);
- input clk;
- input resetn;
- input clear_screen;
- input update_player;
- input update_enemy;
- input wait_screen;
- input [6:0] playerx;
- input [6:0] playery;
- input [6:0] enemyx;
- input [6:0] enemyy;
- parameter NUMOFENEMIES = 2;
- reg [30:0] wait_screen_counter;
- reg [6:0] clear_screen_x;
- reg [6:0] clear_screen_y;
- output reg [3:0] enemyIterator;
- output reg go_next;
- output reg [6:0] x;
- output reg [6:0] y;
- output reg [2:0] colour;
- always@(posedge clk)
- begin
- if(~resetn) // Basic reset functionality
- begin
- clear_screen_x = 1'd0;
- clear_screen_y = 1'd0;
- go_next = 1'd0;
- x = 1'd0;
- y = 1'd0;
- colour = 3'b000;
- end
- else
- begin
- /* This will fully clear the screen, in other words this part of the datapath will go
- through each pixel on the vga screen and place a black pixel on the current
- pixel and will continue to do so until iterates through the whole screen.
- */
- if(clear_screen)
- begin
- go_next = 1'd0;
- x = clear_screen_x;
- y = clear_screen_y;
- colour = 3'b000;
- clear_screen_x = clear_screen_x + 1'd1; // Continue onto the next pixel to the right
- if(clear_screen_x > 7'd126) // Iteration reaches the far right of the screen
- begin
- clear_screen_x = 1'd0; // Restart the iteration back to the beginning (far left of the screen)
- clear_screen_y = clear_screen_y + 1'd1; // Go one pixel down
- end
- else if(clear_screen_x == 7'd126 && clear_screen_y == 7'd126) // Iteration reaches the end of the screen (bottom-right corner)
- begin
- go_next = 1'd1; // Go to the next state
- clear_screen_x = 1'd0; // Reset the iteration for future iterations
- clear_screen_y = 1'd0;
- end
- end
- /* This will re-display the updated x and y position of the player
- */
- if(update_player)
- begin
- go_next = 1'd0;
- x = playerx;
- y = playery;
- colour = 3'b011;
- go_next = 1'd1;
- end
- /* This will re-display the updated x and y position of each enemy
- */
- if(update_enemy)
- begin
- go_next = 1'd0;
- x = enemyx;
- y = enemyy;
- colour = 3'b100;
- enemyIterator = enemyIterator + 1'd1;
- if(enemyIterator >= NUMOFENEMIES)
- begin
- go_next = 1'd1;
- enemyIterator = 1'd0;
- end
- end
- /* Acts as the end of the refresh
- */
- if(wait_screen)
- begin
- go_next = 1'd1;
- end
- end
- end
- endmodule
- module Controller(clk, resetn, go_next, clear_screen, update_player, update_enemy, wait_screen);
- input clk;
- input resetn;
- input go_next;
- output reg clear_screen;
- output reg update_player;
- output reg update_enemy;
- output reg wait_screen;
- reg [1:0] current_state, next_state;
- // Represents the different states of the finite state machine
- localparam S_CLEAR_SCREEN = 2'd0,
- S_UPDATE_PLAYER = 2'd1,
- S_UPDATE_ENEMY = 2'd2,
- S_WAIT_SCREEN = 2'd3;
- always @(*)
- begin: state_table
- case (current_state)
- S_CLEAR_SCREEN: next_state = go_next ? S_UPDATE_PLAYER : S_CLEAR_SCREEN;
- S_UPDATE_PLAYER: next_state = go_next ? S_UPDATE_ENEMY : S_UPDATE_PLAYER;
- S_UPDATE_ENEMY: next_state = go_next ? S_WAIT_SCREEN : S_UPDATE_ENEMY;
- S_WAIT_SCREEN: next_state = go_next ? S_CLEAR_SCREEN : S_WAIT_SCREEN;
- default: next_state = S_UPDATE_PLAYER;
- endcase
- end
- always @(*)
- begin: enable_signals
- clear_screen = 1'd0;
- update_player = 1'd0;
- update_enemy = 1'd0;
- wait_screen = 1'd0;
- case (current_state)
- S_CLEAR_SCREEN:
- begin
- clear_screen = 1'd1;
- end
- S_UPDATE_PLAYER:
- begin
- update_player = 1'd1;
- end
- S_UPDATE_ENEMY:
- begin
- update_enemy = 1'd1;
- end
- S_WAIT_SCREEN:
- begin
- wait_screen = 1'd1;
- end
- endcase
- end
- always @(posedge clk)
- begin: curr_state_FSM
- if(~resetn)
- current_state <= S_CLEAR_SCREEN;
- else
- current_state <= next_state;
- end
- endmodule
- module EnemyController(update, resetn, enemyx, enemyy, enemyIterator);
- input update;
- input resetn;
- input [3:0] enemyIterator;
- parameter NUMOFENEMIES = 2;
- output reg [6:0] enemyx; // x position of the current enemy
- output reg [6:0] enemyy; // y position of the current enemy
- wire [6:0] enemyx_array [0:NUMOFENEMIES-1]; // x position of all enemies
- wire [6:0] enemyy_array [0:NUMOFENEMIES-1]; // y position of all enemies
- reg [6:0] enemyx_init[0:1]; // initial x position of the enemies
- reg [6:0] enemyy_init[0:1]; // initial y position of the enemies
- reg left_and_right[0:1]; // Determines whether the enemy will move up and down, or left and right
- // Initializes the enemy's starting position and other properties
- initial
- begin
- enemyx_init[0] = 7'd50;
- enemyx_init[1] = 7'd100;
- enemyy_init[0] = 7'd50;
- enemyy_init[1] = 7'd100;
- left_and_right[0] = 1'd0;
- left_and_right[1] = 1'd1;
- end
- // Instantiates multiple enemies
- genvar index;
- generate
- for (index = 0; index < NUMOFENEMIES; index = index + 1)
- begin: create_enemies
- Enemy enemy(update, resetn, enemyx_array[index], enemyy_array[index], left_and_right[index], 7'd50, 7'd50);
- end
- endgenerate
- always @(*)
- begin
- enemyx = enemyx_array[0];
- enemyy = enemyy_array[0];
- end
- endmodule
- module Enemy(update, resetn, enemyx, enemyy, left_and_right, enemyx_init, enemyy_init);
- input update;
- input resetn;
- input left_and_right; // if 0 the enemy will move up and down, if 1 the enemy will move left and right
- input [6:0] enemyx_init;
- input [6:0] enemyy_init;
- reg [3:0] movement_position;
- reg left_right; // if 0 move left, if 1 move right
- reg up_down; // if 0 move up, if 1 move down
- output reg [6:0] enemyx;
- output reg [6:0] enemyy;
- reg initialize;
- always @(posedge update)
- begin
- if(!initialize)
- begin
- enemyx = enemyx_init;
- enemyy = enemyy_init;
- initialize = 1'd1;
- end
- else if(~resetn)
- begin
- enemyx = 1'd0;
- enemyy = 1'd0;
- end
- else
- begin
- if(left_and_right) // Enemy will move left and right
- begin
- if(movement_position == 4'd10) // Change direction every time it moves 10 pixels left or right
- begin
- left_right = ~left_right;
- movement_position = 1'd0;
- end
- if(left_right == 1'b0)
- begin
- enemyx = enemyx - 1'd1; // Move enemy to the left by one pixel
- end
- else
- begin
- enemyx = enemyx + 1'd1; // Move enemy to the right by one pixel
- end
- end
- else // Enemy will move up and down
- begin
- if(movement_position == 4'd10) // Change direction everytime it moves 10 pixels up or down
- begin
- up_down = ~up_down;
- movement_position = 1'd0;
- end
- if(up_down == 1'b0)
- begin
- enemyy = enemyy + 1'd1; // Move enemy down by one pixel
- end
- else
- begin
- enemyy = enemyy - 1'd1; // Move enemy up by one pixel
- end
- end
- movement_position <= movement_position + 1'b1; // Iterate how much pixels the enemy has moved by 1
- end
- end
- endmodule
- module Player(update, resetn, playerx, playery, KEY);
- input update;
- input resetn;
- output reg [6:0] playerx;
- output reg [6:0] playery;
- input [3:0] KEY;
- // Initialize the starting position of the player
- initial
- begin
- playerx = 7'd25;
- playery = 7'd25;
- end
- /* This will constantly check for player input and move the player
- accordingly.
- */
- always @(posedge update)
- begin
- if(~resetn)
- begin
- playerx = 1'b0;
- playery = 1'b0;
- end
- else
- begin
- if(~KEY[3]) // MOVE PLAYER LEFT
- begin
- playerx = playerx - 1'b1;
- end
- else if(~KEY[2]) // MOVE PLAYER UP
- begin
- playery = playery - 1'b1;
- end
- else if(~KEY[1]) // MOVE PLAYER DOWN
- begin
- playery = playery + 1'b1;
- end
- else if(~KEY[0]) // MOVE PLAYER RIGHT
- begin
- playerx = playerx + 1'b1;
- end
- end
- end
- endmodule
- module rateDivider(clk, update);
- input clk;
- output reg update;
- reg [25:0] counter;
- always @(posedge clk)
- begin
- counter = counter + 1'd1;
- if(counter > 26'd3124999)
- begin
- counter = 1'd0;
- end
- update = (counter == 1'd0) ? 1 : 0;
- end
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement