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/] [sorter_sys.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 wzab
-------------------------------------------------------------------------------
2
-- Title      : Top entity of heap-sorter
3
-- Project    : heap-sorter
4
-------------------------------------------------------------------------------
5
-- File       : sorter_sys.vhd
6
-- Author     : Wojciech M. Zabolotny <wzab@ise.pw.edu.pl>
7
-- Company    : 
8
-- Created    : 2010-05-14
9
-- Last update: 2018-03-11
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
-- Additionally this design has been described in my article:
20
--    Wojciech M. Zabolotny, "Dual port memory based Heapsort implementation
21
--    for FPGA", Proc. SPIE 8008, 80080E (2011); doi:10.1117/12.905281
22
-- I'd be glad if you cite this article when you publish something based
23
-- on my design.
24
-------------------------------------------------------------------------------
25
-- Revisions  :
26
-- Date        Version  Author  Description
27
-- 2010-05-14  1.0      wzab    Created
28
-------------------------------------------------------------------------------
29
 
30
library ieee;
31
use ieee.std_logic_1164.all;
32
use ieee.numeric_std.all;
33
use ieee.std_logic_textio.all;
34
use std.textio.all;
35
library work;
36
use work.sorter_pkg.all;
37
use work.sys_config.all;
38
 
39
entity sorter_sys is
40
  generic (
41
    NLEVELS : integer := SYS_NLEVELS     -- number of levels in the sorter heap
42
    );
43
 
44
  port (
45
    din   : in  T_DATA_REC;
46
    we    : in  std_logic;
47
    dout  : out T_DATA_REC;
48
    dav   : out std_logic;
49
    clk   : in  std_logic;
50
    rst_n : in  std_logic;
51
    ready : out std_logic);
52
end sorter_sys;
53
 
54
architecture sorter_sys_arch1 of sorter_sys is
55
 
56
  component sort_dp_ram
57
    generic (
58
      ADDR_WIDTH : natural;
59
      NLEVELS    : natural;
60
      NAME       : string;
61
      RAM_STYLE_G : string := "block");
62
    port (
63
      clk    : in  std_logic;
64
      addr_a : in  std_logic_vector(NLEVELS-1 downto 0);
65
      addr_b : in  std_logic_vector(NLEVELS-1 downto 0);
66
      data_a : in  T_DATA_REC;
67
      data_b : in  T_DATA_REC;
68
      we_a   : in  std_logic;
69
      we_b   : in  std_logic;
70
      q_a    : out T_DATA_REC;
71
      q_b    : out T_DATA_REC);
72
  end component;
73
 
74
  component sorter_ctrl
75
    generic (
76
      NLEVELS   : integer;
77
      NADDRBITS : integer);
78
    port (
79
      tm_din       : in  T_DATA_REC;
80
      tm_dout      : out T_DATA_REC;
81
      tm_addr      : out std_logic_vector(NLEVELS-1 downto 0);
82
      tm_we        : out std_logic;
83
      lm_din       : in  T_DATA_REC;
84
      lm_dout      : out T_DATA_REC;
85
      lm_addr      : out std_logic_vector(NLEVELS-1 downto 0);
86
      lm_we        : out std_logic;
87
      rm_din       : in  T_DATA_REC;
88
      rm_dout      : out T_DATA_REC;
89
      rm_addr      : out std_logic_vector(NLEVELS-1 downto 0);
90
      rm_we        : out std_logic;
91
      up_in        : in  std_logic;
92
      up_in_val    : in  T_DATA_REC;
93
      up_in_addr   : in  std_logic_vector(NLEVELS-1 downto 0);
94
      up_out       : out std_logic;
95
      up_out_val   : out T_DATA_REC;
96
      up_out_addr  : out std_logic_vector(NLEVELS-1 downto 0);
97
      low_out      : out std_logic;
98
      low_out_val  : out T_DATA_REC;
99
      low_out_addr : out std_logic_vector(NLEVELS-1 downto 0);
100
      low_in       : in  std_logic;
101
      low_in_val   : in  T_DATA_REC;
102
      low_in_addr  : in  std_logic_vector(NLEVELS-1 downto 0);
103
      clk          : in  std_logic;
104
      clk_en       : in  std_logic;
105
      ready_in     : in  std_logic;
106
      ready_out    : out std_logic;
107
      rst_n        : in  std_logic);
108
  end component;
109
 
110
  -- Create signals for address buses
111
  -- Some of them will remain unused.
112
  subtype T_SORT_BUS_ADDR is std_logic_vector(NLEVELS-1 downto 0);
113
  type T_SORT_ADDR_BUSES is array (NLEVELS downto 0) of T_SORT_BUS_ADDR;
114
  signal low_addr, up_addr, addr_dr, addr_dl, addr_u                       : T_SORT_ADDR_BUSES                  := (others => (others => '0'));
115
  type T_SORT_DATA_BUSES is array (NLEVELS downto 0) of T_DATA_REC;
116
  signal up_update_path, low_update_path, data_d, data_dl, data_dr, data_u : T_SORT_DATA_BUSES                  := (others => DATA_REC_INIT_DATA);
117
  signal q_dr, q_dl, q_u, q_ul, q_ur                                       : T_SORT_DATA_BUSES                  := (others => DATA_REC_INIT_DATA);
118
  signal we_ul, we_ur, we_u, we_dl, we_dr, low_update, up_update, s_ready  : std_logic_vector(NLEVELS downto 0) := (others => '0');
119
  signal addr_switch, addr_switch_del                                      : std_logic_vector(NLEVELS downto 0);
120
  signal l0_reg                                                            : T_DATA_REC;
121
  signal clk_en                                                            : std_logic                          := '1';
122
 
123
  function f_sel_bram_style (
124
    addrwidth   : natural )
125
    return string is
126
  begin
127
    if addrwidth >= 4 then
128
      return "block";
129
    else
130
      return "distributed";
131
    end if;
132
  end function f_sel_bram_style;
133
 
134
begin  -- sorter_sys_arch1
135
 
136
-- Build the sorting tree
137
 
138
  g1 : for i in 0 to NLEVELS-1 generate
139
 
140
    -- Two RAMs from the upper level are seen as a single RAM
141
    -- We use the most significant bit (i-th bit) to distinguish RAM
142
    -- In all RAMs the A-ports are used for upstream connections
143
    -- and the B-ports are used for downstream connections
144
 
145
    -- Below are processes used to combine two upstream RAMs in a single one
146
    i0a : if i >= 1 generate
147
      addr_switch(i) <= addr_u(i)(i-1);
148
    end generate i0a;
149
    i0b : if i = 0 generate
150
      addr_switch(i) <= '0';
151
    end generate i0b;
152
 
153
    -- There is a problem with reading of data provided by two upstream RAMs
154
    -- we need to multiplex the data...
155
    -- Delay for read data multiplexer
156
    s1 : process (clk, rst_n)
157
    begin  -- process s1
158
      if rst_n = '0' then                 -- asynchronous reset (active low)
159
        addr_switch_del(i) <= '0';
160
      elsif clk'event and clk = '1' then  -- rising clock edge
161
        addr_switch_del(i) <= addr_switch(i);
162
      end if;
163
    end process s1;
164
 
165
    -- Upper RAM signals' multiplexer
166
    c1 : process (addr_switch, addr_switch_del, q_ul, q_ur, we_u)
167
    begin  -- process c1
168
      we_ul(i) <= '0';
169
      we_ur(i) <= '0';
170
      if addr_switch(i) = '1' then
171
        we_ul(i) <= we_u(i);
172
      else
173
        we_ur(i) <= we_u(i);
174
      end if;
175
      if addr_switch_del(i) = '1' then
176
        q_u(i) <= q_ul(i);
177
      else
178
        q_u(i) <= q_ur(i);
179
      end if;
180
    end process c1;
181
 
182
    dp_ram_l : sort_dp_ram
183
      generic map (
184
        NLEVELS    => NLEVELS,
185
        ADDR_WIDTH => i,
186
        NAME       => "L",
187
        RAM_STYLE_G => f_sel_bram_style(i))
188
      port map (
189
        clk    => clk,
190
        addr_a => addr_dl(i),
191
        addr_b => addr_u(i+1),
192
        data_a => data_dl(i),
193
        data_b => data_u(i+1),
194
        we_a   => we_dl(i),
195
        we_b   => we_ul(i+1),
196
        q_a    => q_dl(i),
197
        q_b    => q_ul(i+1));
198
 
199
    dp_ram_r : sort_dp_ram
200
      generic map (
201
        NLEVELS    => NLEVELS,
202
        ADDR_WIDTH => i,
203
        NAME       => "R",
204
        RAM_STYLE_G => f_sel_bram_style(i))
205
      port map (
206
        clk    => clk,
207
        addr_a => addr_dr(i),
208
        addr_b => addr_u(i+1),
209
        data_a => data_dr(i),
210
        data_b => data_u(i+1),
211
        we_a   => we_dr(i),
212
        we_b   => we_ur(i+1),
213
        q_a    => q_dr(i),
214
        q_b    => q_ur(i+1));
215
 
216
    sorter_ctrl_1 : sorter_ctrl
217
      generic map (
218
        NLEVELS   => NLEVELS,
219
        NADDRBITS => i)
220
      port map (
221
        tm_din       => q_u(i),
222
        tm_dout      => data_u(i),
223
        tm_addr      => addr_u(i),
224
        tm_we        => we_u(i),
225
        lm_din       => q_dl(i),
226
        lm_dout      => data_dl(i),
227
        lm_addr      => addr_dl(i),
228
        lm_we        => we_dl(i),
229
        rm_din       => q_dr(i),
230
        rm_dout      => data_dr(i),
231
        rm_addr      => addr_dr(i),
232
        rm_we        => we_dr(i),
233
        up_in        => up_update(i),
234
        up_in_val    => up_update_path(i),
235
        up_in_addr   => up_addr(i),
236
        up_out       => low_update(i),
237
        up_out_val   => low_update_path(i),
238
        up_out_addr  => low_addr(i),
239
        low_in       => low_update(i+1),
240
        low_in_val   => low_update_path(i+1),
241
        low_in_addr  => low_addr(i+1),
242
        low_out      => up_update(i+1),  -- connections to the next level
243
        low_out_val  => up_update_path(i+1),
244
        low_out_addr => up_addr(i+1),
245
        clk          => clk,
246
        clk_en       => clk_en,
247
        ready_in     => s_ready(i+1),
248
        ready_out    => s_ready(i),
249
        rst_n        => rst_n);
250
 
251
  end generate g1;
252
  -- top level
253
 
254
  -- On the top level we have only a single register
255
  process (clk, rst_n)
256
    variable rline : line;
257
  begin  -- process
258
    if rst_n = '0' then                 -- asynchronous reset (active low)
259
      l0_reg <= DATA_REC_INIT_DATA;
260
      dav <= '0';
261
    elsif clk'event and clk = '1' then  -- rising clock edge
262
      dav <= '0';
263
      if we_u(0) = '1' then
264
        l0_reg <= data_u(0);
265
        dout   <= data_u(0);
266
        dav    <= '1';
267
        --if SORT_DEBUG then
268
        --  write(rline, string'("OUT: "));
269
        --  write(rline, tdrec2stlv(data_u(0)));
270
        --  writeline(reports, rline);
271
        --end if;
272
      elsif we = '1' then
273
        --if SORT_DEBUG then
274
        --  write(rline, string'("IN: "));
275
        --  write(rline, tdrec2stlv(din));
276
        --  writeline(reports, rline);
277
        --end if;
278
        l0_reg <= din;
279
        -- dout   <= din;
280
      -- else
281
      --   dout <= l0_reg;
282
      end if;
283
    end if;
284
  end process;
285
  ready             <= s_ready(0);
286
  q_ur(0)           <= l0_reg;
287
  q_ul(0)           <= l0_reg;
288
  up_update(0)      <= we;
289
  up_update_path(0) <= din;
290
  up_addr(0)        <= (others => '0');
291
 
292
  -- signals for the last level
293
 
294
  s_ready(NLEVELS) <= '1';
295
  --addr(NLEVELS)    <= (others => '0');
296
  data_dr(NLEVELS) <= DATA_REC_INIT_DATA;
297
  data_dl(NLEVELS) <= DATA_REC_INIT_DATA;
298
  we_dl(NLEVELS)   <= '0';
299
  we_dr(NLEVELS)   <= '0';
300
 
301
  low_update(NLEVELS)      <= '0';
302
  low_update_path(NLEVELS) <= DATA_REC_INIT_DATA;
303
  low_addr(0)              <= (others => '0');
304
 
305
end sorter_sys_arch1;

powered by: WebSVN 2.1.0

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