Wednesday, April 18, 2012

FSM VHDL Lab Code for Thunderbird Turn Signal circuit design (FPGA Digital Systems Project Explanation)


Using Thunderbird Turn Signal digital circuit lab, you can learn how the logic of finite state machine is implemented in real life embedded world for example in this case, 1965 Ford Thunderbird. FSM's contributes a lot more functionality to the world of Digital Systems

SO What is FSM (finite-state machine): A finite-state machine (FSM) or finite-state automaton (plural: automata), or simply a state machine, is a mathematical model used to design computer programs and digital logic circuits. It is conceived as an abstract machine that can be in one of a finite number of states. The machine is in only one state at a time; the state it is in at any given time is called the current state. It can change from one state to another when initiated by a triggering event or condition, this is called a transition. A particular FSM is defined by a list of the possible transition states from each current state, and the triggering condition for each transition.

Now after getting familiar with FSM, lets practice programming it in VHDL language using Thunderbird Turn Signal fsm design circuit lab.

Project specification: The tail lights of a 1965 Ford Thunderbird is shown below. There are three lights on each side that operate in sequence to indicate the direction of a turn. There are three flashing sequence: left turn, right turn, and hazard.


The left-turn sequence is:



The right-turn sequence is similar and represents a “mirror” sequence of the left-turn pattern. In the hazard sequence, the six lights flash on and off alternatively. In all sequences, we assume that each pattern stays for 300 ms.

A simple FSM can be constructed to control the tail light operation. The input and output of the thunderbird turn signal lab are as follows:

Input:
 clk: 50 MHz clock signal from the DE1 board.
 reset
 tick: 1-bit 300ms “tick” signal. It is asserted for one clock cycle every 300 ms.
 left: 1-bit left-turn signal.
 right: 1-bit right-turn signal.
 haz: 1-bit hazard signal.

Output:
 light: 6-bit light signal.

The Thunderbird Turn Signal digital design circuit lab system operates as follows:
11.> Anytime haz is asserted, the FSM enters the hazard sequence immediately. If the FSM currently in the middle of a left- or right-turn, sequence, the sequence will be aborted.

22.> When haz is not asserted and left is asserted and, the FSM goes through the complete left-turn sequence. This means that the lights should go through a complete left-turn sequence even if left is de asserted sometime in the middle of the sequence or if right is asserted in the middle of a sequence. However, the FSM enters the hazard sequence if haz is asserted.

33.> When haz is not asserted and right is asserted and, the FSM goes through the complete right-turn sequence. This means that the lights should go through a complete right-turn sequence even if right is de-asserted sometime in the middle of the sequence or if left is asserted in the middle of a sequence. However, the FSM enters the hazard sequence if haz is asserted.

44.> We assume that left and right will never be asserted simultaneously.


Design Procedures: We can divide this circuit into two segments: 

Counter: generate a one-clock pulse (tick) every 300 ms. 
=>> I have explained how to achieve counter functionality in previous post(you can find them there: digital systems labs). 

FSM: 
=>> Convert the state diagram to an ASM chart following the notations used in the text. Once done with state diagrams, design the FSM as an independent VHDL module.  The entity declaration of this design is    
entity tbird_fsm is
   port(

   clk, reset: std_logic;

   tick, left, right, haz: std_logic;

   light: out std_logic_vector(5 downto 0);
    );
  END tbird_fsm;

After that we will also need to derive the architecture body which will be added below in whole program code. 

Thunderbird lab VHDL code for implementing tail light FSM digital systems circuit:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity lights is
   port(
      clk, reset: in std_logic;
      l, r, h: in std_logic;
      light: out std_logic_vector(5 downto 0)
   );
end lights;
architecture arch of lights is
   constant DVSR: integer:=5000000;
   signal ms_reg, ms_next: unsigned(22 downto 0);
 
   type eg_state_type is (s0, sh1, sh2, sl1, sl2, sl3, sr1, sr2, sr3);
   signal state_reg, state_next: eg_state_type;
