Vous êtes sur la page 1sur 9

FIFOs (First In, First Out) are essentially memory buffers used to temporarily s

tore data until another process is ready to read it. As their name suggests the
first byte written into a FIFO will be the first one to appear on the output. Ty
pically FIFOs are used when you have two processes that operate and a different
rate. A common example is a high speed communications channel that writes a burs
t of data into a FIFO and then a slower communications channel that read the dat
a as need to send it at a slower rate.
The FIFO module below has two settings that can be configured to adjust the widt
h and depth of the FIFO. The DATA_WIDTH variable adjusts the size of the DataIn
and DataOut buses so that you can write different sizes of bytes if needed and t
he FIFO_DEPTH variable adjusts how big the internal memory of the FIFO is.
In order to write data into the FIFO first push the data onto the DataIn bus and
then strobe the WriteEn input high for one clock cycle. This will write whateve
r is on DataIn into the FIFOs internal memory. If writing in bulk the WriteEn si
gnal can be left high while changing the data on the DataIn bus each clock cycle
. When the Full flag goes high, this means that the FIFOs memory is full and will
not accept any more writes until data is read using the ReadEn input. If data i
s written while the Full flag is high it will be ignored.
For a standard FIFO when you write the first byte into the FIFO nothing happens
on the DataOut bus until the ReadEn signal is pulsed high for at-least one clock
cycle to. Once a byte has been written into the FIFO the Empty flag will go low
. To read the next byte from the FIFO strobe the ReadEn signal high for one cloc
k cycle and the next byte of data will be available to read on the next clock cy
cle. When the last byte of data is pushed onto the DataOut bus the Empty flag wi
ll go high.
VHDL Code
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
library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;

entity STD_FIFO is
Generic (
constant DATA_WIDTH : positive := 8;
constant FIFO_DEPTH : positive := 256
);
Port (
CLK : in STD_LOGIC; -- Clock
input
RST : in STD_LOGIC; -- Active
high reset
WriteEn : in STD_LOGIC; -- Write
enable signal
DataIn : in STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0); -- Data i
nput bus
ReadEn : in STD_LOGIC; -- Read e
nable signal
DataOut : out STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0); -- Data o
utput bus
Empty : out STD_LOGIC; -- FIFO e
mpty flag
Full : out STD_LOGIC -- FIFO f
ull flag
);
end STD_FIFO;

architecture Behavioral of STD_FIFO is

begin

-- Memory Pointer Process
fifo_proc : process (CLK)
type FIFO_Memory is array (0 to FIFO_DEPTH - 1) of STD_LOGIC_VECTOR (DAT
A_WIDTH - 1 downto 0);
variable Memory : FIFO_Memory;

variable Head : natural range 0 to FIFO_DEPTH - 1;
variable Tail : natural range 0 to FIFO_DEPTH - 1;

variable Looped : boolean;
begin
if rising_edge(CLK) then
if RST = '1' then
Head := 0;
Tail := 0;

Looped := false;

Full <= '0';
Empty <= '1';
else
if (ReadEn = '1') then
if ((Looped = true) or (Head /= Tail)) then
-- Update data output
DataOut <= Memory(Tail);

-- Update Tail pointer as needed
if (Tail = FIFO_DEPTH - 1) then
Tail := 0;

Looped := false;
else
Tail := Tail + 1;
end if;
end if;
end if;

if (WriteEn = '1') then
if ((Looped = false) or (Head /= Tail)) then
-- Write Data to Memory
Memory(Head) := DataIn;

-- Increment Head pointer as needed
if (Head = FIFO_DEPTH - 1) then
Head := 0;

Looped := true;
else
Head := Head + 1;
end if;
end if;
end if;

-- Update Empty and Full flags
if (Head = Tail) then
if Looped then
Full <= '1';
else
Empty <= '1';
end if;
else
Empty <= '0';
Full <= '0';
end if;
end if;
end if;
end process;

end Behavioral;
Test bench
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
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;

ENTITY TB_STD_FIFO IS
END TB_STD_FIFO;

ARCHITECTURE behavior OF TB_STD_FIFO IS

-- Component Declaration for the Unit Under Test (UUT)
component STD_FIFO
Generic (
constant DATA_WIDTH : positive := 8;
constant FIFO_DEPTH : positive := 16
);
port (
CLK : in std_logic;
RST : in std_logic;
DataIn : in std_logic_vector(7 downto 0);
WriteEn : in std_logic;
ReadEn : in std_logic;
DataOut : out std_logic_vector(7 downto 0);
Full : out std_logic;
Empty : out std_logic
);
end component;

--Inputs
signal CLK : std_logic := '0';
signal RST : std_logic := '0';
signal DataIn : std_logic_vector(7 downto 0) := (others => '0');
signal ReadEn : std_logic := '0';
signal WriteEn : std_logic := '0';

--Outputs
signal DataOut : std_logic_vector(7 downto 0);
signal Empty : std_logic;
signal Full : std_logic;

-- Clock period definitions
constant CLK_period : time := 10 ns;

BEGIN

-- Instantiate the Unit Under Test (UUT)
uut: STD_FIFO
PORT MAP (
CLK => CLK,
RST => RST,
DataIn => DataIn,
WriteEn => WriteEn,
ReadEn => ReadEn,
DataOut => DataOut,
Full => Full,
Empty => Empty
);

-- Clock process definitions
CLK_process :process
begin
CLK <= '0';
wait for CLK_period/2;
CLK <= '1';
wait for CLK_period/2;
end process;

-- Reset process
rst_proc : process
begin
wait for CLK_period * 5;

RST <= '1';

wait for CLK_period * 5;

RST <= '0';

wait;
end process;

-- Write process
wr_proc : process
variable counter : unsigned (7 downto 0) := (others => '0');
begin
wait for CLK_period * 20;

for i in 1 to 32 loop
counter := counter + 1;

DataIn <= std_logic_vector(counter);

wait for CLK_period * 1;

WriteEn <= '1';

wait for CLK_period * 1;

WriteEn <= '0';
end loop;

wait for clk_period * 20;

for i in 1 to 32 loop
counter := counter + 1;

DataIn <= std_logic_vector(counter);

wait for CLK_period * 1;

WriteEn <= '1';

wait for CLK_period * 1;

WriteEn <= '0';
end loop;

wait;
end process;

-- Read process
rd_proc : process
begin
wait for CLK_period * 20;

wait for CLK_period * 40;

ReadEn <= '1';

wait for CLK_period * 60;

ReadEn <= '0';

wait for CLK_period * 30;

ReadEn <= '1';

wait;
end process;

END;

Vous aimerez peut-être aussi