Commit 6943dd6d authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

Merge branch 'switch-v4.0' into wrpc_wrs_merge

Conflicts:
	modules/wr_endpoint/ep_tx_pcs_8bit.vhd
	modules/wr_softpll_ng/wr_softpll_ng.vhd
parents 01b463bf a6f8b588
files = ["wr_fabric_pkg.vhd", "xwb_fabric_sink.vhd", "xwb_fabric_source.vhd", "xwrf_mux.vhd" ]
files = ["wr_fabric_pkg.vhd", "xwb_fabric_sink.vhd", "xwb_fabric_source.vhd", "xwrf_mux.vhd", "xwrf_reg.vhd" ]
......@@ -91,6 +91,19 @@ package wr_fabric_pkg is
);
end component;
component xwrf_reg is
generic(
g_adr_width : integer := 2;
g_dat_width : integer :=16);
port(
rst_n_i : in std_logic;
clk_i : in std_logic;
snk_i : in t_wrf_sink_in;
snk_o : out t_wrf_sink_out;
src_i : in t_wrf_source_in;
src_o : out t_wrf_source_out);
end component;
end wr_fabric_pkg;
package body wr_fabric_pkg is
......
library ieee;
use ieee.std_logic_1164.all;
use work.wr_fabric_pkg.all;
entity xwrf_reg is
generic(
g_adr_width : integer := 2;
g_dat_width : integer :=16);
port(
rst_n_i : in std_logic;
clk_i : in std_logic;
snk_i : in t_wrf_sink_in;
snk_o : out t_wrf_sink_out;
src_i : in t_wrf_source_in;
src_o : out t_wrf_source_out);
end xwrf_reg;
architecture behav of xwrf_reg is
type t_reg_fsm is (PASS, STALL, FLUSH);
signal state : t_reg_fsm;
signal temp : t_wrf_sink_in;
begin
process(clk_i)
begin
if rising_edge(clk_i) then
snk_o <= src_i;
end if;
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
if(rst_n_i = '0') then
state <= PASS;
src_o <= c_dummy_snk_in;
else
case state is
when PASS =>
if (src_i.stall = '0') then
src_o <= snk_i;
else
temp <= snk_i;
state <= STALL;
end if;
when STALL =>
if (src_i.stall = '0') then
src_o <= temp;
state <= FLUSH;
end if;
when FLUSH =>
if (src_i.stall = '0') then
src_o <= snk_i;
state <= PASS;
else
temp <= snk_i;
state <= STALL;
end if;
end case;
end if;
end if;
end process;
end behav;
......@@ -118,7 +118,8 @@ entity dmtd_with_deglitcher is
tag_o : out std_logic_vector(g_counter_bits-1 downto 0);
-- [clk_sys_i] pulse indicates new phase tag on tag_o
tag_stb_p1_o : out std_logic
tag_stb_p1_o : out std_logic;
dbg_clk_d3_o : out std_logic
);
end dmtd_with_deglitcher;
......@@ -347,6 +348,6 @@ begin -- rtl
pulse_i => new_edge_p,
extended_o => dbg_dmtdout_o);
dbg_clk_d3_o <= clk_i_d3;
end rtl;
......@@ -13,7 +13,11 @@ files = [ "endpoint_private_pkg.vhd",
"ep_rx_oob_insert.vhd",
"ep_rx_early_address_match.vhd",
"ep_clock_alignment_fifo.vhd",
"ep_tx_framer.vhd",
"ep_tx_path.vhd",
"ep_tx_crc_inserter.vhd",
"ep_tx_header_processor.vhd",
"ep_tx_vlan_unit.vhd",
"ep_tx_packet_injection.vhd",
"ep_packet_filter.vhd",
"ep_rx_vlan_unit.vhd",
"ep_ts_counter.vhd",
......@@ -30,6 +34,7 @@ files = [ "endpoint_private_pkg.vhd",
"ep_wishbone_controller.vhd",
"ep_registers_pkg.vhd",
"ep_crc32_pkg.vhd",
"ep_tx_inject_ctrl.vhd",
"endpoint_pkg.vhd",
"wr_endpoint.vhd",
"xwr_endpoint.vhd"
......
......@@ -2,4 +2,4 @@
mkdir -p doc
wbgen2 -D ./doc/wrsw_endpoint.html -C endpoint_regs.h -p ep_registers_pkg.vhd -H record -V ep_wishbone_controller.vhd --cstyle struct --lang vhdl -K ../../sim/endpoint_regs.v ep_wishbone_controller.wb
wbgen2 -D ./doc/wrsw_endpoint_mdio.html -V ep_pcs_tbi_mdio_wb.vhd --cstyle defines --lang vhdl -K ../../sim/endpoint_mdio.v pcs_regs.wb
\ No newline at end of file
wbgen2 -D ./doc/wrsw_endpoint_mdio.html -V ep_pcs_tbi_mdio_wb.vhd --cstyle defines --lang vhdl -K ../../sim/endpoint_mdio.v pcs_regs.wb
This diff is collapsed.
This diff is collapsed.
......@@ -9,7 +9,7 @@ package ep_crc32_pkg is
constant c_CRC32_INIT_VALUE : std_logic_vector(31 downto 0) := x"00000000";
function f_update_crc32_d16(d : std_logic_vector; data_in : std_logic_vector) return std_logic_vector;
function f_update_crc32_d8(d : std_logic_vector; data_in : std_logic_vector) return std_logic_vector;
function f_update_crc32_d8(d : std_logic_vector(31 downto 0); data_in : std_logic_vector(7 downto 0)) return std_logic_vector;
end ep_crc32_pkg;
......@@ -56,8 +56,8 @@ package body ep_crc32_pkg is
end f_update_crc32_d16;
function f_update_crc32_d8(d : std_logic_vector; data_in : std_logic_vector) return std_logic_vector is
variable q : std_logic_vector(d'length-1 downto 0);
function f_update_crc32_d8(d : std_logic_vector(31 downto 0); data_in : std_logic_vector(7 downto 0)) return std_logic_vector is
variable q : std_logic_vector(31 downto 0);
begin
q(7) := not ((not d(31)) xor (not d(25)) xor data_in(7) xor data_in(1));
q(6) := not ((not d(31)) xor (not d(30)) xor (not d(25)) xor (not d(24)) xor data_in(7) xor data_in(6) xor data_in(1) xor data_in(0));
......
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : ep_pcs_tbi_mdio_wb.vhd
-- Author : auto-generated by wbgen2 from pcs_regs.wb
-- Created : Thu Feb 14 10:46:19 2013
-- Created : Thu Aug 1 10:24:16 2013
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE pcs_regs.wb
......
This diff is collapsed.
......@@ -16,8 +16,18 @@ entity ep_rtu_header_extract is
src_fab_o : out t_ep_internal_fabric;
src_dreq_i : in std_logic;
mbuf_is_pause_i : in std_logic;
vlan_class_i : in std_logic_vector(2 downto 0);
vlan_vid_i : in std_logic_vector(11 downto 0);
vlan_tag_done_i : in std_logic;
vlan_is_tagged_i: in std_logic;
rmon_drp_at_rtu_full_o: out std_logic;
rtu_rq_o : out t_ep_internal_rtu_request;
rtu_full_i : in std_logic;
rtu_rq_abort_o : out std_logic;
rtu_rq_valid_o : out std_logic
);
......@@ -27,7 +37,13 @@ architecture rtl of ep_rtu_header_extract is
signal hdr_offset : std_logic_vector(11 downto 0);
signal in_packet : std_logic;
signal in_header : std_logic;
signal rtu_rq_valid_basic : std_logic;
signal rtu_rq_valid_tagged : std_logic;
signal rtu_rq_valid_out : std_logic;
signal rtu_rq_abort : std_logic;
procedure f_extract_rtu(signal q : out std_logic_vector;
signal fab : t_ep_internal_fabric;
signal at_offset : std_logic) is
......@@ -40,7 +56,7 @@ architecture rtl of ep_rtu_header_extract is
begin -- rtl
gen_with_rtu : if(g_with_rtu) generate
p_hdr_offset_sreg : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
......@@ -59,43 +75,76 @@ begin -- rtl
if rst_n_i = '0' then
rtu_rq_o.smac <= (others => '0');
rtu_rq_o.dmac <= (others => '0');
rtu_rq_o.vid <= (others => '0');
rtu_rq_o.has_vid <= '0';
rtu_rq_o.prio <= (others => '0');
rtu_rq_o.has_prio <= '0';
in_packet <= '0';
rtu_rq_valid_basic<= '0';
rmon_drp_at_rtu_full_o <='0';
rtu_rq_abort <= '0';
in_header <= '0';
else
rmon_drp_at_rtu_full_o <='0';
if(snk_fab_i.sof = '1' and rtu_full_i = '0') then
in_packet <= '1';
in_header <= '1';
elsif(snk_fab_i.sof = '1' and rtu_full_i = '1') then
rmon_drp_at_rtu_full_o <='1';
end if;
if(snk_fab_i.eof = '1' or snk_fab_i.error = '1') then
if((snk_fab_i.eof = '1' and snk_fab_i.sof = '0') or -- in case both (sof & eof) are HIGH
snk_fab_i.error = '1') then
in_packet <= '0';
end if;
if(snk_fab_i.error = '1' or rtu_rq_valid_out = '1') then
in_header <= '0';
end if;
f_extract_rtu(rtu_rq_o.dmac(47 downto 32), snk_fab_i, hdr_offset(0));
f_extract_rtu(rtu_rq_o.dmac(31 downto 16), snk_fab_i, hdr_offset(1));
f_extract_rtu(rtu_rq_o.dmac(15 downto 0), snk_fab_i, hdr_offset(2));
f_extract_rtu(rtu_rq_o.smac(47 downto 32), snk_fab_i, hdr_offset(3));
f_extract_rtu(rtu_rq_o.smac(31 downto 16), snk_fab_i, hdr_offset(4));
f_extract_rtu(rtu_rq_o.smac(15 downto 0), snk_fab_i, hdr_offset(5));
if(hdr_offset(5) = '1' and in_packet = '1') then
rtu_rq_valid_o <= '1';
if(snk_fab_i.dvalid = '1' and hdr_offset(6) = '1' and in_packet = '1') then
rtu_rq_valid_basic <='1';
elsif(rtu_rq_valid_out = '1' or -- reset after making request or
snk_fab_i.error = '1') then -- when there is error in the header, so we don't
-- make request for invalid frame which will be dumped
-- in the SWcore (which reads error status).
-- the special case when error occurs when the request
-- is made, we do end with the output of error (below, end of file)
rtu_rq_valid_basic <= '0';
end if;
if(in_packet = '1' and in_header = '0' and -- if we have packet and the header is already processed
snk_fab_i.error = '1' and rtu_rq_abort = '0') then
rtu_rq_abort <= '1';
else
rtu_rq_valid_o <= '0';
rtu_rq_abort <= '0';
end if;
end if;
end if;
end process;
src_fab_o.sof <= snk_fab_i.sof and not rtu_full_i;
rtu_rq_abort_o <= rtu_rq_abort;
src_fab_o.sof <= snk_fab_i.sof and not rtu_full_i; -- null dev
rtu_rq_valid_tagged <= rtu_rq_valid_basic and vlan_tag_done_i;
-- the request is not done for PAUSE frames as they never go outside of Endpoint
-- (they are dropped inside Endpoint)
rtu_rq_valid_out <= (rtu_rq_valid_tagged and (not mbuf_is_pause_i))when (vlan_is_tagged_i = '1') else
(rtu_rq_valid_basic and (not mbuf_is_pause_i));
end generate gen_with_rtu;
gen_without_rtu : if (not g_with_rtu) generate
src_fab_o.sof <= snk_fab_i.sof;
rtu_rq_valid_out <='0';
end generate gen_without_rtu;
snk_dreq_o <= src_dreq_i;
......@@ -107,5 +156,11 @@ begin -- rtl
src_fab_o.data <= snk_fab_i.data;
src_fab_o.addr <= snk_fab_i.addr;
src_fab_o.has_rx_timestamp <= snk_fab_i.has_rx_timestamp;
rtu_rq_o.vid <= vlan_vid_i;
rtu_rq_o.has_vid <= vlan_is_tagged_i;
rtu_rq_o.prio <= vlan_class_i;
rtu_rq_o.has_prio <= vlan_is_tagged_i;
rtu_rq_valid_o <= rtu_rq_valid_out and not snk_fab_i.error;
end rtl;
......@@ -47,7 +47,8 @@ use work.ep_wbgen2_pkg.all;
entity ep_rx_buffer is
generic (
g_size : integer := 1024
g_size : integer := 1024;
g_with_fc : boolean := false
);
port(
clk_sys_i : in std_logic;
......@@ -162,9 +163,10 @@ architecture behavioral of ep_rx_buffer is
signal q_usedw : std_logic_vector(f_log2_size(g_size)-1 downto 0);
signal q_empty : std_logic;
signal q_reset : std_logic;
signal q_wr, q_rd : std_logic;
signal q_rd : std_logic;
signal q_drop : std_logic;
signal q_in_valid, q_out_valid : std_logic;
signal q_aempty, q_afull : std_logic;
signal state : t_write_state;
......@@ -180,7 +182,6 @@ begin
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
q_wr <= '0';
q_drop <= '0';
state <= WAIT_FRAME;
in_prev_addr <= (others => '0');
......@@ -190,11 +191,9 @@ begin
in_prev_addr <= snk_fab_i.addr;
end if;
if(unsigned(q_usedw) = c_drop_threshold) then
if(q_afull = '1') then
q_drop <= '1';
end if;
if(unsigned(q_usedw) = c_release_threshold) then
elsif(q_aempty = '1') then
q_drop <= '0';
end if;
......@@ -217,7 +216,7 @@ begin
end if;
end process;
p_pack_rbuf : process(state, fab_to_encode, in_prev_addr)
p_pack_rbuf : process(state, fab_to_encode, in_prev_addr, q_in, q_in_valid)
begin
f_pack_rbuf_contents(state, fab_to_encode, in_prev_addr, q_in, q_in_valid);
end process;
......@@ -247,7 +246,11 @@ begin
generic map (
g_data_width => 18,
g_size => g_size,
g_with_count => true)
g_with_almost_empty => true,
g_with_almost_full => true,
g_almost_empty_threshold => c_release_threshold,
g_almost_full_threshold => c_drop_threshold,
g_with_count => g_with_fc)
port map (
rst_n_i => q_reset,
clk_i => clk_sys_i,
......@@ -257,8 +260,8 @@ begin
rd_i => q_rd,
empty_o => q_empty,
full_o => open,
almost_empty_o => open,
almost_full_o => open,
almost_empty_o => q_aempty,
almost_full_o => q_afull,
count_o => q_usedw);
......@@ -283,7 +286,7 @@ begin
end if;
end process;
p_unpack : process(q_out, out_cur_addr, q_out_valid)
p_unpack : process(q_out, out_cur_addr, q_out_valid,src_fab_int)
begin
f_unpack_rbuf_contents(q_out, out_cur_addr, q_out_valid, src_fab_int);
end process;
......@@ -291,6 +294,17 @@ begin
src_fab_o <= src_fab_int;
snk_dreq_o <= '1';
level_o <= q_usedw(q_usedw'left downto q_usedw'left - 7);
GEN_FC: if g_with_fc = true generate
GEN_LEV_BIG : if f_log2_size(g_size)-1 > level_o'left generate
level_o <= q_usedw(q_usedw'left downto q_usedw'left - 7);
end generate;
GEN_LEV_SML : if f_log2_size(g_size)-1 < level_o'left+1 generate
level_o(q_usedw'left downto 0) <= q_usedw;
end generate;
end generate;
GEN_NOFC: if g_with_fc = false generate
level_o <= (others=>'X');
end generate;
end behavioral;
......@@ -36,6 +36,7 @@
library ieee;
use ieee.std_logic_1164.all;
use work.wr_fabric_pkg.all;
entity ep_rx_bypass_queue is
generic(
......@@ -84,7 +85,7 @@ architecture behavioral of ep_rx_bypass_queue is
return '1';
end function;
type t_queue_array is array(0 to g_width-1) of std_logic_vector(g_size-1 downto 0);
type t_queue_array is array(0 to g_size-1) of std_logic_vector(g_width-1 downto 0);
signal q_data : t_queue_array;
signal q_valid : std_logic_vector(g_size-1 downto 0);
......@@ -97,6 +98,8 @@ architecture behavioral of ep_rx_bypass_queue is
signal sreg_enable : std_logic;
signal first_word : std_logic_vector(g_width-1 downto 0);
signal oob_in : std_logic;
begin -- behavioral
qempty <= f_queue_occupation(q_valid, '1');
......@@ -104,21 +107,23 @@ begin -- behavioral
empty_o <= qempty;
gen_sreg : for i in 0 to g_width-1 generate
U_sreg : ep_shift_reg
generic map (
g_size => g_size)
port map (
clk_i => clk_i,
ce_i => sreg_enable,
d_i => d_i(i),
q_o => q_o(i));
end generate gen_sreg;
first_word <= q_data(g_size-1) ;
process(clk_i)
begin
if rising_edge(clk_i) then
if(sreg_enable = '1') then
q_data(g_size-1) <= d_i;
L0: for i in 0 to g_size-2 loop
q_data(i) <= q_data(i+1);
end loop L0;
end if;
end if;
end process;
sreg_enable <= '1' when ((valid_i = '1') or (qempty = '0' and (flushing = '1') and valid_int = '1')) else '0';
q_o <= q_data(g_size-1) when (first_word(17 downto 16) = c_WRF_OOB) else q_data(0);
oob_in <= '1' when (first_word(17 downto 16) = c_WRF_OOB and q_valid(0) = '1') else '0';
sreg_enable <= '1' when ((valid_i = '1') or (qempty = '0' and valid_int = '1')) else '0';
p_queue : process(clk_i)
begin
......@@ -137,15 +142,19 @@ begin -- behavioral
valid_mask <= dreq_i;
if sreg_enable = '1' then
q_valid(0) <= valid_i;
q_valid(q_valid'length-1 downto 1) <= q_valid(q_valid'length-2 downto 0);
q_valid(0) <= valid_i;
if(oob_in = '1' ) then -- flashing CRC
q_valid(q_valid'length-1 downto 1) <=(others => '0');
else
q_valid(q_valid'length-1 downto 1) <= q_valid(q_valid'length-2 downto 0);
end if;
end if;
end if;
end if;
end process;
dreq_o <= dreq_i and not (flush_i or flushing);
valid_int <= (qfull and valid_i) or (not qempty and flushing and valid_mask);
dreq_o <= (dreq_i or not qfull ) and not ((flush_i or flushing) and not qempty);
valid_int <= (qfull and valid_i) or (not qempty and (oob_in or flushing) and valid_mask);
valid_o <= valid_int;
end behavioral;
......@@ -180,6 +189,4 @@ begin -- rtl
end if;
end process;
q_o <= sreg(g_size-1);
end rtl;
......@@ -11,6 +11,9 @@ use work.ep_wbgen2_pkg.all;
-- to filter out pause and HP frames in advance.
entity ep_rx_early_address_match is
generic
(
g_early_hp_detection : boolean := false);
port(
clk_sys_i : in std_logic;
clk_rx_i : in std_logic;
......@@ -23,9 +26,19 @@ entity ep_rx_early_address_match is
match_done_o : out std_logic;
match_is_hp_o : out std_logic;
-- indicate that pause was detected
match_is_pause_o : out std_logic;
-- tell quanta (for prio-based pause it is the greatest of all prios)
match_pause_quanta_o : out std_logic_vector(15 downto 0);
-- mask with priorities which shall be PAUSEd
match_pause_prio_mask_o : out std_logic_vector(7 downto 0);
-- once the PAUSE frame is decoded, it requests pausing from SWcore
match_pause_p_o : out std_logic;
regs_i : in t_ep_out_registers
);
......@@ -33,7 +46,7 @@ end ep_rx_early_address_match;
architecture behavioral of ep_rx_early_address_match is
signal hdr_offset : std_logic_vector(11 downto 0);
signal hdr_offset : std_logic_vector(16 downto 0);
signal at_ethertype : std_logic;
signal at_vid : std_logic;
......@@ -43,6 +56,12 @@ architecture behavioral of ep_rx_early_address_match is
signal comb_pcp_matches_hp : std_logic;
signal done_int : std_logic;
signal pause_prio_mask : std_logic_vector(7 downto 0);
signal match_pause_req : std_logic;
signal match_is_pause : std_logic;
signal is_perprio_pause : std_logic;
signal match_pause_quanta : std_logic_vector(15 downto 0);
function f_compare_slv (a : std_logic_vector; b : std_logic_vector) return std_logic is
begin
if(a = b) then
......@@ -78,8 +97,11 @@ begin -- behavioral
if rising_edge(clk_rx_i) then
if rst_n_rx_i = '0' or snk_fab_i.sof = '1' then
pause_match_int <= (others => '0');
match_pause_quanta_o <= (others => '0');
match_is_pause_o <= '0';
match_pause_quanta <= (others => '0');
match_is_pause <= '0';
pause_prio_mask <= (others => '0');
match_pause_req <= '0';
is_perprio_pause <= '0';
else
if(snk_fab_i.dvalid = '1') then
if(hdr_offset(0) = '1') then
......@@ -91,33 +113,63 @@ begin -- behavioral
if(hdr_offset(2) = '1') then
pause_match_int (2) <= f_compare_slv(snk_fab_i.data, x"0001");
end if;
if(hdr_offset(3) = '1') then
pause_match_int (3) <= f_compare_slv(snk_fab_i.data, regs_i.mach_o);
end if;
if(hdr_offset(4) = '1') then
pause_match_int (4) <= f_compare_slv(snk_fab_i.data, regs_i.macl_o(31 downto 16));
end if;
if(hdr_offset(5) = '1') then
pause_match_int (5) <= f_compare_slv(snk_fab_i.data, regs_i.macl_o(15 downto 0));
end if;
-- if(hdr_offset(3) = '1') then
-- pause_match_int (3) <= f_compare_slv(snk_fab_i.data, regs_i.mach_o);
-- end if;
-- if(hdr_offset(4) = '1') then
-- pause_match_int (4) <= f_compare_slv(snk_fab_i.data, regs_i.macl_o(31 downto 16));
-- end if;
-- if(hdr_offset(5) = '1') then
-- pause_match_int (5) <= f_compare_slv(snk_fab_i.data, regs_i.macl_o(15 downto 0));
-- end if;
if(hdr_offset(6) = '1') then
pause_match_int (6) <= f_compare_slv(snk_fab_i.data, x"8808");
pause_match_int (3) <= f_compare_slv(snk_fab_i.data, x"8808");
end if;
if(hdr_offset(7) = '1') then
pause_match_int (7) <= f_compare_slv(snk_fab_i.data, x"0001");
pause_match_int (4) <= f_compare_slv(snk_fab_i.data, x"0001"); -- 802.3 PAUSE
pause_match_int (5) <= f_compare_slv(snk_fab_i.data, x"0101"); -- 802.1Q PAUSE (per-prio)
end if;
if(hdr_offset(8) = '1') then
match_is_pause_o <= f_compare_slv(pause_match_int, x"ff");
match_pause_quanta_o <= snk_fab_i.data;
if(f_compare_slv(pause_match_int, b"0001_1111") = '1') then -- 802.3 PAUSE
match_is_pause <= '1'; -- to indicate that frame shall be dropped
if(regs_i.fcr_rxpause_o = '1') then
match_pause_req <= '1';
match_pause_quanta <= snk_fab_i.data;
pause_prio_mask <= (others => '1');
end if;
elsif(f_compare_slv(pause_match_int, b"0010_1111") = '1') then -- 802.1Q PAUSE (per-prio)
match_is_pause <= '1'; -- to indicate that frame shall be dropped
if(regs_i.fcr_rxpause_802_1q_o = '1') then
pause_prio_mask <= snk_fab_i.data(7 downto 0);
is_perprio_pause <= '1';
end if;
end if;
end if;
if (is_perprio_pause ='1' and ((hdr_offset(16 downto 9) and pause_prio_mask) /= b"0000_0000")) then
if(snk_fab_i.data > match_pause_quanta) then
match_pause_quanta <= snk_fab_i.data;
end if;
end if;
if(hdr_offset(16) = '1' and is_perprio_pause = '1') then
match_pause_req <= '1';
end if;
end if;
end if;
end if;
end process;
match_is_pause_o <= match_is_pause;
match_pause_prio_mask_o <= pause_prio_mask;
match_pause_quanta_o <= match_pause_quanta;
gen_with_early_hp_det: if(g_early_hp_detection) generate
-- ML: the p_match_hp is not used, instead identification of HP is done in RTU
p_match_hp : process(clk_rx_i)
variable index : integer;
begin
......@@ -143,6 +195,11 @@ begin -- behavioral
end if;
end if;
end process;
end generate gen_with_early_hp_det;
gen_without_early_hp_det: if(not g_early_hp_detection) generate
match_is_hp_o <='0';
end generate gen_without_early_hp_det;
p_gen_done : process(clk_rx_i)
begin
......@@ -166,6 +223,14 @@ begin -- behavioral
data_i => done_int,
ppulse_o => match_done_o);
U_sync_pause : gc_sync_ffs
generic map (
g_sync_edge => "positive")
port map (
clk_i => clk_sys_i,
rst_n_i => rst_n_sys_i,
data_i => match_pause_req,
ppulse_o => match_pause_p_o);
end behavioral;
......
This diff is collapsed.
......@@ -99,8 +99,10 @@ entity ep_rx_pcs_16bit is
an_rx_valid_o : out std_logic;
an_idle_match_o : out std_logic;
-- RMON statistic counters
rmon_o : inout t_rmon_triggers
-- RMON events
rmon_rx_overrun : out std_logic;
rmon_rx_inv_code : out std_logic;
rmon_rx_sync_lost : out std_logic
);
end ep_rx_pcs_16bit;
......@@ -440,7 +442,7 @@ begin
rmon_rx_overrun_p_int <= '0';
rmon_invalid_code_p_int <= '0';
timestamp_trigger_p_a_o <= '0';
timestamp_trigger_p_a_o <= '0';
timestamp_pending <= "000";
else -- normal PCS operation
......@@ -725,7 +727,7 @@ begin
clk_i => phy_rx_clk_i,
rst_n_i => reset_synced_rxclk,
pulse_i => rmon_invalid_code_p_int,
extended_o => rmon_o.rx_invalid_code);
extended_o => rmon_rx_inv_code);
U_ext_rmon_2 : gc_extend_pulse
generic map (
......@@ -734,10 +736,10 @@ begin
clk_i => phy_rx_clk_i,
rst_n_i => reset_synced_rxclk,
pulse_i => rmon_rx_overrun_p_int,
extended_o => rmon_o.rx_overrun);
extended_o => rmon_rx_overrun);
-- drive the "RX PCS Sync Lost" event counter
rmon_o.rx_sync_lost <= rx_sync_lost_p and (not mdio_mcr_pdown_i);
rmon_rx_sync_lost <= rx_sync_lost_p and (not mdio_mcr_pdown_i);
pcs_fab_o.rx_timestamp_valid <= timestamp_valid_i;
......
......@@ -105,8 +105,10 @@ entity ep_rx_pcs_8bit is
an_rx_valid_o : out std_logic;
an_idle_match_o : out std_logic;
-- RMON statistic counters
rmon_o : inout t_rmon_triggers
-- RMON events
rmon_rx_overrun : out std_logic;
rmon_rx_inv_code : out std_logic;
rmon_rx_sync_lost : out std_logic
);
end ep_rx_pcs_8bit;
......@@ -196,7 +198,6 @@ architecture behavioral of ep_rx_pcs_8bit is
-- RMON counter pulses
signal rmon_rx_overrun_p_int : std_logic;
signal rmon_syncloss_p_int : std_logic;
signal rmon_invalid_code_p_int : std_logic;
-- Misc. signals
......@@ -829,7 +830,7 @@ begin
clk_i => phy_rx_clk_i,
rst_n_i => reset_synced_rxclk,
pulse_i => rmon_invalid_code_p_int,
extended_o => rmon_o.rx_invalid_code);
extended_o => rmon_rx_inv_code);
U_ext_rmon_2 : gc_extend_pulse
generic map (
......@@ -838,10 +839,10 @@ begin
clk_i => phy_rx_clk_i,
rst_n_i => reset_synced_rxclk,
pulse_i => rmon_rx_overrun_p_int,
extended_o => rmon_o.rx_overrun);
extended_o => rmon_rx_overrun);
-- drive the "RX PCS Sync Lost" event counter
rmon_o.rx_sync_lost <= rx_sync_lost_p and (not mdio_mcr_pdown_i);
rmon_rx_sync_lost <= rx_sync_lost_p and (not mdio_mcr_pdown_i);
end behavioral;
......
......@@ -24,7 +24,7 @@ entity ep_rx_status_reg_insert is
mbuf_is_hp_i : in std_logic;
mbuf_is_pause_i : in std_logic;
rmon_o : out t_rmon_triggers
rmon_pfilter_drop_o : out std_logic
);
end ep_rx_status_reg_insert;
......@@ -58,16 +58,24 @@ begin -- rtl
mbuf_ack_o <= '1' when (mbuf_valid_i = '1' and state = WAIT_MBUF) else '0';
snk_dreq_o <= src_dreq_i and dreq_mask and not snk_fab_i.sof;
-- snk_dreq_o <= src_dreq_i and not snk_fab_i.sof;
p_gen_status : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
rmon_pfilter_drop_o <= '0';
state <= WAIT_FRAME;
dreq_mask <= '1';
sreg.match_class <= (others =>'0');
sreg.is_hp <= '0';
sreg.has_crc <= '0';
sreg.has_smac <= '0';
sreg.error <= '0';
else
case state is
when WAIT_FRAME =>
rmon_pfilter_drop_o <= '0';
if(snk_fab_i.sof = '1') then
state <= WAIT_MBUF;
dreq_mask <= '0';
......@@ -75,11 +83,11 @@ begin -- rtl
when WAIT_MBUF =>
if(mbuf_valid_i = '1') then
rmon_o.rx_pause <= mbuf_is_pause_i;
rmon_o.rx_pfilter_drop <= mbuf_drop_i;
rmon_pfilter_drop_o <= mbuf_drop_i;
if(mbuf_drop_i = '0' and mbuf_is_pause_i = '0') then
state <= GEN_STATUS;
dreq_mask <= '1';
else
state <= WAIT_FRAME;
dreq_mask <= '1';
......@@ -91,12 +99,12 @@ begin -- rtl
sreg.has_smac <= '1';
sreg.error <= '0';
else
rmon_o.rx_pfilter_drop <= '0';
rmon_o.rx_pause <= '0';
rmon_o.rx_path_timing_failure <= '0';
rmon_pfilter_drop_o <= '0';
--rmon_o.rx_path_timing_failure <= '0';
end if;
when GEN_STATUS =>
rmon_pfilter_drop_o <= '0';
if(src_dreq_i = '1') then
state <= WAIT_FRAME;
dreq_mask <= '1';
......
......@@ -23,8 +23,8 @@ entity ep_rx_vlan_unit is
tclass_o : out std_logic_vector(2 downto 0);
vid_o : out std_logic_vector(11 downto 0);
tag_done_o : out std_logic;
is_tagged_o: out std_logic;
rmon_o : inout t_rmon_triggers;
regs_i : in t_ep_out_registers;
regs_o : out t_ep_in_registers
);
......@@ -56,6 +56,7 @@ architecture behavioral of ep_rx_vlan_unit is
signal force_dvalid : std_logic;
signal r_tcar_pcp_map : std_logic_vector(23 downto 0);
signal is_tag_inserted: std_logic;
procedure f_vlan_decision
(tag_type : t_tag_type;
......@@ -137,15 +138,13 @@ architecture behavioral of ep_rx_vlan_unit is
end procedure;
begin -- behavioral
at_ethertype <= hdr_offset(6) and snk_fab_i.dvalid;
at_tpid <= hdr_offset(7) and snk_fab_i.dvalid and is_tagged;
at_vid <= hdr_offset(8) and snk_fab_i.dvalid and is_tagged;
at_tpid <= hdr_offset(6) and snk_fab_i.dvalid and is_tagged;--unused
at_vid <= hdr_offset(7) and snk_fab_i.dvalid and is_tagged;
snk_dreq_o <= src_dreq_i and dreq_mask and not at_ethertype;
snk_dreq_o <= src_dreq_i and dreq_mask;-- and not at_ethertype;
p_decode_tag_type : process(snk_fab_i, is_tagged)
begin
......@@ -170,16 +169,17 @@ begin -- behavioral
if rising_edge(clk_sys_i) then
if rst_n_i = '0' or regs_i.ecr_rx_en_o = '0' then
hdr_offset(hdr_offset'left downto 1) <= (others => '0');
hdr_offset(0) <= '1';
state <= WAIT_FRAME;
dreq_mask <= '0';
hdr_offset(0) <= '1';
state <= WAIT_FRAME;
dreq_mask <= '0';
vid_o <= (others =>'0');
is_tag_inserted <= '0';
is_tagged <= '0';
src_fab_o.eof <= '0';
src_fab_o.error <= '0';
src_fab_o.dvalid <= '0';
else
if(snk_fab_i.error = '1') then
state <= DISCARD_FRAME;
else
......@@ -190,7 +190,9 @@ begin -- behavioral
src_fab_o.eof <= '0';
src_fab_o.error <= '0';
is_tagged <= '0';
is_tag_inserted <= '0';
prio_int <= regs_i.vcr0_prio_val_o;
vid_o <= (others =>'0');
if(snk_fab_i.sof = '1') then
hdr_offset(hdr_offset'left downto 1) <= (others => '0');
......@@ -224,9 +226,9 @@ begin -- behavioral
if(snk_fab_i.data = x"8100") then -- got a 802.1q tagged frame
is_tagged <= '1';
else
if (regs_i.vcr0_qmode_o = c_QMODE_PORT_ACCESS or regs_i.vcr0_qmode_o = c_QMODE_PORT_UNQUALIFIED) then
if (regs_i.vcr0_qmode_o = c_QMODE_PORT_ACCESS) then
prio_int <= regs_i.vcr0_prio_val_o;
is_tag_inserted <= '1';
v_src_fab.dvalid := '0';
v_next_state := INSERT_TAG;
v_dreq_mask := '0';
......@@ -254,7 +256,6 @@ begin -- behavioral
-- or not.
f_vlan_decision(comb_tag_type, regs_i.vcr0_qmode_o, admit, use_pvid, use_fixed_prio);
-- assign the VID
if(admit = '0') then -- oops...
v_next_state := DISCARD_FRAME;
......@@ -264,7 +265,7 @@ begin -- behavioral
v_stored_fab.data(11 downto 0) := regs_i.vcr0_pvid_o;
v_src_fab.data(11 downto 0) := regs_i.vcr0_pvid_o;
end if;
vid_o <= v_src_fab.data(11 downto 0);
-- assign the priority
if(regs_i.vcr0_fix_prio_o = '1' or use_fixed_prio = '1') then
-- Forced priority (or a non-priority tagged frame)? Take the priority
......@@ -280,12 +281,30 @@ begin -- behavioral
hdr_offset <= hdr_offset(hdr_offset'left-1 downto 0) & '0';
end if;
src_fab_o.eof <= v_src_fab.eof;
src_fab_o.dvalid <= v_src_fab.dvalid;
src_fab_o.error <= v_src_fab.error;
src_fab_o.addr <= v_src_fab.addr;
src_fab_o.data <= v_src_fab.data;
src_fab_o.bytesel <= v_src_fab.bytesel;
-- new stuff
if(v_next_state = INSERT_TAG) then
src_fab_o.eof <= '0';
src_fab_o.dvalid <= '1';
src_fab_o.error <= '0';
src_fab_o.addr <= c_WRF_DATA;
src_fab_o.data <= x"8100";
src_fab_o.bytesel <= '0';
else
src_fab_o.eof <= v_src_fab.eof;
src_fab_o.dvalid <= v_src_fab.dvalid;
src_fab_o.error <= v_src_fab.error;
src_fab_o.addr <= v_src_fab.addr;
src_fab_o.data <= v_src_fab.data;
src_fab_o.bytesel <= v_src_fab.bytesel;
end if;
-- old stuff
-- src_fab_o.eof <= v_src_fab.eof;
-- src_fab_o.dvalid <= v_src_fab.dvalid;
-- src_fab_o.error <= v_src_fab.error;
-- src_fab_o.addr <= v_src_fab.addr;
-- src_fab_o.data <= v_src_fab.data;
-- src_fab_o.bytesel <= v_src_fab.bytesel;
dreq_mask <= v_dreq_mask;
stored_fab <= v_stored_fab;
......@@ -323,25 +342,60 @@ begin -- behavioral
if(src_dreq_i = '1') then
-- we are at 7th word from the beginning of the frame, but the sink reception
-- is disabled, so we can insert the original ethertype as the TPID
-- new stuff
if(hdr_offset(7) = '1') then
src_fab_o.addr <= c_WRF_DATA;
src_fab_o.data <= x"8100";
src_fab_o.data <= regs_i.vcr0_prio_val_o & '0' & regs_i.vcr0_pvid_o;
src_fab_o.dvalid <= '1';
vid_o <= regs_i.vcr0_pvid_o; -- use the inserted PVID
dreq_mask <= '0';
stored_fab.bytesel <= snk_fab_i.bytesel;
stored_fab.data <= snk_fab_i.data;
stored_fab.addr <= snk_fab_i.addr;
stored_fab.dvalid <= '1';
end if;
if(hdr_offset(8) = '1') then
src_fab_o.addr <= c_WRF_DATA;
src_fab_o.data <= stored_ethertype;
src_fab_o.dvalid <= '1';
dreq_mask <= '1';
end if;
if(hdr_offset(9) = '1') then
src_fab_o.addr <= c_WRF_DATA;
src_fab_o.data <= regs_i.vcr0_prio_val_o & '0' & regs_i.vcr0_pvid_o;
state <= DATA;
src_fab_o.dvalid <= '1';
src_fab_o.addr <= stored_fab.addr;
src_fab_o.data <= stored_fab.data;
src_fab_o.dvalid <= stored_fab.dvalid;
src_fab_o.bytesel <= stored_fab.bytesel;
dreq_mask <= '1';
state <= DATA;
end if;
-- old stuff
-- if(hdr_offset(7) = '1') then
-- src_fab_o.addr <= c_WRF_DATA;
-- src_fab_o.data <= x"8100";
-- src_fab_o.dvalid <= '1';
-- end if;
--
-- if(hdr_offset(8) = '1') then
-- src_fab_o.addr <= c_WRF_DATA;
-- src_fab_o.data <= regs_i.vcr0_prio_val_o & '0' & regs_i.vcr0_pvid_o;
-- src_fab_o.dvalid <= '1';
-- vid_o <= regs_i.vcr0_pvid_o; -- use the inserted PVID
-- dreq_mask <= '1';
-- end if;
--
-- if(hdr_offset(9) = '1') then
-- src_fab_o.addr <= c_WRF_DATA;
-- src_fab_o.data <= stored_ethertype;
-- src_fab_o.dvalid <= '1';
-- dreq_mask <= '1';
-- state <= DATA;
-- end if;
hdr_offset <= hdr_offset(hdr_offset'left-1 downto 0) & '0';
else
src_fab_o.dvalid <= '0';
......@@ -369,6 +423,7 @@ begin -- behavioral
if(rst_n_i = '0' or regs_i.ecr_rx_en_o = '0' or snk_fab_i.sof = '1')then
tag_done_o <= '0';
tclass_o <= "000";
elsif(hdr_offset(9) = '1') then
-- we're already after the headers, so prio_int is
-- certainly valid
......@@ -382,14 +437,15 @@ begin -- behavioral
when "101" => tclass_o <= r_tcar_pcp_map(17 downto 15);
when "110" => tclass_o <= r_tcar_pcp_map(20 downto 18);
when "111" => tclass_o <= r_tcar_pcp_map(23 downto 21);
when others => tclass_o <= "XXX"; -- packet probably contains porn
when others => tclass_o <= "000";--"XXX"; -- packet probably contains porn
end case;
end if;
end if;
end process;
src_fab_o.sof <= regs_i.ecr_rx_en_o and snk_fab_i.sof;
is_tagged_o <= is_tagged or is_tag_inserted;
end behavioral;
......
......@@ -68,7 +68,9 @@ begin -- behavioral
end generate;
gen_nocyc_on_stall: if g_cyc_on_stall = false generate
snk_dreq_o <= '1' when (src_wb_i.stall = '0' and state /= FINISH_CYCLE and snk_fab_i.eof = '0' and snk_fab_i.error = '0' and snk_fab_i.sof = '0' and enter_idle = '0') else '0';
-- snk_dreq_o <= '1' when (src_wb_i.stall = '0' and state /= FINISH_CYCLE and snk_fab_i.eof = '0' and snk_fab_i.error = '0' and snk_fab_i.sof = '0' and enter_idle = '0') else '0';
-- snk_dreq_o <= '1' when (src_wb_i.stall = '0' and state /= FINISH_CYCLE and snk_fab_i.eof = '0' and snk_fab_i.error = '0' and enter_idle = '0') else '0';
snk_dreq_o <= '1' when (src_wb_i.stall = '0' and state /= FINISH_CYCLE and snk_fab_i.eof = '0' and snk_fab_i.error = '0') else '0';
end generate;
p_count_acks : process(clk_sys_i)
......
-------------------------------------------------------------------------------
-- Title : 1000base-X MAC/Endpoint
-- Project : White Rabbit
-------------------------------------------------------------------------------
-- File : ep_tx_crc_inserter.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN BE-CO-HT
-- Created : 2009-06-22
-- Last update: 2012-11-15
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Calculates and embeds the CRC into the transmitted frame.
-------------------------------------------------------------------------------
--
-- Copyright (c) 2009-2012 CERN / BE-CO-HT
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.gencores_pkg.all;
use work.wr_fabric_pkg.all;
use work.endpoint_private_pkg.all;
use work.ep_wbgen2_pkg.all;
use work.ep_crc32_pkg.all;
entity ep_tx_crc_inserter is
generic(
g_use_new_crc : boolean := false);
port (
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
snk_fab_i : in t_ep_internal_fabric;
snk_dreq_o : out std_logic;
src_fab_o : out t_ep_internal_fabric;
src_dreq_i : in std_logic;
dbg_o : out std_logic_vector(2 downto 0)
);
end ep_tx_crc_inserter;
architecture behavioral of ep_tx_crc_inserter is
type t_state is (IDLE, WAIT_CRC, EMBED_1, EMBED_2, EMBED_3);
-- general signals
signal state : t_state;
-- CRC generator signals
signal crc_gen_reset : std_logic;
signal crc_gen_enable : std_logic;
signal crc_value : std_logic_vector(31 downto 0);
signal odd_length : std_logic;
signal embed_valid, embed_eof : std_logic;
signal stored_msb : std_logic_vector(7 downto 0);
signal in_payload : std_logic;
signal src_dreq_d0 : std_logic;
signal crc_p_value, crc_n_value : std_logic_vector(31 downto 0);
--signal crc_next, crc_new : std_logic_vector(31 downto 0);
begin -- behavioral
dbg_o <= "111" when (state = IDLE) else
"110" when (state = WAIT_CRC) else
"101" when (state = EMBED_1) else
"100" when (state = EMBED_2) else
"011" when (state = EMBED_3) else
"000";
in_payload <= '1' when (state = IDLE or state = WAIT_CRC) else '0';
-- ML: potential optimization (if desperate)
-- in_payload <= '1' when (state = IDLE or state = WAIT_CRC) or (src_dreq_d0 = '1' and odd_length = '0' and state = EMBED_2)) else '0';
crc_gen_reset <= '1' when rst_n_i = '0' or snk_fab_i.sof = '1' else '0';
crc_gen_enable <= '1' when (snk_fab_i.dvalid = '1' and in_payload = '1') else '0';
gen_old_crc: if(g_use_new_crc = false) generate
U_tx_crc_generator : gc_crc_gen
generic map (
g_polynomial => x"04C11DB7",
g_init_value => x"ffffffff",
g_residue => x"38fb2284",
g_data_width => 16,
g_half_width => 8,
g_sync_reset => 1,
g_dual_width => 1,
g_registered_match_output => false,
g_registered_crc_output => true)
port map (
clk_i => clk_sys_i,
rst_i => crc_gen_reset,
en_i => crc_gen_enable,
half_i => snk_fab_i.bytesel,
data_i => snk_fab_i.data,
match_o => open,
crc_o => crc_value);
end generate;
gen_new_crc: if(g_use_new_crc = true) generate
p_check_crc_p: process(clk_sys_i)
begin
if falling_edge(clk_sys_i) then
if(crc_gen_reset = '1')then
crc_n_value <= c_CRC32_INIT_VALUE;
elsif(crc_gen_enable = '1') then
crc_n_value <= f_update_crc32_d8(crc_p_value, snk_fab_i.data(15 downto 8));
end if;
end if;
end process;
p_check_crc_n: process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if(crc_gen_reset = '1') then
crc_p_value <= c_CRC32_INIT_VALUE;
elsif(crc_gen_enable = '1' and snk_fab_i.bytesel = '0') then
crc_p_value <= f_update_crc32_d8(crc_n_value, snk_fab_i.data(7 downto 0));
end if;
end if;
end process;
crc_value <= crc_p_value when odd_length = '0' else
crc_n_value;
end generate;
p_delay_dreq: process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
src_dreq_d0 <= src_dreq_i;
end if;
end process;
p_crc_fsm : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if(rst_n_i = '0' or snk_fab_i.error = '1') then
state <= IDLE;
embed_eof <= '0';
else
case state is
when IDLE =>
embed_eof <= '0';
odd_length <= '0';
if(snk_fab_i.sof = '1') then
state <= WAIT_CRC;
end if;
when WAIT_CRC =>
if(snk_fab_i.bytesel = '1') then
odd_length <= '1';
stored_msb <= snk_fab_i.data(15 downto 8);
end if;
if(snk_fab_i.eof = '1' or snk_fab_i.addr = c_WRF_OOB) then
state <= EMBED_1;
end if;
when EMBED_1 =>
if(src_dreq_d0 = '1') then
state <= EMBED_2;
end if;
when EMBED_2 =>
if(src_dreq_d0 = '1') then
if(odd_length = '1') then
state <= EMBED_3;
else
state <= IDLE;
embed_eof <= '1';
end if;
end if;
when EMBED_3 =>
if(src_dreq_d0 = '1') then
state <= IDLE;
embed_eof <= '1';
end if;
end case;
end if;
end if;
end process;
p_drive_data_addr : process(state, crc_value, odd_length, stored_msb, snk_fab_i, src_dreq_d0)
begin
case state is
when EMBED_1 =>
if(odd_length = '1') then
src_fab_o.data <= stored_msb & crc_value(31 downto 24);
src_fab_o.addr <= c_WRF_DATA;
src_fab_o.bytesel <= '0';
src_fab_o.dvalid <= src_dreq_d0;
src_fab_o.eof <= '0';
else
src_fab_o.data <= crc_value(31 downto 16);
src_fab_o.addr <= c_WRF_DATA;
src_fab_o.bytesel <= '0';
src_fab_o.dvalid <= src_dreq_d0;
src_fab_o.eof <= '0';
end if;
when EMBED_2 =>
if(odd_length = '1') then
src_fab_o.data <= crc_value(23 downto 8);
src_fab_o.addr <= c_WRF_DATA;
src_fab_o.bytesel <= '0';
src_fab_o.dvalid <= src_dreq_d0;
src_fab_o.eof <= '0';
else
src_fab_o.data <= crc_value(15 downto 0);
src_fab_o.addr <= c_WRF_DATA;
src_fab_o.bytesel <= '0';
src_fab_o.dvalid <= src_dreq_d0;
src_fab_o.eof <= '1';
end if;
when EMBED_3 =>
src_fab_o.data <= crc_value(7 downto 0) & "XXXXXXXX";
src_fab_o.addr <= c_WRF_DATA;
src_fab_o.bytesel <= '1';
src_fab_o.dvalid <= src_dreq_d0;
src_fab_o.eof <= '1';
when others =>
src_fab_o.data <= snk_fab_i.data;
src_fab_o.addr <= snk_fab_i.addr;
src_fab_o.bytesel <= '0';
src_fab_o.dvalid <= snk_fab_i.dvalid and not snk_fab_i.bytesel;
src_fab_o.eof <= '0';
end case;
src_fab_o.addr <= c_WRF_DATA;
end process;
snk_dreq_o <= src_dreq_i and in_payload;
src_fab_o.sof <= snk_fab_i.sof;
src_fab_o.error <= snk_fab_i.error;
end behavioral;
......@@ -113,6 +113,7 @@ entity ep_tx_framer is
-- Control registers
-------------------------------------------------------------------------------
ep_ctrl_i : in std_logic;
regs_i : in t_ep_out_registers
);
......@@ -172,8 +173,8 @@ architecture behavioral of ep_tx_framer is
signal stall_int : std_logic;
signal stall_int_d0 : std_logic;
signal untagging : std_logic;
signal got_error : std_logic;
signal got_error : std_logic;
signal tx_en : std_logic;
function b2s (x : boolean)
return std_logic is
......@@ -299,8 +300,7 @@ begin -- behavioral
error_p1 <= snk_valid and b2s(snk_i.adr = c_WRF_STATUS) and decoded_status.error;
abort_now <= '1' when (state /= TXF_IDLE and state /= TXF_GAP) and (regs_i.ecr_tx_en_o = '0' or error_p1 = '1') else '0';
abort_now <= '1' when (state /= TXF_IDLE and state /= TXF_GAP) and (tx_en = '0' or error_p1 = '1') else '0';
p_store_status : process(clk_sys_i)
begin
......@@ -419,7 +419,7 @@ begin -- behavioral
-- Check start-of-frame and send-pause signals and eventually
-- commence frame transmission
if(pcs_dreq_i = '1' and (sof_p1 = '1' or fc_pause_p_i = '1') and regs_i.ecr_tx_en_o = '1') then
if(pcs_dreq_i = '1' and (sof_p1 = '1' or fc_pause_p_i = '1') and tx_en = '1') then
-- enable writing to PCS FIFO
q_sof <= '1';
write_mask <= '1';
......@@ -741,8 +741,9 @@ begin -- behavioral
end if;
end process;
stall_int <= (not (pcs_dreq_i and tx_ready) and regs_i.ecr_tx_en_o) or (snk_i.cyc xor snk_cyc_d0); -- /dev/null if disabled
tx_en <= regs_i.ecr_tx_en_o and ep_ctrl_i;
stall_int <= (not (pcs_dreq_i and tx_ready) and tx_en) or (snk_i.cyc xor snk_cyc_d0); -- /dev/null if disabled
snk_out.stall <= stall_int;
......
-------------------------------------------------------------------------------
-- Title : Controller of
-- Project : White Rabbit MAC/Endpoint
-------------------------------------------------------------------------------
-- File : ep_tx_inject_ctrl.vhd
-- Author : Maciej Lipinski
-- Company : CERN BE-CO-HT
-- Created : 2014-01-16
-- Last update: 2014-01-16
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: this module enables to control HW packet injection in order
-- to turn the Endpoint into simple traffic generator for testing purposes
-------------------------------------------------------------------------------
--
-- Copyright (c) 2014 CERN / BE-CO-HT
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.wr_fabric_pkg.all;
use work.endpoint_private_pkg.all;
use work.ep_wbgen2_pkg.all;
entity ep_tx_inject_ctrl is
generic(
g_min_if_gap_length : integer
);
port (
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
snk_fab_i : in t_ep_internal_fabric;
snk_dreq_o : out std_logic;
src_fab_o : out t_ep_internal_fabric;
src_dreq_i : in std_logic;
inject_req_o : out std_logic;
inject_ready_i : in std_logic;
inject_packet_sel_o : out std_logic_vector(2 downto 0);
inject_user_value_o : out std_logic_vector(15 downto 0);
inject_ctr_ena_o : out std_logic;
inject_ctr_mode_o : out std_logic_vector(1 downto 0);
regs_i : in t_ep_out_registers;
regs_o : out t_ep_in_registers
);
end ep_tx_inject_ctrl;
architecture rtl of ep_tx_inject_ctrl is
-- there a lag between setting inject_req and SOF, this nees to be included
constant if_gap_offset : unsigned(15 downto 0) := x"0000"; -- unused
constant src_fab_null : t_ep_internal_fabric := (
sof => '0',
eof => '0',
error => '0',
dvalid => '0',
bytesel => '0',
has_rx_timestamp => '0',
rx_timestamp_valid => '0',
data => (others => '0'),
addr => (others => '0'));
type t_state is (IDLE, INJECT_REQ, INJECT, IFG, END_GEN);
-- Wishbone settings
signal if_gap_value : unsigned(15 downto 0);
signal pck_sel : std_logic_vector(2 downto 0);
signal gen_ena : std_logic;
signal inj_mode : std_logic_vector(1 downto 0);
signal if_gap_cnt : unsigned(15 downto 0);
signal frame_id_cnt : unsigned(15 downto 0);
signal within_packet : std_logic;
signal state : t_state;
-- translation betwen if_gap_value and real IFG:
-- | ----------------------------------------- |
-- | if_gap_value | gap in words | gap in time |
-- | 0 | 7 | 112 ns | disallowed
-- | ......................................... |
-- | 5 | 12 | 192 ns | minimal leagal
-- | 6 | 13 | 208 ns |
-- | ......................................... |
-- | 65536 | 65546 | 1.048ms | maximum allowed due to register size (16 bits)
-- | ----------------------------------------- |
begin -- rtl
p_detect_within : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
within_packet <= '0';
else
if(snk_fab_i.sof = '1')then
within_packet <= '1';
elsif(snk_fab_i.eof = '1' or snk_fab_i.error = '1') then
within_packet <= '0';
end if;
end if;
end if;
end process;
p_config_reg: process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
if_gap_value <= (others=>'0');
pck_sel <= (others=>'0');
gen_ena <= '0';
inj_mode <= (others=>'0');
else
if(regs_i.inj_ctrl_pic_ena_load_o = '1') then -- writing the register
if (regs_i.inj_ctrl_pic_conf_valid_o = '1') then
if_gap_value <= unsigned(regs_i.inj_ctrl_pic_conf_ifg_o);
pck_sel <= regs_i.inj_ctrl_pic_conf_sel_o;
end if;
if(regs_i.inj_ctrl_pic_mode_valid_o = '1') then
inj_mode <= regs_i.inj_ctrl_pic_mode_id_o(1 downto 0);
end if;
gen_ena <= regs_i.inj_ctrl_pic_ena_o;
end if;
end if;
end if;
end process;
p_ctrl_fsm : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
state <= IDLE;
inject_req_o <= '0';
if_gap_cnt <= (others => '0');
frame_id_cnt <= (others => '0');
else
case state is
when IDLE =>
-- start when
-- 1) inject enabled, and
-- 2) no packet being received from SWcore and
-- 3) no packet being just started (otherwise, we could have two SOFs
if(gen_ena = '1' and within_packet = '0' and snk_fab_i.sof = '0') then
inject_req_o <= '1';
if_gap_cnt <= if_gap_offset;
frame_id_cnt <= (others => '0');
state <= INJECT_REQ;
end if;
when INJECT_REQ =>
inject_req_o <= '0';
state <= INJECT;
when INJECT =>
if(inject_ready_i = '1') then
frame_id_cnt <= frame_id_cnt + 1;
state <= IFG;
end if;
when IFG =>
if(gen_ena = '0' ) then --gen disabled
if_gap_cnt <= (others => '0');
frame_id_cnt <= (others => '0');
if(within_packet = '0') then -- if there is no frame being currently dumped
state <= IDLE; -- go to idle state
else -- if there is a frame being dumped,
state <= END_GEN; -- wait until it finishes
end if;
elsif(if_gap_cnt < if_gap_value) then
if_gap_cnt <= if_gap_cnt + 1;
else
inject_req_o <= '1';
if_gap_cnt <= if_gap_offset;
state <= INJECT_REQ;
end if;
when END_GEN =>
if(within_packet = '0') then -- now we can gracefully come back to normal functing
state <= IDLE;
end if;
when others =>
state <= IDLE;
if_gap_cnt <= (others => '0');
frame_id_cnt <= (others => '0');
end case;
end if;
end if;
end process;
inject_user_value_o <= std_logic_vector(frame_id_cnt);
inject_packet_sel_o <= pck_sel;
inject_ctr_ena_o <= gen_ena;
inject_ctr_mode_o <= inj_mode;
snk_dreq_o <= src_dreq_i when (state = IDLE) else '1'; -- dev/null if gen
src_fab_o <= snk_fab_i when (state = IDLE) else src_fab_null;-- dev/null if gen
regs_o.inj_ctrl_pic_conf_ifg_i <= std_logic_vector(if_gap_value);
regs_o.inj_ctrl_pic_conf_sel_i <= pck_sel;
regs_o.inj_ctrl_pic_conf_valid_i <= '0';
regs_o.inj_ctrl_pic_ena_i <= gen_ena;
regs_o.inj_ctrl_pic_mode_id_i <= '0' & inj_mode;
end rtl;
-------------------------------------------------------------------------------
-- Title : 1000base-X MAC/Endpoint - TX packet injection unit
-- Project : White Rabbit
-------------------------------------------------------------------------------
-- File : ep_tx_packet_injection.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN BE-CO-HT
-- Created : 2012-11-01
-- Last update: 2013-03-12
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Asynchronously sends pre-defined packets upon a hardware request.
-- Packet contents are defined in a buffer accessible via Wishbone. The buffer
-- is shared with the TX VLAN unit and can contain templates of up to 8 packets
-- of up to 128 bytes of size. It is possible to replace a selected 16-bit word
-- within each template with a user-provided value.
-------------------------------------------------------------------------------
--
-- Copyright (c) 2012 CERN
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2012-11-01 1.0 twlostow Created
-- 2013-03-12 1.1 mlipinsk added empty-template protaciton
-- prepared signals for RMON
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.endpoint_private_pkg.all;
entity ep_tx_packet_injection is
port
(
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
snk_fab_i : in t_ep_internal_fabric;
snk_dreq_o : out std_logic;
src_fab_o : out t_ep_internal_fabric;
src_dreq_i : in std_logic;
inject_req_i : in std_logic;
inject_ready_o : out std_logic;
inject_packet_sel_i : in std_logic_vector(2 downto 0);
inject_user_value_i : in std_logic_vector(15 downto 0);
inject_mode_i : in std_logic_vector(1 downto 0);
-- 0 : default
-- 1 : corrupt
-- 2 : unused
-- 3 : unused
mem_addr_o : out std_logic_vector(9 downto 0);
mem_data_i : in std_logic_vector(17 downto 0)
);
end ep_tx_packet_injection;
architecture rtl of ep_tx_packet_injection is
type t_state is (WAIT_IDLE, SOF, DO_INJECT, EOF);
alias template_last : std_logic is mem_data_i(16);
alias template_first : std_logic is mem_data_i(16);
alias template_user : std_logic is mem_data_i(17);
signal state : t_state;
signal counter : unsigned(8 downto 0);
signal within_packet : std_logic;
signal select_inject : std_logic;
signal inj_src : t_ep_internal_fabric;
signal inject_req_latched : std_logic;
signal first_word : std_logic; -- ML: used for masking the first word (we use the
-- same bit for SOF and EOF
-- ML: singals for RMON counters
signal no_template_error : std_logic; -- ML: indicates that injection was attempted with no valid template
signal inject_done : std_logic; -- ML: indicates that requrested injection was successful
begin -- rtl
snk_dreq_o <= '0' when (state = DO_INJECT) else src_dreq_i;
inject_done <= '1' when (state = EOF and src_dreq_i = '1') else '0';
p_detect_within : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
within_packet <= '0';
else
if(snk_fab_i.sof = '1')then
within_packet <= '1';
end if;
if(snk_fab_i.eof = '1' or snk_fab_i.error = '1') then
within_packet <= '0';
end if;
end if;
end if;
end process;
p_injection_request_ready : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
inject_ready_o <= '1';
inject_req_latched <= '0';
else
if(inject_req_i = '1') then
inject_ready_o <= '0';
inject_req_latched <= '1';
elsif(state = EOF and src_dreq_i = '1' ) then
inject_ready_o <= '1';
inject_req_latched <= '0';
elsif(no_template_error = '1') then
inject_ready_o <= '1';
inject_req_latched <= '0';
end if;
end if;
end if;
end process;
p_injection_fsm : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
state <= WAIT_IDLE;
select_inject <= '0';
no_template_error <= '0';
inj_src.sof <= '0';
inj_src.eof <= '0';
inj_src.dvalid <= '0';
inj_src.error <= '0';
first_word <= '0';
else
case state is
when WAIT_IDLE =>
inj_src.sof <= '0';
inj_src.eof <= '0';
inj_src.dvalid <= '0';
inj_src.error <= '0';
no_template_error <= '0';
first_word <= '0';
if(inject_req_i = '1') then --ML: we make sure that we remember the packet_sel_i
-- only when req_i HIGH
counter(8 downto 6) <= unsigned(inject_packet_sel_i);
counter(5 downto 0) <= (others => '0');
end if;
if(within_packet = '0' and inject_req_latched = '1' and no_template_error = '0') then
state <= SOF;
select_inject <= '1';
else
select_inject <= '0';
end if;
when SOF =>
if(template_first = '0') then -- ML: check that the first word is valid, abort if error
state <= WAIT_IDLE;
no_template_error <= '1';
elsif(src_dreq_i = '1') then
first_word <= '1'; -- since the same bit is for SOF and EOF, we need to mask SOF
-- during first word
inj_src.sof <= '1';
state <= DO_INJECT;
end if;
when DO_INJECT =>
inj_src.sof <= '0';
if(src_dreq_i = '1') then
inj_src.dvalid <= '1';
counter <= counter + 1;
else
inj_src.dvalid <= '0';
end if;
if(first_word = '1' and template_first = '0') then -- ML: first word read
first_word <= '0';
end if;
if(template_last = '1' and inj_src.dvalid = '1' and first_word = '0' and src_dreq_i = '1') then
inj_src.dvalid <= '0';
state <= EOF;
if(inject_mode_i = "01") then
inj_src.error <= '1';
else
inj_src.eof <= '1';
end if;
end if;
when EOF =>
inj_src.eof <= '0';
inj_src.error <= '0';
if(src_dreq_i = '1') then
state <= WAIT_IDLE;
select_inject <= '0';
end if;
end case;
end if;
end if;
end process;
-- inj_src.bytesel <= '0';
-- the last word cannot be user-defined as we use the user bit to indicate odd size
inj_src.bytesel <= template_user when (template_last = '1' and first_word = '0') else '0';
-- inj_src.error <= '0';
p_inj_src_data : process(template_user, inject_user_value_i, mem_data_i,template_last,first_word)
begin
if(template_user = '1' and template_last = '0' and first_word = '0') then
inj_src.data <= inject_user_value_i;
else
inj_src.data <= mem_data_i(15 downto 0);
end if;
end process;
src_fab_o <= inj_src when select_inject = '1' else snk_fab_i;
mem_addr_o <= '1' & std_logic_vector(counter);
end rtl;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -124,7 +124,7 @@ entity xwr_softpll_ng is
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
debug_o : out std_logic_vector(3 downto 0);
debug_o : out std_logic_vector(5 downto 0);
dbg_fifo_irq_o : out std_logic
);
......@@ -173,7 +173,7 @@ architecture wrapper of xwr_softpll_ng is
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
wb_irq_o : out std_logic;
debug_o : out std_logic_vector(3 downto 0);
debug_o : out std_logic_vector(5 downto 0);
dbg_fifo_irq_o : out std_logic);
end component;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
target = "xilinx"
action = "simulation"
files = "main.sv"
fetchto = "../../../ip_cores"
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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