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

Subversion Repositories heap_sorter

[/] [heap_sorter/] [trunk/] [high_speed_pipelined_4clk_per_word/] [src/] [sort_dpram.vhd_sim] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 wzab
-------------------------------------------------------------------------------
2
-- Title      : Parametrized DP RAM for heap-sorter
3
-- Project    : heap-sorter
4
-------------------------------------------------------------------------------
5
-- File       : sort_dpram.vhd
6
-- Author     : Wojciech M. Zabolotny 
7
-- Company    :
8
-- Created    : 2010-05-14
9
-- Last update: 2018-03-09
10
-- Platform   :
11
-- Standard   : VHDL'93
12
-------------------------------------------------------------------------------
13
-- Description:
14
-------------------------------------------------------------------------------
15
-- Copyright (c) 2010 Wojciech M. Zabolotny
16
-- This file is published under the BSD license, so you can freely adapt
17
-- it for your own purposes.
18
-- Additionally this design has been described in my article:
19
--    Wojciech M. Zabolotny, "Dual port memory based Heapsort implementation
20
--    for FPGA", Proc. SPIE 8008, 80080E (2011); doi:10.1117/12.905281
21
-- I'd be glad if you cite this article when you publish something based
22
-- on my design.
23
-------------------------------------------------------------------------------
24
-- Revisions  :
25
-- Date        Version  Author  Description
26
-- 2010-05-14  1.0      wzab    Created
27
-------------------------------------------------------------------------------
28
 
29
library ieee;
30
use ieee.std_logic_1164.all;
31
use ieee.numeric_std.all;
32
use ieee.std_logic_textio.all;
33
use std.textio.all;
34
library work;
35
use work.sorter_pkg.all;
36
use work.sys_config.all;
37
 
38
entity sort_dp_ram is
39
 
40
  generic
41
    (
42
      ADDR_WIDTH  : natural;
43
      NLEVELS     : natural;
44
      NAME        : string := "X";
45
      RAM_STYLE_G : string := "block"
46
      );
47
 
48
  port
49
    (
50
      clk    : in  std_logic;
51
      clk2   : in  std_logic;
52
      addr_a : in  std_logic_vector(NLEVELS-1 downto 0);
53
      addr_b : in  std_logic_vector(NLEVELS-1 downto 0);
54
      data_a : in  T_DATA_REC;
55
      data_b : in  T_DATA_REC;
56
      we_a   : in  std_logic;
57
      we_b   : in  std_logic;
58
      q_a    : out T_DATA_REC;
59
      q_b    : out T_DATA_REC
60
      );
61
 
62
end sort_dp_ram;
63
 
64
architecture rtl of sort_dp_ram is
65
 
66
  constant SYNC_CLK2 : boolean := false;
67
 
68
  signal vq_a, vq_b, tdata_a, tdata_b : std_logic_vector(DATA_REC_WIDTH-1 downto 0);
69
  signal reg                          : T_DATA_REC := DATA_REC_INIT_DATA;
70
  signal det1, det2, det3             : std_logic  := '1';
71
  signal gwe_a, gwe_b                 : std_logic  := '1';
72
  signal xaddr_a                      : std_logic_vector(NLEVELS-1 downto 0);
73
  signal xaddr_b                      : std_logic_vector(NLEVELS-1 downto 0);
74
 
75
begin
76
 
77
  -- Convert our data records int std_logic_vector, so that
78
  -- standard DP RAM may handle it
79
  tdata_a <= tdrec2stlv(data_a);
80
  tdata_b <= tdrec2stlv(data_b);
81
 
82
 
83
  -- Simulate the combinational net settling after 17.5 ns
84
  process is
85
  begin  -- process
86
    wait until clk'event and clk = '1';  -- rising clock edge
87
    xaddr_a <= (others => 'X');
88
    xaddr_a <= (others => 'X');
89
    wait for 17.5 ns;
90
    xaddr_a <= addr_a;
91
    xaddr_b <= addr_b;
92
  end process;
93
 
94
  -- We need to ensure, that the memory is written only every second cycle (so
95
  -- that the external combinatorial net has two Clk2 cycles to settle)
96
  --
97
  rs1 : process (clk) is
98
  begin  -- process rs1
99
    if clk'event and clk = '1' then     -- rising clock edge
100
      det1 <= not det1;
101
    end if;
102
  end process rs1;
103
 
104
  rs2 : process (clk2) is
105
  begin  -- process rs1
106
    if clk2'event and clk2 = '1' then   -- rising clock edge
107
      det2 <= det1;
108
    end if;
109
  end process rs2;
110
  -- We should activate WE only when det1 and det2 are equal
111
  -- (i.e., after the clk2 pulse not associated with the clk pulse)
112
 
113
  ig1 : if SYNC_CLK2 generate
114
    gwe : process (det1, det2, we_a, we_b) is
