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 help in state machines!!

Status
Not open for further replies.

ellis91

Newbie level 6
Joined
Jul 5, 2011
Messages
13
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,462
Sorry if the post is long, but i need urgent help in this regard. I have to write a vhdl code to accept inputs serially in the form of bytes(1 byte at a time). These bytes are in a particular order i.e they are received in packets where each packet is a frame with a specific number of bytes. This number of bytes in a frame can be defined by the user and is fixed. The main purpose of my code is to:
1. Assign one special byte to mark the beginning of each frame.
2. Search for the special byte in order to start receving data.
3. If the special byte is not found at regular intervals i.e after the number of bytes that the user defined, an error is indicated. Variables to keep count of the errors and the number of special bytes are assigned.
4. If the special byte is found before or after the specific number of bytes, then besides indicating an error, the code should resume receiving data from that special byte.

I know that i have to go about it using state machines, but i don't exactly understnd how the structure of the program and states should be

This was my attempt at the program and i know it is wrong. how can i correct it to do what i want it to do:


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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
-- entity packet_format_error_detection is
port (
 
data_receive, special_byte : in STD_LOGIC_VECTOR(0 to 7);
no_of_bytes : in STD_LOGIC_VECTOR(0 to 7);
clock, subclock : in STD_LOGIC
 
);
 
end final_packet_format_error_detection;
 
architecture statemachine of packet_format_error_detection is
 
type statetype is (IDLE, START_DETECTION, RECEIVE_DATA);
signal state, next_state: statetype;
signal no_error_bytes : integer range 0 to 1024;
signal no_special_bytes : integer range 0 to 1024;
signal byte_count : integer range 0 to 1024;
begin
 
 
operation: process(state, data_receive, special_byte, no_of_bytes, no_error_bytes, no_special_bytes )
 
begin
 
no_error_bytes <= 0;
no_special_bytes <= 0;
byte_count <= 0;
 
case state is
 
when IDLE => if(data_receive = special_byte) then
next_state <= START_DETECTION;
else next_state <= IDLE;
end if;
 
