-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathuart80.vhd
205 lines (196 loc) · 6.11 KB
/
uart80.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
-- **********************************************************
-- * UART Serial Interface . *
-- *========================================================*
-- * Project: FG in PROASIC *
-- * File: uart.vhd *
-- * Author: Chien-Chia Wu *
-- * Description: UART *
-- * *
-- * Hierarchy:parent: *
-- * child : *
-- * *
-- * Revision History: *
-- * Date By Who Modification *
-- * 02/13/03 Chien-Chia Wu Reference uart statements t *
-- * 02/14/03 Chien-Chia Wu (1)Copy from bpchip, *
-- * (2)Modify as 32-bits . *
-- * (3)Swap the cts and rts . *
-- * 02/29/12 Chen-Hanson Ting Back to eP16 *
-- * 03/10/12 Chen-Hanson Ting for eP8080 *
-- **********************************************************
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_misc.all;
use ieee.std_logic_unsigned.all;
entity uart is
port(
-- input
clk_i: in std_logic;
rst_i: in std_logic;
ce_i: in std_logic;
read_i: in std_logic;
write_i: in std_logic;
addr_i: in std_logic_vector(1 downto 0);
data_i: in std_logic_vector(7 downto 0);
-- output
data_o: out std_logic_vector(7 downto 0);
-- external interface
rxd_i: in std_logic;
txd_o: out std_logic
);
end uart;
architecture behavioral of uart is
signal baudrate_reg: std_logic_vector(15 downto 0);
signal hw_xonoff_ff: std_logic;
signal tx_shift_reg: std_logic_vector(10 downto 0);
signal tx_shift_en: std_logic;
signal tx_en: std_logic;
signal tx_rq: std_logic;
signal tx_counter: std_logic_vector(15 downto 0);
signal tx_bitcnt: std_logic_vector(3 downto 0);
signal rx_shift_reg: std_logic_vector(7 downto 0);
signal rx_buffer_reg: std_logic_vector(7 downto 0);
signal rxb_full: std_logic;
signal rx_full: std_logic;
signal rx_en: std_logic;
signal rx_counter: std_logic_vector(15 downto 0);
signal rx_bitcnt: std_logic_vector(3 downto 0);
signal rxd_ff: std_logic;
begin
-- ********************************************************
-- Uart Register Circuit for Read
-- ********************************************************
uart_register_file_read:
process(read_i, ce_i, addr_i, baudrate_reg, tx_en,
hw_xonoff_ff, rxb_full, rx_buffer_reg)
begin
if (read_i='1' and ce_i='1') then
case addr_i is
when "00" => data_o <= baudrate_reg(7 downto 0);
when "01" => data_o <= -- read TX ready flag
"0000000" &
((not tx_en)and((not hw_xonoff_ff)))
;
when "10" => data_o <= --only cleared by rxb read
"000000" & rxb_full & hw_xonoff_ff;
when others => data_o <= -- read&clear rxb_full flag
rx_buffer_reg;
end case;
else
data_o <= (others=>'1');
end if;
end process uart_register_file_read;
-- **********************************************************
-- Uart Register File Process for Write
-- **********************************************************
uart_register_file_write : process (rst_i, clk_i)
begin
if ( rst_i='1' ) then
baudrate_reg<="0000000110101111";
-- 50 MHz, 115.2Kbps
tx_shift_reg <= (others=>'0');
tx_rq <= '0';
hw_xonoff_ff <= '0';
elsif (clk_i'event and clk_i='1') then
if (tx_en='0') then
if (write_i='1' and ce_i='1') then
case addr_i is
when "00"=>baudrate_reg(7 downto 0)<=data_i;
when "01"=>
tx_shift_reg<="11"&data_i(7 downto 0)&'0';
tx_rq<='1';
when "10"=>hw_xonoff_ff<=data_i(0);--flow Control
when others => null;
end case;
end if;
else
tx_rq <= '0';
if (tx_shift_en='1') then
tx_shift_reg<='1'&tx_shift_reg(10 downto 1);
end if;
end if;
end if;
end process uart_register_file_write;
-- **********************************************************
-- Uart TX Core Process
-- **********************************************************
uart_tx_core : process ( rst_i, clk_i)
begin
if (rst_i='1') then
tx_counter <= (others=>'0');
tx_bitcnt <= (others=>'0');
txd_o <= '1';
tx_en <= '0';
tx_shift_en <= '0';
elsif ( clk_i'event and clk_i='1' ) then
tx_shift_en <='0';
if (tx_en='0') and (tx_rq='1') and
(hw_xonoff_ff='0') then
tx_counter <= baudrate_reg;
tx_bitcnt <= "1011";
tx_en <= '1';
elsif (tx_en='1') then
if (tx_counter/="0000000000000000")
then tx_counter <= tx_counter-1;
elsif (tx_bitcnt/="0000") then
tx_bitcnt <= tx_bitcnt-1;
txd_o <= tx_shift_reg(0);
tx_shift_en <= '1';
tx_counter <= baudrate_reg;
else
txd_o <= '1'; -- mark-high=stop-bit
tx_en<='0'; -- closed
end if;
end if;
end if;
end process uart_tx_core;
-- **********************************************************
-- Uart RX Core Process
-- **********************************************************
uart_rx_core : process ( rst_i, clk_i)
begin
if (rst_i='1') then
rx_full <= '0';
rxb_full <= '0';
rx_buffer_reg <= (others=>'0');
rx_counter <= (others=>'0');
rx_bitcnt <= (others=>'0');
rx_en <= '0';
rx_shift_reg <= (others=>'0');
rxd_ff <= '1';
elsif ( clk_i'event and clk_i='1' ) then
rxd_ff <= rxd_i;
if (rx_full='1') then
if (rxb_full='0') or
(read_i='1' and ce_i='1' and addr_i="11") then
rx_buffer_reg <= rx_shift_reg;
rxb_full <= '1';
rx_full <= '0';
end if;
else
if (read_i='1' and ce_i='1' and addr_i="11") then
rxb_full <= '0';
end if;
if (rx_en='0') and (rxd_ff='0') then
rx_counter <= '0' & baudrate_reg(15 downto 1);
rx_bitcnt <= "1001";
rx_en <= '1';
elsif (rx_en='1') then
if(rx_counter/="0000000000000000")
then -- bit-T-counting
rx_counter <= rx_counter-1;
elsif (rx_bitcnt/="0000") then
-- last bit has been received
rx_bitcnt <= rx_bitcnt-1;
rx_shift_reg<=rxd_ff&rx_shift_reg(7 downto 1);
rx_counter <= baudrate_reg;
else
rx_full <= '1';
rx_en <= '0';
end if;
end if;
end if;
end if;
end process uart_rx_core;
end behavioral;