Skip to content
Snippets Groups Projects
Commit 4f96ad1f authored by Mathias Kreider's avatar Mathias Kreider
Browse files

ebm: added raw udp bypass

parent 8d5e5f78
Branches
Tags
No related merge requests found
......@@ -65,25 +65,26 @@ signal eop : std_logic;
signal clear, s_clear : std_logic;
signal stop, stop_cnt : boolean := false;
constant c_RESET : unsigned(31 downto 0) := x"01000000";
constant c_FLUSH : unsigned(31 downto 0) := c_RESET +4; --wo 04
constant c_STATUS : unsigned(31 downto 0) := c_FLUSH +4; --rw 08
constant c_SRC_MAC_HI : unsigned(31 downto 0) := c_STATUS +4; --rw 0C
constant c_SRC_MAC_LO : unsigned(31 downto 0) := c_SRC_MAC_HI +4; --rw 10
constant c_SRC_IPV4 : unsigned(31 downto 0) := c_SRC_MAC_LO +4; --rw 14
constant c_SRC_UDP_PORT : unsigned(31 downto 0) := c_SRC_IPV4 +4; --rw 18
constant c_DST_MAC_HI : unsigned(31 downto 0) := c_SRC_UDP_PORT +4; --rw 1C
constant c_DST_MAC_LO : unsigned(31 downto 0) := c_DST_MAC_HI +4; --rw 20
constant c_DST_IPV4 : unsigned(31 downto 0) := c_DST_MAC_LO +4; --rw 24
constant c_DST_UDP_PORT : unsigned(31 downto 0) := c_DST_IPV4 +4; --rw 28
constant c_PAC_LEN : unsigned(31 downto 0) := c_DST_UDP_PORT +4; --rw 2C
constant c_OPA_HI : unsigned(31 downto 0) := c_PAC_LEN +4; --rw 30
constant c_OPS_MAX : unsigned(31 downto 0) := c_OPA_HI +4; --rw 34
constant c_WOA_BASE : unsigned(31 downto 0) := c_OPS_MAX +4; --ro 38
constant c_ROA_BASE : unsigned(31 downto 0) := c_WOA_BASE +4; --ro 3C
constant c_EB_OPT : unsigned(31 downto 0) := c_ROA_BASE +4; --rw 40
constant c_MTU : natural := 1500;
constant c_CLEAR : unsigned(31 downto 0) := (others => '0'); --wo 00
constant c_FLUSH : unsigned(31 downto 0) := c_CLEAR +4; --wo 04
constant c_STATUS : unsigned(31 downto 0) := c_FLUSH +4; --rw 08
constant c_SRC_MAC_HI : unsigned(31 downto 0) := c_STATUS +4; --rw 0C
constant c_SRC_MAC_LO : unsigned(31 downto 0) := c_SRC_MAC_HI +4; --rw 10
constant c_SRC_IPV4 : unsigned(31 downto 0) := c_SRC_MAC_LO +4; --rw 14
constant c_SRC_UDP_PORT : unsigned(31 downto 0) := c_SRC_IPV4 +4; --rw 18
constant c_DST_MAC_HI : unsigned(31 downto 0) := c_SRC_UDP_PORT +4; --rw 1C
constant c_DST_MAC_LO : unsigned(31 downto 0) := c_DST_MAC_HI +4; --rw 20
constant c_DST_IPV4 : unsigned(31 downto 0) := c_DST_MAC_LO +4; --rw 24
constant c_DST_UDP_PORT : unsigned(31 downto 0) := c_DST_IPV4 +4; --rw 28
constant c_MTU : unsigned(31 downto 0) := c_DST_UDP_PORT +4; --rw 2C
constant c_ADR_HI : unsigned(31 downto 0) := c_MTU +4; --rw 30
constant c_OPS_MAX : unsigned(31 downto 0) := c_ADR_HI +4; --rw 34
constant c_EB_OPT : unsigned(31 downto 0) := c_OPS_MAX +4; --rw 38
constant c_SEMA : unsigned(31 downto 0) := c_EB_OPT +4; --rw 3C
constant c_UDP_RAW : unsigned(31 downto 0) := c_SEMA +4; --rw 40
constant c_UDP_DATA : unsigned(31 downto 0) := c_UDP_RAW +4; --ro 44
constant g_MTU : natural := 1500;
constant c_adr_hi_bits : natural := 10;
signal A_fifo_d,
......@@ -201,7 +202,7 @@ fcO : wb_fc_test
uut: eb_master_top
GENERIC MAP(g_adr_bits_hi => c_adr_hi_bits,
g_mtu => c_mtu)
g_mtu => g_mtu)
PORT MAP (
clk_i => clk,
rst_n_i => rst_n,
......@@ -336,9 +337,14 @@ uut: eb_master_top
wb_wr(c_DST_IPV4, x"C0A80064", '1');
wb_wr(c_DST_UDP_PORT, x"0000EBD1", '1');
wb_wr(c_OPS_MAX, x"00000030", '1');
wb_wr(c_PAC_LEN, x"000005D8", '1');
wb_wr(c_OPA_HI, x"00000000", '1');
wb_wr(c_ADR_HI, x"00000000", '1');
wb_wr(c_EB_OPT, x"00000000", '0');
wb_wr(c_UDP_RAW, x"00000001", '0');
wb_wr(c_UDP_DATA, x"DEADBEE1", '0');
wb_wr(c_UDP_DATA, x"DEADBEE2", '0');
wb_wr(c_UDP_DATA, x"DEADBEE3", '0');
wb_wr(c_FLUSH, x"00000001", '0');
for I in 0 to c_reps-1 loop
......@@ -351,7 +357,7 @@ uut: eb_master_top
ovf := false;
wait for clk_period*RV.RandInt(0, c_max_wb_wait);
wb_wr(c_OPA_HI, x"7FFFFFF0", '0');
wb_wr(c_ADR_HI, x"7FFFFFF0", '0');
v_pack_len := v_pack_len + 2*4;
for k in 0 to RV.RandInt(2, c_msgs_len)-1 loop
......
......@@ -78,8 +78,12 @@
--!
--! 0x40 rw EB_OPT Etherbone Record options
--!
--! 0x44 rw SEMA Semaphore register, can be used to indicate current owner of EBM
--!
--! 0x44 rw SEMA Semaphore register, can be used to indicate current owner of EBM
--!
--! 0x48 rw UDP_MODE writing '1' bypasses Etherbone logic, enabling direct input of UDP payload,
--! resetting to '0' sends the packet.
--!
--! 0x4C wo UDP_DATA Data interface for direct input of UDP payload
--! @author Mathias Kreider <m.kreider@gsi.de>
--!
--------------------------------------------------------------------------------
......@@ -149,17 +153,26 @@ architecture rtl of eb_master_top is
signal s_tx_stb : std_logic;
signal s_clear, s_test : std_logic;
signal s_tx_flush : std_logic;
signal s_udp, r_udp_raw : std_logic;
signal s_skip_stb : std_logic;
signal s_length : unsigned(15 downto 0); -- of UDP in words
signal s_max_ops : unsigned(15 downto 0); -- max eb ops count per packet
signal s_udp_raw_o : std_logic;
signal s_udp_we_o : std_logic;
signal s_udp_valid_i : std_logic;
signal s_udp_data_o : std_logic_vector(31 downto 0);
--wb signals
signal s_framer_in : t_wishbone_slave_in;
signal s_framer_out : t_wishbone_slave_out;
signal s_ctrl_in : t_wishbone_slave_in;
signal s_ctrl_out : t_wishbone_slave_out;
signal s_narrow_in : t_wishbone_master_out;
signal s_narrow_out : t_wishbone_master_in;
signal s_framer2narrow : t_wishbone_master_out;
signal s_narrow2framer : t_wishbone_master_in;
signal s_narrow2tx : t_wishbone_master_out;
......@@ -272,7 +285,12 @@ begin
length_o => s_length,
max_ops_o => s_max_ops,
adr_hi_o => s_adr_hi,
eb_opt_o => s_cfg_rec_hdr
eb_opt_o => s_cfg_rec_hdr,
udp_raw_o => s_udp_raw_o,
udp_we_o => s_udp_we_o,
udp_valid_i => s_udp_valid_i,
udp_data_o => s_udp_data_o
);
framer: eb_framer
......@@ -299,6 +317,8 @@ begin
framer_in <= s_framer_in;
framer_out <= s_framer_out;
narrow : eb_stream_narrow
generic map(
g_slave_width => 32,
......@@ -306,13 +326,45 @@ begin
port map(
clk_i => clk_i,
rst_n_i => s_rst_n,
slave_i => s_framer2narrow,
slave_o => s_narrow2framer,
slave_i => s_narrow_in,
slave_o => s_narrow_out,
master_i => s_tx2narrow,
master_o => s_narrow2tx);
MUX_RAW_UDP : process(s_udp_raw_o, s_udp_we_o, s_udp_data_o, s_narrow_out, s_framer2narrow)
begin
s_narrow_in.sel <= (others => '1');
s_narrow_in.we <= '1';
s_narrow_in.adr <= (others => '0');
if s_udp_raw_o = '1' then
s_narrow_in.cyc <= s_udp_raw_o;
s_narrow_in.stb <= s_udp_we_o;
s_narrow_in.dat <= s_udp_data_o;
s_udp_valid_i <= s_udp_raw_o and s_udp_we_o and not s_narrow_out.stall;
s_narrow2framer <= ('0', '0', '0', '0', '0', (others => '0'));
else
s_udp_valid_i <= '0';
s_narrow_in.cyc <= s_framer2narrow.cyc;
s_narrow_in.stb <= s_framer2narrow.stb;
s_narrow_in.dat <= s_framer2narrow.dat;
s_narrow2framer <= s_narrow_out;
end if;
end process;
-- be careful, don't use this if you don't know what you're doing
RAW_UDP : process(clk_i)
begin
if(rising_edge(clk_i)) then
r_udp_raw <= s_udp_raw_o;
end if;
end process;
s_udp <= s_udp_raw_o and not r_udp_raw;
---TX IF
s_tx_stb <= s_tx_flush;
s_tx_stb <= s_tx_flush or s_udp;
tx : eb_master_eth_tx
generic map(
......
......@@ -60,7 +60,13 @@ port(
length_o : out unsigned(15 downto 0);
max_ops_o : out unsigned(15 downto 0);
adr_hi_o : out std_logic_vector(g_adr_bits_hi-1 downto 0);
eb_opt_o : out t_rec_hdr);
eb_opt_o : out t_rec_hdr;
udp_raw_o : out std_logic;
udp_we_o : out std_logic;
udp_valid_i : in std_logic;
udp_data_o : out std_logic_vector(31 downto 0)
);
end eb_master_wb_if;
......@@ -81,8 +87,11 @@ architecture rtl of eb_master_wb_if is
constant c_MTU : natural := c_DST_UDP_PORT +4; --rw 2C
constant c_ADR_HI : natural := c_MTU +4; --rw 30
constant c_OPS_MAX : natural := c_ADR_HI +4; --rw 34
constant c_EB_OPT : natural := c_OPS_MAX +4; --rw 40
constant c_SEMA : natural := c_EB_OPT +4; --rw 44
constant c_EB_OPT : natural := c_OPS_MAX +4; --rw 38
constant c_SEMA : natural := c_EB_OPT +4; --rw 3C
constant c_UDP_RAW : natural := c_SEMA +4; --rw 40
constant c_UDP_DATA : natural := c_UDP_RAW +4; --ro 44
constant c_STAT_CONFIGURED : t_wishbone_data := x"00000001";
constant c_STAT_BUSY : t_wishbone_data := x"00000002";
......@@ -91,7 +100,7 @@ architecture rtl of eb_master_wb_if is
signal r_slave_out_ack,
r_slave_out_err,
s_stall : std_logic;
r_stall : std_logic;
signal r_slave_out_dat : std_logic_vector(31 downto 0);
signal r_stat : std_logic_vector(31 downto 0);
......@@ -113,6 +122,9 @@ architecture rtl of eb_master_wb_if is
signal r_adr_hi : std_logic_vector(g_adr_bits_hi-1 downto 0);
signal r_eb_opt : std_logic_vector(31 downto 0);
signal r_sema : std_logic_vector(31 downto 0);
signal r_udp_raw : std_logic_vector(0 downto 0);
signal r_udp_data : std_logic_vector(31 downto 0);
signal r_udp_we : std_logic;
constant c_EB_PORT : std_logic_vector(15 downto 0) := x"EBD0";
......@@ -131,13 +143,15 @@ begin
length_o <= unsigned(r_length);
adr_hi_o <= r_adr_hi;
eb_opt_o <= f_parse_rec(r_eb_opt);
s_stall <= '0';
udp_raw_o <= r_udp_raw(0);
udp_we_o <= r_udp_we;
udp_data_o <= r_udp_data;
slave_o.ack <= r_slave_out_ack;
slave_o.err <= r_slave_out_err;
slave_o.dat <= r_slave_out_dat;
slave_o.stall <= s_stall;
slave_o.stall <= r_stall;
p_wb_if : process (clk_i) is
variable v_dat_i : t_wishbone_data;
......@@ -161,17 +175,22 @@ begin
r_his_ip <= (others => '1');
r_his_port <= c_EB_PORT;
r_stat <= (others => '0');
r_sema <= (others => '0');
r_sema <= (others => '0');
r_udp_raw <= (others => '0');
r_udp_we <= '0';
r_stall <= '0';
else
--gather status info
r_stat(error_i'range) <= error_i;
r_stat(31 downto 16) <= byte_cnt_i;
r_stall <= r_stall and not udp_valid_i;
r_udp_we <= r_udp_we and not udp_valid_i;
-- short names
v_dat_i := slave_i.dat;
v_adr := to_integer(unsigned(slave_i.adr(7 downto 2)) & "00");
v_sel := slave_i.sel;
v_en := slave_i.cyc and slave_i.stb and not s_stall;
v_en := slave_i.cyc and slave_i.stb and not r_stall;
v_we := slave_i.we;
--interface outputs
......@@ -186,15 +205,20 @@ begin
r_slave_out_ack <= '1'; -- ack is default, we'll change it if an error occurs
if(v_we = '1') then
case v_adr is
when c_CLEAR => r_clr <= f_wb_wr(r_clr, v_dat_i, v_sel, "set");
when c_FLUSH => if(unsigned(byte_cnt_i) /= 0 and unsigned(error_i) = 0) then
--report "flushing" severity note;
r_flush <= f_wb_wr(r_flush, v_dat_i, v_sel, "set");
when c_CLEAR => r_clr <= f_wb_wr(r_clr, v_dat_i, v_sel, "set");
r_udp_raw <= (others => '0');
when c_FLUSH => if(r_udp_raw = "0") then
if(unsigned(byte_cnt_i) /= 0 and unsigned(error_i) = 0) then
--report "flushing" severity note;
r_flush <= f_wb_wr(r_flush, v_dat_i, v_sel, "set");
else
--report "OVERFLOW detected" severity error;
r_clr <= f_wb_wr(r_clr, v_dat_i, v_sel, "set");
r_slave_out_ack <= '0'; r_slave_out_err <= '1';
end if;
else
--report "OVERFLOW detected" severity error;
r_clr <= f_wb_wr(r_clr, v_dat_i, v_sel, "set");
r_slave_out_ack <= '0'; r_slave_out_err <= '1';
end if;
r_udp_raw <= f_wb_wr(r_udp_raw, v_dat_i, v_sel, "clr");
end if;
when c_SRC_MAC_HI => a_my_mac_hi <= f_wb_wr(a_my_mac_hi, v_dat_i, v_sel, "owr");
when c_SRC_MAC_LO => a_my_mac_lo <= f_wb_wr(a_my_mac_lo, v_dat_i, v_sel, "owr");
......@@ -209,6 +233,14 @@ begin
when c_OPS_MAX => r_ops_max <= f_wb_wr(r_ops_max, v_dat_i, v_sel, "owr");
when c_EB_OPT => r_eb_opt <= f_wb_wr(r_eb_opt, v_dat_i, v_sel, "owr");
when c_SEMA => r_sema <= f_wb_wr(r_sema, v_dat_i, v_sel, "owr");
when c_UDP_RAW => r_udp_raw <= f_wb_wr(r_udp_raw, v_dat_i, v_sel, "owr");
when c_UDP_DATA => if(r_udp_raw = "1") then
r_udp_data <= f_wb_wr(r_udp_data, v_dat_i, v_sel, "owr");
r_udp_we <= '1';
r_stall <= '1';
else
r_slave_out_ack <= '0'; r_slave_out_err <= '1';
end if;
when others => r_slave_out_ack <= '0'; r_slave_out_err <= '1';
end case;
else
......@@ -226,7 +258,8 @@ begin
when c_ADR_HI => r_slave_out_dat(r_slave_out_dat'left downto r_slave_out_dat'length - r_adr_hi'length) <= r_adr_hi;
when c_OPS_MAX => r_slave_out_dat(r_ops_max'range) <= r_ops_max;
when c_EB_OPT => r_slave_out_dat(r_eb_opt'range) <= r_eb_opt;
when c_SEMA => r_slave_out_dat(r_sema'range) <= r_sema;
when c_SEMA => r_slave_out_dat(r_sema'range) <= r_sema;
when c_UDP_RAW => r_slave_out_dat(r_udp_raw'range) <= r_udp_raw;
when others => r_slave_out_ack <= '0'; r_slave_out_err <= '1';
end case;
end if; -- we
......
......@@ -324,7 +324,12 @@ package eb_internals_pkg is
length_o : out unsigned(15 downto 0);
max_ops_o : out unsigned(15 downto 0);
adr_hi_o : out std_logic_vector(g_adr_bits_hi-1 downto 0);
eb_opt_o : out t_rec_hdr);
eb_opt_o : out t_rec_hdr;
udp_raw_o : out std_logic;
udp_we_o : out std_logic;
udp_valid_i : in std_logic;
udp_data_o : out std_logic_vector(31 downto 0));
end component;
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment