OpenCores
URL https://opencores.org/ocsvn/uart_fpga_slow_control_migrated/uart_fpga_slow_control_migrated/trunk

Subversion Repositories uart_fpga_slow_control_migrated

[/] [uart_fpga_slow_control/] [trunk/] [code/] [gh_fifo_async16_sr.vhd] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 aborga
---------------------------------------------------------------------
2
--      Filename:       gh_fifo_async_sr.vhd
3
--
4
--                      
5
--      Description:
6
--              an Asynchronous FIFO, 
7
--                 using "Style #2" gray code address compare
8
--              
9
--      Copyright (c) 2006, 2008 by George Huber 
10
--              an OpenCores.org Project
11
--              free to use, but see documentation for conditions                                                                
12
--
13
--      Revision        History:
14
--      Revision        Date            Author          Comment
15
--      --------        ----------      ---------       -----------
16
--      1.0             12/23/06        h lefevre       Initial revision
17
--      1.1             09/20/08        hlefevre        add simulation init
18
--                                                        (to '0') to ram data 
19
--      
20
--------------------------------------------------------
21
 
22
library IEEE;
23
use IEEE.std_logic_1164.all;
24
use IEEE.std_logic_unsigned.all;
25
USE ieee.std_logic_arith.all;
26
 
27
entity gh_fifo_async16_sr is
28
        GENERIC (add_width: INTEGER :=3; -- min value is 2 (4 memory locations)
29
                 data_width: INTEGER :=8 ); -- size of data bus
30
        port (
31
                clk_WR : in STD_LOGIC; -- write clock
32
                clk_RD : in STD_LOGIC; -- read clock
33
                rst    : in STD_LOGIC; -- resets counters
34
                srst   : in STD_LOGIC:='0'; -- resets counters (sync with clk_WR)
35
                WR     : in STD_LOGIC; -- write control 
36
                RD     : in STD_LOGIC; -- read control
37
                D      : in STD_LOGIC_VECTOR (data_width-1 downto 0);
38
                Q      : out STD_LOGIC_VECTOR (data_width-1 downto 0);
39
                empty  : out STD_LOGIC;
40
                full   : out STD_LOGIC);
41
end entity;
42
 
43
architecture a of gh_fifo_async16_sr is
44
 
45
        type ram_mem_type is array (2**add_width-1 downto 0)
46
                of STD_LOGIC_VECTOR (data_width-1 downto 0);
47
        signal ram_mem : ram_mem_type := (others => (others => '0'));
48
        signal iempty      : STD_LOGIC;
49
        signal ifull       : STD_LOGIC;
50
        signal add_WR_CE   : std_logic;
51
        signal add_WR      : std_logic_vector(add_width downto 0); -- add_width -1 bits are used to address MEM
52
        signal add_WR_GC   : std_logic_vector(add_width downto 0); -- add_width bits are used to compare
53
        signal n_add_WR    : std_logic_vector(add_width downto 0); --   for empty, full flags
54
        signal add_WR_RS   : std_logic_vector(add_width downto 0); -- synced to read clk
55
        signal add_RD_CE   : std_logic;
56
        signal add_RD      : std_logic_vector(add_width downto 0);
57
        signal add_RD_GC   : std_logic_vector(add_width downto 0);
58
        signal add_RD_GCwc : std_logic_vector(add_width downto 0);
59
        signal n_add_RD    : std_logic_vector(add_width downto 0);
60
        signal add_RD_WS   : std_logic_vector(add_width downto 0); -- synced to write clk
61
        signal srst_w      : STD_LOGIC;
62
        signal isrst_w     : STD_LOGIC;
63
        signal srst_r      : STD_LOGIC;
64
        signal isrst_r     : STD_LOGIC;
65
 
66
begin
67
 
68
--------------------------------------------
69
------- memory -----------------------------
70
--------------------------------------------
71
 
72
process (clk_WR)
73
begin
74
        if (rising_edge(clk_WR)) then
75
                if ((WR = '1') and (ifull = '0')) then
76
                        ram_mem(CONV_INTEGER(add_WR(add_width-1 downto 0))) <= D;
77
                end if;
78
        end if;
79
end process;
80
 
81
        Q <= ram_mem(CONV_INTEGER(add_RD(add_width-1 downto 0)));
82
 
83
-----------------------------------------
84
----- Write address counter -------------
85
-----------------------------------------
86
 
87
        add_WR_CE <= '0' when (ifull = '1') else
88
                     '0' when (WR = '0') else
89
                     '1';
90
 
91
        n_add_WR <= add_WR + "01";
92
 
