EmbDev.net

Forum: FPGA, VHDL & Verilog Order of execution of if statements


von Martin (Guest)


Rate this post
useful
not useful
Hello, as I'm still busy getting into VHDL, I'm every now and then 
encoutering problems where I don't really know how to solve them.
I wrote a process which actually should evaluate the signals listed in 
its sensitivity list. Against my expectation it stopped after evaluating 
the first if statement (at least that's what I think as it didn't 
evaluate the rest of the process. Does anybody know how if statements 
are executed or what I could do in order to get right?

Here's the code of the process:
1
  btn_moved: process(west, east, south)
2
  begin
3
    if west = '1' then
4
      load1_ta <= '1';
5
      buttons_west(3) <= west;
6
      buttons_west(2) <= north;
7
      buttons_west(1) <= east;
8
      buttons_west(0) <= south;
9
    end if;
10
    
11
    if east = '1' then
12
      load2_ta <= '1';
13
      buttons_east(3) <= west;
14
      buttons_east(2) <= north;
15
      buttons_east(1) <= east;
16
      buttons_east(0) <= south;
17
    end if;
18
    
19
    if south = '1' then
20
      rst1_ta <= south;
21
      rst2_ta <= south;
22
      
23
      load1_ta <= '0';
24
      load2_ta <= '0';
25
      
26
      buttons_west(0) <= '0';
27
      buttons_west(1) <= '0';
28
      buttons_west(2) <= '0';
29
      buttons_west(3) <= '0';
30
      
31
      buttons_east(0) <= '0';
32
      buttons_east(1) <= '0';
33
      buttons_east(2) <= '0';
34
      buttons_east(3) <= '0';
35
    end if;
36
  end process btn_moved;

Thanks a lot in advance!

Martin

von Andreas S. (andreas) (Admin)


Rate this post
useful
not useful
Processes are simply evaluated from top to bottom, nothing special 
happening there. The state of a signal is determined by the last 
assignment in a process, so if both west and south are '1', buttons_west 
is "0000".

The best way to deal with unexpected behaviour is to use the simulator. 
First you should write a test bench to feed your module with input 
values and check the respective output values. If there is something 
that doesn't work you can find out exactly what is wrong by 
single-stepping through the code.

You can however not find any problem with the simulator. Only a strictly 
synchronous design, i.e. a design that contains no or only clocked 
storage elements (flip flops) works the same in real hardware as in the 
simulator. In your code, you are describing a latch, which is an 
asynchronous storage element and needs to be avoided. A latch is 
generated because, if neither west, east nor south is '1', some of the 
signals have to keep the value from before the process execution. The 
only way to do that in hardware without a clock is a latch. If you need 
that behavior, use a clocked process ("if rising_edge(clk)..."). If you 
don't, give all signals default assignments at the start of the process. 
Then the result of the process will only depend from its input 
variables, not from the previous state of the signals, and you get a 
simple logic network without latches.

von Martin (Company: Angestellt) (herki)


Rate this post
useful
not useful
Hi Martin

Sorry for my bad english.
You are watching on all 3 signals. First of all u have to think about :
* wich priority has each of the 3 signals
* can two or three signals = '1' at the same moment?

You dont use any Clk. That is not really good. Your Design-Software will 
use some Latches.

I think the signals named rst1_ta  rst2_ta  load1_ta and load2_ta are 
not correct assigned. Background:
1. west = '1' --> load1_ta = '1'
2. east = '1' --> load1_ta = '1' and load2_ta = '1' (Is this correct?)

I think the following code is a proper solution. But still without Clk.

btn_moved: process(west, east, south)
  begin
    if west = '1' then
      load1_ta <= '1';
      buttons_west(3) <= west;
      buttons_west(2) <= north;
      buttons_west(1) <= east;
      buttons_west(0) <= south;

    elsif east = '1' then
      load2_ta <= '1';
      buttons_east(3) <= west;
      buttons_east(2) <= north;
      buttons_east(1) <= east;
      buttons_east(0) <= south;

    else --(when the previous statements are not treu)
      rst1_ta <= south;
      rst2_ta <= south;

      load1_ta <= '0';
      load2_ta <= '0';

      buttons_west(3 downto 0) <= "0000";

      buttons_east(3 downto 0) <= "0000";
    end if;
  end process btn_moved;

Now thats the priority of the signals:
1. west
2. east
3. south or when none of the previos if-statement are true

Hopefully I thats helpfull.

Greetings

Martin

von Daniel (root) (Guest)


Rate this post
useful
not useful
Just to make it complete .. one should carefully watch out since there 
is a priority issue
1
x <= 1; -- default, 
2
if a then
3
    x <= 2;
4
elsif b then
5
    x <= 3;
6
elsif c then
7
    x <= 4;
8
else
9
-- apparanty not needed, since default value above is provided
10
-- but some like to express it explicitly
11
end if;

that's the same as
1
if c then
2
    x <= 4;
3
end if;
4
if b then
5
    x <= 3;
6
end if;
7
if a then
8
   x <= 2;
9
else
10
   x <= 1;
11
end if;
1
x <= 1;
2
if c then
3
    x <= 4;
4
end if;
5
if b then
6
    x <= 3;
7
end if;
8
if a then
9
   x <= 2;
10
end if;

if you want comb. logic make default assignment
that's rule I always stick to
it makes code more readable than having tons of if/else branches

hope this was helpful

von help (Guest)


Rate this post
useful
not useful
By the way, 'north' needs also to be in the sensitivity list.

von Martin (Guest)


Rate this post
useful
not useful
Hi,
thanks a lot for your replies. As I said I'm still busy learning VHDL so 
I was not aware of how if-constructions are processed. Eventually I 
solved the problem by rewriting the code in a different way where not 
that many if's are required. But thanks a lot anyway.

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.