Vous êtes sur la page 1sur 37

FINAL PROJECT REPORT: 2D MINI GOLF GAME By, Anshuman Sahoo Ardit Pajo

TABLE OF CONTENTS 1) INTRODUCTION 2)DESIGN 3)SUCCESS 4)LEARNING OUTCOMES 5)APPENDIX A: CODE 6)APPENDIX B: Netlist Viewer Diagrams 7)APPENDIX C: CONTROLS

INTRODUCTION The basic premise of our project '2-D Mini Golf Game' was to display all the concepts of the course like animation on a VGA, FSM, using registers, memory units etc. in one complete project. We wanted our game to be impressive but not too expansive, in order to stay within the constraints of time. We chose golf because of it has a higher level of game play than our other options. The project implements a simple game of golf on a 160x120 VGA screen, using switches and keys on the Altera Cyclone II DE2 board. Our weekly goals were: Week 1 - Create modules that set power and direction of the ball - Power is input through switches - Direction is set using a ticker that rotates around the ball Week 2 - Add hole - Add the start screen - Animate the ball Week 3 - Add the win/lose screens - Add obstacles - Randomize the start position of the ball For us, making the ball animate in the direction chosen by user, and the speed and distance controlled by the input power, seemed like the most challenging part of the project. We had learnt how to animate images in our previous labs, but animation driven by logic was something we realized we needed to work on. The final game works as follows. The user presses StartGame and the screen clears up. The ball appears at a random position and the instruction marquee reads 'Set Power'. The SetPower button is pressed and the value input for power is stored. A 'Set Direction' marquee replaces the previous one, and a ticker is started that rotates around the ball indicating direction. At the appropriate aim, the SetDirection key is pressed and the ball is set into motion. It bounces off obstacles and walls, and if the hole is reached, the user wins. Else, he loses and the game can be played again by pressing reset (KEY[0]; Controls described in Appendix). DESIGN 1) Main Module(golf.v) : The main module provides the control element to our design. It instantiates all the modules, provides the 'start' and 'stop' instruction to some of them. It also defines the overall input and output to the design.

Block Diagram of the High Level Design 2) FSM(toplevelfsm.v) : The FSM module receives inputs from all other modules. The inputs are x and y positions that the different modules are drawing at, the color, enable input. Also, the FSM takes input from registers which become high when a module is completed, and hence directs the state in which the FSM is in. The output from the FSM is then redirected to the VGA Adapter module. The following illustrates how the FSM works.

Finite State Machine The output of the states is defined in a case statement clocked by CLOCK_50. An example of a case is:
STARTSCREEN: begin final_x <= splashscreen_x; final_y <= splashscreen_y; color <= colorofsplash; writeEn_ <= writeEn_splash; end

Hence, instead of using a datapath module, we have directly connected the input to the VGA to the appropriate output from the modules depending on what state the FSM is in. 3) CLEANSCREEN : The clean screen element is used in three states(IDLE, CLEANBALL, CLEANSTART). It cleans the screen back to the background image every time the state is changed to one of the cleaning states. Once the 'cleaning' is complete, registers become high to indicate the need to change the state. 4) STARTSCREEN(disp_splashscreen.v) : The start screen displays the title of the game. It starts the game once SW[0] is switched to 1. 5) DISPLAY BALL(disp_ball_at_start_pos.v) : The module displays the ball at a random spot on the screen. The randomizing takes place when a three bit counter is incremented and reset between 0 and 7, clocked by CLOCK_50. When SW[0] is switched on, the value of counter is stored in a registers. We then use a multiplexer to choose a position out of 8 possible positions on the screen. Using this as start position, it draws the ball. 6) DISPLAY SET POWER(disp_setpower.v) : Displays a moving marquee on top of the game area instructing the user to 'Set Power'. Power is set using a three bit input from switches SW[3:1], and is stored when the set power key, KEY[1] is pressed.

7) DISPLAY SET DIRECTION(disp_setdirection.v) : Displays a marquee instructing user to 'Set Direction'. 8) TICKER(disp_ticker.v) : Displays a rotating ticker that shows a black pixel moving around the ball leaving a red trail. The user can press the KEY[2] at the appropriate moment to select one of the 8 possible directions. 9) CLEAN TICKER(tickclean.v) : Cleans the ticker in a sweeping animation to provide a dramatic effect. 10)ANIMATE(animate_ball.v) : Animates the ball in the power and direction set. Power controls speed and distance covered by ball. The animation module takes care that the ball bounces off the boundaries as well as the obstacles in the game area. 11) WIN(winscreen.v) : Displays the win screen. 12) LOSE(losescreen.v) : Displays the lose screen.

