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
g_simulation : boolean := false;
g_pcs_16bit : boolean := false;
g_tx_force_gap_length : integer := 0;
g_tx_runt_padding : boolean := false;
g_rx_buffer_size : integer := 1024;
g_with_rx_buffer : boolean := true;
g_with_flow_control : boolean := true;
......@@ -154,6 +155,7 @@ package endpoint_pkg is
g_interface_mode : t_wishbone_interface_mode := CLASSIC;
g_address_granularity : t_wishbone_address_granularity := WORD;
g_tx_force_gap_length : integer := 0;
g_tx_runt_padding : boolean := false;
g_simulation : boolean := false;
g_pcs_16bit : boolean := true;
g_rx_buffer_size : integer := 1024;
......
......@@ -186,7 +186,8 @@ package endpoint_private_pkg is
generic (
g_with_packet_injection : boolean;
g_with_timestamper : boolean;
g_force_gap_length : integer);
g_force_gap_length : integer;
g_runt_padding : boolean);
port (
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
......
......@@ -52,7 +52,8 @@ entity ep_tx_header_processor is
generic(
g_with_packet_injection : boolean;
g_with_timestamper : boolean;
g_force_gap_length : integer
g_force_gap_length : integer;
g_runt_padding : boolean
);
port (
......@@ -139,7 +140,7 @@ architecture behavioral of ep_tx_header_processor is
-- general signals
signal state : t_tx_framer_state;
signal counter : unsigned(7 downto 0);
signal counter : unsigned(13 downto 0);
-- Flow Control-related signals
signal tx_pause_mode : std_logic;
......@@ -165,6 +166,8 @@ architecture behavioral of ep_tx_header_processor is
signal tx_en : std_logic;
signal ep_ctrl : std_logic;
signal bitsel_d : std_logic;
signal needs_padding : std_logic;
signal sof_reg : std_logic;
function b2s (x : boolean)
return std_logic is
......@@ -242,6 +245,27 @@ begin -- behavioral
'1' when (state = TXF_ABORT and wb_snk_i.cyc = '1' ) else
'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)
begin
if rising_edge(clk_sys_i) then
......@@ -354,6 +378,7 @@ begin -- behavioral
wb_out.rty <= '0';
txtsu_stb_o <= '0';
bitsel_d <= '0';
src_fab_o.error <= '0';
src_fab_o.eof <= '0';
......@@ -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.
-- 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)
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';
tx_pause_mode <= fc_pause_req_i;
......@@ -379,9 +404,6 @@ begin -- behavioral
if(src_dreq_i = '1') then
state <= TXF_ADDR;
src_fab_o.sof <= '1';
else
state <= TXF_DELAYED_SOF;
src_fab_o.sof <= '0';
end if;
else
......@@ -458,8 +480,9 @@ begin -- behavioral
src_fab_o.dvalid <= '1';
src_fab_o.addr <= (others => '0');
if(counter = x"1e") then
if(counter = x"1d") then
state <= TXF_GAP;
src_fab_o.eof <= '1';
end if;
else
......@@ -480,7 +503,9 @@ begin -- behavioral
-- caused EOF to be longer than one cycle
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';
counter <= (others => '0');
......@@ -511,7 +536,8 @@ begin -- behavioral
if(snk_valid = '1' and wb_snk_i.adr = c_WRF_DATA) then
src_fab_o.data <= wb_snk_i.dat;
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
src_fab_o.dvalid <= '0';
src_fab_o.data <= (others => 'X');
......@@ -522,7 +548,11 @@ begin -- behavioral
bitsel_d <='1';
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
......@@ -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_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
-- the sink is ready to accept data
......
......@@ -52,6 +52,7 @@ entity ep_tx_path is
g_with_packet_injection : boolean;
g_with_inj_ctrl : boolean := true;
g_force_gap_length : integer;
g_runt_padding : boolean;
g_use_new_crc : boolean
);
......@@ -174,7 +175,8 @@ begin -- rtl
generic map (
g_with_packet_injection => g_with_packet_injection,
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 (
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
......
......@@ -59,6 +59,7 @@ entity wr_endpoint is
g_interface_mode : t_wishbone_interface_mode := CLASSIC;
g_address_granularity : t_wishbone_address_granularity := WORD;
g_tx_force_gap_length : integer := 0;
g_tx_runt_padding : boolean := true;
g_simulation : boolean := false;
g_pcs_16bit : boolean := true;
g_rx_buffer_size : integer := 1024;
......@@ -333,6 +334,7 @@ architecture syn of wr_endpoint is
g_with_timestamper : boolean;
g_with_packet_injection : boolean;
g_force_gap_length : integer;
g_runt_padding : boolean;
g_use_new_crc : boolean := false);
port (
clk_sys_i : in std_logic;
......@@ -719,6 +721,7 @@ begin
g_with_vlans => g_with_vlans,
g_with_timestamper => g_with_timestamper,
g_force_gap_length => g_tx_force_gap_length,
g_runt_padding => g_tx_runt_padding,
g_use_new_crc => g_use_new_txcrc)
port map (
clk_sys_i => clk_sys_i,
......
......@@ -50,6 +50,7 @@ entity xwr_endpoint is
g_address_granularity : t_wishbone_address_granularity := WORD;
g_simulation : boolean := false;
g_tx_force_gap_length : integer := 0;
g_tx_runt_padding : boolean := false;
g_pcs_16bit : boolean := false;
g_rx_buffer_size : integer := 1024;
g_with_rx_buffer : boolean := true;
......@@ -263,7 +264,7 @@ begin
g_interface_mode => g_interface_mode,
g_address_granularity => g_address_granularity,
g_tx_force_gap_length => g_tx_force_gap_length,
g_tx_runt_padding => g_tx_runt_padding,
g_simulation => g_simulation,
g_pcs_16bit => g_pcs_16bit,
g_rx_buffer_size => g_rx_buffer_size,
......
......@@ -88,6 +88,7 @@ entity wr_core is
g_virtual_uart : boolean := false;
g_aux_clks : integer := 1;
g_rx_buffer_size : integer := 1024;
g_tx_runt_padding : boolean := false;
g_dpram_initf : string := "default";
g_dpram_size : integer := 90112/4; --in 32-bit words
g_interface_mode : t_wishbone_interface_mode := PIPELINED;
......@@ -597,6 +598,7 @@ begin
g_interface_mode => PIPELINED,
g_address_granularity => BYTE,
g_simulation => f_int_to_bool(g_simulation),
g_tx_runt_padding => g_tx_runt_padding,
g_pcs_16bit => false,
g_rx_buffer_size => g_rx_buffer_size,
g_with_rx_buffer => true,
......
......@@ -300,6 +300,7 @@ package wrcore_pkg is
g_with_external_clock_input : boolean := false;
g_aux_clks : integer := 1;
g_ep_rxbuf_size : integer := 1024;
g_tx_runt_padding : boolean := false;
g_dpram_initf : string := "default";
g_dpram_size : integer := 90112/4; --in 32-bit words
g_interface_mode : t_wishbone_interface_mode := PIPELINED;
......@@ -404,6 +405,7 @@ package wrcore_pkg is
g_virtual_uart : boolean := false;
g_aux_clks : integer := 1;
g_rx_buffer_size : integer := 1024;
g_tx_runt_padding : boolean := false;
g_dpram_initf : string := "default";
g_dpram_size : integer := 90112/4; --in 32-bit words
g_interface_mode : t_wishbone_interface_mode := PIPELINED;
......
......@@ -73,6 +73,7 @@ entity xwr_core is
g_virtual_uart : boolean := false;
g_aux_clks : integer := 1;
g_ep_rxbuf_size : integer := 1024;
g_tx_runt_padding : boolean := false;
g_dpram_initf : string := "";
g_dpram_size : integer := 90112/4; --in 32-bit words
g_interface_mode : t_wishbone_interface_mode := PIPELINED;
......@@ -227,6 +228,7 @@ begin
g_phys_uart => g_phys_uart,
g_virtual_uart => g_virtual_uart,
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_aux_clks => g_aux_clks,
g_dpram_initf => g_dpram_initf,
......
......@@ -658,6 +658,7 @@ begin
g_virtual_uart => true,
g_aux_clks => 0,
g_ep_rxbuf_size => 1024,
g_tx_runt_padding => true,
g_dpram_initf => "wrc.ram",
g_aux_sdb => c_etherbone_sdb,
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