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
32
    
33
entity  UART is
34
  Generic ( Quarz_Taktfrequenz : integer   := 50000000;  -- Hertz               
35
            Baudrate : integer :=  12000000              -- Bits/Sec             
36
        );     
37
38
  Port ( 
39
      
40
      tx_data      : in   std_logic_vector (7 downto 0);
41
      TXD          : out  STD_LOGIC;           
42
         taste_start    : in   STD_LOGIC;           
43
         taste_stopp   : in   STD_LOGIC;
44
      CLK          : in   STD_LOGIC;
45
      
46
      
47
      
48
      RXD      : in   STD_LOGIC;
49
      RX_Data  : out  STD_LOGIC_VECTOR (7 downto 0));
50
      --RX_Busy  : out  STD_LOGIC);
51
      
52
end UART;
53
54
architecture Behavioral of UART is
55
56
signal tx_start : std_logic := '0';
57
signal tx_busy  : std_logic := '0';
58
--signal tx_data  : std_logic_vector  (7 downto 0);-- := x"F0";
59
signal txsr     : std_logic_vector  (9 downto 0):= (others=>'1');
60
signal txbitcnt : integer range 0 to 10 := 10;
61
signal txcnt    : integer range 0 to (Quarz_Taktfrequenz/Baudrate)-1;
62
signal txd_tmp   :std_logic := '0';
63
64
65
--signal rxd_sr    : std_logic_vector (3 downto 0) := "1111";  -- Flankenerkennung und Eintakten
66
signal rxd_sr    : std_logic_vector (1 downto 0) := "11";  -- Flankenerkennung und Eintakten
67
68
69
signal rxsr      : std_logic_vector (7 downto 0) := "00000000";     -- 8 Datenbits
70
signal rxbitcnt   : integer range 0 to 9 := 9;
71
signal rxcnt      : integer range 0 to (Quarz_Taktfrequenz/Baudrate)-1; 
72
73
74
75
76
77
begin 
78
79
-- Verwaltung
80
process begin
81
   wait until rising_edge(CLK);
82
   if (taste_start='1') then     -- Daten = 0xF0
83
--      tx_data <= x"F0";
84
    tx_start <= '1';
85
   end if;
86
   if (taste_stopp='1') then     -- Stoppen
87
      tx_start <= '0';
88
   end if;
89
  
90
end process;
91
92
93
94
95
-- Senden
96
97
TXD     <= txsr(txsr'left);
98
txd_tmp   <= txsr(txsr'left);
99
100
process begin
101
   wait until rising_edge(CLK);
102
   if (tx_start = '1' and tx_busy = '0') then   -- dauernd senden, solange tx_start aktiv
103
      txcnt    <= 0;                            -- Zähler initialisieren         
104
      txbitcnt <= 0;                               
105
      txsr     <= '0' & tx_data & '1';          -- Startbit, 8 Datenbits, Stopbit      
106
  else
107
      if txcnt < ((Quarz_Taktfrequenz/Baudrate)-1)then            
108
         txcnt <= txcnt+1;
109
      else  -- nächstes Bit ausgeben              
110
         if (txbitcnt < 10) then              
111
            txcnt    <= 0;              
112
            txbitcnt <= txbitcnt+1;              
113
            txsr     <= txsr(txsr'left-1 downto 1) & '1';  --txsr     <= txsr(txsr'left-1 downto 1) & '1'; 
114
         end if;         
115
      end if;      
116
  end if;
117
  
118
   if (txbitcnt < 10) then
119
    tx_busy <= '1';
120
    else tx_busy <='0';
121
  end if;
122
end process;
123
124
125
126
-- Empfangen
127
process begin
128
wait until rising_edge(CLK);      
129
--rxd_sr <= rxd_sr(rxd_sr'left-1 downto 0) & txd_tmp;
130
rxd_sr <= rxd_sr(0) & txd_tmp;      
131
       
132
  if (rxbitcnt < 9) then    -- Empfang läuft         
133
    if(rxcnt < (Quarz_Taktfrequenz/Baudrate)-1) then             
134
      rxcnt <= rxcnt+1;         
135
      else rxcnt      <= 0;             
136
          rxbitcnt <= rxbitcnt+1;            
137
          --rxsr     <= rxd_sr(rxd_sr'left-1) & rxsr(rxsr'left downto 1);   -- rechts schieben, weil LSB first
138
          --rxsr     <= rxd_sr(rxd_sr'left-1) & rxsr(1);               -- rechts schieben, weil LSB first 
139
        
140
          rxsr     <= rxd_sr(1) & rxsr(rxsr'left downto 1);            -- rechts schieben, weil LSB first
141
              
142
    end if;      
143
    else -- warten auf Startbit         
144
    --if (rxd_sr(3 downto 2) = "10") then                               -- fallende Flanke Startbit 
145
    if (rxd_sr = "10") then    
146
      --rxcnt    <= ((Quarz_Taktfrequenz/Baudrate)-1)/2;               -- erst mal nur halbe Bitzeit abwarten(bei langsamaren Frequenzen (7 MBit/s)            
147
      rxcnt <= 2;                                          -- erst mal nur halbe Bitzeit abwarten (weil hohe Bitrate)
148
      rxbitcnt <= 0;         
149
    end if;      
150
  end if;   
151
end process;   
152
RX_Data <= rxsr;  
153
--RX_Busy <= '1' when (rxbitcnt<9) else '0';
154
155
156
end Behavioral;