SUCCESS
In the following section I will describe how the game works and the challenges faced during its development: After 3 weeks of hard work we were able to make a working game .The game is a 2D mini golf. The user first is presented with a welcome screen and than when switch SW[0] is set to one the screen clears and the ball is drawn randomly in the screen. The users than sets the power using switches SW[3:1] which gives the user the ability to choose from 8 different powers. When the user presses KEY[1] the power is stored in a register and than a ticker starts moving around the ball suggesting to the user to select the direction in which he/she wants the ball to move. When the users press KEY[2] the direction is stored in another register. After that the ball starts moving in the given direction and deflects accordingly when an obstacle or boundary is reached. In our game there are 3 different obstacles which substantially increases the difficulty of our game. Depending on the power chosen the ball travels different amount of pixels with different speeds and if the ball stops and the hole hasnt been reached than the user looses the game and the loose screen comes on where the user is suggested to press reset KEY[0] to try again. If the ball hits the hole before stopping than the users wins the game and he/she is presented with the win screen. Challenges: During the period of development of our game we were faced with a lot of challenges but our biggest one which took approximately 60% of the entire time needed to create the game was that we couldnt make the ball move in the chosen direction. One of the reason why this happened was that we werent patient to look at the code and see what was the problem but instead we tested it, saw that it didnt work and moved on writing it from the beginning. This slowed our process of development so much that at the end we werent able to complete our first goals. But instead we changed it by removing some parts from the original one and adding some new ones. The one we added were the obstacles and the ability to make the ball appear randomly in the screen. This was a very important decision which made it possible for us to have a working game at the end. What would we do differently if we could start all over again? The first thing we would do differently is to analyze the game better and to understand better it complexity in this way we would have been able to foresee the challenges and

better handle them. Second, we should have divided the work in smaller modules which would have allowed code reusability and increased our productivity. Third as stated above we should have been more patient and fixed our code instead of writing it from the beginning.

Game Screens

APPENDIX A
VERILOG CODE 1)golf.v
module golf(SW, KEY, CLOCK_50, LEDG, LEDR, VGA_CLK, VGA_HS, H_SYNC VGA_VS, V_SYNC VGA_BLANK, VGA_SYNC, VGA_R, VGA_G, Green[9:0] VGA_B ); input [17:0] SW; input [4:0] KEY; input CLOCK_50; output [7:0]LEDG; output [17:0]LEDR; output VGA_CLK; output VGA_HS; output VGA_VS; output VGA_BLANK; output VGA_SYNC; output [9:0] VGA_R; output [9:0] VGA_G; output [9:0] VGA_B; //wire and reg declaration reg power_set; reg direction_set; reg [7:0]start_x; reg [6:0]start_y; reg state_; reg start_ticker_; reg [1:0] score = 2'd3; wire [9:0]power; wire resetn; wire [7:0] curr_x; wire [6:0] curr_y; wire [7:0] tick_x; wire [6:0] tick_y; wire [7:0] splashscreen_x; wire [6:0] splashscreen_y; wire [7:0] clean_x; wire [6:0] clean_y; wire [7:0] setpow_x; wire [6:0] setpow_y; wire [7:0] marquee_x; // VGA Clock // VGA // // // // // VGA

VGA BLANK VGA SYNC VGA Red[9:0] // VGA VGA Blue[9:0]

// // //

VGA Clock // VGA H_SYNC // VGA V_SYNC VGA BLANK VGA SYNC // VGA Red[9:0] // VGA Green[9:0] // VGA Blue[9:0]

wire [6:0] marquee_y; wire [7:0]start_x_; wire [6:0]start_y_; wire [7:0]animate_x; wire [6:0]animate_y; wire [7:0]tickclean_x; wire [6:0]tickclean_y; wire [7:0]fix_x; wire [6:0]fix_y; wire [7:0]idle_x; wire [6:0]idle_y; wire [7:0]ballclean_x; wire [6:0]ballclean_y; wire [2:0]colorofballclean; wire [2:0]colorofidle; wire [2:0]colorofmarquee; wire [2:0] colorofball; wire [2:0] coloroftick; wire [2:0] colorofsplash; wire [2:0] colorofsetpow; wire [2:0] colorofgreen; wire [2:0] colorofgreentick; wire [2:0] colorofanimate; wire writeEn_tickclean; wire writeEn_clean; wire writeEn_pos; wire writeEn_tick; wire writeEn_splash; wire writeEn_setpow; wire writeEn_marquee; wire writeEn_animate; wire writeEn_idle; wire writeEn_ballclean; wire stop_animate; wire start_ticker; wire [7:0]final_x; wire [6:0]final_y; wire [7:0]x; wire [6:0]y; wire [2:0]color; wire [7:0]winscreen_x; wire [6:0]winscreen_y; wire [2:0]colorofwinscreen; wire writeEn_winscreen; wire [7:0]loose_x; wire [6:0]loose_y; wire [2:0]colorofloose; wire writeEn_loose; wire writeEn_; wire clk_speed; wire startgame; wire cleaned; wire clkclean; wire power_set_done; wire marquee_dir; wire clock_animate;

wire display_done; wire tick_clean; wire ballcleaned; wire cleanedone; wire hole_reached, hole_not_reached; wire [7:0] start_x1; wire [6:0] start_y1; wire [31:0] speed; assign resetn = KEY[0]; assign start_x_ = start_x; assign start_y_ = start_y; assign startgame = SW[0]; reg stop_counter; reg [1:0] counter; always@(posedge CLOCK_50 or negedge resetn) begin if(!resetn) stop_counter <= 1'b0; else if(SW[0]) stop_counter <= 1'b1; else stop_counter <= stop_counter; end always@(posedge CLOCK_50 or negedge resetn) begin if(!resetn) begin counter <= 1'b0; end else if(!stop_counter) begin if(counter > 2'd3) counter <= 2'd0; else counter <= counter + 1'b1; end else counter <= counter; end always@(posedge CLOCK_50) begin if(startgame) begin if(counter == 2'b00) begin start_x = 8'd10; start_y = 7'd80; end else if(counter == 2'b01) begin start_x = 8'd10; start_y = 7'd48; end else if(counter == 2'b10) begin

start_x = 8'd50; start_y = 7'd100; end else begin start_x = 8'd95; start_y = 7'd80; end end end //-----------------------------------------------------------------------------------------------------------------------------------initial begin stop_counter = 1'b0; power_set = 1'b0; direction_set = 1'b0; start_ticker_ = 1'b0; end //-----------------------------------------------------------------------------------------------------------------------------------toplevelfsm getstate(power_set_done, start_ticker ,display_done, stop_animate, startgame,cleaned,marquee_dir,tick_clean,cleanedone, ballcleaned, hole_reached, hole_not_reached, score,CLOCK_50, resetn,curr_x, curr_y, colorofball, writeEn_pos, tick_x,tick_y, coloroftick, writeEn_tick,splashscreen_x, splashscreen_y, colorofsplash, writeEn_splash,clean_x, clean_y, colorofgreen, writeEn_clean, setpow_x, setpow_y, colorofsetpow, writeEn_setpow, marquee_x, marquee_y, colorofmarquee, writeEn_marquee, animate_x, animate_y, colorofanimate, writeEn_animate,tickclean_x, tickclean_y, colorofgreentick, writeEn_tickclean,idle_x, idle_y, colorofidle, writeEn_idle,ballclean_x, ballclean_y, colorofballclean, writeEn_ballclean, winscreen_x, winscreen_y, colorofwinscreen, writeEn_winscreen,loose_x, loose_y, colorofloose, writeEn_loose, final_x, final_y, color,writeEn_, LEDR[17:9]);

//-----------------------------------------------------------------------------------------------------------------------------------always@ (posedge CLOCK_50 or negedge KEY[0]) if(!KEY[0]) power_set <= 1'b0; else if(!KEY[1]) power_set <= 1'b1; else power_set <= power_set; always@ (negedge KEY[0] or posedge CLOCK_50) if(!KEY[0]) direction_set <= 1'b0; else if(!KEY[2]) direction_set <= 1'b1; else direction_set <= direction_set ;

always@ (posedge hole_not_reached, negedge resetn) begin if(resetn == 0) score <= 2'd3; else score <= score - 2'b1; end //-----------------------------------------------------------------------------------------------------------------------------------//Set power disp_startscreen e1( startgame,CLOCK_50, splashscreen_x, splashscreen_y, colorofsplash, writeEn_splash); cleanscreen c1(startgame, clkclean,KEY[0], clean_x, clean_y, colorofgreen, writeEn_clean, cleaned); cleanscreen c3(1'b1, CLOCK_50,KEY[0], idle_x, idle_y, colorofidle, writeEn_idle, cleanedone); cleanscreen c4(tick_clean, CLOCK_50,KEY[0], ballclean_x, ballclean_y, colorofballclean, writeEn_ballclean, ballcleaned); setpower pow1(KEY[1],CLOCK_50,KEY[0], SW[3:1], power,speed); disp_setpow disp3(power_set,CLOCK_50,KEY[0],clkclean, setpow_x, setpow_y, colorofsetpow, writeEn_setpow, power_set_done); disp_marquee marq1(power_set_done,CLOCK_50,KEY[0],marquee_x, marquee_y, colorofmarquee, writeEn_marquee, marquee_dir); disp_ball_at_start_pos disp1(cleaned, CLOCK_50,KEY[0],start_x_, start_y_, curr_x, curr_y, colorofball, writeEn_pos, start_ticker); disp_ticker disp2(start_ticker, direction_set, clk_speed,KEY[0],power, start_x_, start_y_, tick_x, tick_y, fix_x, fix_y, coloroftick, writeEn_tick,display_done); speed_ticker s1(CLOCK_50, clk_speed); clockforclean c2(CLOCK_50, clkclean); clean_tick clean2(display_done,clk_speed,KEY[0],start_x_, start_y_, tickclean_x, tickclean_y, colorofgreentick, writeEn_tickclean,tick_clean); animate_ball a1(speed,power,KEY[0],KEY[2],tick_clean,CLOCK_50, fix_x, fix_y,start_x_,start_y_,animate_x,animate_y,colorofanimate,writeEn_animate,LEDR[8:1], hole_reached,hole_not_reached); clockforanimate an1(CLOCK_50, clock_animate); disp_winscreen win1(hole_reached, clkclean, winscreen_x, winscreen_y, colorofwinscreen, writeEn_winscreen); disp_loose loose1(hole_not_reached, clkclean, loose_x, loose_y, colorofloose, writeEn_loose); //update_pos_score (x,y,hole_not_reached,CLOCK_50,resetn, start_x1, start_y1); Draw_Image drawit(.reset(resetn), .clk(CLOCK_50), .color(color), .x(final_x), .y(final_y), .writeEn(writeEn_), .VGA_R(VGA_R), .VGA_G(VGA_G), .VGA_B(VGA_B), .VGA_HS(VGA_HS), .VGA_VS(VGA_VS), .VGA_BLANK(VGA_BLANK), .VGA_SYNC(VGA_SYNC), .VGA_CLK(VGA_CLK)); //------------------------------------------------------------------------------------------------------------------------------------

endmodule

2)toplevelfsm.v
module toplevelfsm(power_set, start_ticker, direction_set, stop_animate,startgame,cleaned,marquee_dir, ticker_clean,cleanedone,ballcleaned,hole_reached,hole_not_reached,score,clk, reset,curr_x, curr_y, colorofball, writeEn_pos, tick_x, tick_y, coloroftick, writeEn_tick,splashscreen_x, splashscreen_y, colorofsplash, writeEn_splash,clean_x, clean_y, colorofgreen, writeEn_clean, setpow_x, setpow_y, colorofsetpow, writeEn_setpow,marquee_x, marquee_y, colorofmarquee, writeEn_marquee,animate_x, animate_y, colorofanimate, writeEn_animate,tickclean_x, tickclean_y, colorofgreentick, writeEn_tickclean, idle_x, idle_y, colorofidle, writeEn_idle,ballclean_x, ballclean_y, colorofballclean, writeEn_ballclean, winscreen_x, winscreen_y, colorofwinscreen, writeEn_winscreen, loose_x, loose_y, colorofloose, writeEn_loose,final_x, final_y, color,writeEn_, led); input power_set; input direction_set; input stop_animate; input start_ticker; input startgame; input cleaned; input marquee_dir; input ticker_clean; input cleanedone; input ballcleaned; input hole_reached; input hole_not_reached; input clk; input reset; input [1:0] score; input [7:0] loose_x; input [6:0] loose_y; input [2:0] colorofloose; input writeEn_loose; input [7:0] ballclean_x; input [6:0] ballclean_y; input [2:0] colorofballclean; input writeEn_ballclean; input [7:0] idle_x; input [6:0] idle_y; input [2:0] colorofidle; input writeEn_idle; input [7:0] curr_x; input [6:0] curr_y; input [2:0] colorofball; input writeEn_pos; input [7:0] clean_x; input [6:0] clean_y; input [2:0] colorofgreen; input writeEn_clean; input [7:0] tick_x; input [6:0] tick_y;

