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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.74/] [rtl/] [vlib/] [memlib/] [fifo_2c_dram2.vhd] - Blame information for rev 40

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 36 wfjm
-- $Id: fifo_2c_dram2.vhd 752 2016-03-27 17:57:18Z mueller $
2 16 wfjm
--
3 36 wfjm
-- Copyright 2016- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4 16 wfjm
--
5
-- This program is free software; you may redistribute and/or modify it under
6
-- the terms of the GNU General Public License as published by the Free
7
-- Software Foundation, either version 2, or at your option any later version.
8
--
9
-- This program is distributed in the hope that it will be useful, but
10
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
-- for complete details.
13
--
14
------------------------------------------------------------------------------
15 36 wfjm
-- Module Name:    fifo_2c_dram2 - syn
16 16 wfjm
-- Description:    FIFO, two clock domain, distributed RAM based, with
17
--                 enable/busy/valid/hold interface.
18
--
19
-- Dependencies:   ram_1swar_1ar_gen
20
--                 genlib/gray_cnt_n
21
--                 genlib/gray2bin_gen
22
--
23
-- Test bench:     tb/tb_fifo_2c_dram
24 36 wfjm
-- Target Devices: generic
25
-- Tool versions:  viv 2015.4; ghdl 0.33
26 16 wfjm
-- Revision History: 
27
-- Date         Rev Version  Comment
28 36 wfjm
-- 2016-03-24   751   1.0    Initial version (derived from fifo_2c_dram, is
29
--                             exactly same logic, re-written to allow proper
30
--                             usage of vivado constraints)
31 16 wfjm
------------------------------------------------------------------------------
32
 
33
library ieee;
34
use ieee.std_logic_1164.all;
35
use ieee.numeric_std.all;
36
 
37
use work.slvtypes.all;
38
use work.genlib.all;
39
use work.memlib.all;
40
 
41 36 wfjm
entity fifo_2c_dram2 is                 -- fifo, 2 clock, dram based (v2)
42 16 wfjm
  generic (
43
    AWIDTH : positive :=  5;            -- address width (sets size)
44
    DWIDTH : positive := 16);           -- data width
45
  port (
46
    CLKW : in slbit;                    -- clock (write side)
47
    CLKR : in slbit;                    -- clock (read side)
48
    RESETW : in slbit;                  -- W|reset from write side
49
    RESETR : in slbit;                  -- R|reset from read side
50
    DI : in slv(DWIDTH-1 downto 0);     -- W|input data
51
    ENA : in slbit;                     -- W|write enable
52
    BUSY : out slbit;                   -- W|write port hold    
53
    DO : out slv(DWIDTH-1 downto 0);    -- R|output data
54
    VAL : out slbit;                    -- R|read valid
55
    HOLD : in slbit;                    -- R|read hold
56
    SIZEW : out slv(AWIDTH-1 downto 0); -- W|number slots to write
57
    SIZER : out slv(AWIDTH-1 downto 0)  -- R|number slots to read 
58
  );
59 36 wfjm
end fifo_2c_dram2;
60 16 wfjm
 
61
 
62 36 wfjm
architecture syn of fifo_2c_dram2 is
63 16 wfjm
 
64 36 wfjm
  subtype a_range is integer range AWIDTH-1 downto  0;   -- addr value regs
65 16 wfjm
 
66 36 wfjm
  signal RW_RADDR_S0 :  slv(a_range) := (others=>'0'); -- read addr: CLKR->CLKW
67
  signal RW_RADDR_S1 :  slv(a_range) := (others=>'0'); -- read addr: CLKW->CLKW
68
  signal RW_SIZEW :     slv(a_range) := (others=>'0'); -- slots to write
69
  signal RW_BUSY :      slbit        := '0';           -- busy flag
70
  signal RW_RSTW :      slbit        := '0';           -- resetw active
71
  signal RW_RSTW_E_S0 : slbit        := '0';           -- rstw-echo: CLKR->CLKW
72
  signal RW_RSTW_E_S1 : slbit        := '0';           -- rstw-echo: CLKW->CLKW
73
  signal RW_RSTR_S0 :   slbit        := '0';           -- resetr: CLKR->CLKW
74
  signal RW_RSTR_S1 :   slbit        := '0';           -- resetr: CLKW->CLKW
75
 
76
  signal NW_SIZEW :     slv(a_range) := (others=>'0'); -- slots to write
77
  signal NW_BUSY :      slbit        := '0';           -- busy flag
78
  signal NW_RSTW :      slbit        := '0';           -- resetw active
79 16 wfjm
 
