Skip to content

Commit 4510a11

Browse files
committed
UART: optimalizations, add frame error detect, etc.
1 parent 3e490cf commit 4510a11

File tree

5 files changed

+278
-91
lines changed

5 files changed

+278
-91
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
Simple UART (Universal Asynchronous Receiver & Transmitter) module for serial communication with an FPGA. The UART module was implemented using VHDL.
44

5-
**The default settings are 115200 Baud rate, 8 Data bits, 1 Stop bit, No parity, disable input data FIFO.**
5+
**The default settings are 115200 baud rate, 8 data bits, 1 stop bit, no parity, disable input data FIFO, 50 MHz system clock.**
66

77
The UART module was tested in hardware. In the near future it will be implemented generic support for parity bit and set the number of stop bits. Stay tuned!
88

99
**Synthesis resource usage summary:**
1010

11-
Input data FIFO | Logic element (LUT) | Registers (FF) | Block RAM (BRAM)
11+
Input FIFO | LE (LUT) | FF | BRAM
1212
--- | --- | --- | ---
13-
disable | 77 | 51 | 0
14-
enable | 116 | 68 | 1
13+
disable | 72 | 46 | 0
14+
enable | 110 | 63 | 1
1515

16-
*Synthesis was performed using Quartus II 64-Bit Version 13.0.1 with default settings for Cyclone II.*
16+
*Synthesis was performed using Quartus II 64-Bit Version 13.0.1 with default settings for FPGA Altera Cyclone II.*

example/uart_loopback.vhd

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use IEEE.NUMERIC_STD.ALL;
2929

3030
entity UART_LOOPBACK is
3131
Generic (
32-
BAUD_RATE : integer := 9600;
32+
BAUD_RATE : integer := 115200;
3333
DATA_BITS : integer := 8;
3434
CLK_FREQ : integer := 50e6;
3535
INPUT_FIFO : boolean := True;
@@ -40,42 +40,62 @@ entity UART_LOOPBACK is
4040
RST_N : in std_logic; -- low active synchronous reset
4141
-- UART INTERFACE
4242
TX_UART : out std_logic;
43-
RX_UART : in std_logic
43+
RX_UART : in std_logic;
44+
-- DEBUG INTERFACE
45+
BUSY : out std_logic;
46+
FRAME_ERR : out std_logic;
47+
DATA_VLD : out std_logic
4448
);
4549
end UART_LOOPBACK;
4650

4751
architecture FULL of UART_LOOPBACK is
4852

49-
-- signals
50-
signal data : std_logic_vector(DATA_BITS-1 downto 0);
51-
signal valid : std_logic;
52-
signal reset : std_logic;
53+
signal data : std_logic_vector(DATA_BITS-1 downto 0);
54+
signal valid : std_logic;
55+
signal reset : std_logic;
56+
signal frame_error : std_logic;
57+
signal send : std_logic;
5358

5459
begin
5560

5661
reset <= not RST_N;
62+
send <= valid WHEN (frame_error = '0') ELSE '0';
5763

5864
uart_i: entity work.UART
5965
generic map (
60-
BAUD_RATE => BAUD_RATE, -- baud rate value, default is 9600
61-
DATA_BITS => DATA_BITS, -- legal values: 5,6,7,8, default is 8 dat bits
62-
CLK_FREQ => CLK_FREQ, -- set system clock frequency in Hz, default is 50 MHz
63-
INPUT_FIFO => INPUT_FIFO, -- enable input data FIFO, default is disable
64-
FIFO_DEPTH => FIFO_DEPTH -- set depth of input data FIFO, default is 256 items
66+
BAUD_RATE => BAUD_RATE,
67+
DATA_BITS => DATA_BITS,
68+
CLK_FREQ => CLK_FREQ,
69+
INPUT_FIFO => INPUT_FIFO,
70+
FIFO_DEPTH => FIFO_DEPTH
6571
)
6672
port map (
67-
CLK => CLK, -- system clock
68-
RST => reset, -- high active synchronous reset
73+
CLK => CLK,
74+
RST => reset,
6975
-- UART INTERFACE
70-
TX_UART => TX_UART,
71-
RX_UART => RX_UART,
76+
TX_UART => TX_UART,
77+
RX_UART => RX_UART,
7278
-- USER DATA OUTPUT INTERFACE
73-
DATA_OUT => data,
74-
DATA_VLD => valid, -- when DATA_VLD = 1, data on DATA_OUT are valid
79+
DATA_OUT => data,
80+
DATA_VLD => valid,
81+
FRAME_ERROR => frame_error,
7582
-- USER DATA INPUT INTERFACE
76-
DATA_IN => data,
77-
DATA_SEND => valid, -- when DATA_SEND = 1, data on DATA_IN will be transmit
78-
BUSY => open -- when BUSY = 1, you must not set DATA_SEND to 1
83+
DATA_IN => data,
84+
DATA_SEND => send,
85+
BUSY => BUSY
7986
);
8087

