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_wr_port.vhd] - Blame information for rev 145

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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