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;
|