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

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [Altera/] [ip.hwp.cpu/] [nios_ii_sram/] [1.0/] [hdl/] [ip/] [hpd_tx_control.vhd] - Blame information for rev 147

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 147 lanttu
-------------------------------------------------------------------------------
2
-- Title      : HIBI PE DMA - tx controller
3
-- Project    : 
4
-------------------------------------------------------------------------------
5
-- File       : hpd_tx_control.vhd
6
-- Author     : kulmala3
7
-- Created    : 2012-01-10
8
-- Last update: 2012-02-08
9
-- Description: 
10
--
11
-------------------------------------------------------------------------------
12
-- Copyright (c) 2005 
13
-- 
14
-------------------------------------------------------------------------------
15
-- Revisions  :
16
-- Date        Version  Author  Description
17
-- 30.03.2005  1.0      AK      Created
18
-------------------------------------------------------------------------------
19
 
20
library ieee;
21
use ieee.std_logic_1164.all;
22
use ieee.numeric_std.all;
23
use ieee.std_logic_unsigned.all;
24
 
25
entity hpd_tx_control is
26
 
27
  generic (
28
 
29
    data_width_g  : integer := 32;
30
    addr_width_g  : integer := 32;
31
    words_width_g : integer := 16);
32
 
33
  port (
34
    clk                     : in  std_logic;
35
    rst_n                   : in  std_logic;
36
    -- Avalon master read interface
37
    avalon_addr_out         : out std_logic_vector(addr_width_g-1 downto 0);
38
    avalon_re_out           : out std_logic;
39
    avalon_readdata_in      : in  std_logic_vector(data_width_g-1 downto 0);
40
    avalon_waitrequest_in   : in  std_logic;
41
    avalon_readdatavalid_in : in  std_logic;
42
 
43
    -- hibi write interface
44
    hibi_data_out : out std_logic_vector(data_width_g-1 downto 0);
45
    hibi_av_out   : out std_logic;
46
    hibi_full_in  : in  std_logic;
47
    hibi_comm_out : out std_logic_vector(4 downto 0);
48
    hibi_we_out   : out std_logic;
49
 
50
    -- DMA conf interface
51
    tx_start_in        : in  std_logic;
52
    tx_status_done_out : out std_logic;
53
    tx_comm_in         : in  std_logic_vector(4 downto 0);
54
    tx_hibi_addr_in    : in  std_logic_vector(addr_width_g-1 downto 0);
55
    tx_ram_addr_in     : in  std_logic_vector(addr_width_g-1 downto 0);
56
    tx_words_in        : in  std_logic_vector(words_width_g-1 downto 0)
57
    );
58
 
59
end hpd_tx_control;
60
 
61
architecture rtl of hpd_tx_control is
62
 
63
  type     control_states is (idle, transmit_addr, transmit, hfull);
64
  signal   control_r     : control_states;
65
  constant addr_offset_c : integer := data_width_g/8;
66
 
67
  signal addr_cnt_en     : std_logic;
68
  signal addr_cnt_value  : std_logic_vector(addr_width_g-1 downto 0);
69
  signal addr_cnt_load   : std_logic;
70
  signal addr_r            : std_logic_vector(addr_width_g-1 downto 0);
71
  signal words_cnt_en      : std_logic;
72
  signal words_cnt_value : std_logic_vector(addr_width_g-1 downto 0);
73
  signal words_cnt_load    : std_logic;
74
  signal words_r           : std_logic_vector(addr_width_g-1 downto 0);
75
 
76
  signal addr_words_eq : std_logic;
77
 
78
  signal addr_to_stop : std_logic_vector(addr_width_g-1 downto 0);
79
  signal avalon_re    : std_logic;
80
  signal start_re_r     : std_logic;
81
 
82
  signal hibi_write_addr_r : std_logic;
83
  signal data_src_sel      : std_logic;
84
  signal hibi_we         : std_logic;
85
  signal hibi_stop_we_r    : std_logic;
86
 
87
 
88
begin  -- rtl
89
 
90
  -----------------------------------------------------------------------------
91
  -- 1) waitrequest affects the data reading
92
  -- 2) readdatavalid data write to hibi