80 36 wfjm
  signal RR_WADDR_S0 :  slv(a_range) := (others=>'0'); -- write addr: CLKW->CLKR
81
  signal RR_WADDR_S1 :  slv(a_range) := (others=>'0'); -- write addr: CLKR->CLKR
82
  signal RR_SIZER :     slv(a_range) := (others=>'0'); -- slots to read
83
  signal RR_VAL:        slbit        := '0';           -- valid flag
84
  signal RR_RSTR :      slbit        := '0';           -- resetr active
85
  signal RR_RSTR_E_S0 : slbit        := '0';           -- rstr-echo: CLKW->CLKR
86
  signal RR_RSTR_E_S1 : slbit        := '0';           -- rstr-echo: CLKR->CLKR
87
  signal RR_RSTW_S0 :   slbit        := '0';           -- resetw: CLKW->CLKR
88
  signal RR_RSTW_S1 :   slbit        := '0';           -- resetw: CLKR->CLKR
89 16 wfjm
 
90 36 wfjm
  signal NR_SIZER :    slv(a_range) := (others=>'0'); -- slots to read
91
  signal NR_VAL:       slbit        := '0';           -- valid flag
92
  signal NR_RSTR :     slbit        := '0';           -- resetr active
93 16 wfjm
 
94
  signal WADDR : slv(AWIDTH-1 downto 0) := (others=>'0');
95
  signal RADDR : slv(AWIDTH-1 downto 0) := (others=>'0');
96 36 wfjm
  signal WADDR_BIN_W : slv(AWIDTH-1 downto 0) := (others=>'0');
97
  signal RADDR_BIN_R : slv(AWIDTH-1 downto 0) := (others=>'0');
98
  signal WADDR_BIN_R : slv(AWIDTH-1 downto 0) := (others=>'0');
99
  signal RADDR_BIN_W : slv(AWIDTH-1 downto 0) := (others=>'0');
100 16 wfjm
 
101
  signal GCW_RST : slbit := '0';
102 36 wfjm
  signal GCW_CE  : slbit := '0';
103 16 wfjm
  signal GCR_RST : slbit := '0';
104 36 wfjm
  signal GCR_CE  : slbit := '0';
105 16 wfjm
 
106 36 wfjm
  attribute ASYNC_REG: string;
107
 
108
  attribute ASYNC_REG of RW_RADDR_S0   : signal is "true";
109
  attribute ASYNC_REG of RW_RADDR_S1   : signal is "true";
110
  attribute ASYNC_REG of RW_RSTW_E_S0  : signal is "true";
111
  attribute ASYNC_REG of RW_RSTW_E_S1  : signal is "true";
112
  attribute ASYNC_REG of RW_RSTR_S0    : signal is "true";
113
  attribute ASYNC_REG of RW_RSTR_S1    : signal is "true";
114
 
115
  attribute ASYNC_REG of RR_WADDR_S0   : signal is "true";
116
  attribute ASYNC_REG of RR_WADDR_S1   : signal is "true";
117
  attribute ASYNC_REG of RR_RSTR_E_S0  : signal is "true";
118
  attribute ASYNC_REG of RR_RSTR_E_S1  : signal is "true";
119
  attribute ASYNC_REG of RR_RSTW_S0    : signal is "true";
120
  attribute ASYNC_REG of RR_RSTW_S1    : signal is "true";
121
 
122 16 wfjm
begin
123
 
124
  RAM : ram_1swar_1ar_gen               -- dual ported memory
125
    generic map (
126
      AWIDTH => AWIDTH,
127
      DWIDTH => DWIDTH)
128
    port map (
129
      CLK   => CLKW,
130
      WE    => GCW_CE,
131
      ADDRA => WADDR,
132
      ADDRB => RADDR,
133
      DI    => DI,
134
      DOA   => open,
135
      DOB   => DO
136
    );
137
 
138
  GCW : gray_cnt_gen                    -- gray counter for write address
139
    generic map (
140
      DWIDTH => AWIDTH)
141
    port map (
142
      CLK   => CLKW,
143
      RESET => GCW_RST,
144
      CE    => GCW_CE,
145
      DATA  => WADDR
146
    );
147
 
148
  GCR : gray_cnt_gen                    -- gray counter for read address
149
    generic map (
150
      DWIDTH => AWIDTH)
151
    port map (
152
      CLK   => CLKR,
153
      RESET => GCR_RST,
154
      CE    => GCR_CE,
155
      DATA  => RADDR
156
    );
157
 
158
  G2B_WW : gray2bin_gen                 -- gray->bin for waddr on write side
159
    generic map (DWIDTH => AWIDTH)
