-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathsync_fifo.vhd
134 lines (113 loc) · 3.34 KB
/
sync_fifo.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
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 16:30:48 08/03/2012
-- Design Name:
-- Module Name: sync_fifo - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.all;
library work;
use work.utils.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity sync_fifo is
generic (
data_width : integer := 8;
data_depth : integer := 1024
);
port (
clk : in std_logic;
reset : in std_logic;
ce : in std_logic;
din : in std_logic_vector(data_width-1 downto 0);
wr : in std_logic;
ff : out std_logic;
dout : out std_logic_vector(data_width-1 downto 0);
rd : in std_logic;
ef : out std_logic
);
end sync_fifo;
architecture RTL of sync_fifo is
-- Type definitions
type ram_type is array (0 to data_depth-1) of std_logic_vector(data_width-1 downto 0);
-- Mem type declaration
signal ram : ram_type;
-- Mem attributes
attribute ram_style : string;
--attribute ram_style of ram : signal is "distributed";
attribute ram_style of ram : signal is "block";
-- Registers
signal rd_ptr : integer range 0 to data_depth-1;
signal wr_ptr : integer range 0 to data_depth-1;
-- Signals
signal ff_d : std_logic;
signal ef_d : std_logic;
begin
dout <= ram(rd_ptr);
ff <= ff_d;
ef <= ef_d;
process(clk)
begin
if rising_edge(clk) then
if reset = '1' then
wr_ptr <= 0;
rd_ptr <= 0;
ff_d <= '0';
ef_d <= '1';
elsif ce = '1' then
-- Read, full, Write is don't care
if rd = '1' and ff_d = '1' and ef_d = '0' then
ff_d <= '0';
rd_ptr <= INC_PTR(rd_ptr, data_depth);
ef_d <= CHK_EF(rd_ptr, wr_ptr, data_depth);
-- Write, empty, Read is don't care
elsif wr = '1' and ff_d = '0' and ef_d = '1' then
ram(wr_ptr) <= din;
ef_d <= '0';
wr_ptr <= INC_PTR(wr_ptr, data_depth);
ff_d <= CHK_FF(rd_ptr, wr_ptr, data_depth);
-- Read, not full, not empty
elsif rd = '1' and wr = '0' and ff_d = '0' and ef_d = '0' then
rd_ptr <= INC_PTR(rd_ptr, data_depth);
ef_d <= CHK_EF(rd_ptr, wr_ptr, data_depth);
-- Write, not full, not empty
elsif rd = '0' and wr = '1' and ff_d = '0' and ef_d = '0' then
ram(wr_ptr) <= din;
wr_ptr <= INC_PTR(wr_ptr, data_depth);
ff_d <= CHK_FF(rd_ptr, wr_ptr, data_depth);
-- Write and Read, not full, not empty
elsif rd = '1' and wr = '1' and ff_d = '0' and ef_d = '0' then
ram(wr_ptr) <= din;
wr_ptr <= INC_PTR(wr_ptr, data_depth);
rd_ptr <= INC_PTR(rd_ptr, data_depth);
-- Full and empty at the same time, Read and Write is don't care
elsif ff_d = '1' and ef_d = '1'then
-- error if we are here, reset the fifo
wr_ptr <= 0;
rd_ptr <= 0;
ff_d <= '0';
ef_d <= '1';
end if;
end if;
end if;
end process;
end RTL;