when START_DETECTION => if( clock'event and clock = '1') then
next_state <= RECEIVE_DATA;
else
next_state <= START_DETECTION;
end if;
 
when RECEIVE_DATA => if( subclock'event and subclock = '1') then
byte_count <= byte_count + 1;
if(data_receive = special_byte) then
if(byte_count = no_of_bytes) then
no_special_bytes <= no_special_bytes + 1;
byte_count <= 0;
next_state <= IDLE;
else
no_special_bytes <= no_special_bytes + 1;
no_error_bytes <= no_error_bytes + 1;
byte_count <= 0;
next_state <= RECEIVE_DATA;
end if;
else
next_state <= RECEIVE_DATA;
end if;
else
next_state <= RECEIVE_DATA;
end if;
end case;
end process;
end statemachine;




I can explain it in even better detail if necessary. Please help me at the earliest
 

hi
in entity part it should have same name first thing...
"entity packet_format_error_detection is
port (

data_receive, special_byte : in STD_LOGIC_VECTOR(0 to 7);
no_of_bytes : in STD_LOGIC_VECTOR(0 to 7);
clock, subclock : in STD_LOGIC

);

end final_packet_format_error_detection;"----->replace line to --->end packet_format_error_detection;

and you cannot have two type of clocks in one design
"if( clock'event and clock = '1') then"
and
"if( subclock'event and subclock = '1') then"
you will get error saying bad synchronous description
so use one clock at the start (after the process)


http://esd.cs.ucr.edu/labs/tutorial/fsm.vhd --->small example for reference and syntax
 
Last edited:
  • Like
Reactions: FvM

    FvM

    Points: 2
    Helpful Answer Positive Rating
Thanks for replyin promptly...

Oops. I corrected the entity error. But how do i go about with the structure of the program? i introduced the sub-clock to control the number of bytes allowed per frame. i am aware that verilog allows two clocks provided one clock is dependent on the other. the code is very raw and is far from polished i guess...
 

i think you can use counter instead of using subclock.
but 2 clocks is not allowed in vhdl.
also clock should be placed before case statement if it is state machine.
 

but 2 clocks is not allowed in vhdl.
It's definitely not a problem of VHDL rather than logic synthesis. You'll face the same problem in any HDL design description. Controlling a single signal from multiple clock events would be equivalent to creating a FF with multiple clock inputs, which doesn't exist in any standard logic technology. You can use these arbitrary constructs in simulation, which doesn't care for physical reality.

As suggested, you better start with a FSM template from literature.
 
  • Like
Reactions: sanju_

    sanju_

    Points: 2
    Helpful Answer Positive Rating
hey thanks i didnt know the reason why it wont allow...
 

@sanju: thanks.. i'l try doin that..


@sanju and FvM:

okay.. i understood the reason for not being able to give two clocks in hdl.. but how do i go about programmin the code to do what i want it to do using state machines?..i don't quite get the logic framing..
 

All state variables of you design, "state" as well as additional counters should be assigned in a single clocked process. Everything can be realized based on this concept.
 

I have to write a vhdl code to accept inputs serially in the form of bytes(1 byte at a time). These bytes are in a particular order i.e they are received in packets where each packet is a frame with a specific number of bytes. This number of bytes in a frame can be defined by the user and is fixed. The main purpose of my code is to:
1. Assign one special byte to mark the beginning of each frame.
2. Search for the special byte in order to start receiving data.
3. If the special byte is not found at regular intervals i.e after the number of bytes that the user defined, an error is indicated. Variables to keep count of the errors and the number of special bytes are assigned.
4. If the special byte is found before or after the specific number of bytes, then besides indicating an error, the code should resume receiving data from that special byte.

I know that i have to go about it using state machines, but i don't exactly understand how the structure of the program and states should be

This was my attempt at the program and i know it is wrong. how can i correct it to do what i want it to do:

---------- Post added at 10:03 ---------- Previous post was at 09:59 ----------

All state variables of you design, "state" as well as additional counters should be assigned in a single clocked process. Everything can be realized based on this concept.
thanks .. i'm trying to do that.. but the logic fails with the present way of approach..
 

hi
post the code if you have modified...
 

Some additional comments
- a real design needs outputs, otherwise it's synthesized to nothing
- if data received isn't updated on each cycle, you would want a data valid qualifier signal instead of the dubious "subclock". It's expected to be synchronous with clock, and will be sampled at the rising edge
- you'll need to specify the allowed packet length somehow, e.g. using generics
- if the "special byte" is fixed, it can be also defined by a generic instead of an input port
- I suggest to visualize the intended state flow in a state diagram
 
Some additional comments
- if data received isn't updated on each cycle, you would want a data valid qualifier signal instead of the dubious "subclock". It's expected to be synchronous with clock, and will be sampled at the rising edge
Dubious indeed. Do you know any link to read up on clock qualifier signals?
 

entity final_packet_format_error_detection is
port (

data_receive: in STD_LOGIC_VECTOR(0 to 7);

clock : in STD_LOGIC;
special_byte : in STD_LOGIC_VECTOR(0 to 7) := "10000000";
no_of_bytes: in integer:= 3;

no_error_bytes : inout integer range 0 to 1024 ;
no_special_bytes : inout integer range 0 to 1024

);

end final_packet_format_error_detection;

architecture Behavioral of final_packet_format_error_detection is

type statetype is (IDLE, START_DETECTION, RECEIVE_DATA);
signal state, next_state: statetype;

signal byte_count : integer range 0 to 1024;
begin

state_transition: process ( clock )
begin

if (clock'event and clock='1') then
state <= next_state;
end if;
end process;



operation: process(state, data_receive, special_byte, no_error_bytes, no_special_bytes )

begin

no_error_bytes <= 0;
no_special_bytes <= 0;
byte_count <= 0;



case state is

when IDLE => if(data_receive = special_byte) then
next_state <= START_DETECTION;
else next_state <= IDLE;
end if;

when START_DETECTION => if( clock'event and clock = '1') then
next_state <= RECEIVE_DATA;
byte_count <= byte_count + 1;
else
next_state <= START_DETECTION;
byte_count <= byte_count + 1;
end if;

when RECEIVE_DATA =>
if(data_receive = special_byte) then
if(byte_count = no_of_bytes) then
no_special_bytes <= no_special_bytes + 1;
byte_count <= 0;
next_state <= START_DETECTION;
else
no_special_bytes <= no_special_bytes + 1;
no_error_bytes <= no_error_bytes + 1;
byte_count <= 0;
next_state <= START_DETECTION;
end if;
else
next_state <= START_DETECTION;
end if;

end case;
end process;
end Behavioral;

This is the modified code. The problem is it is not entering the RECEIVE_DATA state. i think the reason has got to have something to do with the loop entry conditions. What are data valid qualifier signals?
 

when START_DETECTION => if( clock'event and clock = '1') then
next_state <= RECEIVE_DATA;
byte_count <= byte_count + 1;
else
next_state <= START_DETECTION;
byte_count <= byte_count + 1 ;
end if;



here
in this code you are trying in positive edge of code next_state <= RECEIVE_DATA; and negative edge of code next_state <= START_DETECTION;..
you will get error
so assign one clock either positive or negative at the start (after the process begin)


so its not entering RECEIVE_DATA
 

when START_DETECTION => if( clock'event and clock = '1') then
next_state <= RECEIVE_DATA;
byte_count <= byte_count + 1;
else
next_state <= START_DETECTION;
byte_count <= byte_count + 1;

end if;

i removed the else condition. shouldn't that solve the problem? i also shifted the clock condition to where you asked me to. but it still doesn't enter the receive_data state. the no_error_bytes and no_special_bytes continue to remain 0.
 

Do not reference clock at all in your second process. The clock should only be in the first process (that assigns state to the next_state).
 
when START_DETECTION => if( clock'event and clock = '1') then -->no need clock here remove "if( clock'event and clock = '1') then"
 

@trickydicky: i found that useful. it enters the receive_data state
but i think it enters an infinite loop now.
 

Sanju - you're not quite understanding.

The new code that ellis posted is the two process state machine template. The first process is:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
process(clk, reset)
begin
  if reset = '1' then
    state <= init;
  elsif rising_edge(clk) then
    state <= next_state;
  end if;
end process;



This process registers the state variable. The next state process is an asynchronous process that creates the next state based on the previous state and inputs. because it is asynchronous there is no clock, and all inputs must be in the sensitivity list.



Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
next_state_proc : process(state, ip0, ip2 etc)
begin
  case state is
    when init =>
      if ip1 = '1' then
        next_state <= state0;
     else
        next_state <= state1;
     end if;
....etc



Any outputs from the second state MUST be assigned in all paths to prevent latches.

---------- Post added at 11:37 ---------- Previous post was at 11:31 ----------

ellis - you should also not put counters in the second process. because it is asynchronous then technically the counters will try and count an infinit number of times per clock cycle. There are two options for this.

1. Instead of assigning the actual count value, assing "next_count" and then assign count to next count in a synchronous process:


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
process(clk, reset)
begin
  if reset = '1' then
    state <= init;
    count <= 0;
 
  elsif rising_edge(clk) then
    state <= next_state;
    count <= next_count;
  end if;
end process;
 
 
--inside your asynchronous "next" process
next_process : process(count, ip1, state)
begin
 
 next_count <= count; --you MUST assign a default state or latches will be created
 
 
  case state is 
    when A =>
      next_count <= count + 1;
...etc




2. The second option is to create a "count_enable" signal set to '1' in the correct state, and then do the counting in a synchronous process when "count_enable" is true.

3. Use a single process state machine. Then you dont need to worry about latches.
 

@trickydicky: i need the byte_count to keep coming back to zero everytime a special byte is encountered. if i assign it to next_count in a synchronous process, will it do that?
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top