115
    begin  -- process gwe
116
      gwe_a <= '0';
117
      gwe_b <= '0';
118
      if det2 = det1 then
119
        gwe_a <= we_a;
120
        gwe_b <= we_b;
121
      end if;
122
    end process gwe;
123
  end generate ig1;
124
 
125
  ig2 : if not SYNC_CLK2 generate
126
    gwe_a <= we_a;
127
    gwe_b <= we_b;
128
  end generate ig2;
129
 
130
  i1 : if ADDR_WIDTH > 0 generate
131
    -- When ADDR_WIDTH is above 0 embed the real DP RAM
132
    -- (even though synthesis tool may still replace it with
133
    -- registers during optimization for low ADDR_WIDTH)
134
 
135
    q_a <= stlv2tdrec(vq_a);
136
    q_b <= stlv2tdrec(vq_b);
137
    blockgen : if RAM_STYLE_G = "block" generate
138
      dp_ram_1 : entity work.dp_ram_scl_sorter
139
        generic map (
140
          DATA_WIDTH => DATA_REC_WIDTH,
141
          ADDR_WIDTH => ADDR_WIDTH)
142
        port map (
143
          clk    => clk2,
144
          addr_a => xaddr_a(ADDR_WIDTH-1 downto 0),
145
          addr_b => xaddr_b(ADDR_WIDTH-1 downto 0),
146
          data_a => tdata_a,
147
          data_b => tdata_b,
148
          we_a   => gwe_a,
149
          we_b   => gwe_b,
150
          q_a    => vq_a,
151
          q_b    => vq_b);
152
 
153
    end generate;
154
 
155
    distribgen : if RAM_STYLE_G = "distributed" generate
156
      dp_ram_1 : entity work.dp_ram_scl_sorter_distributed
157
        generic map (
158
          DATA_WIDTH => DATA_REC_WIDTH,
159
          ADDR_WIDTH => ADDR_WIDTH)
160
        port map (
161
          clk    => clk2,
162
          addr_a => xaddr_a(ADDR_WIDTH-1 downto 0),
163
          addr_b => xaddr_b(ADDR_WIDTH-1 downto 0),
164
          data_a => tdata_a,
165
          data_b => tdata_b,
166
          we_a   => gwe_a,
167
          we_b   => gwe_b,
168
          q_a    => vq_a,
169
          q_b    => vq_b);
170
 
171
    end generate;
172
 
173
 
174
  end generate i1;
175
 
176
  i2 : if ADDR_WIDTH = 0 generate
177
    -- When ADDR_WIDTH is 0, DP RAM should be simply replaced
178
    -- with a register implemented below
179
 
180
    p1 : process (clk)
181
    begin  -- process p1
182
      if clk'event and clk = '1' then   -- rising clock edge
183
        if we_a = '1' then
184
          reg <= data_a;
185
          q_a <= data_a;
186
          q_b <= data_a;
187
        elsif we_b = '1' then
188
          reg <= data_b;
189
          q_a <= data_b;
190
          q_b <= data_b;
191
        else
192
          q_a <= reg;
193
          q_b <= reg;
194
        end if;
195
      end if;
196
    end process p1;
197
 
198
  end generate i2;
199
 
200
  --dbg1 : if SORT_DEBUG generate
201
 
202
  --  -- Process monitoring read/write accesses to the memory (only for debugging)
203
  --  p3 : process (clk)
204
  --    variable rline : line;
205
  --  begin  -- process p1
206
  --    if clk'event and clk = '1' then   -- rising clock edge
207
  --      if(we_a = '1' and we_b = '1') then
208
  --        write(rline, NAME);
209
  --        write(rline, ADDR_WIDTH);
210
  --        write(rline, string'(" Possible write collision!"));
211
  --        writeline(reports, rline);
212
  --      end if;
213
 
214
--      if we_a = '1' then
215
--        write(rline, NAME);
216
--        write(rline, ADDR_WIDTH);
217
--        write(rline, string'(" WR_A:"));
218
--        wrstlv(rline, addr_a(ADDR_WIDTH-1 downto 0));
219
--        write(rline, string'(" VAL:"));
220
--        wrstlv(rline, tdata_a);
221
--        writeline(reports, rline);
222
--      end if;
223
--      if we_b = '1' then
224
--        write(rline, NAME);
225
--        write(rline, ADDR_WIDTH);
226
--        write(rline, string'(" WR_B:"));
227
--        wrstlv(rline, addr_b(ADDR_WIDTH-1 downto 0));
228
--        write(rline, string'(" VAL:"));
229
--        wrstlv(rline, tdata_b);
230
--        writeline(reports, rline);
231
--      end if;
232
--    end if;
233
--  end process p3;
234
--end generate dbg1;
235
end rtl;

powered by: WebSVN 2.1.0

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