input [2:0] coloroftick; input writeEn_tick; input [7:0] splashscreen_x; input [6:0] splashscreen_y; input [2:0] colorofsplash; input writeEn_splash; input [7:0] setpow_x; input [6:0] setpow_y; input [2:0] colorofsetpow; input writeEn_setpow; input [7:0] marquee_x; input [6:0] marquee_y; input [2:0] colorofmarquee; input writeEn_marquee; input [7:0] animate_x; input [6:0] animate_y; input [2:0] colorofanimate; input writeEn_animate; input [7:0] tickclean_x; input [6:0] tickclean_y; input [2:0] colorofgreentick; input writeEn_tickclean; input [7:0] winscreen_x; input [6:0] winscreen_y; input [2:0] colorofwinscreen; input writeEn_winscreen; output reg [7:0]final_x; output reg [6:0] final_y; output reg [2:0] color; output reg writeEn_; output [8:0]led; assign led[3:0] = y; //assign led[3]= ticker_clean; assign led[4] = direction_set; assign led[5] = marquee_dir; assign led[6] = power_set; assign led [8:7] = score; reg [7:0] setpow_x_; reg [6:0] setpow_y_; reg [7:0] tick_x_; reg [6:0] tick_y_;

always@(posedge clk) begin setpow_x_ <= setpow_x; setpow_y_ <= setpow_y; tick_x_ <= tick_x; tick_y_ <= tick_y; end initial begin

y = 3'b000; end reg [3:0] y, Y; parameter IDLE = 4'b0000,STARTSCREEN = 4'b0001, CLEANSTART = 4'b0010, DISPLAYBALL = 4'b0011, DISPLAYSETPOWER = 4'b0100, DISPLAYSETDIRECTION= 4'b0110, TICKER= 4'b0111, CLEANTICKER = 4'b1000, CLEANBALL=4'b1001, ANIMATE = 4'b1010, WIN = 4'b1011, LOOSE = 4'b1100; always@ (*) begin case(y) IDLE: begin if(cleanedone) Y = STARTSCREEN; else Y = IDLE; end STARTSCREEN : begin if(startgame) Y = CLEANSTART; else Y = STARTSCREEN; end CLEANSTART: begin if(cleaned) Y = DISPLAYBALL; else Y = CLEANSTART; end DISPLAYBALL : begin if(start_ticker) Y = DISPLAYSETPOWER; else Y = DISPLAYBALL; end DISPLAYSETPOWER : begin if(power_set) Y= DISPLAYSETDIRECTION; else Y = DISPLAYSETPOWER; end DISPLAYSETDIRECTION: begin if(marquee_dir) Y= TICKER; else Y = DISPLAYSETDIRECTION; end TICKER : begin if(direction_set) Y = CLEANTICKER; else Y = TICKER; end CLEANTICKER: begin if(ticker_clean)Y = CLEANBALL; else Y = CLEANTICKER; end CLEANBALL: begin if(ballcleaned) Y = ANIMATE; else Y = CLEANBALL; end ANIMATE : begin if(hole_reached) Y = WIN; else if(hole_not_reached) Y = LOOSE; else Y= ANIMATE; end WIN: begin Y = WIN; end LOOSE: begin Y=LOOSE; end default: Y = IDLE; endcase end always@ (posedge clk, negedge reset) begin

