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

Subversion Repositories udp_ipv4_for_10g_ethernet

[/] [udp_ipv4_for_10g_ethernet/] [trunk/] [src/] [hdl/] [frame_tx_if.vhd] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 DFC
-------------------------------------------------------------------------------
2
--
3
-- (C) Copyright 2017 DFC Design, s.r.o., Brno, Czech Republic
4
-- Author: Marek Kvas (m.kvas@dfcdesign.cz)
5
--
6
-------------------------------------------------------------------------------
7
-- This file is part of UDP/IPv4 for 10 G Ethernet core.
8
-- 
9
-- UDP/IPv4 for 10 G Ethernet core 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
-- UDP/IPv4 for 10 G Ethernet core 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 UDP/IPv4 for 10 G Ethernet core.  If not, 
23
-- see <http://www.gnu.org/licenses/>.
24
-------------------------------------------------------------------------------
25
--
26
-- This module adapts TX interface of frame_gen module to be closer to
27
-- the one used by RX path. It adds FIFO to TX data path so users don't
28
-- have to provide data in each cycle and length doesn't have to be known
29
-- in advance.
30
--
31
--
32
-- Two FIFOs are used. One to store data from user, the other one to store
33
-- tags currently consisting of length of frame to be sent only.
34
-- FIFOs are placed outside this module. They must be FWFT.
35
--
36
-- It is aimed to be used together with frame_gen_fifo_if that sits on the 
37
-- other side of FIFOs and interfaces them to the frame_gen module.
38
--
39
-------------------------------------------------------------------------------
40
 
41
library ieee;
42
use ieee.std_logic_1164.all;
43
use ieee.numeric_std.all;
44
 
45
library work;
46
use work.frame_pkg.all;
47
 
48
Library UNISIM;
49
use UNISIM.vcomponents.all;
50
 
51
 
52
entity frame_tx_if is
53
   port (
54
      CLK            : in  std_logic;
55
      RST            : in  std_logic;
56
 
57
      DST_MAC        : in  mac_addr_type;
58
      DST_IP         : in  ip_addr_type;
59
      SRC_UDP        : in  udp_port_type;
60
      DST_UDP        : in  udp_port_type;
61
 
62
      FRAME_VALID    : in  std_logic;
63
      FRAME_RDY      : out std_logic;
64
      FRAME_LAST     : in  std_logic;
65
      FRAME_BE       : in  std_logic_vector(7 downto 0);
66
      FRAME_DATA     : in  data64_port_type;
67
 
68
      -- Tag and data fifos
69
      DFIFO_DATA     : out txi_dfifo_data_type;
70
      DFIFO_WR_EN    : out std_logic;
71
      DFIFO_FULL     : in  std_logic;
72
 
73
      TFIFO_DATA     : out txi_tfifo_data_type;
74
      TFIFO_WR_EN    : out std_logic;
75
      TFIFO_FULL     : in  std_logic
76
        );
77
end entity;
78
 
79
 
80
 
81
architecture synthesis of frame_tx_if is
82
 
83
 
84
   type in_fsm_type is (I_IDLE_DI0, I_DI1, I_DATA, I_TAG);
85
   signal in_fsm_cur    : in_fsm_type;
86
   signal in_fsm_next   : in_fsm_type;
87
 
88
   signal frame_rdy_i   : std_logic;
89
   signal dfifo_wr_en_i : std_logic;
90
   signal tfifo_wr_en_i : std_logic;
91
   signal length_cnt_en : std_logic;
