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

Subversion Repositories heap_sorter

[/] [heap_sorter/] [trunk/] [standard_version/] [src/] [sorter_sys.vhd] - Blame information for rev 7

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

Line No. Rev Author Line
1 2 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: 2011-07-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
    port (
62
      clk    : in  std_logic;
63
      addr_a : in  std_logic_vector(NLEVELS-1 downto 0);
64
      addr_b : in  std_logic_vector(NLEVELS-1 downto 0);
65
      data_a : in  T_DATA_REC;
66
      data_b : in  T_DATA_REC;
67
      we_a   : in  std_logic;
68
      we_b   : in  std_logic;
69
      q_a    : out T_DATA_REC;
70
      q_b    : out T_DATA_REC);
71
  end component;
72
 
73
  component sorter_ctrl
74
    generic (
75
      NLEVELS   : integer;
76
      NADDRBITS : integer);
77
    port (
78
      tm_din       : in  T_DATA_REC;
79
      tm_dout      : out T_DATA_REC;
80
      tm_addr      : out std_logic_vector(NLEVELS-1 downto 0);
81
      tm_we        : out std_logic;
82
      lm_din       : in  T_DATA_REC;
83
      lm_dout      : out T_DATA_REC;
84
      lm_addr      : out std_logic_vector(NLEVELS-1 downto 0);
85
      lm_we        : out std_logic;
86
      rm_din       : in  T_DATA_REC;
87
      rm_dout      : out T_DATA_REC;
88
      rm_addr      : out std_logic_vector(NLEVELS-1 downto 0);
89
      rm_we        : out std_logic;
90
      up_in        : in  std_logic;
91
      up_in_val    : in  T_DATA_REC;
92
      up_in_addr   : in  std_logic_vector(NLEVELS-1 downto 0);
93
      up_out       : out std_logic;
94
      up_out_val   : out T_DATA_REC;
95
      up_out_addr  : out std_logic_vector(NLEVELS-1 downto 0);
96
      low_out      : out std_logic;
97
      low_out_val  : out T_DATA_REC;
98
      low_out_addr : out std_logic_vector(NLEVELS-1 downto 0);
99
      low_in       : in  std_logic;
100
      low_in_val   : in  T_DATA_REC;
101
      low_in_addr  : in  std_logic_vector(NLEVELS-1 downto 0);
102
      clk          : in  std_logic;
103
      clk_en       : in  std_logic;
104
      ready_in     : in  std_logic;
105
      ready_out    : out std_logic;
106
      rst_n        : in  std_logic);
107
  end component;
108
 
109
  -- Create signals for address buses
110
  -- Some of them will remain unused.
111
  subtype T_SORT_BUS_ADDR is std_logic_vector(NLEVELS-1 downto 0);
112
  type T_SORT_ADDR_BUSES is array (NLEVELS downto 0) of T_SORT_BUS_ADDR;
113
  signal low_addr, up_addr, addr_dr, addr_dl, addr_u                       : T_SORT_ADDR_BUSES                  := (others => (others => '0'));
114
  type T_SORT_DATA_BUSES is array (NLEVELS downto 0) of T_DATA_REC;
115
  signal up_update_path, low_update_path, data_d, data_dl, data_dr, data_u : T_SORT_DATA_BUSES                  := (others => DATA_REC_INIT_DATA);
116
  signal q_dr, q_dl, q_u, q_ul, q_ur                                       : T_SORT_DATA_BUSES                  := (others => DATA_REC_INIT_DATA);
117
  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');
118
  signal addr_switch, addr_switch_del                                      : std_logic_vector(NLEVELS downto 0);
119
  signal l0_reg                                                            : T_DATA_REC;
120
  signal clk_en                                                            : std_logic                          := '1';
121
 
122
begin  -- sorter_sys_arch1
123
 
124
-- Build the sorting tree
125
 
126
  g1 : for i in 0 to NLEVELS-1 generate
127
 
128
    -- Two RAMs from the upper level are seen as a single RAM
129
    -- We use the most significant bit (i-th bit) to distinguish RAM
130
    -- In all RAMs the A-ports are used for upstream connections
131
    -- and the B-ports are used for downstream connections
132
 
133
    -- Below are processes used to combine two upstream RAMs in a single one
134
    i0a : if i >= 1 generate
135
      addr_switch(i) <= addr_u(i)(i-1);
136
    end generate i0a;
137
    i0b : if i = 0 generate
138
      addr_switch(i) <= '0';
139
    end generate i0b;
140
 
141
    -- There is a problem with reading of data provided by two upstream RAMs
142
    -- we need to multiplex the data...
143
    -- Delay for read data multiplexer
144
    s1 : process (clk, rst_n)
145
    begin  -- process s1
146
      if rst_n = '0' then                 -- asynchronous reset (active low)
147
        addr_switch_del(i) <= '0';
148
      elsif clk'event and clk = '1' then  -- rising clock edge
149
        addr_switch_del(i) <= addr_switch(i);
150
      end if;
151
    end process s1;
152
 
153
    -- Upper RAM signals' multiplexer
154
    c1 : process (addr_switch, addr_switch_del, q_ul, q_ur, we_u)
155
    begin  -- process c1
156
      we_ul(i) <= '0';
