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

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.storage/] [sdram2hibi/] [1.0/] [vhd/] [sdram_rd_port.vhd] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- Title      : rd_port.vhd
3
-- Project    : 
4
-------------------------------------------------------------------------------
5
-- File       : rd_port.vhd
6
-- Author     : 
7
-- Company    : 
8
-- Created    : 2007-05-22
9
-- Last update: 2012-01-26
10
-- Platform   : 
11
-- Standard   : VHDL'87
12
-------------------------------------------------------------------------------
13
-- Description: Read port for sdram2hibi
14
-------------------------------------------------------------------------------
15
-- Copyright (c) 2007 
16
-------------------------------------------------------------------------------
17
-- Revisions  :
18
-- Date        Version  Author  Description
19
-- 2007-05-22  1.0      penttin5        Created
20
-- 2012-01-22  1.001    alhonen fixed names
21
-------------------------------------------------------------------------------
22
 
23
library ieee;
24
use ieee.std_logic_1164.all;
25
use ieee.numeric_std.all;
26
 
27
entity sdram_rd_port is
28
 
29
  generic (
30
    amountw_g       : integer;
31
    hibi_dataw_g    : integer;
32
    block_overlap_g : integer := 0;
33
    offsetw_g       : integer;
34
    mem_dataw_g     : integer;
35
    mem_addrw_g     : integer);
36
 
37
  port (
38
    clk            : in  std_logic;
39
    rst_n          : in  std_logic;
40
    conf_we_in     : in  std_logic;
41
    conf_data_in   : in  std_logic_vector(hibi_dataw_g - 1 downto 0);
42
    read_in        : in  std_logic;
43
    reserve_in     : in  std_logic;
44
    valid_out      : out std_logic;
45
    reserved_out   : out std_logic;
46
    end_addr_out   : out std_logic_vector(mem_addrw_g - 1 downto 0);
47
    src_addr_out   : out std_logic_vector(mem_addrw_g - 1 downto 0);
48
    amount_out     : out std_logic_vector(amountw_g - 1 downto 0);
49
    ret_addr_out   : out std_logic_vector(hibi_dataw_g - 1 downto 0);
50
    finish_out     : out std_logic;
51
    error_out      : out std_logic);
52
 
53
end sdram_rd_port;
54
 
55
architecture rtl of sdram_rd_port is
56
 
57
  -- parameter numbers
58
  constant src_addr_param_c : integer := 0;
59
  constant amount_param_c   : integer := 1;
60
  constant width_param_c    : integer := 1;
61
  constant ret_addr_param_c : integer := 2;
62
  constant height_param_c   : integer := 3;
63
  constant offset_param_c   : integer := 3;
64
  constant last_param_c     : integer := 3;
65
 
66
  signal reserved_r : std_logic;
67
  signal valid_r    : std_logic;
68
  signal src_addr_r : std_logic_vector(mem_addrw_g - 1 downto 0);
69
  signal amount_r   : std_logic_vector(amountw_g - 1 downto 0);
70
  signal width_r    : std_logic_vector(amountw_g - 1 downto 0);
71
  signal height_r   : std_logic_vector(hibi_dataw_g - offsetw_g - 1 downto 0);
72
  signal offset_r   : std_logic_vector(offsetw_g - 1 downto 0);
73
  signal end_addr_r : std_logic_vector(mem_addrw_g - 1 downto 0);
74
  signal ret_addr_r : std_logic_vector(hibi_dataw_g - 1 downto 0);
75
 
76
  signal finish          : std_logic;
77
  signal param_cnt_r     : integer range last_param_c downto 0;
78
  signal end_addr_rdy_r  : std_logic;
79
  signal calc_end_addr_r : std_logic;
80
  signal h_times_o_r     : std_logic_vector(hibi_dataw_g - 1 downto 0);
81
 
82
begin  -- rtl
83
 
84
  -- drive outputs
85
  reserved_out <= reserved_r;
86
  valid_out    <= valid_r;
87
  src_addr_out <= src_addr_r;
88
  amount_out   <= amount_r;
89
  end_addr_out <= end_addr_r;
90
  ret_addr_out <= ret_addr_r;
91
 
92
  -- purpose: Detect finished operation
93
  -- type   : combinational
94
  -- inputs : read_in, amount_r, height_r
95
  -- outputs: finish
96
  port_finishes : process (read_in, amount_r, height_r)
97
  begin  -- process port_finishes
98
    if read_in = '1'
99
      and to_integer(unsigned(amount_r)) = 1
100
      and (to_integer(unsigned(height_r)) = 1 or
101
           to_integer(unsigned(height_r)) = 0) then
102
      finish <= '1';
103
    else
104
      finish <= '0';
105
    end if;
106
  end process port_finishes;
107
 
108
  finish_output: process (clk, rst_n)
109
  begin  -- process finish_output
110
    if rst_n = '0' then                 -- asynchronous reset (active low)
111
      finish_out <= '0';
112
    elsif clk'event and clk = '1' then  -- rising clock edge
113
      finish_out <= finish;
114
    end if;
115
  end process finish_output;
116
 
