Forum: FPGA, VHDL & Verilog Assignment under elsif does not work

von Burak G. (Company: Bilkent Uni) (brekout)

Rate this post
0 useful
not useful
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:
         ball_x_next <=ball_x;
         ball_y_next <=ball_y;
         if refresh_tick = '1' then
           if ball_y> 400 and ball_x > (bar_l -ball_u) and ball_x < (bar_l +120) then --the ball hits  the bar
               yv_next<= -y_v ;
           elsif ball_y <= 0 then--The ball hits the wall
               yv_next<= y_v;
           elsif ball_x <= 0 then --The ball hits the left side of the screen
              xv_next<= x_v;
           elsif ball_x >= 640 then 
              xv_next<= -x_v ; --The ball hits the right side of the screen
           elsif is_ball_on_bricks_area and bricks_collection(current_brick_row, current_brick_column) = '1' then
              yv_next <= y_v;
              bricks_collection(current_brick_row, current_brick_column) <= '0';
           end if; 
           ball_x_next <=ball_x +xv_reg;
           ball_y_next <=ball_y+yv_reg; 
        end if;
    end process;

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 => 

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:

    a <= b;
    b <= c;
    end process;

Is this a similar problem?

: Edited by Moderator
von Klakx (Guest)

Rate this post
1 useful
not useful
firstly, please use vhdl formatting in this forum.

secondly, complete your sensitivity list with all used signals like 

von Burak G. (Company: Bilkent Uni) (brekout)

Rate this post
0 useful
not useful
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.
elsif is_ball_on_bricks_area and 
bricks_collection(current_brick_row, current_brick_column) = '1' then
              yv_next <= y_v;
              bricks_collection(current_brick_row, current_brick_column) 
<= '0';

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.

von Klakx (Guest)

Rate this post
1 useful
not useful
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 

von Lothar M. (lkmiller) (Moderator)

Rate this post
1 useful
not useful
bricks_collection has to be in the sensitivity list also. But that will 
not help that far, because this is a very dirty tricky trick here:
           elsif is_ball_on_bricks_area and bricks_collection(current_brick_row, current_brick_column) = '1' then
              yv_next <= y_v;
              bricks_collection(current_brick_row, current_brick_column) <= '0';
           end if;
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...

von Burak G. (Company: Bilkent Uni) (brekout)

Rate this post
0 useful
not useful
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.


Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]

Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.