UART.vhd


1
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer: 
4
-- 
5
-- Create Date:    12:42:10 10/26/2009 
6
-- Design Name: 
7
-- Module Name:    UART - Behavioral 
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool versions: 
11
-- Description: 
12
--
13
-- Dependencies: 
14
--
15
-- Revision: 
16
-- Revision 0.01 - File Created
17
-- Additional Comments: 
18
--
19
----------------------------------------------------------------------------------
20
library IEEE;
21
use IEEE.STD_LOGIC_1164.ALL;
22
use IEEE.STD_LOGIC_ARITH.ALL;
23
use IEEE.STD_LOGIC_UNSIGNED.ALL;
24
25
---- Uncomment the following library declaration if instantiating
26
---- any Xilinx primitives in this code.
27
--library UNISIM;
28
--use UNISIM.VComponents.all;
29
30
31
entity  UART is
32
  Generic ( Quarz_Taktfrequenz : integer   := 50000000;  -- Hertz               
33
            Baudrate : integer :=  7000000               -- Bits/Sec             
34
        );     
35
36
  Port ( 
37
      
38
      tx_data      : in   std_logic_vector (7 downto 0);
39
      TXD          : out  STD_LOGIC;           
40
         taste_start    : in   STD_LOGIC;           
41
         taste_stopp   : in   STD_LOGIC;
42
      CLK          : in   STD_LOGIC;
43
      
44
      
45
      
46
      RXD      : in   STD_LOGIC;
47
      RX_Data  : out  STD_LOGIC_VECTOR (7 downto 0));
48
      --RX_Busy  : out  STD_LOGIC);
49
      
50
end UART;
51
52
architecture Behavioral of UART is
53
54
signal tx_start : std_logic := '0';
55
signal tx_busy  : std_logic := '0';
56
--signal tx_data  : std_logic_vector  (7 downto 0) := x"F0";
57
signal txsr     : std_logic_vector  (9 downto 0);
58
signal txbitcnt : integer range 0 to 10 := 10;
59
signal txcnt    : integer range 0 to (Quarz_Taktfrequenz/Baudrate);
60
signal txd_tmp   :std_logic := '0';
61
62
63
signal rxd_sr    : std_logic_vector (3 downto 0) := "1111";  -- Flankenerkennung und Eintakten
64
signal rxsr      : std_logic_vector (7 downto 0) := "00000000";     -- 8 Datenbits
65
signal rxbitcnt   : integer range 0 to 9 := 9;
66
signal rxcnt      : integer range 0 to (Quarz_Taktfrequenz/Baudrate)-1; 
67
68
begin 
69
70
-- Verwaltung
71
process begin
72
   wait until rising_edge(CLK);
73
   if (taste_start='1') then -- Daten = 0xF0
74
--      tx_data <= x"F0";
75
    tx_start <= '1';
76
   end if;
77
   if (taste_stopp='1') then -- Stoppen
78
      tx_start <= '0';
79
   end if;
80
  
81
end process;
82
83
-- Senden
84
85
TXD     <= txsr(txsr'left);
86
txd_tmp   <= txsr(0);
87
88
process begin
89
   wait until rising_edge(CLK);
90
   if (tx_start = '1' and tx_busy = '0') then   -- dauernd senden, solange tx_start aktiv
91
      txcnt    <= 0;                            -- Zähler initialisieren         
92
      txbitcnt <= 0;                               
93
      txsr     <= '0' & tx_data & '1';          -- Startbit, 8 Datenbits, Stopbit      
94
  else
95
      if txcnt < ((Quarz_Taktfrequenz/Baudrate))then            
96
         txcnt <= txcnt+1;
97
      else  -- nächstes Bit ausgeben              
98
         if (txbitcnt<10) then              
99
            txcnt    <= 0;              
100
            txbitcnt <= txbitcnt+1;              
101
            txsr     <= txsr(txsr'left-1 downto 1) & '1';  
102
         end if;         
103
      end if;      
104
  end if;
105
  
106
   if (txbitcnt<10) then
107
    tx_busy <= '1';
108
    else tx_busy <='0';
109
  end if;
110
  
111
 
112
end process;
113
114
115
-- Empfangen
116
process begin
117
wait until rising_edge(CLK);      
118
rxd_sr <= rxd_sr(rxd_sr'left-1 downto 0) & txd_tmp;      
119
  if (rxbitcnt<9) then    -- Empfang läuft         
120
    if(rxcnt<(Quarz_Taktfrequenz/Baudrate)-1) then             
121
      rxcnt <= rxcnt+1;         
122
      else rxcnt      <= 0;             
123
          rxbitcnt <= rxbitcnt+1;            
124
          rxsr     <= rxd_sr(rxd_sr'left-1) & rxsr(rxsr'left downto 1); -- rechts schieben, weil LSB first         
125
    end if;      
126
    else -- warten auf Startbit         
127
    if (rxd_sr(3 downto 2) = "10") then                 -- fallende Flanke Startbit            
128
      rxcnt    <= ((Quarz_Taktfrequenz/Baudrate)-1)/2; -- erst mal nur halbe Bitzeit abwarten            
129
      rxbitcnt <= 0;         
130
    end if;      
131
  end if;   
132
end process;   
133
RX_Data <= rxsr;  
134
--RX_Busy <= '1' when (rxbitcnt<9) else '0';
135
136
137
end Behavioral;