1 ------------------------------------------------------------------------------- 2 -- File : UdpEngineTx.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2015-08-20 5 -- Last update: 2016-09-16 6 ------------------------------------------------------------------------------- 7 -- Description: UDP TX Engine Module 8 -- Note: UDP checksum checked in EthMac core 9 ------------------------------------------------------------------------------- 10 -- This file is part of 'SLAC Firmware Standard Library'. 11 -- It is subject to the license terms in the LICENSE.txt file found in the 12 -- top-level directory of this distribution and at: 13 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. 14 -- No part of 'SLAC Firmware Standard Library', including this file, 15 -- may be copied, modified, propagated, or distributed except according to 16 -- the terms contained in the LICENSE.txt file. 17 ------------------------------------------------------------------------------- 20 use ieee.std_logic_1164.
all;
21 use ieee.std_logic_unsigned.
all;
22 use ieee.std_logic_arith.
all;
30 --! @ingroup ethernet_UdpEngine 33 -- Simulation Generics 35 -- UDP General Generic 39 -- Interface to IPV4 Engine 42 -- Interface to User Application 43 localIp :
in slv(
31 downto 0);
49 -- Interface to DHCP Engine 69 type RegType is record 74 chPntr : range 0 to SIZE_G-1;
75 index : range 0 to SIZE_G-1;
81 constant REG_INIT_C : RegType := ( 82 tKeep => (others => '0'), 83 tData => (others => '0'), 93 signal r : RegType := REG_INIT_C;
99 -- attribute dont_touch : string; 100 -- attribute dont_touch of r : signal is "TRUE"; 106 variable v : RegType;
109 -- Latch the current value 115 if (txSlave.tReady = '1') then 117 v.txMaster.tLast := '0';
118 v.txMaster.tUser := (others => '0');
119 v.txMaster.tKeep := (others => '1');
124 ---------------------------------------------------------------------- 126 -- Check for roll over 127 if (r.index = (SIZE_G-1)) then 131 -- Increment the counter 132 v.index := r.index + 1;
134 -- Check for DHCP data and remote MAC is non-zero 138 -- Write the first header 140 v.txMaster.tData(47 downto 0) := (others => '1');
-- Destination MAC address 141 v.txMaster.tData(63 downto 48) := x"0000";
-- All 0s 142 v.txMaster.tData(95 downto 64) := (others => '0');
-- Source IP address 143 v.txMaster.tData(127 downto 96) := (others => '1');
-- Destination IP address 146 v.state := DHCP_HDR_S;
151 -- Check for data and remote MAC is non-zero 157 -- Write the first header 159 v.txMaster.tData(47 downto 0) := remoteMac(r.index);
-- Destination MAC address 160 v.txMaster.tData(63 downto 48) := x"0000";
-- All 0s 161 v.txMaster.tData(95 downto 64) := localIp;
-- Source IP address 162 v.txMaster.tData(127 downto 96) := remoteIp(r.index);
-- Destination IP address 171 ------------------------------------------------ 172 -- Notes: Non-Standard IPv4 Pseudo Header Format 173 ------------------------------------------------ 174 -- tData[0][47:0] = DST MAC Address 175 -- tData[0][63:48] = zeros 176 -- tData[0][95:64] = SRC IP Address 177 -- tData[0][127:96] = DST IP address 178 -- tData[1][7:0] = zeros 179 -- tData[1][15:8] = Protocol Type = UDP 180 -- tData[1][31:16] = IPv4 Pseudo header length 181 -- tData[1][47:32] = SRC Port 182 -- tData[1][63:48] = DST Port 183 -- tData[1][79:64] = UDP Length 184 -- tData[1][95:80] = UDP Checksum 185 -- tData[1][127:96] = UDP Datagram 186 ------------------------------------------------ 187 ---------------------------------------------------------------------- 189 -- Check if ready to move data 193 -- Write the Second header 195 v.txMaster.tData(7 downto 0) := x"00";
-- All 0s 196 v.txMaster.tData(15 downto 8) := UDP_C;
-- Protocol Type = UDP 197 v.txMaster.tData(31 downto 16) := x"0000";
-- IPv4 Pseudo header length = Calculated in EthMac core 200 v.txMaster.tData(79 downto 64) := x"0000";
-- UDP length = Calculated in EthMac core 201 v.txMaster.tData(95 downto 80) := x"0000";
-- UDP checksum = Calculated in EthMac core 203 v.txMaster.tKeep(11 downto 0) := x"FFF";
205 -- Track the leftovers 207 v.tData(127 downto 96) := (others => '0');
209 v.tKeep(15 downto 12) := (others => '0');
213 if (v.tLast = '1') then 214 -- Check the leftover tKeep is not empty 215 if (v.tKeep /= 0) then 220 v.txMaster.tLast := '1';
227 v.state := DHCP_BUFFER_S;
230 ---------------------------------------------------------------------- 232 -- Check if ready to move data 236 -- Write the Second header 238 v.txMaster.tData(7 downto 0) := x"00";
-- All 0s 239 v.txMaster.tData(15 downto 8) := UDP_C;
-- Protocol Type = UDP 240 v.txMaster.tData(31 downto 16) := x"0000";
-- IPv4 Pseudo header length = Calculated in EthMac core 241 v.txMaster.tData(47 downto 32) := PORT_C(r.chPntr);
-- Source port 242 v.txMaster.tData(63 downto 48) := remotePort(r.chPntr);
-- Destination port 243 v.txMaster.tData(79 downto 64) := x"0000";
-- UDP length = Calculated in EthMac core 244 v.txMaster.tData(95 downto 80) := x"0000";
-- UDP checksum = Calculated in EthMac core 246 v.txMaster.tKeep(11 downto 0) := x"FFF";
248 -- Track the leftovers 250 v.tData(127 downto 96) := (others => '0');
252 v.tKeep(15 downto 12) := (others => '0');
256 if (v.tLast = '1') then 257 -- Check the leftover tKeep is not empty 258 if (v.tKeep /= 0) then 263 v.txMaster.tLast := '1';
273 ---------------------------------------------------------------------- 274 when DHCP_BUFFER_S => 275 -- Check if ready to move data 279 -- Write the Second header 282 v.txMaster.tData(95 downto 0) := r.tData(95 downto 0);
284 v.txMaster.tKeep(11 downto 0) := r.tKeep(11 downto 0);
286 -- Track the leftovers 292 if (v.tLast = '1') then 293 -- Check the leftover tKeep is not empty 294 if (v.tKeep /= 0) then 299 v.txMaster.tLast := '1';
306 ---------------------------------------------------------------------- 308 -- Check if ready to move data 312 -- Write the Second header 315 v.txMaster.tData(95 downto 0) := r.tData(95 downto 0);
317 v.txMaster.tKeep(11 downto 0) := r.tKeep(11 downto 0);
319 -- Track the leftovers 325 if (v.tLast = '1') then 326 -- Check the leftover tKeep is not empty 327 if (v.tKeep /= 0) then 332 v.txMaster.tLast := '1';
339 ---------------------------------------------------------------------- 341 -- Check if ready to move data 342 if (v.txMaster.tValid = '0') then 347 v.txMaster.tLast := '1';
352 ---------------------------------------------------------------------- 360 -- Register the variable for next clock cycle 365 txMaster <= r.txMaster;
370 seq :
process (
clk)
is 372 if rising_edge(clk) then 373 r <= rin after TPD_G;
PIPE_STAGES_Gnatural range 0 to 16:= 0
array(natural range <> ) of AxiStreamSlaveType AxiStreamSlaveArray
array(natural range <> ) of slv( 31 downto 0) Slv32Array
slv( 15 downto 0) := x"4300" DHCP_SPORT
in localIpslv( 31 downto 0)
AxiStreamMasterType :=(tValid => '0',tData =>( others => '0'),tStrb =>( others => '1'),tKeep =>( others => '1'),tLast => '0',tDest =>( others => '0'),tId =>( others => '0'),tUser =>( others => '0')) AXI_STREAM_MASTER_INIT_C
array(natural range <> ) of slv( 47 downto 0) Slv48Array
in remoteIpSlv32Array( SIZE_G- 1 downto 0)
out obDhcpSlaveAxiStreamSlaveType
out sAxisSlaveAxiStreamSlaveType
PORT_GPositiveArray :=( 0=> 8192)
out ibSlavesAxiStreamSlaveArray( SIZE_G- 1 downto 0)
in mAxisSlaveAxiStreamSlaveType
slv( 15 downto 0) := x"4400" DHCP_CPORT
in ibMastersAxiStreamMasterArray( SIZE_G- 1 downto 0)
array(natural range <> ) of positive PositiveArray
in sAxisMasterAxiStreamMasterType
AxiStreamSlaveType :=(tReady => '0') AXI_STREAM_SLAVE_INIT_C
in remoteMacSlv48Array( SIZE_G- 1 downto 0)
in remotePortSlv16Array( SIZE_G- 1 downto 0)
array(natural range <> ) of AxiStreamMasterType AxiStreamMasterArray
out mAxisMasterAxiStreamMasterType
array(natural range <> ) of slv( 15 downto 0) Slv16Array
in obDhcpMasterAxiStreamMasterType := AXI_STREAM_MASTER_INIT_C
slv( 7 downto 0) := x"11" UDP_C
AxiStreamConfigType :=(TSTRB_EN_C => false,TDATA_BYTES_C => 16,TDEST_BITS_C => 8,TID_BITS_C => 0,TKEEP_MODE_C => TKEEP_COMP_C,TUSER_BITS_C => 4,TUSER_MODE_C => TUSER_FIRST_LAST_C) EMAC_AXIS_CONFIG_C
in obUdpSlaveAxiStreamSlaveType
out obUdpMasterAxiStreamMasterType