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

Subversion Repositories xenie

[/] [xenie/] [trunk/] [examples/] [Eth_example/] [src/] [hdl/] [udp_ip_10g_test_app.vhd] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 DFC
-------------------------------------------------------------------------------
2
--
3
-- (C) Copyright 2017 DFC Design, s.r.o., Brno, Czech Republic
4
-- Author: Marek Kvas (m.kvas@dspfpga.com)
5
--
6
-------------------------------------------------------------------------------
7
-- This file is part of Xenia Ethernet Example project.
8
-- 
9
-- Xenia Ethernet Example project is free software: you can 
10
-- redistribute it and/or modify it under the terms of 
11
-- the GNU Lesser General Public License as published by the Free 
12
-- Software Foundation, either version 3 of the License, or
13
-- (at your option) any later version.
14
-- 
15
-- Xenia Ethernet Example project is distributed in the hope that 
16
-- it will be useful, but WITHOUT ANY WARRANTY; without even 
17
-- the implied warranty of MERCHANTABILITY or FITNESS FOR A 
18
-- PARTICULAR PURPOSE.  See the GNU Lesser General Public License 
19
-- for more details.
20
-- 
21
-- You should have received a copy of the GNU Lesser General Public 
22
-- License along with Xenia Ethernet Example project.  If not, 
23
-- see <http://www.gnu.org/licenses/>.
24
-------------------------------------------------------------------------------
25
--
26
-- This is core demonstrates usage of udp_ip_10g core. There are two functions
27
-- integrated here.
28
--
29
-- When data come to udp port g_loopback_port. Packet is looped back with
30
-- source info used as a destination info.
31
-- 
32
-- When frame comes to udp port g_test_port, first 4 bytes are checked for
33
-- magic number. If it matches and length is higher than minimal length for
34
-- test packet, response packet is sent. Response starts with magic number and
35
-- next 4 bytes copied from incomming frame - user can use this feature to
36
-- identify response frames. 64 bit timestamp and packet counters follow.
37
-- Packet has this structure
38
--  7   6   5   4        3   2   1   0
39
-- User ID           | Magic number
40
--     64 bit long timestamp
41
-- test pkt cnt      | loopback pkt cnt
42
-- accepted tst cnt  | unknown port pkt cnt
43
-- Padding to the size of request packet
44
--
45
--
46
-------------------------------------------------------------------------------
47
 
48
 
49
library ieee;
50
use ieee.std_logic_1164.all;
51
use ieee.numeric_std.all;
52
 
53
 
54
entity udp_ip_10g_test_app is
55
   generic (
56
      g_loopback_port   : std_logic_vector(15 downto 0) := x"DFC0";
57
      g_test_port       : std_logic_vector(15 downto 0) := x"DFC1";
58
      g_net_info_port   : std_logic_vector(15 downto 0) := x"DFCC"
59
           );
60
   port (
61
      RST               : in  std_logic;
62
      CLK               : in  std_logic;
63
 
64
      -- Host information user interface
65
      HOST_MAC          : in  std_logic_vector(47 downto 0);
66
      HOST_IP           : in  std_logic_vector(31 downto 0);
67
      HOST_IP_NETMASK   : in  std_logic_vector(31 downto 0);
68
 
69
      -- TX user interface
70
      TX_DST_MAC        : out std_logic_vector(47 downto 0);
71
      TX_DST_IP         : out std_logic_vector(31 downto 0);
72
      TX_SRC_UDP        : out std_logic_vector(15 downto 0);
73
      TX_DST_UDP        : out std_logic_vector(15 downto 0);
74
 
75
      TX_FRAME_VALID    : out std_logic;
76
      TX_FRAME_RDY      : in  std_logic;
77
      TX_FRAME_LAST     : out std_logic;
78
      TX_FRAME_BE       : out std_logic_vector(7 downto 0);
79
      TX_FRAME_DATA     : out std_logic_vector(63 downto 0);
80
 
81
      -- RX user interface
82
      RX_SRC_MAC        : in  std_logic_vector(47 downto 0);
83
      RX_SRC_IP         : in  std_logic_vector(31 downto 0);
84
      RX_SRC_UDP        : in  std_logic_vector(15 downto 0);
85
      RX_DST_UDP        : in  std_logic_vector(15 downto 0);
86
 
87
      RX_FRAME_VALID    : in  std_logic;
88
      RX_FRAME_RDY      : out std_logic;
89
      RX_FRAME_LAST     : in  std_logic;
90
      RX_FRAME_BE       : in  std_logic_vector(7 downto 0);
91
      RX_FRAME_DATA     : in  std_logic_vector(63 downto 0);
92
      RX_FRAME_LENGTH   : in  std_logic_vector(15 downto 0)
93
        );