if(!reset) begin y <= IDLE; end else y <= Y; end always@(posedge clk) begin case(y) IDLE: begin final_x <= idle_x; final_y <= idle_y; color <= colorofidle; writeEn_ <= writeEn_idle; end STARTSCREEN: begin final_x <= splashscreen_x; final_y <= splashscreen_y; color <= colorofsplash; writeEn_ <= writeEn_splash; end CLEANSTART: begin final_x <= clean_x; final_y <= clean_y; color <= colorofgreen; writeEn_ <= writeEn_clean; end DISPLAYBALL: begin final_x <= curr_x; final_y <= curr_y; color <= colorofball; writeEn_ <= writeEn_pos; end DISPLAYSETPOWER: begin final_x <= setpow_x_; final_y <= setpow_y_; color <= colorofsetpow; writeEn_ <= writeEn_setpow; end DISPLAYSETDIRECTION: begin final_x <= marquee_x; final_y <= marquee_y; color <= colorofmarquee; writeEn_ <= writeEn_marquee; end TICKER: begin final_x <= tick_x_; final_y <= tick_y_; color <= coloroftick;

writeEn_ <= writeEn_tick; end CLEANTICKER: begin final_x <= tickclean_x; final_y <= tickclean_y; color <= colorofgreentick; writeEn_ <= writeEn_tickclean; end CLEANBALL: begin final_x <= ballclean_x; final_y <= ballclean_y; color <= colorofballclean; writeEn_ <= writeEn_ballclean; end ANIMATE: begin final_x <= animate_x; final_y <= animate_y; color <= colorofanimate; writeEn_ <= writeEn_animate; end WIN: begin final_x <= winscreen_x; final_y <= winscreen_y; color <= colorofwinscreen; writeEn_ <= writeEn_winscreen; end LOOSE: begin final_x <= loose_x; final_y <= loose_y; color <= colorofloose; writeEn_ <= writeEn_loose; end default: begin final_x <= 8'b01001110; final_y <= 7'b00111010; color <= 3'b010; writeEn_ <= 1'b0; end endcase end endmodule

3)cleanScreen.v
module cleanscreen(clean,clk,reset,curr_x, curr_y, color, writeEn, cleaned); input clk,reset; input clean; reg [7:0]start_x; reg [6:0]start_y; output reg [7:0] curr_x; output reg [6:0] curr_y; output reg[2:0] color; output reg cleaned;

output reg writeEn; reg [11:0] counter; reg startgame_; always@(posedge clk or negedge reset ) if(!reset) startgame_ <= 0; else if(clean) startgame_ <= 1; else startgame_ <= startgame_ ; initial begin writeEn = 0; startgame_ = 0; start_x = 8'd48; start_y = 8'd28; cleaned = 0; curr_x = 8'd0; curr_y = 7'd0; end

always@ (posedge clk or negedge reset) begin if(!reset ) begin writeEn <= 0; cleaned <=0; curr_x <= 0; curr_y <= 0; end else if(startgame_) begin curr_x <= curr_x + 8'd1; if(curr_x > 8'd159) begin curr_y <= curr_y + 7'd1; curr_x <= 8'd0; end writeEn <= 1'b1; if(curr_y >7'd119) cleaned <= 1; end end always@(curr_y or curr_x) begin

if(curr_y < 7'd40) color = 3'b011; else if(curr_y == 7'd40) color = 3'b000; else begin if(curr_y > 7'd78 & curr_y <7'd84 & curr_x > 8'd147 & curr_x < 8'd153) color = 3'b000; else if(curr_y > 7'd40 & curr_y < 7'd75 & curr_x == 8'd40) color = 3'b110; else if(curr_y > 7'd70 & curr_y <7'd120 & curr_x == 8'd90) color = 3'b110; else if(curr_y > 7'd40 & curr_y <7'd64 & curr_x == 8'd120) color = 3'b110; else color = 3'b010; end end endmodule

4)disp_startscreen.v
module disp_startscreen( startgame,clk,curr_x, curr_y, color, writeEn); input clk; input startgame; reg [7:0]start_x; reg [6:0]start_y; output reg [7:0] curr_x; output reg [6:0] curr_y; output [2:0] color; output reg writeEn; reg [11:0] counter; initial begin counter = 12'd0; writeEn = 0; start_x = 8'd48; start_y = 7'd28; end

always@ (posedge clk) begin writeEn <= 1'b1; counter <= counter + 12'b1;

end always@ (posedge clk) begin curr_x <= start_x + counter[5:0]; curr_y <= start_y + counter[11:6]; end ImageROM_splashscreen splash1(.address(counter), .clock(clk), .q(color)); endmodule

5)disp_ball_at_start_pos.v
module disp_ball_at_start_pos(cleaned,clk,reset,start_x, start_y, curr_x, curr_y, color, writeEn, start_ticker); input cleaned,clk,reset; input [7:0]start_x; input [6:0]start_y; output reg [7:0] curr_x; output reg [6:0] curr_y; output reg[2:0] color; output reg start_ticker; output reg writeEn; reg [3:0] counter; reg cleaned_; always@(posedge clk or negedge reset) begin if(!reset) start_ticker <= 0; else if((curr_x - start_x == 2'b11 & curr_y - start_y == 2'b11)) start_ticker <= 1; else start_ticker <= start_ticker; end initial begin counter = 4'b0000; writeEn = 0; start_ticker = 0; end

always@ (posedge clk or negedge reset) begin if(!reset) begin counter <= 4'b0000; writeEn <= 0; end else if(cleaned) begin writeEn <= 1'b1; counter <= counter + 4'd1; color <= 3'b111; end else begin counter <= counter; writeEn <= writeEn; end end always@ (posedge clk) begin curr_x <= start_x + counter[1:0]; curr_y <= start_y + counter[3:2]; end endmodule

