otsdaq_prepmodernization  v2_05_02_indev
ethernet_interface.vhd
1 -------------------------------------------------------------------------------
2 --
3 -- Title : ethernet_interface
4 -- Design : ethernet_controller
5 -- Author : rrivera at fnal dot gov
6 -- Company : Fermi National Accelerator Laboratory
7 --
8 -------------------------------------------------------------------------------
9 --
10 -- Modified : Thu Nov 12 10:33:07 2015
11 --
12 -------------------------------------------------------------------------------
13 --
14 -- Description :
15 --
16 -------------------------------------------------------------------------------
17 -- Design unit header --
18 
19 library ieee;
20 use ieee.std_logic_1164.ALL;
21 use ieee.numeric_std.ALL;
22 
23 use work.params_package.all;
24 
26  port (
27  reset_in : in std_logic; -- optional for user to reset, this block will self reset on startup
28  reset_out : out std_logic; -- ethernet reset can be used for "reset on start-up" or for reset to PHY
29 
30  -- rx/tx signals
31  rx_addr : out std_logic_vector (31 downto 0);
32  rx_data : out std_logic_vector (63 downto 0);
33  rx_wren : out std_logic;
34  tx_data : in std_logic_vector (63 downto 0);
35 --erased for simple interface
36 --erased for simple interface
37 
38  -- burst signals
39  b_force_packet : in std_logic;
40  b_data : in std_logic_vector (63 downto 0);
41  b_data_we : in std_logic;
42  b_enable : out std_logic;
43 --erased for simple interface
44 
45 
46  -- internal address space signals
47 --erased for simple interface
48 --erased for simple interface
49 --erased for simple interface
50 --erased for simple interface
51 --erased for simple interface
52 
53 --erased for simple interface
54 
55  user_addr : in std_logic_vector (7 downto 0);
56 
57  -- PHY interface signals
58  MASTER_CLK : in std_logic;
59  slow_clk : in std_logic;
60 
61  PHY_RXD : in std_logic_vector (7 downto 0);
62  PHY_RX_DV : in std_logic;
63  PHY_RX_ER : in std_logic;
64 
65  TX_CLK : out std_logic;
66  PHY_TXD : out std_logic_vector (7 downto 0);
67  PHY_TX_EN : out std_logic;
68  PHY_TX_ER : out std_logic
69  );
70 end ethernet_interface;
71 
72 
73 
74 architecture BEHAVIORAL of ethernet_interface is
75 
76  signal b_end_packet : std_logic;
77  signal b_masked_we : std_logic;
78  signal b_enable_sig : std_logic;
79  signal four_bit_mode : std_logic;
80  signal user_busy : std_logic;
81  signal user_crc_err : std_logic;
82  signal user_rx_data_out : std_logic_vector (7 downto 0);
83  signal user_rx_size_out : std_logic_vector (10 downto 0);
84  signal user_rx_valid_out : std_logic;
85  signal user_tx_trigger : std_logic;
86  signal user_tx_data_in : std_logic_vector (7 downto 0);
87  signal user_tx_enable_out : std_logic;
88  signal user_tx_size_in : std_logic_vector (10 downto 0);
89  signal reset : std_logic;
90 
91  signal user_rx_src_capture_for_ctrl : std_logic; -- take sender address, latch src when capture is '1' for dest
92  signal user_rx_src_capture_for_data : std_logic; -- take sender address, latch src when capture is '1' for dest
93 
94  signal user_rx_src_addr : std_logic_vector (31 downto 0);
95  signal user_rx_src_mac : std_logic_vector (47 downto 0);
96  signal user_rx_src_port : std_logic_vector (15 downto 0);
97  signal user_tx_dest_addr : std_logic_vector (31 downto 0);
98  signal user_tx_dest_mac : std_logic_vector (47 downto 0);
99  signal user_tx_dest_port : std_logic_vector (15 downto 0);
100 
101  signal user_tx_rden : std_logic;
102  signal user_ready : std_logic;
103  signal user_b_force_packet : std_logic;
104  signal crc_chk_out : std_logic;
105 
106 
107  signal ots_addr : std_logic_vector (63 downto 0);
108  signal ots_block_sel : unsigned (31 downto 0);
109  signal ots_block_addr : unsigned (31 downto 0);
110  signal ots_wren : std_logic;
111  signal ots_din, ots_dout : std_logic_vector (63 downto 0);
112  signal ots_rden : std_logic;
113  signal ots_ready : std_logic;
114  signal ots_user_mask : std_logic := '0';
115  signal internal_eth_dout : std_logic_vector (63 downto 0);
116  signal internal_reset : std_logic := '0';
117  signal reset_mgr_in : std_logic;
118 
119  signal arp_announce : std_logic := '0';
120  signal burst_mode : std_logic := '0';
121  signal self_addr : std_logic_vector(23 downto 0) := x"C0A81E"; --192.168.30.X; x"C0A885"; --192.168.133.X;
122  signal self_mac : std_logic_vector(39 downto 0) := x"008055EC00";
123  signal self_port : std_logic_vector(15 downto 0) := ETH_CONTROLLER_DEFAULT_PORT;
124  signal user_addr_byte : std_logic_vector(7 downto 0) := ETH_CONTROLLER_DEFAULT_ADDR;
125  signal user_addr_sig : std_logic_vector(7 downto 0) := ETH_CONTROLLER_DEFAULT_ADDR;
126  signal tx_data_dest_addr : std_logic_vector(31 downto 0);
127  signal tx_data_dest_mac : std_logic_vector(47 downto 0);
128  signal tx_data_dest_port : std_logic_vector(15 downto 0);
129  signal tx_ctrl_dest_addr : std_logic_vector(31 downto 0);
130  signal tx_ctrl_dest_mac : std_logic_vector(47 downto 0);
131  signal tx_ctrl_dest_port : std_logic_vector(15 downto 0);
132 
133  -------- start simple declaration section -----------
134  -- comments denoted as will be removed in this case by install script
135 --erased for simple interface will be commented out
136  signal internal_block_sel : std_logic_vector (31 downto 0) := (others => '0');
137  signal internal_addr : std_logic_vector (31 downto 0):= (others => '0');
138  signal internal_we : std_logic := '0';
139  signal internal_din : std_logic_vector (63 downto 0):= (others => '0');
140  signal internal_dout : std_logic_vector (63 downto 0):= (others => '0');
141 
142  --signal user_addr : std_logic_vector (7 downto 0):= (others => '0');
143  -------- end simple declaration section -----------
144 
145 begin
146 
147  ec_wrapper : entity work.ethernet_controller_wrapper
148  port map (
149  GMII_RXD(7 downto 0)=>PHY_RXD(7 downto 0),
150  GMII_RX_CLK =>MASTER_CLK,
151  GMII_RX_DV =>PHY_RX_DV,
152  GMII_RX_ER =>PHY_RX_ER,
153  GMII_TXD(7 downto 0)=>PHY_TXD(7 downto 0),
154  GMII_TX_EN =>PHY_TX_EN,
155  GMII_TX_ER =>PHY_TX_ER,
156  GTX_CLK=>TX_CLK,
157 
158  reset =>reset,
159 
160  self_addr(31 downto 8)=>self_addr,
161  self_addr(7 downto 0)=>user_addr_sig,
162  self_mac(47 downto 8)=>self_mac,
163  self_mac(7 downto 0)=>user_addr_sig,
164  self_port =>self_port,
165  arp_announce =>arp_announce,
166 
167  user_tx_dest_addr(31 downto 0)=>user_tx_dest_addr(31 downto 0),
168  user_tx_dest_mac(47 downto 0)=>user_tx_dest_mac(47 downto 0),
169  user_tx_dest_port(15 downto 0)=>user_tx_dest_port(15 downto 0),
170 
171  user_rx_src_capture_for_ctrl =>user_rx_src_capture_for_ctrl ,
172  user_rx_src_capture_for_data =>user_rx_src_capture_for_data ,
173  user_rx_src_addr(31 downto 0)=>user_rx_src_addr(31 downto 0),
174  user_rx_src_mac(47 downto 0)=>user_rx_src_mac(47 downto 0),
175  user_rx_src_port(15 downto 0)=>user_rx_src_port(15 downto 0),
176 
177  user_tx_trigger =>user_tx_trigger,
178  user_tx_data_in(7 downto 0)=>user_tx_data_in(7 downto 0),
179  user_tx_size_in(10 downto 0)=>user_tx_size_in(10 downto 0),
180  crc_err=>user_crc_err ,
181  crc_chk_out =>crc_chk_out,
182  four_bit_mode_out =>four_bit_mode,
183  udp_fwd_port =>open, -- could use this to reject packets that are not 2001, e.g. (or to choose between data manager and something else)
184  user_busy =>user_busy,
185  user_rx_data_out(7 downto 0)=>user_rx_data_out(7 downto 0),
186  user_rx_size_out(10 downto 0)=>user_rx_size_out(10 downto 0),
187  user_rx_valid_out =>user_rx_valid_out ,
188  user_tx_enable_out =>user_tx_enable_out );
189 
190  data_manager_blk : entity work.data_manager
191  port map (b_data(63 downto 0)=>b_data(63 downto 0),
192  b_data_we =>b_data_we,
193  b_end_packet =>b_end_packet,
194  b_mode =>burst_mode,
195  four_bit_mode =>four_bit_mode,
196  user_busy =>user_busy,
197  user_crc_err =>user_crc_err,
198  user_crc_chk =>crc_chk_out,
199 
200  user_rx_data_out(7 downto 0)=>user_rx_data_out(7 downto 0),
201  user_rx_valid_out =>user_rx_valid_out ,
202  user_rx_src_addr =>user_rx_src_addr,
203  user_rx_src_mac =>user_rx_src_mac,
204  user_rx_src_port =>user_rx_src_port,
205 
206  tx_ctrl_dest_addr =>tx_ctrl_dest_addr,
207  tx_ctrl_dest_mac =>tx_ctrl_dest_mac,
208  tx_ctrl_dest_port =>tx_ctrl_dest_port ,
209  tx_data_dest_addr =>tx_data_dest_addr,
210  tx_data_dest_mac =>tx_data_dest_mac,
211  tx_data_dest_port =>tx_data_dest_port ,
212  user_tx_dest_addr =>user_tx_dest_addr,
213  user_tx_dest_mac =>user_tx_dest_mac,
214  user_tx_dest_port =>user_tx_dest_port ,
215 
216  MASTER_CLK =>MASTER_CLK,
217  reset =>reset,
218  tx_data(63 downto 0)=>ots_dout(63 downto 0),
219  b_enable =>b_enable_sig,
220 
221  user_tx_trigger =>user_tx_trigger,
222  user_tx_enable_out =>user_tx_enable_out ,
223  user_tx_data_in(7 downto 0)=>user_tx_data_in(7 downto 0),
224  user_tx_size_in(10 downto 0)=>user_tx_size_in(10 downto 0),
225 
226  ram_addr(63 downto 0)=>ots_addr,
227  ram_rden =>ots_rden,
228  ram_wren =>ots_wren,
229  user_ready =>ots_ready,
230  rx_data(63 downto 0)=>ots_din(63 downto 0));
231 
232 
233  b_masked_we <= b_data_we and b_enable_sig;
234  b_enable <= b_enable_sig;
235 
236  burst_traffic_controller_blk : entity work.burst_traffic_controller
237  port map (BURST_WE =>b_masked_we,
238  MASTER_CLK =>MASTER_CLK,
239  BURST_FORCE_PACKET =>user_b_force_packet,
240  RESET =>reset,
241  BURST_END_PACKET =>b_end_packet);
242 
243 
244  -------- start reset section -----------
245  -- handle self reset for Eth Interface and input and output reset
246  reset_mgr : entity work.reset_mgr
247  port map (
248  slow_clk => slow_clk,
249  reset_start => reset_mgr_in ,
250  reset => reset);
251 
252  reset_out <= reset;
253  -------- end reset section -----------
254 
255 
256  -------- start internal address space section -----------
257  -- Assume works like a dual port RAM and is always "ready"
258  -- one port on user firmware
259  -- one port on ethernet interface
260  --
261  --
262 
263  ots_block_sel <= unsigned(ots_addr(63 downto 32));
264  ots_block_addr <= unsigned(ots_addr(31 downto 0));
265  rx_addr <= std_logic_vector(ots_block_addr);
266  rx_data <= ots_din;
267 
268  -- NOTE: User code is treated as "block 0"
269  ots_user_mask <= '1' when ( ots_block_sel = 0) else '0';
270  rx_wren <= ots_user_mask and ots_wren;
271  user_tx_rden <= ots_user_mask and ots_rden;
272 
273  ots_dout <= tx_data when (ots_user_mask = '1') else internal_eth_dout;
274  ots_ready <= (not ots_user_mask) or user_ready; -- ots address space is always ready
275 
276  reset_mgr_in <= internal_reset or reset_in;
277 
278 
279  process(MASTER_CLK)
280  begin
281  if (rising_edge(MASTER_CLK)) then
282 
283  if(unsigned(user_addr) = 0) then --take internally if user_addr is 0
284  user_addr_sig <= user_addr_byte;
285  else
286  user_addr_sig <= user_addr;
287  end if;
288 
289  internal_eth_dout <= (others => '0');
290  internal_dout <= (others => '0');
291  internal_reset <= '0';
292  arp_announce <= '0';
293 
294  if ( ots_wren = '1' and -- WRITE eth ===========
295  ots_block_sel = x"1") then -- Ethernet block address space
296  if ( ots_block_addr = x"0" ) then
297  self_addr <= ots_din(23 downto 0);
298  arp_announce <= '1';
299  elsif ( ots_block_addr = x"1" ) then
300  user_addr_byte <= ots_din(7 downto 0);
301  arp_announce <= '1';
302  elsif ( ots_block_addr = x"2" ) then
303  self_mac <= ots_din(39 downto 0);
304  arp_announce <= '1';
305  elsif ( ots_block_addr = x"3" ) then
306  tx_ctrl_dest_addr <= ots_din(31 downto 0);
307  elsif ( ots_block_addr = x"4" ) then
308  tx_ctrl_dest_mac <= ots_din(47 downto 0);
309  elsif ( ots_block_addr = x"5" ) then
310  tx_ctrl_dest_port <= ots_din(15 downto 0);
311  elsif ( ots_block_addr = x"6" ) then
312  tx_data_dest_addr <= ots_din(31 downto 0);
313  elsif ( ots_block_addr = x"7" ) then
314  tx_data_dest_mac <= ots_din(47 downto 0);
315  elsif ( ots_block_addr = x"8" ) then
316  tx_data_dest_port <= ots_din(15 downto 0);
317  elsif ( ots_block_addr = x"9" ) then
318  burst_mode <= ots_din(0);
319  elsif ( ots_block_addr = x"FFFFFFFF" ) then
320  internal_reset <= ots_din(0);
321  end if;
322  elsif ( internal_we = '1' and -- WRITE internal ===========
323  unsigned(internal_block_sel) = x"1") then -- Ethernet block address space
324  if ( unsigned(internal_addr) = x"0" ) then
325  self_addr <= internal_din(23 downto 0);
326  arp_announce <= '1';
327  elsif ( unsigned(internal_addr) = x"1" ) then
328  user_addr_byte <= internal_din(7 downto 0);
329  arp_announce <= '1';
330  elsif ( unsigned(internal_addr) = x"2" ) then
331  self_mac <= internal_din(39 downto 0);
332  arp_announce <= '1';
333  elsif ( unsigned(internal_addr) = x"3" ) then
334  tx_ctrl_dest_addr <= internal_din(31 downto 0);
335  elsif ( unsigned(internal_addr) = x"4" ) then
336  tx_ctrl_dest_mac <= internal_din(47 downto 0);
337  elsif ( unsigned(internal_addr) = x"5" ) then
338  tx_ctrl_dest_port <= internal_din(15 downto 0);
339  elsif ( unsigned(internal_addr) = x"6" ) then
340  tx_data_dest_addr <= internal_din(31 downto 0);
341  elsif ( unsigned(internal_addr) = x"7" ) then
342  tx_data_dest_mac <= internal_din(47 downto 0);
343  elsif ( unsigned(internal_addr) = x"8" ) then
344  tx_data_dest_port <= internal_din(15 downto 0);
345  elsif ( unsigned(internal_addr) = x"9" ) then
346  burst_mode <= internal_din(0);
347  elsif ( unsigned(internal_addr) = x"FFFFFFFF" ) then
348  internal_reset <= internal_din(0);
349  end if;
350  elsif ( user_rx_src_capture_for_ctrl = '1' ) then -- SPECIAL WRITE for source capture for ctrl ===========
351  tx_ctrl_dest_addr <= user_rx_src_addr;
352  tx_ctrl_dest_mac <= user_rx_src_mac;
353  tx_ctrl_dest_port <= user_rx_src_port;
354  elsif ( user_rx_src_capture_for_data = '1' ) then -- SPECIAL WRITE for source capture for data ===========
355  tx_data_dest_addr <= user_rx_src_addr;
356  tx_data_dest_mac <= user_rx_src_mac;
357  tx_data_dest_port <= user_rx_src_port;
358  end if;
359 
360  if ( ots_rden = '1' and -- READ eth ===========
361  ots_block_sel = x"1") then -- Ethernet block address space
362  if ( ots_block_addr = x"0" ) then
363  internal_eth_dout(23 downto 0) <= self_addr;
364  elsif ( ots_block_addr = x"1" ) then
365  internal_eth_dout(7 downto 0) <= user_addr_byte;
366  elsif ( ots_block_addr = x"2" ) then
367  internal_eth_dout(39 downto 0) <= self_mac;
368  elsif ( ots_block_addr = x"3" ) then
369  internal_eth_dout(31 downto 0) <= tx_ctrl_dest_addr;
370  elsif ( ots_block_addr = x"4" ) then
371  internal_eth_dout(47 downto 0) <= tx_ctrl_dest_mac;
372  elsif ( ots_block_addr = x"5" ) then
373  internal_eth_dout(15 downto 0) <= tx_ctrl_dest_port;
374  elsif ( ots_block_addr = x"6" ) then
375  internal_eth_dout(31 downto 0) <= tx_data_dest_addr;
376  elsif ( ots_block_addr = x"7" ) then
377  internal_eth_dout(47 downto 0) <= tx_data_dest_mac;
378  elsif ( ots_block_addr = x"8" ) then
379  internal_eth_dout(15 downto 0) <= tx_data_dest_port;
380  elsif ( ots_block_addr = x"9" ) then
381  internal_eth_dout(0) <= burst_mode;
382  elsif ( ots_block_addr = x"64" ) then
383  internal_eth_dout(15 downto 0) <= ETH_INTERFACE_VERSION;
384  end if;
385  end if;
386 
387  if ( -- always READ internal ===========
388  unsigned(internal_block_sel) = x"1") then -- Ethernet block address space
389  if ( unsigned(internal_addr) = x"0" ) then
390  internal_dout(23 downto 0) <= self_addr;
391  elsif ( unsigned(internal_addr) = x"1" ) then
392  internal_dout(7 downto 0) <= user_addr_byte;
393  elsif ( unsigned(internal_addr) = x"2" ) then
394  internal_dout(39 downto 0) <= self_mac;
395  elsif ( unsigned(internal_addr) = x"3" ) then
396  internal_dout(31 downto 0) <= tx_ctrl_dest_addr;
397  elsif ( unsigned(internal_addr) = x"4" ) then
398  internal_dout(47 downto 0) <= tx_ctrl_dest_mac;
399  elsif ( unsigned(internal_addr) = x"5" ) then
400  internal_dout(15 downto 0) <= tx_ctrl_dest_port;
401  elsif ( unsigned(internal_addr) = x"6" ) then
402  internal_dout(31 downto 0) <= tx_data_dest_addr;
403  elsif ( unsigned(internal_addr) = x"7" ) then
404  internal_dout(47 downto 0) <= tx_data_dest_mac;
405  elsif ( unsigned(internal_addr) = x"8" ) then
406  internal_dout(15 downto 0) <= tx_data_dest_port;
407  elsif ( unsigned(internal_addr) = x"9" ) then
408  internal_dout(0) <= burst_mode;
409  elsif ( unsigned(internal_addr) = x"64" ) then
410  internal_dout(15 downto 0) <= ETH_INTERFACE_VERSION;
411  end if;
412  end if;
413 
414 
415 
416 
417  end if;
418  end process;
419 
420 
421 
422  -------- end internal address space section -----------
423 
424 
425 --erased for simple interface
426 --erased for simple interface
427 --erased for simple interface
428 
429  -------- start simple section -----------
430  -- comments denoted as will be removed in this case by install script
431 --erased for simple interface will be commented out
432 
433  user_ready <= '1';
434  user_b_force_packet <= b_force_packet;
435 
436  -------- end simple section -----------
437 
438 end BEHAVIORAL;
439