Commit aa03d1ec authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

wr_endpoint: Tx padding for runt frames (according to IEEE802.3 std)

Based on Peter's work, ported to current wr_endpoint code.
parent 1e29dca6
...@@ -62,6 +62,7 @@ package endpoint_pkg is ...@@ -62,6 +62,7 @@ package endpoint_pkg is
g_simulation : boolean := false; g_simulation : boolean := false;
g_pcs_16bit : boolean := false; g_pcs_16bit : boolean := false;
g_tx_force_gap_length : integer := 0; g_tx_force_gap_length : integer := 0;
g_tx_runt_padding : boolean := false;
g_rx_buffer_size : integer := 1024; g_rx_buffer_size : integer := 1024;
g_with_rx_buffer : boolean := true; g_with_rx_buffer : boolean := true;
g_with_flow_control : boolean := true; g_with_flow_control : boolean := true;
...@@ -154,6 +155,7 @@ package endpoint_pkg is ...@@ -154,6 +155,7 @@ package endpoint_pkg is
g_interface_mode : t_wishbone_interface_mode := CLASSIC; g_interface_mode : t_wishbone_interface_mode := CLASSIC;
g_address_granularity : t_wishbone_address_granularity := WORD; g_address_granularity : t_wishbone_address_granularity := WORD;
g_tx_force_gap_length : integer := 0; g_tx_force_gap_length : integer := 0;
g_tx_runt_padding : boolean := false;
g_simulation : boolean := false; g_simulation : boolean := false;
g_pcs_16bit : boolean := true; g_pcs_16bit : boolean := true;
g_rx_buffer_size : integer := 1024; g_rx_buffer_size : integer := 1024;
......
...@@ -186,7 +186,8 @@ package endpoint_private_pkg is ...@@ -186,7 +186,8 @@ package endpoint_private_pkg is
generic ( generic (
g_with_packet_injection : boolean; g_with_packet_injection : boolean;
g_with_timestamper : boolean; g_with_timestamper : boolean;
g_force_gap_length : integer); g_force_gap_length : integer;
g_runt_padding : boolean);
port ( port (
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
rst_n_i : in std_logic; rst_n_i : in std_logic;
......
...@@ -52,7 +52,8 @@ entity ep_tx_header_processor is ...@@ -52,7 +52,8 @@ entity ep_tx_header_processor is
generic( generic(
g_with_packet_injection : boolean; g_with_packet_injection : boolean;
g_with_timestamper : boolean; g_with_timestamper : boolean;
g_force_gap_length : integer g_force_gap_length : integer;
g_runt_padding : boolean
); );
port ( port (
...@@ -139,7 +140,7 @@ architecture behavioral of ep_tx_header_processor is ...@@ -139,7 +140,7 @@ architecture behavioral of ep_tx_header_processor is
-- general signals -- general signals
signal state : t_tx_framer_state; signal state : t_tx_framer_state;
signal counter : unsigned(7 downto 0); signal counter : unsigned(13 downto 0);
-- Flow Control-related signals -- Flow Control-related signals
signal tx_pause_mode : std_logic; signal tx_pause_mode : std_logic;
...@@ -165,6 +166,8 @@ architecture behavioral of ep_tx_header_processor is ...@@ -165,6 +166,8 @@ architecture behavioral of ep_tx_header_processor is
signal tx_en : std_logic; signal tx_en : std_logic;
signal ep_ctrl : std_logic; signal ep_ctrl : std_logic;
signal bitsel_d : std_logic; signal bitsel_d : std_logic;
signal needs_padding : std_logic;
signal sof_reg : std_logic;
function b2s (x : boolean) function b2s (x : boolean)
return std_logic is return std_logic is
...@@ -242,6 +245,27 @@ begin -- behavioral ...@@ -242,6 +245,27 @@ begin -- behavioral
'1' when (state = TXF_ABORT and wb_snk_i.cyc = '1' ) else '1' when (state = TXF_ABORT and wb_snk_i.cyc = '1' ) else
'0'; -- ML '0'; -- ML
GEN_PADDING: if(g_runt_padding) generate
needs_padding <= '1' when(counter < x"1e") else -- 0x1e, but we count here also ethertype
'0';
end generate;
GEN_NOPADDING: if( not g_runt_padding) generate
needs_padding <= '0';
end generate;
process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if(rst_n_i='0') then
sof_reg <= '0';
elsif(sof_p1='1') then
sof_reg <= '1';
elsif(state = TXF_ADDR) then
sof_reg <= '0';
end if;
end if;
end process;
p_store_status : process(clk_sys_i) p_store_status : process(clk_sys_i)
begin begin
if rising_edge(clk_sys_i) then if rising_edge(clk_sys_i) then
...@@ -354,6 +378,7 @@ begin -- behavioral ...@@ -354,6 +378,7 @@ begin -- behavioral
wb_out.rty <= '0'; wb_out.rty <= '0';
txtsu_stb_o <= '0'; txtsu_stb_o <= '0';
bitsel_d <= '0';
src_fab_o.error <= '0'; src_fab_o.error <= '0';
src_fab_o.eof <= '0'; src_fab_o.eof <= '0';
...@@ -368,7 +393,7 @@ begin -- behavioral ...@@ -368,7 +393,7 @@ begin -- behavioral
-- it means that if we wait for dreq to be high.... we can miss SOF and thus entire frame. -- it means that if we wait for dreq to be high.... we can miss SOF and thus entire frame.
-- New state added to include a case where SOF (start of cycle) starts when dreq is LOW. -- New state added to include a case where SOF (start of cycle) starts when dreq is LOW.
-- (we cannot just go to TXF_ADDR... it is because the PCS needs the minimal gap to add CRC) -- (we cannot just go to TXF_ADDR... it is because the PCS needs the minimal gap to add CRC)
if((sof_p1 = '1' or fc_pause_req_i = '1') and tx_en = '1') then --ML if((sof_p1 = '1' or sof_reg='1' or fc_pause_req_i = '1') and tx_en = '1') then --ML
fc_pause_ready_o <= '0'; fc_pause_ready_o <= '0';
tx_pause_mode <= fc_pause_req_i; tx_pause_mode <= fc_pause_req_i;
...@@ -379,9 +404,6 @@ begin -- behavioral ...@@ -379,9 +404,6 @@ begin -- behavioral
if(src_dreq_i = '1') then if(src_dreq_i = '1') then
state <= TXF_ADDR; state <= TXF_ADDR;
src_fab_o.sof <= '1'; src_fab_o.sof <= '1';
else
state <= TXF_DELAYED_SOF;
src_fab_o.sof <= '0';
end if; end if;
else else
...@@ -458,8 +480,9 @@ begin -- behavioral ...@@ -458,8 +480,9 @@ begin -- behavioral
src_fab_o.dvalid <= '1'; src_fab_o.dvalid <= '1';
src_fab_o.addr <= (others => '0'); src_fab_o.addr <= (others => '0');
if(counter = x"1e") then if(counter = x"1d") then
state <= TXF_GAP; state <= TXF_GAP;
src_fab_o.eof <= '1';
end if; end if;
else else
...@@ -480,7 +503,9 @@ begin -- behavioral ...@@ -480,7 +503,9 @@ begin -- behavioral
-- caused EOF to be longer than one cycle -- caused EOF to be longer than one cycle
src_fab_o.eof <= '0'; src_fab_o.eof <= '0';
if(eof_p1 = '1') then if((wb_snk_i.adr = c_WRF_OOB or eof_p1='1') and needs_padding='1') then
state <= TXF_PAD;
elsif(eof_p1 = '1' and needs_padding='0') then
src_fab_o.eof <= '1'; src_fab_o.eof <= '1';
counter <= (others => '0'); counter <= (others => '0');
...@@ -511,7 +536,8 @@ begin -- behavioral ...@@ -511,7 +536,8 @@ begin -- behavioral
if(snk_valid = '1' and wb_snk_i.adr = c_WRF_DATA) then if(snk_valid = '1' and wb_snk_i.adr = c_WRF_DATA) then
src_fab_o.data <= wb_snk_i.dat; src_fab_o.data <= wb_snk_i.dat;
src_fab_o.dvalid <= '1'; src_fab_o.dvalid <= '1';
src_fab_o.bytesel <= not wb_snk_i.sel(0); src_fab_o.bytesel <= (not wb_snk_i.sel(0)) and (not needs_padding);
counter <= counter + 1;
else else
src_fab_o.dvalid <= '0'; src_fab_o.dvalid <= '0';
src_fab_o.data <= (others => 'X'); src_fab_o.data <= (others => 'X');
...@@ -522,7 +548,11 @@ begin -- behavioral ...@@ -522,7 +548,11 @@ begin -- behavioral
bitsel_d <='1'; bitsel_d <='1';
end if; end if;
src_fab_o.addr <= wb_snk_i.adr; if(needs_padding='1') then
src_fab_o.addr <= (others=>'0');
else
src_fab_o.addr <= wb_snk_i.adr;
end if;
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- TX FSM states: WAIT_CRC, EMBED_CRC: dealing with frame checksum field -- TX FSM states: WAIT_CRC, EMBED_CRC: dealing with frame checksum field
...@@ -615,7 +645,7 @@ begin -- behavioral ...@@ -615,7 +645,7 @@ begin -- behavioral
--------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------
-- elsif(src_dreq_i = '1' and state /= TXF_GAP and state /= TXF_ABORT and state /= TXF_DELAYED_SOF and state /= TXF_STORE_TSTAMP) then -- elsif(src_dreq_i = '1' and state /= TXF_GAP and state /= TXF_ABORT and state /= TXF_DELAYED_SOF and state /= TXF_STORE_TSTAMP) then
--------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------
elsif(src_dreq_i = '1' and state /= TXF_GAP and state /= TXF_DELAYED_SOF and state /= TXF_STORE_TSTAMP) then elsif(src_dreq_i = '1' and state /= TXF_PAD and state /= TXF_GAP and state /= TXF_DELAYED_SOF and state /= TXF_STORE_TSTAMP) then
wb_out.stall <= '0'; -- during data/header phase - whenever wb_out.stall <= '0'; -- during data/header phase - whenever
-- the sink is ready to accept data -- the sink is ready to accept data
......
...@@ -52,6 +52,7 @@ entity ep_tx_path is ...@@ -52,6 +52,7 @@ entity ep_tx_path is
g_with_packet_injection : boolean; g_with_packet_injection : boolean;
g_with_inj_ctrl : boolean := true; g_with_inj_ctrl : boolean := true;
g_force_gap_length : integer; g_force_gap_length : integer;
g_runt_padding : boolean;
g_use_new_crc : boolean g_use_new_crc : boolean
); );
...@@ -174,7 +175,8 @@ begin -- rtl ...@@ -174,7 +175,8 @@ begin -- rtl
generic map ( generic map (
g_with_packet_injection => g_with_packet_injection, g_with_packet_injection => g_with_packet_injection,
g_with_timestamper => g_with_timestamper, g_with_timestamper => g_with_timestamper,
g_force_gap_length => g_force_gap_length) g_force_gap_length => g_force_gap_length,
g_runt_padding => g_runt_padding)
port map ( port map (
clk_sys_i => clk_sys_i, clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i, rst_n_i => rst_n_i,
......
...@@ -59,6 +59,7 @@ entity wr_endpoint is ...@@ -59,6 +59,7 @@ entity wr_endpoint is
g_interface_mode : t_wishbone_interface_mode := CLASSIC; g_interface_mode : t_wishbone_interface_mode := CLASSIC;
g_address_granularity : t_wishbone_address_granularity := WORD; g_address_granularity : t_wishbone_address_granularity := WORD;
g_tx_force_gap_length : integer := 0; g_tx_force_gap_length : integer := 0;
g_tx_runt_padding : boolean := true;
g_simulation : boolean := false; g_simulation : boolean := false;
g_pcs_16bit : boolean := true; g_pcs_16bit : boolean := true;
g_rx_buffer_size : integer := 1024; g_rx_buffer_size : integer := 1024;
...@@ -333,6 +334,7 @@ architecture syn of wr_endpoint is ...@@ -333,6 +334,7 @@ architecture syn of wr_endpoint is
g_with_timestamper : boolean; g_with_timestamper : boolean;
g_with_packet_injection : boolean; g_with_packet_injection : boolean;
g_force_gap_length : integer; g_force_gap_length : integer;
g_runt_padding : boolean;
g_use_new_crc : boolean := false); g_use_new_crc : boolean := false);
port ( port (
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
...@@ -719,6 +721,7 @@ begin ...@@ -719,6 +721,7 @@ begin
g_with_vlans => g_with_vlans, g_with_vlans => g_with_vlans,
g_with_timestamper => g_with_timestamper, g_with_timestamper => g_with_timestamper,
g_force_gap_length => g_tx_force_gap_length, g_force_gap_length => g_tx_force_gap_length,
g_runt_padding => g_tx_runt_padding,
g_use_new_crc => g_use_new_txcrc) g_use_new_crc => g_use_new_txcrc)
port map ( port map (
clk_sys_i => clk_sys_i, clk_sys_i => clk_sys_i,
......
...@@ -50,6 +50,7 @@ entity xwr_endpoint is ...@@ -50,6 +50,7 @@ entity xwr_endpoint is
g_address_granularity : t_wishbone_address_granularity := WORD; g_address_granularity : t_wishbone_address_granularity := WORD;
g_simulation : boolean := false; g_simulation : boolean := false;
g_tx_force_gap_length : integer := 0; g_tx_force_gap_length : integer := 0;
g_tx_runt_padding : boolean := false;
g_pcs_16bit : boolean := false; g_pcs_16bit : boolean := false;
g_rx_buffer_size : integer := 1024; g_rx_buffer_size : integer := 1024;
g_with_rx_buffer : boolean := true; g_with_rx_buffer : boolean := true;
...@@ -263,7 +264,7 @@ begin ...@@ -263,7 +264,7 @@ begin
g_interface_mode => g_interface_mode, g_interface_mode => g_interface_mode,
g_address_granularity => g_address_granularity, g_address_granularity => g_address_granularity,
g_tx_force_gap_length => g_tx_force_gap_length, g_tx_force_gap_length => g_tx_force_gap_length,
g_tx_runt_padding => g_tx_runt_padding,
g_simulation => g_simulation, g_simulation => g_simulation,
g_pcs_16bit => g_pcs_16bit, g_pcs_16bit => g_pcs_16bit,
g_rx_buffer_size => g_rx_buffer_size, g_rx_buffer_size => g_rx_buffer_size,
......
...@@ -88,6 +88,7 @@ entity wr_core is ...@@ -88,6 +88,7 @@ entity wr_core is
g_virtual_uart : boolean := false; g_virtual_uart : boolean := false;
g_aux_clks : integer := 1; g_aux_clks : integer := 1;
g_rx_buffer_size : integer := 1024; g_rx_buffer_size : integer := 1024;
g_tx_runt_padding : boolean := false;
g_dpram_initf : string := "default"; g_dpram_initf : string := "default";
g_dpram_size : integer := 90112/4; --in 32-bit words g_dpram_size : integer := 90112/4; --in 32-bit words
g_interface_mode : t_wishbone_interface_mode := PIPELINED; g_interface_mode : t_wishbone_interface_mode := PIPELINED;
...@@ -597,6 +598,7 @@ begin ...@@ -597,6 +598,7 @@ begin
g_interface_mode => PIPELINED, g_interface_mode => PIPELINED,
g_address_granularity => BYTE, g_address_granularity => BYTE,
g_simulation => f_int_to_bool(g_simulation), g_simulation => f_int_to_bool(g_simulation),
g_tx_runt_padding => g_tx_runt_padding,
g_pcs_16bit => false, g_pcs_16bit => false,
g_rx_buffer_size => g_rx_buffer_size, g_rx_buffer_size => g_rx_buffer_size,
g_with_rx_buffer => true, g_with_rx_buffer => true,
......
...@@ -300,6 +300,7 @@ package wrcore_pkg is ...@@ -300,6 +300,7 @@ package wrcore_pkg is
g_with_external_clock_input : boolean := false; g_with_external_clock_input : boolean := false;
g_aux_clks : integer := 1; g_aux_clks : integer := 1;
g_ep_rxbuf_size : integer := 1024; g_ep_rxbuf_size : integer := 1024;
g_tx_runt_padding : boolean := false;
g_dpram_initf : string := "default"; g_dpram_initf : string := "default";
g_dpram_size : integer := 90112/4; --in 32-bit words g_dpram_size : integer := 90112/4; --in 32-bit words
g_interface_mode : t_wishbone_interface_mode := PIPELINED; g_interface_mode : t_wishbone_interface_mode := PIPELINED;
...@@ -404,6 +405,7 @@ package wrcore_pkg is ...@@ -404,6 +405,7 @@ package wrcore_pkg is
g_virtual_uart : boolean := false; g_virtual_uart : boolean := false;
g_aux_clks : integer := 1; g_aux_clks : integer := 1;
g_rx_buffer_size : integer := 1024; g_rx_buffer_size : integer := 1024;
g_tx_runt_padding : boolean := false;
g_dpram_initf : string := "default"; g_dpram_initf : string := "default";
g_dpram_size : integer := 90112/4; --in 32-bit words g_dpram_size : integer := 90112/4; --in 32-bit words
g_interface_mode : t_wishbone_interface_mode := PIPELINED; g_interface_mode : t_wishbone_interface_mode := PIPELINED;
......
...@@ -73,6 +73,7 @@ entity xwr_core is ...@@ -73,6 +73,7 @@ entity xwr_core is
g_virtual_uart : boolean := false; g_virtual_uart : boolean := false;
g_aux_clks : integer := 1; g_aux_clks : integer := 1;
g_ep_rxbuf_size : integer := 1024; g_ep_rxbuf_size : integer := 1024;
g_tx_runt_padding : boolean := false;
g_dpram_initf : string := ""; g_dpram_initf : string := "";
g_dpram_size : integer := 90112/4; --in 32-bit words g_dpram_size : integer := 90112/4; --in 32-bit words
g_interface_mode : t_wishbone_interface_mode := PIPELINED; g_interface_mode : t_wishbone_interface_mode := PIPELINED;
...@@ -227,6 +228,7 @@ begin ...@@ -227,6 +228,7 @@ begin
g_phys_uart => g_phys_uart, g_phys_uart => g_phys_uart,
g_virtual_uart => g_virtual_uart, g_virtual_uart => g_virtual_uart,
g_rx_buffer_size => g_ep_rxbuf_size, g_rx_buffer_size => g_ep_rxbuf_size,
g_tx_runt_padding => g_tx_runt_padding,
g_with_external_clock_input => g_with_external_clock_input, g_with_external_clock_input => g_with_external_clock_input,
g_aux_clks => g_aux_clks, g_aux_clks => g_aux_clks,
g_dpram_initf => g_dpram_initf, g_dpram_initf => g_dpram_initf,
......
...@@ -658,6 +658,7 @@ begin ...@@ -658,6 +658,7 @@ begin
g_virtual_uart => true, g_virtual_uart => true,
g_aux_clks => 0, g_aux_clks => 0,
g_ep_rxbuf_size => 1024, g_ep_rxbuf_size => 1024,
g_tx_runt_padding => true,
g_dpram_initf => "wrc.ram", g_dpram_initf => "wrc.ram",
g_aux_sdb => c_etherbone_sdb, g_aux_sdb => c_etherbone_sdb,
g_dpram_size => 131072/4, g_dpram_size => 131072/4,
......
Markdown is supported
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