93
  -- 3) avalon side read must control the amount of data
94
  -- 4) whenever readdatavalid is asserted, data is written to HIBI
95
  -- 5) HIBI full is problematic. A counter must be added to see from which
96
  --    address we have succesfully read the data so far. We cannot
97
  --    save the data to register, because we are unaware of the latency.
98
  --    So when full comes, the read process from avalon must be started
99
  --    again.
100
  -- 6) write and read signals should be asynchronously controlled by
101
  --    signals from hibi and avalon in order to react as fast as possible.
102
  -- 7) after full the write should be ceased. readdatavalid from older data
103
  --    should be taken care of. Write continues only after read enable has
104
  --    been asserted again?
105
  -- 8) read from avalon must proceed as fast as possible. for example,
106
  --    start already when writing address to hibi. (at least one clock
107
  --    cycle latency expected, should be safe). Or after full.
108
  -- 9) data to hibi comes from either register input (address) or
109
  --    straight from the memory. mux is needed.
110
  -----------------------------------------------------------------------------
111
 
112
  hibi_comm_out   <= tx_comm_in;
113
  avalon_addr_out <= addr_r;
114
 
115
  addr_cnt_s : process (clk, rst_n)
116
  begin  -- process addr_cnt
117
    if rst_n = '0' then                 -- asynchronous reset (active low)
118
      addr_r <= (others => '0');
119
    elsif clk'event and clk = '1' then  -- rising clock edge
120
      if addr_cnt_en = '1' then
121
        addr_r <= addr_r +
122
                  std_logic_vector(to_unsigned(addr_offset_c, addr_width_g));
123
      elsif addr_cnt_load = '1' then
124
        addr_r <= addr_cnt_value;
125
      end if;
126
    end if;
127
  end process addr_cnt_s;
128
 
129
 
130
  addr_cnt_load <= (tx_start_in or hibi_full_in);
131
 
132
  addr_cnt : process (tx_ram_addr_in, words_r, tx_start_in)
133
  begin  -- process addr_cnt
134
    if tx_start_in = '1' then
135
      -- addr from input
136
      addr_cnt_value <= tx_ram_addr_in;
137
    else
138
      -- addr from counter
139
      addr_cnt_value <= words_r;
140
    end if;
141
  end process addr_cnt;
142
 
143
 
144
  words_cnt : process (clk, rst_n)
145
  begin
146
    if rst_n = '0' then                 -- asynchronous reset (active low)
147
      words_r <= (others => '0');
148
    elsif clk'event and clk = '1' then  -- rising clock edge
149
      if words_cnt_en = '1' then
150
        words_r <= words_r +
151
                   std_logic_vector(to_unsigned(addr_offset_c, addr_width_g));
152
      elsif words_cnt_load = '1' then
153
        words_r <= words_cnt_value;
154
      end if;
155
    end if;
156
  end process words_cnt;
157
 
158
  -- words counted only when data is written
159
  words_cnt_en <= hibi_we and (not data_src_sel);
160
 
161
  -- hibi_we depends on readdatavalid and full + control signal for
162
  -- address writing
163
  -- start address writing right when the signal comes in.
164
  -- no old readdatavalids should be written if full is short.
165
  hibi_we_out <= hibi_we;
166
  hibi_we <= ((data_src_sel) or
167
                (avalon_readdatavalid_in and (not hibi_stop_we_r)))
168
               and (not hibi_full_in);
169
 
170
  data_src_sel <= tx_start_in or hibi_write_addr_r;
171
  hibi_av_out  <= data_src_sel;
172
 
173
  addr_data : process (tx_hibi_addr_in, avalon_readdata_in, data_src_sel)
174
  begin  -- process addr_data
175
    if data_src_sel = '1' then
176
      hibi_data_out                          <= (others => '0');
177
      hibi_data_out(addr_width_g-1 downto 0) <= tx_hibi_addr_in;
178
    else
179
      hibi_data_out <= avalon_readdata_in;
180
    end if;
181
  end process addr_data;
182
 
183
  -- if we're reading and not forced to wait,
184
  -- increase the address. we want to cease reading if hibi goes full
