From: hadeshyp Date: Fri, 8 Dec 2006 18:12:37 +0000 (+0000) Subject: added first version for the API, Ingo X-Git-Tag: oldGBE~775 X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=b1d5787078b048207e4706c09f37a6d2743447a5;p=trbnet.git added first version for the API, Ingo --- diff --git a/testbench/in_active_api.txt b/testbench/in_active_api.txt new file mode 100644 index 0000000..5fb14a5 --- /dev/null +++ b/testbench/in_active_api.txt @@ -0,0 +1,10 @@ +0:0:0000 +0:0:0000 +0:0:0000 +0:0:0000 +0:1:0000 -- start sending here +0:1:0000 +0:1:0000 +0:0:0000 -- stop sending +0:0:0000 +0:0:0000 \ No newline at end of file diff --git a/testbench/testsim.tcl b/testbench/testsim.tcl new file mode 100644 index 0000000..fc5802c --- /dev/null +++ b/testbench/testsim.tcl @@ -0,0 +1,5 @@ +ntrace select -o on -m / -l this +ntrace select -o on -m /UUT/ -l this +ntrace start +run 1000 ns +quit \ No newline at end of file diff --git a/testbench/trb_net_active_api_testbench.vhd b/testbench/trb_net_active_api_testbench.vhd new file mode 100644 index 0000000..a7c3b3d --- /dev/null +++ b/testbench/trb_net_active_api_testbench.vhd @@ -0,0 +1,197 @@ +library ieee; + +use ieee.std_logic_1164.all; + +USE ieee.std_logic_signed.ALL; + +USE ieee.std_logic_arith.ALL; + +USE std.textio.ALL; +USE ieee.std_logic_textio.ALL; + +entity trb_net_active_api_testbench is + +end trb_net_active_api_testbench; + +architecture trb_net_active_api_testbench_arch of trb_net_active_api_testbench is + + signal clk : std_logic := '0'; + signal reset : std_logic := '1'; + + signal apl_data_in : std_logic_vector(47 downto 0) := (others => '0'); + signal apl_write_in : std_logic := '0'; + signal apl_send_in : std_logic := '0'; + + signal int_init_data_out : std_logic_vector(50 downto 0) := (others => '0'); + signal int_init_dataready_out : std_logic := '0'; + + signal read_f1 : std_logic_vector(3 downto 0) := (others => '0'); + +component trb_net_active_api + + generic (FIFO_TO_INT_DEPTH : integer := 3; -- Depth of the FIFO, 2^(n+1), + -- for the direction to + -- internal world + FIFO_TO_APL_DEPTH : integer := 3; -- direction to application + FIFO_TERM_BUFFER_DEPTH : integer := 0); -- fifo for auto-answering of + -- the master path, if set to 0 + -- no buffer is used at all + + + port( + -- Misc + CLK : in std_logic; + RESET : in std_logic; + CLK_EN : in std_logic; + + -- APL Transmitter port + APL_DATA_IN: in STD_LOGIC_VECTOR (47 downto 0); -- Data word "application to network" + APL_WRITE_IN: in STD_LOGIC; -- Data word is valid and should be transmitted + APL_FIFO_FULL_OUT: out STD_LOGIC; -- Stop transfer, the fifo is full + APL_SHORT_TRANSFER_IN: in STD_LOGIC; -- + APL_DTYPE_IN: in STD_LOGIC_VECTOR (3 downto 0); -- see NewTriggerBusNetworkDescr + APL_ERROR_PATTERN: in STD_LOGIC_VECTOR (31 downto 0); -- see NewTriggerBusNetworkDescr + APL_SEND_IN: in STD_LOGIC; -- Release sending of the data + APL_TARGET_ADDRESS_IN: in STD_LOGIC_VECTOR (15 downto 0); -- Address of + -- the target (only for active APIs) + + -- Receiver port + APL_DATA_OUT: out STD_LOGIC_VECTOR (47 downto 0); -- Data word "network to application" + APL_TYP_OUT: out STD_LOGIC_VECTOR (2 downto 0); -- Which kind of data word: DAT, HDR or TRM + APL_DATAREADY_OUT: out STD_LOGIC; -- Data word is valid and might be read out + APL_READ_IN: in STD_LOGIC; -- Read data word + + -- APL Control port + APL_RUN_OUT: out STD_LOGIC; -- Data transfer is running + APL_MY_ADDRESS_IN: in STD_LOGIC_VECTOR (15 downto 0); -- My own address (temporary solution!!!) + + -- Internal direction port + -- This is just a clone from trb_net_iobuf + + INT_INIT_DATAREADY_OUT: out STD_LOGIC; + INT_INIT_DATA_OUT: out STD_LOGIC_VECTOR (50 downto 0); -- Data word + INT_INIT_READ_IN: in STD_LOGIC; + INT_INIT_ERROR_OUT: out STD_LOGIC_VECTOR (2 downto 0); -- Status bits + INT_INIT_DATAREADY_IN: in STD_LOGIC; + INT_INIT_DATA_IN: in STD_LOGIC_VECTOR (50 downto 0); -- Data word + INT_INIT_READ_OUT: out STD_LOGIC; + INT_INIT_ERROR_IN: in STD_LOGIC_VECTOR (2 downto 0); -- Status bits + + INT_REPLY_HEADER_IN: in STD_LOGIC; -- Concentrator kindly asks to resend the last + -- header (only for the reply path) + INT_REPLY_DATAREADY_OUT: out STD_LOGIC; + INT_REPLY_DATA_OUT: out STD_LOGIC_VECTOR (50 downto 0); -- Data word + INT_REPLY_READ_IN: in STD_LOGIC; + INT_REPLY_ERROR_OUT: out STD_LOGIC_VECTOR (2 downto 0); -- Status bits + INT_REPLY_DATAREADY_IN: in STD_LOGIC; + INT_REPLY_DATA_IN: in STD_LOGIC_VECTOR (50 downto 0); -- Data word + INT_REPLY_READ_OUT: out STD_LOGIC; + INT_REPLY_ERROR_IN: in STD_LOGIC_VECTOR (2 downto 0) -- Status bits + -- Status and control port + + -- not needed now, but later + + ); +END component; + +begin + +UUT: trb_net_active_api + generic map ( + FIFO_TERM_BUFFER_DEPTH => 0) + port map ( + CLK => clk, + RESET => reset, + CLK_EN => '1', + + APL_DATA_IN => apl_data_in, + APL_WRITE_IN => apl_write_in, + APL_SHORT_TRANSFER_IN => '0', + APL_DTYPE_IN => (others => '0'), + APL_ERROR_PATTERN => x"12341234", + APL_SEND_IN => apl_send_in, + APL_TARGET_ADDRESS_IN => x"0010", + + APL_READ_IN => '0', + APL_MY_ADDRESS_IN => x"0009", + + + INT_INIT_READ_IN => '1', --advanced read + INT_INIT_DATAREADY_IN => '0', + INT_INIT_DATAREADY_OUT => int_init_dataready_out, + INT_INIT_DATA_IN => (others => '0'), + INT_INIT_ERROR_IN => (others => '0'), + INT_INIT_DATA_OUT => int_init_data_out, + + INT_REPLY_HEADER_IN => '0', + INT_REPLY_READ_IN => '0', + INT_REPLY_DATAREADY_IN => '0', + INT_REPLY_DATA_IN => (others => '0'), + INT_REPLY_ERROR_IN => (others => '0') + ); + + clk <= not clk after 10ns; + + apl_data_in(3 downto 0) <= read_f1; + + + + + DO_RESET : process + begin + reset <= '1'; + wait for 30ns; + reset <= '0'; + wait; + end process DO_RESET; + + STIMULI: process (clk) + file protokoll : text open read_mode is "in_active_api.txt"; + variable myoutline : line; + variable leer : character; + variable var1, var2 : std_logic; + variable varx1 : std_logic_vector(2 downto 0); + variable varx2, varx3 : std_logic_vector(3 downto 0); + begin + if falling_edge(CLK) then + if (not endfile(protokoll)) then + readline(protokoll,myoutline); + + read(myoutline,var1); + apl_write_in <= var1; + read(myoutline,leer); + + read(myoutline,var2); + apl_send_in <= var2; + read(myoutline,leer); + + read(myoutline,varx2); + read_f1 <= varx2; + + end if; + end if; + end process STIMULI; + + + +end trb_net_active_api_testbench_arch; + + +-- fuse -prj trb_net_active_api_testbench_beh.prj -top trb_net_active_api_testbench -o trb_net_active_api_testbench + +-- vhdl work "/home/hadaq/acromag/design/DX2002test/trbnet/trb_net_std.vhd" +-- vhdl work "/home/hadaq/acromag/design/DX2002test/trbnet/trb_net_fifo.vhd" +-- vhdl work "/home/hadaq/acromag/design/DX2002test/trbnet/xilinx/arch_trb_net_fifo.vhd" +-- vhdl work "/home/hadaq/acromag/design/DX2002test/trbnet/xilinx/generic_fifo.vhd" +-- vhdl work "/home/hadaq/acromag/design/DX2002test/trbnet/xilinx/generic_shift.vhd" +-- vhdl work "/home/hadaq/acromag/design/DX2002test/trbnet/trb_net_fifo_testbench.vhd" + +-- trb_net_active_api_testbench -tclbatch testsim.tcl + +-- ntrace select -o on -m / -l this +-- ntrace start +-- run 1000 ns +-- quit + +-- isimwave isimwavedata.xwv + diff --git a/trb_net_active_api.vhd b/trb_net_active_api.vhd new file mode 100644 index 0000000..e91b5e9 --- /dev/null +++ b/trb_net_active_api.vhd @@ -0,0 +1,331 @@ +-- connection between the TRBNET and any application +-- for a description see HADES wiki +-- http://hades-wiki.gsi.de/cgi-bin/view/DaqSlowControl/TrbNetAPI + +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_ARITH.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +use work.trb_net_std.all; + + +entity trb_net_active_api is + + generic (FIFO_TO_INT_DEPTH : integer := 3; -- Depth of the FIFO, 2^(n+1), + -- for the direction to + -- internal world + FIFO_TO_APL_DEPTH : integer := 3; -- direction to application + FIFO_TERM_BUFFER_DEPTH : integer := 0); -- fifo for auto-answering of + -- the master path, if set to 0 + -- no buffer is used at all + + + port( + -- Misc + CLK : in std_logic; + RESET : in std_logic; + CLK_EN : in std_logic; + + -- APL Transmitter port + APL_DATA_IN: in STD_LOGIC_VECTOR (47 downto 0); -- Data word "application to network" + APL_WRITE_IN: in STD_LOGIC; -- Data word is valid and should be transmitted + APL_FIFO_FULL_OUT: out STD_LOGIC; -- Stop transfer, the fifo is full + APL_SHORT_TRANSFER_IN: in STD_LOGIC; -- + APL_DTYPE_IN: in STD_LOGIC_VECTOR (3 downto 0); -- see NewTriggerBusNetworkDescr + APL_ERROR_PATTERN: in STD_LOGIC_VECTOR (31 downto 0); -- see NewTriggerBusNetworkDescr + APL_SEND_IN: in STD_LOGIC; -- Release sending of the data + APL_TARGET_ADDRESS_IN: in STD_LOGIC_VECTOR (15 downto 0); -- Address of + -- the target (only for active APIs) + + -- Receiver port + APL_DATA_OUT: out STD_LOGIC_VECTOR (47 downto 0); -- Data word "network to application" + APL_TYP_OUT: out STD_LOGIC_VECTOR (2 downto 0); -- Which kind of data word: DAT, HDR or TRM + APL_DATAREADY_OUT: out STD_LOGIC; -- Data word is valid and might be read out + APL_READ_IN: in STD_LOGIC; -- Read data word + + -- APL Control port + APL_RUN_OUT: out STD_LOGIC; -- Data transfer is running + APL_MY_ADDRESS_IN: in STD_LOGIC_VECTOR (15 downto 0); -- My own address (temporary solution!!!) + + -- Internal direction port + -- This is just a clone from trb_net_iobuf + + INT_INIT_DATAREADY_OUT: out STD_LOGIC; + INT_INIT_DATA_OUT: out STD_LOGIC_VECTOR (50 downto 0); -- Data word + INT_INIT_READ_IN: in STD_LOGIC; + INT_INIT_ERROR_OUT: out STD_LOGIC_VECTOR (2 downto 0); -- Status bits + INT_INIT_DATAREADY_IN: in STD_LOGIC; + INT_INIT_DATA_IN: in STD_LOGIC_VECTOR (50 downto 0); -- Data word + INT_INIT_READ_OUT: out STD_LOGIC; + INT_INIT_ERROR_IN: in STD_LOGIC_VECTOR (2 downto 0); -- Status bits + + INT_REPLY_HEADER_IN: in STD_LOGIC; -- Concentrator kindly asks to resend the last + -- header (only for the reply path) + INT_REPLY_DATAREADY_OUT: out STD_LOGIC; + INT_REPLY_DATA_OUT: out STD_LOGIC_VECTOR (50 downto 0); -- Data word + INT_REPLY_READ_IN: in STD_LOGIC; + INT_REPLY_ERROR_OUT: out STD_LOGIC_VECTOR (2 downto 0); -- Status bits + INT_REPLY_DATAREADY_IN: in STD_LOGIC; + INT_REPLY_DATA_IN: in STD_LOGIC_VECTOR (50 downto 0); -- Data word + INT_REPLY_READ_OUT: out STD_LOGIC; + INT_REPLY_ERROR_IN: in STD_LOGIC_VECTOR (2 downto 0) -- Status bits + -- Status and control port + + -- not needed now, but later + + ); +END trb_net_active_api; + +architecture trb_net_active_api_arch of trb_net_active_api is + +component trb_net_fifo is + generic (WIDTH : integer := 8; -- FIFO word width + DEPTH : integer := 4); -- Depth of the FIFO, 2^(n+1) + + port (CLK : in std_logic; + RESET : in std_logic; + CLK_EN : in std_logic; + + DATA_IN : in std_logic_vector(WIDTH - 1 downto 0); -- Input data + WRITE_ENABLE_IN : in std_logic; + DATA_OUT : out std_logic_vector(WIDTH - 1 downto 0); -- Output data + READ_ENABLE_IN : in std_logic; + FULL_OUT : out std_logic; -- Full Flag + EMPTY_OUT : out std_logic; + DEPTH_OUT : out std_logic_vector(7 downto 0) + ); + + end component; + +-- signals for the APL to INT fifo: +signal fifo_to_int_data_in : std_logic_vector(47 downto 0); +signal fifo_to_int_write : std_logic; +signal fifo_to_int_data_out : std_logic_vector(47 downto 0); +signal fifo_to_int_read : std_logic; +signal fifo_to_int_full : std_logic; +signal fifo_to_int_empty : std_logic; + +-- signals for the INT to APL: +signal fifo_to_apl_data_in : std_logic_vector(50 downto 0); +signal fifo_to_apl_write : std_logic; +signal fifo_to_apl_data_out : std_logic_vector(50 downto 0); +signal fifo_to_apl_read : std_logic; +signal fifo_to_apl_full : std_logic; +signal fifo_to_apl_empty : std_logic; + +-- signals for the test buffer +signal fifo_term_buffer_data_in : std_logic_vector(47 downto 0); +signal fifo_term_buffer_write : std_logic; +signal fifo_term_buffer_data_out : std_logic_vector(47 downto 0); +signal fifo_term_buffer_read : std_logic; +signal fifo_term_buffer_full : std_logic; +signal fifo_term_buffer_empty : std_logic; + +type API_STATE is (IDLE, SEND_HEADER, RUNNING, SHUTDOWN, SEND_SHORT, SEND_TRAILER, WAITING,MY_ERROR); +signal current_state, next_state : API_STATE; + +signal combined_header, registered_header, next_registered_header: std_logic_vector(47 downto 0); +signal combined_trailer, registered_trailer, next_registered_trailer: std_logic_vector(47 downto 0); + +signal sequence_counter,next_sequence_counter : std_logic_vector(7 downto 0); +signal next_INT_INIT_DATA_OUT, reg_INT_INIT_DATA_OUT: std_logic_vector(50 downto 0); +signal next_INT_INIT_DATAREADY_OUT, reg_INT_INIT_DATAREADY_OUT: std_logic; + +begin + + FIFO_TO_INT: trb_net_fifo + generic map ( + WIDTH => 48, + DEPTH => FIFO_TO_INT_DEPTH) + port map ( + CLK => CLK, + RESET => RESET, + CLK_EN => CLK_EN, + DATA_IN => fifo_to_int_data_in, + WRITE_ENABLE_IN => fifo_to_int_write, + DATA_OUT => fifo_to_int_data_out, + READ_ENABLE_IN => fifo_to_int_read, + FULL_OUT => fifo_to_int_full, + EMPTY_OUT => fifo_to_int_empty + ); + + FIFO_TO_APL: trb_net_fifo + generic map ( + WIDTH => 51, + DEPTH => FIFO_TO_APL_DEPTH) + port map ( + CLK => CLK, + RESET => RESET, + CLK_EN => CLK_EN, + DATA_IN => fifo_to_apl_data_in, + WRITE_ENABLE_IN => fifo_to_apl_write, + DATA_OUT => fifo_to_apl_data_out, + READ_ENABLE_IN => fifo_to_apl_read, + FULL_OUT => fifo_to_apl_full, + EMPTY_OUT => fifo_to_apl_empty + ); + +CHECK_BUFFER: if FIFO_TERM_BUFFER_DEPTH >0 generate + + FIFO_TERM_BUFFER: trb_net_fifo + generic map ( + WIDTH => 48, + DEPTH => FIFO_TERM_BUFFER_DEPTH) + port map ( + CLK => CLK, + RESET => RESET, + CLK_EN => CLK_EN, + DATA_IN => fifo_term_buffer_data_in, + WRITE_ENABLE_IN => fifo_term_buffer_write, + DATA_OUT => fifo_term_buffer_data_out, + READ_ENABLE_IN => fifo_term_buffer_read, + FULL_OUT => fifo_term_buffer_full, + EMPTY_OUT => fifo_term_buffer_empty + ); + + end generate CHECK_BUFFER; + +-- combinatorial part of state machine + STATE_COMB : process(current_state, APL_SEND_IN, combined_header, INT_INIT_READ_IN, + APL_WRITE_IN, fifo_to_int_empty, next_registered_header, + reg_INT_INIT_DATA_OUT, reg_INT_INIT_DATA_OUT, + fifo_to_int_data_out, combined_trailer, + next_registered_trailer) + begin -- process + next_state <= MY_ERROR; + next_registered_header <= next_registered_header; + next_INT_INIT_DATAREADY_OUT <= '0'; + next_INT_INIT_DATA_OUT(TYPE_POSITION) <= TYPE_ILLEGAL; + next_INT_INIT_DATA_OUT(DWORD_POSITION) <= (others => '0'); + next_registered_trailer <= next_registered_trailer; + +------------------------------------------------------------------------------- +-- IDLE +------------------------------------------------------------------------------- + if current_state = IDLE then + if APL_SEND_IN = '1' then + if APL_SHORT_TRANSFER_IN = '1' and APL_WRITE_IN = '0' and fifo_to_int_empty = '1' then + next_registered_header <= (others => '0'); + next_state <= SEND_SHORT; -- no next data word, waiting for + -- falling edge of APL_SEND_IN + next_INT_INIT_DATAREADY_OUT <= '0'; + else -- normal transfer, prepare the header + next_registered_header <= combined_header; + next_state <= SEND_HEADER; + next_INT_INIT_DATA_OUT(TYPE_POSITION) <= TYPE_HDR; + next_INT_INIT_DATA_OUT(DWORD_POSITION) <= combined_header; + next_INT_INIT_DATAREADY_OUT <= '1'; + end if; -- next word will be a header + else + next_state <= IDLE; + end if; -- APL_SEND_IN +------------------------------------------------------------------------------- +-- SEND_HEADER +------------------------------------------------------------------------------- + elsif current_state = SEND_HEADER then + if INT_INIT_READ_IN = '1' then -- kill current header + next_state <= RUNNING; + if fifo_to_int_empty = '1' then + next_INT_INIT_DATAREADY_OUT <= '0'; + else + next_INT_INIT_DATAREADY_OUT <= '1'; + next_INT_INIT_DATA_OUT(TYPE_POSITION) <= TYPE_DAT; + next_INT_INIT_DATA_OUT(DWORD_POSITION) <= fifo_to_int_data_out; + end if; -- fifo_to_int_empty + else + next_state <= SEND_HEADER; + next_INT_INIT_DATA_OUT(TYPE_POSITION) <= TYPE_HDR; + next_INT_INIT_DATA_OUT(DWORD_POSITION) <= registered_header; + next_INT_INIT_DATAREADY_OUT <= '1'; + end if; +------------------------------------------------------------------------------- +-- RUNNING +------------------------------------------------------------------------------- + elsif current_state = RUNNING then + if APL_SEND_IN = '0' then -- terminate the transfer + if fifo_to_int_empty = '1' then -- immediate stop + next_state <= SEND_TRAILER; + next_registered_trailer <= combined_trailer; + next_INT_INIT_DATAREADY_OUT <= '1'; + next_INT_INIT_DATA_OUT(TYPE_POSITION) <= TYPE_TRM; + next_INT_INIT_DATA_OUT(DWORD_POSITION) <= combined_trailer; + else + next_state <= SHUTDOWN; + end if; + else -- APL_SEND_IN: still running + next_state <= RUNNING; + -- BUGBUG data words have to be prepared + end if; +------------------------------------------------------------------------------- +-- SEND_TRAILER +------------------------------------------------------------------------------- + elsif current_state = SEND_TRAILER then + + + end if; -- end state switch + + end process; + + + + -- combine the next header + combined_header(F1_POSITION) <= APL_MY_ADDRESS_IN; + combined_header(F2_POSITION) <= APL_TARGET_ADDRESS_IN; + combined_header(15 downto 14) <= (others => '0'); -- LAY + combined_header(13 downto 12) <= (others => '0'); -- VERS + combined_header(11 downto 4) <= sequence_counter; -- SEQNR + combined_header(3 downto 0) <= APL_DTYPE_IN; + combined_trailer(F1_POSITION) <= APL_ERROR_PATTERN(31 downto 16); + combined_trailer(F2_POSITION) <= APL_ERROR_PATTERN(15 downto 0); + combined_trailer(15 downto 14) <= (others => '0'); -- res. + combined_trailer(13 downto 12) <= (others => '0'); -- VERS + combined_trailer(11 downto 4) <= sequence_counter; -- SEQNR + combined_trailer(3 downto 0) <= APL_DTYPE_IN; + -- this is not very consequent, find a better solution the be independent + -- with the range + + INT_INIT_DATA_OUT <= reg_INT_INIT_DATA_OUT; -- registered output for + -- internal port + INT_INIT_DATAREADY_OUT <= reg_INT_INIT_DATAREADY_OUT; + +-- generate the sequence counter + -- combinatorial part + SEQNR_COMB : process(sequence_counter) + begin + if current_state = SEND_TRAILER and next_state = WAITING then + next_sequence_counter <= sequence_counter+1; + else + next_sequence_counter <= sequence_counter; + end if; + end process; + +CLK_REG: process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + sequence_counter <= (others => '0'); + reg_INT_INIT_DATA_OUT <= (others => '0'); + reg_INT_INIT_DATAREADY_OUT <= '0'; + current_state <= IDLE; + registered_header <= (others => '0'); + registered_trailer <= (others => '0'); + elsif CLK_EN = '1' then + sequence_counter <= next_sequence_counter; + reg_INT_INIT_DATA_OUT <= next_INT_INIT_DATA_OUT; + reg_INT_INIT_DATAREADY_OUT <= next_INT_INIT_DATAREADY_OUT; + current_state <= next_state; + registered_header <= next_registered_header; + registered_trailer <= next_registered_trailer; + else + sequence_counter <= sequence_counter; + reg_INT_INIT_DATA_OUT <= reg_INT_INIT_DATA_OUT; + reg_INT_INIT_DATAREADY_OUT <= reg_INT_INIT_DATAREADY_OUT; + current_state <= current_state; + registered_header <= registered_header; + registered_trailer <= registered_trailer; + end if; + end if; + end process; + +end trb_net_active_api_arch; diff --git a/trb_net_iobuf.vhd b/trb_net_iobuf.vhd index 8394254..290ea71 100644 --- a/trb_net_iobuf.vhd +++ b/trb_net_iobuf.vhd @@ -60,8 +60,8 @@ entity trb_net_iobuf is STAT_REPLY_BUFFER: out STD_LOGIC_VECTOR (31 downto 0); -- General Status CTRL_GEN: in STD_LOGIC_VECTOR (31 downto 0); CTRL_LOCKED: in STD_LOGIC_VECTOR (31 downto 0); - CTRL_INIT_BUFFER: in STD_LOGIC_VECTOR (31 downto 0); - CTRL_REPLY_BUFFER: in STD_LOGIC_VECTOR (31 downto 0) + STAT_CTRL_INIT_BUFFER: in STD_LOGIC_VECTOR (31 downto 0); + STAT_CTRL_REPLY_BUFFER: in STD_LOGIC_VECTOR (31 downto 0) ); END trb_net_iobuf; @@ -151,6 +151,10 @@ architecture trb_net_iobuf_arch of trb_net_iobuf is signal REPLYOBUF_error_out: STD_LOGIC_VECTOR (2 downto 0); signal REPLYOBUF_stat_locked, REPLYOBUF_ctrl_locked: STD_LOGIC_VECTOR (15 downto 0); signal REPLYOBUF_stat_buffer, REPLYOBUF_ctrl_buffer: STD_LOGIC_VECTOR (31 downto 0); + +-- locking control + signal INIT_IS_LOCKED, REPLY_IS_LOCKED: STD_LOGIC; + signal next_INIT_IS_LOCKED, next_REPLY_IS_LOCKED: STD_LOGIC; begin @@ -242,6 +246,64 @@ architecture trb_net_iobuf_arch of trb_net_iobuf is STAT_REPLY_BUFFER(15 downto 14) <= REPLYOBUF_stat_buffer(1 downto 0); STAT_REPLY_BUFFER(31 downto 16) <= REPLYOBUF_stat_buffer(31 downto 16); +-- build the CTRL register of the OBUFs + INITOBUF_ctrl_buffer(9 downto 0) <= INITIBUF_stat_buffer(9 downto 0); + REPLYOBUF_ctrl_buffer(9 downto 0) <= REPLYIBUF_stat_buffer(9 downto 0); + + -- comb part of the locking control +comb_locked : process (INIT_IS_LOCKED, REPLY_IS_LOCKED, INITIBUF_stat_locked, REPLYOBUF_stat_locked, REPLYIBUF_stat_locked, INITOBUF_stat_locked, CTRL_LOCKED) + + begin -- process + next_INIT_IS_LOCKED <= INIT_IS_LOCKED; + next_REPLY_IS_LOCKED <= REPLY_IS_LOCKED; + REPLYOBUF_ctrl_locked <= (others => '0'); + REPLYIBUF_ctrl_locked <= (others => '0'); + INITOBUF_ctrl_locked <= (others => '0'); + INITIBUF_ctrl_locked <= (others => '0'); + if INITIBUF_stat_locked(0) = '1' then + next_INIT_IS_LOCKED <= '1'; + elsif REPLYOBUF_stat_locked(0) = '1' or CTRL_LOCKED(0) = '1' then + next_INIT_IS_LOCKED <= '0'; + end if; + if REPLYIBUF_stat_locked(0) = '1' then + next_REPLY_IS_LOCKED <= '1'; + elsif INITOBUF_stat_locked(0) = '1' or CTRL_LOCKED(1) = '1' then + next_REPLY_IS_LOCKED <= '0'; + end if; + + if INIT_IS_LOCKED = '0' and next_INIT_IS_LOCKED = '1' then + REPLYOBUF_ctrl_locked(0) <= '1'; + end if; + if INIT_IS_LOCKED = '1' and next_INIT_IS_LOCKED = '0' then + INITIBUF_ctrl_locked(0) <= '1'; + end if; + if REPLY_IS_LOCKED = '0' and next_REPLY_IS_LOCKED = '1' then + INITOBUF_ctrl_locked(0) <= '1'; + end if; + if REPLY_IS_LOCKED = '1' and next_REPLY_IS_LOCKED = '0' then + REPLYIBUF_ctrl_locked(0) <= '1'; + end if; + end process; + + reg_locked: process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + INIT_IS_LOCKED <= '0'; + REPLY_IS_LOCKED <= '0'; + elsif CLK_EN = '1' then + INIT_IS_LOCKED <= next_INIT_IS_LOCKED; + REPLY_IS_LOCKED <= next_REPLY_IS_LOCKED; + else + INIT_IS_LOCKED <= INIT_IS_LOCKED; + REPLY_IS_LOCKED <= REPLY_IS_LOCKED; + end if; + end if; + end process; + + + + end trb_net_iobuf_arch; diff --git a/trb_net_std.vhd b/trb_net_std.vhd index 01d1d94..becfded 100644 --- a/trb_net_std.vhd +++ b/trb_net_std.vhd @@ -25,7 +25,8 @@ package trb_net_std is subtype F1_POSITION is integer range 47 downto 32; subtype F2_POSITION is integer range 31 downto 16; subtype F3_POSITION is integer range 15 downto 0; - + subtype DWORD_POSITION is integer range 47 downto 0; + constant F1_CHECK_ACK : std_logic_vector(15 downto 0) := x"0000"; subtype BUFFER_SIZE_POSITION is integer range 19 downto 16;