6)disp_setpow.v
module disp_setpow(power_set, clk,reset, clk_speed, curr_x, curr_y, colorofsetpow, writeEn_setpow , power_set_done); input clk, clk_speed, power_set,reset; output reg [7:0] curr_x; output reg [6:0] curr_y; output reg[2:0] colorofsetpow; output reg writeEn_setpow; output reg power_set_done; reg [9:0] counter; reg [7:0] start_x; reg [6:0] start_y; reg power_set_; reg flag; reg wiped; wire [2:0]col;

initial begin counter = 10'b0000000000; writeEn_setpow = 0; start_x = 8'd10; start_y = 7'd5; flag = 1; power_set_done = 0; wiped = 0; end

always@ (posedge clk_speed or negedge reset) begin if(!reset) begin counter = 10'b0000000000; writeEn_setpow = 0; start_x = 8'd10; start_y = 7'd5; flag = 1; power_set_done = 0; wiped = 0; end else if(power_set) begin writeEn_setpow <= 1'b1; counter <= counter + 1'b1; colorofsetpow <= 3'b011; curr_x <= start_x + counter[4:0]; curr_y <= start_y + counter[9:5]; if(counter == 10'b1111111111) begin if(wiped == 1) power_set_done = 1; wiped = 1; end end else begin if(flag) begin writeEn_setpow <= 1'b1; counter <= counter + 1'b1; colorofsetpow <= col; curr_x <= start_x + counter[4:0]; curr_y <= start_y + counter[9:5];

if(counter == 10'b1111111111) begin counter <= 10'd0; flag <= 0; end end else begin writeEn_setpow <= 1'b1; counter <= counter + 1'b1; colorofsetpow <= 3'b011; curr_x <= start_x + counter[4:0]; curr_y <= start_y + counter[9:5]; if(counter == 10'b1111111111) begin counter <= 10'd0; flag <= 1; start_x <= start_x + 4; if(start_x > 8'd128) start_x <= 8'd10; end end end end

ImageROM_setpow tick4(.address(counter), .clock(clk), .q(col)); endmodule

7)disp_marquee.v
module disp_marquee(power_set_done, clk,reset,curr_x, curr_y, colorofmarquee, writeEn_marquee, marquee_dir); input clk, power_set_done,reset; output reg [7:0] curr_x; output reg [6:0] curr_y; output [2:0] colorofmarquee; output reg writeEn_marquee; output reg marquee_dir; reg [9:0] counter; reg [7:0] start_x; reg [6:0] start_y; initial begin counter = 10'b0000000000; writeEn_marquee = 0; start_x = 8'd65;

start_y = 7'd5; marquee_dir = 0; end

always@ (posedge clk or negedge reset) begin if(!reset) begin counter = 10'b0000000000; writeEn_marquee = 0; start_x = 8'd65; start_y = 7'd5; marquee_dir = 0; end else if(power_set_done) begin writeEn_marquee <= 1'b1; counter <= counter + 1'b1; curr_x <= start_x + counter[4:0]; curr_y <= start_y + counter[9:5]; if(counter == 10'b1111111111) marquee_dir <= 1; end end ImageROM_setdir tick5(.address(counter), .clock(clk), .q(colorofmarquee)); endmodule

8)disp_ticker.v
module disp_ticker (start_ticker,direction_set,clk_output,reset, speed, start_x, start_y, tick_x, tick_y,fixed_tickx, fixed_ticky, coloroftick, writeEn,display_done); input start_ticker, direction_set,reset; input [2:0]speed; input [7:0]start_x; input [6:0]start_y; input clk_output; output reg [7:0]tick_x; output reg [6:0]tick_y; output reg [7:0]fixed_tickx; output reg [6:0]fixed_ticky; output reg[2:0] coloroftick; output reg writeEn; output reg display_done;

reg [2:0] counterx; reg [2:0] countery; reg start_ticker_; reg [2:0]enable; reg flag, direction_set_; always@ (posedge direction_set) begin fixed_tickx <= tick_x; fixed_ticky <= tick_y; end initial begin writeEn = 1'b0; coloroftick = 3'b000; flag = 0; counterx = 3'b000; countery = 3'b000; display_done = 0; fixed_tickx = 8'd0; fixed_ticky = 7'd0; end

always@ (posedge clk_output or negedge reset) begin if(!reset) begin writeEn = 1'b0; coloroftick = 3'b000; flag = 0; counterx = 3'b000; countery = 3'b000; display_done = 0; end else if(!direction_set) begin writeEn <= 1'b1; if(flag == 0) begin coloroftick <= 3'b000; flag = 1; end else if (flag == 1) begin if(countery == 3'b000 & counterx == 3'b000) counterx <= counterx + 3'd4; else if(counterx == 3'b100 & countery == 3'b000) counterx <= counterx + 3'd3; else if(counterx == 3'b111 & countery == 3'b000) countery <= countery + 3'd4; else if(counterx == 3'b111 & countery == 3'b100) countery <= countery + 3'd3;

else if(counterx == 3'b111 & countery == 3'b111) counterx <= counterx - 3'd3; else if(counterx == 3'b100 & countery == 3'b111) counterx <= counterx - 3'd4; else if(counterx == 3'b000 & countery == 3'b111) countery <= countery - 3'd3; else if(counterx == 3'b000 & countery == 3'b100) countery <= countery - 3'd4; tick_x <= start_x - 8'd2 + counterx; tick_y <= start_y - 7'd2 + countery; coloroftick <= 3'b100; flag = 0; end end else begin writeEn <= 1'b1; coloroftick <= 3'b100; tick_x <= start_x - 8'd2 + counterx; tick_y <= start_y - 7'd2 + countery; display_done = 1; end end endmodule

