component trb_net16_term is
generic (
- SECURE_MODE : integer range 0 to 1 := 0
- --if secure_mode is not used, apl must provide error pattern and dtype until
- --next trigger comes in. In secure mode these must be available when hold_trm goes low
- );
+ USE_APL_PORT : integer range 0 to 1 := c_YES;
+ --even when 0, ERROR_PACKET_IN is used for automatic replys
+ SECURE_MODE : integer range 0 to 1 := std_TERM_SECURE_MODE
+ --if secure_mode is not used, apl must provide error pattern and dtype until
+ --next trigger comes in. In secure mode these need to be available while relase_trg is high
+ );
port(
-- Misc
- CLK : in std_logic;
- RESET : in std_logic;
+ CLK : in std_logic;
+ RESET : in std_logic;
CLK_EN : in std_logic;
+
INT_DATAREADY_OUT: out std_logic;
INT_DATA_OUT: out std_logic_vector (c_DATA_WIDTH-1 downto 0); -- Data word
INT_PACKET_NUM_OUT: out std_logic_vector (c_NUM_WIDTH-1 downto 0);
INT_READ_IN: in std_logic;
+
INT_DATAREADY_IN: in std_logic;
INT_DATA_IN: in std_logic_vector (c_DATA_WIDTH-1 downto 0); -- Data word
INT_PACKET_NUM_IN: in std_logic_vector (c_NUM_WIDTH-1 downto 0);
INT_READ_OUT: out std_logic;
+
-- "mini" APL, just to see the triggers coming in
APL_DTYPE_OUT: out std_logic_vector (3 downto 0); -- see NewTriggerBusNetworkDescr
APL_ERROR_PATTERN_OUT: out std_logic_vector (31 downto 0); -- see NewTriggerBusNetworkDescr
APL_GOT_TRM: out std_logic;
APL_RELEASE_TRM: in std_logic;
APL_ERROR_PATTERN_IN: in std_logic_vector (31 downto 0) -- see NewTriggerBusNetworkDescr
- -- Status and control port
);
end component;
MED_INIT_DATA_OUT => m_DATA_OUT((i*2+1)*c_DATA_WIDTH-1 downto i*2*c_DATA_WIDTH),
MED_INIT_PACKET_NUM_OUT => m_PACKET_NUM_OUT((i*2+1)*c_NUM_WIDTH-1 downto i*2*c_NUM_WIDTH),
MED_INIT_READ_IN => m_READ_IN(i*2),
---
--- MED_INIT_DATAREADY_IN => m_DATAREADY_IN(i*2),
--- MED_INIT_DATA_IN => m_DATA_IN((i*2+1)*c_DATA_WIDTH-1 downto i*2*c_DATA_WIDTH),
--- MED_INIT_PACKET_NUM_IN => m_PACKET_NUM_IN((i*2+1)*c_NUM_WIDTH-1 downto i*2*c_NUM_WIDTH),
--- MED_INIT_READ_OUT => m_READ_OUT(i*2),
--- MED_INIT_ERROR_IN => m_ERROR_IN((i+1)*3-1 downto i*3),
MED_REPLY_DATAREADY_OUT => m_DATAREADY_OUT(i*2+1),
MED_REPLY_DATA_OUT => m_DATA_OUT((i*2+2)*c_DATA_WIDTH-1 downto (i*2+1)*c_DATA_WIDTH),
MED_REPLY_PACKET_NUM_OUT=> m_PACKET_NUM_OUT((i*2+2)*c_NUM_WIDTH-1 downto (i*2+1)*c_NUM_WIDTH),
MED_REPLY_READ_IN => m_READ_IN(i*2+1),
---
--- MED_REPLY_DATAREADY_IN => m_DATAREADY_IN(i*2+1),
--- MED_REPLY_DATA_IN => m_DATA_IN((i*2+2)*c_DATA_WIDTH-1 downto (i*2+1)*c_DATA_WIDTH),
--- MED_REPLY_PACKET_NUM_IN => m_PACKET_NUM_IN((i*2+2)*c_NUM_WIDTH-1 downto (i*2+1)*c_NUM_WIDTH),
--- MED_REPLY_READ_OUT => m_READ_OUT(i*2+1),
--- MED_REPLY_ERROR_IN => m_ERROR_IN((i+1)*3-1 downto i*3),
MED_DATAREADY_IN => m_DATAREADY_IN(i),
MED_DATA_IN => m_DATA_IN((j+1)*c_DATA_WIDTH-1 downto j*c_DATA_WIDTH),
);
end generate;
end generate;
-
+
--rearrange vectors for hub logic
gen_rearrange : for CHANNEL in 0 to 2**(c_MUX_WIDTH-1)-1 generate
constant api_num : integer := calc_special_number(CHANNEL, API_NUMBER, API_CHANNELS);
entity trb_net16_hub_logic is
generic (
--media interfaces
- POINT_NUMBER : integer range 2 to 32 := 12
+ POINT_NUMBER : integer range 2 to 32 := 3
);
port (
CLK : in std_logic;
signal current_REPLY_reading_hdr : std_logic_vector(POINT_NUMBER-1 downto 0);
signal last_header_addr : std_logic_vector(1 downto 0);
signal last_header_data : std_logic_vector(POINT_NUMBER*c_DATA_WIDTH-1 downto 0);
- signal reading_last_hdr : std_logic_vector(POINT_NUMBER-1 downto 0);
+ signal reading_last_hdr,next_reading_last_hdr : std_logic_vector(POINT_NUMBER-1 downto 0);
--general signals
signal locked, next_locked : std_logic;
signal get_locked, release_locked : std_logic;
signal got_trm : std_logic_vector(POINT_NUMBER-1 downto 0);
signal locking_point, next_locking_point : std_logic_vector(POINT_NUMBER-1 downto 0);
- signal reading_from_point,next_reading_from_point : std_logic_vector(POINT_NUMBER-1 downto 0);
signal send_reply_trm : std_logic;
signal init_locked, next_init_locked : std_logic;
signal get_init_locked, release_init_locked: std_logic;
signal REPLY_MUX_reading : std_logic_vector(POINT_NUMBER-1 downto 0);
+ signal reply_arbiter_result,last_reply_arbiter_result : std_logic_vector(POINT_NUMBER-1 downto 0);
type state_type is (SENDING_DATA, SENDING_REPLY_TRM);
signal current_state, next_state : state_type;
signal reply_fsm_state : std_logic;
signal waiting_for_init_finish, next_waiting_for_init_finish : std_logic;
+ signal read_from_point_before : std_logic_vector(POINT_NUMBER-1 downto 0);
+ signal next_resending_header, resending_header : std_logic;
+ signal idle_counter : std_logic_vector(4 downto 0);
+ signal idle_time_exceeded : std_logic;
begin
REPLY_HEADER_OUT <= (others => '0');
gen_reading_trmFn : for i in 0 to POINT_NUMBER-1 generate
--- reading_trmF1(i) <= '1' when REPLY_PACKET_NUM_IN((i+1)*c_NUM_WIDTH-1 downto i*c_NUM_WIDTH) = "01"
--- and REPLY_reading_trm(i) = '1'
--- and REPLY_DATAREADY_IN(i) = '1'
--- else '0';
--- reading_trmF2(i) <= '1' when REPLY_PACKET_NUM_IN((i+1)*c_NUM_WIDTH-1 downto i*c_NUM_WIDTH) = "10"
--- and REPLY_reading_trm(i) = '1'
--- and REPLY_DATAREADY_IN(i) = '1'
--- else '0';
reading_trmF1(i) <= not REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+1) and REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH)
and REPLY_reading_trm(i) and REPLY_DATAREADY_IN(i);
end if;
end if;
end process;
-
+
--count received TRM
----------------------------------
end if;
end process;
+--save if data was read from one port
+----------------------------------
+ read_before_proc : process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if RESET = '1' or send_reply_trm = '1' or locked = '0' then
+ read_from_point_before <= (others => '0');
+ else
+ read_from_point_before <= (REPLY_DATAREADY_IN and buf_REPLY_READ_OUT) or read_from_point_before;
+ end if;
+ end if;
+ end process;
---REPLY Count 16 and 64 bit packets
+--REPLY Counters
----------------------------------
+ --counter for 16bit words
gen_packet_counter : process(CLK)
begin
if rising_edge(CLK) then
end if;
end process;
+ --counts data packets only
gen_data_counter : process(CLK)
- begin
+ begin
if rising_edge(CLK) then
if RESET = '1' or reply_point_lock = '0' then
data_counter <= (others => '0');
- elsif comb_REPLY_POOL_PACKET_NUM="11" and comb_REPLY_POOL_DATAREADY = '1' then
+ elsif comb_REPLY_POOL_PACKET_NUM="00" and comb_REPLY_POOL_DATAREADY = '1'
+ and comb_REPLY_POOL_DATA(2 downto 0) = TYPE_DAT then
data_counter <= data_counter + 1;
end if;
end if;
- end process;
-
+ end process;
+ --counter for idle time
+-- gen_idle_count : process(CLK)
+-- begin
+-- if rising_edge(CLK) then
+-- if RESET = '1' or packet_counter="00" then
+-- idle_counter <= (others => '0');
+-- idle_time_exceeded <= '0';
+-- elsif or_all(REPLY_MUX_reading and REPLY_DATAREADY_IN) = '0' and idle_time_exceeded = '0' then
+-- idle_counter <= idle_counter + 1;
+-- if idle_counter = c_MAX_IDLE_TIME_PER_PACKET then
+-- idle_time_exceeded <= '1';
+-- end if;
+-- end if;
+-- end if;
+-- end process;
--REPLY mux select input
RESET => RESET,
CLK_EN => reply_arbiter_CLK_EN,
INPUT_IN => reply_arbiter_input,
- RESULT_OUT => REPLY_MUX_reading,
+ RESULT_OUT => reply_arbiter_result,
ENABLE => '1',
CTRL => (others => '0')
);
-- when switching from one point to another some data was already read from, we have
-- to set reading_last_hdr instead of reading_from_point
-reading_last_hdr <= (others => '0');
-
- gen_reply_point_lock : process(reply_point_lock, reading_from_point, comb_REPLY_muxed_PACKET_NUM, REPLY_MUX_reading,
- REPLY_DATAREADY_IN, comb_REPLY_muxed_DATA)
+
+
+ gen_reply_point_lock : process(reply_point_lock, comb_REPLY_muxed_PACKET_NUM,
+ reply_arbiter_result, REPLY_DATAREADY_IN, comb_REPLY_muxed_DATA,
+ REPLY_MUX_reading, last_reply_arbiter_result, got_trm,
+ read_from_point_before, resending_header, comb_REPLY_muxed_DATAREADY)
begin
next_point_lock <= reply_point_lock;
- next_reading_from_point <= reading_from_point;
+ REPLY_MUX_reading <= reply_arbiter_result;
+ next_reading_last_hdr <= (others => '0');
+ next_resending_header <= '0';
+ --release lock if TRM is read
if comb_REPLY_muxed_PACKET_NUM = "00" and or_all(REPLY_MUX_reading and REPLY_DATAREADY_IN) = '1' then
if comb_REPLY_muxed_DATA(2 downto 0) = TYPE_TRM then
next_point_lock <= '0';
- next_reading_from_point <= (others => '0');
else
next_point_lock <= '1';
- reading_from_point <= REPLY_MUX_reading;
+ end if;
+ end if;
+
+ --release lock when input timed out after even number of data packets (even: because of 32bit alignment)
+
+
+ --trigger resending of header upon switch of arbiter when necessary
+ if or_all(not last_reply_arbiter_result and reply_arbiter_result and not got_trm and read_from_point_before) = '1'
+ or resending_header = '1' then
+ next_resending_header <= '1';
+ next_reading_last_hdr <= reply_arbiter_result;
+ REPLY_MUX_reading <= (others => '0');
+ if resending_header = '1' and comb_REPLY_muxed_PACKET_NUM = "11" and comb_REPLY_muxed_DATAREADY = '1' then
+ next_resending_header <= '0';
+ next_reading_last_hdr <= (others => '0');
end if;
end if;
end process;
+--if last_point_lock = 0 and read_from_point_before = 1 and REPLY_MUX_reading \= last_REPLY_MUX_reading then resend_header
+
gen_point_lock : process(CLK)
begin
if rising_edge(CLK) then
if RESET = '1' then
reply_point_lock <= '0';
- reading_from_point <= (others => '0');
else
reply_point_lock <=next_point_lock;
- reading_from_point <= next_reading_from_point;
+ last_reply_arbiter_result <= reply_arbiter_result;
+ resending_header <= next_resending_header;
+ reading_last_hdr <= next_reading_last_hdr;
end if;
end if;
end process;
--REPLY mux
----------------------------------
gen_reply_mux1 : for i in 0 to c_DATA_WIDTH-1 generate
- data_mux : process(REPLY_DATA_IN, REPLY_MUX_reading)
+ data_mux : process(REPLY_DATA_IN, REPLY_MUX_reading,last_header_data, reading_last_hdr)
variable tmp_data : std_logic;
begin
tmp_data := '0';
end generate;
gen_reply_mux2 : for i in 0 to c_NUM_WIDTH-1 generate
- packet_num_mux : process(REPLY_PACKET_NUM_IN, REPLY_MUX_reading)
+ packet_num_mux : process(REPLY_PACKET_NUM_IN, REPLY_MUX_reading,packet_counter, reading_last_hdr)
variable tmp_pm : std_logic;
begin
tmp_pm := '0';
gen_pm_mux : for j in 0 to POINT_NUMBER-1 loop
- tmp_pm := tmp_pm or (REPLY_PACKET_NUM_IN(j*c_NUM_WIDTH+i) and REPLY_MUX_reading(j));
+ tmp_pm := tmp_pm or (REPLY_PACKET_NUM_IN(j*c_NUM_WIDTH+i) and REPLY_MUX_reading(j))
+ or (packet_counter(i) and reading_last_hdr(j));
end loop;
comb_REPLY_muxed_PACKET_NUM(i) <= tmp_pm;
end process;
end generate;
- comb_REPLY_muxed_DATAREADY <= or_all(REPLY_MUX_reading and REPLY_DATAREADY_IN and not current_REPLY_reading_trm) and REPLY_MUX_real_reading;
+ comb_REPLY_muxed_DATAREADY <= (or_all(REPLY_MUX_reading and REPLY_DATAREADY_IN and not current_REPLY_reading_trm) or or_all(reading_last_hdr)) and REPLY_MUX_real_reading;
--REPLY POOL state machine
----------------------------------
reply_state_machine : process(REPLY_POOL_next_READ, current_state, packet_counter,
send_reply_trm, SEQ_NR, REPLY_combined_trm_F1, REPLY_combined_trm_F2,
- comb_REPLY_muxed_DATAREADY, comb_REPLY_muxed_DATA,
+ comb_REPLY_muxed_DATAREADY, comb_REPLY_muxed_DATA, init_locked,
comb_REPLY_muxed_PACKET_NUM, waiting_for_init_finish)
begin
release_locked <= '0';