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.interface/] [udp2hibi/] [1.0/] [vhd/] [tx_ctrl.vhd] - Blame information for rev 183

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

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- Title      : Tx control block
3
-- Project    : UDP2HIBI
4
-------------------------------------------------------------------------------
5
-- File       : tx_ctrl.vhd
6
-- Author     : Jussi Nieminen  <niemin95@galapagosinkeiju.cs.tut.fi>
7
-- Last update: 2012-03-23
8
-- Platform   : 
9
-------------------------------------------------------------------------------
10
-- Description: Sub-block of udp2hibi.
11
--              Takes care of chatting with udp/ip block.
12
--              This gets data from HIBI receiver and gives it to UDP/IP.
13
--              Includes multclk-fifo and a state machine.
14
-------------------------------------------------------------------------------
15
-- Revisions  :
16
-- Date        Version  Author  Description
17
-- 2009/12/11  1.0      niemin95        Created
18
-- 2012-03-23  1.0      ege             Beautifying and commenting.
19
-------------------------------------------------------------------------------
20
 
21
library ieee;
22
use ieee.std_logic_1164.all;
23
use ieee.numeric_std.all;
24
use work.udp2hibi_pkg.all;
25
 
26
 
27
entity tx_ctrl is
28
 
29
  generic (
30
    frequency_g           : integer := 50_000_000;
31
    multiclk_fifo_depth_g : integer := 10
32
    );
33
 
34
  port (
35
    clk                 : in  std_logic;
36
    clk_udp             : in  std_logic;
37
    rst_n               : in  std_logic;
38
 
39
    -- for multiclk fifo
40
    tx_data_in          : in  std_logic_vector (udp_block_data_w_c-1 downto 0);
41
    tx_we_in            : in  std_logic;
42
    tx_full_out         : out std_logic;
43
 
44
    -- from multiclk fifo to udp/ip
45
    tx_data_out         : out std_logic_vector (udp_block_data_w_c-1 downto 0);
46
    tx_data_valid_out   : out std_logic;
47
    tx_re_in            : in  std_logic;
48
 
49
    -- other signals to udp/ip
50
    new_tx_out          : out std_logic;
51
    tx_len_out          : out std_logic_vector (tx_len_w_c-1 downto 0);
52
    dest_ip_out         : out std_logic_vector (ip_addr_w_c-1 downto 0);
53
    dest_port_out       : out std_logic_vector (udp_port_w_c-1 downto 0);
54
    source_port_out     : out std_logic_vector (udp_port_w_c-1 downto 0);
55
 
56
    -- signals to and from hibi_receiver
57
    new_tx_in           : in  std_logic;
58
    tx_len_in           : in  std_logic_vector (tx_len_w_c-1 downto 0);
59
    new_tx_ack_out      : out std_logic;
60
    timeout_in          : in  std_logic_vector (timeout_w_c-1 downto 0);
61
    timeout_to_hr_out   : out std_logic;
62
 
63
    -- signals to and from ctrl regs
64
    tx_ip_in            : in  std_logic_vector (ip_addr_w_c-1 downto 0);
65
    tx_dest_port_in     : in  std_logic_vector (udp_port_w_c-1 downto 0);
66
    tx_source_port_in   : in  std_logic_vector (udp_port_w_c-1 downto 0);
67
    timeout_release_out : out std_logic
68
    );
69
 
70
end tx_ctrl;
71
 
72
 
73
architecture rtl of tx_ctrl is
74
 
75
  component multiclk_fifo
76
    generic (
77
      re_freq_g    : integer;
78
      we_freq_g    : integer;
79
      depth_g      : integer;
80
      data_width_g : integer);
81
    port (
82
      clk_re    : in  std_logic;
83
      clk_we    : in  std_logic;
84
      rst_n     : in  std_logic;
85
      data_in   : in  std_logic_vector (data_width_g-1 downto 0);
86
      we_in     : in  std_logic;
87
      full_out  : out std_logic;
88
      one_p_out : out std_logic;
89
      re_in     : in  std_logic;
90
      data_out  : out std_logic_vector (data_width_g-1 downto 0);
91
      empty_out : out std_logic;
92
      one_d_out : out std_logic);
93
  end component;
94
 
95
 
96
  signal  new_tx_r        : std_logic;