117
  param_counter: process (clk, rst_n)
118
  begin  -- process param_counter
119
    if rst_n = '0' then                 -- asynchronous reset (active low)
120
      param_cnt_r <= 0;
121
    elsif clk'event and clk = '1' then  -- rising clock edge
122
 
123
      if conf_we_in = '1' and param_cnt_r = last_param_c then
124
        param_cnt_r <= 0;
125
      elsif conf_we_in = '1' then
126
        param_cnt_r <= param_cnt_r + 1;
127
      else
128
        param_cnt_r <= param_cnt_r;
129
      end if;
130
    end if;
131
  end process param_counter;
132
 
133
  reserved_proc : process (clk, rst_n)
134
  begin  -- process reserved_proc
135
    if rst_n = '0' then                 -- asynchronous reset (active low)
136
      reserved_r <= '0';
137
    elsif clk'event and clk = '1' then  -- rising clock edge
138
 
139
      if finish = '1' then
140
        -- operation finishes
141
        reserved_r <= '0';
142
      elsif reserve_in = '1' then
143
        -- reserve from sdram2hibi
144
        reserved_r <= '1';
145
      else
146
        reserved_r <= reserved_r;
147
      end if;
148
    end if;
149
  end process reserved_proc;
150
 
151
  valid_proc : process (clk, rst_n)
152
  begin  -- process valid_proc
153
    if rst_n = '0' then                 -- asynchronous reset (active low)
154
      valid_r <= '0';
155
    elsif clk'event and clk = '1' then  -- rising clock edge
156
 
157
      if finish = '1' then
158
        -- operation finishes
159
        valid_r <= '0';
160
      elsif block_overlap_g = 0
161
        and conf_we_in = '1' and param_cnt_r = last_param_c then
162
        -- without block overlap, configuration finishes on
163
        -- third paramater write
164
        valid_r <= '1';
165
      elsif block_overlap_g = 1 and end_addr_rdy_r = '1' then
166
        -- with block overlap, configuration finishes on
167
        -- end address calculation
168
        valid_r <= '1';
169
      else
170
        valid_r <= valid_r;
171
      end if;
172
    end if;
173
 
174
  end process valid_proc;
175
 
176
  src_addr_proc : process (clk, rst_n)
177
  begin  -- process src_addr_proc
178
    if rst_n = '0' then                 -- asynchronous reset (active low)
179
      src_addr_r <= (others => '0');
180
    elsif clk'event and clk = '1' then  -- rising clock edge
181
 
182
      if read_in = '1' and to_integer(unsigned(amount_r)) = 1 then
183
        -- line finishes, jump to next line
184
        src_addr_r <= std_logic_vector(unsigned(src_addr_r) +
185
                                       unsigned(offset_r) + 1);
186
      elsif read_in = '1' then
187
        -- line continues, increase src_addr
188
        src_addr_r <= std_logic_vector(unsigned(src_addr_r) + 1);
189
 
190
      elsif conf_we_in = '1' and param_cnt_r = src_addr_param_c then
191
        -- configure from sdram2hibi
192
        src_addr_r <= conf_data_in(mem_addrw_g - 1 downto 0);
193
      else
194
        src_addr_r <= src_addr_r;
195
      end if;
196
    end if;
197
  end process src_addr_proc;
198
 
199
  width_proc : process (clk, rst_n)
200
  begin  -- process width_proc
201
    if rst_n = '0' then                 -- asynchronous reset (active low)
202
      width_r <= (others => '0');
203
    elsif clk'event and clk = '1' then  -- rising clock edge
204
 
205
      if conf_we_in = '1' and param_cnt_r = width_param_c then
206
        width_r <= conf_data_in(amountw_g - 1 downto 0);
207
      else
208
        width_r <= width_r;
209
      end if;
210
    end if;
211
  end process width_proc;
212
 
213
  height_proc : process (clk, rst_n)
214
  begin  -- process height_proc
215
    if rst_n = '0' then                 -- asynchronous reset (active low)
216
      height_r <= (others => '0');
217
    elsif clk'event and clk = '1' then  -- rising clock edge
218
      if read_in = '1' and to_integer(unsigned(amount_r)) = 1
219
        and to_integer(unsigned(height_r)) /= 0 then
220
        height_r <= std_logic_vector(unsigned(height_r) - 1);
221
      elsif conf_we_in = '1' and param_cnt_r = height_param_c then
