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

Subversion Repositories xenie

[/] [xenie/] [trunk/] [examples/] [Eth_example/] [ip_repo/] [udp_ip_10g/] [src/] [hdl/] [frame_rx_if.vhd] - Rev 4

Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
--
-- (C) Copyright 2017 DFC Design, s.r.o., Brno, Czech Republic
-- Author: Marek Kvas (m.kvas@dfcdesign.cz)
--
-------------------------------------------------------------------------------
-- This file is part of UDP/IPv4 for 10 G Ethernet core.
-- 
-- UDP/IPv4 for 10 G Ethernet core is free software: you can 
-- redistribute it and/or modify it under the terms of 
-- the GNU Lesser General Public License as published by the Free 
-- Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
-- 
-- UDP/IPv4 for 10 G Ethernet core is distributed in the hope that 
-- it will be useful, but WITHOUT ANY WARRANTY; without even 
-- the implied warranty of MERCHANTABILITY or FITNESS FOR A 
-- PARTICULAR PURPOSE.  See the GNU Lesser General Public License 
-- for more details.
-- 
-- You should have received a copy of the GNU Lesser General Public 
-- License along with UDP/IPv4 for 10 G Ethernet core.  If not, 
-- see <http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------------
--
-- This module sits on outputs of tag and data fifos and translates them
-- to easily understandable interface.
--
--
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library work;
use work.frame_pkg.all;
 
Library UNISIM;
use UNISIM.vcomponents.all;
 
 
entity frame_rx_if is
   port (
      RST            : in  std_logic;
      CLK            : in  std_logic;
 
      FRAME_VALID    : out std_logic;
      FRAME_RD_EN    : in  std_logic;
      FRAME_LENGTH   : out std_logic_vector(C_FP_TAG_LENGTH_BITLEN - 1 downto 0);
      FRAME_LAST     : out std_logic;
      FRAME_BE       : out std_logic_vector(7 downto 0);
      FRAME_DATA     : out data64_port_type;
      SRC_MAC        : out mac_addr_type;
      SRC_IP         : out ip_addr_type;
      SRC_UDP        : out udp_port_type;
      DST_UDP        : out udp_port_type;
 
 
      -- Tag and data fifos
      DFIFO_DATA     : in  fp_dfifo_data_type;
      DFIFO_RD_EN    : out std_logic;
      DFIFO_EMPTY    : in  std_logic;
 
      TFIFO_DATA     : in  fp_tfifo_data_type;
      TFIFO_RD_EN    : out std_logic;
      TFIFO_EMPTY    : in  std_logic
        );
