Hello everyone,
I am developing a brick breaking game in VHDL. For this project, I have
successfully implemented a image generator and a VGA synchronizer.
However, I am having problems with the game logic. In this game, bricks
are supposed to be destroyed when the ball hits. When a collision is
observed, the ball should change its direction. So as to realize this, I
wrote the following code:
1
process(refresh_tick,ball_x,ball_y,xv_reg,yv_reg)
2
begin
3
ball_x_next<=ball_x;
4
ball_y_next<=ball_y;
5
xv_next<=xv_reg;
6
yv_next<=yv_reg;
7
ifrefresh_tick='1'then
8
ifball_y>400andball_x>(bar_l-ball_u)andball_x<(bar_l+120)then--the ball hits the bar
9
yv_next<=-y_v;
10
elsifball_y<=0then--The ball hits the wall
11
yv_next<=y_v;
12
elsifball_x<=0then--The ball hits the left side of the screen
13
xv_next<=x_v;
14
elsifball_x>=640then
15
xv_next<=-x_v;--The ball hits the right side of the screen
In this game, I define bricks as a 2D array:
type brick_array is array (0 to 4, 0 to 9) of std_logic;
signal bricks_collection : brick_array := (others => (others =>
'1'));
So, when a collision is detected, the destroyed brick is assigned as '0'
and ball change its direction yv_next <= y_v; Unfortunately, only one of
them is executed during the run time which is at this case
bricks_collection(current_brick_row, current_brick_column) <= '0';. I
know that the logic I came up with works, that is, collisions are
detected successfully.
These statements under the last elsif statement should be run
concurrently. But they are not. How do I make them run concurrently?
So I know that in a process if I do something like this, the second
assignment takes place at the second clock tick:
process(clk)
begin
a <= b;
b <= c;
end process;
Is this a similar problem?
firstly, please use vhdl formatting in this forum.
secondly, complete your sensitivity list with all used signals like
"is_ball_on_bricks_area,x,x_v,y_v,.."
Thank you for your reply. I can not go back and change the formatting.
Sorry about that.
I added is_ball_on_bricks_area to the sensitivity list. However, x_v and
y_v are constant which are determining the speed of the ball. That is,
if y_v is 3, ball goes down. If it is -3, the ball goes up.
So let me repeat the problem in different words.
Here, if I remove bricks_collection part, yv_next <= yv part is executed
correctly. However, when I keep it as it is, which I should, only the
second assignment takes place.
current_brick_row and current_brick_column look also like no constants,
try to add them also to sensitivity list.
also there is bricks_collection only defined in one arc which will lead
to latch behavior. I dont know your code and cannot say if this was
intended.
Here we have a asynchronous reset on bricks_collection and therefore a
latch. Usually latches are a very bad thing, because mostly they
happen accidentially. In your design this is (like nearly always) due to
the 2-process coding style.
In other words: bricks_collection is storing some information. Storing
elements in a FPGA should be flipflops. Therefore there should be
something like a bricks_collection_next (like all of the other
flipflops). And that bricks_collection_next then must be written to
bricks_collection with the (one and olny) clock (like all the others).
BTW just one question: why do you use a process for that all?
It could be easily done concurrent...
Thank you so much. Indeed, latch behavior was not intended.
I was able to solve all my problems by introducing the register logic
once more.
Miller, before starting on this project, I read few articles, reports,
and went through some examples of similar games. I saw that they are
using so-called 2-process design method. Therefore, I adapted a similar
approach. However, I have never thought "latch behavior" could lead to
prevent assignment of y_v to yv_next and I have yet to understand the
reason behind that.