93
process (clk_WR,rst)
94
begin
95
        if (rst = '1') then
96
                add_WR <= (others => '0');
97
                add_RD_WS(add_width downto add_width-1) <= "11";
98
                add_RD_WS(add_width-2 downto 0) <= (others => '0');
99
                add_WR_GC <= (others => '0');
100
        elsif (rising_edge(clk_WR)) then
101
                add_RD_WS <= add_RD_GCwc;
102
                if (srst_w = '1') then
103
                        add_WR <= (others => '0');
104
                        add_WR_GC <= (others => '0');
105
                elsif (add_WR_CE = '1') then
106
                        add_WR <= n_add_WR;
107
                        for i in 0 to add_width-1 loop
108
                                add_WR_GC(i) <= n_add_WR(i) xor n_add_WR(i+1);
109
                        end loop;
110
                        add_WR_GC(add_width) <= n_add_WR(add_width);
111
                else
112
                        add_WR <= add_WR;
113
                        add_WR_GC <= add_WR_GC;
114
                end if;
115
        end if;
116
end process;
117
 
118
        full <= ifull;
119
 
120
        ifull <= '0' when (iempty = '1') else -- just in case add_RD_WS is reset to all zero's
121
                 '0' when (add_RD_WS /= add_WR_GC) else ---- instend of "11 zero's" 
122
                 '1';
123
 
124
-----------------------------------------
125
----- Read address counter --------------
126
-----------------------------------------
127
 
128
 
129
        add_RD_CE <= '0' when (iempty = '1') else
130
                     '0' when (RD = '0') else
131
                     '1';
132
 
133
        n_add_RD <= add_RD + "01";
134
 
135
process (clk_RD,rst)
136
begin
137
        if (rst = '1') then
138
                add_RD <= (others => '0');
139
                add_WR_RS <= (others => '0');
140
                add_RD_GC <= (others => '0');
141
                add_RD_GCwc(add_width downto add_width-1) <= "11";
142
                add_RD_GCwc(add_width-2 downto 0) <= (others => '0');
143
        elsif (rising_edge(clk_RD)) then
144
                add_WR_RS <= add_WR_GC;
145
                if (srst_r = '1') then
146
                        add_RD <= (others => '0');
147
                        add_RD_GC <= (others => '0');
148
                        add_RD_GCwc(add_width downto add_width-1) <= "11";
149
                        add_RD_GCwc(add_width-2 downto 0) <= (others => '0');
150
                elsif (add_RD_CE = '1') then
151
                        add_RD <= n_add_RD;
152
                        for j in 0 to add_width-1 loop
153
                                add_RD_GC(j) <= n_add_RD(j) xor n_add_RD(j+1);
154
                        end loop;
155
                        add_RD_GC(add_width) <= n_add_RD(add_width);
156
                        for k in 0 to add_width-2 loop
157
                                add_RD_GCwc(k) <= n_add_RD(k) xor n_add_RD(k+1);
158
                        end loop;
159
                        add_RD_GCwc(add_width-1) <= n_add_RD(add_width-1) xor (not n_add_RD(add_width));
160
                        add_RD_GCwc(add_width) <= (not n_add_RD(add_width));
161
                else
162
                        add_RD <= add_RD;
163
                        add_RD_GC <= add_RD_GC;
164
                        add_RD_GCwc <= add_RD_GCwc;
165
                end if;
166
        end if;
167
end process;
168
 
169
        empty <= iempty;
170
 
171
        iempty <= '1' when (add_WR_RS = add_RD_GC) else
172
                  '0';
173
 
174
----------------------------------
175
--- sync rest stuff --------------
176
--- srst is sync with clk_WR -----
177
--- srst_r is sync with clk_RD ---
178
----------------------------------
179
 
180
process (clk_WR,rst)
181
begin
182
        if (rst = '1') then
183
                srst_w <= '0';
184
                isrst_r <= '0';
185
        elsif (rising_edge(clk_WR)) then
186
                isrst_r <= srst_r;
187
                if (srst = '1') then
188
                        srst_w <= '1';
189
                elsif (isrst_r = '1') then
190
                        srst_w <= '0';
191
                end if;
192
        end if;
193
end process;
194
 
195
process (clk_RD,rst)
196
begin
197
        if (rst = '1') then
198
                srst_r <= '0';
199
                isrst_w <= '0';
200
        elsif (rising_edge(clk_RD)) then
201
                isrst_w <= srst_w;
202
                if (isrst_w = '1') then
203
                        srst_r <= '1';
204
                else
205
                        srst_r <= '0';
206
                end if;
207
        end if;
208
end process;
209
 
210
end architecture;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.