You have no items in your shopping cart.

Subtotal: 0.00

Abstract

To meet modern complex control systems communication demands, the project presents a multi-channel UART controller based on FIFO(First In First Out) technique and FPGA(Field Programmable Gate Array). The project presents design method of asynchronous FIFO and structure of the controller implemented in Spartan3an FPGA Project kit. This controller is designed with FIFO circuit block and UART (Universal Asynchronous Receiver Transmitter) circuit block within FPGA to implement communication in modern complex control systems quickly and effectively. From the communication sequence diagrams, it is easily to know that this controller can be used to implement communication when master equipment and slaver equipment are set at different Baud Rate. It also can be used to reduce synchronization error between sub-systems in a system with several sub-systems. The controller is reconfigurable and scalable.

Demonstration Video

 

Software:

  • Xilinx ISE 10.1i or above

Language:

  • VHDL, C Code

Hardware:

 

Block Diagram for FPGA Implementation of Multi Channel UART using Spartan3an FPGA Project kit



Block_Dgm_Multi_Channel_UART



ARC_Dgm_Multi_Channel_UART

Introduction:

In the multi-channel controller, there are different blocks including UART block, Status Detectors, asynchronous FIFOs block and Baud Rate Generator block. Each block has different function in the controller. The first part is UART circuit block. It consists of three parts Receive Circuit, Transmit Circuit and Control/Status Registers. The Transmit Circuit consists of a Transmit Buffer and a Shift Register. Transmit Buffer loads data being transmitted from local CPU. And Shift Register accepts data from the Transmit Buffer and send it to the TXD pin one by one bit. The Receive Circuit consists of a Receive Shift Register and a Receive Buffer. The Receive Shift Register receives data from RXD one by one bit. The Receive Buffer loads data from long-distance MCU and gets it ready for the local PC to read.

The Control Register a special function register is used to control the UART and indicate status of it. According to each bit’s value the UART will choose different kind of communication method and the UART knows what to do to receive or transmit data. FIFOs are used to store data received from the PC and get ready for sub MCUs. When writing data into FIFOs and reading data out of FIFOs we could set different clock domains according to the PC’s and MCUs’ Baud Rate. So it can be used to implement communications between MCUs at different Baud Rate

Flow chart



flow_char_Multi_Channel_UART

Spartan3an FPGA Project kit UART Placement



SP3_stick_Multi_Channel_UARTs

Multi Channel UART using Spartan3an FPGA Project kit Output Image

Multi Channel UART using Spartan3an FPGA Project Kit Output Image

 

Multi Channel UART using Spartan3an FPGA Project Kit Output Image

Multi Channel UART using Spartan3an FPGA Project Kit Output Image

 

Multi Channel UART using Spartan3an FPGA Project Kit Output Image

 

Multi Channel UART using Spartan3an FPGA Project Kit Output Image

Source Code

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity topmodule is
port(En_50   : in std_logic;
     En_25   : in std_logic;
     En_12_5 : in std_logic;
     En_6_25 : in std_logic;	  
     clk     : in std_logic;
     uartout : out std_logic;
     uartout1 : out std_logic;
	  uartout2 : out std_logic
);
end topmodule;


architecture bhv of topmodule is
constant speed: natural := 50e6;
signal clk1 : std_logic;
signal clk_s : std_logic; 
signal clk_s1 : std_logic;
signal clk_s2 : std_logic;

component test
generic(system_speed: integer);
port(clock : in std_logic;
     txd   :out std_logic);
	  end component;
	  
begin

P1:process(clk)
begin 
if (clk'event and clk = '1') then
clk_s <= not (clk_s);
end if;
end process P1;

P2:process(clk)
begin 
if (clk_s'event and clk_s = '1') then
clk_s1 <= not (clk_s1);
end if;
end process P2;

P3:process(clk)
begin 
if (clk_s1'event and clk_s1 = '1') then
clk_s2 <= not (clk_s2);
end if;
end process P3;

enable: process(clk)
begin
if En_50 = '1' then
clk1 <= clk;

elsif En_25 = '1' then
clk1 <= clk_s;

elsif En_12_5 = '1' then
clk1 <= clk_s1;

elsif En_6_25 = '1' then
clk1 <= clk_s2;

end if ;
end process enable;


clock_mana1 : test generic map(system_speed=> speed)
port map (clk1,uartout);
clock_mana2 : test generic map(system_speed=> speed)
port map (clk1,uartout1);
clock_mana3 : test generic map(system_speed=> speed)
port map (clk1,uartout2);

	  
end  bhv; 

UART.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity test is
generic(system_speed : integer);
port(clock: in std_logic;
txd: out std_logic);
end entity test;

architecture rtl of test is

signal baudrate_clock, second_clock, old_second_clock: std_logic;
signal bit_counter: unsigned(3 downto 0) := x"9";
signal shift_register: unsigned(9 downto 0) := (others => '0');
signal char_index: natural range 0 to 99;

component clock_generator 
generic(clock_in_speed, clock_out_speed: integer);
port(
clock_in: in std_logic;
clock_out: out std_logic);
end component;

component clock_gen 
generic(clock_in_speed, clock_out_speed: integer);
port(
clk_in: in std_logic;
clk_out: out std_logic);
end component;

begin




baudrate_generator: clock_generator
generic map(clock_in_speed => system_speed, clock_out_speed => 9600)
port map(
clock_in => clock,
clock_out => baudrate_clock);

clk_generator: clock_gen
generic map(clock_in_speed => system_speed, clock_out_speed => 1)
port map(
clk_in => clock,
clk_out => second_clock);

send: process(baudrate_clock)
begin
 
if baudrate_clock'event and baudrate_clock = '1' then
txd <= '1';
if bit_counter = 9 then
if second_clock /= old_second_clock then
old_second_clock <= second_clock;
if second_clock = '1' then
bit_counter <= x"0";
char_index <= char_index + 1;
case char_index is
when 0 =>
shift_register <= b"1" & x"48" & b"0";--H
when 1 =>
shift_register <= b"1" & x"45" & b"0";--E
when 2 =>
shift_register <= b"1" & x"4C" & b"0";--L
when 3 =>
shift_register <= b"1" & x"4C" & b"0";--L
when 4 =>
shift_register <= b"1" & x"4F" & b"0";--O
when 5 =>
shift_register <= b"1" & x"48" & b"0";--H
when 6 =>
shift_register <= b"1" & x"48" & b"0";--H
when 7 =>
shift_register <= b"1" & x"45" & b"0";--L
when 8 =>
shift_register <= b"1" & x"4C" & b"0";--L
when 9 =>
shift_register <= b"1" & x"4F" & b"0";--O

when others =>
shift_register <= b"1" & x"00" & b"0";
--char_index <= 0;
--when others =>
--char_index <= 0;
end case;
end if;
end if;
else
txd <= shift_register(0);
bit_counter <= bit_counter + 1;
shift_register <= shift_register ror 1;
end if;
end if;
end process;

end architecture rtl;

Pin Assignment for Spartan3an FPGA Project kit

NET "clk"  LOC = "p127"  ;
NET "En_6_25"  LOC = "p33"  ;
NET "En_12_5"  LOC = "p35"  ;
NET "En_25"  LOC = "p45"  ;
NET "En_50"  LOC = "p53"  ;
NET "uartout"  LOC = "p75"  ;
NET "uartout1"  LOC = "p54"  ;
NET "uartout2"  LOC = "p77"  ;

NET "En_6_25" CLOCK_DEDICATED_ROUTE = FALSE;