You've already forked gitified_old_clb_svn
4727 lines
173 KiB
VHDL
4727 lines
173 KiB
VHDL
--------------------------------------------------------------------------------
|
||
--
|
||
-- This VHDL file was generated by EASE/HDL 8.0 Revision 10 from HDL Works B.V.
|
||
--
|
||
-- Ease library : design
|
||
-- HDL library : work
|
||
-- Host name : SERING
|
||
-- User name : peterj
|
||
-- Time stamp : Mon Jun 29 14:49:53 2015
|
||
--
|
||
-- Designed by :
|
||
-- Company : HDL Works
|
||
-- Project info :
|
||
--
|
||
--------------------------------------------------------------------------------
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.SYSCON
|
||
-- Last modified : Fri Sep 12 15:15:37 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
|
||
entity SYSCON is
|
||
port (
|
||
ClkI_n : out std_logic;
|
||
ClkI_p : out std_logic;
|
||
RST_I : out std_logic);
|
||
end entity SYSCON;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.SYSCON.rtl
|
||
-- Last modified : Fri Sep 12 15:15:37 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
architecture rtl of SYSCON is
|
||
|
||
begin
|
||
Process
|
||
-- 200 MHz = 5 ns, 125 MHz = 8 ns, 100 MHz = 10 ns, 27 MHz = 37 ns
|
||
Constant ClockPeriod: Time := 8 ns;
|
||
Variable Clock: Std_Logic;
|
||
-- RST_I is de-asserted after 5 CLK_I cycles
|
||
Variable RstCount: Integer range 0 to 127 := 64;
|
||
Begin
|
||
If now = 0 ns Then
|
||
Clock := '0';
|
||
Else
|
||
Clock := Not Clock;
|
||
If clock = '0' and RstCount > 0 Then
|
||
RstCount := RstCount - 1;
|
||
End If;
|
||
End If;
|
||
|
||
ClkI_p <= Clock;
|
||
ClkI_n <= Not Clock;
|
||
|
||
If RstCount > 0 Then
|
||
RST_I <= '1';
|
||
Else
|
||
RST_I <= '0';
|
||
End If;
|
||
|
||
Wait for ClockPeriod / 2;
|
||
End Process;
|
||
|
||
end architecture rtl ; -- of SYSCON
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.RdOutAll
|
||
-- Last modified : Mon Nov 04 15:52:52 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
|
||
entity RdOutAll is
|
||
port (
|
||
UDP_Rx_Empty : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
UDP_Rx_RdReq : out std_logic_vector(NUM_UDP_PRTS-1 downto 0));
|
||
end entity RdOutAll;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.RdOutAll.rtl
|
||
-- Last modified : Mon Nov 04 15:52:52 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
architecture rtl of RdOutAll is
|
||
|
||
begin
|
||
Process (UDP_Rx_Empty)
|
||
begin
|
||
For i In 0 to NUM_UDP_PRTS-1 loop
|
||
UDP_Rx_RdReq(i) <= not UDP_Rx_Empty(i);
|
||
end loop;
|
||
end Process;
|
||
end architecture rtl ; -- of RdOutAll
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.FireCPU_Packet
|
||
-- Last modified : Mon Sep 02 14:53:29 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
|
||
entity FireCPU_Packet is
|
||
port (
|
||
CPU_AccGnt : in std_logic;
|
||
Clk : in std_logic;
|
||
Rst : in std_logic;
|
||
TxFireCPU : in std_logic;
|
||
UDP_TX_CPU : out ipmux_cpu_in_type);
|
||
end entity FireCPU_Packet;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.FireCPU_Packet.fsm
|
||
-- Last modified : Mon Sep 02 14:53:29 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
architecture fsm of FireCPU_Packet is
|
||
|
||
-- State Machine Options:
|
||
-- Clock : Clk (Rising edge).
|
||
-- State assignment : Enumerate.
|
||
-- State decoding : Case construct.
|
||
-- Actions on transitions : Clocked.
|
||
-- Actions on states : Clocked.
|
||
|
||
type state_type is (Idle, WriteCPU_Frame, StForever, WaitForGrant,
|
||
WriteCPU_SOP, WriteCPU_EOP, WriteCPU_FramePart2, WriteCPU_Pause,
|
||
WriteCPU_FramePart1, WriteCPU_Pause1) ;
|
||
signal state : state_type ; -- Current State
|
||
Signal Offset: Integer Range 0 to MAX_RESERV_PKT_BUF;
|
||
|
||
|
||
begin
|
||
--Packet Buffer Full Flag is only checked once.
|
||
--If Full = False then there is at least place
|
||
--to store one packet (size PKT_LEN + PAYLOAD).
|
||
--It is the responsibility of the input *NOT* to
|
||
--exceed this maximum; Overfglow is not checked!
|
||
--This state machine is only used for test purposes.
|
||
--The state machine fires one CPU frame (defined in Variable CPU_Frame_RegFile of size
|
||
--Constant FRAME_SIZE, initialized in InitHRegFile).
|
||
--Once fired it ends in an endless loop (thus only one CPU frame is transferred).
|
||
UDP_TX_CPU.Addr <= Std_Logic_Vector(To_Unsigned(Offset,TX_PKT_BUF_ADRSIZE));
|
||
|
||
|
||
state_decoding: process (Clk, Rst) is
|
||
Constant FRAME_SIZE : Integer := 26;
|
||
Variable CPU_Frame_RegFile: std_logic_v16array(FRAME_SIZE-1 downto 0);
|
||
Variable Idx: Integer Range 0 to MAX_RESERV_PKT_BUF;
|
||
|
||
begin
|
||
if (Rst = '1') then
|
||
state <= Idle ;
|
||
-- Initialize:
|
||
UDP_TX_CPU.Request <= '0';
|
||
UDP_TX_CPU.D <= (Others => '0');
|
||
UDP_TX_CPU.EOP <= '0';
|
||
Offset <= 0;
|
||
Idx := 0;
|
||
UDP_TX_CPU.WrEn <= '0';
|
||
elsif (rising_edge(Clk)) then
|
||
lbl_state : case state is
|
||
when Idle =>
|
||
if (
|
||
TxFireCPU = '1'
|
||
-- FALSE
|
||
) then
|
||
state <= WaitForGrant ;
|
||
UDP_TX_CPU.Request <= '1';
|
||
UDP_TX_CPU.D <= (Others => '0');
|
||
UDP_TX_CPU.EOP <= '0';
|
||
Offset <= Idx;
|
||
Idx := 0;
|
||
UDP_TX_CPU.WrEn <= '0';
|
||
else
|
||
state <= Idle ;
|
||
-- InitHregFile:
|
||
CPU_Frame_RegFile(0) := x"001B";
|
||
CPU_Frame_RegFile(1) := x"21B0";
|
||
CPU_Frame_RegFile(2) := x"AA75";
|
||
CPU_Frame_RegFile(3) := x"FFEE";
|
||
CPU_Frame_RegFile(4) := x"DDCC";
|
||
CPU_Frame_RegFile(5) := x"BBAA";
|
||
CPU_Frame_RegFile(6) := x"0800";
|
||
CPU_Frame_RegFile(7) := x"4500";
|
||
CPU_Frame_RegFile(8) := x"0026";
|
||
CPU_Frame_RegFile(9) := x"0000";
|
||
CPU_Frame_RegFile(10) := x"0000";
|
||
CPU_Frame_RegFile(11) := x"8011";
|
||
CPU_Frame_RegFile(12) := x"B771";
|
||
CPU_Frame_RegFile(13) := x"C0A8";
|
||
CPU_Frame_RegFile(14) := x"0103";
|
||
CPU_Frame_RegFile(15) := x"C0A8";
|
||
CPU_Frame_RegFile(16) := x"0102";
|
||
CPU_Frame_RegFile(17) := x"2023";
|
||
CPU_Frame_RegFile(18) := x"1022";
|
||
CPU_Frame_RegFile(19) := x"0012";
|
||
|
||
CPU_Frame_RegFile(20) := x"5EB6";
|
||
--CPU_Frame_RegFile(20) := x"5EB7"; -- Bad Checksum!
|
||
|
||
CPU_Frame_RegFile(21) := x"CC33";
|
||
CPU_Frame_RegFile(22) := x"0000";
|
||
CPU_Frame_RegFile(23) := x"1111";
|
||
CPU_Frame_RegFile(24) := x"2222";
|
||
CPU_Frame_RegFile(25) := x"EE11";
|
||
end if ;
|
||
when WriteCPU_Frame =>
|
||
if (Idx = 7) then
|
||
state <= WriteCPU_Pause ;
|
||
UDP_TX_CPU.Request <= '1';
|
||
UDP_TX_CPU.D <= (Others => '0');
|
||
UDP_TX_CPU.EOP <= '0';
|
||
Offset <= Idx;
|
||
Idx := Idx + 1;
|
||
UDP_TX_CPU.WrEn <= '0';
|
||
|
||
else
|
||
state <= WriteCPU_Frame ;
|
||
UDP_TX_CPU.Request <= '1';
|
||
UDP_TX_CPU.D <= CPU_Frame_RegFile(Idx);
|
||
UDP_TX_CPU.EOP <= '0';
|
||
Offset <= Idx;
|
||
Idx := Idx + 1;
|
||
UDP_TX_CPU.WrEn <= '1';
|
||
|
||
end if ;
|
||
when StForever =>
|
||
state <= StForever ;
|
||
-- Initialize:
|
||
UDP_TX_CPU.Request <= '0';
|
||
UDP_TX_CPU.D <= (Others => '0');
|
||
UDP_TX_CPU.EOP <= '0';
|
||
Offset <= 0;
|
||
Idx := 0;
|
||
UDP_TX_CPU.WrEn <= '0';
|
||
when WaitForGrant =>
|
||
if (CPU_AccGnt = '1') then
|
||
state <= WriteCPU_SOP ;
|
||
UDP_TX_CPU.Request <= '1';
|
||
UDP_TX_CPU.D <= CPU_Frame_RegFile(Idx);
|
||
UDP_TX_CPU.EOP <= '0';
|
||
Offset <= 0;
|
||
Idx := Idx + 1;
|
||
UDP_TX_CPU.WrEn <= '1';
|
||
else
|
||
state <= WaitForGrant ;
|
||
UDP_TX_CPU.Request <= '1';
|
||
UDP_TX_CPU.D <= (Others => '0');
|
||
UDP_TX_CPU.EOP <= '0';
|
||
Offset <= Idx;
|
||
Idx := 0;
|
||
UDP_TX_CPU.WrEn <= '0';
|
||
end if ;
|
||
when WriteCPU_SOP =>
|
||
state <= WriteCPU_Frame ;
|
||
UDP_TX_CPU.Request <= '1';
|
||
UDP_TX_CPU.D <= CPU_Frame_RegFile(Idx);
|
||
UDP_TX_CPU.EOP <= '0';
|
||
Offset <= Idx;
|
||
Idx := Idx + 1;
|
||
UDP_TX_CPU.WrEn <= '1';
|
||
|
||
when WriteCPU_EOP =>
|
||
state <= WriteCPU_FramePart2 ;
|
||
UDP_TX_CPU.Request <= '1';
|
||
UDP_TX_CPU.D <= CPU_Frame_RegFile(Idx);
|
||
UDP_TX_CPU.EOP <= '0';
|
||
Offset <= Idx;
|
||
Idx := Idx + 1;
|
||
UDP_TX_CPU.WrEn <= '1';
|
||
|
||
when WriteCPU_FramePart2 =>
|
||
if (Idx = 25) then
|
||
state <= WriteCPU_Pause1 ;
|
||
UDP_TX_CPU.Request <= '1';
|
||
UDP_TX_CPU.D <= (Others => '0');
|
||
UDP_TX_CPU.EOP <= '0';
|
||
Offset <= Idx;
|
||
Idx := Idx + 1;
|
||
UDP_TX_CPU.WrEn <= '0';
|
||
|
||
else
|
||
state <= WriteCPU_FramePart2 ;
|
||
UDP_TX_CPU.Request <= '1';
|
||
UDP_TX_CPU.D <= CPU_Frame_RegFile(Idx);
|
||
UDP_TX_CPU.EOP <= '0';
|
||
Offset <= Idx;
|
||
Idx := Idx + 1;
|
||
UDP_TX_CPU.WrEn <= '1';
|
||
|
||
end if ;
|
||
when WriteCPU_Pause =>
|
||
if (Idx = 28) then
|
||
state <= WriteCPU_FramePart1 ;
|
||
Idx := 7;
|
||
UDP_TX_CPU.Request <= '1';
|
||
UDP_TX_CPU.D <= CPU_Frame_RegFile(Idx);
|
||
UDP_TX_CPU.EOP <= '0';
|
||
Offset <= Idx;
|
||
Idx := Idx + 1;
|
||
UDP_TX_CPU.WrEn <= '1';
|
||
|
||
else
|
||
state <= WriteCPU_Pause ;
|
||
UDP_TX_CPU.Request <= '1';
|
||
UDP_TX_CPU.D <= (Others => '0');
|
||
UDP_TX_CPU.EOP <= '0';
|
||
Offset <= Idx;
|
||
Idx := Idx + 1;
|
||
UDP_TX_CPU.WrEn <= '0';
|
||
|
||
end if ;
|
||
when WriteCPU_FramePart1 =>
|
||
if (Idx = 15) then
|
||
state <= WriteCPU_EOP ;
|
||
UDP_TX_CPU.Request <= '1';
|
||
UDP_TX_CPU.D <= CPU_Frame_RegFile(25);
|
||
UDP_TX_CPU.EOP <= '1';
|
||
Offset <= 25;
|
||
Idx := 15;
|
||
UDP_TX_CPU.WrEn <= '1';
|
||
else
|
||
state <= WriteCPU_FramePart1 ;
|
||
UDP_TX_CPU.Request <= '1';
|
||
UDP_TX_CPU.D <= CPU_Frame_RegFile(Idx);
|
||
UDP_TX_CPU.EOP <= '0';
|
||
Offset <= Idx;
|
||
Idx := Idx + 1;
|
||
UDP_TX_CPU.WrEn <= '1';
|
||
|
||
end if ;
|
||
when WriteCPU_Pause1 =>
|
||
if (Idx = 38) then
|
||
state <= StForever ;
|
||
-- Initialize:
|
||
UDP_TX_CPU.Request <= '0';
|
||
UDP_TX_CPU.D <= (Others => '0');
|
||
UDP_TX_CPU.EOP <= '0';
|
||
Offset <= 0;
|
||
Idx := 0;
|
||
UDP_TX_CPU.WrEn <= '0';
|
||
else
|
||
state <= WriteCPU_Pause1 ;
|
||
UDP_TX_CPU.Request <= '1';
|
||
UDP_TX_CPU.D <= (Others => '0');
|
||
UDP_TX_CPU.EOP <= '0';
|
||
Offset <= Idx;
|
||
Idx := Idx + 1;
|
||
UDP_TX_CPU.WrEn <= '0';
|
||
|
||
end if ;
|
||
end case lbl_state ;
|
||
end if ; -- Reset & Clock
|
||
end process state_decoding ;
|
||
|
||
end architecture fsm ; -- of FireCPU_Packet
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.FirePacket
|
||
-- Last modified : Fri Nov 22 14:56:18 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
|
||
entity FirePacket is
|
||
generic(
|
||
Single : boolean := False);
|
||
port (
|
||
Clk : in std_logic;
|
||
Full : in std_logic;
|
||
Rst : in std_logic;
|
||
TxFireCPU : out std_logic;
|
||
Tx_Fire : in std_logic;
|
||
UDP_Tx : out dbus_type;
|
||
WrReq : out std_logic);
|
||
end entity FirePacket;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.FirePacket.fsm
|
||
-- Last modified : Fri Nov 22 14:56:18 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
architecture fsm of FirePacket is
|
||
|
||
-- State Machine Options:
|
||
-- Clock : Clk (Rising edge).
|
||
-- State assignment : Enumerate.
|
||
-- State decoding : Case construct.
|
||
-- Actions on transitions : Clocked.
|
||
-- Actions on states : Clocked.
|
||
|
||
type state_type is (Idle, SOD1, Frame1, EOD1, StForever, EOD2, FramePause,
|
||
SingleWord) ;
|
||
signal state : state_type ; -- Current State
|
||
|
||
|
||
begin
|
||
--Cnt= 2 .. 4485 (words)
|
||
--Byte 3, 4
|
||
--:
|
||
--Byte 8969, 8970
|
||
--
|
||
--Cnt = 4486 (in words)
|
||
--Byte 8971, 8972
|
||
--Cnt= 1 (words)
|
||
--Byte 1, 2
|
||
--
|
||
--Reserve Space for IP_HDR_CNT + UDP_HDR_CNT = 28 bytes / 14 words
|
||
--
|
||
--Single = True Then
|
||
--Only fire a sinle word (With EOD set)
|
||
--Insert a small pause, just to see if emptying
|
||
--the input FIFO is properly handled by entities
|
||
--TxStreamSel and TxBuffers
|
||
--This state machine is only used for test purposes.
|
||
--The state machine fires Frame(s). The boolean generic "Single" determines
|
||
--wheter a long frame (size MAX_PKT_LEN) or one ore more short frames are generated.
|
||
--
|
||
--Single = False:
|
||
--First a long frame (MAX_PKT_LEN = 9000 = Jumbo Frame):
|
||
--0x050D
|
||
--0x0002
|
||
--0x0003
|
||
--:
|
||
--0x01FF
|
||
-- Pause to verify if the logic is able to handle an empty input fifo
|
||
--0x0200
|
||
--:
|
||
--0x1185
|
||
--0x0E0D
|
||
--Next a CPU Frame (fire the "FireCPU_Packet" State Machine)
|
||
--Next more "long" frames (same format as first frame)
|
||
--
|
||
--Single = True:
|
||
--The first short frame is only 2 words:
|
||
--0x5678
|
||
--0x0E0D
|
||
--Next following short frames are only 1 word:
|
||
--0x0E0D
|
||
|
||
state_decoding: process (Clk, Rst) is
|
||
Variable Cnt: Integer Range 0 to 16383;
|
||
Variable Frame: Integer Range 0 to 1023;
|
||
Variable PauseCnt: Integer Range 0 to 16383;
|
||
|
||
|
||
|
||
begin
|
||
if (Rst = '1') then
|
||
state <= Idle ;
|
||
-- Initalize:
|
||
--UDP_Tx.SOD <= '0';
|
||
UDP_Tx.EOD <= '0';
|
||
UDP_Tx.D <= x"aa11";
|
||
WrReq <= '0';
|
||
Cnt := 0;
|
||
Frame := 0;
|
||
TxFireCPU <= '0';
|
||
elsif (rising_edge(Clk)) then
|
||
lbl_state : case state is
|
||
when Idle =>
|
||
if (Tx_Fire = '1' And Single = True) then
|
||
state <= SingleWord ;
|
||
Cnt := 1;
|
||
Frame := 0;
|
||
--UDP_Tx.SOD <= '0';
|
||
UDP_Tx.EOD <= '0';
|
||
UDP_Tx.D <= x"8765";
|
||
WrReq <= Not Full;
|
||
elsif (Tx_Fire = '1') then
|
||
state <= SOD1 ;
|
||
Cnt := 1;
|
||
Frame := 0;
|
||
--UDP_Tx.SOD <= '1';
|
||
UDP_Tx.EOD <= '0';
|
||
UDP_Tx.D <= x"050D";
|
||
WrReq <= Not Full;
|
||
-- CntInc:
|
||
If Full = '0' Then
|
||
Cnt := Cnt + 1;
|
||
End If;
|
||
else
|
||
state <= Idle ;
|
||
--UDP_Tx.SOD <= '0';
|
||
UDP_Tx.EOD <= '0';
|
||
UDP_Tx.D <= x"aa11";
|
||
WrReq <= '0';
|
||
end if ;
|
||
when SOD1 =>
|
||
if (Full = '0') then
|
||
state <= Frame1 ;
|
||
--UDP_Tx.SOD <= '0';
|
||
UDP_Tx.EOD <= '0';
|
||
UDP_Tx.D <= Std_Logic_Vector(To_Unsigned(Cnt,16));
|
||
WrReq <= Not Full;
|
||
-- CntInc:
|
||
If Full = '0' Then
|
||
Cnt := Cnt + 1;
|
||
End If;
|
||
TxFireCPU <= '0';
|
||
else
|
||
state <= SOD1 ;
|
||
--UDP_Tx.SOD <= '1';
|
||
UDP_Tx.EOD <= '0';
|
||
UDP_Tx.D <= x"050D";
|
||
WrReq <= Not Full;
|
||
-- CntInc:
|
||
If Full = '0' Then
|
||
Cnt := Cnt + 1;
|
||
End If;
|
||
end if ;
|
||
when Frame1 =>
|
||
if (Cnt = 512) then
|
||
state <= FramePause ;
|
||
PauseCnt := 0;
|
||
TxFireCPU <= '0';
|
||
PauseCnt := PauseCnt + 1;
|
||
--UDP_Tx.SOD <= '0';
|
||
UDP_Tx.EOD <= '0';
|
||
UDP_Tx.D <= x"1234";
|
||
WrReq <= '0';
|
||
elsif (Full = '0' And Cnt = MAX_PKT_LEN - (IP_HDR_CNT + UDP_HDR_CNT)) then
|
||
state <= EOD1 ;
|
||
--UDP_Tx.SOD <= '0';
|
||
UDP_Tx.EOD <= '1';
|
||
UDP_Tx.D <= x"0E0D";
|
||
WrReq <= Not Full;
|
||
Frame := Frame + 1;
|
||
else
|
||
state <= Frame1 ;
|
||
--UDP_Tx.SOD <= '0';
|
||
UDP_Tx.EOD <= '0';
|
||
UDP_Tx.D <= Std_Logic_Vector(To_Unsigned(Cnt,16));
|
||
WrReq <= Not Full;
|
||
-- CntInc:
|
||
If Full = '0' Then
|
||
Cnt := Cnt + 1;
|
||
End If;
|
||
TxFireCPU <= '0';
|
||
end if ;
|
||
when EOD1 =>
|
||
if (
|
||
-- Full = '0' And Frame = 128
|
||
-- Full = '0' And Frame = 15
|
||
Full = '0' And Frame = 2
|
||
) then
|
||
state <= StForever ;
|
||
cnt := 1;
|
||
--UDP_Tx.SOD <= '0';
|
||
UDP_Tx.EOD <= '0';
|
||
UDP_Tx.D <= x"0000";
|
||
WrReq <= '0';
|
||
elsif (Full = '0') then
|
||
state <= SOD1 ;
|
||
cnt := 1;
|
||
TxFireCPU <= '1';
|
||
--UDP_Tx.SOD <= '1';
|
||
UDP_Tx.EOD <= '0';
|
||
UDP_Tx.D <= x"050D";
|
||
WrReq <= Not Full;
|
||
-- CntInc:
|
||
If Full = '0' Then
|
||
Cnt := Cnt + 1;
|
||
End If;
|
||
else
|
||
state <= EOD1 ;
|
||
--UDP_Tx.SOD <= '0';
|
||
UDP_Tx.EOD <= '1';
|
||
UDP_Tx.D <= x"0E0D";
|
||
WrReq <= Not Full;
|
||
Frame := Frame + 1;
|
||
end if ;
|
||
when StForever =>
|
||
state <= StForever ;
|
||
--UDP_Tx.SOD <= '0';
|
||
UDP_Tx.EOD <= '0';
|
||
UDP_Tx.D <= x"0000";
|
||
WrReq <= '0';
|
||
when EOD2 =>
|
||
if (Full = '0' And Frame = 2) then
|
||
state <= StForever ;
|
||
cnt := 1;
|
||
--UDP_Tx.SOD <= '0';
|
||
UDP_Tx.EOD <= '0';
|
||
UDP_Tx.D <= x"0000";
|
||
WrReq <= '0';
|
||
else
|
||
state <= EOD2 ;
|
||
--UDP_Tx.SOD <= '0';
|
||
UDP_Tx.EOD <= '1';
|
||
UDP_Tx.D <= x"0E0D";
|
||
WrReq <= Not Full;
|
||
Frame := Frame + 1;
|
||
end if ;
|
||
when FramePause =>
|
||
if (PauseCnt = 1024) then
|
||
state <= Frame1 ;
|
||
--UDP_Tx.SOD <= '0';
|
||
UDP_Tx.EOD <= '0';
|
||
UDP_Tx.D <= Std_Logic_Vector(To_Unsigned(Cnt,16));
|
||
WrReq <= Not Full;
|
||
-- CntInc:
|
||
If Full = '0' Then
|
||
Cnt := Cnt + 1;
|
||
End If;
|
||
TxFireCPU <= '0';
|
||
else
|
||
state <= FramePause ;
|
||
TxFireCPU <= '0';
|
||
PauseCnt := PauseCnt + 1;
|
||
--UDP_Tx.SOD <= '0';
|
||
UDP_Tx.EOD <= '0';
|
||
UDP_Tx.D <= x"1234";
|
||
WrReq <= '0';
|
||
end if ;
|
||
when SingleWord =>
|
||
state <= EOD2 ;
|
||
--UDP_Tx.SOD <= '0';
|
||
UDP_Tx.EOD <= '1';
|
||
UDP_Tx.D <= x"0E0D";
|
||
WrReq <= Not Full;
|
||
Frame := Frame + 1;
|
||
end case lbl_state ;
|
||
end if ; -- Reset & Clock
|
||
end process state_decoding ;
|
||
|
||
end architecture fsm ; -- of FirePacket
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.Debounce
|
||
-- Last modified : Tue Jun 12 17:23:50 2012.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
|
||
entity Debounce is
|
||
generic(
|
||
Simulation : boolean := False);
|
||
port (
|
||
Clk : in std_logic;
|
||
I : in std_logic;
|
||
O : out std_logic;
|
||
Rst : in std_logic);
|
||
end entity Debounce;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.Debounce.rtl
|
||
-- Last modified : Tue Jun 12 17:23:50 2012.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
architecture rtl of Debounce is
|
||
|
||
begin
|
||
Process (Clk, Rst)
|
||
Variable Meta_1, Meta_2, TerminalCount: Std_Logic;
|
||
Variable Cnt: Unsigned (11 downto 0);
|
||
Begin
|
||
If Rst = '1' Then
|
||
Meta_1 := '0';
|
||
Meta_2 := '0';
|
||
Cnt := (Others => '0');
|
||
TerminalCount := '0';
|
||
O <= '0';
|
||
ElsIf Rising_Edge(Clk) Then
|
||
Meta_2 := Meta_1;
|
||
Meta_1 := I;
|
||
|
||
If Meta_2 = '1' Then
|
||
If Simulation = True Then
|
||
TerminalCount := Cnt(Cnt'Right);
|
||
Else
|
||
TerminalCount := Cnt(Cnt'Left);
|
||
End If;
|
||
|
||
If TerminalCount = '1' Then
|
||
O <= '1';
|
||
Else
|
||
Cnt := Cnt + 1;
|
||
O <= '0';
|
||
End If;
|
||
Else
|
||
Cnt := (Others => '0');
|
||
O <= '0';
|
||
End If;
|
||
End If;
|
||
End Process;
|
||
end architecture rtl ; -- of Debounce
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.FirePackets
|
||
-- Last modified : Mon Sep 02 15:07:57 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
|
||
entity FirePackets is
|
||
generic(
|
||
Simulation : boolean := False);
|
||
port (
|
||
Clk : in std_logic;
|
||
Fire : in std_logic_vector(3 downto 0);
|
||
Rst : in std_logic;
|
||
UDP_Tx : out dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
UDP_Tx_Full : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
UDP_Tx_WrReq : out std_logic_vector(NUM_UDP_PRTS-1 downto 0));
|
||
end entity FirePackets;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.FirePackets.a0
|
||
-- Last modified : Mon Sep 02 15:07:57 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
architecture a0 of FirePackets is
|
||
|
||
signal O : std_logic;
|
||
signal O0 : std_logic;
|
||
signal O1 : std_logic;
|
||
signal O2 : std_logic;
|
||
|
||
component Debounce
|
||
generic(
|
||
Simulation : boolean := False);
|
||
port (
|
||
Clk : in std_logic;
|
||
I : in std_logic;
|
||
O : out std_logic;
|
||
Rst : in std_logic);
|
||
end component Debounce;
|
||
|
||
component FirePacket
|
||
generic(
|
||
Single : boolean := False);
|
||
port (
|
||
Clk : in std_logic;
|
||
Full : in std_logic;
|
||
Rst : in std_logic;
|
||
TxFireCPU : out std_logic;
|
||
Tx_Fire : in std_logic;
|
||
UDP_Tx : out dbus_type;
|
||
WrReq : out std_logic);
|
||
end component FirePacket;
|
||
|
||
begin
|
||
|
||
u0: Debounce
|
||
generic map(
|
||
Simulation => Simulation)
|
||
port map(
|
||
Clk => Clk,
|
||
I => Fire(0),
|
||
O => O,
|
||
Rst => Rst);
|
||
|
||
u1: Debounce
|
||
generic map(
|
||
Simulation => Simulation)
|
||
port map(
|
||
Clk => Clk,
|
||
I => Fire(1),
|
||
O => O0,
|
||
Rst => Rst);
|
||
|
||
u2: Debounce
|
||
generic map(
|
||
Simulation => Simulation)
|
||
port map(
|
||
Clk => Clk,
|
||
I => Fire(2),
|
||
O => O1,
|
||
Rst => Rst);
|
||
|
||
u3: Debounce
|
||
generic map(
|
||
Simulation => Simulation)
|
||
port map(
|
||
Clk => Clk,
|
||
I => Fire(3),
|
||
O => O2,
|
||
Rst => Rst);
|
||
|
||
u4: FirePacket
|
||
generic map(
|
||
Single => False)
|
||
port map(
|
||
Clk => Clk,
|
||
Full => UDP_Tx_Full(0),
|
||
Rst => Rst,
|
||
TxFireCPU => open,
|
||
Tx_Fire => O,
|
||
UDP_Tx => UDP_Tx(0),
|
||
WrReq => UDP_Tx_WrReq(0));
|
||
|
||
u5: FirePacket
|
||
generic map(
|
||
Single => False)
|
||
port map(
|
||
Clk => Clk,
|
||
Full => UDP_Tx_Full(1),
|
||
Rst => Rst,
|
||
TxFireCPU => open,
|
||
Tx_Fire => O0,
|
||
UDP_Tx => UDP_Tx(1),
|
||
WrReq => UDP_Tx_WrReq(1));
|
||
|
||
u6: FirePacket
|
||
generic map(
|
||
Single => False)
|
||
port map(
|
||
Clk => Clk,
|
||
Full => UDP_Tx_Full(2),
|
||
Rst => Rst,
|
||
TxFireCPU => open,
|
||
Tx_Fire => O1,
|
||
UDP_Tx => UDP_Tx(2),
|
||
WrReq => UDP_Tx_WrReq(2));
|
||
|
||
u7: FirePacket
|
||
generic map(
|
||
Single => True)
|
||
port map(
|
||
Clk => Clk,
|
||
Full => UDP_Tx_Full(3),
|
||
Rst => Rst,
|
||
TxFireCPU => open,
|
||
Tx_Fire => O2,
|
||
UDP_Tx => UDP_Tx(3),
|
||
WrReq => UDP_Tx_WrReq(3));
|
||
end architecture a0 ; -- of FirePackets
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.PowerOnRst
|
||
-- Last modified : Fri Sep 12 15:15:37 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
|
||
entity PowerOnRst is
|
||
port (
|
||
Rst : out std_logic;
|
||
RstIn : in std_logic);
|
||
end entity PowerOnRst;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.PowerOnRst.rtl
|
||
-- Last modified : Fri Sep 12 15:15:37 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
Library UNISIM;
|
||
use UNISIM.vcomponents.all;
|
||
|
||
architecture rtl of PowerOnRst is
|
||
----- component IBUFG -----
|
||
component IBUFG
|
||
generic (
|
||
CAPACITANCE : string := "DONT_CARE";
|
||
IBUF_DELAY_VALUE : string := "0";
|
||
IBUF_LOW_PWR : boolean := TRUE;
|
||
IOSTANDARD : string := "DEFAULT"
|
||
);
|
||
port (
|
||
O : out std_ulogic;
|
||
I : in std_ulogic
|
||
);
|
||
end component;
|
||
|
||
----- component STARTUPE2 (7-Family Start-up) -----
|
||
component STARTUPE2
|
||
generic (
|
||
PROG_USR : string := "FALSE";
|
||
SIM_CCLK_FREQ : real := 0.0
|
||
);
|
||
port (
|
||
CFGCLK : out std_ulogic;
|
||
CFGMCLK : out std_ulogic;
|
||
EOS : out std_ulogic;
|
||
PREQ : out std_ulogic;
|
||
CLK : in std_ulogic;
|
||
GSR : in std_ulogic;
|
||
GTS : in std_ulogic;
|
||
KEYCLEARB : in std_ulogic;
|
||
PACK : in std_ulogic;
|
||
USRCCLKO : in std_ulogic;
|
||
USRCCLKTS : in std_ulogic;
|
||
USRDONEO : in std_ulogic;
|
||
USRDONETS : in std_ulogic
|
||
);
|
||
end component;
|
||
|
||
Signal RstIntern: std_logic;
|
||
Signal EOSIntern: std_logic;
|
||
-- Signal EOSdel: std_logic;
|
||
|
||
begin
|
||
-- STARTUPE2: 7-family STARTUP Block
|
||
-- Xilinx 7 Series FPGA Libraries Guide for HDL Designs, ug768 version 13.1
|
||
STARTUPE2_inst : STARTUPE2
|
||
generic map (
|
||
PROG_USR => "FALSE", -- Activate program event security feature
|
||
SIM_CCLK_FREQ => 0.0
|
||
)
|
||
port map (
|
||
CFGCLK => open, -- 1-bit Configuration main clock output
|
||
CFGMCLK => open, -- 1-bit Configuration internal oscillator clock output
|
||
EOS => EOSIntern, -- 1-bit Active high output signal indicating the End Of Configuration.
|
||
PREQ => open, -- 1-bit PROGRAM request to fabric output
|
||
CLK => '0', -- 1-bit User start-up clock input
|
||
GSR => '0', -- 1-bit Global Set/Reset input (GSR cannot be used for the port name)
|
||
GTS => '0', -- 1-bit Global 3-state input (GTS cannot be used for the port name)
|
||
KEYCLEARB => '0', -- 1-bit Clear AES Decrypter Key input from Battery-Backed RAM (BBRAM)
|
||
PACK => '0', -- 1-bit PROGRAM acknowledge input
|
||
USRCCLKO => '0', -- 1-bit User CCLK input
|
||
USRCCLKTS => '0', -- 1-bit User CCLK 3-state enable input
|
||
USRDONEO => '0', -- 1-bit User DONE pin output control
|
||
USRDONETS => '0' -- 1-bit User DONE 3-state enable output
|
||
);
|
||
|
||
RESET_IBUFG: IBUFG
|
||
port map (
|
||
O => RstIntern,
|
||
I => RstIn
|
||
);
|
||
|
||
Rst <= RstIntern Or Not EOSIntern;
|
||
|
||
end architecture rtl ; -- of PowerOnRst
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.ClkDist
|
||
-- Last modified : Mon Nov 11 09:38:53 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.EMAC16bit_Package.all;
|
||
use work.v_array_package.all;
|
||
|
||
entity ClkDist is
|
||
port (
|
||
Clk125 : in std_logic;
|
||
Clk62_5 : in std_logic;
|
||
Emptyi : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Emptyo : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Fulli : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Fullo : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
RdClk : out std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
RdReqi : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
RdReqo : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Rx : in dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
Tx : out dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
UDP_Rx : out dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
UDP_Tx : in dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
WrClk : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
WrReqi : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
WrReqo : out std_logic_vector(NUM_UDP_PRTS-1 downto 0));
|
||
end entity ClkDist;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.ClkDist.rtl
|
||
-- Last modified : Mon Nov 11 09:38:53 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
architecture rtl of ClkDist is
|
||
|
||
begin
|
||
-- The RdClk and WrClk signals are assigned here.
|
||
-- This creates one delta delay in simulation!
|
||
-- In order to keep clock and data signals alligned all signals
|
||
-- are simply fed forward (although also adding one delta delay).
|
||
|
||
-- RX side
|
||
Emptyo <= Emptyi;
|
||
RdReqo <= RdReqi;
|
||
UDP_Rx <= Rx;
|
||
|
||
RdClk(0) <= Clk62_5;
|
||
RdClk(1) <= Clk62_5;
|
||
RdClk(2) <= Clk62_5;
|
||
RdClk(3) <= Clk62_5;
|
||
RdClk(4) <= Clk62_5; -- The Fifo connected to the CPU which is running on 62,5 MHz
|
||
|
||
-- Tx Side
|
||
Fullo <= Fulli;
|
||
WrReqo <= WrReqi;
|
||
Tx <= UDP_Tx;
|
||
|
||
WrClk(0) <= Clk62_5;
|
||
WrClk(1) <= Clk62_5;
|
||
WrClk(2) <= Clk62_5;
|
||
WrClk(3) <= Clk62_5;
|
||
|
||
end architecture rtl ; -- of ClkDist
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.ipmux_regs_and_rxtxcpu
|
||
-- Last modified : Mon Jun 29 14:49:51 2015.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
use work.wishbone_pkg.all;
|
||
|
||
entity ipmux_regs_and_rxtxcpu is
|
||
port (
|
||
CPU_AccGnt : in std_logic;
|
||
CPU_Tx : out ipmux_cpu_in_type;
|
||
Clk : in std_logic;
|
||
Flush : out std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
PacketsDone : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Rst : in std_logic;
|
||
Rx_Empty : in std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
TxStreamDebug : in std_logic_vector(11 downto 0);
|
||
Tx_Full : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
cpu_rdreq : out std_logic;
|
||
cpu_rx : in dbus_type;
|
||
div_ratio : out std_logic_vector(31 downto 0);
|
||
eth_regs_o : out eth_regs_type;
|
||
numpackets : out std_logic_vector(9 downto 0);
|
||
numwords : out std_logic_vector(13 downto 0);
|
||
udptstctrl : out std_logic_vector(2 downto 0);
|
||
wb_ipmux_reg_i : in t_wishbone_slave_in;
|
||
wb_ipmux_reg_o : out t_wishbone_slave_out;
|
||
wb_ipmux_rx_tx_i : in t_wishbone_slave_in;
|
||
wb_ipmux_rx_tx_o : out t_wishbone_slave_out);
|
||
end entity ipmux_regs_and_rxtxcpu;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.ipmux_regs_and_rxtxcpu.rtl
|
||
-- Last modified : Mon Jun 29 14:49:51 2015.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
architecture rtl of ipmux_regs_and_rxtxcpu is
|
||
|
||
signal ack_reg: std_logic; -- internal acknowledeg for wb_ipmux_reg
|
||
signal wr_reg: std_logic; -- internal write
|
||
signal rd_reg: std_logic; -- internal read
|
||
|
||
signal ack_txrx: std_logic; -- internal acknowledeg for wb_ipmux_rx_tx
|
||
signal rd_rx: std_logic; -- internal read
|
||
signal wr_tx: std_logic; -- internal read
|
||
|
||
|
||
-- actual wishbone registers
|
||
signal MAC_Mod : std_logic_vector(47 downto 0); -- Module MAC address
|
||
signal MAC_Srv : std_logic_vector(47 downto 0); -- Server MAC address
|
||
signal IP_Mod : std_logic_vector(31 downto 0); -- Module IP address
|
||
signal IP_Srv : std_logic_vector(31 downto 0); -- Server IP address
|
||
signal UDP_SrvPrt : std_logic_v16array(NUM_UDP_PRTS-1 downto 0); -- Server Port
|
||
signal UDP_ModPrt : std_logic_v16array(NUM_UDP_PRTS-1 downto 0); -- Module Port
|
||
|
||
signal reg_flush : std_logic_vector(4 downto 0); -- Access Control Status Register -> Flush
|
||
signal reg_tx_request : std_logic; -- Access Control Status Register -> Tx_Request
|
||
|
||
signal reg_div_ratio : std_logic_vector(31 downto 0); -- packet test generator: divide ratio (counts * 16 ns ticks)
|
||
signal reg_numwords : std_logic_vector(13 downto 0); -- packet test generator: number of words per packet
|
||
signal reg_numpackets : std_logic_vector( 9 downto 0); -- packet test generator: number of packets per burst
|
||
signal reg_udptstcntr : std_logic_vector( 2 downto 0); -- packet test generator: control register (continuously or trigger)
|
||
|
||
begin
|
||
-- ==============================================================================
|
||
-- Implement IPMUX Register acces via wb_ipmux_reg_i and wb_ipmux_reg_o
|
||
-- ==============================================================================
|
||
|
||
-- generate acknowledge output signal
|
||
gen_ack_reg : process(Clk, Rst)
|
||
begin
|
||
if Rst = '1' then
|
||
ack_reg <= '0';
|
||
elsif rising_edge(Clk) then
|
||
ack_reg <= wb_ipmux_reg_i.cyc and wb_ipmux_reg_i.stb and not ack_reg; -- because timing is always honored
|
||
end if;
|
||
end process gen_ack_reg;
|
||
wb_ipmux_reg_o.ack <= ack_reg;
|
||
|
||
-- generate other wishbone signals
|
||
wb_ipmux_reg_o.err <= '0';
|
||
wb_ipmux_reg_o.rty <= '0';
|
||
wb_ipmux_reg_o.stall <= '0';
|
||
wb_ipmux_reg_o.int <= '0';
|
||
|
||
-- generate wishbone write and read access signal
|
||
wr_reg <= wb_ipmux_reg_i.cyc and wb_ipmux_reg_i.stb and wb_ipmux_reg_i.we;
|
||
rd_reg <= wb_ipmux_reg_i.cyc and wb_ipmux_reg_i.stb and not wb_ipmux_reg_i.we;
|
||
|
||
-- assign wishbone data output
|
||
wb_read_reg : process(Clk, Rst)
|
||
begin
|
||
if Rst = '1' then
|
||
wb_ipmux_reg_o.dat <= (others => '0');
|
||
elsif rising_edge(Clk) then
|
||
if (rd_reg = '1') then
|
||
case to_integer(unsigned(wb_ipmux_reg_i.adr(7 downto 2))) is
|
||
when 16#00# => wb_ipmux_reg_o.dat <= MAC_Srv(31 downto 0);
|
||
when 16#01# => wb_ipmux_reg_o.dat <= x"0000" & MAC_Srv(47 downto 32);
|
||
when 16#02# => wb_ipmux_reg_o.dat <= MAC_Mod(31 downto 0);
|
||
when 16#03# => wb_ipmux_reg_o.dat <= x"0000" & MAC_Mod(47 downto 32);
|
||
when 16#04# => wb_ipmux_reg_o.dat <= IP_Srv;
|
||
when 16#05# => wb_ipmux_reg_o.dat <= IP_Mod;
|
||
when 16#06# => wb_ipmux_reg_o.dat <= UDP_SrvPrt(0) & UDP_ModPrt(0);
|
||
when 16#07# => wb_ipmux_reg_o.dat <= UDP_SrvPrt(1) & UDP_ModPrt(1);
|
||
when 16#08# => wb_ipmux_reg_o.dat <= UDP_SrvPrt(2) & UDP_ModPrt(2);
|
||
when 16#09# => wb_ipmux_reg_o.dat <= UDP_SrvPrt(3) & UDP_ModPrt(3);
|
||
when 16#0A# => wb_ipmux_reg_o.dat <= "0000" & Tx_Full & "000" & Rx_Empty & "000" & reg_flush & "000000" & CPU_AccGnt & reg_tx_request;
|
||
|
||
when 16#10# => wb_ipmux_reg_o.dat <= reg_div_ratio;
|
||
when 16#11# => wb_ipmux_reg_o.dat <= x"0000" & "00" & reg_numwords;
|
||
when 16#12# => wb_ipmux_reg_o.dat <= x"00000" & "00" & reg_numpackets;
|
||
when 16#13# => wb_ipmux_reg_o.dat <= x"0000000" & '0' & reg_udptstcntr;
|
||
when 16#14# => wb_ipmux_reg_o.dat <= x"0000" & PacketsDone & TxStreamDebug;
|
||
when others => wb_ipmux_reg_o.dat <= (others => '0');
|
||
report ("### IPMUX_Registers: Illegal read address");
|
||
end case;
|
||
end if;
|
||
end if;
|
||
end process wb_read_reg;
|
||
|
||
-- assign the registers with wishbone data input
|
||
wb_write_reg: process(Clk, Rst)
|
||
begin
|
||
if (Rst = '1') then
|
||
MAC_Mod <= (others => '0');
|
||
MAC_Srv <= (others => '0');
|
||
IP_Mod <= (others => '0');
|
||
IP_Srv <= (others => '0');
|
||
for i in 0 to (NUM_UDP_PRTS-1) loop
|
||
UDP_SrvPrt(i) <= (others => '0');
|
||
UDP_ModPrt(i) <= (others => '0');
|
||
end loop;
|
||
|
||
reg_tx_request <= '0';
|
||
reg_flush <= (others => '0');
|
||
reg_div_ratio <= std_logic_vector(to_unsigned(2422,32)); -- default = 1 / (2422 * 16 ns) = 25,8 KHz
|
||
reg_numwords <= std_logic_vector(to_unsigned(4,14)); -- default = 4 words payload per UDP packet (gives minimum size Ethernet packets of 60 bytes)
|
||
reg_numpackets <= std_logic_vector(to_unsigned(16,10)); -- default = bunches of 16 packets
|
||
reg_udptstcntr <= (others => '0'); -- default = no continuous, no trigger
|
||
|
||
elsif rising_edge(Clk) then
|
||
if (wr_reg = '1') then
|
||
case to_integer(unsigned(wb_ipmux_reg_i.adr(7 downto 2))) is
|
||
when 16#00# => MAC_Srv(31 downto 0) <= wb_ipmux_reg_i.dat;
|
||
when 16#01# => MAC_Srv(47 downto 32) <= wb_ipmux_reg_i.dat(15 downto 0);
|
||
when 16#02# => MAC_Mod(31 downto 0) <= wb_ipmux_reg_i.dat;
|
||
when 16#03# => MAC_Mod(47 downto 32) <= wb_ipmux_reg_i.dat(15 downto 0);
|
||
when 16#04# => IP_Srv <= wb_ipmux_reg_i.dat;
|
||
when 16#05# => IP_Mod <= wb_ipmux_reg_i.dat;
|
||
when 16#06# => UDP_SrvPrt(0) <= wb_ipmux_reg_i.dat(31 downto 16);
|
||
UDP_ModPrt(0) <= wb_ipmux_reg_i.dat(15 downto 0);
|
||
when 16#07# => UDP_SrvPrt(1) <= wb_ipmux_reg_i.dat(31 downto 16);
|
||
UDP_ModPrt(1) <= wb_ipmux_reg_i.dat(15 downto 0);
|
||
when 16#08# => UDP_SrvPrt(2) <= wb_ipmux_reg_i.dat(31 downto 16);
|
||
UDP_ModPrt(2) <= wb_ipmux_reg_i.dat(15 downto 0);
|
||
when 16#09# => UDP_SrvPrt(3) <= wb_ipmux_reg_i.dat(31 downto 16);
|
||
UDP_ModPrt(3) <= wb_ipmux_reg_i.dat(15 downto 0);
|
||
when 16#0A# => reg_tx_request <= wb_ipmux_reg_i.dat(0); -- Tx Request
|
||
reg_flush <= wb_ipmux_reg_i.dat(12 downto 8); -- Flush
|
||
when 16#10# => reg_div_ratio <= wb_ipmux_reg_i.dat;
|
||
when 16#11# => reg_numwords <= wb_ipmux_reg_i.dat(13 downto 0);
|
||
when 16#12# => reg_numpackets <= wb_ipmux_reg_i.dat( 9 downto 0);
|
||
when 16#13# => reg_udptstcntr <= wb_ipmux_reg_i.dat( 2 downto 0);
|
||
--when 16#14# => -- Read Only
|
||
when others => report ("### IPMUX_Registers: Illegal write address");
|
||
end case;
|
||
end if;
|
||
end if;
|
||
end process wb_write_reg;
|
||
|
||
-- assign the registers to the output pins
|
||
eth_regs_o.MAC_Mod <= MAC_Mod;
|
||
eth_regs_o.MAC_Srv <= MAC_Srv;
|
||
eth_regs_o.IP_Mod <= IP_Mod;
|
||
eth_regs_o.IP_Srv <= IP_Srv;
|
||
eth_regs_o.UDP_SrvPrt <= UDP_SrvPrt;
|
||
eth_regs_o.UDP_ModPrt <= UDP_ModPrt;
|
||
|
||
div_ratio <= reg_div_ratio;
|
||
numwords <= reg_numwords;
|
||
numpackets <= reg_numpackets;
|
||
udptstctrl <= reg_udptstcntr;
|
||
|
||
CPU_Tx.Request <= reg_tx_request;
|
||
Flush <= reg_flush;
|
||
|
||
-- ==============================================================================
|
||
-- Implement IPMUX Tx/Rx CPU interface via wb_ipmux_rx_tx_i and wb_ipmux_rx_tx_o
|
||
-- ==============================================================================
|
||
|
||
-- generate acknowledge output signal
|
||
gen_ack_txrx : process(Clk, Rst)
|
||
begin
|
||
if Rst = '1' then
|
||
ack_txrx <= '0';
|
||
elsif rising_edge(Clk) then
|
||
ack_txrx <= wb_ipmux_rx_tx_i.cyc and wb_ipmux_rx_tx_i.stb and not ack_txrx; -- because timing is always honoured
|
||
end if;
|
||
end process gen_ack_txrx;
|
||
wb_ipmux_rx_tx_o.ack <= ack_txrx;
|
||
|
||
-- generate other wishbone signals
|
||
wb_ipmux_rx_tx_o.err <= '0';
|
||
wb_ipmux_rx_tx_o.rty <= '0';
|
||
wb_ipmux_rx_tx_o.stall <= '0';
|
||
wb_ipmux_rx_tx_o.int <= '0';
|
||
|
||
-- generate wishbone write and read access signal
|
||
wr_tx <= wb_ipmux_rx_tx_i.cyc and wb_ipmux_rx_tx_i.stb and wb_ipmux_rx_tx_i.we;
|
||
rd_rx <= wb_ipmux_rx_tx_i.cyc and wb_ipmux_rx_tx_i.stb and not wb_ipmux_rx_tx_i.we;
|
||
|
||
cpu_rdreq <= rd_rx;
|
||
wb_ipmux_rx_tx_o.dat <= x"000" & "000" & cpu_rx.EOD & cpu_rx.D; -- assign wishbone data output
|
||
|
||
-- Check for address range
|
||
addr_range_check: process(wb_ipmux_rx_tx_i.adr, wr_tx, rd_rx, cpu_rx)
|
||
Constant AddrRange: integer := TX_PKT_BUF_ADRSIZE-1;
|
||
Variable Addr: std_logic_vector (TX_PKT_BUF_ADRSIZE-1 downto 0);
|
||
begin
|
||
Addr(Addr'left downto AddrRange) := (others => '0');
|
||
-- In case TX_PKT_BUF_ADRSIZE = 14 then Range 0x0000-0x7FFC (14 downto 2) = 0x0000-0x1FFF (12 downto 0)
|
||
Addr(AddrRange - 1 downto 0) := wb_ipmux_rx_tx_i.adr(AddrRange + 1 downto 2);
|
||
case to_integer(unsigned(Addr)) is
|
||
when 16#0000# to MAX_RESERV_PKT_BUF => CPU_TX.Addr <= Addr;
|
||
CPU_Tx.WrEn <= wr_tx;
|
||
when others => CPU_TX.Addr <= (others => '0');
|
||
CPU_Tx.WrEn <= '0';
|
||
report ("### IPMUX_CPU_RX_TX: Illegal address");
|
||
end case;
|
||
end process addr_range_check;
|
||
|
||
CPU_Tx.D <= wb_ipmux_rx_tx_i.dat(15 downto 0);
|
||
CPU_Tx.EOP <= wb_ipmux_rx_tx_i.dat(16);
|
||
|
||
end architecture rtl ; -- of ipmux_regs_and_rxtxcpu
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.TxStreamSel
|
||
-- Last modified : Mon Jun 29 14:49:31 2015.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
|
||
entity TxStreamSel is
|
||
port (
|
||
Clk : in std_logic;
|
||
ConnectReq : in std_logic;
|
||
Connected : out std_logic;
|
||
Dout : out std_logic_vector(15 downto 0);
|
||
EODout : out std_logic;
|
||
Packet : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Packet_RdReq : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
RdReqOut : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
RdReqin : in std_logic;
|
||
Rst : in std_logic;
|
||
Stream : out natural range NUM_UDP_PRTS-1 downto 0;
|
||
TXi : in dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
TxStreamDebug : out std_logic_vector(11 downto 0);
|
||
Validin : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Validout : out std_logic);
|
||
end entity TxStreamSel;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.TxStreamSel.fsm
|
||
-- Last modified : Mon Jun 29 14:49:31 2015.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
architecture fsm of TxStreamSel is
|
||
|
||
type state_type is (Idle, SearchConnect, ReadUntilEOP, State_Connected) ;
|
||
signal state : state_type ; -- Current State
|
||
|
||
Signal StreamPointer: Natural Range NUM_UDP_PRTS - 1 Downto 0;
|
||
|
||
begin
|
||
|
||
TxStreamDebug(3 downto 0) <= std_logic_vector(to_unsigned(2**StreamPointer,4));
|
||
TxStreamDebug(4) <= ConnectReq;
|
||
TxStreamDebug(7 downto 5) <= (others => '0');
|
||
TxStreamDebug(11 downto 8) <= packet;
|
||
|
||
-- Pipeline between entity "TxFifos" and "TxBuffers/tx_data2buf"
|
||
-- This will ease the timing of the system
|
||
Process (Clk, Rst)
|
||
Begin
|
||
If Rst = '1' Then
|
||
Stream <= 0;
|
||
Dout <= (Others => '0');
|
||
EODout <= '0';
|
||
Validout <= '0';
|
||
ElsIf Rising_Edge(Clk) Then
|
||
-- Pipeline between entity "TxFifos" and "TxBuffers/tx_data2buf"
|
||
-- This will ease the timing of the system
|
||
Stream <= StreamPointer;
|
||
Dout <= TXi(StreamPointer).D;
|
||
EODout <= TXi(StreamPointer).EOD;
|
||
If state = ReadUntilEOP Then
|
||
If Validin(StreamPointer) = '0' Or RdReqin = '1' Then
|
||
Validout <= Validin(StreamPointer);
|
||
Else
|
||
Validout <= '0';
|
||
End If;
|
||
Else
|
||
Validout <= '0';
|
||
End If;
|
||
End If;
|
||
End Process;
|
||
|
||
process (state, StreamPointer)
|
||
Begin
|
||
-- By default, do not RdReqout any of the input FIFOs
|
||
RdReqout <= (Others => '0');
|
||
If state = ReadUntilEOP Then
|
||
-- Overrule the RdReqout <= (Others => '0') above if needed:
|
||
RdReqout(StreamPointer) <= '1';
|
||
End If;
|
||
End Process;
|
||
|
||
state_decoding: Process (Clk, Rst) Is
|
||
Begin
|
||
If (Rst = '1') Then
|
||
state <= Idle ;
|
||
StreamPointer <= 0;
|
||
Connected <= '0';
|
||
Packet_RdReq <= (others => '0');
|
||
ElsIf (rising_edge(Clk)) Then
|
||
Case state Is
|
||
When Idle =>
|
||
-- One of the input pipelines contains data
|
||
-- and the TxBuffer is ready to accept a connection
|
||
If (Unsigned(Packet) /= 0 And ConnectReq = '1') Then
|
||
state <= SearchConnect ;
|
||
-- IncStreamPointer:
|
||
-- Forcing a Stream Increment forces a round-
|
||
-- robbin (otherwise the input fifo that keeps
|
||
-- "not-empty" asserted, holds the stream)
|
||
If StreamPointer = NUM_UDP_PRTS - 1 Then
|
||
StreamPointer <= 0;
|
||
Else
|
||
StreamPointer <= StreamPointer + 1;
|
||
End If;
|
||
Else
|
||
state <= Idle;
|
||
Connected <= '0';
|
||
End If ;
|
||
|
||
When SearchConnect =>
|
||
If (Packet(StreamPointer) = '1') Then
|
||
state <= State_Connected;
|
||
|
||
-- Read one entry from the fifo that keeps track of the amount of packets in the data fifo
|
||
Packet_RdReq(StreamPointer) <= '1';
|
||
Connected <= '1';
|
||
|
||
-- The pointed input doesn't contain data
|
||
Else
|
||
state <= SearchConnect;
|
||
-- IncStreamPointer:
|
||
If StreamPointer = NUM_UDP_PRTS - 1 Then
|
||
StreamPointer <= 0;
|
||
Else
|
||
StreamPointer <= StreamPointer + 1;
|
||
End If;
|
||
End If ;
|
||
|
||
When State_Connected =>
|
||
-- Signal "ConnectReq" is the handshake with the tx_data2buf state machine.
|
||
-- If connect = 0 then the "tx_data2buf" machine advanced (i.e. it got out of
|
||
-- the Idle state).
|
||
Packet_RdReq(StreamPointer) <= '0';
|
||
If (ConnectReq = '0') Then
|
||
state <= ReadUntilEOP ;
|
||
Connected <= '0';
|
||
Else
|
||
state <= State_Connected ;
|
||
Connected <= '1';
|
||
End If ;
|
||
|
||
When ReadUntilEOP =>
|
||
If (TXi(StreamPointer).EOD = '1') Then
|
||
state <= Idle ;
|
||
Connected <= '0';
|
||
Else
|
||
state <= ReadUntilEOP ;
|
||
Connected <= '0';
|
||
End If ;
|
||
|
||
End Case ;
|
||
End If ;
|
||
End Process state_decoding ;
|
||
|
||
end architecture fsm ; -- of TxStreamSel
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.txfifos
|
||
-- Last modified : Mon Jun 29 14:23:22 2015.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.genram_pkg.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
|
||
entity txfifos is
|
||
port (
|
||
Flush : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Full : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Packet : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Packet_RdReq : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
PacketsDone : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
RdClk : in std_logic;
|
||
RdReq : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Rst : in std_logic;
|
||
TXi : in dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
TXo : out dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
Valid : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
WrClk : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
WrReq : in std_logic_vector(NUM_UDP_PRTS-1 downto 0));
|
||
end entity txfifos;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.txfifos.rtl
|
||
-- Last modified : Mon Jun 29 14:23:22 2015.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
architecture rtl of txfifos is
|
||
component Reg1En
|
||
Port
|
||
(
|
||
Clk : in std_logic;
|
||
En : in std_logic;
|
||
D : in std_logic;
|
||
Q : out std_logic;
|
||
Rst : in std_logic
|
||
);
|
||
end component ;
|
||
|
||
constant fifo_size: natural := 8192;
|
||
constant full_threshold: natural := fifo_size - 16;
|
||
|
||
constant d_i_null: std_logic_vector(0 downto 0) := (others => '0');
|
||
|
||
type std_logic_v9array is array ( natural range <> ) of std_logic_vector(8 downto 0);
|
||
type std_logic_v18array is array ( natural range <> ) of std_logic_vector(17 downto 0);
|
||
|
||
signal Din_Intern : std_logic_v18array(NUM_UDP_PRTS-1 downto 0);
|
||
signal Dout_Intern : std_logic_v18array(NUM_UDP_PRTS-1 downto 0);
|
||
signal Empty_Intern : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal Valid_Intern : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal NotEmpty_Intern : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal RdReq_Intern : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal Rst_Intern : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal Rst_Intern_n : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal WrReq_EOD : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal Empty_EOD : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal Full_data : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal Full_EOD : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
|
||
begin
|
||
|
||
GenTxFifos: For i In 0 to NUM_UDP_PRTS-1 Generate
|
||
|
||
Din_Intern(i)(17) <= '0';
|
||
Din_Intern(i)(16) <= TXi(i).EOD;
|
||
Din_Intern(i)(15 downto 0) <= TXi(i).D;
|
||
TXo(i).EOD <= Dout_Intern(i)(16);
|
||
TXo(i).D <= Dout_Intern(i)(15 downto 0);
|
||
|
||
NotEmpty_Intern(i) <= Not Empty_Intern(i);
|
||
RdReq_Intern(i) <= Not Valid_Intern(i) Or RdReq(i);
|
||
Valid(i) <= Valid_Intern(i);
|
||
Full(i) <= Full_data(i) Or Full_EOD(i);
|
||
Rst_Intern(i) <= Flush(i) Or Rst;
|
||
Rst_Intern_n(i) <= not(Flush(i) Or Rst);
|
||
|
||
ValidReg: Reg1En
|
||
Port Map
|
||
(
|
||
Clk => RdClk,
|
||
En => RdReq_Intern(i),
|
||
D => NotEmpty_Intern(i),
|
||
Q => Valid_Intern(i),
|
||
Rst => Rst_Intern(i)
|
||
);
|
||
|
||
-- There are two FIFOs implemented for each channel:
|
||
-- 1) tx_data_fifo that receives the packet payload data (in 16 bit words, plus an End Of Data bit)
|
||
-- 2) tx_eod_fifo is written only when an End Of Data is written to to tx_data_fifo
|
||
-- The latter FIFO holds no actual data, rather the flag structure of the FIFO is used to signal
|
||
-- that a complete packet (including EOD) was written to the data FIFO such that it is ready to be
|
||
-- readout in one go.
|
||
-- This avoids the situation where an input stream is serviced by IPMUX while the packet trailer (EOD)
|
||
-- is still under way (which may take any time) thereby blocking transfers of any other IPMUX input streams.
|
||
|
||
tx_data_fifo: generic_async_fifo
|
||
generic map(
|
||
g_data_width => 18,
|
||
g_size => fifo_size,
|
||
g_with_rd_empty => true,
|
||
g_with_wr_almost_full => true,
|
||
g_almost_full_threshold => full_threshold
|
||
)
|
||
port map
|
||
(
|
||
rst_n_i => Rst_Intern_n(i),
|
||
clk_wr_i => WrClk(i),
|
||
d_i => Din_Intern(i),
|
||
we_i => WrReq(i),
|
||
wr_empty_o => open,
|
||
wr_full_o => open,
|
||
wr_almost_empty_o => open,
|
||
wr_almost_full_o => Full_data(i),
|
||
wr_count_o => open,
|
||
clk_rd_i => RdClk,
|
||
q_o => Dout_Intern(i),
|
||
rd_i => RdReq_Intern(i),
|
||
rd_empty_o => Empty_Intern(i),
|
||
rd_full_o => open,
|
||
rd_almost_empty_o => open,
|
||
rd_almost_full_o => open,
|
||
rd_count_o => open
|
||
);
|
||
|
||
WrReq_EOD(i) <= WrReq(i) And TXi(i).EOD;
|
||
Packet(i) <= Not Empty_EOD(i);
|
||
|
||
-- PacketsDone signals weather a stream is done with the transfer of a complete packet from it's tx_data_fifo to the packet buffer.
|
||
-- so as soon as the tx_eod_fifo is not empty (Empty_EOD(i) = '0') then there is data to be shipped for the associated stream, until
|
||
-- all data out of the tx_data_fifo was read, up to the EOD bit (Dout_Intern(i)(16) = '1')
|
||
process (RdClk, Rst_Intern_n(i))
|
||
begin
|
||
if Rst_Intern_n(i) = '0' then
|
||
PacketsDone(i) <= '1';
|
||
elsif rising_edge(RdClk) then
|
||
if Empty_EOD(i) = '0' then
|
||
PacketsDone(i) <= '0';
|
||
elsif Dout_Intern(i)(16) = '1' then
|
||
PacketsDone(i) <= '1';
|
||
end if;
|
||
end if;
|
||
end process;
|
||
|
||
tx_eod_fifo: generic_async_fifo
|
||
generic map(
|
||
g_data_width => 1,
|
||
g_size => fifo_size,
|
||
g_with_rd_empty => true,
|
||
g_with_wr_almost_full => true,
|
||
g_almost_full_threshold => full_threshold
|
||
)
|
||
port map
|
||
(
|
||
rst_n_i => Rst_Intern_n(i),
|
||
clk_wr_i => WrClk(i),
|
||
d_i => d_i_null, -- Only FIFO flag functionality is used (no data input)
|
||
we_i => WrReq_EOD(i), -- Write when EOD is signalled
|
||
wr_empty_o => open,
|
||
wr_full_o => open,
|
||
wr_almost_empty_o => open,
|
||
wr_almost_full_o => Full_EOD(i),
|
||
wr_count_o => open,
|
||
clk_rd_i => RdClk,
|
||
q_o => open,
|
||
rd_i => Packet_RdReq(i),
|
||
rd_empty_o => Empty_EOD(i),
|
||
rd_full_o => open,
|
||
rd_almost_empty_o => open,
|
||
rd_almost_full_o => open,
|
||
rd_count_o => open
|
||
);
|
||
End Generate GenTxFifos;
|
||
end architecture rtl ; -- of txfifos
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.rxfifos
|
||
-- Last modified : Mon Sep 15 10:25:37 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.genram_pkg.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
|
||
entity rxfifos is
|
||
port (
|
||
Empty : out std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
Flush : in std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
Full : out std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
RXi : in dbus_type_array(NUM_UDP_PRTS downto 0);
|
||
RXo : out dbus_type_array(NUM_UDP_PRTS downto 0);
|
||
RdClk : in std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
RdReq : in std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
Rst : in std_logic;
|
||
WrClk : in std_logic;
|
||
WrReq : in std_logic_vector(NUM_UDP_PRTS downto 0));
|
||
end entity rxfifos;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.rxfifos.rtl
|
||
-- Last modified : Mon Sep 15 10:25:37 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
architecture rtl of rxfifos is
|
||
|
||
type std_logic_v9array is array ( natural range <> ) of std_logic_vector(8 downto 0);
|
||
type std_logic_v18array is array ( natural range <> ) of std_logic_vector(17 downto 0);
|
||
|
||
Signal Din_Intern: std_logic_v18array(NUM_UDP_PRTS downto 0);
|
||
Signal Dout_Intern: std_logic_v18array(NUM_UDP_PRTS downto 0);
|
||
Signal Rst_Intern_n: std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
|
||
begin
|
||
|
||
GenRxFifos: For i In 0 to NUM_UDP_PRTS Generate
|
||
|
||
Din_Intern(i)(17) <= '0';
|
||
Din_Intern(i)(16) <= RXi(i).EOD;
|
||
Din_Intern(i)(15 downto 0) <= RXi(i).D;
|
||
RXo(i).EOD <= Dout_Intern(i)(16);
|
||
RXo(i).D <= Dout_Intern(i)(15 downto 0);
|
||
Rst_Intern_n(i) <= not(Flush(i) Or Rst);
|
||
|
||
rxfifo: generic_async_fifo
|
||
generic map(
|
||
g_data_width => 18,
|
||
g_size => 8192,
|
||
g_with_rd_empty => true,
|
||
g_with_wr_almost_full => true,
|
||
g_almost_full_threshold => 8176
|
||
)
|
||
port map
|
||
(
|
||
rst_n_i => Rst_Intern_n(i),
|
||
clk_wr_i => WrClk,
|
||
d_i => Din_Intern(i),
|
||
we_i => WrReq(i),
|
||
wr_empty_o => open,
|
||
wr_full_o => open,
|
||
wr_almost_empty_o => open,
|
||
wr_almost_full_o => Full(i),
|
||
wr_count_o => open,
|
||
clk_rd_i => RdClk(i),
|
||
q_o => Dout_Intern(i),
|
||
rd_i => RdReq(i),
|
||
rd_empty_o => Empty(i),
|
||
rd_full_o => open,
|
||
rd_almost_empty_o => open,
|
||
rd_almost_full_o => open,
|
||
rd_count_o => open
|
||
);
|
||
End Generate GenRxFifos;
|
||
|
||
end architecture rtl ; -- of rxfifos
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.RxStreamSel
|
||
-- Last modified : Fri Nov 22 14:59:51 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
|
||
entity RxStreamSel is
|
||
port (
|
||
Din : in std_logic_vector(15 downto 0);
|
||
EODin : in std_logic;
|
||
EOFin : in std_logic;
|
||
Full : in std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
Fullout : out std_logic;
|
||
RXo : out dbus_type_array(NUM_UDP_PRTS downto 0);
|
||
SODin : in std_logic;
|
||
Stream : in std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
WrReq : out std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
WrReqin : in std_logic);
|
||
end entity RxStreamSel;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.RxStreamSel.rtl
|
||
-- Last modified : Fri Nov 22 14:59:51 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
architecture rtl of RxStreamSel is
|
||
|
||
begin
|
||
Process (Full, Din, EOFin, EODin, Stream, WrReqin)
|
||
-- Process (Full, Din, EOFin, EODin, SODin, Stream, WrReqin)
|
||
Begin
|
||
-- Default is all zero
|
||
Fullout <= '0';
|
||
For i In NUM_UDP_PRTS downto 0 Loop
|
||
RXo(i).D <= (Others => '0');
|
||
-- RXo(i).SOD <= '0';
|
||
RXo(i).EOD <= '0';
|
||
WrReq(i) <= '0';
|
||
End Loop;
|
||
|
||
-- Now connect the selected stream
|
||
For i In Stream'Range Loop
|
||
If Stream(i) = '1' Then
|
||
RXo(i).D <= Din;
|
||
-- On the data link layer, where the transactions with the MAC take place, a <20>frame<6D> is defined
|
||
-- as all data that are signaled <20>rx_data_valid<69> by the MAC. These data range from the first byte
|
||
-- after the Start of Frame Delimiter (SFD) to the last data byte before the first Frame Control
|
||
-- Sequence (FCS).
|
||
-- Note that for Ethernet v2 framing (see also: http://en.wikipedia.org/wiki/EtherType) this
|
||
-- also includes padded data that might have been inserted to ensure that the frame length is
|
||
-- at least 64 bytes.
|
||
-- Start and End of Data are asserted at the start and end of the
|
||
-- payload data of the mac frame (without padded data)
|
||
-- RXo(i).SOD <= SODin;
|
||
RXo(i).EOD <= EODin;
|
||
WrReq(i) <= WrReqin;
|
||
Fullout <= Full(i);
|
||
End If;
|
||
End Loop;
|
||
-- The exception is the CPU stream where the End Of Frame Signalling from the MAC is routed directly to
|
||
-- the EOD of the CPU channel. There is no other means to know the end of a Frame since unknown Frames
|
||
-- are not decoded.
|
||
RXo(NUM_UDP_PRTS).EOD <= EOFin;
|
||
End Process;
|
||
|
||
end architecture rtl ; -- of RxStreamSel
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.rx_buf2data
|
||
-- Last modified : Tue Oct 29 13:57:00 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
|
||
entity rx_buf2data is
|
||
generic(
|
||
abits : integer := 15);
|
||
port (
|
||
Clk : in std_logic;
|
||
Din : in std_logic_vector(15 downto 0);
|
||
EODout : out std_logic;
|
||
EOFin : in std_logic;
|
||
Empty : in std_logic;
|
||
FragID : out std_logic_vector(15 downto 0);
|
||
FragOff : out std_logic_vector(11 downto 0);
|
||
Full : in std_logic;
|
||
MoreFrags : out std_logic;
|
||
PktRdPtr : out std_logic_vector(abits-1 downto 0);
|
||
RdAddr : out std_logic_vector(abits-1 downto 0);
|
||
Rst : in std_logic;
|
||
SODout : out std_logic;
|
||
Stream : out std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
UDP_CheckSumErr : out std_logic;
|
||
WrReq : out std_logic;
|
||
eth_regs_i : in eth_regs_type);
|
||
end entity rx_buf2data;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.rx_buf2data.fsm
|
||
-- Last modified : Tue Oct 29 13:57:00 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
architecture fsm of rx_buf2data is
|
||
|
||
-- State Machine Options:
|
||
-- Clock : Clk (Rising edge).
|
||
-- State assignment : Enumerate.
|
||
-- State decoding : Case construct.
|
||
-- Actions on transitions : Clocked.
|
||
-- Actions on states : Clocked.
|
||
|
||
type state_type is (Idle, StartMemAcc, ReadHeader, HeaderChecks, StatusOut,
|
||
TransferData, TransferOtherData) ;
|
||
signal state : state_type ; -- Current State
|
||
Signal Offset: Integer Range 0 to MAX_RESERV_PKT_BUF;
|
||
Signal PktPtr: Unsigned(abits-1 downto 0);
|
||
Signal ErrorVector: Unsigned(7 downto 0);
|
||
Signal WrReqIntern: Std_Logic;
|
||
Signal SOD_Intern: Std_Logic;
|
||
Signal StreamIntern: Std_Logic_Vector(NUM_UDP_PRTS downto 0);
|
||
|
||
|
||
begin
|
||
--It takes MEM_ACC_TICKS pipeline stages to fetch
|
||
--the data, henche "Idx - MEM_ACC_TICKS"
|
||
---- One may want to check if EOF is set at the proper location
|
||
---- Although this is equal to checking THIS implementation.
|
||
---- EOF should be set on address "Offset <= IP_HDR + To_Integer(IP_Length/2) - 1;"
|
||
---- Note: IP_Length is in bytes, NOT in 16 bit words!
|
||
---- Also note that for Ethernet v2 framing EOF is signalled including padded data
|
||
---- that might have been added to the MAC frame to ensure that the frame length is
|
||
---- at least 64 bytes! In such case EOF does not correspond to
|
||
---- "IP_HDR + To_Integer(IP_Length/2) - 1;"
|
||
--Note 1:
|
||
--During "TransferData" or "TransferOtherData"
|
||
--a Packet may be padded with zeros. Buffer
|
||
--reading should be done until EOP occus but
|
||
--WrReq should only be asserted during valid
|
||
--Payload data.
|
||
--
|
||
--Note 2:
|
||
--The UDP_CheckSum is calculated during
|
||
--"TransferData" and NOT during "TransferOtherData"
|
||
--(which may be used by other protocols).
|
||
--Mind the Full situation while the last word
|
||
--is transferred...
|
||
--Leave "TransferData" only when the last
|
||
--WrRequest is asserted due to Payload_Length = 0
|
||
--(thus WrReqIntern = '1').
|
||
--With padded packets wait for the MAC to signal
|
||
--EOFin (Payload_Length got 0 earlier).
|
||
--
|
||
--Mind the Full situation while the last word
|
||
--is transferred...
|
||
--Leave "TransferOtherData" only when the last
|
||
--WrRequest is asserted due to EOFin = '1' and
|
||
--WrReqIntern = '1'.
|
||
--
|
||
RdAddr <= Std_Logic_Vector(PktPtr + To_Unsigned(Offset,RX_PKT_BUF_ADRSIZE));
|
||
PktRdPtr <= Std_Logic_Vector(PktPtr);
|
||
WrReq <= WrReqIntern;
|
||
SODout <= SOD_Intern;
|
||
Stream <= StreamIntern;
|
||
|
||
|
||
state_decoding: process (Clk, Rst) is
|
||
Variable Packet_HeaderRegFile: std_logic_v16array(MAC_HDR_CNT + IP_HDR_CNT + UDP_HDR_CNT -1 downto 0);
|
||
Variable IP_Length: Unsigned(15 downto 0);
|
||
Variable Payload_Length: Unsigned(15 downto 0);
|
||
Variable IP_CheckSum : Unsigned(31 downto 0);
|
||
Variable UDP_CheckSum : Unsigned(31 downto 0);
|
||
Variable Idx: Integer Range 0 to 31;
|
||
Constant MEM_ACC_TICKS : Positive := 1;
|
||
|
||
begin
|
||
if (Rst = '1') then
|
||
state <= Idle ;
|
||
-- Initialize:
|
||
For i In Packet_HeaderRegFile'Range Loop
|
||
Packet_HeaderRegFile(i) := (Others => '0');
|
||
End Loop;
|
||
Idx := 0;
|
||
Offset <= MAC_HDR + Idx;
|
||
WrReqIntern <= '0';
|
||
IP_CheckSum := (Others => '0');
|
||
UDP_CheckSum := (Others => '0');
|
||
IP_Length := (Others => '0');
|
||
Payload_Length := (Others => '0');
|
||
ErrorVector <= (Others => '0');
|
||
FragID <= (Others => '0');
|
||
MoreFrags <= '0';
|
||
FragOff <= (Others => '0');
|
||
StreamIntern <= (NUM_UDP_PRTS => '1', Others =>'0');
|
||
SOD_Intern <= '0';
|
||
EODout <= '0';
|
||
PktPtr <= (Others => '0');
|
||
UDP_CheckSumErr <= '0';
|
||
elsif (rising_edge(Clk)) then
|
||
lbl_state : case state is
|
||
when Idle =>
|
||
if (Empty = '0') then
|
||
state <= StartMemAcc ;
|
||
Idx := Idx + 1;
|
||
Offset <= MAC_HDR + Idx;
|
||
UDP_CheckSumErr <= '0';
|
||
|
||
else
|
||
state <= Idle ;
|
||
-- Initialize:
|
||
For i In Packet_HeaderRegFile'Range Loop
|
||
Packet_HeaderRegFile(i) := (Others => '0');
|
||
End Loop;
|
||
Idx := 0;
|
||
Offset <= MAC_HDR + Idx;
|
||
WrReqIntern <= '0';
|
||
IP_CheckSum := (Others => '0');
|
||
UDP_CheckSum := (Others => '0');
|
||
IP_Length := (Others => '0');
|
||
Payload_Length := (Others => '0');
|
||
ErrorVector <= (Others => '0');
|
||
FragID <= (Others => '0');
|
||
MoreFrags <= '0';
|
||
FragOff <= (Others => '0');
|
||
StreamIntern <= (NUM_UDP_PRTS => '1', Others =>'0');
|
||
SOD_Intern <= '0';
|
||
EODout <= '0';
|
||
end if ;
|
||
when StartMemAcc =>
|
||
if (Idx = MEM_ACC_TICKS) then
|
||
state <= ReadHeader ;
|
||
Packet_HeaderRegFile(Idx - MEM_ACC_TICKS) := Din;
|
||
If (Idx - MEM_ACC_TICKS) >= IP_HDR and (Idx - MEM_ACC_TICKS) < UDP_HDR Then
|
||
IP_CheckSum := IP_CheckSum + Unsigned(Din);
|
||
End If;
|
||
If (Idx - MEM_ACC_TICKS) >= UDP_HDR and (Idx - MEM_ACC_TICKS) < PAYLOAD Then
|
||
UDP_CheckSum := UDP_CheckSum + Unsigned(Din);
|
||
End If;
|
||
Idx := Idx + 1;
|
||
Offset <= MAC_HDR + Idx;
|
||
|
||
else
|
||
state <= StartMemAcc ;
|
||
Idx := Idx + 1;
|
||
Offset <= MAC_HDR + Idx;
|
||
UDP_CheckSumErr <= '0';
|
||
|
||
end if ;
|
||
when ReadHeader =>
|
||
if (Idx = MEM_ACC_TICKS + PAYLOAD) then
|
||
state <= HeaderChecks ;
|
||
IP_CheckSum (15 Downto 0) := Not(IP_CheckSum(31 downto 16) + IP_CheckSum(15 downto 0));
|
||
IP_Length := Unsigned(Packet_HeaderRegFile(IP_HDR + IP_IDX_LEN));
|
||
|
||
-- "The Default Stream"
|
||
StreamIntern <= (NUM_UDP_PRTS => '1', Others =>'0');
|
||
Offset <= 0;
|
||
Payload_Length := (IP_Length / 2) + MAC_HDR_CNT;
|
||
--
|
||
|
||
If Packet_HeaderRegFile(MAC_HDR + MAC_IDX_LEN) /= ETH_TYPE_II Then ErrorVector (0) <= '1'; End If;
|
||
If IP_CheckSum (15 Downto 0) /= 0 Then ErrorVector (1) <= '1'; End If;
|
||
If Packet_HeaderRegFile(IP_HDR + IP_IDX_VER_LEN_TOS)(IP_VER_LEN'Range) /= IP_VER_LEN Then ErrorVector (2) <= '1'; End If;
|
||
If Packet_HeaderRegFile(IP_HDR + IP_IDX_TTL_PROT)(IP_PROT_UDP'Range) /= IP_PROT_UDP Then ErrorVector (3) <= '1'; End If;
|
||
|
||
SOD_Intern <= '1';
|
||
else
|
||
state <= ReadHeader ;
|
||
Packet_HeaderRegFile(Idx - MEM_ACC_TICKS) := Din;
|
||
If (Idx - MEM_ACC_TICKS) >= IP_HDR and (Idx - MEM_ACC_TICKS) < UDP_HDR Then
|
||
IP_CheckSum := IP_CheckSum + Unsigned(Din);
|
||
End If;
|
||
If (Idx - MEM_ACC_TICKS) >= UDP_HDR and (Idx - MEM_ACC_TICKS) < PAYLOAD Then
|
||
UDP_CheckSum := UDP_CheckSum + Unsigned(Din);
|
||
End If;
|
||
Idx := Idx + 1;
|
||
Offset <= MAC_HDR + Idx;
|
||
|
||
end if ;
|
||
when HeaderChecks =>
|
||
if (ErrorVector /= 0) then
|
||
state <= TransferOtherData ;
|
||
If Full = '0' Then
|
||
Offset <= Offset + 1;
|
||
If SOD_intern = '1' And WrReqIntern = '1' Then
|
||
SOD_intern <= '0';
|
||
End If;
|
||
WrReqIntern <= '1';
|
||
Else
|
||
WrReqIntern <= '0';
|
||
End If;
|
||
else
|
||
state <= StatusOut ;
|
||
FragID <= Packet_HeaderRegFile(IP_HDR + IP_IDX_ID);
|
||
MoreFrags <= Packet_HeaderRegFile(IP_HDR + IP_IDX_FLAGS_FRAGOFF)(IP_FLAGS_MOREFRAGS_INDEX);
|
||
FragOff <= Packet_HeaderRegFile(IP_HDR + IP_IDX_FLAGS_FRAGOFF)(IP_FRAGOFF_RANGE);
|
||
|
||
-- "The Default Stream"
|
||
StreamIntern <= (NUM_UDP_PRTS => '1', Others =>'0');
|
||
Offset <= 0;
|
||
Payload_Length := (IP_Length / 2) + MAC_HDR_CNT;
|
||
--
|
||
|
||
For i In NUM_UDP_PRTS - 1 downto 0 Loop
|
||
If Unsigned(eth_regs_i.UDP_ModPrt(i)) = Unsigned(Packet_HeaderRegFile(UDP_HDR + UDP_IDX_DSTPRT)) Then
|
||
StreamIntern(i) <= '1';
|
||
Offset <= PAYLOAD;
|
||
Payload_Length := (IP_Length / 2) - IP_HDR_CNT - UDP_HDR_CNT;
|
||
StreamIntern(NUM_UDP_PRTS) <= '0';
|
||
End If;
|
||
End Loop;
|
||
|
||
-- PrepareUDP_CheckSum:
|
||
-- For UDP Checksum calculation the items in the UDP header (UDP Source Port,
|
||
-- UDP Destination Port, UDP Length and UDP Checksum) were already collected
|
||
-- during header reading.
|
||
-- Add the UDP Pseudo-Header that contains:
|
||
-- IP Source address
|
||
-- IP Destination address
|
||
-- x"00" & Protocol
|
||
-- UDP_Length (note that actually the UDP_Length is calculated twice!)
|
||
UDP_CheckSum := UDP_CheckSum +
|
||
(x"0000" & Unsigned(Packet_HeaderRegFile(IP_HDR + IP_IDX_IP_SRC))) +
|
||
(x"0000" & Unsigned(Packet_HeaderRegFile(IP_HDR + IP_IDX_IP_SRC + 1))) +
|
||
(x"0000" & Unsigned(Packet_HeaderRegFile(IP_HDR + IP_IDX_IP_DST))) +
|
||
(x"0000" & Unsigned(Packet_HeaderRegFile(IP_HDR + IP_IDX_IP_DST + 1))) +
|
||
(x"0000" & x"00" & Unsigned(Packet_HeaderRegFile(IP_HDR + IP_IDX_TTL_PROT)(7 downto 0))) +
|
||
(x"0000" & Unsigned(Packet_HeaderRegFile(UDP_HDR + UDP_IDX_LEN)));
|
||
end if ;
|
||
when StatusOut =>
|
||
if (StreamIntern(NUM_UDP_PRTS) = '1') then
|
||
state <= TransferOtherData ;
|
||
If Full = '0' Then
|
||
Offset <= Offset + 1;
|
||
If SOD_intern = '1' And WrReqIntern = '1' Then
|
||
SOD_intern <= '0';
|
||
End If;
|
||
WrReqIntern <= '1';
|
||
Else
|
||
WrReqIntern <= '0';
|
||
End If;
|
||
else
|
||
state <= TransferData ;
|
||
If Full = '0' Then
|
||
Offset <= Offset + 1;
|
||
If SOD_intern = '1' And WrReqIntern = '1' Then
|
||
SOD_intern <= '0';
|
||
End If;
|
||
If Payload_Length = 1 Then
|
||
EODout <= '1';
|
||
Else
|
||
EODout <= '0';
|
||
End If;
|
||
If Payload_Length > 0 Then
|
||
Payload_Length := Payload_Length - 1;
|
||
WrReqIntern <= '1';
|
||
UDP_CheckSum := UDP_CheckSum + (x"0000" & Unsigned(Din));
|
||
Else
|
||
WrReqIntern <= '0';
|
||
End If;
|
||
Else
|
||
WrReqIntern <= '0';
|
||
End If;
|
||
end if ;
|
||
when TransferData =>
|
||
if (EOFin = '1' And Payload_Length = 0) then
|
||
state <= Idle ;
|
||
PktPtr <= PktPtr + To_Unsigned(Offset,RX_PKT_BUF_ADRSIZE);
|
||
-- FinalizeUDP_CheckSum:
|
||
-- Add the last data word
|
||
If WrReqIntern = '1' Then
|
||
UDP_CheckSum := UDP_CheckSum + (x"0000" & Unsigned(Din));
|
||
End If;
|
||
|
||
UDP_CheckSum (15 Downto 0) := Not(UDP_CheckSum(31 downto 16) + UDP_CheckSum(15 downto 0));
|
||
If UDP_CheckSum (15 Downto 0) /= 0 Then
|
||
UDP_CheckSumErr <= '1';
|
||
Else
|
||
UDP_CheckSumErr <= '0';
|
||
End If;
|
||
|
||
-- Initialize:
|
||
For i In Packet_HeaderRegFile'Range Loop
|
||
Packet_HeaderRegFile(i) := (Others => '0');
|
||
End Loop;
|
||
Idx := 0;
|
||
Offset <= MAC_HDR + Idx;
|
||
WrReqIntern <= '0';
|
||
IP_CheckSum := (Others => '0');
|
||
UDP_CheckSum := (Others => '0');
|
||
IP_Length := (Others => '0');
|
||
Payload_Length := (Others => '0');
|
||
ErrorVector <= (Others => '0');
|
||
FragID <= (Others => '0');
|
||
MoreFrags <= '0';
|
||
FragOff <= (Others => '0');
|
||
StreamIntern <= (NUM_UDP_PRTS => '1', Others =>'0');
|
||
SOD_Intern <= '0';
|
||
EODout <= '0';
|
||
else
|
||
state <= TransferData ;
|
||
If Full = '0' Then
|
||
Offset <= Offset + 1;
|
||
If SOD_intern = '1' And WrReqIntern = '1' Then
|
||
SOD_intern <= '0';
|
||
End If;
|
||
If Payload_Length = 1 Then
|
||
EODout <= '1';
|
||
Else
|
||
EODout <= '0';
|
||
End If;
|
||
If Payload_Length > 0 Then
|
||
Payload_Length := Payload_Length - 1;
|
||
WrReqIntern <= '1';
|
||
UDP_CheckSum := UDP_CheckSum + (x"0000" & Unsigned(Din));
|
||
Else
|
||
WrReqIntern <= '0';
|
||
End If;
|
||
Else
|
||
WrReqIntern <= '0';
|
||
End If;
|
||
end if ;
|
||
when TransferOtherData =>
|
||
if (EOFin = '1' And WrReqIntern = '1') then
|
||
state <= Idle ;
|
||
PktPtr <= PktPtr + To_Unsigned(Offset,RX_PKT_BUF_ADRSIZE);
|
||
-- Initialize:
|
||
For i In Packet_HeaderRegFile'Range Loop
|
||
Packet_HeaderRegFile(i) := (Others => '0');
|
||
End Loop;
|
||
Idx := 0;
|
||
Offset <= MAC_HDR + Idx;
|
||
WrReqIntern <= '0';
|
||
IP_CheckSum := (Others => '0');
|
||
UDP_CheckSum := (Others => '0');
|
||
IP_Length := (Others => '0');
|
||
Payload_Length := (Others => '0');
|
||
ErrorVector <= (Others => '0');
|
||
FragID <= (Others => '0');
|
||
MoreFrags <= '0';
|
||
FragOff <= (Others => '0');
|
||
StreamIntern <= (NUM_UDP_PRTS => '1', Others =>'0');
|
||
SOD_Intern <= '0';
|
||
EODout <= '0';
|
||
else
|
||
state <= TransferOtherData ;
|
||
If Full = '0' Then
|
||
Offset <= Offset + 1;
|
||
If SOD_intern = '1' And WrReqIntern = '1' Then
|
||
SOD_intern <= '0';
|
||
End If;
|
||
WrReqIntern <= '1';
|
||
Else
|
||
WrReqIntern <= '0';
|
||
End If;
|
||
end if ;
|
||
end case lbl_state ;
|
||
end if ; -- Reset & Clock
|
||
end process state_decoding ;
|
||
|
||
end architecture fsm ; -- of rx_buf2data
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.PauseReqLogic
|
||
-- Last modified : Thu Nov 14 15:46:58 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
|
||
entity PauseReqLogic is
|
||
port (
|
||
Clk : in std_logic;
|
||
PauseAck : in std_logic;
|
||
PauseReq : out std_logic;
|
||
PauseVal : out std_logic_vector(15 downto 0);
|
||
Rst : in std_logic;
|
||
WaterMarkHigh : in std_logic;
|
||
WaterMarkLow : in std_logic);
|
||
end entity PauseReqLogic;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.PauseReqLogic.rtl
|
||
-- Last modified : Thu Nov 14 15:46:58 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
architecture rtl of PauseReqLogic is
|
||
begin
|
||
Process (Clk, Rst)
|
||
Variable WaterMarkLow_del: Std_logic;
|
||
Variable WaterMarkHigh_del: Std_logic;
|
||
Begin
|
||
If Rst = '1' Then
|
||
WaterMarkLow_del := '1';
|
||
WaterMarkHigh_del := '0';
|
||
PauseReq <= '0';
|
||
PauseVal <= x"0000";
|
||
ElsIf Rising_Edge(Clk) Then
|
||
-- Remove any pending Pause Request when Ack
|
||
If PauseAck = '1' Then
|
||
PauseReq <= '0';
|
||
PauseVal <= x"0000";
|
||
-- If Rising_Edge(WaterMarkLow) Then "Cancel" Pause Request
|
||
-- note that PauseVal may be updated to the current value when a former PauseReq is still pending
|
||
ElsIf WaterMarkLow = '1' and WaterMarkLow_del = '0' Then
|
||
PauseReq <= '1';
|
||
PauseVal <= x"0000";
|
||
-- If Rising_Edge(WaterMarkHigh) Then Pause Request 65535
|
||
-- Pause_Quantas (= 512 bit times)
|
||
-- is 65535 * 512 * 800 ps (for 1 Gbit Ethernet) = ~26.8 ms
|
||
-- See IEEE802.3-2005 Annex 31B
|
||
-- note that PauseVal may be updated to the current value when a former PauseReq is still pending
|
||
ElsIf WaterMarkHigh = '1' and WaterMarkHigh_del = '0' Then
|
||
PauseReq <= '1';
|
||
PauseVal <= x"FFFF";
|
||
End If;
|
||
-- Pipeline
|
||
WaterMarkLow_del := WaterMarkLow;
|
||
WaterMarkHigh_del := WaterMarkHigh;
|
||
End If;
|
||
End Process;
|
||
|
||
end architecture rtl ; -- of PauseReqLogic
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.rx_mac2buf
|
||
-- Last modified : Mon Jun 29 14:23:22 2015.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
use work.wr_fabric_pkg.all;
|
||
|
||
entity rx_mac2buf is
|
||
generic(
|
||
abits : integer := 15);
|
||
port (
|
||
Clk : in std_logic;
|
||
Dout : out std_logic_vector(15 downto 0);
|
||
EOF : out std_logic;
|
||
Full : in std_logic;
|
||
OverFlow : out std_logic;
|
||
PktWrPtr : out std_logic_vector(abits-1 downto 0);
|
||
Rst : in std_logic;
|
||
We : out std_logic;
|
||
WrAddr : out std_logic_vector(abits-1 downto 0);
|
||
snk_i : in t_wrf_sink_in;
|
||
snk_o : out t_wrf_sink_out);
|
||
end entity rx_mac2buf;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.rx_mac2buf.rtl
|
||
-- Last modified : Mon Jun 29 14:23:22 2015.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
architecture rtl of rx_mac2buf is
|
||
|
||
-- general signals
|
||
signal rd_req : std_logic;
|
||
signal q_data_p1 : std_logic_vector(15 downto 0);
|
||
signal q_valid_p1 : std_logic;
|
||
signal q_adr_p1 : std_logic_vector(1 downto 0);
|
||
|
||
signal snk_valid : std_logic;
|
||
signal eocycle : std_logic;
|
||
signal adr_change : std_logic;
|
||
signal snk_cyc_d0 : std_logic;
|
||
|
||
signal snk_out : t_wrf_sink_out;
|
||
signal stall_int : std_logic;
|
||
signal shift_pipeline : std_logic;
|
||
|
||
Signal Offset : Integer Range 0 to MAX_RESERV_PKT_BUF;
|
||
Signal PktPtr : Unsigned(abits-1 downto 0);
|
||
Signal We_Int : Std_Logic;
|
||
Signal good_frame : Std_Logic;
|
||
Signal bad_frame : Std_Logic;
|
||
|
||
begin
|
||
-- IPmux should always be capable to store at leaste one jumbo packet.
|
||
-- Backpressure is not implemented using "rd_req" but by sending Ethernet Pause Frames.
|
||
-- Therefore rd_req ia always asserted.
|
||
rd_req <= '1';
|
||
|
||
p_detect_frame : process(Clk, Rst)
|
||
begin
|
||
if rising_edge(Clk) then
|
||
if Rst = '1' then
|
||
snk_cyc_d0 <= '0';
|
||
else
|
||
snk_cyc_d0 <= snk_i.cyc;
|
||
end if;
|
||
end if;
|
||
end process;
|
||
|
||
eocycle <= snk_cyc_d0 and not snk_i.cyc;
|
||
snk_valid <= (snk_i.cyc and snk_i.stb and snk_i.we) and not stall_int;
|
||
shift_pipeline <= '1' when snk_valid = '1' or adr_change = '1' or eocycle = '1' else '0';
|
||
|
||
adr_change <= '1' when (q_adr_p1 = c_WRF_DATA and snk_i.adr /= c_WRF_DATA) else '0';
|
||
|
||
p_pipeline : process (Clk, Rst)
|
||
begin -- process
|
||
if rising_edge(Clk) then
|
||
if(Rst = '1') then
|
||
q_data_p1 <= (others => '0');
|
||
q_adr_p1 <= (others => '0');
|
||
q_valid_p1 <= '0';
|
||
else
|
||
if(shift_pipeline = '1') then
|
||
q_data_p1 <= snk_i.dat;
|
||
q_adr_p1 <= snk_i.adr;
|
||
if snk_i.adr = c_WRF_DATA then
|
||
q_valid_p1 <= snk_valid;
|
||
else
|
||
q_valid_p1 <= '0';
|
||
end if;
|
||
end if;
|
||
end if;
|
||
end if;
|
||
end process;
|
||
|
||
Dout <= q_data_p1;
|
||
EOF <= eocycle Or adr_change;
|
||
|
||
stall_int <= not (rd_req);
|
||
snk_out.stall <= stall_int;
|
||
snk_out.err <= '0';
|
||
snk_out.rty <= '0';
|
||
|
||
p_gen_ack : process(Clk, Rst)
|
||
begin
|
||
if(Rst = '1') then
|
||
snk_out.ack <= '0';
|
||
elsif rising_edge(Clk) then
|
||
snk_out.ack <= snk_valid;
|
||
end if;
|
||
end process;
|
||
|
||
snk_o <= snk_out;
|
||
|
||
-- Good and Bad Frame need at least one pipeline since they musn't co-incide with "We_Int"
|
||
-- Note that in our case (connecting to White Rabbit PTP Core) we never have a bad-frame!
|
||
p_frame_pipeline : process(Clk, Rst)
|
||
begin
|
||
if(Rst = '1') then
|
||
good_frame <= '0';
|
||
bad_frame <= '0';
|
||
elsif rising_edge(Clk) then
|
||
good_frame <= eocycle;
|
||
bad_frame <= '0';
|
||
end if;
|
||
end process;
|
||
|
||
WrAddr <= Std_Logic_Vector(PktPtr + To_Unsigned(Offset,RX_PKT_BUF_ADRSIZE));
|
||
PktWrPtr <= Std_Logic_Vector(PktPtr);
|
||
We_Int <= shift_pipeline when q_valid_p1 = '1' and Full = '0' else '0';
|
||
Overflow <= shift_pipeline when q_valid_p1 = '1' and Full = '1' else '0';
|
||
We <= We_Int;
|
||
|
||
RxPktBufPointers: Process (Clk, Rst)
|
||
Begin
|
||
If Rst = '1' Then
|
||
Offset <= 0;
|
||
PktPtr <= (Others => '0');
|
||
ElsIf Rising_Edge(Clk) Then
|
||
If We_Int = '1' Then
|
||
Offset <= Offset + 1;
|
||
-- When "Good Frame" then increment the Packet Pointer
|
||
ElsIf good_frame = '1' Then
|
||
PktPtr <= PktPtr + To_Unsigned(Offset,RX_PKT_BUF_ADRSIZE);
|
||
Offset <= 0;
|
||
-- When "Bad Frame" then leave the Packet Pointer thus overwriting
|
||
-- the bad frame in the buffer memory with the next frame.
|
||
ElsIf bad_frame = '1' Then
|
||
Offset <= 0;
|
||
End If;
|
||
End If;
|
||
End Process RxPktBufPointers;
|
||
|
||
end architecture rtl ; -- of rx_mac2buf
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.PacketBuffer
|
||
-- Last modified : Fri Sep 12 17:28:03 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.genram_pkg.all;
|
||
|
||
entity PacketBuffer is
|
||
generic(
|
||
abits : integer := 15;
|
||
dbits : integer := 8);
|
||
port (
|
||
AddrA : in std_logic_vector(abits-1 downto 0);
|
||
AddrB : in std_logic_vector(abits-1 downto 0);
|
||
Clk : in std_logic;
|
||
Din : in std_logic_vector(dbits-1 downto 0);
|
||
Q : out std_logic_vector(dbits-1 downto 0);
|
||
Rst : in std_logic;
|
||
WeA : in std_logic);
|
||
end entity PacketBuffer;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.PacketBuffer.rtl
|
||
-- Last modified : Fri Sep 12 17:28:03 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
architecture rtl of PacketBuffer is
|
||
|
||
signal rst_n: Std_Logic;
|
||
|
||
begin
|
||
|
||
rst_n <= not Rst;
|
||
|
||
u0: generic_dpram
|
||
generic map (
|
||
g_data_width => 17,
|
||
g_size => 2**abits,
|
||
g_dual_clock => false)
|
||
port map (
|
||
rst_n_i => rst_n,
|
||
clka_i => Clk,
|
||
bwea_i => "111",
|
||
wea_i => Wea,
|
||
aa_i => AddrA,
|
||
da_i => Din,
|
||
qa_o => open,
|
||
clkb_i => '0',
|
||
bweb_i => "000",
|
||
web_i => '0',
|
||
ab_i => AddrB,
|
||
db_i => "00000000000000000",
|
||
qb_o => Q
|
||
);
|
||
|
||
end architecture rtl ; -- of PacketBuffer
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.Calc_UDP_PseudoHeader
|
||
-- Last modified : Tue Mar 10 09:20:10 2015.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
|
||
entity Calc_UDP_PseudoHeader is
|
||
port (
|
||
Clk : in std_logic;
|
||
PseudoHeader : out std_logic_vector(31 downto 0);
|
||
Rst : in std_logic;
|
||
eth_regs_i : in eth_regs_type);
|
||
end entity Calc_UDP_PseudoHeader;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.Calc_UDP_PseudoHeader.a0
|
||
-- Last modified : Tue Mar 10 09:20:10 2015.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
architecture a0 of Calc_UDP_PseudoHeader is
|
||
|
||
begin
|
||
Process (Clk, Rst)
|
||
Variable PseudoHdr : Unsigned(31 downto 0);
|
||
Begin
|
||
If Rst = '1' Then
|
||
PseudoHdr := (Others => '0');
|
||
ElsIf Rising_Edge(Clk) Then
|
||
-- The UDP CheckSum is calculated using an UDP Pseudo-Header that contains:
|
||
-- IP Source address
|
||
-- IP Destination address
|
||
-- x"00" & Protocol
|
||
-- UDP_Length
|
||
-- Note: UDP Length is to be added when this value is known
|
||
PseudoHdr :=
|
||
(x"0000" & Unsigned(eth_regs_i.IP_Mod(31 downto 16))) +
|
||
(x"0000" & Unsigned(eth_regs_i.IP_Mod(15 downto 0))) +
|
||
(x"0000" & Unsigned(eth_regs_i.IP_Srv(31 downto 16))) +
|
||
(x"0000" & Unsigned(eth_regs_i.IP_Srv(15 downto 0))) +
|
||
(x"0000" & x"0011");
|
||
End If;
|
||
PseudoHeader <= Std_Logic_Vector(PseudoHdr);
|
||
End Process;
|
||
end architecture a0 ; -- of Calc_UDP_PseudoHeader
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.tx_data2buf
|
||
-- Last modified : Wed Oct 30 16:55:17 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
|
||
entity tx_data2buf is
|
||
generic(
|
||
abits : integer := 15);
|
||
port (
|
||
CPU_AccGnt : out std_logic;
|
||
CPU_Tx : in ipmux_cpu_in_type;
|
||
Clk : in std_logic;
|
||
ConnectReq : out std_logic;
|
||
Connected : in std_logic;
|
||
Dout : out std_logic_vector(15 downto 0);
|
||
EOPout : out std_logic;
|
||
FragID : in std_logic_vector(15 downto 0);
|
||
FragOff : in std_logic_vector(11 downto 0);
|
||
Full : in std_logic;
|
||
MoreFrag : in std_logic;
|
||
PktWrPtr : out std_logic_vector(abits-1 downto 0);
|
||
PseudoHeader : in std_logic_vector(31 downto 0);
|
||
Rst : in std_logic;
|
||
SelSm : out std_logic;
|
||
Stream : in natural range NUM_UDP_PRTS-1 downto 0;
|
||
TX_LL_DATA : in std_logic_vector(15 downto 0);
|
||
TX_LL_EOP : in std_logic;
|
||
TX_LL_RDREQ : out std_logic;
|
||
TX_LL_VALID : in std_logic;
|
||
WrAddr : out std_logic_vector(abits-1 downto 0);
|
||
WrEn : out std_logic;
|
||
eth_regs_i : in eth_regs_type);
|
||
end entity tx_data2buf;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.tx_data2buf.fsm
|
||
-- Last modified : Wed Oct 30 16:55:17 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
architecture fsm of tx_data2buf is
|
||
|
||
-- State Machine Options:
|
||
-- Clock : Clk (Rising edge).
|
||
-- State assignment : Enumerate.
|
||
-- State decoding : Case construct.
|
||
-- Actions on transitions : Clocked.
|
||
-- Actions on states : Clocked.
|
||
|
||
type state_type is (Idle, More_Data, UDP_WriteHeader, IP_WriteHeader,
|
||
IP_WriteCheckSum, MAC_WriteHeader, AccessByCPU) ;
|
||
signal state : state_type ; -- Current State
|
||
Signal Offset: Integer Range 0 to MAX_RESERV_PKT_BUF;
|
||
Signal PktPtr: Unsigned(abits-1 downto 0);
|
||
Signal Pkt_End: Unsigned(abits-1 downto 0);
|
||
Signal RdReq: Std_Logic;
|
||
Signal ConnectReq_Intern: Std_Logic;
|
||
|
||
|
||
|
||
begin
|
||
--Packet Buffer Full Flag is only checked once.
|
||
--If Full = False then there is at least place
|
||
--to store one packet (size PKT_LEN + PAYLOAD).
|
||
--It is the responsibility of the input *NOT* to
|
||
--exceed this maximum; Overfglow is not checked!
|
||
WrAddr <= Std_Logic_Vector(PktPtr + To_Unsigned(Offset,TX_PKT_BUF_ADRSIZE));
|
||
PktWrPtr <= Std_Logic_Vector(PktPtr);
|
||
-- Asynchronously avoid a new TX_LL_RDREQ when the Packet Buffer becomes Full
|
||
TX_LL_RDREQ <= RdReq And Not Full;
|
||
ConnectReq <= ConnectReq_Intern;
|
||
|
||
|
||
state_decoding: process (Clk, Rst) is
|
||
Variable MAC_HeaderRegFile: std_logic_v16array(MAC_HDR_CNT-1 downto 0);
|
||
Variable IP_HeaderRegFile: std_logic_v16array(IP_HDR_CNT-1 downto 0);
|
||
Variable IP_Length: Unsigned(15 downto 0);
|
||
Variable UDP_HeaderRegFile: std_logic_v16array(UDP_HDR_CNT-1 downto 0);
|
||
Variable UDP_Length: Unsigned(15 downto 0);
|
||
Variable CheckSum : Unsigned(31 downto 0);
|
||
Variable Idx: Integer Range 0 to 31;
|
||
|
||
begin
|
||
if (Rst = '1') then
|
||
state <= Idle ;
|
||
-- Initialize:
|
||
ConnectReq_Intern <= '1';
|
||
PktPtr <= (Others => '0');
|
||
Pkt_End <= (Others => '0');
|
||
Offset <= PAYLOAD;
|
||
RdReq <= '1';
|
||
SelSm <= '0';
|
||
WrEn <= '0';
|
||
CPU_AccGnt <= '0';
|
||
Dout <= (Others => '0');
|
||
Idx := 0;
|
||
CheckSum := (Others => '0');
|
||
EOPout <= '0';
|
||
elsif (rising_edge(Clk)) then
|
||
lbl_state : case state is
|
||
when Idle =>
|
||
if (Full = '0' And CPU_Tx.Request = '1') then
|
||
state <= AccessByCPU ;
|
||
Offset <= To_Integer(Unsigned(CPU_Tx.Addr));
|
||
RdReq <= '0';
|
||
SelSm <= '1';
|
||
WrEn <= CPU_Tx.WrEn;
|
||
CPU_AccGnt <= '1';
|
||
Dout <= CPU_Tx.D;
|
||
EOPout <= CPU_Tx.EOP;
|
||
If CPU_Tx.EOP = '1' and CPU_Tx.WrEn = '1' Then
|
||
Pkt_End <= Unsigned(CPU_Tx.Addr);
|
||
End If;
|
||
ConnectReq_Intern <= '0';
|
||
elsif (
|
||
Full = '0' And
|
||
Connected = '1'
|
||
) then
|
||
state <= More_Data ;
|
||
RdReq <= '1';
|
||
SelSm <= '0';
|
||
WrEn <= '1';
|
||
CPU_AccGnt <= '0';
|
||
If TX_LL_VALID = '1' And ConnectReq_Intern = '0' Then
|
||
Offset <= Offset + 1;
|
||
CheckSum := CheckSum + (x"0000" & Unsigned(TX_LL_DATA));
|
||
End If;
|
||
|
||
ConnectReq_Intern <= '0';
|
||
else
|
||
state <= Idle ;
|
||
Offset <= PAYLOAD;
|
||
If CPU_Tx.Request = '0' Then
|
||
RdReq <= '1';
|
||
ConnectReq_Intern <= '1';
|
||
Else
|
||
RdReq <= '0';
|
||
ConnectReq_Intern <= '0';
|
||
End If;
|
||
SelSm <= '1';
|
||
WrEn <= '0';
|
||
CPU_AccGnt <= '0';
|
||
EOPout <= '0';
|
||
-- InitHregFile:
|
||
-- MAC Destination Address
|
||
MAC_HeaderRegFile(MAC_IDX_DST) := eth_regs_i.MAC_Srv (47 downto 32);
|
||
MAC_HeaderRegFile(MAC_IDX_DST + 1) := eth_regs_i.MAC_Srv (31 downto 16);
|
||
MAC_HeaderRegFile(MAC_IDX_DST + 2) := eth_regs_i.MAC_Srv (15 downto 0);
|
||
-- MAC Source Address
|
||
MAC_HeaderRegFile(MAC_IDX_SRC) := eth_regs_i.MAC_Mod (47 downto 32);
|
||
MAC_HeaderRegFile(MAC_IDX_SRC + 1) := eth_regs_i.MAC_Mod (31 downto 16);
|
||
MAC_HeaderRegFile(MAC_IDX_SRC + 2) := eth_regs_i.MAC_Mod (15 downto 0);
|
||
-- Type/Length (EtherType is Internet Protocol Version 4 (0x0800)
|
||
MAC_HeaderRegFile(MAC_IDX_LEN) := x"0800";
|
||
|
||
-- IP Version / Header Length / Type Of Service
|
||
IP_HeaderRegFile(IP_IDX_VER_LEN_TOS) := x"4500";
|
||
-- IP Length (assigned later according to input stream)
|
||
IP_HeaderRegFile(IP_IDX_LEN) := x"0000";
|
||
-- IP ID (assigned later according to FragID input)
|
||
IP_HeaderRegFile(IP_IDX_ID) := x"0000";
|
||
-- IP Flags / Fragment Offset (assigned later according to MoreFrag and FragOff input)
|
||
IP_HeaderRegFile(IP_IDX_FLAGS_FRAGOFF) := x"0000";
|
||
-- IP Time To Live (128), PROT: UDP = 17
|
||
IP_HeaderRegFile(IP_IDX_TTL_PROT) := x"8011";
|
||
-- IP Header CheckSum. Initially set to 0x0000 for
|
||
-- Checksum calculation (assigned later according to input stream)
|
||
IP_HeaderRegFile(IP_IDX_CHECKS) := x"0000";
|
||
-- IP Source Address
|
||
IP_HeaderRegFile(IP_IDX_IP_SRC) := eth_regs_i.IP_Mod(31 downto 16);
|
||
IP_HeaderRegFile(IP_IDX_IP_SRC + 1) := eth_regs_i.IP_Mod(15 downto 0);
|
||
-- IP Destination Address
|
||
IP_HeaderRegFile(IP_IDX_IP_DST) := eth_regs_i.IP_Srv(31 downto 16);
|
||
IP_HeaderRegFile(IP_IDX_IP_DST + 1) := eth_regs_i.IP_Srv(15 downto 0);
|
||
|
||
-- UDP Source Port (assigned later according to input stream)
|
||
UDP_HeaderRegFile(UDP_IDX_SRCPRT) := x"0000";
|
||
-- UDP Destination Port (assigned later according to input stream)
|
||
UDP_HeaderRegFile(UDP_IDX_DSTPRT) := x"0000";
|
||
-- UDP Length
|
||
UDP_HeaderRegFile(UDP_IDX_LEN) := x"0000";
|
||
-- UDP CheckSum
|
||
-- CheckSum is optional. If it is not calculated then
|
||
-- it should be set to 0x0000.
|
||
UDP_HeaderRegFile(UDP_IDX_CHECKS) := x"0000";
|
||
|
||
-- The UDP CheckSum is calculated using an UDP Pseudo-Header that contains:
|
||
-- IP Source address
|
||
-- IP Destination address
|
||
-- x"00" & Protocol
|
||
-- UDP_Length
|
||
-- Note: UDP Length is to be added when this value is known
|
||
|
||
--CheckSum :=
|
||
-- (x"0000" & Unsigned(IP_HeaderRegFile(IP_IDX_IP_SRC))) +
|
||
-- (x"0000" & Unsigned(IP_HeaderRegFile(IP_IDX_IP_SRC + 1))) +
|
||
-- (x"0000" & Unsigned(IP_HeaderRegFile(IP_IDX_IP_DST))) +
|
||
-- (x"0000" & Unsigned(IP_HeaderRegFile(IP_IDX_IP_DST + 1))) +
|
||
-- (x"0000" & x"00" & Unsigned(IP_HeaderRegFile(IP_IDX_TTL_PROT)(7 downto 0)));
|
||
|
||
-- Note that due timing issues between "eth_regs_i.IP_Src" and "CheckSum" which occured
|
||
-- during place&route it was decided to pre-calculate the content of the pseudo header.
|
||
CheckSum := Unsigned(PseudoHeader);
|
||
|
||
end if ;
|
||
when More_Data =>
|
||
if (TX_LL_EOP = '1' And TX_LL_VALID = '1') then
|
||
state <= UDP_WriteHeader ;
|
||
-- Write_UDP_Ports_Length_and_CheckSum_To_HregFile:
|
||
-- UDP Source Port
|
||
UDP_HeaderRegFile(UDP_IDX_SRCPRT) := eth_regs_i.UDP_ModPrt(Stream);
|
||
-- UDP Destination Port
|
||
UDP_HeaderRegFile(UDP_IDX_DSTPRT) := eth_regs_i.UDP_SrvPrt(Stream);
|
||
|
||
-- UDP Length is the length of the UDP header and
|
||
-- the data (= offset + 1 - PAYLOAD) in 16 bit words
|
||
-- henche "2*" to calculate bytes.
|
||
UDP_Length := To_Unsigned((2*(UDP_HDR_CNT + Offset + 1 - PAYLOAD)),16);
|
||
UDP_HeaderRegFile(UDP_IDX_LEN) := Std_Logic_Vector(UDP_Length);
|
||
|
||
-- UDP CRC is the sum over the Pseudo Header and all the data words.
|
||
-- Don't forget to add the last dataword here
|
||
-- The Pseudo Header was pre-calculated in "InitHregFile" but the UDP Length
|
||
-- was not yet known at that time. So it must be added here as well twice,
|
||
-- since the UDP Length is part of the Pseudo Header *AND* part of the UDP Header!
|
||
CheckSum := CheckSum + (x"0000" & Unsigned(TX_LL_DATA)) + (x"000" & "000" & UDP_Length & '0');
|
||
|
||
-- Add the the UDP Source and Destination Ports to the Checksum
|
||
CheckSum := CheckSum +
|
||
(x"0000" & Unsigned(UDP_HeaderRegFile(UDP_IDX_SRCPRT))) +
|
||
(x"0000" & Unsigned(UDP_HeaderRegFile(UDP_IDX_DSTPRT)));
|
||
|
||
CheckSum (16 Downto 0) := ('0' & CheckSum(31 downto 16)) + ('0' & CheckSum(15 downto 0));
|
||
-- Note that two 16 bit additions may lead to overflow
|
||
-- for example 0xffff + 0xffff = 0x1fffe
|
||
-- need to add overflow bit (16) to (15 downto 0)
|
||
CheckSum (15 Downto 0) := ("0000000" & CheckSum(16)) + CheckSum(15 downto 0);
|
||
UDP_HeaderRegFile(UDP_IDX_CHECKS) := Not Std_Logic_Vector(CheckSum(15 downto 0));
|
||
Pkt_End <= To_Unsigned(Offset,TX_PKT_BUF_ADRSIZE);
|
||
Idx := 0;
|
||
RdReq <= '0';
|
||
SelSm <= '1';
|
||
WrEn <= '1';
|
||
CPU_AccGnt <= '0';
|
||
Dout <= UDP_HeaderRegFile(Idx);
|
||
Offset <= UDP_HDR + Idx;
|
||
Idx := Idx + 1;
|
||
|
||
ConnectReq_Intern <= '0';
|
||
else
|
||
state <= More_Data ;
|
||
RdReq <= '1';
|
||
SelSm <= '0';
|
||
WrEn <= '1';
|
||
CPU_AccGnt <= '0';
|
||
If TX_LL_VALID = '1' And ConnectReq_Intern = '0' Then
|
||
Offset <= Offset + 1;
|
||
CheckSum := CheckSum + (x"0000" & Unsigned(TX_LL_DATA));
|
||
End If;
|
||
|
||
ConnectReq_Intern <= '0';
|
||
end if ;
|
||
when UDP_WriteHeader =>
|
||
if (Idx = UDP_HDR_CNT) then
|
||
state <= IP_WriteHeader ;
|
||
-- Write_IP_Length_To_HregFile:
|
||
-- IP Length is the length of the IP header and
|
||
-- the data. Note that IP_HDR_CNT is in 16 bit words
|
||
-- henche "2*" to calculate bytes.
|
||
IP_Length := To_Unsigned(2 * IP_HDR_CNT,16) + UDP_Length;
|
||
IP_HeaderRegFile(IP_IDX_LEN) := Std_Logic_Vector(IP_Length);
|
||
|
||
-- IP Fragment ID
|
||
IP_HeaderRegFile(IP_IDX_ID) := FragID;
|
||
-- IP Flags / Fragment Offset
|
||
IP_HeaderRegFile(IP_IDX_FLAGS_FRAGOFF) := "00" & MoreFrag & '0' & FragOff;
|
||
Idx := 0;
|
||
CheckSum := (Others => '0');
|
||
|
||
RdReq <= '0';
|
||
SelSm <= '1';
|
||
WrEn <= '1';
|
||
CPU_AccGnt <= '0';
|
||
Dout <= IP_HeaderRegFile(Idx);
|
||
CheckSum := CheckSum + (x"0000" & Unsigned(IP_HeaderRegFile(Idx)));
|
||
Offset <= IP_HDR + Idx;
|
||
Idx := Idx + 1;
|
||
|
||
ConnectReq_Intern <= '0';
|
||
else
|
||
state <= UDP_WriteHeader ;
|
||
RdReq <= '0';
|
||
SelSm <= '1';
|
||
WrEn <= '1';
|
||
CPU_AccGnt <= '0';
|
||
Dout <= UDP_HeaderRegFile(Idx);
|
||
Offset <= UDP_HDR + Idx;
|
||
Idx := Idx + 1;
|
||
|
||
ConnectReq_Intern <= '0';
|
||
end if ;
|
||
when IP_WriteHeader =>
|
||
if (Idx = IP_HDR_CNT) then
|
||
state <= IP_WriteCheckSum ;
|
||
CheckSum (16 Downto 0) := ('0' & CheckSum(31 downto 16)) + ('0' & CheckSum(15 downto 0));
|
||
-- Note that two 16 bit additions may lead to overflow
|
||
-- for example 0xffff + 0xffff = 0x1fffe
|
||
-- need to add overflow bit (16) to (15 downto 0)
|
||
CheckSum (15 Downto 0) := ("0000000" & CheckSum(16)) + CheckSum(15 downto 0);
|
||
RdReq <= '0';
|
||
SelSm <= '1';
|
||
WrEn <= '1';
|
||
CPU_AccGnt <= '0';
|
||
Dout <= Not Std_Logic_Vector(CheckSum(15 downto 0));
|
||
Offset <= IP_HDR + IP_IDX_CHECKS;
|
||
ConnectReq_Intern <= '0';
|
||
else
|
||
state <= IP_WriteHeader ;
|
||
RdReq <= '0';
|
||
SelSm <= '1';
|
||
WrEn <= '1';
|
||
CPU_AccGnt <= '0';
|
||
Dout <= IP_HeaderRegFile(Idx);
|
||
CheckSum := CheckSum + (x"0000" & Unsigned(IP_HeaderRegFile(Idx)));
|
||
Offset <= IP_HDR + Idx;
|
||
Idx := Idx + 1;
|
||
|
||
ConnectReq_Intern <= '0';
|
||
end if ;
|
||
when IP_WriteCheckSum =>
|
||
state <= MAC_WriteHeader ;
|
||
Idx := 0;
|
||
-- Write_MAC_Length_To_HregFile:
|
||
-- MAC Length is equal to the IP_Length
|
||
-- Add the Legth value to the EtherType that is
|
||
-- already initialized in MAC_HeaderRegFile(MAC_IDX_LEN)
|
||
|
||
-- MAC_HeaderRegFile(MAC_IDX_LEN) := Std_Logic_Vector(Unsigned(MAC_HeaderRegFile(MAC_IDX_LEN)) + IP_Length);
|
||
|
||
RdReq <= '0';
|
||
SelSm <= '1';
|
||
WrEn <= '1';
|
||
CPU_AccGnt <= '0';
|
||
Dout <= MAC_HeaderRegFile(Idx);
|
||
Offset <= MAC_HDR + Idx;
|
||
Idx := Idx + 1;
|
||
|
||
ConnectReq_Intern <= '0';
|
||
when MAC_WriteHeader =>
|
||
if (Idx = MAC_HDR_CNT) then
|
||
state <= Idle ;
|
||
PktPtr <= PktPtr + Pkt_End + 1;
|
||
Offset <= PAYLOAD;
|
||
If CPU_Tx.Request = '0' Then
|
||
RdReq <= '1';
|
||
ConnectReq_Intern <= '1';
|
||
Else
|
||
RdReq <= '0';
|
||
ConnectReq_Intern <= '0';
|
||
End If;
|
||
SelSm <= '1';
|
||
WrEn <= '0';
|
||
CPU_AccGnt <= '0';
|
||
EOPout <= '0';
|
||
-- InitHregFile:
|
||
-- MAC Destination Address
|
||
MAC_HeaderRegFile(MAC_IDX_DST) := eth_regs_i.MAC_Srv (47 downto 32);
|
||
MAC_HeaderRegFile(MAC_IDX_DST + 1) := eth_regs_i.MAC_Srv (31 downto 16);
|
||
MAC_HeaderRegFile(MAC_IDX_DST + 2) := eth_regs_i.MAC_Srv (15 downto 0);
|
||
-- MAC Source Address
|
||
MAC_HeaderRegFile(MAC_IDX_SRC) := eth_regs_i.MAC_Mod (47 downto 32);
|
||
MAC_HeaderRegFile(MAC_IDX_SRC + 1) := eth_regs_i.MAC_Mod (31 downto 16);
|
||
MAC_HeaderRegFile(MAC_IDX_SRC + 2) := eth_regs_i.MAC_Mod (15 downto 0);
|
||
-- Type/Length (EtherType is Internet Protocol Version 4 (0x0800)
|
||
MAC_HeaderRegFile(MAC_IDX_LEN) := x"0800";
|
||
|
||
-- IP Version / Header Length / Type Of Service
|
||
IP_HeaderRegFile(IP_IDX_VER_LEN_TOS) := x"4500";
|
||
-- IP Length (assigned later according to input stream)
|
||
IP_HeaderRegFile(IP_IDX_LEN) := x"0000";
|
||
-- IP ID (assigned later according to FragID input)
|
||
IP_HeaderRegFile(IP_IDX_ID) := x"0000";
|
||
-- IP Flags / Fragment Offset (assigned later according to MoreFrag and FragOff input)
|
||
IP_HeaderRegFile(IP_IDX_FLAGS_FRAGOFF) := x"0000";
|
||
-- IP Time To Live (128), PROT: UDP = 17
|
||
IP_HeaderRegFile(IP_IDX_TTL_PROT) := x"8011";
|
||
-- IP Header CheckSum. Initially set to 0x0000 for
|
||
-- Checksum calculation (assigned later according to input stream)
|
||
IP_HeaderRegFile(IP_IDX_CHECKS) := x"0000";
|
||
-- IP Source Address
|
||
IP_HeaderRegFile(IP_IDX_IP_SRC) := eth_regs_i.IP_Mod(31 downto 16);
|
||
IP_HeaderRegFile(IP_IDX_IP_SRC + 1) := eth_regs_i.IP_Mod(15 downto 0);
|
||
-- IP Destination Address
|
||
IP_HeaderRegFile(IP_IDX_IP_DST) := eth_regs_i.IP_Srv(31 downto 16);
|
||
IP_HeaderRegFile(IP_IDX_IP_DST + 1) := eth_regs_i.IP_Srv(15 downto 0);
|
||
|
||
-- UDP Source Port (assigned later according to input stream)
|
||
UDP_HeaderRegFile(UDP_IDX_SRCPRT) := x"0000";
|
||
-- UDP Destination Port (assigned later according to input stream)
|
||
UDP_HeaderRegFile(UDP_IDX_DSTPRT) := x"0000";
|
||
-- UDP Length
|
||
UDP_HeaderRegFile(UDP_IDX_LEN) := x"0000";
|
||
-- UDP CheckSum
|
||
-- CheckSum is optional. If it is not calculated then
|
||
-- it should be set to 0x0000.
|
||
UDP_HeaderRegFile(UDP_IDX_CHECKS) := x"0000";
|
||
|
||
-- The UDP CheckSum is calculated using an UDP Pseudo-Header that contains:
|
||
-- IP Source address
|
||
-- IP Destination address
|
||
-- x"00" & Protocol
|
||
-- UDP_Length
|
||
-- Note: UDP Length is to be added when this value is known
|
||
|
||
--CheckSum :=
|
||
-- (x"0000" & Unsigned(IP_HeaderRegFile(IP_IDX_IP_SRC))) +
|
||
-- (x"0000" & Unsigned(IP_HeaderRegFile(IP_IDX_IP_SRC + 1))) +
|
||
-- (x"0000" & Unsigned(IP_HeaderRegFile(IP_IDX_IP_DST))) +
|
||
-- (x"0000" & Unsigned(IP_HeaderRegFile(IP_IDX_IP_DST + 1))) +
|
||
-- (x"0000" & x"00" & Unsigned(IP_HeaderRegFile(IP_IDX_TTL_PROT)(7 downto 0)));
|
||
|
||
-- Note that due timing issues between "eth_regs_i.IP_Src" and "CheckSum" which occured
|
||
-- during place&route it was decided to pre-calculate the content of the pseudo header.
|
||
CheckSum := Unsigned(PseudoHeader);
|
||
|
||
else
|
||
state <= MAC_WriteHeader ;
|
||
RdReq <= '0';
|
||
SelSm <= '1';
|
||
WrEn <= '1';
|
||
CPU_AccGnt <= '0';
|
||
Dout <= MAC_HeaderRegFile(Idx);
|
||
Offset <= MAC_HDR + Idx;
|
||
Idx := Idx + 1;
|
||
|
||
ConnectReq_Intern <= '0';
|
||
end if ;
|
||
when AccessByCPU =>
|
||
if (CPU_Tx.Request = '0') then
|
||
state <= Idle ;
|
||
PktPtr <= PktPtr + Pkt_End + 1;
|
||
Offset <= PAYLOAD;
|
||
If CPU_Tx.Request = '0' Then
|
||
RdReq <= '1';
|
||
ConnectReq_Intern <= '1';
|
||
Else
|
||
RdReq <= '0';
|
||
ConnectReq_Intern <= '0';
|
||
End If;
|
||
SelSm <= '1';
|
||
WrEn <= '0';
|
||
CPU_AccGnt <= '0';
|
||
EOPout <= '0';
|
||
-- InitHregFile:
|
||
-- MAC Destination Address
|
||
MAC_HeaderRegFile(MAC_IDX_DST) := eth_regs_i.MAC_Srv (47 downto 32);
|
||
MAC_HeaderRegFile(MAC_IDX_DST + 1) := eth_regs_i.MAC_Srv (31 downto 16);
|
||
MAC_HeaderRegFile(MAC_IDX_DST + 2) := eth_regs_i.MAC_Srv (15 downto 0);
|
||
-- MAC Source Address
|
||
MAC_HeaderRegFile(MAC_IDX_SRC) := eth_regs_i.MAC_Mod (47 downto 32);
|
||
MAC_HeaderRegFile(MAC_IDX_SRC + 1) := eth_regs_i.MAC_Mod (31 downto 16);
|
||
MAC_HeaderRegFile(MAC_IDX_SRC + 2) := eth_regs_i.MAC_Mod (15 downto 0);
|
||
-- Type/Length (EtherType is Internet Protocol Version 4 (0x0800)
|
||
MAC_HeaderRegFile(MAC_IDX_LEN) := x"0800";
|
||
|
||
-- IP Version / Header Length / Type Of Service
|
||
IP_HeaderRegFile(IP_IDX_VER_LEN_TOS) := x"4500";
|
||
-- IP Length (assigned later according to input stream)
|
||
IP_HeaderRegFile(IP_IDX_LEN) := x"0000";
|
||
-- IP ID (assigned later according to FragID input)
|
||
IP_HeaderRegFile(IP_IDX_ID) := x"0000";
|
||
-- IP Flags / Fragment Offset (assigned later according to MoreFrag and FragOff input)
|
||
IP_HeaderRegFile(IP_IDX_FLAGS_FRAGOFF) := x"0000";
|
||
-- IP Time To Live (128), PROT: UDP = 17
|
||
IP_HeaderRegFile(IP_IDX_TTL_PROT) := x"8011";
|
||
-- IP Header CheckSum. Initially set to 0x0000 for
|
||
-- Checksum calculation (assigned later according to input stream)
|
||
IP_HeaderRegFile(IP_IDX_CHECKS) := x"0000";
|
||
-- IP Source Address
|
||
IP_HeaderRegFile(IP_IDX_IP_SRC) := eth_regs_i.IP_Mod(31 downto 16);
|
||
IP_HeaderRegFile(IP_IDX_IP_SRC + 1) := eth_regs_i.IP_Mod(15 downto 0);
|
||
-- IP Destination Address
|
||
IP_HeaderRegFile(IP_IDX_IP_DST) := eth_regs_i.IP_Srv(31 downto 16);
|
||
IP_HeaderRegFile(IP_IDX_IP_DST + 1) := eth_regs_i.IP_Srv(15 downto 0);
|
||
|
||
-- UDP Source Port (assigned later according to input stream)
|
||
UDP_HeaderRegFile(UDP_IDX_SRCPRT) := x"0000";
|
||
-- UDP Destination Port (assigned later according to input stream)
|
||
UDP_HeaderRegFile(UDP_IDX_DSTPRT) := x"0000";
|
||
-- UDP Length
|
||
UDP_HeaderRegFile(UDP_IDX_LEN) := x"0000";
|
||
-- UDP CheckSum
|
||
-- CheckSum is optional. If it is not calculated then
|
||
-- it should be set to 0x0000.
|
||
UDP_HeaderRegFile(UDP_IDX_CHECKS) := x"0000";
|
||
|
||
-- The UDP CheckSum is calculated using an UDP Pseudo-Header that contains:
|
||
-- IP Source address
|
||
-- IP Destination address
|
||
-- x"00" & Protocol
|
||
-- UDP_Length
|
||
-- Note: UDP Length is to be added when this value is known
|
||
|
||
--CheckSum :=
|
||
-- (x"0000" & Unsigned(IP_HeaderRegFile(IP_IDX_IP_SRC))) +
|
||
-- (x"0000" & Unsigned(IP_HeaderRegFile(IP_IDX_IP_SRC + 1))) +
|
||
-- (x"0000" & Unsigned(IP_HeaderRegFile(IP_IDX_IP_DST))) +
|
||
-- (x"0000" & Unsigned(IP_HeaderRegFile(IP_IDX_IP_DST + 1))) +
|
||
-- (x"0000" & x"00" & Unsigned(IP_HeaderRegFile(IP_IDX_TTL_PROT)(7 downto 0)));
|
||
|
||
-- Note that due timing issues between "eth_regs_i.IP_Src" and "CheckSum" which occured
|
||
-- during place&route it was decided to pre-calculate the content of the pseudo header.
|
||
CheckSum := Unsigned(PseudoHeader);
|
||
|
||
else
|
||
state <= AccessByCPU ;
|
||
Offset <= To_Integer(Unsigned(CPU_Tx.Addr));
|
||
RdReq <= '0';
|
||
SelSm <= '1';
|
||
WrEn <= CPU_Tx.WrEn;
|
||
CPU_AccGnt <= '1';
|
||
Dout <= CPU_Tx.D;
|
||
EOPout <= CPU_Tx.EOP;
|
||
If CPU_Tx.EOP = '1' and CPU_Tx.WrEn = '1' Then
|
||
Pkt_End <= Unsigned(CPU_Tx.Addr);
|
||
End If;
|
||
ConnectReq_Intern <= '0';
|
||
end if ;
|
||
end case lbl_state ;
|
||
end if ; -- Reset & Clock
|
||
end process state_decoding ;
|
||
|
||
end architecture fsm ; -- of tx_data2buf
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.tx_pkt2mac
|
||
-- Last modified : Fri Sep 12 17:21:27 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
use work.wr_fabric_pkg.all;
|
||
|
||
entity tx_pkt2mac is
|
||
generic(
|
||
abits : integer := 15);
|
||
port (
|
||
Clk : in std_logic;
|
||
Din : in std_logic_vector(15 downto 0);
|
||
EOP : in std_logic;
|
||
Empty : in std_logic;
|
||
PktRdPtr : out std_logic_vector(abits-1 downto 0);
|
||
RdAddr : out std_logic_vector(abits-1 downto 0);
|
||
Rst : in std_logic;
|
||
src_i : in t_wrf_source_in;
|
||
src_o : out t_wrf_source_out);
|
||
end entity tx_pkt2mac;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.tx_pkt2mac.rtl
|
||
-- Last modified : Fri Sep 12 17:21:27 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
architecture rtl of tx_pkt2mac is
|
||
-- State Machine Options:
|
||
-- Clock : Clk (Rising edge).
|
||
-- State assignment : Enumerate.
|
||
-- State decoding : Case construct.
|
||
-- Actions on transitions : Clocked.
|
||
-- Actions on states : Clocked.
|
||
|
||
type state_type is (Idle, wrf_status, Frame, Stall, EndCycle) ;
|
||
signal state : state_type ; -- Current State
|
||
Signal Offset: Integer Range 0 to MAX_RESERV_PKT_BUF;
|
||
Signal PktPtr: Unsigned(abits-1 downto 0);
|
||
|
||
begin
|
||
RdAddr <= Std_Logic_Vector(PktPtr + To_Unsigned(Offset,TX_PKT_BUF_ADRSIZE));
|
||
PktRdPtr <= Std_Logic_Vector(PktPtr);
|
||
src_o.adr <= c_WRF_STATUS when state = wrf_status else c_WRF_DATA;
|
||
src_o.dat <= x"0204" when state = wrf_status else Din; -- Status word derived from figure 7 (wrpc_hdl.pdf)
|
||
src_o.we <= '1'; -- source is writing by definition
|
||
src_o.sel <= (others => '1'); -- we live in a 16 bit domain
|
||
|
||
state_decoding: process (Clk, Rst) is
|
||
begin
|
||
if (Rst = '1') then
|
||
state <= Idle ;
|
||
-- Initialize:
|
||
PktPtr <= (Others => '0');
|
||
-- Pkt_Str <= (Others => '0');
|
||
Offset <= 0;
|
||
src_o.cyc <= '0';
|
||
src_o.stb <= '0';
|
||
elsif (rising_edge(Clk)) then
|
||
case state is
|
||
when Idle =>
|
||
src_o.cyc <= '0';
|
||
src_o.stb <= '0';
|
||
Offset <= 0;
|
||
if (Empty = '0') then
|
||
state <= wrf_status ;
|
||
src_o.cyc <= '1';
|
||
src_o.stb <= '1';
|
||
else
|
||
state <= Idle ;
|
||
end if ;
|
||
|
||
when wrf_status =>
|
||
if (src_i.stall = '0') then
|
||
src_o.stb <= '1';
|
||
state <= Frame ;
|
||
Offset <= Offset + 1; -- read in advance (it takes data one cycle to e available)
|
||
else
|
||
state <= wrf_status ;
|
||
end if ;
|
||
|
||
when Frame =>
|
||
state <= Frame;
|
||
if (src_i.stall = '1') then -- stall then take back the pipeline data pointer
|
||
Offset <= Offset - 1;
|
||
state <= Stall;
|
||
src_o.stb <= '0';
|
||
elsif (src_i.stall = '0') then
|
||
if (EOP = '1') then
|
||
state <= EndCycle ;
|
||
src_o.stb <= '0';
|
||
PktPtr <= PktPtr +To_Unsigned(Offset,TX_PKT_BUF_ADRSIZE);
|
||
Offset <= 0;
|
||
else
|
||
src_o.stb <= '1';
|
||
Offset <= Offset + 1;
|
||
end if;
|
||
end if ;
|
||
|
||
when Stall =>
|
||
src_o.stb <= '0';
|
||
if (src_i.stall = '0') then
|
||
src_o.stb <= '1';
|
||
state <= Frame ;
|
||
Offset <= Offset + 1; -- read in advance (it takes data one cycle to e available)
|
||
end if ;
|
||
|
||
when EndCycle =>
|
||
src_o.stb <= '0';
|
||
if (src_i.stall = '0') then
|
||
state <= Idle;
|
||
src_o.cyc <= '0'; -- cyc should only be '0' after ack_i was seen (which equals to stall = '0')
|
||
else
|
||
state <= EndCycle ;
|
||
end if;
|
||
end case ;
|
||
end if ; -- Reset & Clock
|
||
end process state_decoding ;
|
||
|
||
end architecture rtl ; -- of tx_pkt2mac
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.PktBufFlags
|
||
-- Last modified : Mon Sep 02 15:09:26 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
|
||
entity PktBufFlags is
|
||
generic(
|
||
abits : integer := 15);
|
||
port (
|
||
Empty : out std_logic;
|
||
Full : out std_logic;
|
||
PktRdPtr : in std_logic_vector(abits-1 downto 0);
|
||
PktWrPtr : in std_logic_vector(abits-1 downto 0);
|
||
WaterMarkHigh : out std_logic;
|
||
WaterMarkLow : out std_logic);
|
||
end entity PktBufFlags;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.PktBufFlags.rtl
|
||
-- Last modified : Mon Sep 02 15:09:26 2013.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
architecture rtl of PktBufFlags is
|
||
|
||
-- Note:
|
||
-- A buffer size of 32678 (16 bit) words (abits = 15) can contain 65536 bytes which
|
||
-- corresponds to 7 jumbo frames.
|
||
-- A High Water Mark set to 50% means that a pause request is issued after four jumbo frames were received
|
||
-- (the fifth on it's way...; place left to store 5, 6 and 7)
|
||
-- Recall hat 50% of 65536 is 32678 is more than three and less than four jumbo frames of 9014 bytes. Flag
|
||
-- behavior acts upon the Packet Read and Write pointers (not the actual read and write address pointers!)
|
||
-- since packets may be signaled as "bad" and therefore will not occupy buffer space...
|
||
|
||
-- Jumbo Number of % of abits = 14 % of abits = 15 % of abits = 16
|
||
-- Bytes (= 32678 Bytes) (= 65536 Bytes) (= 131072 Bytes)
|
||
-- 1 9014 27,51% 13,75% 6,88%
|
||
-- 2 18028 55,02% 27,51% 13,75%
|
||
-- 3 27042 82,53% 41,26% 20,63%
|
||
-- 4 36056 110,03% 55,02% 27,51%
|
||
-- 5 45070 68,77% 34,39%
|
||
-- 6 54084 82,53% 41,26%
|
||
-- 7 63098 96,28% 48,14%
|
||
-- 8 72112 110,03% 55,02%
|
||
-- 9 81126 61,89%
|
||
-- 10 90140 68,77%
|
||
-- 11 99154 75,65%
|
||
-- 12 108168 82,53%
|
||
-- 13 117182 89,40%
|
||
-- 14 126196 96,28%
|
||
-- 15 135210 103,16%
|
||
|
||
Constant LowLevelPerc: Integer := 30;
|
||
Constant HighLevelPerc: Integer := 50;
|
||
begin
|
||
|
||
Process (PktRdPtr, PktWrPtr)
|
||
Begin
|
||
If PktRdPtr = PktWrPtr Then
|
||
Empty <= '1';
|
||
Else
|
||
Empty <= '0';
|
||
End If;
|
||
|
||
-- Signal Low WaterMark
|
||
If (Unsigned(PktWrPtr) - Unsigned(PktRdPtr)) < To_Unsigned((2**abits * LowLevelPerc)/100, abits) Then
|
||
WaterMarkLow <= '1';
|
||
Else
|
||
WaterMarkLow <= '0';
|
||
End If;
|
||
|
||
-- Signal High WaterMark
|
||
If (Unsigned(PktWrPtr) - Unsigned(PktRdPtr)) > To_Unsigned((2**abits * HighLevelPerc)/100, abits) And
|
||
PktRdPtr /= PktWrPtr Then
|
||
WaterMarkHigh <= '1';
|
||
Else
|
||
WaterMarkHigh <= '0';
|
||
End If;
|
||
|
||
-- Signal Full, as soon as there is no room left for a complete (Jumbo) packet
|
||
If (Unsigned(PktRdPtr) - Unsigned(PktWrPtr)) <= To_Unsigned(MAX_RESERV_PKT_BUF, abits) And
|
||
PktRdPtr /= PktWrPtr Then
|
||
Full <= '1';
|
||
Else
|
||
Full <= '0';
|
||
End If;
|
||
End Process;
|
||
end architecture rtl ; -- of PktBufFlags
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.TxWrDataSrcSel
|
||
-- Last modified : Fri Mar 30 11:53:19 2012.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
|
||
entity TxWrDataSrcSel is
|
||
port (
|
||
Dout : out std_logic_vector(15 downto 0);
|
||
EOPin : in std_logic;
|
||
EOPout : out std_logic;
|
||
SelSm : in std_logic;
|
||
SmDin : in std_logic_vector(15 downto 0);
|
||
TX_LL_DATA : in std_logic_vector(15 downto 0);
|
||
TX_LL_EOP : in std_logic;
|
||
TX_LL_VALID : in std_logic;
|
||
WrEn : out std_logic;
|
||
WrEnIn : in std_logic);
|
||
end entity TxWrDataSrcSel;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.TxWrDataSrcSel.rtl
|
||
-- Last modified : Fri Mar 30 11:53:19 2012.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
architecture rtl of TxWrDataSrcSel is
|
||
|
||
begin
|
||
WrEn <= WrEnIn When SelSm = '1' Else TX_LL_VALID;
|
||
Dout <= SmDin When SelSm = '1' Else TX_LL_DATA;
|
||
EOPout <= EOPin When SelSm = '1' Else TX_LL_EOP;
|
||
end architecture rtl ; -- of TxWrDataSrcSel
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.TxBuffers
|
||
-- Last modified : Mon Sep 15 10:25:34 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
use work.wr_fabric_pkg.all;
|
||
|
||
entity TxBuffers is
|
||
port (
|
||
CPU_AccGnt : out std_logic;
|
||
CPU_Tx : in ipmux_cpu_in_type;
|
||
Connect : out std_logic;
|
||
Connected : in std_logic;
|
||
FragID : in std_logic_vector(15 downto 0);
|
||
FragOff : in std_logic_vector(11 downto 0);
|
||
MoreFrag : in std_logic;
|
||
Stream : in natural range NUM_UDP_PRTS-1 downto 0;
|
||
TX_LL_DATA : in std_logic_vector(15 downto 0);
|
||
TX_LL_EOP : in std_logic;
|
||
TX_LL_RDREQ : out std_logic;
|
||
TX_LL_VALID : in std_logic;
|
||
eth_regs_i : in eth_regs_type;
|
||
src_i : in t_wrf_source_in;
|
||
src_o : out t_wrf_source_out;
|
||
tx_clk : in std_logic;
|
||
tx_collision : in std_logic;
|
||
tx_overflow : out std_logic;
|
||
tx_reset : in std_logic;
|
||
tx_retransmit : in std_logic;
|
||
tx_underrun : out std_logic);
|
||
end entity TxBuffers;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.TxBuffers.rtl
|
||
-- Last modified : Mon Sep 15 10:25:34 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
architecture rtl of TxBuffers is
|
||
|
||
signal Q : std_logic_vector(16 downto 0);
|
||
signal Dout : std_logic_vector(16 downto 0);
|
||
signal SelSm : std_logic;
|
||
signal WrEn0 : std_logic;
|
||
signal Dout0 : std_logic_vector(15 downto 0);
|
||
signal PktWrPtr : std_logic_vector(TX_PKT_BUF_ADRSIZE-1 downto 0);
|
||
signal PktRdPtr0 : std_logic_vector(TX_PKT_BUF_ADRSIZE-1 downto 0);
|
||
signal WrAddr0 : std_logic_vector(TX_PKT_BUF_ADRSIZE-1 downto 0);
|
||
signal Full : std_logic;
|
||
signal Empty : std_logic;
|
||
signal WrEn : std_logic;
|
||
signal WrAddr : std_logic_vector(TX_PKT_BUF_ADRSIZE-1 downto 0);
|
||
signal EOPout : std_logic;
|
||
signal PseudoHeader : std_logic_vector(31 downto 0);
|
||
|
||
component TxWrDataSrcSel
|
||
port (
|
||
Dout : out std_logic_vector(15 downto 0);
|
||
EOPin : in std_logic;
|
||
EOPout : out std_logic;
|
||
SelSm : in std_logic;
|
||
SmDin : in std_logic_vector(15 downto 0);
|
||
TX_LL_DATA : in std_logic_vector(15 downto 0);
|
||
TX_LL_EOP : in std_logic;
|
||
TX_LL_VALID : in std_logic;
|
||
WrEn : out std_logic;
|
||
WrEnIn : in std_logic);
|
||
end component TxWrDataSrcSel;
|
||
|
||
component PktBufFlags
|
||
generic(
|
||
abits : integer := 15);
|
||
port (
|
||
Empty : out std_logic;
|
||
Full : out std_logic;
|
||
PktRdPtr : in std_logic_vector(abits-1 downto 0);
|
||
PktWrPtr : in std_logic_vector(abits-1 downto 0);
|
||
WaterMarkHigh : out std_logic;
|
||
WaterMarkLow : out std_logic);
|
||
end component PktBufFlags;
|
||
|
||
component tx_pkt2mac
|
||
generic(
|
||
abits : integer := 15);
|
||
port (
|
||
Clk : in std_logic;
|
||
Din : in std_logic_vector(15 downto 0);
|
||
EOP : in std_logic;
|
||
Empty : in std_logic;
|
||
PktRdPtr : out std_logic_vector(abits-1 downto 0);
|
||
RdAddr : out std_logic_vector(abits-1 downto 0);
|
||
Rst : in std_logic;
|
||
src_i : in t_wrf_source_in;
|
||
src_o : out t_wrf_source_out);
|
||
end component tx_pkt2mac;
|
||
|
||
component tx_data2buf
|
||
generic(
|
||
abits : integer := 15);
|
||
port (
|
||
CPU_AccGnt : out std_logic;
|
||
CPU_Tx : in ipmux_cpu_in_type;
|
||
Clk : in std_logic;
|
||
ConnectReq : out std_logic;
|
||
Connected : in std_logic;
|
||
Dout : out std_logic_vector(15 downto 0);
|
||
EOPout : out std_logic;
|
||
FragID : in std_logic_vector(15 downto 0);
|
||
FragOff : in std_logic_vector(11 downto 0);
|
||
Full : in std_logic;
|
||
MoreFrag : in std_logic;
|
||
PktWrPtr : out std_logic_vector(abits-1 downto 0);
|
||
PseudoHeader : in std_logic_vector(31 downto 0);
|
||
Rst : in std_logic;
|
||
SelSm : out std_logic;
|
||
Stream : in natural range NUM_UDP_PRTS-1 downto 0;
|
||
TX_LL_DATA : in std_logic_vector(15 downto 0);
|
||
TX_LL_EOP : in std_logic;
|
||
TX_LL_RDREQ : out std_logic;
|
||
TX_LL_VALID : in std_logic;
|
||
WrAddr : out std_logic_vector(abits-1 downto 0);
|
||
WrEn : out std_logic;
|
||
eth_regs_i : in eth_regs_type);
|
||
end component tx_data2buf;
|
||
|
||
component Calc_UDP_PseudoHeader
|
||
port (
|
||
Clk : in std_logic;
|
||
PseudoHeader : out std_logic_vector(31 downto 0);
|
||
Rst : in std_logic;
|
||
eth_regs_i : in eth_regs_type);
|
||
end component Calc_UDP_PseudoHeader;
|
||
|
||
component PacketBuffer
|
||
generic(
|
||
abits : integer := 15;
|
||
dbits : integer := 8);
|
||
port (
|
||
AddrA : in std_logic_vector(abits-1 downto 0);
|
||
AddrB : in std_logic_vector(abits-1 downto 0);
|
||
Clk : in std_logic;
|
||
Din : in std_logic_vector(dbits-1 downto 0);
|
||
Q : out std_logic_vector(dbits-1 downto 0);
|
||
Rst : in std_logic;
|
||
WeA : in std_logic);
|
||
end component PacketBuffer;
|
||
|
||
begin
|
||
--32 KB buffer can store at least
|
||
--3 jumbo frames (9000 bytes each)
|
||
--Local Link Interface
|
||
--MAC Interface
|
||
--A complete paket is always accumelated
|
||
--in the buffer before a transmit is started,
|
||
--so an underrun can never occur.
|
||
--Note that due timing issues between "eth_regs.IP_Src" and "tx_data2buf/CheckSum"
|
||
--which occured during place&route it was decided to pre-calculate the content of
|
||
--the pseudo header in order to avoid timing problems.
|
||
--
|
||
tx_overflow <= '0';
|
||
tx_underrun <= '0';
|
||
|
||
u2: TxWrDataSrcSel
|
||
port map(
|
||
Dout => Dout(15 downto 0),
|
||
EOPin => EOPout,
|
||
EOPout => Dout(16),
|
||
SelSm => SelSm,
|
||
SmDin => Dout0,
|
||
TX_LL_DATA => TX_LL_DATA,
|
||
TX_LL_EOP => TX_LL_EOP,
|
||
TX_LL_VALID => TX_LL_VALID,
|
||
WrEn => WrEn0,
|
||
WrEnIn => WrEn);
|
||
|
||
u4: PktBufFlags
|
||
generic map(
|
||
abits => TX_PKT_BUF_ADRSIZE)
|
||
port map(
|
||
Empty => Empty,
|
||
Full => Full,
|
||
PktRdPtr => PktRdPtr0,
|
||
PktWrPtr => PktWrPtr,
|
||
WaterMarkHigh => open,
|
||
WaterMarkLow => open);
|
||
|
||
u3: tx_pkt2mac
|
||
generic map(
|
||
abits => TX_PKT_BUF_ADRSIZE)
|
||
port map(
|
||
Clk => tx_clk,
|
||
Din => Q(15 downto 0),
|
||
EOP => Q(16),
|
||
Empty => Empty,
|
||
PktRdPtr => PktRdPtr0,
|
||
RdAddr => WrAddr0,
|
||
Rst => tx_reset,
|
||
src_i => src_i,
|
||
src_o => src_o);
|
||
|
||
u1: tx_data2buf
|
||
generic map(
|
||
abits => TX_PKT_BUF_ADRSIZE)
|
||
port map(
|
||
CPU_AccGnt => CPU_AccGnt,
|
||
CPU_Tx => CPU_Tx,
|
||
Clk => tx_clk,
|
||
ConnectReq => Connect,
|
||
Connected => Connected,
|
||
Dout => Dout0,
|
||
EOPout => EOPout,
|
||
FragID => FragID,
|
||
FragOff => FragOff,
|
||
Full => Full,
|
||
MoreFrag => MoreFrag,
|
||
PktWrPtr => PktWrPtr,
|
||
PseudoHeader => PseudoHeader,
|
||
Rst => tx_reset,
|
||
SelSm => SelSm,
|
||
Stream => Stream,
|
||
TX_LL_DATA => TX_LL_DATA,
|
||
TX_LL_EOP => TX_LL_EOP,
|
||
TX_LL_RDREQ => TX_LL_RDREQ,
|
||
TX_LL_VALID => TX_LL_VALID,
|
||
WrAddr => WrAddr,
|
||
WrEn => WrEn,
|
||
eth_regs_i => eth_regs_i);
|
||
|
||
u6: Calc_UDP_PseudoHeader
|
||
port map(
|
||
Clk => tx_clk,
|
||
PseudoHeader => PseudoHeader,
|
||
Rst => tx_reset,
|
||
eth_regs_i => eth_regs_i);
|
||
|
||
u0: PacketBuffer
|
||
generic map(
|
||
abits => TX_PKT_BUF_ADRSIZE,
|
||
dbits => 17)
|
||
port map(
|
||
AddrA => WrAddr,
|
||
AddrB => WrAddr0,
|
||
Clk => tx_clk,
|
||
Din => Dout,
|
||
Q => Q,
|
||
Rst => tx_reset,
|
||
WeA => WrEn0);
|
||
end architecture rtl ; -- of TxBuffers
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.RxBuffers
|
||
-- Last modified : Fri Sep 12 17:27:37 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.wr_fabric_pkg.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
|
||
entity RxBuffers is
|
||
port (
|
||
FragID : out std_logic_vector(15 downto 0);
|
||
FragOff : out std_logic_vector(11 downto 0);
|
||
Full : in std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
MoreFrags : out std_logic;
|
||
PauseAck : in std_logic;
|
||
PauseReq : out std_logic;
|
||
PauseVal : out std_logic_vector(15 downto 0);
|
||
RXo : out dbus_type_array(NUM_UDP_PRTS downto 0);
|
||
UDP_CheckSumErr : out std_logic;
|
||
WrReq : out std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
eth_regs_i : in eth_regs_type;
|
||
rx_clk : in std_logic;
|
||
rx_reset : in std_logic;
|
||
snk_i : in t_wrf_sink_in;
|
||
snk_o : out t_wrf_sink_out);
|
||
end entity RxBuffers;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.RxBuffers.structure
|
||
-- Last modified : Fri Sep 12 17:27:37 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
architecture structure of RxBuffers is
|
||
|
||
signal Din0 : std_logic_vector(16 downto 0);
|
||
signal We : std_logic;
|
||
signal PktWrPtr : std_logic_vector(RX_PKT_BUF_ADRSIZE-1 downto 0);
|
||
signal WrAddr : std_logic_vector(RX_PKT_BUF_ADRSIZE-1 downto 0);
|
||
signal LowThrs : std_logic;
|
||
signal HighThrs : std_logic;
|
||
signal Empty0 : std_logic;
|
||
signal PktRdPtr0 : std_logic_vector(RX_PKT_BUF_ADRSIZE-1 downto 0);
|
||
signal RdAddr : std_logic_vector(RX_PKT_BUF_ADRSIZE-1 downto 0);
|
||
signal Net_3 : std_logic_vector(16 downto 0);
|
||
signal Stream : std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
signal Full_net : std_logic;
|
||
signal Fullout : std_logic;
|
||
signal Tst_WrReq_net : std_logic;
|
||
signal SODout_net : std_logic;
|
||
signal EODout_net : std_logic;
|
||
|
||
component rx_mac2buf
|
||
generic(
|
||
abits : integer := 15);
|
||
port (
|
||
Clk : in std_logic;
|
||
Dout : out std_logic_vector(15 downto 0);
|
||
EOF : out std_logic;
|
||
Full : in std_logic;
|
||
OverFlow : out std_logic;
|
||
PktWrPtr : out std_logic_vector(abits-1 downto 0);
|
||
Rst : in std_logic;
|
||
We : out std_logic;
|
||
WrAddr : out std_logic_vector(abits-1 downto 0);
|
||
snk_i : in t_wrf_sink_in;
|
||
snk_o : out t_wrf_sink_out);
|
||
end component rx_mac2buf;
|
||
|
||
component PktBufFlags
|
||
generic(
|
||
abits : integer := 15);
|
||
port (
|
||
Empty : out std_logic;
|
||
Full : out std_logic;
|
||
PktRdPtr : in std_logic_vector(abits-1 downto 0);
|
||
PktWrPtr : in std_logic_vector(abits-1 downto 0);
|
||
WaterMarkHigh : out std_logic;
|
||
WaterMarkLow : out std_logic);
|
||
end component PktBufFlags;
|
||
|
||
component PauseReqLogic
|
||
port (
|
||
Clk : in std_logic;
|
||
PauseAck : in std_logic;
|
||
PauseReq : out std_logic;
|
||
PauseVal : out std_logic_vector(15 downto 0);
|
||
Rst : in std_logic;
|
||
WaterMarkHigh : in std_logic;
|
||
WaterMarkLow : in std_logic);
|
||
end component PauseReqLogic;
|
||
|
||
component rx_buf2data
|
||
generic(
|
||
abits : integer := 15);
|
||
port (
|
||
Clk : in std_logic;
|
||
Din : in std_logic_vector(15 downto 0);
|
||
EODout : out std_logic;
|
||
EOFin : in std_logic;
|
||
Empty : in std_logic;
|
||
FragID : out std_logic_vector(15 downto 0);
|
||
FragOff : out std_logic_vector(11 downto 0);
|
||
Full : in std_logic;
|
||
MoreFrags : out std_logic;
|
||
PktRdPtr : out std_logic_vector(abits-1 downto 0);
|
||
RdAddr : out std_logic_vector(abits-1 downto 0);
|
||
Rst : in std_logic;
|
||
SODout : out std_logic;
|
||
Stream : out std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
UDP_CheckSumErr : out std_logic;
|
||
WrReq : out std_logic;
|
||
eth_regs_i : in eth_regs_type);
|
||
end component rx_buf2data;
|
||
|
||
component RxStreamSel
|
||
port (
|
||
Din : in std_logic_vector(15 downto 0);
|
||
EODin : in std_logic;
|
||
EOFin : in std_logic;
|
||
Full : in std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
Fullout : out std_logic;
|
||
RXo : out dbus_type_array(NUM_UDP_PRTS downto 0);
|
||
SODin : in std_logic;
|
||
Stream : in std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
WrReq : out std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
WrReqin : in std_logic);
|
||
end component RxStreamSel;
|
||
|
||
component PacketBuffer
|
||
generic(
|
||
abits : integer := 15;
|
||
dbits : integer := 8);
|
||
port (
|
||
AddrA : in std_logic_vector(abits-1 downto 0);
|
||
AddrB : in std_logic_vector(abits-1 downto 0);
|
||
Clk : in std_logic;
|
||
Din : in std_logic_vector(dbits-1 downto 0);
|
||
Q : out std_logic_vector(dbits-1 downto 0);
|
||
Rst : in std_logic;
|
||
WeA : in std_logic);
|
||
end component PacketBuffer;
|
||
|
||
begin
|
||
--MAC Interface (White Rabbit PTP Core; WRPC)
|
||
--Local Link Interface
|
||
--EOF signals the End Of MAC Frame. The MAC frame ranges from the first
|
||
--byte after the Start of Frame Delimiter (SFD) to the last data byte
|
||
--before the first Frame Control Sequence (FCS). Note however that for
|
||
--Ethernet v2 framing this *also* includes padded data that might have
|
||
--been inserted to ensure that the frame length is at least 64 bytes!
|
||
--
|
||
--Entity "rx_buf2data" generates Start and End Of Data (SOD and EOD) to
|
||
--signal the first and last data byte of the UDP packet (or the CPU packet)
|
||
--without including padded data bytes.
|
||
--
|
||
--The exception is the CPU stream where the End Of Frame Signalling from
|
||
--the MAC is routed directly to the EOD of the CPU channel (see entity
|
||
--RxStreamSel). There is no other means to know the end of a Frame since
|
||
--unknown Frames are not decoded.
|
||
--
|
||
--UDP CheckSum Error is signalled after a packet is
|
||
--transferred to the output fifo and is de-asserted
|
||
--when the state machine (re)starts for receiving
|
||
--another packet. For monitorring purposes one may
|
||
--want to count the rising edges of this signal in
|
||
--order to track the amount of UDP checksum errors.
|
||
--Overflow occurs when Full ='1' while
|
||
--the MAC wants to write a frame into
|
||
--the buffer memory.
|
||
--Signal is pulsed?
|
||
|
||
u1: rx_mac2buf
|
||
generic map(
|
||
abits => RX_PKT_BUF_ADRSIZE)
|
||
port map(
|
||
Clk => rx_clk,
|
||
Dout => Din0(15 downto 0),
|
||
EOF => Din0(16),
|
||
Full => Full_net,
|
||
OverFlow => open,
|
||
PktWrPtr => PktWrPtr,
|
||
Rst => rx_reset,
|
||
We => We,
|
||
WrAddr => WrAddr,
|
||
snk_i => snk_i,
|
||
snk_o => snk_o);
|
||
|
||
u4: PktBufFlags
|
||
generic map(
|
||
abits => RX_PKT_BUF_ADRSIZE)
|
||
port map(
|
||
Empty => Empty0,
|
||
Full => Full_net,
|
||
PktRdPtr => PktRdPtr0,
|
||
PktWrPtr => PktWrPtr,
|
||
WaterMarkHigh => HighThrs,
|
||
WaterMarkLow => LowThrs);
|
||
|
||
u2: PauseReqLogic
|
||
port map(
|
||
Clk => rx_clk,
|
||
PauseAck => PauseAck,
|
||
PauseReq => PauseReq,
|
||
PauseVal => PauseVal,
|
||
Rst => rx_reset,
|
||
WaterMarkHigh => HighThrs,
|
||
WaterMarkLow => LowThrs);
|
||
|
||
u5: rx_buf2data
|
||
generic map(
|
||
abits => RX_PKT_BUF_ADRSIZE)
|
||
port map(
|
||
Clk => rx_clk,
|
||
Din => Net_3(15 downto 0),
|
||
EODout => EODout_net,
|
||
EOFin => Net_3(16),
|
||
Empty => Empty0,
|
||
FragID => FragID,
|
||
FragOff => FragOff,
|
||
Full => Fullout,
|
||
MoreFrags => MoreFrags,
|
||
PktRdPtr => PktRdPtr0,
|
||
RdAddr => RdAddr,
|
||
Rst => rx_reset,
|
||
SODout => SODout_net,
|
||
Stream => Stream,
|
||
UDP_CheckSumErr => UDP_CheckSumErr,
|
||
WrReq => Tst_WrReq_net,
|
||
eth_regs_i => eth_regs_i);
|
||
|
||
u3: RxStreamSel
|
||
port map(
|
||
Din => Net_3(15 downto 0),
|
||
EODin => EODout_net,
|
||
EOFin => Net_3(16),
|
||
Full => Full,
|
||
Fullout => Fullout,
|
||
RXo => RXo,
|
||
SODin => SODout_net,
|
||
Stream => Stream,
|
||
WrReq => WrReq,
|
||
WrReqin => Tst_WrReq_net);
|
||
|
||
u0: PacketBuffer
|
||
generic map(
|
||
abits => RX_PKT_BUF_ADRSIZE,
|
||
dbits => 17)
|
||
port map(
|
||
AddrA => WrAddr,
|
||
AddrB => RdAddr,
|
||
Clk => rx_clk,
|
||
Din => Din0,
|
||
Q => Net_3,
|
||
Rst => rx_reset,
|
||
WeA => We);
|
||
end architecture structure ; -- of RxBuffers
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.ipmux
|
||
-- Last modified : Mon Jun 29 14:49:52 2015.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.wr_fabric_pkg.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
use work.wishbone_pkg.all;
|
||
|
||
entity ipmux is
|
||
port (
|
||
CPU_Gnt : out std_logic;
|
||
CPU_Req : out std_logic;
|
||
ConnectReq : out std_logic;
|
||
Empty : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Full : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
PauseAck : in std_logic;
|
||
PauseReq : out std_logic;
|
||
PauseVal : out std_logic_vector(15 downto 0);
|
||
RdClk : in std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
RdReq : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Rst : in std_logic;
|
||
Rx : out dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
Stream : out natural range NUM_UDP_PRTS-1 downto 0;
|
||
Tx : in dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
WrClk : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
WrReq : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
div_ratio : out std_logic_vector(31 downto 0);
|
||
numpackets : out std_logic_vector(9 downto 0);
|
||
numwords : out std_logic_vector(13 downto 0);
|
||
snk_i : in t_wrf_sink_in;
|
||
snk_o : out t_wrf_sink_out;
|
||
src_i : in t_wrf_source_in;
|
||
src_o : out t_wrf_source_out;
|
||
tx_clk : in std_logic;
|
||
tx_reset : in std_logic;
|
||
udptstctrl : out std_logic_vector(2 downto 0);
|
||
wb_ipmux_reg_i : in t_wishbone_slave_in;
|
||
wb_ipmux_reg_o : out t_wishbone_slave_out;
|
||
wb_ipmux_rx_tx_i : in t_wishbone_slave_in;
|
||
wb_ipmux_rx_tx_o : out t_wishbone_slave_out);
|
||
end entity ipmux;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.ipmux.rtl
|
||
-- Last modified : Mon Jun 29 14:49:52 2015.
|
||
--------------------------------------------------------------------------------
|
||
|
||
architecture rtl of ipmux is
|
||
|
||
signal CPU_Gnt_net : std_logic;
|
||
signal Full_net : std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
signal Full_net0 : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal RdReqOut : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal Valid : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal Dout1 : std_logic_vector(15 downto 0);
|
||
signal EOPout : std_logic;
|
||
signal TX_LL_RDREQ0 : std_logic;
|
||
signal Validinout : std_logic;
|
||
signal Empty_net : std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
signal u7_RdReq : std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
signal WrReq_net : std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
signal Rx_net0 : dbus_type_array(NUM_UDP_PRTS downto 0);
|
||
signal TXo : dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
signal RX_net : dbus_type_array(NUM_UDP_PRTS downto 0);
|
||
signal u4_eth_regs_o : eth_regs_type;
|
||
signal CPU_Tx : ipmux_cpu_in_type;
|
||
signal u4_Flush : std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
signal ConnectReq_net : std_logic;
|
||
signal Stream_net : natural range NUM_UDP_PRTS-1 downto 0;
|
||
signal u1_Connected : std_logic;
|
||
signal Packet : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal Packet_RdReq : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal TxStreamDebug : std_logic_vector(11 downto 0);
|
||
signal PacketsDone : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
|
||
component TxBuffers
|
||
port (
|
||
CPU_AccGnt : out std_logic;
|
||
CPU_Tx : in ipmux_cpu_in_type;
|
||
Connect : out std_logic;
|
||
Connected : in std_logic;
|
||
FragID : in std_logic_vector(15 downto 0);
|
||
FragOff : in std_logic_vector(11 downto 0);
|
||
MoreFrag : in std_logic;
|
||
Stream : in natural range NUM_UDP_PRTS-1 downto 0;
|
||
TX_LL_DATA : in std_logic_vector(15 downto 0);
|
||
TX_LL_EOP : in std_logic;
|
||
TX_LL_RDREQ : out std_logic;
|
||
TX_LL_VALID : in std_logic;
|
||
eth_regs_i : in eth_regs_type;
|
||
src_i : in t_wrf_source_in;
|
||
src_o : out t_wrf_source_out;
|
||
tx_clk : in std_logic;
|
||
tx_collision : in std_logic;
|
||
tx_overflow : out std_logic;
|
||
tx_reset : in std_logic;
|
||
tx_retransmit : in std_logic;
|
||
tx_underrun : out std_logic);
|
||
end component TxBuffers;
|
||
|
||
component RxBuffers
|
||
port (
|
||
FragID : out std_logic_vector(15 downto 0);
|
||
FragOff : out std_logic_vector(11 downto 0);
|
||
Full : in std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
MoreFrags : out std_logic;
|
||
PauseAck : in std_logic;
|
||
PauseReq : out std_logic;
|
||
PauseVal : out std_logic_vector(15 downto 0);
|
||
RXo : out dbus_type_array(NUM_UDP_PRTS downto 0);
|
||
UDP_CheckSumErr : out std_logic;
|
||
WrReq : out std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
eth_regs_i : in eth_regs_type;
|
||
rx_clk : in std_logic;
|
||
rx_reset : in std_logic;
|
||
snk_i : in t_wrf_sink_in;
|
||
snk_o : out t_wrf_sink_out);
|
||
end component RxBuffers;
|
||
|
||
component rxfifos
|
||
port (
|
||
Empty : out std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
Flush : in std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
Full : out std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
RXi : in dbus_type_array(NUM_UDP_PRTS downto 0);
|
||
RXo : out dbus_type_array(NUM_UDP_PRTS downto 0);
|
||
RdClk : in std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
RdReq : in std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
Rst : in std_logic;
|
||
WrClk : in std_logic;
|
||
WrReq : in std_logic_vector(NUM_UDP_PRTS downto 0));
|
||
end component rxfifos;
|
||
|
||
component txfifos
|
||
port (
|
||
Flush : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Full : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Packet : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Packet_RdReq : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
PacketsDone : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
RdClk : in std_logic;
|
||
RdReq : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Rst : in std_logic;
|
||
TXi : in dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
TXo : out dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
Valid : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
WrClk : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
WrReq : in std_logic_vector(NUM_UDP_PRTS-1 downto 0));
|
||
end component txfifos;
|
||
|
||
component TxStreamSel
|
||
port (
|
||
Clk : in std_logic;
|
||
ConnectReq : in std_logic;
|
||
Connected : out std_logic;
|
||
Dout : out std_logic_vector(15 downto 0);
|
||
EODout : out std_logic;
|
||
Packet : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Packet_RdReq : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
RdReqOut : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
RdReqin : in std_logic;
|
||
Rst : in std_logic;
|
||
Stream : out natural range NUM_UDP_PRTS-1 downto 0;
|
||
TXi : in dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
TxStreamDebug : out std_logic_vector(11 downto 0);
|
||
Validin : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Validout : out std_logic);
|
||
end component TxStreamSel;
|
||
|
||
component ipmux_regs_and_rxtxcpu
|
||
port (
|
||
CPU_AccGnt : in std_logic;
|
||
CPU_Tx : out ipmux_cpu_in_type;
|
||
Clk : in std_logic;
|
||
Flush : out std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
PacketsDone : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Rst : in std_logic;
|
||
Rx_Empty : in std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
TxStreamDebug : in std_logic_vector(11 downto 0);
|
||
Tx_Full : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
cpu_rdreq : out std_logic;
|
||
cpu_rx : in dbus_type;
|
||
div_ratio : out std_logic_vector(31 downto 0);
|
||
eth_regs_o : out eth_regs_type;
|
||
numpackets : out std_logic_vector(9 downto 0);
|
||
numwords : out std_logic_vector(13 downto 0);
|
||
udptstctrl : out std_logic_vector(2 downto 0);
|
||
wb_ipmux_reg_i : in t_wishbone_slave_in;
|
||
wb_ipmux_reg_o : out t_wishbone_slave_out;
|
||
wb_ipmux_rx_tx_i : in t_wishbone_slave_in;
|
||
wb_ipmux_rx_tx_o : out t_wishbone_slave_out);
|
||
end component ipmux_regs_and_rxtxcpu;
|
||
|
||
begin
|
||
--Application Clock domain
|
||
--MAC Clock domain
|
||
--There are NUM_UDP_PRTS + 1 Receive Fifos.
|
||
--The Default Stream (= CPU; index = NUM_UDP_PRTS)
|
||
--is handled in a similar way as the UDP receive streams.
|
||
--Wishbone connection
|
||
--to IPMUX registers
|
||
--Wishbone connection
|
||
--to CPU Rx/Tx Interface
|
||
--Debugging:
|
||
CPU_Gnt <= CPU_Gnt_net;
|
||
Full <= Full_net0;
|
||
Empty <= Empty_net(NUM_UDP_PRTS-1 downto 0);
|
||
u7_RdReq(NUM_UDP_PRTS-1 downto 0) <= RdReq;
|
||
Rx <= Rx_net0(NUM_UDP_PRTS-1 downto 0);
|
||
ConnectReq <= ConnectReq_net;
|
||
Stream <= Stream_net;
|
||
|
||
u0: TxBuffers
|
||
port map(
|
||
CPU_AccGnt => CPU_Gnt_net,
|
||
CPU_Tx => CPU_Tx,
|
||
Connect => ConnectReq_net,
|
||
Connected => u1_Connected,
|
||
FragID => x"0000",
|
||
FragOff => x"000",
|
||
MoreFrag => '0',
|
||
Stream => Stream_net,
|
||
TX_LL_DATA => Dout1,
|
||
TX_LL_EOP => EOPout,
|
||
TX_LL_RDREQ => TX_LL_RDREQ0,
|
||
TX_LL_VALID => Validinout,
|
||
eth_regs_i => u4_eth_regs_o,
|
||
src_i => src_i,
|
||
src_o => src_o,
|
||
tx_clk => tx_clk,
|
||
tx_collision => '0',
|
||
tx_overflow => open,
|
||
tx_reset => tx_reset,
|
||
tx_retransmit => '0',
|
||
tx_underrun => open);
|
||
|
||
u6: RxBuffers
|
||
port map(
|
||
FragID => open,
|
||
FragOff => open,
|
||
Full => Full_net,
|
||
MoreFrags => open,
|
||
PauseAck => PauseAck,
|
||
PauseReq => PauseReq,
|
||
PauseVal => PauseVal,
|
||
RXo => RX_net,
|
||
UDP_CheckSumErr => open,
|
||
WrReq => WrReq_net,
|
||
eth_regs_i => u4_eth_regs_o,
|
||
rx_clk => tx_clk,
|
||
rx_reset => tx_reset,
|
||
snk_i => snk_i,
|
||
snk_o => snk_o);
|
||
|
||
u7: rxfifos
|
||
port map(
|
||
Empty => Empty_net,
|
||
Flush => u4_Flush,
|
||
Full => Full_net,
|
||
RXi => RX_net,
|
||
RXo => Rx_net0,
|
||
RdClk => RdClk,
|
||
RdReq => u7_RdReq,
|
||
Rst => Rst,
|
||
WrClk => tx_clk,
|
||
WrReq => WrReq_net);
|
||
|
||
u8: txfifos
|
||
port map(
|
||
Flush => u4_Flush(NUM_UDP_PRTS-1 downto 0),
|
||
Full => Full_net0,
|
||
Packet => Packet,
|
||
Packet_RdReq => Packet_RdReq,
|
||
PacketsDone => PacketsDone,
|
||
RdClk => tx_clk,
|
||
RdReq => RdReqOut,
|
||
Rst => Rst,
|
||
TXi => Tx,
|
||
TXo => TXo,
|
||
Valid => Valid,
|
||
WrClk => WrClk,
|
||
WrReq => WrReq);
|
||
|
||
u1: TxStreamSel
|
||
port map(
|
||
Clk => tx_clk,
|
||
ConnectReq => ConnectReq_net,
|
||
Connected => u1_Connected,
|
||
Dout => Dout1,
|
||
EODout => EOPout,
|
||
Packet => Packet,
|
||
Packet_RdReq => Packet_RdReq,
|
||
RdReqOut => RdReqOut,
|
||
RdReqin => TX_LL_RDREQ0,
|
||
Rst => tx_reset,
|
||
Stream => Stream_net,
|
||
TXi => TXo,
|
||
TxStreamDebug => TxStreamDebug,
|
||
Validin => Valid,
|
||
Validout => Validinout);
|
||
|
||
u4: ipmux_regs_and_rxtxcpu
|
||
port map(
|
||
CPU_AccGnt => CPU_Gnt_net,
|
||
CPU_Tx => CPU_Tx,
|
||
Clk => tx_clk,
|
||
Flush => u4_Flush,
|
||
PacketsDone => PacketsDone,
|
||
Rst => Rst,
|
||
Rx_Empty => Empty_net,
|
||
TxStreamDebug => TxStreamDebug,
|
||
Tx_Full => Full_net0,
|
||
cpu_rdreq => u7_RdReq(NUM_UDP_PRTS),
|
||
cpu_rx => Rx_net0(NUM_UDP_PRTS),
|
||
div_ratio => div_ratio,
|
||
eth_regs_o => u4_eth_regs_o,
|
||
numpackets => numpackets,
|
||
numwords => numwords,
|
||
udptstctrl => udptstctrl,
|
||
wb_ipmux_reg_i => wb_ipmux_reg_i,
|
||
wb_ipmux_reg_o => wb_ipmux_reg_o,
|
||
wb_ipmux_rx_tx_i => wb_ipmux_rx_tx_i,
|
||
wb_ipmux_rx_tx_o => wb_ipmux_rx_tx_o);
|
||
CPU_Req <= CPU_Tx.Request;
|
||
end architecture rtl ; -- of ipmux
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.fpga
|
||
-- Last modified : Wed Sep 17 13:50:52 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.wr_fabric_pkg.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
use work.wishbone_pkg.all;
|
||
|
||
entity fpga is
|
||
generic(
|
||
Simulation : boolean := False);
|
||
port (
|
||
ClkI_n : in std_logic;
|
||
ClkI_p : in std_logic;
|
||
Fire : in std_logic_vector(3 downto 0);
|
||
RstIn : in std_logic;
|
||
TxFireCPU : in std_logic;
|
||
UDP_Rx : out dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
UDP_Rx_Empty : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
UDP_Rx_RdReq : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
snk_i : in t_wrf_sink_in;
|
||
snk_o : out t_wrf_sink_out;
|
||
src_i : in t_wrf_source_in;
|
||
src_o : out t_wrf_source_out;
|
||
wb_ipmux_reg_i : in t_wishbone_slave_in;
|
||
wb_ipmux_reg_o : out t_wishbone_slave_out;
|
||
wb_ipmux_rx_tx_i : in t_wishbone_slave_in;
|
||
wb_ipmux_rx_tx_o : out t_wishbone_slave_out);
|
||
end entity fpga;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.fpga.a0
|
||
-- Last modified : Wed Sep 17 13:50:52 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
library UNISIM;
|
||
use UNISIM.IBUFDS_GTE2;
|
||
|
||
architecture a0 of fpga is
|
||
|
||
signal Rst : std_logic;
|
||
signal RdClk_net : std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
signal RdReq_net : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal Empty_net : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal WrClk_net : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal WrReq_net : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal Full_net : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal Rx : dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
signal Tx : dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
signal O : std_logic;
|
||
signal clk_62_5_o : std_logic;
|
||
signal Fullo : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal UDP_Tx_WrReq : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal UDP_Tx : dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
signal UDP_Rx_Empty_net : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal u7_UDP_Rx_RdReq : std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
signal u3_clk_125_o : std_logic;
|
||
|
||
component ipmux
|
||
port (
|
||
CPU_Gnt : out std_logic;
|
||
CPU_Req : out std_logic;
|
||
ConnectReq : out std_logic;
|
||
Empty : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Full : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
PauseAck : in std_logic;
|
||
PauseReq : out std_logic;
|
||
PauseVal : out std_logic_vector(15 downto 0);
|
||
RdClk : in std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
RdReq : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Rst : in std_logic;
|
||
Rx : out dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
Stream : out natural range NUM_UDP_PRTS-1 downto 0;
|
||
Tx : in dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
WrClk : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
WrReq : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
div_ratio : out std_logic_vector(31 downto 0);
|
||
numpackets : out std_logic_vector(9 downto 0);
|
||
numwords : out std_logic_vector(13 downto 0);
|
||
snk_i : in t_wrf_sink_in;
|
||
snk_o : out t_wrf_sink_out;
|
||
src_i : in t_wrf_source_in;
|
||
src_o : out t_wrf_source_out;
|
||
tx_clk : in std_logic;
|
||
tx_reset : in std_logic;
|
||
udptstctrl : out std_logic_vector(2 downto 0);
|
||
wb_ipmux_reg_i : in t_wishbone_slave_in;
|
||
wb_ipmux_reg_o : out t_wishbone_slave_out;
|
||
wb_ipmux_rx_tx_i : in t_wishbone_slave_in;
|
||
wb_ipmux_rx_tx_o : out t_wishbone_slave_out);
|
||
end component ipmux;
|
||
|
||
component ClkDist
|
||
port (
|
||
Clk125 : in std_logic;
|
||
Clk62_5 : in std_logic;
|
||
Emptyi : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Emptyo : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Fulli : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Fullo : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
RdClk : out std_logic_vector(NUM_UDP_PRTS downto 0);
|
||
RdReqi : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
RdReqo : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
Rx : in dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
Tx : out dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
UDP_Rx : out dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
UDP_Tx : in dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
WrClk : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
WrReqi : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
WrReqo : out std_logic_vector(NUM_UDP_PRTS-1 downto 0));
|
||
end component ClkDist;
|
||
|
||
component PowerOnRst
|
||
port (
|
||
Rst : out std_logic;
|
||
RstIn : in std_logic);
|
||
end component PowerOnRst;
|
||
|
||
component IBUFDS_GTE2
|
||
port (
|
||
CEB : in std_logic;
|
||
I : in std_logic;
|
||
IB : in std_logic;
|
||
O : out std_logic;
|
||
ODIV2 : out std_logic);
|
||
end component IBUFDS_GTE2;
|
||
|
||
component cmp_sys_clk_pll
|
||
port (
|
||
clk_125_o : out std_logic;
|
||
clk_62_5_o : out std_logic;
|
||
clk_i : in std_logic;
|
||
locked_o : out std_logic;
|
||
rst_i : in std_logic);
|
||
end component cmp_sys_clk_pll;
|
||
|
||
component FirePackets
|
||
generic(
|
||
Simulation : boolean := False);
|
||
port (
|
||
Clk : in std_logic;
|
||
Fire : in std_logic_vector(3 downto 0);
|
||
Rst : in std_logic;
|
||
UDP_Tx : out dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
UDP_Tx_Full : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
UDP_Tx_WrReq : out std_logic_vector(NUM_UDP_PRTS-1 downto 0));
|
||
end component FirePackets;
|
||
|
||
component FireCPU_Packet
|
||
port (
|
||
CPU_AccGnt : in std_logic;
|
||
Clk : in std_logic;
|
||
Rst : in std_logic;
|
||
TxFireCPU : in std_logic;
|
||
UDP_TX_CPU : out ipmux_cpu_in_type);
|
||
end component FireCPU_Packet;
|
||
|
||
component RdOutAll
|
||
port (
|
||
UDP_Rx_Empty : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
UDP_Rx_RdReq : out std_logic_vector(NUM_UDP_PRTS-1 downto 0));
|
||
end component RdOutAll;
|
||
|
||
begin
|
||
--MAC (= WR Endpoint)
|
||
--Application interface
|
||
--FirePackets is there for test purposes.
|
||
--Packets are fires at 125 MHz (16 bit data;
|
||
--twice the Ethernet speed)
|
||
--Tx Ethernet Data
|
||
--Rx Ethernet Data
|
||
--FirCPU_Packet is a Recidu for
|
||
--testing the transfission of CPU
|
||
--packets. This is now implemented
|
||
--via wishobe register access.
|
||
--Debug
|
||
UDP_Rx_Empty <= UDP_Rx_Empty_net;
|
||
|
||
u14: ipmux
|
||
port map(
|
||
CPU_Gnt => open,
|
||
CPU_Req => open,
|
||
ConnectReq => open,
|
||
Empty => Empty_net,
|
||
Full => Full_net,
|
||
PauseAck => '0',
|
||
PauseReq => open,
|
||
PauseVal => open,
|
||
RdClk => RdClk_net,
|
||
RdReq => RdReq_net,
|
||
Rst => Rst,
|
||
Rx => Rx,
|
||
Stream => open,
|
||
Tx => Tx,
|
||
WrClk => WrClk_net,
|
||
WrReq => WrReq_net,
|
||
div_ratio => open,
|
||
numpackets => open,
|
||
numwords => open,
|
||
snk_i => snk_i,
|
||
snk_o => snk_o,
|
||
src_i => src_i,
|
||
src_o => src_o,
|
||
tx_clk => clk_62_5_o,
|
||
tx_reset => Rst,
|
||
udptstctrl => open,
|
||
wb_ipmux_reg_i => wb_ipmux_reg_i,
|
||
wb_ipmux_reg_o => wb_ipmux_reg_o,
|
||
wb_ipmux_rx_tx_i => wb_ipmux_rx_tx_i,
|
||
wb_ipmux_rx_tx_o => wb_ipmux_rx_tx_o);
|
||
|
||
u1: ClkDist
|
||
port map(
|
||
Clk125 => u3_clk_125_o,
|
||
Clk62_5 => clk_62_5_o,
|
||
Emptyi => Empty_net,
|
||
Emptyo => UDP_Rx_Empty_net,
|
||
Fulli => Full_net,
|
||
Fullo => Fullo,
|
||
RdClk => RdClk_net,
|
||
RdReqi => u7_UDP_Rx_RdReq,
|
||
RdReqo => RdReq_net,
|
||
Rx => Rx,
|
||
Tx => Tx,
|
||
UDP_Rx => UDP_Rx,
|
||
UDP_Tx => UDP_Tx,
|
||
WrClk => WrClk_net,
|
||
WrReqi => UDP_Tx_WrReq,
|
||
WrReqo => WrReq_net);
|
||
|
||
u0: PowerOnRst
|
||
port map(
|
||
Rst => Rst,
|
||
RstIn => RstIn);
|
||
|
||
u2: IBUFDS_GTE2
|
||
port map(
|
||
CEB => '0',
|
||
I => ClkI_p,
|
||
IB => ClkI_n,
|
||
O => O,
|
||
ODIV2 => open);
|
||
|
||
u3: cmp_sys_clk_pll
|
||
port map(
|
||
clk_125_o => u3_clk_125_o,
|
||
clk_62_5_o => clk_62_5_o,
|
||
clk_i => O,
|
||
locked_o => open,
|
||
rst_i => '0');
|
||
|
||
u4: FirePackets
|
||
generic map(
|
||
Simulation => Simulation)
|
||
port map(
|
||
Clk => clk_62_5_o,
|
||
Fire => Fire,
|
||
Rst => Rst,
|
||
UDP_Tx => UDP_Tx,
|
||
UDP_Tx_Full => Fullo,
|
||
UDP_Tx_WrReq => UDP_Tx_WrReq);
|
||
|
||
u5: FireCPU_Packet
|
||
port map(
|
||
CPU_AccGnt => '0',
|
||
Clk => clk_62_5_o,
|
||
Rst => Rst,
|
||
TxFireCPU => TxFireCPU,
|
||
UDP_TX_CPU => open);
|
||
|
||
u7: RdOutAll
|
||
port map(
|
||
UDP_Rx_Empty => UDP_Rx_Empty_net,
|
||
UDP_Rx_RdReq => u7_UDP_Rx_RdReq);
|
||
end architecture a0 ; -- of fpga
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Entity design.System
|
||
-- Last modified : Fri Sep 12 15:53:43 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
|
||
library ieee, work;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
use work.wishbone_pkg.all;
|
||
use work.wr_fabric_pkg.all;
|
||
use work.v_array_package.all;
|
||
use work.EMAC16bit_Package.all;
|
||
|
||
entity System is
|
||
port (
|
||
Fire : in std_logic_vector(3 downto 0);
|
||
TxFireCPU : in std_logic;
|
||
UDP_Rx : out dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
UDP_Rx_Empty : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
UDP_Rx_RdReq : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
wb_ipmux_reg_i : in t_wishbone_slave_in;
|
||
wb_ipmux_reg_o : out t_wishbone_slave_out;
|
||
wb_ipmux_rx_tx_i : in t_wishbone_slave_in;
|
||
wb_ipmux_rx_tx_o : out t_wishbone_slave_out);
|
||
end entity System;
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Architecture design.System.structure
|
||
-- Last modified : Fri Sep 12 15:53:43 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
architecture structure of System is
|
||
|
||
signal RST_I : std_logic;
|
||
signal ClkI_p : std_logic;
|
||
signal ClkI_n : std_logic;
|
||
signal src_o : t_wrf_source_out;
|
||
signal snk_o : t_wrf_sink_out;
|
||
|
||
component fpga
|
||
generic(
|
||
Simulation : boolean := False);
|
||
port (
|
||
ClkI_n : in std_logic;
|
||
ClkI_p : in std_logic;
|
||
Fire : in std_logic_vector(3 downto 0);
|
||
RstIn : in std_logic;
|
||
TxFireCPU : in std_logic;
|
||
UDP_Rx : out dbus_type_array(NUM_UDP_PRTS-1 downto 0);
|
||
UDP_Rx_Empty : out std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
UDP_Rx_RdReq : in std_logic_vector(NUM_UDP_PRTS-1 downto 0);
|
||
snk_i : in t_wrf_sink_in;
|
||
snk_o : out t_wrf_sink_out;
|
||
src_i : in t_wrf_source_in;
|
||
src_o : out t_wrf_source_out;
|
||
wb_ipmux_reg_i : in t_wishbone_slave_in;
|
||
wb_ipmux_reg_o : out t_wishbone_slave_out;
|
||
wb_ipmux_rx_tx_i : in t_wishbone_slave_in;
|
||
wb_ipmux_rx_tx_o : out t_wishbone_slave_out);
|
||
end component fpga;
|
||
|
||
component SYSCON
|
||
port (
|
||
ClkI_n : out std_logic;
|
||
ClkI_p : out std_logic;
|
||
RST_I : out std_logic);
|
||
end component SYSCON;
|
||
|
||
begin
|
||
|
||
u0: fpga
|
||
generic map(
|
||
Simulation => False)
|
||
port map(
|
||
ClkI_n => ClkI_n,
|
||
ClkI_p => ClkI_p,
|
||
Fire => Fire,
|
||
RstIn => RST_I,
|
||
TxFireCPU => TxFireCPU,
|
||
UDP_Rx => UDP_Rx,
|
||
UDP_Rx_Empty => UDP_Rx_Empty,
|
||
UDP_Rx_RdReq => UDP_Rx_RdReq,
|
||
snk_i => src_o,
|
||
snk_o => snk_o,
|
||
src_i => snk_o,
|
||
src_o => src_o,
|
||
wb_ipmux_reg_i => wb_ipmux_reg_i,
|
||
wb_ipmux_reg_o => wb_ipmux_reg_o,
|
||
wb_ipmux_rx_tx_i => wb_ipmux_rx_tx_i,
|
||
wb_ipmux_rx_tx_o => wb_ipmux_rx_tx_o);
|
||
|
||
u1: SYSCON
|
||
port map(
|
||
ClkI_n => ClkI_n,
|
||
ClkI_p => ClkI_p,
|
||
RST_I => RST_I);
|
||
end architecture structure ; -- of System
|
||
|
||
--------------------------------------------------------------------------------
|
||
-- Object : Configuration design.System.Functional
|
||
-- Last modified : Fri Sep 12 15:53:43 2014.
|
||
--------------------------------------------------------------------------------
|
||
|
||
|
||
library work, UNISIM;
|
||
|
||
|
||
configuration Functional of System is
|
||
for structure
|
||
for u0 : fpga
|
||
use entity work.fpga(a0);
|
||
for a0
|
||
for u14 : ipmux
|
||
use entity work.ipmux(rtl);
|
||
for rtl
|
||
for u0 : TxBuffers
|
||
use entity work.TxBuffers(rtl);
|
||
for rtl
|
||
for u2 : TxWrDataSrcSel
|
||
use entity work.TxWrDataSrcSel(rtl);
|
||
end for;
|
||
for u4 : PktBufFlags
|
||
use entity work.PktBufFlags(rtl);
|
||
end for;
|
||
for u3 : tx_pkt2mac
|
||
use entity work.tx_pkt2mac(rtl);
|
||
end for;
|
||
for u1 : tx_data2buf
|
||
use entity work.tx_data2buf(fsm);
|
||
end for;
|
||
for u6 : Calc_UDP_PseudoHeader
|
||
use entity work.Calc_UDP_PseudoHeader(a0);
|
||
end for;
|
||
for u0 : PacketBuffer
|
||
use entity work.PacketBuffer(rtl);
|
||
end for;
|
||
end for;
|
||
end for;
|
||
for u6 : RxBuffers
|
||
use entity work.RxBuffers(structure);
|
||
for structure
|
||
for u1 : rx_mac2buf
|
||
use entity work.rx_mac2buf(rtl);
|
||
end for;
|
||
for u4 : PktBufFlags
|
||
use entity work.PktBufFlags(rtl);
|
||
end for;
|
||
for u2 : PauseReqLogic
|
||
use entity work.PauseReqLogic(rtl);
|
||
end for;
|
||
for u5 : rx_buf2data
|
||
use entity work.rx_buf2data(fsm);
|
||
end for;
|
||
for u3 : RxStreamSel
|
||
use entity work.RxStreamSel(rtl);
|
||
end for;
|
||
for u0 : PacketBuffer
|
||
use entity work.PacketBuffer(rtl);
|
||
end for;
|
||
end for;
|
||
end for;
|
||
for u7 : rxfifos
|
||
use entity work.rxfifos(rtl);
|
||
for rtl
|
||
for GenRxFifos
|
||
end for;
|
||
end for;
|
||
end for;
|
||
for u8 : txfifos
|
||
use entity work.txfifos(rtl);
|
||
for rtl
|
||
for GenTxFifos
|
||
for ValidReg : Reg1en
|
||
use entity work.Reg1en(a0);
|
||
end for;
|
||
for ValidReg : Reg1en
|
||
use entity work.Reg1en(a0);
|
||
end for;
|
||
end for;
|
||
end for;
|
||
end for;
|
||
for u1 : TxStreamSel
|
||
use entity work.TxStreamSel(fsm);
|
||
end for;
|
||
for u4 : ipmux_regs_and_rxtxcpu
|
||
use entity work.ipmux_regs_and_rxtxcpu(rtl);
|
||
end for;
|
||
end for;
|
||
end for;
|
||
for u1 : ClkDist
|
||
use entity work.ClkDist(rtl);
|
||
end for;
|
||
for u0 : PowerOnRst
|
||
use entity work.PowerOnRst(rtl);
|
||
end for;
|
||
for u2 : IBUFDS_GTE2
|
||
use entity UNISIM.IBUFDS_GTE2(IBUFDS_GTE2_V);
|
||
end for;
|
||
for u3 : cmp_sys_clk_pll
|
||
use entity work.cmp_sys_clk_pll(xilinx);
|
||
end for;
|
||
for u4 : FirePackets
|
||
use entity work.FirePackets(a0);
|
||
for a0
|
||
for u0 : Debounce
|
||
use entity work.Debounce(rtl);
|
||
end for;
|
||
for u1 : Debounce
|
||
use entity work.Debounce(rtl);
|
||
end for;
|
||
for u2 : Debounce
|
||
use entity work.Debounce(rtl);
|
||
end for;
|
||
for u3 : Debounce
|
||
use entity work.Debounce(rtl);
|
||
end for;
|
||
for u4 : FirePacket
|
||
use entity work.FirePacket(fsm);
|
||
end for;
|
||
for u5 : FirePacket
|
||
use entity work.FirePacket(fsm);
|
||
end for;
|
||
for u6 : FirePacket
|
||
use entity work.FirePacket(fsm);
|
||
end for;
|
||
for u7 : FirePacket
|
||
use entity work.FirePacket(fsm);
|
||
end for;
|
||
end for;
|
||
end for;
|
||
for u5 : FireCPU_Packet
|
||
use entity work.FireCPU_Packet(fsm);
|
||
end for;
|
||
for u7 : RdOutAll
|
||
use entity work.RdOutAll(rtl);
|
||
end for;
|
||
end for;
|
||
end for;
|
||
for u1 : SYSCON
|
||
use entity work.SYSCON(rtl);
|
||
end for;
|
||
end for;
|
||
end configuration Functional;
|
||
|