92
   signal length_cnt    : unsigned(txi_tfifo_data_type'length - 1 downto 0);
93
 
94
 
95
begin
96
 
97
   -- FSM controlling insertion of data into FIFOs
98
   in_fsm_adv_proc : process(CLK)
99
   begin
100
      if rising_edge(CLK) then
101
         if RST = '1' then
102
            in_fsm_cur <= I_IDLE_DI0;
103
         else
104
            in_fsm_cur <= in_fsm_next;
105
         end if;
106
      end if;
107
   end process;
108
 
109
 
110
   in_fsm_trans_out_proc : process(in_fsm_cur, DFIFO_FULL, TFIFO_FULL,
111
                              DST_MAC, DST_UDP, DST_IP, SRC_UDP,
112
                              FRAME_VALID, FRAME_LAST, FRAME_BE, FRAME_DATA)
113
   begin
114
      in_fsm_next <= in_fsm_cur;
115
      frame_rdy_i <= not DFIFO_FULL;
116
      dfifo_wr_en_i <= '0';
117
      tfifo_wr_en_i <= '0';
118
      DFIFO_DATA <= FRAME_BE & FRAME_DATA;
119
      length_cnt_en <= '0';
120
 
121
      case in_fsm_cur is
122
         when I_IDLE_DI0 =>
123
            frame_rdy_i <= '0';
124
            DFIFO_DATA <= x"000000" & DST_IP & SRC_UDP;
125
            if FRAME_VALID = '1' and DFIFO_FULL = '0' then
126
               in_fsm_next <= I_DI1;
127
               dfifo_wr_en_i <= '1';
128
            end if;
129
         when I_DI1 =>
130
            frame_rdy_i <= '0';
131
            DFIFO_DATA <= x"00" & DST_MAC & DST_UDP;
132
            if DFIFO_FULL = '0' then
133
               in_fsm_next <= I_DATA;
134
               dfifo_wr_en_i <= '1';
135
            end if;
136
         when I_DATA =>
137
            length_cnt_en <= '1';
138
            -- In case of empty packet this inserts empty word into the fifo
139
            -- frame_gen_fifo_if is responsible for discarding it
140
            dfifo_wr_en_i <= not DFIFO_FULL and FRAME_VALID;
141
            if FRAME_LAST = '1' and FRAME_VALID = '1' and DFIFO_FULL = '0' then
142
               in_fsm_next <= I_TAG;
143
            end if;
144
         when I_TAG =>
145
            frame_rdy_i <= '0';
146
            if TFIFO_FULL = '0' then
147
               tfifo_wr_en_i <= '1';
148
               in_fsm_next <= I_IDLE_DI0;
149
            end if;
150
         when others =>
151
            in_fsm_next <= I_TAG;
152
      end case;
153
   end process;
154
 
155
   -- Count written bytes to determine length;
156
   length_proc : process(CLK)
157
   begin
158
      if rising_edge(CLK) then
159
         if length_cnt_en  = '1' then
160
            if dfifo_wr_en_i = '1' then
161
               if FRAME_LAST = '0' then
162
                  length_cnt <= length_cnt + 8;
163
               else
164
                  case (FRAME_BE) is
165
                     when "11111111" => length_cnt <= length_cnt + 8;
166
                     when "01111111" => length_cnt <= length_cnt + 7;
167
                     when "00111111" => length_cnt <= length_cnt + 6;
168
                     when "00011111" => length_cnt <= length_cnt + 5;
169
                     when "00001111" => length_cnt <= length_cnt + 4;
170
                     when "00000111" => length_cnt <= length_cnt + 3;
171
                     when "00000011" => length_cnt <= length_cnt + 2;
172
                     when "00000001" => length_cnt <= length_cnt + 1;
173
                     when "00000000" => length_cnt <= length_cnt + 0;
174
                     when others => length_cnt <= length_cnt + 8;
175
                  end case;
176
               end if;
177
            end if;
178
         else
179
            length_cnt <= (others => '0');
180
         end if;
181
      end if;
182
   end process;
183
 
184
 
185
   FRAME_RDY <= frame_rdy_i;
186
   DFIFO_WR_EN <= dfifo_wr_en_i;
187
   TFIFO_WR_EN <= tfifo_wr_en_i;
188
   TFIFO_DATA <= std_logic_vector(length_cnt);
189
end architecture;

powered by: WebSVN 2.1.0

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