| 1 | library ieee;
 | 
| 2 | use ieee.std_logic_1164.all;
 | 
| 3 | use ieee.std_logic_unsigned.all;
 | 
| 4 | use ieee.std_logic_arith.all;
 | 
| 5 | 
 | 
| 6 | 
 | 
| 7 | entity uart is
 | 
| 8 |   
 | 
| 9 |   port (
 | 
| 10 |     clk             : in  std_logic;
 | 
| 11 |     reset           : in  std_logic;
 | 
| 12 |     seriell_in      : in  std_logic;
 | 
| 13 |     seriell_out     : out std_logic_vector(7 downto 0) := (others => '0');
 | 
| 14 |     seriell_ctr_out : out std_logic := '0';
 | 
| 15 |     test_out        : out std_logic_vector(7 downto 0):= (others => '0'));
 | 
| 16 | 
 | 
| 17 | end uart;
 | 
| 18 | 
 | 
| 19 | 
 | 
| 20 | architecture rtl of uart is
 | 
| 21 | 
 | 
| 22 |   --type and signal for the finit state machine
 | 
| 23 |   type t_state is (IDLE, START, DATS, PARITY, STOP);
 | 
| 24 |   signal presentstate : t_state;
 | 
| 25 |   signal nextstate    : t_state;
 | 
| 26 |   
 | 
| 27 |   --Signal for the prescaler
 | 
| 28 |   signal precount : std_logic := '0';
 | 
| 29 | 
 | 
| 30 |   --Signal for puffering the input
 | 
| 31 |   signal mem_input : std_logic_vector(7 downto 0) := (others => '0');
 | 
| 32 | 
 | 
| 33 |   --constant for the baudrate
 | 
| 34 |   constant baudrate : std_logic_vector(5 downto 0) := conv_std_logic_vector(13,6);--baudrate = 8*460,8kBit/s
 | 
| 35 |   
 | 
| 36 | begin  -- rtl
 | 
| 37 | 
 | 
| 38 |   -- purpose: Prescaler for the uart
 | 
| 39 |   -- type   : sequential
 | 
| 40 |   -- inputs : clk48, reset_n
 | 
| 41 |   -- outputs: precount
 | 
| 42 |   Prescaler: process (clk, reset)
 | 
| 43 |     variable count : std_logic_vector(5 downto 0) := (others => '0');
 | 
| 44 |   begin  -- process Prescaler
 | 
| 45 |     if reset = '0' then                       -- asynchronous reset (active low)
 | 
| 46 |       count := (others => '0');
 | 
| 47 |       presentstate <= IDLE;
 | 
| 48 |     elsif clk'event and clk = '1' then        -- rising clock edge
 | 
| 49 |       presentstate <= nextstate;              -- set the presentstate to the nextstate
 | 
| 50 |       precount <= '0';                        -- reset of the variable precount
 | 
| 51 |       count := count + 1;
 | 
| 52 |       if count = baudrate then
 | 
| 53 |         count := (others => '0');
 | 
| 54 |         precount <= '1';                      --set of the variable precount 
 | 
| 55 |       end if;
 | 
| 56 |       
 | 
| 57 |     end if;
 | 
| 58 |   end process Prescaler;
 | 
| 59 | 
 | 
| 60 | 
 | 
| 61 |   -- purpose: Sequential Process for the fsm
 | 
| 62 |   -- type   : sequential
 | 
| 63 |   -- inputs : clk48, reset_n
 | 
| 64 |   -- outputs: presentstate
 | 
| 65 |   seqfsm2: process (clk, reset)
 | 
| 66 | 
 | 
| 67 |     variable count  : std_logic_vector(3 downto 0) := (others => '0');
 | 
| 68 |     variable dat1  : std_logic_vector(2 downto 0) := (others => '0');
 | 
| 69 |     variable dat0  : std_logic_vector(2 downto 0) := (others => '1');
 | 
| 70 |     variable pos    : integer range 0 to 8 := 0;
 | 
| 71 |     
 | 
| 72 |   begin  -- process seqfsm2
 | 
| 73 |     if reset = '0' then                       -- asynchronous reset (active low)
 | 
| 74 |       
 | 
| 75 |     elsif clk'event and clk = '1' then      -- rising clock edge
 | 
| 76 |       seriell_ctr_out <= '0';
 | 
| 77 |       if precount = '1' then
 | 
| 78 |         case presentstate is
 | 
| 79 |           -------------------------------------------------------------------------------
 | 
| 80 |           -- IDLE State
 | 
| 81 |           -------------------------------------------------------------------------------
 | 
| 82 |           when IDLE =>                         
 | 
| 83 |             mem_input <= (others => '0');
 | 
