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;
0 commit comments