-- -- Transition Radiation Detector -- -- MCM Control Unit - Configuration Network -- -- -- -- $Id: mcm_nw_nwl.vhd,v 1.2 2002/10/18 00:41:22 rgareus Exp $ -- -- Robin Gareus, Kirchhoff Institute for Physics, Heidelberg -- rgareus@kip.uni-heidelberg.de -- ------------------------------------------------------------ -- -- Network Layer -- -- This basically is a large MUX. We have _two_ Network-Sub-Layers (NWSL) -- which implement the network-protocol but have only _one_ application- -- layer (APL) above. -- -- The first sub-layer has priority, in case of both requesting at the same -- time. -- -- Because of the bridge-functionality this becomes a little bit confusing :) -- We have to be sure that - when switching the bridge - there is currently -- no data being sent out. -- -- See Note below on process set_bridge! -- -- we have 3 states for each NWSL and one idle state. -- The states are -- idle : application layer gets no data. both NWSL are unconnected. -- p0 : NWSL0 has access to APL -- b0 : NWSL0 has requested a bridge switch -- : wait until bridge can be (re)set -- bs0 : NWSL0's bridge command is being executed -- p1,b1,bs1 are equivalent for NWSL1 -- -- -- last modified: 14:43 / 09 Oct 2003 / V.Angelov -- added one DFF for the select between ring0/1 output -- to the bus. -------------------------------------------------- -- standard includes, library definitions. -------------------------------------------------- library ieee,work; use ieee.std_logic_1164.all; use work.mcm_nw_nwsl; -------------------------------------------------- -- ENTITY -------------------------------------------------- entity mcm_nw_nwl is port( -- Signals from Data Link Layer (recv) d0_fr_dll : in std_logic_vector(68 downto 0); s0_fr_dll : in std_logic; buf0_half : in std_logic; buf0_err : in std_logic; d1_fr_dll : in std_logic_vector(68 downto 0); s1_fr_dll : in std_logic; buf1_half : in std_logic; buf1_err : in std_logic; -- Signals to Data Link Layer (send) d0_buffer_ready : in std_logic; d0_to_dll : out std_logic_vector(68 downto 0); d0_to_dll_we : out std_logic; d0_to_dll_send : out std_logic; d1_buffer_ready : in std_logic; d1_to_dll : out std_logic_vector(68 downto 0); d1_to_dll_we : out std_logic; d1_to_dll_send : out std_logic; -- bridge to dll bridge : out std_logic; -- Signals to Application Layer request : out std_logic_vector(52 downto 0); request_valid : out std_logic; -- Signals from Application Layer reply : in std_logic_vector(52 downto 0); reply_valid : in std_logic; altered_frame : in std_logic; bridge_alter : in std_logic; bridge_mode : in std_logic; clk_buf_dis : out std_logic; reset_n : in std_logic; clk : in std_logic ); end mcm_nw_nwl; -------------------------------------------------- -- ARCHITECTURE -------------------------------------------------- architecture structural of mcm_nw_nwl is -------------------------------------------------- -- internal signals -------------------------------------------------- subtype state_type is std_logic_vector(2 downto 0); constant idle : state_type := "000"; constant p0 : state_type := "001"; constant p1 : state_type := "010"; constant b0 : state_type := "011"; constant b1 : state_type := "100"; constant bs0 : state_type := "101"; constant bs1 : state_type := "110"; SIGNAL current_state,next_state : state_type; SIGNAL rq0,rq1,reply0,reply1 : std_logic_vector(52 downto 0); SIGNAL rq0_valid,rq1_valid : std_logic; SIGNAL altered_frame0,altered_frame1 : std_logic; SIGNAL reply0_valid,reply1_valid : std_logic; SIGNAL bridgeable0,bridgeable1 : std_logic; SIGNAL wait_for_bridge : std_logic; SIGNAL bridged,bridge_buffered : std_logic; SIGNAL select_rq : std_logic; SIGNAL clk_buf_dis_nws0 : std_logic; SIGNAL clk_buf_dis_nws1 : std_logic; -------------------------------------------------- -- components -------------------------------------------------- COMPONENT hamm_reg is generic(Nbits : Integer := 4; Init_value : Integer := 0); port (clk, rst_n : in std_logic; data_in : in std_logic_vector(Nbits-1 downto 0); data_out : out std_logic_vector(Nbits-1 downto 0) ); END COMPONENT; COMPONENT mcm_nw_nwsl is port( -- Signals from Data Link Layer (recv) d_fr_dll : in std_logic_vector(68 downto 0); s_fr_dll : in std_logic; d_buffer_half : in std_logic; d_buf_err : in std_logic; -- Signals to Data Link Layer (send) d_buffer_ready : in std_logic; d_to_dll : out std_logic_vector(68 downto 0); d_we : out std_logic; d_initiate_send : out std_logic; -- Signals to Application Layer request : out std_logic_vector(52 downto 0); request_valid : out std_logic; -- Signals from Application Layer reply : in std_logic_vector(52 downto 0); reply_valid : in std_logic; altered_frame : in std_logic; -- Signal for bridge-synchrinsation wait_for_bridge : in std_logic; -- avoid deadlock. bridge : in std_logic; -- avoid deadlock. reset_n : in std_logic; clk_buf_dis : out std_logic; clk : in std_logic ); END COMPONENT; -------------------------------------------------- -- port maps -------------------------------------------------- begin sl0: mcm_nw_nwsl port map( d_fr_dll => d0_fr_dll, s_fr_dll => s0_fr_dll, d_buffer_half => buf0_half, d_buf_err => buf0_err, d_buffer_ready => d0_buffer_ready, d_to_dll => d0_to_dll, d_we => d0_to_dll_we, d_initiate_send => d0_to_dll_send, request => rq0, request_valid => rq0_valid, reply => reply0, reply_valid => reply0_valid, altered_frame => altered_frame0, wait_for_bridge => wait_for_bridge, bridge => bridged, reset_n => reset_n, clk_buf_dis => clk_buf_dis_nws0, clk => clk ); sl1: mcm_nw_nwsl port map( d_fr_dll => d1_fr_dll, s_fr_dll => s1_fr_dll, d_buffer_half => buf1_half, d_buf_err => buf1_err, d_buffer_ready => d1_buffer_ready, d_to_dll => d1_to_dll, d_we => d1_to_dll_we, d_initiate_send => d1_to_dll_send, request => rq1, request_valid => rq1_valid, reply => reply1, reply_valid => reply1_valid, altered_frame => altered_frame1, wait_for_bridge => wait_for_bridge, bridge => bridged, reset_n => reset_n, clk_buf_dis => clk_buf_dis_nws1, clk => clk ); -------------------------------------------------- -- processes -------------------------------------------------- -- generate state-machines next state nextstate: process ( current_state,rq0_valid,rq1_valid, bridge_alter,bridgeable0,bridgeable1) begin next_state <= current_state; case current_state is when idle => if ( rq0_valid = '1') then next_state <= p0; elsif ( rq1_valid = '1') then next_state <= p1; end if; when p0 => if ( bridge_alter = '1') then next_state <= b0; elsif ( rq0_valid = '0' ) then next_state <= idle; end if; when p1 => if ( bridge_alter = '1') then next_state <= b1; elsif ( rq1_valid = '0') then next_state <= idle; end if; when b0 => if ( bridgeable0 = '1' and bridgeable1 = '1') then next_state <= bs0; end if; when b1 => if ( bridgeable0 = '1' and bridgeable1 = '1') then next_state <= bs1; end if; when bs0 => if ( rq0_valid = '0' ) then next_state <= idle; end if; when bs1 => if ( rq1_valid = '0' ) then next_state <= idle; end if; when OTHERS => next_state <= idle; -- THIS SHOULD NEVER HAPPEN!! end case; end process nextstate; -- put state machine into next state. h1: hamm_reg generic map(Nbits => 3, Init_value => 0) port map ( clk => clk, rst_n => reset_n, data_in => next_state, data_out => current_state); -- set the state of the bridge. -- To switch the Bridgestate, both output buffers have to be flushed. -- If - while the buffers are beeing flushed - a new frame arrives -- the request to application-layer will bevome invalid. -- With the request becoming invalid, the reply will also be invalid -- and we loose the answer of the bridge-flip request. -- So: We have to buffer the value, the bridge should be set to! -- This is also done in this process: set_bridge: process (clk,reset_n,current_state, bridge_buffered,bridge_alter,bridge_mode) begin if ( reset_n = '0' ) then bridged <= '0'; bridge_buffered <= '0'; elsif ( clk'event and clk = '1') then if (bridge_alter = '1' and ( current_state /= bs0 and current_state /= bs1) ) then bridge_buffered <= bridge_mode; end if; if (current_state = bs0 or current_state = bs1) then bridged <= bridge_buffered; end if; end if; end process set_bridge; -- Set Output values depending on current state and other values... setoutput: process( current_state,reset_n, reply,reply_valid,altered_frame, rq0,rq0_valid, rq1,rq1_valid, bridge_alter,bridged,bridge_buffered) begin -- -- defaults -- -- request <= ( OTHERS => '-'); -- Modified by Deyan Atanasov request_valid <= '0'; reply0 <= ( OTHERS => '-'); reply0_valid <= '0'; altered_frame0 <= '0'; reply1 <= ( OTHERS => '-'); reply1_valid <= '0'; altered_frame1 <= '0'; wait_for_bridge <= '0'; case current_state is when idle => NULL; when p0 => -- request <= rq0; -- Modified by Deyan Atanasov request_valid <= rq0_valid; reply0 <= reply; reply0_valid <= reply_valid and (not bridge_alter); altered_frame0 <= altered_frame; when b0 => -- request <= rq0; request_valid <= rq0_valid; reply0 <= reply; reply0_valid <= reply_valid and (not bridge_alter); altered_frame0 <= altered_frame; wait_for_bridge <= '1'; when bs0 => -- request <= rq0; request_valid <= rq0_valid; reply0 <= reply; reply0_valid <= reply_valid and ( bridged xnor bridge_buffered); altered_frame0 <= altered_frame; wait_for_bridge <= '1'; when p1 => -- request <= rq1; request_valid <= rq1_valid; reply1 <= reply; reply1_valid <= reply_valid and (not bridge_alter); altered_frame1 <= altered_frame; when b1 => -- request <= rq1; request_valid <= rq1_valid; reply1 <= reply; reply1_valid <= reply_valid and (not bridge_alter); altered_frame1 <= altered_frame; wait_for_bridge <= '1'; when bs1 => -- request <= rq1; request_valid <= rq1_valid; reply1 <= reply; reply1_valid <= reply_valid and ( bridged xnor bridge_buffered); altered_frame1 <= altered_frame; wait_for_bridge <= '1'; when OTHERS => NULL; end case; end process setoutput; bridgeable0 <= d0_buffer_ready; bridgeable1 <= d1_buffer_ready; bridge <= bridged; -- with current_state select -- Added by Deyan Atanasov -- request <= rq0 when p0, -- rq0 when b0, -- rq0 when bs0, -- rq1 when p1, -- rq1 when b1, -- rq1 when bs1, -- rq0 when idle, -- rq0 when others; -- Changed by V.A. process(clk, reset_n) begin if reset_n = '0' then select_rq <= '0'; clk_buf_dis <= '1'; elsif clk'event and clk = '1' then case next_state is when p0 | b0 | bs0 => select_rq <= '0'; when p1 | b1 | bs1 => select_rq <= '1'; when others => select_rq <= '-'; end case; if current_state = idle then clk_buf_dis <= clk_buf_dis_nws0 and clk_buf_dis_nws1; else clk_buf_dis <= '0'; end if; end if; end process; request <= rq0 when select_rq = '0' else rq1 when select_rq = '1' else (others => '-'); end structural; -------------------------------------------------- -- CONFIGURATION -------------------------------------------------- -- synopsys translate_off CONFIGURATION mcm_nw_nwl_CFG of mcm_nw_nwl is for structural end for; end mcm_nw_nwl_CFG; -- synopsys translate_on