9)clean_tick.v
module clean_tick(direction_set,clk_speed,reset,start_x, start_y, tick_x, tick_y, coloroftick, writeEn,tick_clean); input direction_set,reset; input [7:0]start_x; input [6:0]start_y; input clk_speed; output reg [7:0]tick_x; output reg [6:0]tick_y; output reg[2:0] coloroftick; output reg writeEn; output reg tick_clean; reg [2:0] counterx; reg [2:0] countery; reg [2:0]enable; reg flag, direction_set_; initial begin writeEn = 1'b0; coloroftick = 3'b000; flag = 0;

counterx = 3'b000; countery = 3'b000; tick_clean = 0; end

always@ (posedge clk_speed or negedge reset) begin if(!reset) begin writeEn = 1'b0; coloroftick = 3'b000; flag = 0; counterx = 3'b000; countery = 3'b000; tick_clean <= 0; end else begin if(direction_set) begin writeEn <= 1'b1; begin if(countery == 3'b000 & counterx == 3'b000) counterx <= counterx + 3'd4; else if(counterx == 3'b100 & countery == 3'b000) counterx <= counterx + 3'd3; else if(counterx == 3'b111 & countery == 3'b000) countery <= countery + 3'd4; else if(counterx == 3'b111 & countery == 3'b100) countery <= countery + 3'd3; else if(counterx == 3'b111 & countery == 3'b111) counterx <= counterx - 3'd3; else if(counterx == 3'b100 & countery == 3'b111) counterx <= counterx - 3'd4; else if(counterx == 3'b000 & countery == 3'b111) countery <= countery - 3'd3; else if(counterx == 3'b000 & countery == 3'b100) begin countery <= countery - 3'd4; tick_clean <= 1; end else begin tick_clean <= 0; end tick_x <= start_x - 8'd2 + counterx; tick_y <= start_y - 7'd2 + countery; coloroftick <= 3'b010; end end

end end endmodule

