From 342cfdbfb9b7f3d08c59897da0e936aca027a294 Mon Sep 17 00:00:00 2001 From: hadeshyp Date: Mon, 22 Dec 2008 12:18:47 +0000 Subject: [PATCH] *** empty log message *** --- trb_net16_api_base.vhd | 1 + trb_net16_hub_base.vhd | 19 +- trb_net16_med_8_SDR_sync.vhd | 456 +++++++++++++++++++++++++++++++++++ trb_net16_regIO.vhd | 323 ++++++++++++++++--------- trb_net_std.vhd | 2 + 5 files changed, 683 insertions(+), 118 deletions(-) create mode 100644 trb_net16_med_8_SDR_sync.vhd diff --git a/trb_net16_api_base.vhd b/trb_net16_api_base.vhd index 9af3988..e2e3ec6 100644 --- a/trb_net16_api_base.vhd +++ b/trb_net16_api_base.vhd @@ -34,6 +34,7 @@ entity trb_net16_api_base is APL_SHORT_TRANSFER_IN : in std_logic; APL_DTYPE_IN : in std_logic_vector (3 downto 0); APL_ERROR_PATTERN_IN : in std_logic_vector (31 downto 0); + APL_LENGTH_IN : in std_logic_vector (15 downto 0); APL_SEND_IN : in std_logic; APL_TARGET_ADDRESS_IN : in std_logic_vector (15 downto 0);-- the target (only for active APIs) diff --git a/trb_net16_hub_base.vhd b/trb_net16_hub_base.vhd index ad856a7..7ae760d 100644 --- a/trb_net16_hub_base.vhd +++ b/trb_net16_hub_base.vhd @@ -490,14 +490,14 @@ architecture trb_net16_hub_base_arch of trb_net16_hub_base is DAT_ADDR_OUT : out std_logic_vector(c_REGIO_ADDRESS_WIDTH-1 downto 0); DAT_READ_ENABLE_OUT : out std_logic; DAT_WRITE_ENABLE_OUT: out std_logic; - DAT_DATA_OUT : out std_logic_vector(c_REGIO_REGISTER_WIDTH-1 downto 0); - --Data input can only be used as reaction on read or write access. write operation should return data - --if successful - DAT_DATA_IN : in std_logic_vector(c_REGIO_REGISTER_WIDTH-1 downto 0); - DAT_DATAREADY_IN : in std_logic; - DAT_NO_MORE_DATA_IN : in std_logic; - --finish transmission, when reading from a fifo and it got empty - --Additional write access to ctrl registers + DAT_DATA_OUT : out std_logic_vector(c_REGIO_REG_WIDTH-1 downto 0); + DAT_DATA_IN : in std_logic_vector(c_REGIO_REG_WIDTH-1 downto 0); + DAT_DATAREADY_IN : in std_logic; + DAT_NO_MORE_DATA_IN : in std_logic; + DAT_WRITE_ACK_IN : in std_logic; + DAT_UNKNOWN_ADDR_IN : in std_logic; + DAT_TIMEOUT_OUT : out std_logic; + EXT_REG_DATA_IN : in std_logic_vector(31 downto 0); EXT_REG_DATA_OUT : out std_logic_vector(31 downto 0); EXT_REG_WRITE_IN : in std_logic; @@ -1198,6 +1198,9 @@ HUB_MED_CONNECTED(31 downto MII_NUMBER) <= (others => '1'); DAT_DATA_IN => x"00000000", DAT_DATAREADY_IN => '0', DAT_NO_MORE_DATA_IN => '0', + DAT_UNKNOWN_ADDR_IN => '0', + DAT_TIMEOUT_OUT => open, + DAT_WRITE_ACK_IN => '0', EXT_REG_DATA_IN => REGIO_EXT_REG_DATA_IN, EXT_REG_WRITE_IN => REGIO_EXT_REG_WRITE_IN, EXT_REG_ADDR_IN => REGIO_EXT_REG_ADDR_IN, diff --git a/trb_net16_med_8_SDR_sync.vhd b/trb_net16_med_8_SDR_sync.vhd new file mode 100644 index 0000000..08976e7 --- /dev/null +++ b/trb_net16_med_8_SDR_sync.vhd @@ -0,0 +1,456 @@ +--media interface with 16 data lines, single data rate and oversampling of RX input +--oversampling running at 250 MHz + + + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.std_logic_ARITH.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; + +entity trb_net16_med_8_SDR_sync is + port( + -- Misc + 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); + 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); + INT_PACKET_NUM_IN : in std_logic_vector (c_NUM_WIDTH-1 downto 0); + INT_READ_OUT : out std_logic; + + -- Media direction port + TX_DATA_OUT : out std_logic_vector (15 downto 0); + TX_CTRL_OUT : out std_logic_vector (3 downto 0); + RX_DATA_IN : in std_logic_vector (15 downto 0); + RX_CTRL_IN : in std_logic_vector (3 downto 0); + + -- Status and control port + STAT_OP: out std_logic_vector (15 downto 0); + CTRL_OP: in std_logic_vector (15 downto 0); + + STAT: out std_logic_vector (31 downto 0); + CTRL: in std_logic_vector (31 downto 0) + ); +end entity; + +architecture trb_net16_med_8_SDR_sync_arch of trb_net16_med_8_SDR_sync is + + component trb_net_fifo_16bit_bram_dualport is + generic( + USE_STATUS_FLAGS : integer := c_YES + ); + port ( + read_clock_in: IN std_logic; + write_clock_in: IN std_logic; + read_enable_in: IN std_logic; + write_enable_in: IN std_logic; + fifo_gsr_in: IN std_logic; + write_data_in: IN std_logic_vector(17 downto 0); + read_data_out: OUT std_logic_vector(17 downto 0); + full_out: OUT std_logic; + empty_out: OUT std_logic; + fifostatus_out: OUT std_logic_vector(3 downto 0); + valid_read_out: OUT std_logic; + almost_empty_out:OUT std_logic; + almost_full_out :OUT std_logic + ); + end component; + + component dualdatarate_flipflop is + --1 clock, no CE, PRE for Lattice SCM + generic( + WIDTH : integer := 1 + ); + port( + C0 : in std_logic; + C1 : in std_logic; + CE : in std_logic; + CLR : in std_logic; + D0 : in std_logic_vector(WIDTH-1 downto 0); + D1 : in std_logic_vector(WIDTH-1 downto 0); + PRE : in std_logic; + Q : out std_logic_vector(WIDTH-1 downto 0) + ); + end component; + + signal RECV_CLK, recv_clk_locked : std_logic; + signal reg_RX_CLK, buf_RX_CLK, last_RX_CLK : std_logic; + signal reg_RX_CTRL, buf_RX_CTRL : std_logic_vector(3 downto 0); + signal reg_RX_DATA, buf_RX_DATA : std_logic_vector(15 downto 0); + + signal rx_datavalid : std_logic; + signal rx_first_packet : std_logic; + signal rx_reset : std_logic; + signal rx_parity : std_logic; + signal rx_parity_match : std_logic; + + signal rx_fifo_read_enable : std_logic; + signal rx_fifo_write_enable, next_rx_fifo_write_enable: std_logic; + signal rx_fifo_data_in, next_rx_fifo_data_in : std_logic_vector(17 downto 0); + signal rx_fifo_data_out : std_logic_vector(17 downto 0); + signal rx_fifo_full : std_logic; + signal rx_fifo_empty : std_logic; + signal rx_fifostatus_out : std_logic_vector(3 downto 0); + signal rx_valid_read_out : std_logic; + signal rx_almost_empty_out : std_logic; + signal rx_almost_full_out : std_logic; + + + signal buf_INT_DATAREADY_OUT : std_logic; + + signal rx_packet_counter : std_logic_vector(c_NUM_WIDTH-1 downto 0); + signal wait_for_startup : std_logic; + signal wait_for_startup_slow : std_logic; + signal rx_CLK_counter : std_logic_vector(4 downto 0); + signal rx_clock_detect : std_logic; + + signal med_reset : std_logic; + + signal tx_datavalid, tx_first_packet, tx_reset, tx_parity : std_logic; + signal buf_INT_DATA_IN : std_logic_vector(c_DATA_WIDTH-1 downto 0); + signal buf_INT_READ_OUT : std_logic; + signal tx_clock_enable : std_logic; + signal next_tx_reset : std_logic; + signal buf_tx_reset : std_logic; + signal buf_tx_clk : std_logic; + signal recv_clk_real_locked : std_logic; + signal locked_counter : std_logic_vector(19 downto 0); + + signal led_counter : std_logic_vector(18 downto 0); + signal send_resync_counter : std_logic_vector(11 downto 0); + signal send_resync : std_logic; + signal rx_led, tx_led, link_led : std_logic; + signal med_error : std_logic_vector(2 downto 0); + signal trbnet_reset : std_logic; +begin + + +--Transmitter (full speed only) +------------------------- + INT_READ_OUT <= buf_INT_READ_OUT; + buf_INT_READ_OUT <= not wait_for_startup_slow and not buf_tx_reset; + + TX_DATA_OUT <= buf_INT_DATA_IN; + TX_CTRL_OUT(0) <= tx_datavalid; + TX_CTRL_OUT(1) <= tx_first_packet; + TX_CTRL_OUT(2) <= tx_reset; + TX_CTRL_OUT(3) <= tx_parity; + + tx_clock_enable <= not RESET; + + next_tx_reset <= CTRL_OP(15) or (recv_clk_real_locked and wait_for_startup_slow); + + + process(CLK) + begin + if rising_edge(CLK) then + TX_CLK_OUT <= buf_tx_clk; + end if; + end process; + + process(CLK) + begin + if rising_edge(CLK) then + if med_reset = '1' then + tx_datavalid <= '0'; + tx_reset <= '1'; + buf_tx_reset <= '1'; + buf_INT_DATA_IN <= (others => '0'); + tx_first_packet <= '0'; + tx_parity <= '0'; + buf_tx_clk <= '0'; + else + buf_INT_DATA_IN <= INT_DATA_IN; + tx_datavalid <= INT_DATAREADY_IN and buf_INT_READ_OUT; + if INT_PACKET_NUM_IN = c_H0 then + tx_first_packet <= '1'; + else + tx_first_packet <= '0'; + end if; + tx_reset <= buf_tx_reset; + buf_tx_reset <= next_tx_reset; + tx_parity <= xor_all(INT_DATA_IN); + buf_tx_clk <= not buf_tx_clk; + end if; + end if; + end process; + + + +--Receiver +------------------------- + RECV_CLOCK_GEN : trb_net_clock_generator + generic map( + FREQUENCY_IN => 100.0, + FREQUENCY_OUT => 200.0, + CLOCK_MULT => 2, + CLOCK_DIV => 1, + CLKIN_DIVIDE_BY_2 => false, + CLKIN_PERIOD => 10.0 + ) + port map( + RESET => RESET, + CLK_IN => CLK, + CLK_OUT => RECV_CLK, + LOCKED => recv_clk_locked + ); + +process(CLK) + begin + if rising_edge(CLK) then + if recv_clk_locked = '0' then + locked_counter <= (others => '0'); + recv_clk_real_locked <= '0'; + else + if locked_counter /= x"0000F" then + locked_counter <= locked_counter + 1; + else + recv_clk_real_locked <= '1'; + end if; + end if; + end if; + end process; + + RX_INPUT_REG : process(RECV_CLK) + begin + if rising_edge(RECV_CLK) then + reg_RX_CLK <= RX_CLK_IN; + reg_RX_CTRL <= RX_CTRL_IN; + reg_RX_DATA <= RX_DATA_IN; + end if; + end process; + + RX_REG : process(RECV_CLK, recv_clk_real_locked) + begin + if rising_edge(RECV_CLK) then + if recv_clk_real_locked = '0' then + buf_RX_CTRL <= (others => '0'); + buf_RX_CLK <= '0'; + last_RX_CLK <= '0'; + buf_RX_DATA <= (others => '0'); + else + buf_RX_CLK <= reg_RX_CLK; + buf_RX_DATA <= reg_RX_DATA; + buf_RX_CTRL <= reg_RX_CTRL; + last_RX_CLK <= buf_RX_CLK; + end if; + end if; + end process; + + rx_datavalid <= buf_RX_CTRL(0); + rx_first_packet <= buf_RX_CTRL(1); + rx_reset <= buf_RX_CTRL(2); + rx_parity <= buf_RX_CTRL(3); + + rx_parity_match <= '1' when rx_parity = xor_all(buf_RX_DATA) else '0'; + next_rx_fifo_write_enable <= (buf_RX_CLK xor last_RX_CLK) and rx_datavalid; + next_rx_fifo_data_in <= rx_first_packet & rx_parity_match & buf_RX_DATA; + + reg_fifo_in : process(RECV_CLK) + begin + if rising_edge(RECV_CLK) then + rx_fifo_write_enable <= next_rx_fifo_write_enable; + rx_fifo_data_in <= next_rx_fifo_data_in; + end if; + end process; + + RX_FIFO : trb_net_fifo_16bit_bram_dualport + port map( + read_clock_in => CLK, + write_clock_in => RECV_CLK, + read_enable_in => rx_fifo_read_enable, + write_enable_in => rx_fifo_write_enable, + fifo_gsr_in => med_reset, + write_data_in => rx_fifo_data_in, + read_data_out => rx_fifo_data_out, + full_out => rx_fifo_full, + empty_out => rx_fifo_empty, + fifostatus_out => rx_fifostatus_out, + valid_read_out => rx_valid_read_out, + almost_empty_out => rx_almost_empty_out, + almost_full_out => rx_almost_full_out + ); + + rx_fifo_read_enable <= INT_READ_IN; + + INT_DATA_OUT <= rx_fifo_data_out(15 downto 0); + INT_PACKET_NUM_OUT <= rx_packet_counter; + INT_DATAREADY_OUT <= buf_INT_DATAREADY_OUT; + + packet_counter_p : process(CLK) + begin + if rising_edge(CLK) then + if med_reset = '1' then + rx_packet_counter <= "100"; + elsif buf_INT_DATAREADY_OUT = '1' then + if rx_packet_counter = c_max_word_number then + rx_packet_counter <= (others => '0'); + else + rx_packet_counter <= rx_packet_counter + 1; + end if; + end if; + end if; + end process; + + + rx_dataready_p : process(CLK) + begin + if rising_edge(CLK) then + if med_reset = '1' then + buf_INT_DATAREADY_OUT <= '0'; + else + buf_INT_DATAREADY_OUT <= rx_fifo_read_enable and not rx_fifo_empty; + end if; + end if; + end process; + + +--monitor link +------------------------- + process(CLK) + begin + if rising_edge(CLK) then + wait_for_startup_slow <= wait_for_startup; + end if; + end process; + + process(RECV_CLK, recv_clk_real_locked,med_reset) + begin + if rising_edge(RECV_CLK) then + if recv_clk_real_locked = '0' or med_reset = '1' or rx_clock_detect = '0' then + wait_for_startup <= '1'; + elsif rx_reset = '1' and recv_clk_locked = '1' then + wait_for_startup <= '0'; + end if; + end if; + end process; + + + ERROR_OUT_gen : process(CLK) + begin + if rising_edge(CLK) then + if recv_clk_real_locked = '0' or rx_clock_detect = '0' then + med_error <= ERROR_NC; + elsif (buf_INT_DATAREADY_OUT = '1' and rx_fifo_data_out(16) = '0') then --Parity error + med_error <= ERROR_ENCOD; + elsif (rx_packet_counter /= "100" and buf_INT_DATAREADY_OUT = '1' and rx_fifo_data_out(17) = '1') then + med_error <= ERROR_FATAL; --Counter error + else + med_error <= ERROR_OK; + end if; + end if; + end process; + + + rx_clk_detect_counter: process (RECV_CLK, recv_clk_real_locked) + begin + if rising_edge(RECV_CLK) then + if recv_clk_real_locked = '0' then + rx_CLK_counter <= (others => '0'); + rx_clock_detect <= '0'; + elsif buf_RX_CLK = '1' and last_RX_CLK = '0' then + rx_CLK_counter <= (others => '0'); + rx_clock_detect <= '1'; + elsif rx_CLK_counter /= 31 then + rx_CLK_counter <= rx_CLK_counter + 1; + elsif rx_CLK_counter = 31 then + rx_clock_detect <= '0'; + end if; + end if; + end process; + + +--STAT & CTRL Ports +------------------------- + +--LED + link_led <= rx_clock_detect and not wait_for_startup_slow; + + process(CLK) + begin + if rising_edge(CLK) then + if led_counter(18) = '1' then + led_counter <= (others => '0'); + else + led_counter <= led_counter + 1; + end if; + if rx_fifo_empty = '0' then + rx_led <= '1'; + elsif led_counter(18) = '1' then + rx_led <= '0'; + end if; + if tx_datavalid = '1' then + tx_led <= '1'; + elsif led_counter(18) = '1' then + tx_led <= '0'; + end if; + end if; + end process; + + + STAT_OP(2 downto 0) <= med_error; + STAT_OP(8 downto 3) <= (others => '0'); + STAT_OP(9) <= link_led; + STAT_OP(10) <= rx_led; + STAT_OP(11) <= tx_led; + STAT_OP(12) <= '0'; + STAT_OP(13) <= trbnet_reset; + STAT_OP(14) <= rx_clock_detect; + STAT_OP(15) <= '1' when rx_reset = '1' and wait_for_startup_slow = '0' else '0'; + + STAT(12) <= rx_parity_match; + STAT(11) <= RECV_CLK; + STAT(10) <= recv_clk_real_locked; + STAT(9) <= rx_reset; + STAT(8) <= buf_RX_CLK xor last_RX_CLK; + STAT(7) <= recv_clk_locked; + STAT(6) <= wait_for_startup; + STAT(5) <= rx_first_packet; + STAT(4) <= buf_tx_clk; --not or_all(INT_PACKET_NUM_IN); --tx_first_packet; + STAT(3) <= rx_datavalid; + STAT(2) <= next_tx_reset; + STAT(1) <= buf_RX_CLK; + + STAT(13) <= or_all(rx_fifostatus_out); + STAT(14) <= rx_valid_read_out; + STAT(15) <= rx_almost_empty_out; + STAT(16) <= rx_almost_full_out; + STAT(31 downto 17) <= (others => '0'); + + med_reset <= RESET or send_resync; + trbnet_reset <= rx_reset or not recv_clk_real_locked; + + +--detect resync + process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + send_resync <= '0'; + send_resync_counter <= (others => '0'); + else + if not (send_resync_counter = 0) then + send_resync_counter <= send_resync_counter + 1; + end if; + if CTRL_OP(15) = '1' and send_resync_counter(11 downto 4) = 0 then + send_resync <= '1'; + send_resync_counter <= send_resync_counter + 1; + end if; + if send_resync_counter = x"00F" then + send_resync <= '0'; + end if; + end if; + end if; + end process; + +end architecture; \ No newline at end of file diff --git a/trb_net16_regIO.vhd b/trb_net16_regIO.vhd index 186af9f..cf6f8ca 100644 --- a/trb_net16_regIO.vhd +++ b/trb_net16_regIO.vhd @@ -17,7 +17,7 @@ entity trb_net16_regIO is INIT_CTRL_REGS : std_logic_vector(2**(3)*32-1 downto 0) := (others => '0'); --set to 0 for unused ctrl registers to save resources - USED_CTRL_REGS : std_logic_vector(2**(3)-1 downto 0) := "00001111"; + USED_CTRL_REGS : std_logic_vector(2**(3)-1 downto 0) := "00000001"; --set to 0 for each unused bit in a register USED_CTRL_BITMASK : std_logic_vector(2**(3)*32-1 downto 0) := (others => '1'); @@ -62,22 +62,23 @@ entity trb_net16_regIO is MY_ADDRESS_OUT : out std_logic_vector(15 downto 0); --Common Register in / out - COMMON_STAT_REG_IN : in std_logic_vector(std_COMSTATREG*c_REGIO_REGISTER_WIDTH-1 downto 0); - COMMON_CTRL_REG_OUT : out std_logic_vector(std_COMCTRLREG*c_REGIO_REGISTER_WIDTH-1 downto 0); + COMMON_STAT_REG_IN : in std_logic_vector(std_COMSTATREG*c_REGIO_REG_WIDTH-1 downto 0); + COMMON_CTRL_REG_OUT : out std_logic_vector(std_COMCTRLREG*c_REGIO_REG_WIDTH-1 downto 0); --Custom Register in / out - REGISTERS_IN : in std_logic_vector(c_REGIO_REGISTER_WIDTH*2**(NUM_STAT_REGS)-1 downto 0); - REGISTERS_OUT : out std_logic_vector(c_REGIO_REGISTER_WIDTH*2**(NUM_CTRL_REGS)-1 downto 0); + REGISTERS_IN : in std_logic_vector(c_REGIO_REG_WIDTH*2**(NUM_STAT_REGS)-1 downto 0); + REGISTERS_OUT : out std_logic_vector(c_REGIO_REG_WIDTH*2**(NUM_CTRL_REGS)-1 downto 0); --Internal Data Port DAT_ADDR_OUT : out std_logic_vector(c_REGIO_ADDRESS_WIDTH-1 downto 0); DAT_READ_ENABLE_OUT : out std_logic; DAT_WRITE_ENABLE_OUT: out std_logic; - DAT_DATA_OUT : out std_logic_vector(c_REGIO_REGISTER_WIDTH-1 downto 0); - --Data input can only be used as reaction on read or write access. write operation should return data - --if successful - DAT_DATA_IN : in std_logic_vector(c_REGIO_REGISTER_WIDTH-1 downto 0); - DAT_DATAREADY_IN : in std_logic; - DAT_NO_MORE_DATA_IN : in std_logic; - --finish transmission, when reading from a fifo and it got empty + DAT_DATA_OUT : out std_logic_vector(c_REGIO_REG_WIDTH-1 downto 0); + DAT_DATA_IN : in std_logic_vector(c_REGIO_REG_WIDTH-1 downto 0); + DAT_DATAREADY_IN : in std_logic; + DAT_NO_MORE_DATA_IN : in std_logic; + DAT_WRITE_ACK_IN : in std_logic; + DAT_UNKNOWN_ADDR_IN : in std_logic; + DAT_TIMEOUT_OUT : out std_logic; + --Additional write access to ctrl registers EXT_REG_DATA_IN : in std_logic_vector(31 downto 0); EXT_REG_DATA_OUT : out std_logic_vector(31 downto 0); @@ -148,7 +149,7 @@ architecture trb_net16_regIO_arch of trb_net16_regIO is type fsm_state_t is (IDLE, HEADER_RECV, REG_READ, REG_WRITE, ONE_READ, ONE_WRITE, SEND_REPLY_SHORT_TRANSFER, MEM_START_WRITE, MEM_READ, MEM_WRITE, DAT_START_READ, DAT_READ, SEND_REPLY_DATA_finish, ADDRESS_ACK, ADDRESS_RECV, - MEM_START_READ, DAT_START_READ_AFTER_WRITE); + MEM_START_READ, SEND_RW_ERROR, MEM_WRITE_2, WAIT_AFTER_REG_WRITE); signal current_state, next_state : fsm_state_t; -- signal HDR_F1, HDR_F2, HDR_F3, HDR_F0 : std_logic_vector(c_DATA_WIDTH-1 downto 0); -- signal next_HDR_F1, next_HDR_F2, next_HDR_F3, next_HDR_F0 : std_logic_vector(c_DATA_WIDTH-1 downto 0); @@ -164,21 +165,21 @@ architecture trb_net16_regIO_arch of trb_net16_regIO is signal buf_API_SHORT_TRANSFER_OUT, next_API_SHORT_TRANSFER_OUT : std_logic; signal buf_API_DATAREADY_OUT, next_API_DATAREADY_OUT : std_logic; - signal buf_DAT_DATA_OUT : std_logic_vector(c_REGIO_REGISTER_WIDTH-1 downto 0); - signal buf_DAT_DATA_IN : std_logic_vector(c_REGIO_REGISTER_WIDTH-1 downto 0); + signal buf_DAT_DATA_OUT : std_logic_vector(c_REGIO_REG_WIDTH-1 downto 0); + signal buf_DAT_DATA_IN : std_logic_vector(c_REGIO_REG_WIDTH-1 downto 0); signal buf_DAT_READ_ENABLE_OUT, next_DAT_READ_ENABLE_OUT : std_logic; signal buf_DAT_WRITE_ENABLE_OUT, next_DAT_WRITE_ENABLE_OUT : std_logic; signal buf_DAT_ADDR_OUT : std_logic_vector(c_REGIO_ADDRESS_WIDTH-1 downto 0); - signal buf_REGISTERS_OUT : std_logic_vector(c_REGIO_REGISTER_WIDTH*2**(NUM_CTRL_REGS)-1 downto 0); + signal buf_REGISTERS_OUT : std_logic_vector(c_REGIO_REG_WIDTH*2**(NUM_CTRL_REGS)-1 downto 0); signal REGISTERS_OUT_write_enable : std_logic_vector(2**(NUM_CTRL_REGS)-1 downto 0); signal next_REGISTERS_OUT_write_enable : std_logic_vector(2**(NUM_CTRL_REGS)-1 downto 0); signal reg_enable_pattern : std_logic_vector(63 downto 0); signal next_COMMON_REGISTERS_OUT_write_enable: std_logic_vector(std_COMCTRLREG - 1 downto 0); signal COMMON_REGISTERS_OUT_write_enable : std_logic_vector(std_COMCTRLREG - 1 downto 0); - signal buf_COMMON_CTRL_REG_OUT : std_logic_vector(c_REGIO_REGISTER_WIDTH*std_COMCTRLREG-1 downto 0); + signal buf_COMMON_CTRL_REG_OUT : std_logic_vector(c_REGIO_REG_WIDTH*std_COMCTRLREG-1 downto 0); signal state_bits : std_logic_vector(3 downto 0); signal ADR_SEND_OUT : std_logic; @@ -197,6 +198,20 @@ architecture trb_net16_regIO_arch of trb_net16_regIO is signal packet_counter : std_logic_vector(c_NUM_WIDTH-1 downto 0); signal next_packet_counter : std_logic_vector(c_NUM_WIDTH-1 downto 0); signal addr_counter_enable, next_addr_counter_enable : std_logic; + signal timeout_counter : std_logic_vector(c_regio_timeout_bit downto 0); + signal next_timeout_counter : std_logic_vector(c_regio_timeout_bit downto 0); + signal timeout : std_logic; + signal next_timeout : std_logic; + signal unknown : std_logic; + signal next_unknown : std_logic; + signal next_API_READ_OUT : std_logic; + signal next_nomoredata : std_logic; + signal nomoredata : std_logic; + signal DAT_DATAREADY_IN_before : std_logic; + signal combined_API_READ_OUT : std_logic; + signal dat_data_counter : std_logic_vector(15 downto 0); + signal next_dat_data_counter : std_logic_vector(15 downto 0); + begin @@ -238,15 +253,15 @@ begin buf_DAT_ADDR_OUT <= address; buf_DAT_DATA_OUT <= saved_Reg_high & saved_Reg_low; - fsm : process(current_state, - API_DATA_IN, API_PACKET_NUM_IN, API_TYP_IN, API_DATAREADY_IN, API_READ_IN, - address, saved_Reg_high, saved_Reg_low, saved_operation, + fsm : process(API_DATA_IN, API_PACKET_NUM_IN, API_TYP_IN, API_DATAREADY_IN, API_READ_IN, + address, saved_Reg_high, saved_Reg_low, saved_operation, current_state, buf_API_SEND_OUT, next_packet_counter, buf_API_DATA_OUT, buf_API_SHORT_TRANSFER_OUT, REGISTERS_IN, buf_REGISTERS_OUT, reg_enable_pattern, DAT_NO_MORE_DATA_IN, - DAT_DATAREADY_IN, buf_DAT_DATA_IN, ADR_REJECTED, + DAT_DATAREADY_IN, buf_DAT_DATA_IN, ADR_REJECTED, timeout_counter, nomoredata, ADR_READ_OUT, ADR_DATAREADY_OUT, ADR_DATA_OUT, length, dont_understand, - buf_rom_read_addr, ADR_SEND_OUT, rom_read_dout, COMMON_STAT_REG_IN, buf_COMMON_CTRL_REG_OUT --- , HDR_F1, HDR_F2, HDR_F3 + buf_rom_read_addr, ADR_SEND_OUT, rom_read_dout, COMMON_STAT_REG_IN, buf_COMMON_CTRL_REG_OUT, + timeout, unknown, addr_counter_enable, DAT_UNKNOWN_ADDR_IN, dat_data_counter, + DAT_WRITE_ACK_IN, DAT_DATAREADY_IN_before ) variable regnum_STAT : integer range 0 to 2**NUM_STAT_REGS-1; variable regnum_CTRL : integer range 0 to 2**NUM_CTRL_REGS-1; @@ -254,15 +269,11 @@ begin variable regnum_cCTRL : integer range 0 to std_COMCTRLREG-1; begin next_state <= current_state; --- next_HDR_F1 <= HDR_F1; --- next_HDR_F2 <= HDR_F2; --- next_HDR_F3 <= HDR_F3; next_address <= address; next_Reg_high <= saved_Reg_high; next_Reg_low <= saved_Reg_low; ADR_DATAREADY_IN <= '0'; ADR_READ_IN <= '0'; - buf_API_READ_OUT <= '1'; next_API_SEND_OUT <= buf_API_SEND_OUT; next_API_DATAREADY_OUT <= '0'; next_API_DATA_OUT <= buf_API_DATA_OUT; @@ -279,12 +290,23 @@ begin regnum_cSTAT := conv_integer(address(std_COMneededwidth-1 downto 0)); regnum_cCTRL := conv_integer(address(std_COMneededwidth-1 downto 0)); next_dont_understand <= dont_understand; + next_timeout <= timeout; + next_unknown <= unknown; + next_nomoredata <= nomoredata; + next_timeout_counter <= (others => '0'); + next_addr_counter_enable <= addr_counter_enable; + next_API_READ_OUT <= '1'; + next_dat_data_counter <= dat_data_counter; case current_state is when IDLE => next_dont_understand <= '0'; next_API_SEND_OUT <= '0'; next_API_SHORT_TRANSFER_OUT <= '0'; + next_unknown <= '0'; + next_timeout <= '0'; + next_nomoredata <= '0'; + next_dat_data_counter <= (others => '0'); if API_TYP_IN = TYPE_HDR then next_state <= HEADER_RECV; end if; @@ -292,14 +314,7 @@ begin when HEADER_RECV => --read and save HDR if API_DATAREADY_IN = '1' then case API_PACKET_NUM_IN is --- when c_F0 => --- next_HDR_F0 <= API_DATA_IN; --- when c_F1 => --- next_HDR_F1 <= API_DATA_IN; --- when c_F2 => --- next_HDR_F2 <= API_DATA_IN; when c_F3 => --- next_HDR_F3 <= API_DATA_IN; case API_DATA_IN(3 downto 0) is when c_read_register_type => next_state <= ONE_READ; when c_write_register_type => next_state <= ONE_WRITE; @@ -317,7 +332,6 @@ begin when ADDRESS_RECV => ADR_DATAREADY_IN <= API_DATAREADY_IN; - buf_API_READ_OUT <= ADR_READ_OUT; ADR_READ_IN <= '0'; if ADR_REJECTED = '1' then next_state <= SEND_REPLY_SHORT_TRANSFER; @@ -395,12 +409,23 @@ begin next_state <= REG_READ; else next_DAT_WRITE_ENABLE_OUT <= '1'; - next_state <= DAT_START_READ_AFTER_WRITE; + next_state <= WAIT_AFTER_REG_WRITE; end if; when others => null; end case; end if; + when WAIT_AFTER_REG_WRITE => + next_timeout_counter <= timeout_counter + 1; + if DAT_WRITE_ACK_IN = '1' then + next_state <= SEND_REPLY_SHORT_TRANSFER; + elsif DAT_NO_MORE_DATA_IN = '1' or DAT_UNKNOWN_ADDR_IN = '1' or timeout_counter(c_regio_timeout_bit) = '1' then + next_state <= SEND_RW_ERROR; + next_timeout <= timeout_counter(c_regio_timeout_bit); + next_unknown <= DAT_UNKNOWN_ADDR_IN; + next_nomoredata <= DAT_NO_MORE_DATA_IN; + end if; + when REG_READ => next_API_SEND_OUT <= '1'; next_API_DATAREADY_OUT <= '1'; @@ -412,25 +437,25 @@ begin next_API_DATA_OUT <= rom_read_dout; rom_read_addr <= address(1 downto 0) & '0'; elsif address(7 downto 6) = "10" then - next_API_DATA_OUT <= REGISTERS_IN(regnum_STAT*c_REGIO_REGISTER_WIDTH+31 downto regnum_STAT*c_REGIO_REGISTER_WIDTH+16); + next_API_DATA_OUT <= REGISTERS_IN(regnum_STAT*c_REGIO_REG_WIDTH+31 downto regnum_STAT*c_REGIO_REG_WIDTH+16); elsif address(7 downto 6) = "11" then - next_API_DATA_OUT <= buf_REGISTERS_OUT(regnum_CTRL*c_REGIO_REGISTER_WIDTH+31 downto regnum_CTRL*c_REGIO_REGISTER_WIDTH+16); + next_API_DATA_OUT <= buf_REGISTERS_OUT(regnum_CTRL*c_REGIO_REG_WIDTH+31 downto regnum_CTRL*c_REGIO_REG_WIDTH+16); elsif address(5) = '0' then - next_API_DATA_OUT <= COMMON_STAT_REG_IN(regnum_cSTAT*c_REGIO_REGISTER_WIDTH+31 downto regnum_cSTAT*c_REGIO_REGISTER_WIDTH+16); + next_API_DATA_OUT <= COMMON_STAT_REG_IN(regnum_cSTAT*c_REGIO_REG_WIDTH+31 downto regnum_cSTAT*c_REGIO_REG_WIDTH+16); else --if address(5) = '1' then - next_API_DATA_OUT <= buf_COMMON_CTRL_REG_OUT(regnum_cCTRL*c_REGIO_REGISTER_WIDTH+31 downto regnum_cCTRL*c_REGIO_REGISTER_WIDTH+16); + next_API_DATA_OUT <= buf_COMMON_CTRL_REG_OUT(regnum_cCTRL*c_REGIO_REG_WIDTH+31 downto regnum_cCTRL*c_REGIO_REG_WIDTH+16); end if; when c_F2 => if address(7 downto 6) = "01" then next_API_DATA_OUT <= rom_read_dout; elsif address(7 downto 6) = "10" then - next_API_DATA_OUT <= REGISTERS_IN(regnum_STAT*c_REGIO_REGISTER_WIDTH+15 downto regnum_STAT*c_REGIO_REGISTER_WIDTH); + next_API_DATA_OUT <= REGISTERS_IN(regnum_STAT*c_REGIO_REG_WIDTH+15 downto regnum_STAT*c_REGIO_REG_WIDTH); elsif address(7 downto 6) = "11" then - next_API_DATA_OUT <= buf_REGISTERS_OUT(regnum_CTRL*c_REGIO_REGISTER_WIDTH+15 downto regnum_CTRL*c_REGIO_REGISTER_WIDTH); + next_API_DATA_OUT <= buf_REGISTERS_OUT(regnum_CTRL*c_REGIO_REG_WIDTH+15 downto regnum_CTRL*c_REGIO_REG_WIDTH); elsif address(5) = '0' then - next_API_DATA_OUT <= COMMON_STAT_REG_IN(regnum_cSTAT*c_REGIO_REGISTER_WIDTH+15 downto regnum_cSTAT*c_REGIO_REGISTER_WIDTH); + next_API_DATA_OUT <= COMMON_STAT_REG_IN(regnum_cSTAT*c_REGIO_REG_WIDTH+15 downto regnum_cSTAT*c_REGIO_REG_WIDTH); else --if address(5) = '1' then - next_API_DATA_OUT <= buf_COMMON_CTRL_REG_OUT(regnum_cCTRL*c_REGIO_REGISTER_WIDTH+15 downto regnum_cCTRL*c_REGIO_REGISTER_WIDTH); + next_API_DATA_OUT <= buf_COMMON_CTRL_REG_OUT(regnum_cCTRL*c_REGIO_REG_WIDTH+15 downto regnum_cCTRL*c_REGIO_REG_WIDTH); end if; when c_F3 => next_API_DATA_OUT <= (others => '0'); @@ -446,16 +471,19 @@ begin next_state <= SEND_REPLY_SHORT_TRANSFER; next_dont_understand <= '1'; else - if API_TYP_IN = TYPE_DAT and API_PACKET_NUM_IN = c_F1 and API_DATAREADY_IN = '1' then - next_length <= '0' & API_DATA_IN(14 downto 0); - next_addr_counter_enable <= API_DATA_IN(15); - next_DAT_READ_ENABLE_OUT <= '1'; - next_state <= MEM_READ; - elsif API_TYP_IN = TYPE_DAT and API_PACKET_NUM_IN = c_F0 and API_DATAREADY_IN = '1' then - next_address <= API_DATA_IN; - if API_DATA_IN(15 downto 8) = 0 then - next_state <= SEND_REPLY_SHORT_TRANSFER; - next_dont_understand <= '1'; + if API_TYP_IN = TYPE_DAT and API_DATAREADY_IN = '1' then + if API_PACKET_NUM_IN = c_F1 then + next_length <= '0' & API_DATA_IN(14 downto 0); + next_addr_counter_enable <= API_DATA_IN(15); + next_DAT_READ_ENABLE_OUT <= '1'; + next_dat_data_counter <= dat_data_counter + 1; + next_state <= MEM_READ; + elsif API_PACKET_NUM_IN = c_F0 then + next_address <= API_DATA_IN; + if API_DATA_IN(15 downto 8) = 0 then + next_state <= SEND_REPLY_SHORT_TRANSFER; + next_dont_understand <= '1'; + end if; end if; end if; end if; @@ -464,15 +492,23 @@ begin next_API_DATAREADY_OUT <= '1'; case next_packet_counter is when c_F0 => - if DAT_DATAREADY_IN = '0' then + next_timeout_counter <= timeout_counter + 1; + if DAT_DATAREADY_IN = '0' and DAT_DATAREADY_IN_before = '0' then next_API_DATAREADY_OUT <= '0'; end if; if length = 0 or DAT_NO_MORE_DATA_IN = '1' then - next_state <= SEND_REPLY_DATA_finish; + next_state <= SEND_REPLY_SHORT_TRANSFER; + next_nomoredata <= DAT_NO_MORE_DATA_IN; next_API_DATAREADY_OUT <= '0'; - else + elsif DAT_UNKNOWN_ADDR_IN = '1' then + next_state <= SEND_REPLY_DATA_finish; + next_unknown <= '1'; + elsif DAT_DATAREADY_IN = '1' then next_API_SEND_OUT <= '1'; next_API_DATA_OUT <= address; + elsif timeout_counter(c_regio_timeout_bit) = '1' then + next_state <= SEND_REPLY_DATA_finish; + next_timeout <= '1'; end if; when c_F1 => next_API_DATA_OUT <= buf_DAT_DATA_IN(31 downto 16); @@ -483,6 +519,8 @@ begin next_API_DATA_OUT <= (others => '0'); if length > 1 and API_READ_IN = '1' then next_DAT_READ_ENABLE_OUT <= '1'; + next_dat_data_counter <= dat_data_counter + 1; + next_timeout_counter <= (others => '0'); if addr_counter_enable = '1' then next_address <= address + 1; end if; @@ -494,68 +532,97 @@ begin if USE_DAT_PORT = c_NO then next_state <= SEND_REPLY_SHORT_TRANSFER; next_dont_understand <= '1'; - elsif API_PACKET_NUM_IN = c_F0 and API_TYP_IN = TYPE_DAT and API_DATAREADY_IN = '1' then - next_address <= API_DATA_IN; - elsif API_PACKET_NUM_IN = c_F1 and API_TYP_IN = TYPE_DAT and API_DATAREADY_IN = '1' then - next_addr_counter_enable <= API_DATA_IN(15); - elsif API_PACKET_NUM_IN = c_F3 and API_TYP_IN = TYPE_DAT and API_DATAREADY_IN = '1' then - next_state <= MEM_WRITE; + else + if API_TYP_IN = TYPE_DAT and API_DATAREADY_IN = '1' then + if API_PACKET_NUM_IN = c_F0 then + next_address <= API_DATA_IN; + elsif API_PACKET_NUM_IN = c_F1 then + next_addr_counter_enable <= API_DATA_IN(15); + elsif API_PACKET_NUM_IN = c_F3 then + next_state <= MEM_WRITE; + end if; + end if; end if; when MEM_WRITE => - if USE_DAT_PORT = c_NO then - next_state <= SEND_REPLY_SHORT_TRANSFER; - next_dont_understand <= '1'; - elsif API_DATAREADY_IN = '1' then + if API_DATAREADY_IN = '1' then case API_PACKET_NUM_IN is when c_F1 => - next_Reg_high <= API_DATA_IN; + next_Reg_high <= API_DATA_IN; when c_F2 => - next_Reg_low <= API_DATA_IN; + next_Reg_low <= API_DATA_IN; next_DAT_WRITE_ENABLE_OUT <= '1'; + next_dat_data_counter <= dat_data_counter + 1; + next_API_READ_OUT <= '0'; + next_state <= MEM_WRITE_2; when c_F3 => if addr_counter_enable = '1' then - next_address <= address + 1; + next_address <= address + 1; end if; when others => null; end case; if API_TYP_IN = TYPE_TRM then - next_state <= DAT_START_READ; - next_DAT_READ_ENABLE_OUT <= '1'; - next_API_SEND_OUT <= '1'; + next_state <= SEND_REPLY_SHORT_TRANSFER; end if; end if; - when DAT_START_READ_AFTER_WRITE => - next_state <= DAT_START_READ; - next_DAT_READ_ENABLE_OUT <= '1'; + when MEM_WRITE_2 => + if DAT_WRITE_ACK_IN = '1' then + next_API_READ_OUT <= '1'; + next_state <= MEM_WRITE; + elsif timeout_counter(c_regio_timeout_bit) = '1' or DAT_UNKNOWN_ADDR_IN = '1' or DAT_NO_MORE_DATA_IN = '1' then + next_API_READ_OUT <= '1'; + next_state <= SEND_RW_ERROR; + next_timeout <= timeout_counter(c_regio_timeout_bit); + next_unknown <= DAT_UNKNOWN_ADDR_IN; + next_nomoredata <= DAT_NO_MORE_DATA_IN; + else + next_timeout_counter <= timeout_counter + 1; + next_API_READ_OUT <= '0'; + end if; when DAT_START_READ => if DAT_DATAREADY_IN = '1' then - next_state <= DAT_READ; - elsif DAT_NO_MORE_DATA_IN = '1' then - next_state <= SEND_REPLY_SHORT_TRANSFER; + next_state <= DAT_READ; + elsif DAT_NO_MORE_DATA_IN = '1' or DAT_UNKNOWN_ADDR_IN = '1' or timeout_counter(c_regio_timeout_bit) = '1' then + next_state <= SEND_REPLY_SHORT_TRANSFER; + next_nomoredata <= DAT_NO_MORE_DATA_IN; + next_unknown <= DAT_UNKNOWN_ADDR_IN; + next_timeout <= timeout_counter(c_regio_timeout_bit); + else + next_timeout_counter <= timeout_counter + 1; end if; when DAT_READ => next_API_SEND_OUT <= '1'; next_API_DATAREADY_OUT <= '1'; case next_packet_counter is - when c_F0 => next_API_DATA_OUT <= address; - when c_F1 => next_API_DATA_OUT <= buf_DAT_DATA_IN(31 downto 16); - when c_F2 => - next_API_DATA_OUT <= buf_DAT_DATA_IN(15 downto 0); - when c_F3 => - next_API_DATA_OUT <= (others => '0'); - if API_READ_IN = '1' then - next_state <= SEND_REPLY_DATA_finish; - end if; + when c_F0 => next_API_DATA_OUT <= address; + when c_F1 => next_API_DATA_OUT <= buf_DAT_DATA_IN(31 downto 16); + when c_F2 => next_API_DATA_OUT <= buf_DAT_DATA_IN(15 downto 0); + when c_F3 => next_API_DATA_OUT <= (others => '0'); + if API_READ_IN = '1' then + next_state <= SEND_REPLY_DATA_finish; + end if; when others => null; end case; + when SEND_RW_ERROR => + next_API_SEND_OUT <= '1'; + next_API_DATAREADY_OUT <= '1'; + case next_packet_counter is + when c_F0 => next_API_DATA_OUT <= address; + when c_F1 => next_API_DATA_OUT <= dat_data_counter; + when c_F2 => next_API_DATA_OUT <= (others => '0'); + when c_F3 => next_API_DATA_OUT <= (others => '0'); + if API_READ_IN = '1' then + next_state <= SEND_REPLY_DATA_finish; + end if; + when others => null; + end case; when others => - next_state <= IDLE; - end case; + next_state <= IDLE; + end case; end process; @@ -574,14 +641,16 @@ begin length <= (others => '0'); dont_understand <= '0'; addr_counter_enable <= '0'; + timeout_counter <= (others => '0'); + timeout <= '0'; + unknown <= '0'; + nomoredata <= '0'; + buf_API_READ_OUT <= '0'; else current_state <= next_state; --- HDR_F0 <= next_HDR_F0; --- HDR_F1 <= next_HDR_F1; --- HDR_F2 <= next_HDR_F2; --- HDR_F3 <= next_HDR_F3; buf_API_SEND_OUT <= next_API_SEND_OUT; buf_API_SHORT_TRANSFER_OUT <= next_API_SHORT_TRANSFER_OUT; + buf_API_READ_OUT <= next_API_READ_OUT; address <= next_address; saved_Reg_high <= next_Reg_high; saved_Reg_low <= next_Reg_low; @@ -594,11 +663,17 @@ begin length <= next_length; dont_understand <= next_dont_understand; addr_counter_enable <= next_addr_counter_enable; + timeout_counter <= next_timeout_counter; + timeout <= next_timeout; + unknown <= next_unknown; + nomoredata <= next_nomoredata; + dat_data_counter <= next_dat_data_counter; end if; end if; end process; +--generate packet numbers reg_packet_counter : process(CLK) begin if rising_edge(CLK) then @@ -610,7 +685,6 @@ begin end if; end process; - next_packet_counter_proc : process(API_READ_IN, buf_API_DATAREADY_OUT, packet_counter) begin if buf_API_DATAREADY_OUT = '1' and API_READ_IN = '1' then @@ -637,21 +711,35 @@ begin end if; end process; +--save Dataready_in in case API can not read immediately + process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + DAT_DATAREADY_IN_before <= '0'; + elsif DAT_DATAREADY_IN = '1' then + DAT_DATAREADY_IN_before <= '1'; + elsif API_READ_IN = '1' and buf_API_DATAREADY_OUT = '1' then + DAT_DATAREADY_IN_before <= '0'; + end if; + end if; + end process; + gen_regout : for i in 0 to 2**(NUM_CTRL_REGS)-1 generate - gen_regoutff1 : for j in i*c_REGIO_REGISTER_WIDTH to (i+1)*c_REGIO_REGISTER_WIDTH-1 generate + gen_regoutff1 : for j in i*c_REGIO_REG_WIDTH to (i+1)*c_REGIO_REG_WIDTH-1 generate gen_regoutff : if USED_CTRL_REGS(i) = '1' and USED_CTRL_BITMASK(j) = '1' generate process(CLK) - variable tmp : std_logic_vector(c_REGIO_REGISTER_WIDTH-1 downto 0); + variable tmp : std_logic_vector(c_REGIO_REG_WIDTH-1 downto 0); begin if rising_edge(CLK) then if RESET = '1' then buf_REGISTERS_OUT(j) <= INIT_CTRL_REGS(j); elsif REGISTERS_OUT_write_enable(i) = '1' then tmp := saved_Reg_high & saved_Reg_low; - buf_REGISTERS_OUT(j) <= tmp(j-i*c_REGIO_REGISTER_WIDTH); + buf_REGISTERS_OUT(j) <= tmp(j-i*c_REGIO_REG_WIDTH); elsif EXT_REG_WRITE_IN = '1' and EXT_REG_ADDR_IN = (conv_std_logic_vector(i,8) or x"D0") then - buf_REGISTERS_OUT(j) <= EXT_REG_DATA_IN(j-i*c_REGIO_REGISTER_WIDTH); + buf_REGISTERS_OUT(j) <= EXT_REG_DATA_IN(j-i*c_REGIO_REG_WIDTH); end if; end if; end process; @@ -663,18 +751,18 @@ begin end generate; gen_cregout : for i in 0 to std_COMCTRLREG-1 generate - gen_cregoutff1 : for j in i*c_REGIO_REGISTER_WIDTH to (i+1)*c_REGIO_REGISTER_WIDTH-1 generate + gen_cregoutff1 : for j in i*c_REGIO_REG_WIDTH to (i+1)*c_REGIO_REG_WIDTH-1 generate process(CLK) - variable tmp : std_logic_vector(c_REGIO_REGISTER_WIDTH-1 downto 0); + variable tmp : std_logic_vector(c_REGIO_REG_WIDTH-1 downto 0); begin if rising_edge(CLK) then if RESET = '1' then buf_COMMON_CTRL_REG_OUT(j) <= '0'; elsif COMMON_REGISTERS_OUT_write_enable(i) = '1' then tmp := saved_Reg_high & saved_Reg_low; - buf_COMMON_CTRL_REG_OUT(j) <= tmp(j-i*c_REGIO_REGISTER_WIDTH); + buf_COMMON_CTRL_REG_OUT(j) <= tmp(j-i*c_REGIO_REG_WIDTH); elsif EXT_REG_WRITE_IN = '1' and EXT_REG_ADDR_IN = (conv_std_logic_vector(i,8) or x"20") then - buf_COMMON_CTRL_REG_OUT(j) <= EXT_REG_DATA_IN(j-i*c_REGIO_REGISTER_WIDTH); + buf_COMMON_CTRL_REG_OUT(j) <= EXT_REG_DATA_IN(j-i*c_REGIO_REG_WIDTH); end if; end if; end process; @@ -698,13 +786,13 @@ begin elsif EXT_REG_ADDR_IN(7 downto 6) = "01" then EXT_REG_DATA_OUT <= (others => '0'); elsif EXT_REG_ADDR_IN(7 downto 6) = "10" then - EXT_REG_DATA_OUT <= REGISTERS_IN(regnum_STAT*c_REGIO_REGISTER_WIDTH+31 downto regnum_STAT*c_REGIO_REGISTER_WIDTH); + EXT_REG_DATA_OUT <= REGISTERS_IN(regnum_STAT*c_REGIO_REG_WIDTH+31 downto regnum_STAT*c_REGIO_REG_WIDTH); elsif EXT_REG_ADDR_IN(7 downto 6) = "11" then - EXT_REG_DATA_OUT <= buf_REGISTERS_OUT(regnum_CTRL*c_REGIO_REGISTER_WIDTH+31 downto regnum_CTRL*c_REGIO_REGISTER_WIDTH); + EXT_REG_DATA_OUT <= buf_REGISTERS_OUT(regnum_CTRL*c_REGIO_REG_WIDTH+31 downto regnum_CTRL*c_REGIO_REG_WIDTH); elsif EXT_REG_ADDR_IN(5) = '0' then - EXT_REG_DATA_OUT <= COMMON_STAT_REG_IN(regnum_cSTAT*c_REGIO_REGISTER_WIDTH+31 downto regnum_cSTAT*c_REGIO_REGISTER_WIDTH); + EXT_REG_DATA_OUT <= COMMON_STAT_REG_IN(regnum_cSTAT*c_REGIO_REG_WIDTH+31 downto regnum_cSTAT*c_REGIO_REG_WIDTH); else --if EXT_CTRL_ADDR_IN(5) = '1' then - EXT_REG_DATA_OUT <= buf_COMMON_CTRL_REG_OUT(regnum_cCTRL*c_REGIO_REGISTER_WIDTH+31 downto regnum_cCTRL*c_REGIO_REGISTER_WIDTH); + EXT_REG_DATA_OUT <= buf_COMMON_CTRL_REG_OUT(regnum_cCTRL*c_REGIO_REG_WIDTH+31 downto regnum_cCTRL*c_REGIO_REG_WIDTH); end if; end if; end process; @@ -721,6 +809,17 @@ begin end process; + --combine read_out of regio and addresses + process(current_state, ADR_READ_OUT, buf_API_READ_OUT) + begin + if current_state = ADDRESS_RECV then + combined_API_READ_OUT <= ADR_READ_OUT; + else + combined_API_READ_OUT <= buf_API_READ_OUT; + end if; + end process; + + board_rom : rom_16x8 generic map( INIT0 => COMPILE_TIME(15 downto 0), @@ -738,12 +837,15 @@ begin dout => rom_read_dout ); - - buf_API_ERROR_PATTERN_OUT(31 downto 5) <= (others => '0'); + buf_API_ERROR_PATTERN_OUT(31 downto 19) <= (others => '0'); + buf_API_ERROR_PATTERN_OUT(18) <= nomoredata; + buf_API_ERROR_PATTERN_OUT(17) <= timeout; + buf_API_ERROR_PATTERN_OUT(16) <= unknown; + buf_API_ERROR_PATTERN_OUT(15 downto 5) <= (others => '0'); buf_API_ERROR_PATTERN_OUT(4) <= dont_understand; buf_API_ERROR_PATTERN_OUT(3 downto 0) <= (others => '0'); - API_READ_OUT <= buf_API_READ_OUT; + API_READ_OUT <= combined_API_READ_OUT; API_SEND_OUT <= buf_API_SEND_OUT; API_DATAREADY_OUT <= buf_API_DATAREADY_OUT; API_PACKET_NUM_OUT <= buf_API_PACKET_NUM_OUT; @@ -755,6 +857,7 @@ begin DAT_READ_ENABLE_OUT <= buf_DAT_READ_ENABLE_OUT; DAT_WRITE_ENABLE_OUT <= buf_DAT_WRITE_ENABLE_OUT; DAT_ADDR_OUT <= buf_DAT_ADDR_OUT; + DAT_TIMEOUT_OUT <= timeout; REGISTERS_OUT <= buf_REGISTERS_OUT; COMMON_CTRL_REG_OUT <= buf_COMMON_CTRL_REG_OUT; diff --git a/trb_net_std.vhd b/trb_net_std.vhd index 854a9ea..5e452fa 100644 --- a/trb_net_std.vhd +++ b/trb_net_std.vhd @@ -102,6 +102,8 @@ package trb_net_std is constant std_COMneededwidth : integer := 1; constant c_REGIO_ADDRESS_WIDTH : integer := 16; constant c_REGIO_REGISTER_WIDTH : integer := 32; + constant c_REGIO_REG_WIDTH : integer := 32; + constant c_regio_timeout_bit : integer := 5; --RegIO operation dtype constant c_network_control_type : std_logic_vector(3 downto 0) := x"F"; -- 2.43.0