160 36 wfjm
    port map (DI => WADDR, DO => WADDR_BIN_W);
161 16 wfjm
  G2B_WR : gray2bin_gen                 -- gray->bin for waddr on read  side
162
    generic map (DWIDTH => AWIDTH)
163 36 wfjm
    port map (DI => RR_WADDR_S1, DO => WADDR_BIN_R);
164
  G2B_RR : gray2bin_gen                 -- gray->bin for raddr on read  side
165
    generic map (DWIDTH => AWIDTH)
166
    port map (DI => RADDR, DO => RADDR_BIN_R);
167 16 wfjm
  G2B_RW : gray2bin_gen                 -- gray->bin for raddr on write side
168
    generic map (DWIDTH => AWIDTH)
169 36 wfjm
    port map (DI => RW_RADDR_S1, DO => RADDR_BIN_W);
170
 
171
  --
172
  -- write side --------------------------------------------------------------
173
  --
174 16 wfjm
  proc_regw: process (CLKW)
175
  begin
176
    if rising_edge(CLKW) then
177 36 wfjm
      RW_RADDR_S0  <= RADDR;            -- sync 0: CLKR->CLKW
178
      RW_RADDR_S1  <= RW_RADDR_S0;      -- sync 1: CLKW
179
      RW_SIZEW     <= NW_SIZEW;
180
      RW_BUSY      <= NW_BUSY;
181
      RW_RSTW      <= NW_RSTW;
182
      RW_RSTW_E_S0 <= RR_RSTW_S1;       -- sync 0: CLKR->CLKW
183
      RW_RSTW_E_S1 <= RW_RSTW_E_S0;     -- sync 1: CLKW
184
      RW_RSTR_S0   <= RR_RSTR;          -- sync 0: CLKR->CLKW
185
      RW_RSTR_S1   <= RW_RSTR_S0;       -- sync 1: CLKW
186
  end if;
187 16 wfjm
  end process proc_regw;
188
 
189 36 wfjm
  proc_nextw: process (RW_BUSY, RW_SIZEW, RW_RSTW, RW_RSTW_E_S1, RW_RSTR_S1,
190
                       ENA, RESETW, RADDR_BIN_W, WADDR_BIN_W)
191 16 wfjm
 
192
    variable ibusy : slbit := '0';
193 36 wfjm
    variable irstw : slbit := '0';
194 16 wfjm
    variable igcw_ce  : slbit := '0';
195
    variable igcw_rst : slbit := '0';
196 36 wfjm
    variable isizew : slv(a_range) := (others=>'0');
197 16 wfjm
  begin
198
 
199 36 wfjm
    isizew := slv(unsigned(RADDR_BIN_W) + unsigned(not WADDR_BIN_W));
200 16 wfjm
    ibusy  := '0';
201
    igcw_ce  := '0';
202
    igcw_rst := '0';
203
 
204
    if unsigned(isizew) = 0 then        -- if no free slots
205
      ibusy := '1';                       -- next cycle busy=1
206
    end if;
207
 
208 36 wfjm
    if ENA='1' and RW_BUSY='0' then     -- if ena=1 and this cycle busy=0
209 16 wfjm
      igcw_ce := '1';                     -- write this value
210
      if unsigned(isizew) = 1 then        -- if this last free slot
211
        ibusy := '1';                       -- next cycle busy=1
212
      end if;
213
    end if;
214 36 wfjm
 
215
    irstw := RW_RSTW;
216 16 wfjm
    if RESETW = '1' then                -- reset(write side) request
217 36 wfjm
      irstw := '1';                       -- set RSTW flag
218
    elsif RW_RSTW_E_S1 = '1' then       -- request gone and return seen
219
      irstw := '0';                       -- clear RSTW flag
220 16 wfjm
    end if;
221
 
222 36 wfjm
    if RW_RSTW='1' and RW_RSTW_E_S1='1' then -- RSTW seen on write and read side
223 16 wfjm
      igcw_rst := '1';                     -- clear write address counter
224
    end if;
225 36 wfjm
    if RW_RSTR_S1 = '1' then            -- RSTR active
226 16 wfjm
      igcw_rst := '1';                    -- clear write address counter
227
    end if;
228
 
229 36 wfjm
    if RESETW='1' or RW_RSTW='1' or RW_RSTW_E_S1='1' or RW_RSTR_S1='1'
230 16 wfjm
    then             -- RESETW or RESETR active
231
      ibusy  := '1';                      -- signal write side busy
232
      isizew := (others=>'1');
233
    end if;
234
 
235 36 wfjm
    NW_BUSY  <= ibusy;