97
  signal  tx_cnt_r        : integer range 0 to 2**(tx_len_w_c-1);
98
  subtype timeout_int is integer range 0 to 2**timeout_w_c-1;
99
  signal  timeout_cnt_r   : timeout_int;
100
  signal  timeout_value_r : timeout_int;
101
 
102
  signal tx_data_to_fifo      : std_logic_vector(udp_block_data_w_c-1 downto 0);
103
  signal tx_we_to_fifo        : std_logic;
104
  signal tx_full_from_fifo    : std_logic;
105
  signal full_to_h_receiver_r : std_logic;
106
  signal gain_tx_control_r    : std_logic;
107
  signal tx_we_local_r        : std_logic;
108
  signal empty_from_fifo      : std_logic;
109
  signal udp_ip_re_old_r      : std_logic;
110
  signal new_tx_ack_r         : std_logic;
111
 
112
  -- states:
113
  -- idle: as one might guess..
114
  -- tx: count writes to fifo, and reset timeout_cnt every time data is written
115
  -- dump: timeout, dump fake data to fifo until tx_len of data is written
116
  type   state_type is (idle, tx, dump);
117
  signal state_r : state_type;
118
 
119
-------------------------------------------------------------------------------
120
begin  -- rtl
121
-------------------------------------------------------------------------------
122
 
123
  tx_multiclk_fifo : multiclk_fifo
124
    generic map (
125
      re_freq_g    => udp_block_freq_c,
126
      we_freq_g    => frequency_g,
127
      depth_g      => multiclk_fifo_depth_g,
128
      data_width_g => udp_block_data_w_c
129
      )
130
    port map (
131
      clk_re    => clk_udp,
132
      clk_we    => clk,
133
      rst_n     => rst_n,
134
 
135
      data_in   => tx_data_to_fifo,
136
      we_in     => tx_we_to_fifo,
137
      full_out  => tx_full_from_fifo,
138
      one_p_out => open,
139
 
140
      re_in     => tx_re_in,
141
      data_out  => tx_data_out,
142
      empty_out => empty_from_fifo,
143
      one_d_out => open
144
      );
145
 
146
  tx_data_valid_out <= not empty_from_fifo;
147
 
148
  -- Inputs from ctrl-regs go directly to hibi
149
  dest_ip_out     <= tx_ip_in;
150
  dest_port_out   <= tx_dest_port_in;
151
  source_port_out <= tx_source_port_in;
152
  new_tx_out      <= new_tx_r;
153
 
154
  tx_full_out <= tx_full_from_fifo or full_to_h_receiver_r;
155
 
156
 
157
  -----------------------------------------------------------------------------
158
  -- in case of a timeout, this block has to take care of finishing the tx
159
  -- (with fake data ofcourse)
160
  -----------------------------------------------------------------------------
161
  tx_fifo_mux : process (gain_tx_control_r, tx_we_local_r, tx_we_in, tx_data_in)
162
  begin  -- process tx_fifo_mux
163
    if gain_tx_control_r = '1' then
164
      -- timeout has occured, write zeroes to fifo
165
      tx_data_to_fifo <= (others => '0');
166
      tx_we_to_fifo   <= tx_we_local_r;
167
    else
168
      -- situation normal, nothing fouled up...
169
      tx_data_to_fifo <= tx_data_in;
170
      tx_we_to_fifo   <= tx_we_in;
171
    end if;
172
  end process tx_fifo_mux;
173
 
174
  new_tx_ack_out <= new_tx_ack_r;
175
 
176
  -----------------------------------------------------------------------------
177
  --
178
  -----------------------------------------------------------------------------
179
  main : process (clk, rst_n)
180
    variable sub_from_len_v : integer range 0 to 1;
181
  begin  -- process main
182
    if rst_n = '0' then                 -- asynchronous reset (active low)
183
 
184
      tx_cnt_r        <= 0;
185
      timeout_cnt_r   <= 0;
186
      timeout_value_r <= 0;
187
      state_r         <= idle;
188
 
189
      full_to_h_receiver_r <= '0';
190
      gain_tx_control_r    <= '0';
191
      tx_we_local_r        <= '0';
192
      udp_ip_re_old_r      <= '0';
193
 
194
      timeout_release_out <= '0';
