Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

VHDL state machine execution

Status
Not open for further replies.

hareeshP

Member level 3
Joined
Jul 19, 2017
Messages
59
Helped
1
Reputation
2
Reaction score
1
Trophy points
8
Activity points
491
Hi all,
I have posted a portion of a code. Which is a state machine. I want to know how the below code executes. In the code, when this statement is ture

Code VHDL - [expand]
1
if scl_falling_strobe = '1' and bit_counter = 8 then

the code executes SEND_ACK1 state or it goes on executing sequentially (next line)??




Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
when WRITE_CMD =>
                --On each rising edge, read the data bit on the SDA line and store it
                --in rx_data_buf
                if scl_rising_strobe = '1' then
                    if bit_counter <= 7 then
                        rx_data_buf(7-bit_counter)  <= sda_d;
                        bit_counter                 <= bit_counter + 1;
                    end if;
                    if bit_counter = 7 then
                        rx_data_rdy_reg     <= '1';
                    end if;
                end if;
 
                --When the byte is done, send an ACK
                if scl_falling_strobe = '1' and bit_counter = 8 then
                     state           <= SEND_ACK_1;
                     bit_counter     <= 0;
                        if data_flag = 0 then
                            temp <= rx_data_buf;
                            conversion <= unsigned(temp);
                            data_read <= to_integer(conversion);
                            data_flag       <= data_flag + 1;
                       elsif data_flag = 1 then
                            r_memory(data_read) <= rx_data_buf;                         
                            data_flag       <= data_flag + 1;
                        elsif data_flag = 2 then
                            data_flag <= 0;
                        end if;

 

Neither.

Think of signal assignments being "prepared" in the process, but executed all together in zero time at its very end (remember, you can have multiple assignments to the same signal in a process where only the last one "wins"). So, state will indeed be "SEND_ACK_1" at the end of the process, but other statements will be executed as well. This also assures that other processes that might fire on state changes will be triggered soonest at the very end of the current process.

You should read (and understand) about VDHL's "delta cycles" concept.
 

VHDL IS sequential - but like mfro said, signals are only scheduled to be updated at the end of the current delta. So if multiple assignments are made to the same signal, then the last one is taken. But then remember that variables are updated immediatly, so a variable can have multiple different values within a single delta, and pass each of those values to a signal, depending on how the code works. eg:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
variable a : integer;
 
process(clk)
begin
  if rising_edge(clk) then 
    a := 5;
    op0 <= a;
    a := 6;
    op1 <= a;
    a := 7;
    op2 <= a;
  end if;
end process;



So it is important to remember that VHDL code is sequential (to the OP - do not use variables - see how confusing it can all be?)

This also assures that other processes that might fire on state changes will be triggered soonest at the very end of the current process.

Actually, its not the end of the process, but when the process suspends. In RTL you usually have a sensitivity list so the process is executed once when a signal in the sensitivity list changes. If there is no sensitivity list, then the process will need to hit a wait statement before signals will get updated.

To the OP - please ignore the above, and try and understand that you're trying to simulate hardware with this code. So the code cannot be "sequential" like a programming language,

[/pedant]
 

Have you had the chance to simulated it?

From a glance I predict -

bit counter is 0 to 8
when rx_data_buf (7) is assigned, you also set rx_data_rdy_reg (which I assume you're defaulting to 0 or resetting elsewhere)
Half a I2C clock cycle+time to determine edge strobe later you're setting state to SEND_ACK_1 & doing some data flag stuff.

A system clock (or what ever your using for the state machine) later you should be in new state - SEND_ACK_1 & your data flag will have changed

If your system clock isn't fast enough you might find i2c clock is causing chaos by sending new bits before you're moved onto the next state to process it.
 

(to the OP - do not use variables - see how confusing it can all be?)

variables can be useful in some cases. From what I can tell, some devs go though a "variables as local registers" phase and then realize that it wasn't worth it. But for named sub-expressions, and in a few other rare cases, variables are useful. IMO, the use of a variable should be simple and justified.
 

Hi all,
I have posted a portion of a code. Which is a state machine. I want to know how the below code executes. In the code, when this statement is ture

Code VHDL - [expand]
1
if scl_falling_strobe = '1' and bit_counter = 8 then

the code executes SEND_ACK1 state or it goes on executing sequentially (next line)??




Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
when WRITE_CMD =>
                --On each rising edge, read the data bit on the SDA line and store it
                --in rx_data_buf
                if scl_rising_strobe = '1' then
                    if bit_counter <= 7 then
                        rx_data_buf(7-bit_counter)  <= sda_d;
                        bit_counter                 <= bit_counter + 1;
                    end if;
                    if bit_counter = 7 then
                        rx_data_rdy_reg     <= '1';
                    end if;
                end if;
 
                --When the byte is done, send an ACK
                if scl_falling_strobe = '1' and bit_counter = 8 then
                     state           <= SEND_ACK_1;
                     bit_counter     <= 0;
                        if data_flag = 0 then
                            temp <= rx_data_buf;
                            conversion <= unsigned(temp);
                            data_read <= to_integer(conversion);
                            data_flag       <= data_flag + 1;
                       elsif data_flag = 1 then
                            r_memory(data_read) <= rx_data_buf;                         
                            data_flag       <= data_flag + 1;
                        elsif data_flag = 2 then
                            data_flag <= 0;
                        end if;


Can you share the code of your state register and next state logic process.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top