end entity;
 
 
 
 
architecture synthesis of frame_rx_if is
 
   constant LC_RI_LENGTH_POS  : integer := 0;
   constant LC_RI_DST_UDP_POS : integer := 
                                 LC_RI_LENGTH_POS + C_FP_TAG_LENGTH_BITLEN;
   constant LC_RI_SRC_UDP_POS : integer := 
                                 LC_RI_DST_UDP_POS + udp_port_type'length;
   constant LC_RI_SRC_IP_POS  : integer := 
                                 LC_RI_SRC_UDP_POS + udp_port_type'length;
   constant LC_RI_SRC_MAC_POS : integer := 
                                 LC_RI_SRC_IP_POS + ip_addr_type'length;
 
 
 
   -- Main FSM 
   type main_fsm_type is (M_WTAG, M_DATA, M_DISCARD);
   signal main_fsm_cur     : main_fsm_type;
   signal main_fsm_next    : main_fsm_type;
 
   -- FSM control signals
   signal load_tag_info       : std_logic;
   signal load_ret_info       : std_logic;
   signal load_discard_info   : std_logic;
   signal dfifo_rd_en_discard : std_logic;
   signal last_word           : std_logic;
 
 
   signal frame_length_i      : std_logic_vector(FRAME_LENGTH'range);
   signal data_cnt            : unsigned(FRAME_LENGTH'range);
 
   signal frame_valid_i       : std_logic;
 
   -- Internal variant of output signal
   signal tfifo_rd_en_i    : std_logic;
   signal dfifo_rd_en_i    : std_logic;
 
   -- Decomposed tag fifo
   signal tfifo_length     : std_logic_vector(C_FP_TAG_LENGTH_BITLEN - 1 
                                                                     downto 0);
   signal tfifo_flags      : std_logic_vector(C_FP_TAG_FLAGS_BITLEN - 1 
                                                                     downto 0);
   signal tfifo_return_info: std_logic_vector(C_FP_TAG_RET_INFO_LENGTH_BITLEN -1
                                                                     downto 0);
   signal return_info      : std_logic_vector(
                              4*C_FP_TAG_RET_INFO_LENGTH_BITLEN-1 downto 0);
 
   -- Decompose data fifo
   signal dfifo_rdata      : data64_port_type;
   signal dfifo_be         : std_logic_vector(7 downto 0);
 
begin
 
      -- Decompose fifos
   tfifo_length <= TFIFO_DATA(C_FP_TAG_LENGTH_BITLEN - 1 downto 0);
   tfifo_return_info <= TFIFO_DATA(C_FP_TAG_RET_INFO_LENGTH_BITLEN - 1
                                                 downto 0);
   tfifo_flags  <= TFIFO_DATA(TFIFO_DATA'left
                        downto C_FP_TAG_RET_INFO_LENGTH_BITLEN);
 
 
   dfifo_rdata <= DFIFO_DATA(dfifo_rdata'range);
   dfifo_be <= DFIFO_DATA(DFIFO_DATA'left downto dfifo_rdata'length);
 
   -- Main FSM
   main_fsm_adv_proc : process (RST, CLK)
   begin
      if RST = '1' then
         main_fsm_cur <= M_WTAG;
      elsif rising_edge(CLK) then
         main_fsm_cur <= main_fsm_next;
      end if;
   end process;
 
   main_fsm_trans_out_proc : process (main_fsm_cur, TFIFO_EMPTY, tfifo_flags,
                                      last_word, dfifo_rd_en_i)
   begin
 
      load_tag_info <= '0';
      load_discard_info <= '0';
      dfifo_rd_en_discard <= '0';
      tfifo_rd_en_i <= '0';
      load_ret_info <= '0';
      frame_valid_i <= '0';
 
      main_fsm_next <= main_fsm_cur;
      case main_fsm_cur is
         when M_WTAG =>
            if TFIFO_EMPTY = '0' then
               tfifo_rd_en_i <= '1';
               case tfifo_flags is
                  when C_FP_TAG_UDP =>
                     main_fsm_next <= M_DATA;
                     load_tag_info <= '1';
                  when C_FP_TAG_RETINF =>
                     load_ret_info <= '1';
                  when C_FP_TAG_DISCARD =>
                     load_discard_info <= '1';
                     main_fsm_next <= M_DISCARD;
                  when others =>
                     load_discard_info <= '1';
                     main_fsm_next <= M_DISCARD;
               end case;
            end if;
         when M_DATA =>
            frame_valid_i <= '1';
            if last_word = '1' and dfifo_rd_en_i = '1' then
               main_fsm_next <= M_WTAG;
            end if;
         when M_DISCARD =>
            dfifo_rd_en_discard <= '1';
            if last_word = '1' then
               main_fsm_next <= M_WTAG;
            end if;
         when others =>
            main_fsm_next <= M_WTAG;
      end case;
 
   end process;
 
 
   -- Count down packet len
   data_cnt_proc : process (RST, CLK)
      variable len : unsigned(tfifo_length'range);
   begin
      if RST = '1' then
         data_cnt <= (others => '0');
         last_word <= '0';
      elsif rising_edge(CLK) then
         if load_tag_info = '1' or
            load_discard_info = '1' then
            len := unsigned(tfifo_length);
            data_cnt <= len;
            if len <= 8 then
               last_word <= '1';
            else
               last_word <= '0';
            end if;
         elsif dfifo_rd_en_i = '1' then
            last_word <= '0';
            if data_cnt > 8 then
               data_cnt <= data_cnt - 8;
               if data_cnt <= 16 then
                  last_word <= '1';
               end if;
            else
               data_cnt <= (others => '0');
            end if;
         end if;
      end if;
   end process;
 
   -- Register return info
   ret_info_reg_proc : process(CLK)
   begin
      if rising_edge(CLK) then
         if load_ret_info = '1' or load_tag_info = '1' then
            for i in return_info'length/C_FP_TAG_RET_INFO_LENGTH_BITLEN 
                           downto 2 loop             
               return_info(i * C_FP_TAG_RET_INFO_LENGTH_BITLEN - 1 downto
                           (i-1) * C_FP_TAG_RET_INFO_LENGTH_BITLEN ) <= 
               return_info((i-1) * C_FP_TAG_RET_INFO_LENGTH_BITLEN - 1 downto
                           (i-2) * C_FP_TAG_RET_INFO_LENGTH_BITLEN );
            end loop;
            return_info(C_FP_TAG_RET_INFO_LENGTH_BITLEN - 1 downto 0) <=
               tfifo_return_info;
         end if;
      end if;
   end process;
 
   dfifo_rd_en_i <= '1' when dfifo_rd_en_discard = '1' or
                    (frame_valid_i = '1' and FRAME_RD_EN = '1') else '0';
 
 
   -- Outputs assignment
   -- DFIFO_EMPTY should never happen if tags are consistent.
   -- If it happens there is no way back. Reset is needed to recover.
   DFIFO_RD_EN <= dfifo_rd_en_i;
   TFIFO_RD_EN <= tfifo_rd_en_i;
 
   FRAME_VALID <= frame_valid_i;
   FRAME_LAST <= last_word;
   FRAME_DATA <= dfifo_rdata;
   FRAME_BE <= dfifo_be;
   FRAME_LENGTH <= return_info(C_FP_TAG_LENGTH_BITLEN - 1 downto 0);
   DST_UDP <= return_info(LC_RI_DST_UDP_POS + udp_port_type'left
                     downto LC_RI_DST_UDP_POS );
   SRC_UDP <= return_info(LC_RI_SRC_UDP_POS + udp_port_type'left
                     downto LC_RI_SRC_UDP_POS);
   SRC_IP  <= return_info(LC_RI_SRC_IP_POS + ip_addr_type'left
                     downto LC_RI_SRC_IP_POS );
   SRC_MAC <= return_info(LC_RI_SRC_MAC_POS + mac_addr_type'left
                     downto LC_RI_SRC_MAC_POS);
 
 
 
 
end architecture;
 
 
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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