94
end entity;
95
 
96
 
97
architecture synthesis of udp_ip_10g_test_app is
98
 
99
   constant LC_TEST_MAGIC        : std_logic_vector(31 downto 0) := x"DFCDFC01";
100
   constant LC_TEST_MIN_PKT      : integer := 32;
101
 
102
 
103
   type main_fsm_type is (M_IDLE, M_LOOPBACK, M_TEST, M_TEST_RESP_DATA,
104
                          M_NET_INFO, M_DISCARD);
105
 
106
   signal main_fsm_cur              : main_fsm_type;
107
   signal main_fsm_next             : main_fsm_type;
108
   signal tx_frame_valid_i          : std_logic;
109
   signal rx_frame_rdy_i            : std_logic;
110
   signal tx_frame_data_i           : std_logic_vector(TX_FRAME_DATA'range);
111
   signal tx_frame_be_i             : std_logic_vector(TX_FRAME_BE'range);
112
   signal tx_frame_last_i           : std_logic;
113
   signal loopback_pkt_cnt_inc      : std_logic;
114
   signal test_pkt_cnt_inc          : std_logic;
115
   signal unknown_port_pkt_cnt_inc  : std_logic;
116
   signal test_pkt_accept_cnt_inc   : std_logic;
117
   signal loopback_pkt_cnt          : std_logic_vector(31 downto 0);
118
   signal test_pkt_cnt              : std_logic_vector(31 downto 0);
119
   signal unknown_port_pkt_cnt      : std_logic_vector(31 downto 0);
120
   signal test_pkt_accept_cnt       : std_logic_vector(31 downto 0);
121
 
122
   signal tstmp64_cnt               : std_logic_vector(63 downto 0);
123
 
124
   signal test_pkt_prepare          : std_logic;
125
   signal test_pkt_last             : std_logic;
126
   signal test_pkt_last_d           : std_logic;
127
   signal test_pkt_shift            : std_logic;
128
   signal net_info_pkt_prepare      : std_logic;
129
   signal net_info_pkt_last         : std_logic;
130
   signal net_info_pkt_shift        : std_logic;
131
   signal data_out_reg              : std_logic_vector(TX_FRAME_DATA'range);
132
   signal data_out_be_reg           : std_logic_vector(TX_FRAME_BE'range);
133
 
134
   type test_pkt_fsm_type is (TP_LPBK_TEST_CNTS, TP_UNKNOW_TST_ACCEPT_CNTS);
135
   signal test_pkt_fsm              : test_pkt_fsm_type;
136
 
137
   type net_info_pkt_fsm_type is (NI_MAC_ADDR, NI_IP_INFO);
138
   signal net_info_pkt_fsm          : net_info_pkt_fsm_type;
139
 
140
 
141
begin
142
 
143
   TX_DST_MAC      <= RX_SRC_MAC;
144
   TX_DST_IP       <= RX_SRC_IP;
145
   TX_DST_UDP      <= RX_SRC_UDP;
146
   TX_SRC_UDP      <= RX_DST_UDP;
147
 
148
 
149
   main_fsm_adv_proc : process(CLK)
150
   begin
151
      if rising_edge(CLK) then
152
         if RST = '1' then
153
            main_fsm_cur <= M_IDLE;
154
         else
155
            main_fsm_cur <= main_fsm_next;
156
         end if;
157
      end if;
158
   end process;
159
 
160
   main_fsm_transout_proc : process(main_fsm_cur, RX_FRAME_VALID, RX_DST_UDP,
161
                             RX_FRAME_DATA, RX_FRAME_BE, RX_FRAME_LAST,
162
                             TX_FRAME_RDY, data_out_reg, data_out_be_reg,
163
                             test_pkt_last, test_pkt_last_d,
164
                             RX_FRAME_LENGTH, net_info_pkt_last)
165
   begin
166
      main_fsm_next <= main_fsm_cur;
167
      tx_frame_valid_i <= '0';
168
      rx_frame_rdy_i <= '0';
169
 
170
      tx_frame_data_i   <= RX_FRAME_DATA;
171
      tx_frame_be_i     <= RX_FRAME_BE;
172
      tx_frame_last_i   <= RX_FRAME_LAST;
173
 
174
 
175
      loopback_pkt_cnt_inc <= '0';
176
      test_pkt_cnt_inc <= '0';
177
      unknown_port_pkt_cnt_inc <= '0';
178
      test_pkt_accept_cnt_inc <= '0';
179
 
180
      test_pkt_prepare <= '0';
181
      test_pkt_shift <= '0';
182
 
183
      net_info_pkt_prepare <= '0';
184
      net_info_pkt_shift <= '0';
185
 
186
      case main_fsm_cur is
187
         when M_IDLE =>
188
            if RX_FRAME_VALID = '1' then
189
               case RX_DST_UDP is
190
                  when g_loopback_port =>
191
                     main_fsm_next <= M_LOOPBACK;
192
                     loopback_pkt_cnt_inc <= '1';
193
                  when g_test_port =>
194
                     if RX_FRAME_DATA(31 downto 0) = LC_TEST_MAGIC and
195
                        unsigned(RX_FRAME_LENGTH) >= LC_TEST_MIN_PKT then
196
                        test_pkt_accept_cnt_inc <= '1';
197
                        main_fsm_next <= M_TEST;
198
                     else
199
                        main_fsm_next <= M_DISCARD;
200
                     end if;
201
                     test_pkt_cnt_inc <= '1';
202
                  when g_net_info_port =>
203
                     main_fsm_next <= M_NET_INFO;
204
                     net_info_pkt_prepare <= '1';
205
                  when others =>
206
                     main_fsm_next <= M_DISCARD;
207
                     unknown_port_pkt_cnt_inc <= '1';
208
               end case;
209
            end if;
210
         when M_LOOPBACK =>
211
            tx_frame_valid_i <= '1'; -- RX is guaranteed to have all data ready
212
            rx_frame_rdy_i <= TX_FRAME_RDY;
213
            if RX_FRAME_LAST = '1' and TX_FRAME_RDY = '1' then
214
               -- last word was accepted by tx
215
               main_fsm_next <= M_IDLE;
216
            end if;
217
         when M_TEST =>
218
            -- Copy magic and user id to response
219
            tx_frame_valid_i <= '1';
220
            if TX_FRAME_RDY = '1' then
221
               rx_frame_rdy_i <= '1';
222
               main_fsm_next <= M_TEST_RESP_DATA;
223
               test_pkt_prepare <= '1';
224
            end if;
225
         when M_TEST_RESP_DATA =>
226
            -- We can be sure that RX data are longer than inserted header
227
            -- as we tested it in IDLE state
228
            if test_pkt_last = '0' or test_pkt_last_d = '0' then
229
               tx_frame_data_i <= data_out_reg; -- send data from temporary register
230
            else
231
               tx_frame_data_i <= RX_FRAME_DATA; -- send data from request
232
            end if;
233
            tx_frame_be_i <= RX_FRAME_BE;
234
            tx_frame_valid_i <= '1'; -- we have always data ready
235
            tx_frame_last_i <= RX_FRAME_LAST;
236
            rx_frame_rdy_i <= TX_FRAME_RDY; -- drain unused rx data
237
            test_pkt_shift <= TX_FRAME_RDY;
238
 
239
            -- Sent frame shall be of the same length as the received one
240
            if TX_FRAME_RDY = '1' and RX_FRAME_LAST = '1' then
241
               main_fsm_next <= M_IDLE;
242
            end if;
243
         when M_NET_INFO =>
244
            tx_frame_data_i <= data_out_reg; -- send data from temporary register
245
            tx_frame_be_i <= data_out_be_reg;
246
            tx_frame_valid_i <= '1';
247
            tx_frame_last_i <= net_info_pkt_last;
248
            net_info_pkt_shift <= TX_FRAME_RDY;
249
            if TX_FRAME_RDY = '1' and net_info_pkt_last = '1' then
250
               -- Discard request packet
251
               main_fsm_next <= M_DISCARD;
252
            end if;
253
         when M_DISCARD =>
254
            rx_frame_rdy_i <= RX_FRAME_VALID;
255
            if RX_FRAME_LAST = '1' or RX_FRAME_VALID = '0' then
256
               main_fsm_next <= M_IDLE;
257
            end if;
258
      end case;
259
   end process;
260
 
261
   test_net_info_pkt_build_proc : process(CLK)
262
   begin
263
      if rising_edge(CLK) then
264
         if test_pkt_prepare = '1' then
265
            test_pkt_last <= '0';
266
            data_out_reg <= tstmp64_cnt;
267
            data_out_be_reg <= (others => '1');
268
            test_pkt_fsm <= TP_LPBK_TEST_CNTS;
269
         elsif test_pkt_shift = '1' then
270
            case test_pkt_fsm is
271
               when TP_LPBK_TEST_CNTS =>
272
                  data_out_reg <= test_pkt_cnt & loopback_pkt_cnt;
273
                  test_pkt_fsm <= TP_UNKNOW_TST_ACCEPT_CNTS;
274
               when TP_UNKNOW_TST_ACCEPT_CNTS =>
275
                  data_out_reg <= test_pkt_accept_cnt &
276
                                  unknown_port_pkt_cnt;
277
                  test_pkt_last <= '1';
278
            end case;
279
            test_pkt_last_d <= test_pkt_last;
280
         end if;
281
 
282
         if net_info_pkt_prepare = '1' then
283
            net_info_pkt_last <= '0';
284
            data_out_reg <= tstmp64_cnt;
285
            data_out_be_reg <= (others => '1');
286
            net_info_pkt_fsm <= NI_MAC_ADDR;
287
         elsif net_info_pkt_shift = '1' then
288
            case net_info_pkt_fsm is
289
               when NI_MAC_ADDR =>
290
                  data_out_reg <= x"0000" & HOST_MAC;
291
                  net_info_pkt_fsm <= NI_IP_INFO;
292
               when NI_IP_INFO =>
293
                  data_out_reg <= HOST_IP_NETMASK & HOST_IP;
294
                  net_info_pkt_last <= '1';
295
            end case;
296
         end if;
297
      end if;
298
   end process;
299
 
300
   counters_proc : process(CLK)
301
   begin
302
      if rising_edge(CLK) then
303
         if loopback_pkt_cnt_inc = '1' then
304
            loopback_pkt_cnt <= std_logic_vector(unsigned(loopback_pkt_cnt) + 1);
305
         end if;
306
 
307
         if test_pkt_cnt_inc = '1' then
308
            test_pkt_cnt <= std_logic_vector(unsigned(test_pkt_cnt) + 1);
309
         end if;
310
 
311
         if unknown_port_pkt_cnt_inc = '1' then
312
            unknown_port_pkt_cnt <= std_logic_vector(unsigned(
313
                                                      unknown_port_pkt_cnt) + 1);
314
         end if;
315
 
316
         if test_pkt_accept_cnt_inc = '1' then
317
            test_pkt_accept_cnt <= std_logic_vector(unsigned(
318
                                                      test_pkt_accept_cnt) + 1);
319
         end if;
320
 
321
         -- timestamp counter
322
         tstmp64_cnt <= std_logic_vector(unsigned(tstmp64_cnt) + 1);
323
 
324
         if RST = '1' then
325
            tstmp64_cnt          <= (others => '0');
326
            test_pkt_accept_cnt  <= (others => '0');
327
            unknown_port_pkt_cnt <= (others => '0');
328
            test_pkt_cnt         <= (others => '0');
329
            loopback_pkt_cnt     <= (others => '0');
330
         end if;
331
 
332
      end if;
333
   end process;
334
 
335
 
336
   TX_FRAME_VALID <= tx_frame_valid_i;
337
   TX_FRAME_LAST  <= tx_frame_last_i;
338
   TX_FRAME_BE    <= tx_frame_be_i;
339
   TX_FRAME_DATA  <= tx_frame_data_i;
340
   RX_FRAME_RDY   <= rx_frame_rdy_i;
341
 
342
end architecture;
343
 
344
 
345
 
346
 
347
 
348
 
349
 

powered by: WebSVN 2.1.0

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