Skip to content

Commit 06ba8cd

Browse files
committed
UART: Add input data FIFO
1 parent 65078bc commit 06ba8cd

File tree

4 files changed

+339
-12
lines changed

4 files changed

+339
-12
lines changed

source/comp/uart_fifo.vhd

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
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+
use IEEE.MATH_REAL.ALL;
30+
31+
entity UART_FIFO is
32+
Generic (
33+
DATA_WIDTH : integer := 8;
34+
FIFO_DEPTH : integer := 256
35+
);
36+
Port (
37+
CLK : in std_logic; -- system clock
38+
RST : in std_logic; -- high active synchronous reset
39+
-- FIFO WRITE INTERFACE
40+
DATA_IN : in std_logic_vector(DATA_WIDTH-1 downto 0);
41+
WR_EN : in std_logic;
42+
FULL : out std_logic;
43+
-- FIFO READ INTERFACE
44+
DATA_OUT : out std_logic_vector(DATA_WIDTH-1 downto 0);
45+
DATA_VLD : out std_logic;
46+
RD_EN : in std_logic;
47+
EMPTY : out std_logic
48+
);
49+
end UART_FIFO;
50+
51+
architecture FULL of UART_FIFO is
52+
53+
constant addr_width : integer := integer(ceil(log2(real(FIFO_DEPTH))));
54+
55+
signal wr_addr : unsigned(addr_width-1 downto 0);
56+
signal wr_ready : std_logic;
57+
signal rd_addr : unsigned(addr_width-1 downto 0);
58+
signal rd_ready : std_logic;
59+
signal full_sig : std_logic;
60+
signal empty_sig : std_logic;
61+
62+
type bram_type is array(FIFO_DEPTH-1 downto 0) of std_logic_vector(DATA_WIDTH-1 downto 0);
63+
signal bram : bram_type := (others => (others => '0'));
64+
65+
begin
66+
67+
wr_ready <= WR_EN AND NOT full_sig AND NOT RST;
68+
rd_ready <= RD_EN AND NOT empty_sig AND NOT RST;
69+
70+
FULL <= full_sig;
71+
EMPTY <= empty_sig;
72+
73+
-- -------------------------------------------------------------------------
74+
-- BRAM AND DATA VALID FLAG GENERATOR
75+
-- -------------------------------------------------------------------------
76+
77+
bram_mem : process (CLK)
78+
begin
79+
if (rising_edge(CLK)) then
80+
if (wr_ready = '1') then
81+
bram(to_integer(wr_addr)) <= DATA_IN;
82+
end if;
83+
DATA_OUT <= bram(to_integer(rd_addr));
84+
end if;
85+
end process;
86+
87+
data_vld_flag_gen : process (CLK)
88+
begin
89+
if (rising_edge(CLK)) then
90+
DATA_VLD <= rd_ready;
91+
end if;
92+
end process;
93+
94+
-- -------------------------------------------------------------------------
95+
-- FIFO WRITE ADDRESS COUNTER
96+
-- -------------------------------------------------------------------------
97+
98+
wr_addr_cnt : process (CLK)
99+
begin
100+
if (rising_edge(CLK)) then
101+
if (RST = '1') then
102+
wr_addr <= (others => '0');
103+
elsif (wr_ready = '1') then
104+
wr_addr <= wr_addr + 1;
105+
end if;
106+
end if;
107+
end process;
108+
109+
-- -------------------------------------------------------------------------
110+
-- FIFO READ ADDRESS COUNTER
111+
-- -------------------------------------------------------------------------
112+
113+
rd_addr_cnt : process (CLK)
114+
begin
115+
if (rising_edge(CLK)) then
116+
if (RST = '1') then
117+
rd_addr <= (others => '0');
118+
elsif (rd_ready = '1') then
119+
rd_addr <= rd_addr + 1;
120+
end if;
121+
end if;
122+
end process;
123+
124+
-- -------------------------------------------------------------------------
125+
-- FULL FLAG GENERATOR
126+
-- -------------------------------------------------------------------------
127+
128+
full_flag_gen : process (rd_addr, wr_addr)
129+
begin
130+
if (rd_addr = (wr_addr+1)) then
131+
full_sig <= '1';
132+
else
133+
full_sig <= '0';
134+
end if;
135+
end process;
136+
137+
-- -------------------------------------------------------------------------
138+
-- EMPTY FLAG GENERATOR
139+
-- -------------------------------------------------------------------------
140+
141+
empty_flag_gen : process (rd_addr, wr_addr)
142+
begin
143+
if (rd_addr = wr_addr) then
144+
empty_sig <= '1';
145+
else
146+
empty_sig <= '0';
147+
end if;
148+
end process;
149+
150+
end FULL;
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
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_FIFO_TESTBENCH is
31+
end UART_FIFO_TESTBENCH;
32+
33+
architecture FULL of UART_FIFO_TESTBENCH is
34+
35+
signal CLK : std_logic := '0';
36+
signal RST : std_logic := '0';
37+
signal data_in : std_logic_vector(7 downto 0);
38+
signal wr_en : std_logic;
39+
signal data_out : std_logic_vector(7 downto 0);
40+
signal data_vld : std_logic;
41+
signal rd_en : std_logic;
42+
signal full : std_logic;
43+
signal empty : std_logic;
44+
45+
constant clk_period : time := 20 ns;
46+
47+
begin
48+
49+
utt: entity work.UART_FIFO
50+
generic map (
51+
DATA_WIDTH => 8,
52+
FIFO_DEPTH => 32
53+
)
54+
port map (
55+
CLK => CLK,
56+
RST => RST,
57+
-- FIFO WRITE INTERFACE
58+
DATA_IN => data_in,
59+
WR_EN => wr_en,
60+
FULL => full,
61+
-- FIFO READ INTERFACE
62+
DATA_OUT => data_out,
63+
DATA_VLD => data_vld,
64+
RD_EN => rd_en,
65+
EMPTY => empty
66+
);
67+
68+
clk_process : process
69+
begin
70+
CLK <= '0';
71+
wait for clk_period/2;
72+
CLK <= '1';
73+
wait for clk_period/2;
74+
end process;
75+
76+
rst_process : process
77+
begin
78+
RST <= '1';
79+
wait for 40 ns;
80+
RST <= '0';
81+
wait;
82+
end process;
83+
84+
read_test : process
85+
begin
86+
rd_en <= '0';
87+
88+
wait until (rising_edge(CLK) and RST='0' and empty='0');
89+
for i in 1 to 20 loop
90+
rd_en <= '1';
91+
wait until (rising_edge(CLK) and RST='0' and empty='0');
92+
end loop;
93+
rd_en <= '0';
94+
95+
wait for 800 ns;
96+
97+
wait until (rising_edge(CLK) and RST='0' and empty='0');
98+
for i in 21 to 70 loop
99+
rd_en <= '1';
100+
wait until (rising_edge(CLK) and RST='0' and empty='0');
101+
end loop;
102+
rd_en <= '0';
103+
104+
wait;
105+
end process;
106+
107+
write_test : process
108+
begin
109+
data_in <= (others => '0');
110+
wr_en <= '0';
111+
112+
wait until (rising_edge(CLK) and RST='0' and full='0');
113+
wr_en <= '1';
114+
for i in 1 to 11 loop
115+
data_in <= std_logic_vector(to_unsigned(i, data_in'length));
116+
wait until (rising_edge(CLK) and RST='0' and full='0');
117+
end loop;
118+
wr_en <= '0';
119+
120+
wait for 200 ns;
121+
122+
wait until (rising_edge(CLK) and RST='0' and full='0');
123+
wr_en <= '1';
124+
for i in 12 to 70 loop
125+
data_in <= std_logic_vector(to_unsigned(i, data_in'length));
126+
wait until (rising_edge(CLK) and RST='0' and full='0');
127+
end loop;
128+
wr_en <= '0';
129+
130+
wait;
131+
end process;
132+
133+
end FULL;

0 commit comments

Comments
 (0)