| 84 |             if seriell_in = '0' then            -- if seriell_in = 0 the receiving starts 
 | 
| 85 |               nextstate <= START;
 | 
| 86 |             end if;
 | 
| 87 |           -------------------------------------------------------------------
 | 
| 88 |           -- START State
 | 
| 89 |           -------------------------------------------------------------------
 | 
| 90 |           when START =>                         
 | 
| 91 |             pos := 0;
 | 
| 92 |             if seriell_in = '0' then
 | 
| 93 |               count := count + 1;
 | 
| 94 |               if count = conv_std_logic_vector(7,4) then            -- when there were 8 zeros the startbit is finished
 | 
| 95 |                 nextstate <= DATS;
 | 
| 96 |                 dat1  := (others => '0') ;
 | 
| 97 |                 dat0  := (others => '1');
 | 
| 98 |                 count := (others => '0');
 | 
| 99 |               end if;
 | 
| 100 |             else
 | 
| 101 |               nextstate <= IDLE;                -- when there is a error bei the startbis change back to IDLE Mode
 | 
| 102 |             end if;       
 | 
| 103 |           ---------------------------------------------------------------------
 | 
| 104 |           -- DATS State
 | 
| 105 |           ---------------------------------------------------------------------
 | 
| 106 |           when DATS =>                          
 | 
| 107 |             if seriell_in = '0' then
 | 
| 108 |               dat0 := dat0 - 1;
 | 
| 109 |               count := count + 1;
 | 
| 110 |             end if;
 | 
| 111 |             if seriell_in = '1' then
 | 
| 112 |               dat1 := dat1 + 1;
 | 
| 113 |               count := count + 1;
 | 
| 114 |             end if;
 | 
| 115 |             
 | 
| 116 |             if count = conv_std_logic_vector(5,4) and dat1 = conv_std_logic_vector(5,3) then
 | 
| 117 |               mem_input(pos) <= '1';    --when ther were five times a one the Bitis set to 1
 | 
| 118 |             end if;
 | 
| 119 |             if count = conv_std_logic_vector(5,4) and dat0 = conv_std_logic_vector(2,3) then
 | 
| 120 |               mem_input(pos) <= '0';    --when there were five times a zero the Bit is set to 0
 | 
| 121 |             end if;
 | 
| 122 |             
 | 
| 123 |             if count = conv_std_logic_vector(8,4) then
 | 
| 124 |               pos := pos + 1; 
 | 
| 125 |               dat1 := (others => '0');
 | 
| 126 |               dat0 := (others => '1');
 | 
| 127 |               count := (others => '0');
 | 
| 128 |               if pos = 8 then           -- if 8 Bits are received he change to the STOP State
 | 
| 129 |                 nextstate <= PARITY;
 | 
| 130 |               end if;
 | 
| 131 |             end if;
 | 
| 132 |           ---------------------------------------------------------------------
 | 
| 133 |           -- PARITY State
 | 
| 134 |           ---------------------------------------------------------------------  
 | 
| 135 |           when PARITY =>
 | 
| 136 |             --In this state you have the possibility to control the message
 | 
| 137 |             --with the parity bit.
 | 
| 138 |             count := count + 1;
 | 
| 139 |             if count = conv_std_logic_vector(8,4) then    --if he received the Stopbit he change to the IDLE State
 | 
| 140 |               nextstate <= STOP;
 | 
| 141 |               count := (others => '0');
 | 
| 142 |             end if;
 | 
| 143 |           ---------------------------------------------------------------------
 | 
| 144 |           -- STOP State
 | 
| 145 |           ---------------------------------------------------------------------  
 | 
| 146 |           when STOP =>                          -- STOP State
 | 
| 147 |             if seriell_in = '1' then
 | 
| 148 |               count := count + 1;
 | 
| 149 |               if count = conv_std_logic_vector(8,4) then    --if he received the Stopbit he change to the IDLE State
 | 
| 150 |                 nextstate <= IDLE;
 | 
| 151 |                 count := (others => '0');
 | 
| 152 |                 dat1 := (others => '0');
 | 
| 153 |                 dat0 := (others => '1');
 | 
| 154 |                 seriell_out <= mem_input;
 | 
| 155 |                 test_out <= mem_input;
 | 
| 156 |                 seriell_ctr_out <= '1';
 | 
| 157 |               end if;
 | 
| 158 |             end if; 
 | 
| 159 |           when others => nextstate <= IDLE;  --if there is an error the fsm go
 | 
| 160 |                                              --back to the IDLE state
 | 
| 161 |         end case;
 | 
| 162 |       end if;
 | 
| 163 |     end if;
 | 
| 164 |   end process seqfsm2;
 | 
| 165 |   
 | 
| 166 | 
 | 
| 167 | end rtl;
 |