157
      we_ur(i) <= '0';
158
      if addr_switch(i) = '1' then
159
        we_ul(i) <= we_u(i);
160
      else
161
        we_ur(i) <= we_u(i);
162
      end if;
163
      if addr_switch_del(i) = '1' then
164
        q_u(i) <= q_ul(i);
165
      else
166
        q_u(i) <= q_ur(i);
167
      end if;
168
    end process c1;
169
 
170
    dp_ram_l : sort_dp_ram
171
      generic map (
172
        NLEVELS    => NLEVELS,
173
        ADDR_WIDTH => i,
174
        NAME       => "L")
175
      port map (
176
        clk    => clk,
177
        addr_a => addr_dl(i),
178
        addr_b => addr_u(i+1),
179
        data_a => data_dl(i),
180
        data_b => data_u(i+1),
181
        we_a   => we_dl(i),
182
        we_b   => we_ul(i+1),
183
        q_a    => q_dl(i),
184
        q_b    => q_ul(i+1));
185
 
186
    dp_ram_r : sort_dp_ram
187
      generic map (
188
        NLEVELS    => NLEVELS,
189
        ADDR_WIDTH => i,
190
        NAME       => "R")
191
      port map (
192
        clk    => clk,
193
        addr_a => addr_dr(i),
194
        addr_b => addr_u(i+1),
195
        data_a => data_dr(i),
196
        data_b => data_u(i+1),
197
        we_a   => we_dr(i),
198
        we_b   => we_ur(i+1),
199
        q_a    => q_dr(i),
200
        q_b    => q_ur(i+1));
201
 
202
    sorter_ctrl_1 : sorter_ctrl
203
      generic map (
204
        NLEVELS   => NLEVELS,
205
        NADDRBITS => i)
206
      port map (
207
        tm_din       => q_u(i),
208
        tm_dout      => data_u(i),
209
        tm_addr      => addr_u(i),
210
        tm_we        => we_u(i),
211
        lm_din       => q_dl(i),
212
        lm_dout      => data_dl(i),
213
        lm_addr      => addr_dl(i),
214
        lm_we        => we_dl(i),
215
        rm_din       => q_dr(i),
216
        rm_dout      => data_dr(i),
217
        rm_addr      => addr_dr(i),
218
        rm_we        => we_dr(i),
219
        up_in        => up_update(i),
220
        up_in_val    => up_update_path(i),
221
        up_in_addr   => up_addr(i),
222
        up_out       => low_update(i),
223
        up_out_val   => low_update_path(i),
224
        up_out_addr  => low_addr(i),
225
        low_in       => low_update(i+1),
226
        low_in_val   => low_update_path(i+1),
227
        low_in_addr  => low_addr(i+1),
228
        low_out      => up_update(i+1),  -- connections to the next level
229
        low_out_val  => up_update_path(i+1),
230
        low_out_addr => up_addr(i+1),
231
        clk          => clk,
232
        clk_en       => clk_en,
233
        ready_in     => s_ready(i+1),
234
        ready_out    => s_ready(i),
235
        rst_n        => rst_n);
236
 
237
  end generate g1;
238
  -- top level
239
 
240
  -- On the top level we have only a single register
241
  process (clk, rst_n)
242
    variable rline : line;
243
  begin  -- process
244
    if rst_n = '0' then                 -- asynchronous reset (active low)
245
      l0_reg <= DATA_REC_INIT_DATA;
246
    elsif clk'event and clk = '1' then  -- rising clock edge
247
      dav <= '0';
248
      if we_u(0) = '1' then
249
        l0_reg <= data_u(0);
250
        dout   <= data_u(0);
251
        dav    <= '1';
252
        if SORT_DEBUG then
253
          write(rline, string'("OUT: "));
254
          write(rline, tdrec2stlv(data_u(0)));
255
          writeline(reports, rline);
256
        end if;
257
      elsif we = '1' then
258
        if SORT_DEBUG then
259
          write(rline, string'("IN: "));
260
          write(rline, tdrec2stlv(din));
261
          writeline(reports, rline);
262
        end if;
263
        l0_reg <= din;
264
        dout   <= din;
265
      else
266
        dout <= l0_reg;
267
      end if;
268
    end if;
269
  end process;
270
  ready             <= s_ready(0);
271
  q_ur(0)           <= l0_reg;
272
  q_ul(0)           <= l0_reg;
273
  up_update(0)      <= we;
274
  up_update_path(0) <= din;
275
  up_addr(0)        <= (others => '0');
276
 
277
  -- signals for the last level
278
 
279
  s_ready(NLEVELS) <= '1';
280
  --addr(NLEVELS)    <= (others => '0');
281
  data_dr(NLEVELS) <= DATA_REC_INIT_DATA;
282
  data_dl(NLEVELS) <= DATA_REC_INIT_DATA;
283
  we_dl(NLEVELS)   <= '0';
284
  we_dr(NLEVELS)   <= '0';
285
 
286
  low_update(NLEVELS)      <= '0';
287
  low_update_path(NLEVELS) <= DATA_REC_INIT_DATA;
288
  low_addr(0)              <= (others => '0');
289
 
290
end sorter_sys_arch1;

powered by: WebSVN 2.1.0

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