begin
  process(clk)
   begin
      if (clk'event and clk='1') then
         ms_reg <= ms_next;
-- d0_reg <= d0_next;
      end if;
   end process;
ms_next <=
      (others=>'0') when ms_reg=DVSR else
      ms_reg + 1;
 -- state register
   process(reset,clk,ms_reg,state_reg)
   begin
      if (reset='1') then
         state_reg <= s0;
      elsif (clk='1' and clk'event) then
if (ms_reg=DVSR) then
state_reg <= state_next;
      end if;
end if;
   end process;
   -- next-state logic
   process(state_reg, l, r, h, clk)
   begin
--if tick='1' then
      case state_reg is
        when s0=>
if (h='1') then state_next <= sh1;
elsif (l='1') then state_next <= sl1;
elsif (r='1') then state_next <=sr1;
else state_next <= s0;
end if;
when sh1=>
state_next <= sh2;
when sh2=>
if (h='1') then state_next <= sh1;
elsif (l='1') then state_next <= sl1;
elsif (r='1') then state_next <=sr1;
else state_next <= s0;
end if;
when sl1=>
if (h='1') then state_next <= sh1;
else state_next <= sl2;
end if;
when sl2=>
if (h='1') then state_next <= sh1;
else state_next <= sl3;
end if;
when sl3=>
if (h='1') then state_next <= sh1;
elsif (l='1') then state_next <= sl1;
elsif (r='1') then state_next <=sr1;
else state_next <= s0;
end if;
when sr1=>
if (h='1') then state_next <= sh1;
else state_next <= sr2;
end if;
when sr2=>
if (h='1') then state_next <= sh1;
else state_next <= sr3;
end if;
when sr3=>
if (h='1') then state_next <= sh1;
elsif (l='1') then state_next <= sl1;
elsif (r='1') then state_next <=sr1;
else state_next <= s0;
end if;
      end case;
--end if;
end process;
   -- Moore output logic
   process(state_reg)
   begin
      case state_reg is
         when s0 =>
-- if tick='1' then
            light <= "000000";
-- end if; when sh1 =>
-- if tick='1' then
            light <= "111111";
-- end if;
         when sh2 =>
-- if tick='1' then
            light <= "000000";
-- end if; when sl1 =>
-- if tick='1' then
            light <= "001000";
-- end if;
         when sl2 =>
-- if tick='1' then
            light <= "011000";
-- end if; when sl3 =>
-- if tick='1' then
            light <= "111000";
-- end if;
         when sr1 =>
-- if tick='1' then
            light <= "000100";
-- end if; when sr2 =>
-- if tick='1' then
            light <= "000110";
-- end if;
when sr3 =>
-- if tick='1' then
            light <= "000111";
-- end if;
      end case;
   end process;
end arch;



   
Then obviously compile the design and perform simulation to verify its operation. I used EP2C20F484C8 Cyclone ii FPGA Starter board for implementation of Thunderbird Turn Signal FSM digital circuit design.

Implementation and testing:
You will use the 50MHz oscillator for clock and 4 switches for the reset signal and three control signals. You could use any FPGA board but I have compiled and tested the code on Altera provided FPGA board. I have posted below the pin assignments I used for my EP2C20F484C8 Cyclone ii FPGA Starter board:
From To Assignment Name Value Enabled
     reset Location PIN_L22 Yes
     h Location PIN_L21 Yes
     r Location PIN_M22 Yes
     l Location PIN_V12 Yes
     clk Location PIN_L1 Yes
light[0] Location PIN_R20 Yes
light[1] Location PIN_R19 Yes
light[2] Location PIN_U19 Yes
light[3] Location PIN_Y19 Yes
light[4] Location PIN_T18 Yes
light[5] Location PIN_V19 Yes

1 comments:

how would you create a testbench for this in modelsim?

Post a Comment