0
\$\begingroup\$

I'm working on a game of brick breaker and I've encountered a problem that I can't figure out. whenever the ball collides with the corners of the peddle it starts vibrating (it's Yspeed vector changes constantly) and I can't understand why. whenever collision between ball and peddle occurs, I'm using a flag which I reset only after one clock (so it won't be zero after one frame and enter into collision again) and I send signal that collision occurred. I identify the collision by checking if two objects sent drawing request at the same time.

here's the code:

I have a module top_level_peddle, which is responsible for the peddle movement and drawing, inside it, there's a smaller module named borderBitMap here, there are to input pixelX and pixelY which are entering from the VGA contorller (those are the pixels the VGA is currently drawing), i get the offsetX and offsetY of the current pixel the VGA is drawing from the top left corner of the peddle and I get notified whether a drawing request was sent (insideRectangle input). for every corner I output different color. I also output different colors in case currently drawn pixels are at the top or bottom border or the left or right borders of the peddle.

module	borderBitMap	(	
					input	logic	clk,
					input	logic	resetN,
					input logic	[10:0] offsetX,// offset from top left  position 
					input logic	[10:0] offsetY,
					input	logic	InsideRectangle, //input that the pixel is within a bracket 

					output	logic	[7:0] RGBout  //rgb value from the bitmap 
); 

localparam  int OBJECT_WIDTH = 75;
localparam  int OBJECT_HEIGHT = 25;
integer x_from_center; 
integer y_from_center;

localparam logic [7:0] TRANSPARENT_ENCODING = 8'hFF ;// RGB value in the bitmap representing a transparent pixel 
localparam logic [7:0] RED = 8'hE0 ;
localparam logic [7:0] GREEN = 8'h0C ;
localparam logic [7:0] MAGENTA = 8'hE3 ;
localparam logic [7:0] OLIVE = 8'h6C ;
localparam logic [7:0] PURPLE = 8'h61 ;
localparam logic [7:0] TEAL = 8'h1D ;


// pipeline (ff) to get the pixel color from the array 	 

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
always_ff@(posedge clk or negedge resetN)
begin
	if(!resetN) begin
		RGBout <=	8'h00;
	end
	else begin
		
		if (InsideRectangle == 1'b1 ) begin  // inside an external bracket 
				
				// UPPER LEFT CORNER
				if( (offsetX < 2) && (offsetY < 2) ) begin
						RGBout <= MAGENTA;
				end
				
				//  UPPER RIGHT CORNER
				else if( (offsetX > OBJECT_WIDTH - 2) && (offsetY < 2) ) begin
						RGBout <= PURPLE;
				end
				
				// LOWER RIGHT CORNER

				else if( (offsetX >  OBJECT_WIDTH - 2) && (offsetY > OBJECT_HEIGHT - 2) ) begin
						RGBout <= TEAL;
				end
				
				
				// LOWER LEFT CORNER

				else if( (offsetX < 2) && (offsetY > OBJECT_HEIGHT - 2) ) begin
						RGBout <= OLIVE;
				end

				// UPPER AND LOWER SIDES OF PADDLE
				else if( (offsetX >= 2) && (offsetX <= OBJECT_WIDTH - 2)  ) begin
						RGBout <= RED;
				end
				
				// LEFT AND RIGHT SIDES OF PADDLE
				else if( (offsetY >= 2) && (offsetY <= OBJECT_HEIGHT - 2) ) begin
						RGBout <= GREEN;
				end
				
				else begin
						RGBout <= TRANSPARENT_ENCODING;
				end

		end
		
		else 
			RGBout <= TRANSPARENT_ENCODING ; // force color to transparent so it will not be displayed 
	end 
end

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// decide if to draw the pixel or not 


endmodule

the outputs of this module goes inside another module called Ball_move. inside this module, I check the color that was sent, and I check if the collision logic notified that a collision occurred, and in respect to the inputs I change the speed vector (Xspeed and Yspeed) of the ball

module	Ball_move	(	
 
					input	logic	clk,
					input	logic	resetN,
					input	logic	startOfFrame,  // short pulse every start of frame 30Hz 
					input logic [10:0] pixelX,
					input logic [10:0] pixelY,
					input logic collision,
					
					input logic [7:0] rgb_border,
					
					output	logic	[10:0]	topLeftX,// output the top left corner 
					output	logic	[10:0]	topLeftY
					
);


// a module used to generate a ball trajectory.  

parameter int INITIAL_X = 280;
parameter int INITIAL_Y = 185;
parameter int INITIAL_X_SPEED = 300;
parameter int INITIAL_Y_SPEED = 300;
parameter int ACCEL = 1.8;
parameter int SIZE = 26;
parameter int CENTER_X = SIZE/2;
int flag = 0;

const int	MULTIPLIER	=	64;
// multiplier is used to work with integers in high resolution 
// we devide at the end by multiplier which must be 2^n 
const int	x_FRAME_SIZE	=	639 * MULTIPLIER;
const int	y_FRAME_SIZE	=	479 * MULTIPLIER;


int Xspeed, topLeftX_tmp; // local parameters 
int Yspeed, topLeftY_tmp;
int collision_x, collision_y;


localparam logic [7:0] RED = 8'hE0 ;
localparam logic [7:0] GREEN = 8'h0C ;
localparam logic [7:0] MAGENTA = 8'hE3 ;
localparam logic [7:0] OLIVE = 8'h6C ;
localparam logic [7:0] PURPLE = 8'h61 ;
localparam logic [7:0] TEAL = 8'h1D ;


//  calculation x Axis speed 

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

always_ff@(posedge clk or negedge resetN)
begin
	if(!resetN) begin
		Yspeed	<= INITIAL_Y_SPEED;
		Xspeed	<= INITIAL_X_SPEED;
		flag <= 0;
	end
	
	else 	begin
			if (pixelX == 11'b0) begin 
				Yspeed <= Yspeed*ACCEL ;
				Xspeed <= Xspeed*ACCEL ;
			end
			if ((topLeftX_tmp <= 0 ) && (Xspeed < 0) ) begin // hit left border while moving right
				Xspeed <= -Xspeed ; 
			
			end else if ( (topLeftX_tmp >= (x_FRAME_SIZE-(SIZE*MULTIPLIER))) && (Xspeed > 0 )) begin // hit right border while moving left
				Xspeed <= -Xspeed ;
			end 
			
			if ((topLeftY_tmp <= 0 ) && (Yspeed < 0 )) begin// hit top border heading up
				Yspeed <= -Yspeed ; 
			end else if ( ( topLeftY_tmp  >= (y_FRAME_SIZE - (SIZE*MULTIPLIER)) )&& (Yspeed > 0 ) )begin //hit bottom border heading down 
				Yspeed <= -Yspeed ; 
			end
			
			else if ((collision== 1'b1 && flag==32'b0)) begin
					
					case(rgb_border)
					
						 RED: begin
									Yspeed <= -Yspeed ; 
									Xspeed <= Xspeed ;
									flag <=32'b10; 
						 end
						 
						 GREEN: begin
									Yspeed <= Yspeed ; 
									Xspeed <= -Xspeed ; 
									flag <=32'b10;
						 end
						 
						 MAGENTA: begin
						 			if((Xspeed > 0) && (Yspeed > 0)) begin
										Yspeed <= -Yspeed ; 
										Xspeed <= -Xspeed ;
										flag <=32'b10; 
									end
									
									else if((Xspeed < 0) && (Yspeed > 0)) begin
										Yspeed <= -Yspeed ;
										Xspeed <= Xspeed ;
										flag <=32'b10;
									end
									
									else if((Xspeed > 0) && (Yspeed < 0) ) begin
										 Yspeed <= Yspeed;
										 Xspeed <= -Xspeed;
										flag <=32'b10;
									end
						 end
						 
						 OLIVE: begin
									if((Xspeed > 0) && (Yspeed < 0)) begin
										Yspeed <= -Yspeed ; 
										Xspeed <= -Xspeed ; 
										flag <=32'b10;
									end
									
									else if((Xspeed < 0) && (Yspeed < 0)) begin
										Yspeed <= -Yspeed ;
										Xspeed <= Xspeed ;
										flag <=32'b10;
									end
									
									else if((Xspeed > 0) && (Yspeed > 0)) begin
										 Yspeed <= Yspeed;
										 Xspeed <= -Xspeed;
										flag <=32'b10;
									end
						 end
						 
						 PURPLE: begin
										if ((Xspeed < 0) && (Yspeed > 0)) begin
											Yspeed <= -Yspeed ; 
											Xspeed <= -Xspeed ; 
											flag <=32'b10;
										end
										
										else if ((Xspeed > 0) && (Yspeed > 0))begin
											Yspeed <= -Yspeed ;
											Xspeed <= Xspeed ;
											flag <=32'b10;
										end
										
										else if ((Xspeed < 0) && (Yspeed < 0)) begin
											 Yspeed <= Yspeed;
											 Xspeed <= -Xspeed;
											 flag <=32'b10;
										end
						 end
						 
						 TEAL: begin
									if((Xspeed < 0) && (Yspeed < 0)) begin
										Yspeed <= -Yspeed ; 
										Xspeed <= -Xspeed ; 
										flag <=32'b10;
									end
									
									else if((Xspeed > 0) && (Yspeed < 0)) begin
										Yspeed <= -Yspeed ;
										Xspeed <= Xspeed ;
										flag <=32'b10;
									end
									
									else if ((Xspeed < 0) && (Yspeed > 0)) begin
										 Yspeed <= Yspeed;
										 Xspeed <= -Xspeed;
										 flag <=32'b10;
									end
						 end
						 
						 default: begin
										Yspeed <= Yspeed;
										Xspeed <= Xspeed;
										flag <=32'b10;
						 end
					
					endcase
				
	
			end
		if((pixelX == 1'b0) && (flag > 32'b0)) begin //   perform only 30 times per second 	
				flag <= flag - 1;
		end
	
	end
end

// position calculate 

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
always_ff@(posedge clk or negedge resetN)
begin

	if(!resetN) begin
		topLeftX_tmp	<= INITIAL_X * MULTIPLIER;
		topLeftY_tmp	<= INITIAL_Y * MULTIPLIER;
	end
	
	else if (startOfFrame == 1'b1) begin //   perform only 30 times per second 	
			topLeftX_tmp  <= topLeftX_tmp + Xspeed; 
			topLeftY_tmp  <= topLeftY_tmp + Yspeed;
			
	end 
end

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//get a better (64 times) resolution using integer   

		assign topLeftX = topLeftX_tmp / MULTIPLIER ;   // note:  it must be 2^n 
		assign topLeftY = topLeftY_tmp / MULTIPLIER ; 
		
endmodule

this is my collision logic:

module	ball_collision	(	
					input		logic	clk,
					input		logic	resetN,
					
					input		logic	paddleDrawingRequest,
					input		logic	ballDrawingRequest,
					input		logic	brickDrawingRequest,
										
					output	logic	collision,					
					output	logic	brick_ball_collision,
					output	logic	paddle_ball_collision				
);






//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
always_ff@ (posedge clk or negedge resetN)
begin
	if(!resetN) begin
			brick_ball_collision <= 1'b0;
			paddle_ball_collision <= 1'b0;
			collision <=1'b0;
	end
	else begin
		if((paddleDrawingRequest&&ballDrawingRequest) == 1'b1) begin
			collision <=1'b1;
			paddle_ball_collision <= 1'b1;
			brick_ball_collision <= 1'b0;
		end else if((brickDrawingRequest&&ballDrawingRequest) == 1'b1) begin
			collision <=1'b1;
			brick_ball_collision <= 1'b1;
			paddle_ball_collision <= 1'b0;
		end else begin
			collision <=1'b0;
			brick_ball_collision <= 1'b0;
			paddle_ball_collision <= 1'b0;
		end
	end
end

endmodule

I would really appreciate your help, I've been working on it for many hours the last few days, and I just can't wrap my head around what's the problem is. I tried many solutions and I checked few times that my files are correct and there's no problem with the names or wires.

thank you in advance

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.