236
    NW_RSTW  <= irstw;
237
    NW_SIZEW <= isizew;
238 16 wfjm
 
239
    GCW_CE  <= igcw_ce;
240
    GCW_RST <= igcw_rst;
241 36 wfjm
    BUSY    <= RW_BUSY;
242
    SIZEW   <= RW_SIZEW;
243 16 wfjm
 
244
  end process proc_nextw;
245
 
246 36 wfjm
  --
247
  -- read side ---------------------------------------------------------------
248
  --
249 16 wfjm
  proc_regr: process (CLKR)
250
  begin
251
    if rising_edge(CLKR) then
252 36 wfjm
      RR_WADDR_S0  <= WADDR;            -- sync 0: CLKW->CLKR
253
      RR_WADDR_S1  <= RR_WADDR_S0;      -- sync 1: CLKW
254
      RR_SIZER     <= NR_SIZER;
255
      RR_VAL       <= NR_VAL;
256
      RR_RSTR      <= NR_RSTR;
257
      RR_RSTR_E_S0 <= RW_RSTR_S1;       -- sync 0: CLKW->CLKR
258
      RR_RSTR_E_S1 <= RR_RSTR_E_S0;     -- sync 1: CLKW
259
      RR_RSTW_S0   <= RW_RSTW;          -- sync 0: CLKW->CLKR
260
      RR_RSTW_S1   <= RR_RSTW_S0;       -- sync 1: CLKW
261 16 wfjm
    end if;
262
  end process proc_regr;
263
 
264 36 wfjm
  proc_nextr: process (RR_VAL, RR_SIZER, RR_RSTR, RR_RSTR_E_S1, RR_RSTW_S1,
265
                       HOLD, RESETR, RADDR_BIN_R, WADDR_BIN_R)
266 16 wfjm
 
267
    variable ival : slbit := '0';
268 36 wfjm
    variable irstr : slbit := '0';
269 16 wfjm
    variable igcr_ce  : slbit := '0';
270
    variable igcr_rst : slbit := '0';
271 36 wfjm
    variable isizer : slv(a_range) := (others=>'0');
272 16 wfjm
 
273
  begin
274
 
275 36 wfjm
    isizer := slv(unsigned(WADDR_BIN_R) - unsigned(RADDR_BIN_R));
276 16 wfjm
    ival  := '1';
277
    igcr_ce  := '0';
278
    igcr_rst := '0';
279
 
280
    if unsigned(isizer) = 0 then        -- if nothing to read
281
      ival := '0';                        -- next cycle val=0
282
    end if;
283
 
284 36 wfjm
    if RR_VAL='1' and HOLD='0' then     -- this cycle val=1 and no hold
285 16 wfjm
      igcr_ce := '1';                     -- retire this value
286
      if unsigned(isizer) = 1  then       -- if this is last one
287
        ival := '0';                        -- next cycle val=0
288
      end if;
289
    end if;
290
 
291 36 wfjm
    irstr := RR_RSTR;
292 16 wfjm
    if RESETR = '1' then                -- reset(read side) request
293 36 wfjm
      irstr := '1';                       -- set RSTR flag
294
    elsif RR_RSTR_E_S1 = '1' then       -- request gone and return seen
295
      irstr := '0';                       -- clear RSTR flag
296 16 wfjm
    end if;
297
 
298 36 wfjm
    if RR_RSTR='1' and RR_RSTR_E_S1='1' then -- RSTR seen on read and write side
299 16 wfjm
      igcr_rst := '1';                     -- clear read address counter
300
    end if;
301 36 wfjm
    if RR_RSTW_S1 = '1' then            -- RSTW active
302 16 wfjm
      igcr_rst := '1';                    -- clear read address counter
303
    end if;
304
 
305 36 wfjm
    if RESETR='1' or RR_RSTR='1' or RR_RSTR_E_S1='1' or RR_RSTW_S1='1'
306 16 wfjm
    then                                -- RESETR or RESETW active 
307
      ival   := '0';                       -- signal read side empty
308
      isizer := (others=>'0');
309
    end if;
310
 
311 36 wfjm
    NR_VAL   <= ival;
312
    NR_RSTR  <= irstr;
313
    NR_SIZER <= isizer;
314 16 wfjm
 
315
    GCR_CE  <= igcr_ce;
316
    GCR_RST <= igcr_rst;
317 36 wfjm
    VAL     <= RR_VAL;
318
    SIZER   <= RR_SIZER;
319 16 wfjm
 
320
  end process proc_nextr;
321
 
322
end syn;

powered by: WebSVN 2.1.0

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