185
  -- (reload address)
186
  addr_cnt_en <= (avalon_re and (not avalon_waitrequest_in)) and
187
                   (not hibi_full_in);
188
  avalon_re_out <= avalon_re;
189
  -- read enable depends on the words transferred, if a 
190
  -- transmission is ongoing. shoot as soon as possible,
191
  -- whenever new transmission is assigned.
192
  avalon_re   <= start_re_r;
193
 
194
  comparison : process (addr_r, addr_to_stop)
195
  begin  -- process comparison
196
    if addr_r = addr_to_stop then
197
      addr_words_eq <= '1';
198
    else
199
      addr_words_eq <= '0';
200
    end if;
201
  end process comparison;
202
 
203
  addr_to_stop_p : process (tx_words_in, tx_ram_addr_in)
204
  begin  -- process addr_to_stop
205
    addr_to_stop <= tx_ram_addr_in + std_logic_vector(
206
      resize(unsigned(tx_words_in)*addr_offset_c, addr_width_g));
207
  end process addr_to_stop_p;
208
 
209
  words_cnt_value <= tx_ram_addr_in;
210
  words_cnt_load  <= tx_start_in;
211
 
212
  main : process (clk, rst_n)
213
  begin  -- process main
214
    if rst_n = '0' then                 -- asynchronous reset (active low)
215
      control_r          <= idle;
216
      start_re_r         <= '0';
217
      hibi_write_addr_r  <= '0';
218
      tx_status_done_out <= '1';
219
      hibi_stop_we_r     <= '0';
220
 
221
    elsif clk'event and clk = '1' then  -- rising clock edge
222
      case control_r is
223
        when idle =>
224
          hibi_write_addr_r  <= '0';
225
          start_re_r         <= '0';
226
          tx_status_done_out <= '1';
227
          hibi_stop_we_r     <= '1';
228
 
229
          if tx_start_in = '1' then
230
            -- avalon read address
231
            -- address which contents written to hibi
232
            tx_status_done_out <= '0';
233
            hibi_stop_we_r     <= '0';
234
 
235
            if hibi_full_in = '0' then
236
              -- address will be transferred in this clock cycle
237
              control_r  <= transmit;
238
              start_re_r <= '1';
239
            else
240
              hibi_write_addr_r <= '1';
241
              control_r         <= transmit_addr;
242
            end if;
243
          end if;
244
 
245
        when transmit_addr =>
246
          -- if we're here, hibi was full
247
          if hibi_full_in = '0' then
248
            -- we wrote the addr
249
            start_re_r        <= '1';
250
            control_r         <= transmit;
251
            hibi_write_addr_r <= '0';
252
          else
253
            start_re_r        <= '0';
254
            control_r         <= transmit_addr;
255
            hibi_write_addr_r <= '1';
256
          end if;
257
 
258
        when transmit =>
259
          if hibi_full_in = '1' then
260
            start_re_r     <= '0';
261
            control_r      <= hfull;
262
            hibi_stop_we_r <= '1';
263
          else
264
            start_re_r     <= '1';
265
            hibi_stop_we_r <= '0';
266
            control_r      <= transmit;
267
          end if;
268
 
269
--          if addr_words_eq = '1' and hibi_full_in = '0' then
270
          if addr_words_eq = '1' and hibi_we = '1' then
271
            control_r          <= idle;
272
            -- stopped transferring
273
            tx_status_done_out <= '1';
274
            hibi_stop_we_r     <= '1';
275
          end if;
276
 
277
        when hfull =>
278
          if hibi_full_in = '0' and avalon_readdatavalid_in = '0' then
279
            -- datavalid has to go down before proceed.
280
            -- so we make sure that no invalid data is written
281
            -- when there's a short full.
282
            start_re_r     <= '1';
283
            hibi_stop_we_r <= '0';
284
            control_r      <= transmit;
285
          else
286
            start_re_r     <= '0';
287
            hibi_stop_we_r <= '1';
288
            control_r      <= hfull;
289
          end if;
290
 
291
        when others => null;
292
      end case;
293
    end if;
294
  end process main;
295
 
296
end rtl;

powered by: WebSVN 2.1.0

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