Skip to content
Snippets Groups Projects
Commit d5b78f4d authored by Maciej Lipinski's avatar Maciej Lipinski
Browse files

[TRU] Marker Protocol conversation switch-over between different ports

parent 34c5ea56
Branches
Tags
No related merge requests found
......@@ -6,7 +6,7 @@
-- Author : Maciej Lipinski
-- Company : CERN BE-CO-HT
-- Created : 2012-09-10
-- Last update: 2012-09-13
-- Last update: 2013-08-01
-- Platform : FPGA-generic
-- Standard : VHDL'87
-------------------------------------------------------------------------------
......@@ -81,27 +81,190 @@ end tru_trans_lacp_dist;
architecture rtl of tru_trans_lacp_dist is
signal s_ep : t_trans2ep;
signal s_sw : t_trans2sw;
type t_tru_trans_state is(S_IDLE,
S_WAIT_RESP_MARKER,
S_TRANSITIONED);
signal s_tru_trans_state : t_tru_trans_state;
signal s_start_transition : std_logic;
signal s_portA_frame_cnt : unsigned(integer(CEIL(LOG2(real(g_mt_trans_max_fr_cnt-1)))) -1 downto 0);
signal s_portB_frame_cnt : unsigned(integer(CEIL(LOG2(real(g_mt_trans_max_fr_cnt-1)))) -1 downto 0);
signal s_statTransActive : std_logic;
signal s_statTransFinished : std_logic;
signal s_port_A_mask : std_logic_vector(g_num_ports-1 downto 0);
signal s_port_B_mask : std_logic_vector(g_num_ports-1 downto 0);
signal s_port_A_prio : std_logic_vector(g_prio_width-1 downto 0);
signal s_port_B_prio : std_logic_vector(g_prio_width-1 downto 0);
signal s_port_A_has_prio : std_logic;
signal s_port_B_has_prio : std_logic;
signal s_port_prio_mask : std_logic_vector(2**g_prio_width-1 downto 0);
signal s_ep_ctr_A : t_trans2ep;
signal s_ep_ctr_B : t_trans2ep;
signal s_ep_zero : t_trans2ep;
signal s_sw_ctrl : t_trans2sw;
begin --rtl
-- TODO
statTransActive_o <= '0';
statTransFinished_o <= '0';
tru_tab_bank_o <= '0';
s_ep.pauseSend <= '0';
s_ep.pauseTime <= (others => '0');
s_sw.blockTime <= (others => '0');
s_sw.blockQueuesMask <= (others => '0');
s_sw.blockPortsMask <= (others => '0');
s_sw.blockReq <= '0';
-- to make code less messy - start transition only it is enabled by config and all necessary
-- config is valid
s_start_transition <= config_i.tcr_trans_ena and
config_i.tcr_trans_port_a_valid and
config_i.tcr_trans_port_b_valid;
-- generating mask with 1 at the priority for with we perform transition (configured value)
-- TODO: we would need more options here
G_PRIO_MASK: for i in 0 to 2**g_prio_width-1 generate
s_port_prio_mask(i) <= '1' when(i = to_integer(unsigned(config_i.tcr_trans_prio))) else '0';
end generate G_PRIO_MASK;
-- generating mask with 1 at the port to which we transition ... TODO: we need more then one
G_MASK: for i in 0 to g_num_ports-1 generate
s_port_A_mask(i) <= '1' when (i = to_integer(unsigned(config_i.tcr_trans_port_a_id)) and config_i.tcr_trans_port_a_valid ='1') else '0';
s_port_B_mask(i) <= '1' when (i = to_integer(unsigned(config_i.tcr_trans_port_b_id)) and config_i.tcr_trans_port_b_valid ='1') else '0';
end generate G_MASK;
-- preparing masks
s_sw_ctrl.blockPortsMask(g_num_ports-1 downto 0) <= s_port_B_mask;
s_sw_ctrl.blockQueuesMask(2**g_prio_width-1 downto 0) <= s_port_prio_mask;
-- filling in not-used bits
s_sw_ctrl.blockPortsMask(s_sw_ctrl.blockPortsMask'length -1 downto g_num_ports) <= (others =>'0');
s_sw_ctrl.blockQueuesMask(s_sw_ctrl.blockQueuesMask'length-1 downto 2**g_prio_width) <= (others =>'0');
-- an empty entry
s_ep_zero.pauseSend <= '0';
s_ep_zero.pauseTime <= (others => '0');
s_ep_zero.outQueueBlockMask <= (others => '0');
s_ep_zero.outQueueBlockReq <= '0';
s_ep_zero.hwframe_fwd <= '0';
s_ep_zero.hwframe_blk <= '0';
TRANS_FSM: process(clk_i, rst_n_i)
begin
if rising_edge(clk_i) then
if(rst_n_i = '0') then
s_tru_trans_state <= S_IDLE;
s_statTransActive <= '0';
s_statTransFinished <= '0';
tru_tab_bank_o <= '0';
s_ep_ctr_A <= s_ep_zero;
s_ep_ctr_B <= s_ep_zero;
s_sw_ctrl.blockTime <= (others => '0');
s_sw_ctrl.blockReq <= '0';
else
case s_tru_trans_state is
--====================================================================================
when S_IDLE =>
--====================================================================================
s_portA_frame_cnt <= (others => '0');
s_portB_frame_cnt <= (others => '0');
s_statTransActive <= '0';
s_sw_ctrl.blockTime <= (others => '0');
s_sw_ctrl.blockReq <= '0';
-- new transition is not started until the previous has been cleared/finished
if(s_start_transition = '1' and s_statTransFinished ='0' and s_statTransActive = '0') then --
s_tru_trans_state <= S_WAIT_RESP_MARKER;
s_portA_frame_cnt <= (others => '0');
s_portB_frame_cnt <= (others => '0');
s_statTransActive <= '1'; -- indicate that transition is active (goes to the WBgen
-- status reg read by SW)
s_statTransFinished <= '0';
-- block Port_B
s_sw_ctrl.blockReq <= '1';
s_sw_ctrl.blockTime <= config_i.tcr_trans_block_time;
-- change distribution
tru_tab_bank_o <= '1'; -- request bank swap of TRU TAB
end if;
--====================================================================================
when S_WAIT_RESP_MARKER => -- block the output queue of port_B and wait to receive
-- Marker Response on port_A
--====================================================================================
tru_tab_bank_o <= '0';
s_sw_ctrl.blockReq <= '0';
-- Marker Response on port A detected, can unblock the port
if((s_port_A_mask and rxFrameMask_i) = s_port_A_mask) then
s_tru_trans_state <= S_TRANSITIONED;
-- stop pause
s_sw_ctrl.blockReq <= '1';
s_sw_ctrl.blockTime <= (others => '0');
end if;
--====================================================================================
when S_TRANSITIONED => -- swap banks (assuming proper config in the TRU TAB)
--====================================================================================
-- transition: done
s_tru_trans_state <= S_IDLE;
s_portA_frame_cnt <= (others => '0');
s_portB_frame_cnt <= (others => '0');
s_statTransActive <= '0';
s_statTransFinished <= '1';
tru_tab_bank_o <= '0';
s_sw_ctrl.blockReq <= '1';
--====================================================================================
when others =>
--====================================================================================
s_portA_frame_cnt <= (others => '0');
s_portB_frame_cnt <= (others => '0');
s_statTransActive <= '0';
s_statTransFinished <= '0';
s_tru_trans_state <= S_IDLE;
end case;
-- clearing of finished bit by configuration
if(s_statTransFinished = '1' and s_statTransActive ='1' and config_i.tcr_trans_clr = '1') then
s_statTransFinished <= '0';
end if;
end if;
end if;
end process;
statTransActive_o <= s_statTransActive;
statTransFinished_o <= s_statTransFinished;
sw_o <= s_sw_ctrl;
-- MUX of Port A/B control (outputs) to appropraite ports
EP_OUT: for i in 0 to g_num_ports-1 generate
ep_o(i) <= s_ep;
ep_o(i)<= s_ep_ctr_A when (i = to_integer(unsigned(config_i.tcr_trans_port_a_id))) else
s_ep_ctr_B when (i = to_integer(unsigned(config_i.tcr_trans_port_b_id))) else
s_ep_zero;
end generate EP_OUT;
sw_o <= s_sw;
-- -- TODO
--
-- statTransActive_o <= '0';
-- statTransFinished_o <= '0';
-- tru_tab_bank_o <= '0';
-- s_ep.pauseSend <= '0';
-- s_ep.pauseTime <= (others => '0');
-- s_sw.blockTime <= (others => '0');
-- s_sw.blockQueuesMask <= (others => '0');
-- s_sw.blockPortsMask <= (others => '0');
-- s_sw.blockReq <= '0';
--
-- EP_OUT: for i in 0 to g_num_ports-1 generate
-- ep_o(i) <= s_ep;
-- end generate EP_OUT;
--
-- sw_o <= s_sw;
end rtl;
This diff is collapsed.
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