10)animate_ball.v
module animate_ball(speed,power,reset,direction_set,tick_clean,clk, tick_x, tick_y,ball_x,ball_y,animatex,animatey,color,writeEn,led,hole_reached,hole_not_reached); input clk,tick_clean,reset; input [9:0]power; input [31:0] speed; output reg [7:0]animatex; output reg[6:0]animatey; output reg[2:0]color; output reg writeEn; reg [7:0]x; reg [6:0]y; reg flag; reg start_draw, start_clean; wire color_draw; output reg hole_reached; output reg hole_not_reached; input direction_set; input [7:0]tick_x,ball_x; input [6:0]tick_y,ball_y; reg add_x,add_y,enable_x,enable_y; reg [9:0] count_steps; reg [32:0] delay_ball_stop; initial begin count_steps = 10'd0; hole_reached = 1'b0; hole_not_reached = 1'b0; delay_ball_stop = 33'd0; end always@ (posedge clk or negedge reset) begin if(!reset) begin enable_x <=0; enable_y <=0; add_x <=0; add_y <=0; hole_reached <= 1'b0; hole_not_reached <= 1'b0; delay_ball_stop <= 33'd0; end else begin if(!direction_set) begin if(tick_x == (ball_x-8'd2)& tick_y == (ball_y-7'd2)) begin add_x <= 0; add_y <= 0; enable_x <= 1; enable_y <= 1;

hole_not_reached <= 0; end //top middle else if(tick_x == (ball_x + 8'd2) & tick_y == (ball_y-7'd2)) begin add_x <= 0; add_y <= 0; enable_x <= 0; enable_y <= 1; end //top right else if(tick_x == (ball_x + 8'd5) & tick_y == (ball_y-7'd2)) begin add_x <= 1; add_y <= 0; enable_x <= 1; enable_y <= 1; end // middle right else if(tick_x == (ball_x + 8'd5) & tick_y == (ball_y+7'd2)) begin add_x <= 1; add_y <= 0; enable_x <= 1; enable_y <= 0; end //bottom right else if(tick_x == (ball_x + 8'd5) & tick_y == (ball_y+7'd5)) begin add_x <= 1; add_y <= 1; enable_x <= 1; enable_y <= 1; end //bottom middle else if(tick_x == (ball_x + 8'd2) & tick_y == (ball_y+7'd5)) begin add_x <= 0; add_y <= 1; enable_x <= 0; enable_y <= 1; end //bottom left else if(tick_x == (ball_x-8'd2)& tick_y == (ball_y+7'd5)) begin add_x <= 0; add_y <= 1; enable_x <= 1; enable_y <= 1; end //middle left else if(tick_x == (ball_x-8'd2) & tick_y == (ball_y+7'd2)) begin add_x <= 0; add_y <= 0; enable_x <= 1;

enable_y <= 0; end end else begin if((y < 7'd42)| (y > 7'd114)|(x < 8'd2) | (x > 8'd154) | (count_steps > power)| (y > 7'd75 & y <7'd86 & x > 8'd144 & x < 8'd154)| (y > 7'd40 & y <7'd75 & x == 8'd36)|(y > 7'd40 & y <7'd75 & x == 8'd41)|(y == 74 & x >35 & x <41)| (y > 7'd66 & y <7'd120 & x == 8'd86)|(y > 7'd66 & y <7'd120 & x == 8'd91)|(y == 7'd71 & x >8'd85 & x < 8'd91)| (y > 7'd40 & y <7'd64 & x == 8'd116)| (y > 7'd40 & y <7'd64 & x == 8'd121)) begin if((y < 7'd42)) begin add_y <= 1; end if((y > 7'd114)) begin add_y <= 0; end if(x < 8'd2) begin add_x <= 1; end if((x > 8'd154)) begin add_x <= 0; end if(count_steps > power) begin enable_x <= 0; enable_y <= 0; add_x <= 0; add_y<= 0; delay_ball_stop <= delay_ball_stop +33'b1; if(delay_ball_stop == 33'b100000000) begin hole_not_reached <= 1; hole_reached <= 1'b0; end end if(y > 7'd77 & y <7'd84 & x > 8'd144 & x < 8'd153) begin enable_x <= 0; enable_y <= 0; add_x <= 0; add_y<= 0; hole_reached <= 1'b1; hole_not_reached <= 1'b0; end if(y > 7'd40 & y < 7'd75 & x == 8'd36) begin add_x <= 0; end if(y > 7'd40 & y <7'd75 & x == 8'd41)

begin add_x <= 1; end if(y == 74 & x >35 & x <41) begin add_y <= 1; end if(y > 7'd66 & y <7'd120 & x == 8'd86) begin add_x <= 0; end if(y > 7'd66 & y <7'd120 & x == 8'd91) begin add_x <= 1; end if(y == 7'd71 & x >8'd85 & x < 8'd91) begin add_y <= 0; end if(y > 7'd40 & y <7'd64 & x == 8'd116) begin add_x <= 0; end if(y > 7'd40 & y <7'd64 & x == 8'd121) begin add_x <= 1; end end else begin add_y <= add_y; add_x <= add_x; hole_reached <= 1'b0; hole_not_reached <= 1'b0; end end end end

initial begin flag = 0; start_clean =0; start_draw =0; end always@(posedge clk or negedge reset) begin if(!reset) begin count_steps<=10'd0; flag =0; x<=ball_x; y<=ball_y; end

else begin if(!tick_clean) begin x<=ball_x; y<=ball_y; count_steps <= 10'd0; end else begin if(flag == 0 & start_draw == 1) begin flag = 1; end else if(flag == 1 & start_clean == 1) begin if(enable_x) begin if(add_x) x = x+ 8'd1; else x = x-8'd1; end if(enable_y) begin if(add_y) y = y+7'd1; else y = y-7'd1; end if(hole_reached) flag = 1; else flag = 0; count_steps <= count_steps + 10'd1; end else begin x <= x; y <= y; end end end end reg [4:0] counter; reg [32:0] count; initial begin counter = 5'b00000; count = 32'd0; writeEn = 0; end

always@ (posedge clk or negedge reset) begin if(!reset) begin start_clean =0; start_draw =0; end else begin if(!tick_clean) begin start_clean =0; start_draw =0; end else if( flag == 1) begin start_draw = 0; writeEn <= 1'b1; counter <= counter +5'd1; color<=3'b010; if(counter == 5'b01111) begin counter <= 5'b00000; start_clean = 1; end end else if(flag == 0) begin start_clean =0; writeEn <= 1'b1; counter <= counter +5'd1; color<= 3'b111; count = count + 1; if(counter > 5'b01111 & count >=speed) begin count = 32'd0; counter <= 5'b00000; start_draw = 1; end end end end always@ (posedge clk) begin animatex <= x + counter[1:0]; animatey <= y + counter[3:2];

end endmodule

11)disp_winscreen.v
module disp_winscreen( startgame,clk,curr_x, curr_y, color, writeEn); input clk; input startgame; reg [7:0]start_x; reg [6:0]start_y; output reg [7:0] curr_x; output reg [6:0] curr_y; output [2:0] color; output reg writeEn; reg [11:0] counter;

initial begin counter = 12'd0; writeEn = 0; start_x = 8'd48; start_y = 7'd28; end

always@ (posedge clk) begin if(startgame) begin writeEn <= 1'b1; counter <= counter + 12'b1; end else writeEn <= 1'b0; end always@ (posedge clk) begin curr_x <= start_x + counter[5:0]; curr_y <= start_y + counter[11:6]; end

ImageROM_winscreen splash4(.address(counter), .clock(clk), .q(color)); endmodule

12)disp_loose.v
module disp_loose( startgame,clk,curr_x, curr_y, color, writeEn); input clk; input startgame; reg [7:0]start_x; reg [6:0]start_y; output reg [7:0] curr_x; output reg [6:0] curr_y; output [2:0] color; output reg writeEn; reg [11:0] counter; initial begin counter = 12'd0; writeEn = 0; start_x = 8'd48; start_y = 7'd28; end always@ (posedge clk) begin if(startgame) begin writeEn <= 1'b1; counter <= counter + 12'b1; end else writeEn <= 1'b0; end always@ (posedge clk) begin curr_x <= start_x + counter[5:0]; curr_y <= start_y + counter[11:6]; end

ImageROM_loose l1(.address(counter), .clock(clk), .q(color)); endmodule

APPENDIX B

RTL Viewer Diagram to give an idea of the structure of design

Post-fitting Technology Viewer shows the inter connectivity of the modules

APPENDIX C

Vous aimerez peut-être aussi