195
      timeout_to_hr_out   <= '0';
196
      new_tx_r            <= '0';
197
      tx_len_out          <= (others => '0');
198
      new_tx_ack_r        <= '0';
199
 
200
    elsif clk'event and clk = '1' then  -- rising clock edge
201
 
202
      udp_ip_re_old_r <= tx_re_in;
203
 
204
      -- default values
205
      new_tx_ack_r        <= '0';
206
      timeout_release_out <= '0';
207
      timeout_to_hr_out   <= '0';
208
      tx_we_local_r       <= '0';
209
 
210
      -- We don't know in which state we are when udp/ip starts to read, so
211
      -- clear new_tx here
212
      if new_tx_r = '1' and tx_re_in = '1' and udp_ip_re_old_r = '0' then
213
        -- Rising edge of re, clear new_tx
214
        new_tx_r <= '0';
215
      end if;
216
 
217
      case state_r is
218
 
219
        -----------------------------------------------------------------------
220
        when idle =>
221
 
222
          if new_tx_in = '1' and new_tx_ack_r = '0' then
223
            new_tx_ack_r <= '1';
224
 
225
            -- store length (in halfwords) and timeout
226
            sub_from_len_v := 0;
227
            if tx_we_in = '1' and tx_full_from_fifo = '0' then
228
              -- if new_tx comes parallel with the first write operation, we
229
              -- must subtrackt one from the tx_cnt
230
              sub_from_len_v := 1;
231
            end if;
232
            tx_cnt_r <= to_integer(unsigned(tx_len_in(tx_len_w_c-1 downto 1)))
233
                        + to_integer(unsigned(tx_len_in(0 downto 0)))
234
                        - sub_from_len_v;
235
            timeout_value_r <= to_integer(unsigned(timeout_in));
236
            timeout_cnt_r   <= 0;
237
 
238
            if to_integer(unsigned(tx_len_in)) > 2 or sub_from_len_v = 0 then
239
              -- no need to get into tx state if tx_len is 1 and the data is already
240
              -- written (in fact going to tx state would result in malfunction)
241
              state_r <= tx;
242
            end if;
243
 
244
            new_tx_r   <= '1';
245
            tx_len_out <= tx_len_in;
246
          end if;
247
 
248
 
249
          -----------------------------------------------------------------------
250
        when tx =>
251
 
252
          if tx_we_in = '1' and tx_full_from_fifo = '0' then
253
 
254
            -- reset timeout counter
255
            timeout_cnt_r <= 0;
256
 
257
            if tx_cnt_r = 1 then
258
              -- last data written
259
              state_r  <= idle;
260
              tx_cnt_r <= 0;
261
            else
262
              tx_cnt_r <= tx_cnt_r - 1;
263
            end if;
264
 
265
          elsif timeout_cnt_r = timeout_value_r then
266
 
267
            -- timeout! Fill fifo with fake data, and inform ctrl regs
268
            state_r              <= dump;
269
            timeout_release_out  <= '1';
270
            timeout_to_hr_out    <= '1';
271
            -- take control over the data line
272
            gain_tx_control_r    <= '1';
273
            full_to_h_receiver_r <= '1';
274
            timeout_cnt_r        <= 0;
275
 
276
          else
277
            -- increase timeout counter
278
            timeout_cnt_r <= timeout_cnt_r + 1;
279
          end if;
280
 
281
 
282
          -----------------------------------------------------------------------
283
        when dump =>
284
 
285
          if tx_full_from_fifo = '0' then
286
 
287
            -- write them zeroes
288
            tx_we_local_r <= '1';
289
 
290
            if tx_we_local_r = '1' then
291
 
292
              if tx_cnt_r = 1 then
293
                -- last data
294
                state_r  <= idle;
295
                tx_cnt_r <= 0;
296
 
297
                -- give fifo back to hibi_receiver
298
                gain_tx_control_r    <= '0';
299
                full_to_h_receiver_r <= '0';
300
 
301
              else
302
                tx_cnt_r <= tx_cnt_r - 1;
303
              end if;
304
            end if;
305
          end if;
306
 
307
        when others => null;
308
      end case;
309
 
310
    end if;
311
  end process main;
312
 
313
 
314
end rtl;

powered by: WebSVN 2.1.0

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