--- /dev/null
+--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
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');
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);
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);
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;
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
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;
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;
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;
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;
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;
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';
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');
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;
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);
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;
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;
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;
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
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
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;
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;
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;
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),
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;
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;