222
        height_r <= conf_data_in(conf_data_in'length - 1 downto offsetw_g);
223
      else
224
        height_r <= height_r;
225
      end if;
226
    end if;
227
  end process height_proc;
228
 
229
  offset_proc : process (clk, rst_n)
230
  begin  -- process offset_proc
231
    if rst_n = '0' then                 -- asynchronous reset (active low)
232
      offset_r <= (others => '0');
233
    elsif clk'event and clk = '1' then  -- rising clock edge
234
      if conf_we_in = '1' and param_cnt_r = offset_param_c then
235
        offset_r <= conf_data_in(offsetw_g - 1 downto 0);
236
      else
237
        offset_r <= offset_r;
238
      end if;
239
    end if;
240
  end process offset_proc;
241
 
242
  end_addr_proc : process (clk, rst_n)
243
    variable h_times_o_v : integer;
244
  begin  -- process end_addr_proc
245
    if rst_n = '0' then                 -- asynchronous reset (active low)
246
      end_addr_r      <= (others => '0');
247
      end_addr_rdy_r  <= '0';
248
      calc_end_addr_r <= '0';
249
      h_times_o_r     <= (others => '0');
250
    elsif clk'event and clk = '1' then  -- rising clock edge
251
 
252
      h_times_o_r <= h_times_o_r;
253
 
254
      if finish = '1' then
255
        -- opertation finishes
256
        end_addr_rdy_r  <= '0';
257
        calc_end_addr_r <= '0';
258
 
259
      elsif conf_we_in = '1' and param_cnt_r = src_addr_param_c then
260
        -- calculate end address in seperate steps
261
        -- if block_overlap_g = 0:
262
        --    final end_addr_r = dst_addr_r + width_r
263
        -- if block_overlap_g = 1:
264
        --    final end_addr_r = dst_addr_r + width_r + (height_r-1)*offset_r
265
 
266
        -- 1) end_addr_r = dst_addr
267
        end_addr_r      <= conf_data_in(mem_addrw_g - 1 downto 0);
268
        end_addr_rdy_r  <= '0';
269
        calc_end_addr_r <= '0';
270
 
271
      elsif conf_we_in = '1' and param_cnt_r = width_param_c then
272
 
273
        -- 2) end_addr_r = dst_addr + width
274
        end_addr_r <= std_logic_vector(unsigned(end_addr_r) +
275
                                       unsigned(conf_data_in(mem_addrw_g - 1
276
                                                             downto 0)));
277
        if block_overlap_g = 0 then
278
          -- If no block overlap, this is the final result
279
          end_addr_rdy_r  <= '1';
280
        else
281
          -- Otherwise we have to calculate more
282
          end_addr_rdy_r  <= '0';
283
        end if;
284
        calc_end_addr_r <= '0';
285
 
286
      elsif block_overlap_g = 1 and
287
        conf_we_in = '1' and param_cnt_r = height_param_c then
288
 
289
        -- 3) end_addr_r = dst_addr + width
290
        --    h_times_o_r = height * offset
291
 
292
        h_times_o_v :=
293
          to_integer(unsigned(conf_data_in(conf_data_in'length - 1
294
                                           downto offsetw_g))) *
295
          to_integer(unsigned(conf_data_in(offsetw_g - 1
296
                                           downto 0)));
297
 
298
        h_times_o_r <= std_logic_vector(to_unsigned(h_times_o_v, hibi_dataw_g));
299
 
300
        end_addr_rdy_r  <= '0';
301
        calc_end_addr_r <= '1';
302
 
303
      elsif calc_end_addr_r = '1' then
304
        -- 4) end_addr_r = dst_addr_r + width_r + height_r*offset_r - height_r
305
        --               = dst_addr_r + amount_r + (height_r-1)*offset_r
306
        end_addr_r      <= std_logic_vector(
307
          unsigned(end_addr_r) + unsigned(h_times_o_r(end_addr_r'length - 1 downto 0))
308
          - unsigned(height_r));
309
 
310
        end_addr_rdy_r  <= '1';
311
        calc_end_addr_r <= '0';
312
      else
313
        calc_end_addr_r <= calc_end_addr_r;
314
        end_addr_rdy_r  <= end_addr_rdy_r;
315
      end if;
316
 
317
    end if;
318
  end process end_addr_proc;
319
 
320
  amount_proc : process (clk, rst_n)
321
  begin  -- process amount_proc
322
    if rst_n = '0' then                 -- asynchronous reset (active low)
323
      amount_r <= (others => '0');
324
    elsif clk'event and clk = '1' then  -- rising clock edge
325
 
326
      if read_in = '1' and to_integer(unsigned(amount_r)) = 1 then
327
        -- next line on block transfer or transfer finishes
328
        amount_r <= width_r;
329
      elsif read_in = '1' then
330
        -- transfer continues on the same line
331
        amount_r <= std_logic_vector(unsigned(amount_r) - 1);
332
      elsif conf_we_in = '1' and param_cnt_r = amount_param_c then
333
        -- param write from sdram2hibi
334
        amount_r <= conf_data_in(amountw_g - 1 downto 0);
335
      end if;
336
    end if;
337
  end process amount_proc;
338
 
339
  ret_addr_proc: process (clk, rst_n)
340
  begin  -- process ret_addr_proc
341
    if rst_n = '0' then                 -- asynchronous reset (active low)
342
      ret_addr_r <= (others => '0');
343
    elsif clk'event and clk = '1' then  -- rising clock edge
344
 
345
      if conf_we_in = '1' and param_cnt_r = ret_addr_param_c then
346
        ret_addr_r <= conf_data_in;
347
      else
348
        ret_addr_r <= ret_addr_r;
349
      end if;
350
    end if;
351
  end process ret_addr_proc;
352
end rtl;

powered by: WebSVN 2.1.0

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