AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
ipbus_ctrl.vhd
1 -- ipbus_ctrl
2 --
3 -- Top level of the ipbus bus master
4 --
5 -- Bridges ethernet MAC interface and / or out-of-band interfaces
6 -- to the ipbus.
7 
8 -- Dave Newbold, Sep 2012
9 
10 library ieee;
11 use ieee.std_logic_1164.all;
12 use work.ipbus.all;
13 use work.ipbus_trans_decl.all;
14 
15 entity ipbus_ctrl is
16  generic(
17  MAC_CFG: ipb_mac_cfg := EXTERNAL;
18  IP_CFG: ipb_ip_cfg := EXTERNAL;
19 -- Number of address bits to select RX or TX buffer in UDP I/F
20 -- Number of RX and TX buffers is 2**BUFWIDTH
21  BUFWIDTH: natural := 4;
22 -- Numer of address bits to select internal buffer in UDP I/F
23 -- Number of internal buffers is 2**INTERNALWIDTH
24  INTERNALWIDTH: natural := 1;
25 -- Number of address bits within each buffer in UDP I/F
26 -- Size of each buffer is 2**ADDRWIDTH
27  ADDRWIDTH: natural := 11;
28 -- UDP port for IPbus traffic in this instance of UDP I/F
29  IPBUSPORT: std_logic_vector(15 DOWNTO 0) := x"C351";
30 -- Flag whether this UDP I/F instance ignores everything except IPBus traffic
31  SECONDARYPORT: std_logic := '0';
32  N_OOB: natural := 0
33  );
34  port(
35  mac_clk: in std_logic; -- Ethernet MAC clock (125MHz)
36  rst_macclk: in std_logic; -- MAC clock domain sync reset
37  ipb_clk: in std_logic; -- IPbus clock
38  rst_ipb: in std_logic; -- IPbus clock domain sync reset
39  mac_rx_data: in std_logic_vector(7 downto 0); -- AXI4 style MAC signals
40  mac_rx_valid: in std_logic;
41  mac_rx_last: in std_logic;
42  mac_rx_error: in std_logic;
43  mac_tx_data: out std_logic_vector(7 downto 0);
44  mac_tx_valid: out std_logic;
45  mac_tx_last: out std_logic;
46  mac_tx_error: out std_logic;
47  mac_tx_ready: in std_logic;
48  ipb_out: out ipb_wbus; -- IPbus bus signals
49  ipb_in: in ipb_rbus;
50  ipb_req: out std_logic;
51  ipb_grant: in std_logic := '1';
52  mac_addr: in std_logic_vector(47 downto 0) := X"000000000000"; -- Static MAC and IP addresses
53  ip_addr: in std_logic_vector(31 downto 0) := X"00000000";
54  enable: in std_logic := '1';
55  RARP_select: in std_logic := '0';
56  pkt_rx: out std_logic;
57  pkt_tx: out std_logic;
58  pkt_rx_led: out std_logic;
59  pkt_tx_led: out std_logic;
60  oob_in: in ipbus_trans_in_array(N_OOB - 1 downto 0) := (others => ('0', X"00000000", '0'));
61  oob_out: out ipbus_trans_out_array(N_OOB - 1 downto 0)
62  );
63 
64 end ipbus_ctrl;
65 
66 architecture rtl of ipbus_ctrl is
67 
68  signal trans_in, trans_in_udp: ipbus_trans_in;
69  signal trans_out, trans_out_udp: ipbus_trans_out;
70  signal udp_rxpacket_ignored, udp_rxpacket_dropped: std_logic;
71  signal cfg, cfg_out: std_logic_vector(127 downto 0);
72  signal my_mac_addr: std_logic_vector(47 downto 0);
73  signal my_ip_addr, my_ip_addr_udp: std_logic_vector(31 downto 0);
74 -- signal last_hdr: std_logic_vector(31 downto 0);
75  signal pkt_rx_i, pkt_tx_i, udp_en, rarp_en: std_logic;
76  signal buf_in_a: ipbus_trans_in_array(N_OOB downto 0);
77  signal buf_out_a: ipbus_trans_out_array(N_OOB downto 0);
78 
79 begin
80 
81  udp_if: entity work.udp_if generic map(
82  BUFWIDTH => BUFWIDTH,
83  INTERNALWIDTH => INTERNALWIDTH,
84  ADDRWIDTH => ADDRWIDTH,
85  IPBUSPORT => IPBUSPORT,
86  SECONDARYPORT => SECONDARYPORT
87  )
88  port map(
89  mac_clk => mac_clk,
90  rst_macclk => rst_macclk,
91  ipb_clk => ipb_clk,
92  rst_ipb => rst_ipb,
93  IP_addr => my_ip_addr,
94  MAC_addr => my_mac_addr,
95  enable => udp_en ,
96  RARP => rarp_en,
97  mac_rx_data => mac_rx_data,
98  mac_rx_error => mac_rx_error,
99  mac_rx_last => mac_rx_last,
100  mac_rx_valid => mac_rx_valid,
101  mac_tx_ready => mac_tx_ready,
102  pkt_done_read => trans_out_udp.pkt_done,
103  pkt_done_write => trans_out_udp.pkt_done,
104  raddr => trans_out_udp.raddr,
105  waddr => trans_out_udp.waddr,
106  wdata => trans_out_udp.wdata,
107  we => trans_out_udp.we,
108  busy => trans_in_udp.busy,
109  mac_tx_data => mac_tx_data,
110  mac_tx_error => mac_tx_error,
111  mac_tx_last => mac_tx_last,
112  mac_tx_valid => mac_tx_valid,
113  My_IP_addr => my_ip_addr_udp ,
114  pkt_rdy => trans_in_udp.pkt_rdy,
115  rdata => trans_in_udp.rdata,
116  rxpacket_ignored => udp_rxpacket_ignored,
117  rxpacket_dropped => udp_rxpacket_dropped
118  );
119 
120  arb_gen: if N_OOB > 0 generate
121 
122  buf_in_a <= oob_in & trans_in_udp;
123  trans_out_udp <= buf_out_a(0);
124  oob_out <= buf_out_a(N_OOB downto 1);
125 
126  arb: entity work.trans_arb
127  generic map(NSRC => N_OOB + 1 )
128  port map(
129  clk => ipb_clk,
130  rst => rst_ipb,
131  buf_in => buf_in_a,
132  buf_out => buf_out_a,
133  trans_out => trans_in,
134  trans_in => trans_out
135  );
136 
137  end generate;
138 
139  n_arb_gen: if N_OOB = 0 generate
140  trans_in <= trans_in_udp;
141  trans_out_udp <= trans_out;
142  end generate;
143 
144  trans: entity work.transactor port map(
145  clk => ipb_clk,
146  rst => rst_ipb, -- This is probably not what we want...
147  ipb_out => ipb_out,
148  ipb_in => ipb_in,
149  ipb_req => ipb_req,
150  ipb_grant => ipb_grant,
151  trans_in => trans_in,
152  trans_out => trans_out,
153  cfg_vector_in => cfg_out,
154  cfg_vector_out => cfg,
155  pkt_rx => pkt_rx_i,
156  pkt_tx => pkt_tx_i
157  );
158 
159  cfg_out <= my_ip_addr_udp & X"000" & "00" & rarp_en & udp_en & my_mac_addr & X"00000000";
160 -- cfg_out <= my_ip_addr_udp & X"000" & "00" & rarp_en & udp_en & my_mac_addr & last_hdr;
161 
162  with MAC_CFG select my_mac_addr <=
163  mac_addr when EXTERNAL,
164  cfg(79 downto 32) when others;
165 
166  with IP_CFG select my_ip_addr <=
167  ip_addr when EXTERNAL,
168  cfg(127 downto 96) when others;
169 
170  udp_en <= cfg(80) or enable;
171 
172  rarp_en <= cfg(81) or RARP_select;
173 
174  stretch_rx: entity work.stretcher port map(
175  clk => mac_clk,
176  d => pkt_rx_i,
177  q => pkt_rx_led
178  );
179 
180  stretch_tx: entity work.stretcher port map(
181  clk => mac_clk,
182  d => pkt_tx_i,
183  q => pkt_tx_led
184  );
185 
186  pkt_rx <= pkt_rx_i;
187  pkt_tx <= pkt_tx_i;
188 
189 -- latch_hdr: process (ipb_clk)
190 -- begin
191 -- if rising_edge(ipb_clk) then
192 -- if rst_ipb = '1' then
193 -- last_hdr <= (Others => '1');
194 -- elsif trans_out_udp.pkt_done = '1' then
195 -- last_hdr <= "0" & trans_in_udp.pkt_rdy & trans_in_udp.busy & trans_out_udp.we & trans_out_udp.waddr & trans_out_udp.wdata(15 downto 0);
196 -- end if;
197 -- end if;
198 -- end process;
199 
200 end rtl;