88+
frame_err_gen : process (CLK)
89+
begin
90+
if (rising_edge(CLK)) then
91+
if (reset = '1') then
92+
FRAME_ERR <= '0';
93+
elsif (valid = '1') then
94+
FRAME_ERR <= frame_error;
95+
end if;
96+
end if;
97+
end process;
98+
99+
DATA_VLD <= valid;
100+
81101
end FULL;
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
-- The MIT License (MIT)
2+
--
3+
-- Copyright (c) 2015 Jakub Cabal
4+
--
5+
-- Permission is hereby granted, free of charge, to any person obtaining a copy
6+
-- of this software and associated documentation files (the "Software"), to deal
7+
-- in the Software without restriction, including without limitation the rights
8+
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
-- copies of the Software, and to permit persons to whom the Software is
10+
-- furnished to do so, subject to the following conditions:
11+
--
12+
-- The above copyright notice and this permission notice shall be included in
13+
-- all copies or substantial portions of the Software.
14+
--
15+
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
-- SOFTWARE.
22+
--
23+
-- Website: https://github.com/jakubcabal/uart_for_fpga
24+
--------------------------------------------------------------------------------
25+
26+
library IEEE;
27+
use IEEE.STD_LOGIC_1164.ALL;
28+
use IEEE.NUMERIC_STD.ALL;
29+
30+
entity UART_LOOPBACK_TESTBENCH is
31+
end UART_LOOPBACK_TESTBENCH;
32+
33+
architecture FULL of UART_LOOPBACK_TESTBENCH is
34+
35+
signal CLK : std_logic := '0';
36+
signal RST_N : std_logic := '0';
37+
signal tx_uart : std_logic;
38+
signal rx_uart : std_logic := '1';
39+
signal data_vld : std_logic;
40+
signal frame_error : std_logic;
41+
signal busy : std_logic;
42+
43+
constant clk_period : time := 20 ns;
44+
constant uart_period : time := 8696 ns;
45+
constant data_value : std_logic_vector(7 downto 0) := "10100111";
46+
constant data_value2 : std_logic_vector(7 downto 0) := "00110110";
47+
48+
begin
49+
50+
utt: entity work.UART_LOOPBACK
51+
generic map (
52+
BAUD_RATE => 115200, -- baud rate value
53+
DATA_BITS => 8, -- legal values: 5,6,7,8
54+
CLK_FREQ => 50e6, -- set system clock frequency in Hz
55+
INPUT_FIFO => True, -- enable input data FIFO
56+
FIFO_DEPTH => 256 -- set depth of input data FIFO
57+
)
58+
port map (
59+
CLK => CLK,
60+
RST_N => RST_N,
61+
-- UART RS232 INTERFACE
62+
TX_UART => tx_uart,
63+
RX_UART => rx_uart,
64+
-- DEBUG INTERFACE
65+
BUSY => busy,
66+
FRAME_ERR => frame_error,
67+
DATA_VLD => data_vld
68+
);
69+
70+
clk_process : process
71+
begin
72+
CLK <= '0';
73+
wait for clk_period/2;
74+
CLK <= '1';
75+
wait for clk_period/2;
76+
end process;
77+
78+
test_rx_uart : process
79+
begin
80+
rx_uart <= '1';
81+
RST_N <= '0';
82+
wait for 100 ns;
83+
RST_N <= '1';
84+
85+
wait for uart_period;
86+
87+
rx_uart <= '0'; -- start bit
88+
wait for uart_period;
89+
90+
for i in 0 to 7 loop
91+
rx_uart <= data_value(i); -- data bits
92+
wait for uart_period;
93+
end loop;
94+
95+
rx_uart <= '1'; -- stop bit
96+
wait for uart_period;
97+
98+
rx_uart <= '0'; -- start bit
99+
wait for uart_period;
100+
101+
for i in 0 to 7 loop
102+
rx_uart <= data_value2(i); -- data bits
103+
wait for uart_period;
104+
end loop;
105+
106+
rx_uart <= '1'; -- stop bit
107+
wait for uart_period;
108+
109+
rx_uart <= '0'; -- start bit
110+
wait for uart_period;
111+
112+
for i in 0 to 7 loop
113+
rx_uart <= data_value(i); -- data bits
114+
wait for uart_period;
115+
end loop;
116+
117+
rx_uart <= '1'; -- stop bit
118+
wait for uart_period;
119+
120+
rx_uart <= '0'; -- start bit
121+
wait for uart_period;
122+
123+
for i in 0 to 7 loop
124+
rx_uart <= data_value2(i); -- data bits
125+
wait for uart_period;
126+
end loop;
127+
128+
rx_uart <= '1'; -- stop bit
129+
wait for uart_period;
130+
131+
wait;
132+
133+
end process;
134+
135+
end FULL;

0 commit comments

Comments
 (0)