--- /dev/null
+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_addresses is
+ generic(
+ INIT_ADDRESS : std_logic_vector(15 downto 0) := x"FFFF";
+ INIT_UNIQUE_ID : std_logic_vector(95 downto 0) := x"1000_2000_3654_4876_5bcd_6ef1"
+ );
+ port(
+ CLK : in std_logic;
+ RESET : in std_logic;
+ CLK_EN : in std_logic;
+ API_DATA_IN : in std_logic_vector(15 downto 0);
+ API_DATAREADY_IN : in std_logic;
+ API_READ_OUT : out std_logic;
+ RAM_DATA_IN : in std_logic_vector(15 downto 0);
+ RAM_DATA_OUT : out std_logic_vector(15 downto 0);
+ RAM_ADDR_IN : in std_logic_vector(2 downto 0);
+ RAM_WR_IN : in std_logic;
+ API_DATA_OUT : out std_logic_vector(15 downto 0);
+ API_PACKET_NUM_OUT: out std_logic_vector(1 downto 0);
+ API_DATAREADY_OUT : out std_logic;
+ API_READ_IN : in std_logic;
+ ADDRESS_REJECTED : out std_logic;
+ ADDRESS_OUT : out std_logic_vector(15 downto 0)
+ );
+end entity;
+
+architecture trb_net16_addresses_arch of trb_net16_addresses is
+ component trb_net_ram_16x8_dp is
+ generic(
+ INIT0 : std_logic_vector(15 downto 0) := x"0000";
+ INIT1 : std_logic_vector(15 downto 0) := x"0000";
+ INIT2 : std_logic_vector(15 downto 0) := x"0000";
+ INIT3 : std_logic_vector(15 downto 0) := x"0000";
+ INIT4 : std_logic_vector(15 downto 0) := x"0000";
+ INIT5 : std_logic_vector(15 downto 0) := x"0000";
+ INIT6 : std_logic_vector(15 downto 0) := x"0000";
+ INIT7 : std_logic_vector(15 downto 0) := x"0000"
+ );
+ port(
+ CLK : in std_logic;
+ wr1 : in std_logic;
+ a1 : in std_logic_vector(2 downto 0);
+ dout1 : out std_logic_vector(15 downto 0);
+ din1 : in std_logic_vector(15 downto 0);
+ a2 : in std_logic_vector(2 downto 0);
+ dout2 : out std_logic_vector(15 downto 0)
+ );
+ end component;
+
+signal write_ADDRESS : std_logic;
+signal ram_read_addr : std_logic_vector(2 downto 0);
+signal ram_read_dout : std_logic_vector(15 downto 0);
+signal matching_counter : std_logic_vector(2 downto 0);
+signal ram_read_addr1 : std_logic_vector(2 downto 0);
+signal ram_read_addr2 : std_logic_vector(2 downto 0);
+signal buf_API_READ_OUT, next_API_READ_OUT : std_logic;
+
+type state_t is (IDLE, SEND1, SEND2, SEND3);
+signal next_state, state : state_t;
+
+--memory
+--00: SET_ADDRESS & endpoint_id
+--01: unique_id_0
+--02: unique_id_1
+--03: unique_id_2
+--04: unique_id_3
+--05: 00 & board_info0
+--06: board_info1
+--07: ACK_ADDRESS
+
+begin
+
+
+ ram_read_addr <= ram_read_addr1 or ram_read_addr2;
+
+ read_id : process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ ADDRESS_OUT <= INIT_ADDRESS;
+ ram_read_addr1 <= (others => '0');
+ matching_counter <= (others => '0');
+ else
+ buf_API_READ_OUT <= '1';
+ write_ADDRESS <= '0';
+ ADDRESS_REJECTED <= '0';
+ if API_DATAREADY_IN = '1' and buf_API_READ_OUT = '1' then
+ buf_API_READ_OUT <= '0';
+ ram_read_addr1 <= ram_read_addr1 + 1;
+ if API_DATA_IN = ram_read_dout then
+ matching_counter <= matching_counter + 1;
+ end if;
+ if ram_read_addr1 = "101" then
+ matching_counter <= "000";
+ ram_read_addr1 <= "000";
+ if matching_counter = "101" then
+ ADDRESS_OUT <= API_DATA_IN;
+ write_ADDRESS <= '1';
+ else
+ ADDRESS_REJECTED <= '1';
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ send_ack : process(write_ADDRESS, state, API_READ_IN, ram_read_dout)
+ begin
+ next_state <= state;
+ API_DATAREADY_OUT <= '0';
+ API_PACKET_NUM_OUT <= "01";
+ API_DATA_OUT <= ram_read_dout;
+ ram_read_addr2 <= "000";
+
+ case state is
+ when IDLE =>
+ if write_ADDRESS = '1' then
+ ram_read_addr2 <= "101";
+ next_state <= SEND1;
+ end if;
+ when SEND1 =>
+ API_DATAREADY_OUT <= '1';
+ API_PACKET_NUM_OUT <= "01";
+ ram_read_addr2 <= "101";
+ if API_READ_IN = '1' then
+ ram_read_addr2 <= "110";
+ next_state <= SEND2;
+ end if;
+ when SEND2 =>
+ API_DATAREADY_OUT <= '1';
+ API_PACKET_NUM_OUT <= "10";
+ ram_read_addr2 <= "110";
+ if API_READ_IN = '1' then
+ ram_read_addr2 <= "111";
+ next_state <= SEND3;
+ end if;
+ when SEND3 =>
+ API_DATAREADY_OUT <= '1';
+ API_PACKET_NUM_OUT <= "11";
+ ram_read_addr2 <= "111";
+ if API_READ_IN = '1' then
+ next_state <= IDLE;
+ ram_read_addr2 <= "000";
+ end if;
+ end case;
+ end process;
+
+
+ process(CLK)
+ begin
+ if rising_edge(CLK) then
+ state <= next_state;
+ -- buf_API_READ_OUT <= next_API_READ_OUT;
+ end if;
+ end process;
+
+ STAT_RAM : trb_net_ram_16x8_dp
+ generic map(
+ INIT0 => SET_ADDRESS & INIT_UNIQUE_ID(71 downto 64),
+ INIT1 => INIT_UNIQUE_ID(15 downto 0),
+ INIT2 => INIT_UNIQUE_ID(31 downto 16),
+ INIT3 => INIT_UNIQUE_ID(47 downto 32),
+ INIT4 => INIT_UNIQUE_ID(63 downto 48),
+ INIT5 => ACK_ADDRESS,
+ INIT6 => x"00" & INIT_UNIQUE_ID(79 downto 72),
+ INIT7 => INIT_UNIQUE_ID(95 downto 80)
+ )
+ port map(
+ CLK => CLK,
+ wr1 => RAM_WR_IN,
+ a1 => RAM_ADDR_IN,
+ din1 => RAM_DATA_IN,
+ dout1 => RAM_DATA_OUT,
+ a2 => ram_read_addr,
+ dout2 => ram_read_dout
+ );
+
+API_READ_OUT <= buf_API_READ_OUT;
+
+end architecture;
\ No newline at end of file
HUB_CTRL_REG_ADDR_WIDTH : integer range 1 to 7 := 4;
HUB_USED_CHANNELS : hub_channel_config_t := (c_YES,c_YES,c_YES,c_YES);
IBUF_SECURE_MODE : integer range 0 to 1 := c_NO;
- HUB_ADDRESS : std_logic_vector(15 downto 0) := x"F003";
+ INIT_ADDRESS : std_logic_vector(15 downto 0) := x"FFFF";
+ INIT_UNIQUE_ID : std_logic_vector(95 downto 0) := (others => '0');
--media interfaces
MII_NUMBER : integer range 2 to c_MAX_MII_PER_HUB := 4;
MII_IBUF_DEPTH : hub_iobuf_config_t := std_HUB_IBUF_DEPTH;
signal HUB_CTRL_CHANNEL : std_logic_vector (2**(c_MUX_WIDTH-1)*16-1 downto 0);
signal HUB_CTRL_activepoints : std_logic_vector (2**(c_MUX_WIDTH-1)*32-1 downto 0);
signal HUB_CTRL_GEN : std_logic_vector (31 downto 0);
+ signal HUB_ADDRESS : std_logic_vector (15 downto 0);
signal IOBUF_STAT_GEN : std_logic_vector ((MII_NUMBER*2**(c_MUX_WIDTH-1) + API_NUMBER + TRG_NUMBER)*32-1 downto 0);
signal IOBUF_IBUF_BUFFER : std_logic_vector ((MII_NUMBER*2**(c_MUX_WIDTH-1) + API_NUMBER + TRG_NUMBER)*32-1 downto 0);
generic (
REGISTER_WIDTH : integer range 32 to 32 := 32;
ADDRESS_WIDTH : integer range 8 to 16 := 16;
- ADDRESS_USED_WIDTH : integer range 1 to 16 := HUB_CTRL_REG_ADDR_WIDTH;
+ NUM_STAT_REGS : integer range 0 to 6 := 3; --log2 of number of status registers
+ NUM_CTRL_REGS : integer range 0 to 6 := 3; --log2 of number of ctrl registers
--standard values for output registers
- RESET_REGISTER_OUT : std_logic_vector(2**(HUB_CTRL_REG_ADDR_WIDTH-1)*32-1 downto 0);
- USED_REGISTER_OUT : std_logic_vector(2**(HUB_CTRL_REG_ADDR_WIDTH-1)-1 downto 0);
- BITMASK_REGISTER_OUT : std_logic_vector(2**(HUB_CTRL_REG_ADDR_WIDTH-1)*32-1 downto 0);
+ 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) := "11111111";
+ --set to 0 for each unused bit in a register
+ USED_CTRL_BITMASK : std_logic_vector(2**(3)*32-1 downto 0) :=
+ (others => '1');
--no data / address out?
- NO_DAT_PORT : std_logic := '0'
+ NO_DAT_PORT : std_logic := '0';
+ INIT_ADDRESS : std_logic_vector(15 downto 0) := x"FFFF";
+ INIT_UNIQUE_ID : std_logic_vector(95 downto 0) := (others => '0')
);
port(
+ -- Misc
CLK : in std_logic;
RESET : in std_logic;
CLK_EN : in std_logic;
- MY_ADDRESS : in std_logic_vector (15 downto 0);
- -- Port to API
+ -- Port to API
API_DATA_OUT : out std_logic_vector (c_DATA_WIDTH-1 downto 0);
- API_PACKET_NUM_OUT : out std_logic_vector (c_NUM_WIDTH-1 downto 0);
+ API_PACKET_NUM_OUT : out std_logic_vector (c_NUM_WIDTH-1 downto 0);
API_WRITE_OUT : out std_logic;
API_FIFO_FULL_IN : in std_logic;
API_SHORT_TRANSFER_OUT : out std_logic;
API_TARGET_ADDRESS_OUT : out std_logic_vector (15 downto 0);
-- Receiver port
API_DATA_IN : in std_logic_vector (c_DATA_WIDTH-1 downto 0);
- API_PACKET_NUM_IN : in std_logic_vector (c_NUM_WIDTH-1 downto 0);
+ API_PACKET_NUM_IN : in std_logic_vector (c_NUM_WIDTH-1 downto 0);
API_TYP_IN : in std_logic_vector (2 downto 0);
API_DATAREADY_IN : in std_logic;
API_READ_OUT : out std_logic;
-- APL Control port
API_RUN_IN : in std_logic;
- API_MY_ADDRESS_OUT : out std_logic_vector (15 downto 0);
API_SEQNR_IN : in std_logic_vector (7 downto 0);
- --Register in / outside
- REGISTERS_IN : in std_logic_vector(REGISTER_WIDTH*2**(ADDRESS_USED_WIDTH-1)-1 downto 0);
- REGISTERS_OUT : out std_logic_vector(REGISTER_WIDTH*2**(ADDRESS_USED_WIDTH-1)-1 downto 0);
- --following ports only used when no internal register is accessed
+
+ MY_ADDRESS_OUT : out std_logic_vector(15 downto 0);
+
+ --Register in / out
+ REGISTERS_IN : in std_logic_vector(REGISTER_WIDTH*2**(NUM_STAT_REGS)-1 downto 0);
+ REGISTERS_OUT : out std_logic_vector(REGISTER_WIDTH*2**(NUM_CTRL_REGS)-1 downto 0);
+
+ --following ports only used when no internal register is accessed
DAT_ADDR_OUT : out std_logic_vector(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(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(REGISTER_WIDTH-1 downto 0);
- DAT_DATAREADY_IN : in std_logic
+ DAT_DATAREADY_IN : in std_logic;
+ DAT_NO_MORE_DATA_IN : in std_logic
+ --To finish transmission, when reading from a fifo and it got empty
);
end component;
end generate;
end generate;
-
hub_control : trb_net16_regIO
generic map(
REGISTER_WIDTH => 32,
ADDRESS_WIDTH => 16,
- ADDRESS_USED_WIDTH => HUB_CTRL_REG_ADDR_WIDTH,
- RESET_REGISTER_OUT => x"FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF" &
- x"00000000_00000000_00000000_00000000",
- USED_REGISTER_OUT => "11111111",
- BITMASK_REGISTER_OUT => x"FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF" &
- x"FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF",
- NO_DAT_PORT => '1'
+ NUM_STAT_REGS => 3,
+ NUM_CTRL_REGS => 3,
+ INIT_CTRL_REGS => x"FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF" &
+ x"00000000_00000000_00000000_00000000",
+ USED_CTRL_REGS => "11111111",
+ USED_CTRL_BITMASK => x"FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF" &
+ x"FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF",
+ NO_DAT_PORT => '1',
+ INIT_ADDRESS => INIT_ADDRESS,
+ INIT_UNIQUE_ID => INIT_UNIQUE_ID
)
port map(
CLK => CLK,
RESET => RESET,
CLK_EN => CLK_EN,
- MY_ADDRESS => HUB_ADDRESS,
-- Port to API
API_DATA_OUT => HC_DATA_IN,
API_PACKET_NUM_OUT => HC_PACKET_NUM_IN,
API_READ_OUT => HC_READ_IN,
-- HC Control port
API_RUN_IN => HC_RUN_OUT,
- API_MY_ADDRESS_OUT => HC_MY_ADDRESS_IN,
API_SEQNR_IN => HC_SEQNR_OUT,
+ MY_ADDRESS_OUT => HUB_ADDRESS,
REGISTERS_IN => HC_STAT_REGS,
REGISTERS_OUT => HC_CTRL_REGS,
DAT_ADDR_OUT => open,
DAT_WRITE_ENABLE_OUT=> open,
DAT_DATA_OUT => open,
DAT_DATA_IN => x"00000000",
- DAT_DATAREADY_IN => '0'
+ DAT_DATAREADY_IN => '0',
+ DAT_NO_MORE_DATA_IN => '0'
);
+
--8x CTRL, 8x STAT
generic (
REGISTER_WIDTH : integer range 32 to 32 := 32;
ADDRESS_WIDTH : integer range 8 to 16 := 16;
- ADDRESS_USED_WIDTH : integer range 1 to 5 := 4;
+ NUM_STAT_REGS : integer range 0 to 6 := 3; --log2 of number of status registers
+ NUM_CTRL_REGS : integer range 0 to 6 := 3; --log2 of number of ctrl registers
--standard values for output registers
- RESET_REGISTER_OUT : std_logic_vector(2**(4-1)*32-1 downto 0) :=
- x"00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000";
+ 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_REGISTER_OUT : std_logic_vector(2**(4-1)-1 downto 0) := "11111111";
+ USED_CTRL_REGS : std_logic_vector(2**(3)-1 downto 0) := "11111111";
--set to 0 for each unused bit in a register
- BITMASK_REGISTER_OUT : std_logic_vector(2**(4-1)*32-1 downto 0) :=
- x"FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF";
+ USED_CTRL_BITMASK : std_logic_vector(2**(3)*32-1 downto 0) :=
+ (others => '1');
--no data / address out?
- NO_DAT_PORT : std_logic := '0'
+ NO_DAT_PORT : std_logic := '0';
+ INIT_ADDRESS : std_logic_vector(15 downto 0) := x"FFFF";
+ INIT_UNIQUE_ID : std_logic_vector(95 downto 0) := (others => '0')
);
port(
-- Misc
CLK : in std_logic;
RESET : in std_logic;
CLK_EN : in std_logic;
-
- MY_ADDRESS : in std_logic_vector (15 downto 0);
-- Port to API
API_DATA_OUT : out std_logic_vector (c_DATA_WIDTH-1 downto 0);
API_PACKET_NUM_OUT : out std_logic_vector (c_NUM_WIDTH-1 downto 0);
API_READ_OUT : out std_logic;
-- APL Control port
API_RUN_IN : in std_logic;
- API_MY_ADDRESS_OUT : out std_logic_vector (15 downto 0);
API_SEQNR_IN : in std_logic_vector (7 downto 0);
- --Register in / outside
- REGISTERS_IN : in std_logic_vector(REGISTER_WIDTH*2**(ADDRESS_USED_WIDTH-1)-1 downto 0);
- REGISTERS_OUT : out std_logic_vector(REGISTER_WIDTH*2**(ADDRESS_USED_WIDTH-1)-1 downto 0);
+ MY_ADDRESS_OUT : out std_logic_vector(15 downto 0);
+
+ --Register in / out
+ REGISTERS_IN : in std_logic_vector(REGISTER_WIDTH*2**(NUM_STAT_REGS)-1 downto 0);
+ REGISTERS_OUT : out std_logic_vector(REGISTER_WIDTH*2**(NUM_CTRL_REGS)-1 downto 0);
--following ports only used when no internal register is accessed
DAT_ADDR_OUT : out std_logic_vector(ADDRESS_WIDTH-1 downto 0);
DAT_READ_ENABLE_OUT : out std_logic;
DAT_WRITE_ENABLE_OUT: out std_logic;
- --Data output is only used when writing
DAT_DATA_OUT : out std_logic_vector(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(REGISTER_WIDTH-1 downto 0);
- DAT_DATAREADY_IN : in std_logic
+ DAT_DATAREADY_IN : in std_logic;
+ DAT_NO_MORE_DATA_IN : in std_logic
+ --To finish transmission, when reading from a fifo and it got empty
);
end entity;
component trb_net_pattern_gen is
generic (
- WIDTH : integer := ADDRESS_USED_WIDTH-1
+ WIDTH : integer := NUM_CTRL_REGS
);
port(
INPUT_IN : in STD_LOGIC_VECTOR (WIDTH-1 downto 0);
);
end component;
- type fsm_state_t is (IDLE, HEADER_RECV, REG_READ, REG_WRITE, WAIT_FOR_INIT_TRM,
- SEND_REPLY_DATA_finish, SEND_REPLY_SHORT_TRANSFER, SEND_REPLY_DATA,
- DAT_INT, DAT_WAIT);
+ component trb_net16_addresses is
+ generic(
+ INIT_ADDRESS : std_logic_vector(15 downto 0) := x"FFFF";
+ INIT_UNIQUE_ID : std_logic_vector(95 downto 0) := x"1000_2000_3654_4876_5bcd_6ef1"
+ );
+ port(
+ CLK : in std_logic;
+ RESET : in std_logic;
+ CLK_EN : in std_logic;
+ API_DATA_IN : in std_logic_vector(15 downto 0);
+ API_DATAREADY_IN : in std_logic;
+ API_READ_OUT : out std_logic;
+ RAM_DATA_IN : in std_logic_vector(15 downto 0);
+ RAM_DATA_OUT : out std_logic_vector(15 downto 0);
+ RAM_ADDR_IN : in std_logic_vector(2 downto 0);
+ RAM_WR_IN : in std_logic;
+ API_DATA_OUT : out std_logic_vector(15 downto 0);
+ API_PACKET_NUM_OUT: out std_logic_vector(1 downto 0);
+ API_DATAREADY_OUT : out std_logic;
+ API_READ_IN : in std_logic;
+ ADDRESS_REJECTED : out std_logic;
+ ADDRESS_OUT : out std_logic_vector(15 downto 0)
+ );
+ end component;
+
+ type fsm_state_t is (IDLE, HEADER_RECV, REG_READ, REG_WRITE, ONE_READ, ONE_WRITE, SEND_REPLY_SHORT_TRANSFER,
+ MEM_READ, MEM_WRITE, DAT_START_READ, DAT_READ, SEND_REPLY_DATA_finish, ADDRESS_ACK, ADDRESS_RECV);
signal current_state, next_state : fsm_state_t;
signal HDR_F1, HDR_F2, HDR_F3 : std_logic_vector(15 downto 0);
signal next_HDR_F1, next_HDR_F2, next_HDR_F3 : std_logic_vector(15 downto 0);
signal buf_API_SHORT_TRANSFER_OUT, next_API_SHORT_TRANSFER_OUT : std_logic;
signal buf_API_WRITE_OUT, next_API_WRITE_OUT : std_logic;
- signal buf_DAT_DATA_OUT, next_DAT_DATA_OUT : std_logic_vector(REGISTER_WIDTH-1 downto 0);
+ signal buf_DAT_DATA_OUT : std_logic_vector(REGISTER_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, next_DAT_ADDR_OUT : std_logic_vector(ADDRESS_WIDTH-1 downto 0);
+ signal buf_DAT_ADDR_OUT : std_logic_vector(ADDRESS_WIDTH-1 downto 0);
- signal buf_REGISTERS_OUT : std_logic_vector(REGISTER_WIDTH*2**(ADDRESS_USED_WIDTH-1)-1 downto 0);
- signal REGISTERS_OUT_write_enable : std_logic_vector(2**(ADDRESS_USED_WIDTH-1)-1 downto 0);
- signal reg_enable_pattern : std_logic_vector(2**(ADDRESS_USED_WIDTH-1)-1 downto 0);
+ signal buf_REGISTERS_OUT : std_logic_vector(REGISTER_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(2**(NUM_CTRL_REGS)-1 downto 0);
signal state_bits : std_logic_vector(2 downto 0);
+ signal ADR_DATAREADY_IN : std_logic;
+ signal ADR_READ_OUT : std_logic;
+ signal ADR_DATA_OUT : std_logic_vector(15 downto 0);
+ signal ADR_READ_IN : std_logic;
+ signal ADR_DATAREADY_OUT : std_logic;
+ signal RAM_DATA_IN, RAM_DATA_OUT : std_logic_vector(15 downto 0);
+ signal ADR_PACKET_NUM_OUT : std_logic_vector(1 downto 0);
+ signal RAM_ADDR_IN : std_logic_vector(2 downto 0);
+ signal RAM_WR_IN : std_logic;
+ signal ADR_REJECTED : std_logic;
+ signal next_API_ERROR_PATTERN_OUT : std_logic_vector(31 downto 0);
+ signal buf_API_ERROR_PATTERN_OUT : std_logic_vector(31 downto 0);
+
begin
pattern_gen_inst : trb_net_pattern_gen
port map(
- INPUT_IN => address(ADDRESS_USED_WIDTH-2 downto 0),
+ INPUT_IN => address(NUM_CTRL_REGS-1 downto 0),
RESULT_OUT => reg_enable_pattern
);
+ addresses : trb_net16_addresses
+ generic map(
+ INIT_ADDRESS => INIT_ADDRESS,
+ INIT_UNIQUE_ID => INIT_UNIQUE_ID
+ )
+ port map(
+ CLK => CLK,
+ RESET => RESET,
+ CLK_EN => CLK_EN,
+ API_DATA_IN => API_DATA_IN,
+ API_DATAREADY_IN => ADR_DATAREADY_IN,
+ API_READ_OUT => ADR_READ_OUT,
+ API_DATA_OUT => ADR_DATA_OUT,
+ API_DATAREADY_OUT => ADR_DATAREADY_OUT,
+ API_PACKET_NUM_OUT=> ADR_PACKET_NUM_OUT,
+ API_READ_IN => ADR_READ_IN,
+ RAM_DATA_IN => RAM_DATA_IN,
+ RAM_DATA_OUT => RAM_DATA_OUT,
+ RAM_ADDR_IN => RAM_ADDR_IN,
+ RAM_WR_IN => RAM_WR_IN,
+ ADDRESS_REJECTED => ADR_REJECTED,
+ ADDRESS_OUT => MY_ADDRESS_OUT
+ );
+
+ RAM_DATA_IN <= (others => '0');
+ RAM_WR_IN <= '0';
+
+ 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_FIFO_FULL_IN, API_RUN_IN,
HDR_F1, HDR_F2, HDR_F3, address, saved_Reg_high, saved_Reg_low, saved_operation,
buf_API_SEND_OUT, buf_API_PACKET_NUM_OUT, buf_API_DATA_OUT, buf_API_SHORT_TRANSFER_OUT,
- REGISTERS_IN, buf_REGISTERS_OUT, reg_enable_pattern,
- buf_DAT_DATA_OUT, buf_DAT_ADDR_OUT, DAT_DATAREADY_IN, DAT_DATA_IN
+ REGISTERS_IN, buf_REGISTERS_OUT, reg_enable_pattern, DAT_NO_MORE_DATA_IN,
+ buf_DAT_DATA_OUT, buf_DAT_ADDR_OUT, DAT_DATAREADY_IN, DAT_DATA_IN, ADR_REJECTED,
+ ADR_READ_OUT, ADR_DATAREADY_OUT, ADR_DATA_OUT, ADR_PACKET_NUM_OUT
)
- variable regnum : integer range 0 to 2**(ADDRESS_USED_WIDTH-1)-1;
+ variable regnum : integer range 0 to 2**(NUM_STAT_REGS)-1;
begin
next_state <= current_state;
next_HDR_F1 <= HDR_F1;
next_address <= address;
next_Reg_high <= saved_Reg_high;
next_Reg_low <= saved_Reg_low;
- next_API_READ_OUT <= '1';
+-- next_API_READ_OUT <= '1';
+ ADR_DATAREADY_IN <= '0';
+ ADR_READ_IN <= '0';
+ buf_API_READ_OUT <= '1';
next_API_SEND_OUT <= buf_API_SEND_OUT;
next_API_WRITE_OUT <= '0';
next_API_PACKET_NUM_OUT <= buf_API_PACKET_NUM_OUT;
next_API_DATA_OUT <= buf_API_DATA_OUT;
next_API_SHORT_TRANSFER_OUT <= buf_API_SHORT_TRANSFER_OUT;
next_operation <= saved_operation;
- REGISTERS_OUT_write_enable <= (others => '0');
- next_DAT_DATA_OUT <= buf_DAT_DATA_OUT;
+ next_REGISTERS_OUT_write_enable <= (others => '0');
next_DAT_READ_ENABLE_OUT <= '0';
next_DAT_WRITE_ENABLE_OUT <= '0';
- next_DAT_ADDR_OUT <= buf_DAT_ADDR_OUT;
+ buf_API_ERROR_PATTERN_OUT(0) <= '1';
- regnum := conv_integer(address(ADDRESS_USED_WIDTH-2 downto 0));
+ regnum := conv_integer(address(NUM_STAT_REGS-1 downto 0));
case current_state is
when IDLE =>
next_state <= HEADER_RECV;
end if;
- --read and save HDR, then decide what to do by dtype
- when HEADER_RECV =>
+ when HEADER_RECV => --read and save HDR
if API_DATAREADY_IN = '1' then
if API_PACKET_NUM_IN = "01" then
next_HDR_F1 <= API_DATA_IN;
if API_PACKET_NUM_IN = "11" then
next_HDR_F3 <= API_DATA_IN;
case API_DATA_IN(3 downto 0) is
- when "1000" => next_state <= REG_READ;
- when "1001" => next_state <= REG_WRITE;
+ when "1000" => next_state <= ONE_READ;
+ when "1001" => next_state <= ONE_WRITE;
+ when "1010" => next_state <= MEM_READ;
+ when "1011" => next_state <= MEM_WRITE;
+ when "1111" => next_state <= ADDRESS_RECV;
when others => next_state <= SEND_REPLY_SHORT_TRANSFER;
end case;
next_operation <= API_DATA_IN(3 downto 0);
end if;
end if;
- --writing register operation
- when REG_WRITE =>
- if API_TYP_IN = TYPE_DAT then
- case API_PACKET_NUM_IN is
- when "01" =>
- next_address <= API_DATA_IN;
- when "10" =>
- next_Reg_high <= API_DATA_IN;
- when "11" =>
- next_Reg_low <= API_DATA_IN;
- REGISTERS_OUT_write_enable <= reg_enable_pattern;
- next_state <= WAIT_FOR_INIT_TRM;
- if or_all(address(ADDRESS_WIDTH-1 downto ADDRESS_USED_WIDTH)) = '1' then
- if NO_DAT_PORT = '0' then
- next_state <= DAT_INT;
- else
- next_state <= SEND_REPLY_SHORT_TRANSFER;
- end if;
- end if;
- when others =>
- null;
- end case;
+ 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;
+ end if;
+ if ADR_DATAREADY_OUT = '1' then
+ next_state <= ADDRESS_ACK;
end if;
- when REG_READ =>
+ when ADDRESS_ACK =>
+ ADR_READ_IN <= not API_FIFO_FULL_IN;
+ next_API_SEND_OUT <= '1';
+ next_API_WRITE_OUT <= ADR_DATAREADY_OUT;
+ next_API_DATA_OUT <= ADR_DATA_OUT;
+ next_API_PACKET_NUM_OUT <= ADR_PACKET_NUM_OUT;
+ if ADR_PACKET_NUM_OUT = "11" and not API_FIFO_FULL_IN = '1' then
+ next_state <= SEND_REPLY_DATA_finish;
+ end if;
+
+
+ when ONE_READ => --wait for register address
if API_TYP_IN = TYPE_DAT and API_PACKET_NUM_IN = "01" and API_DATAREADY_IN = '1' then
next_address <= API_DATA_IN;
- next_state <= WAIT_FOR_INIT_TRM;
- if or_all(API_DATA_IN(ADDRESS_WIDTH-1 downto ADDRESS_USED_WIDTH)) = '1' then
+ if or_all(API_DATA_IN(ADDRESS_WIDTH-1 downto 8)) = '1' then --data port address
if NO_DAT_PORT = '0' then
- next_state <= DAT_INT;
+ next_DAT_READ_ENABLE_OUT <= '1';
+ next_state <= DAT_READ;
else
next_state <= SEND_REPLY_SHORT_TRANSFER;
end if;
+ else --register address
+ next_state <= REG_READ;
end if;
end if;
- when WAIT_FOR_INIT_TRM =>
- if API_TYP_IN = TYPE_TRM and API_PACKET_NUM_IN = "11" then
- next_state <= SEND_REPLY_DATA;
+ when ONE_WRITE => --wait for register address
+ if API_TYP_IN = TYPE_DAT and API_PACKET_NUM_IN = "01" and API_DATAREADY_IN = '1' then
+ next_address <= API_DATA_IN;
+ if not (API_DATA_IN(15 downto 8)) = x"00" then --data port address
+ if NO_DAT_PORT = '0' then
+ next_state <= REG_WRITE;
+ else
+ next_state <= SEND_REPLY_SHORT_TRANSFER;
+ end if;
+ elsif API_DATA_IN(7) = '1' then --register address
+ if API_DATA_IN(6) = '1' then
+ if API_DATA_IN(5 downto NUM_CTRL_REGS) = 0 then
+ next_state <= REG_WRITE; --ctrl register
+ else
+ next_state <= SEND_REPLY_SHORT_TRANSFER;
+ end if; --unused address - not valid
+ else
+ if API_DATA_IN(5 downto NUM_STAT_REGS) = 0 then
+ next_state <= REG_READ; --stat register - not writing
+ else
+ next_state <= SEND_REPLY_SHORT_TRANSFER;
+ end if; --unused address - not valid
+ end if;
+ else --status ram address - not valid
+ next_state <= SEND_REPLY_SHORT_TRANSFER;
+ end if;
end if;
- when SEND_REPLY_DATA =>
+ when SEND_REPLY_DATA_finish =>
+ next_API_SEND_OUT <= '0';
+ next_state <= IDLE;
+
+ when SEND_REPLY_SHORT_TRANSFER =>
+ next_API_SHORT_TRANSFER_OUT <= '1';
+ next_API_SEND_OUT <= '1';
+ next_state <= SEND_REPLY_DATA_finish;
+
+ when REG_WRITE =>
+ case API_PACKET_NUM_IN is
+ when "10" =>
+ next_Reg_high <= API_DATA_IN;
+ when "11" =>
+ next_Reg_low <= API_DATA_IN;
+ if or_all(address(15 downto 8)) = '0' then
+ next_REGISTERS_OUT_write_enable <= reg_enable_pattern;
+ next_state <= REG_READ;
+ else
+ next_DAT_WRITE_ENABLE_OUT <= '1';
+ next_state <= DAT_START_READ;
+ end if;
+ when others => null;
+ end case;
+
+ when REG_READ =>
next_API_SEND_OUT <= '1';
if API_FIFO_FULL_IN = '1' then
next_API_WRITE_OUT <= '0';
next_API_DATA_OUT <= address;
elsif buf_API_PACKET_NUM_OUT = "01" then
next_API_PACKET_NUM_OUT <= "10";
- if address(ADDRESS_USED_WIDTH-1) = '0' then
+ if address(6) = '0' then
next_API_DATA_OUT <= REGISTERS_IN(regnum*REGISTER_WIDTH+31 downto regnum*REGISTER_WIDTH+16);
else
next_API_DATA_OUT <= buf_REGISTERS_OUT(regnum*REGISTER_WIDTH+31 downto regnum*REGISTER_WIDTH+16);
end if;
elsif buf_API_PACKET_NUM_OUT = "10" then
next_API_PACKET_NUM_OUT <= "11";
- if address(ADDRESS_USED_WIDTH-1) = '0' then
+ if address(6) = '0' then
next_API_DATA_OUT <= REGISTERS_IN(regnum*REGISTER_WIDTH+15 downto regnum*REGISTER_WIDTH);
else
next_API_DATA_OUT <= buf_REGISTERS_OUT(regnum*REGISTER_WIDTH+15 downto regnum*REGISTER_WIDTH);
next_state <= SEND_REPLY_DATA_finish;
end if;
end if;
- when SEND_REPLY_DATA_finish =>
- next_API_SEND_OUT <= '0';
- next_state <= IDLE;
- when SEND_REPLY_SHORT_TRANSFER =>
- if API_TYP_IN = TYPE_TRM and API_PACKET_NUM_IN = "11" then
- next_API_SHORT_TRANSFER_OUT <= '1';
- next_API_SEND_OUT <= '1';
- next_state <= SEND_REPLY_DATA_finish;
- end if;
- when DAT_INT =>
- if API_TYP_IN = TYPE_TRM and API_PACKET_NUM_IN = "11" then
- next_DAT_DATA_OUT <= saved_Reg_high & saved_Reg_low;
- next_DAT_ADDR_OUT <= address;
- if saved_operation = "1000" then
- next_DAT_READ_ENABLE_OUT <= '1';
- elsif saved_operation = "1001" then
- next_DAT_WRITE_ENABLE_OUT <= '1';
- end if;
- next_state <= DAT_WAIT;
- end if;
+ when MEM_READ =>
+ next_state <= SEND_REPLY_SHORT_TRANSFER;
- when DAT_WAIT =>
+ when MEM_WRITE =>
+ next_state <= SEND_REPLY_SHORT_TRANSFER;
+
+ when DAT_START_READ =>
+ next_DAT_READ_ENABLE_OUT <= '1';
+ next_state <= DAT_READ;
+
+ when DAT_READ =>
if DAT_DATAREADY_IN = '1' then
next_API_PACKET_NUM_OUT <= "01";
next_API_DATA_OUT <= address;
next_API_WRITE_OUT <= '1';
next_state <= SEND_REPLY_DATA_finish;
end if;
+
+
+
+
when others =>
next_state <= IDLE;
end case;
if rising_edge(CLK) then
if RESET = '1' then
current_state <= IDLE;
- HDR_F1 <= (others => '0');
- HDR_F2 <= (others => '0');
- HDR_F3 <= (others => '0');
- buf_API_READ_OUT <= '0';
- buf_API_READ_OUT <= '0';
buf_API_SEND_OUT <= '0';
buf_API_WRITE_OUT <= '0';
buf_API_PACKET_NUM_OUT <= "11";
- buf_API_DATA_OUT <= (others => '0');
- buf_API_SHORT_TRANSFER_OUT <= '0';
- address <= (others => '0');
- saved_Reg_high <= (others => '0');
- saved_Reg_low <= (others => '0');
- saved_operation <= (others => '0');
- buf_DAT_DATA_OUT <= (others => '0');
buf_DAT_READ_ENABLE_OUT <= '0';
buf_DAT_WRITE_ENABLE_OUT <= '0';
- buf_DAT_ADDR_OUT <= (others => '0');
+ buf_API_DATA_OUT <= (others => '0');
+ buf_API_PACKET_NUM_OUT <= (others => '0');
+ saved_operation <= "0000";
else
current_state <= next_state;
HDR_F1 <= next_HDR_F1;
HDR_F2 <= next_HDR_F2;
HDR_F3 <= next_HDR_F3;
- buf_API_READ_OUT <= next_API_READ_OUT;
buf_API_SEND_OUT <= next_API_SEND_OUT;
buf_API_WRITE_OUT <= next_API_WRITE_OUT;
buf_API_PACKET_NUM_OUT <= next_API_PACKET_NUM_OUT;
saved_Reg_high <= next_Reg_high;
saved_Reg_low <= next_Reg_low;
saved_operation <= next_operation;
- buf_DAT_DATA_OUT <= next_DAT_DATA_OUT;
buf_DAT_READ_ENABLE_OUT <= next_DAT_READ_ENABLE_OUT;
buf_DAT_WRITE_ENABLE_OUT <= next_DAT_WRITE_ENABLE_OUT;
- buf_DAT_ADDR_OUT <= next_DAT_ADDR_OUT;
+ REGISTERS_OUT_write_enable <= next_REGISTERS_OUT_write_enable;
end if;
end if;
end process;
- gen_regout : for i in 0 to 2**(ADDRESS_USED_WIDTH-1)-1 generate
+ gen_regout : for i in 0 to 2**(NUM_CTRL_REGS)-1 generate
gen_regoutff1 : for j in i*REGISTER_WIDTH to (i+1)*REGISTER_WIDTH-1 generate
- gen_regoutff : if USED_REGISTER_OUT(i) = '1' and BITMASK_REGISTER_OUT(j) = '1' generate
+ gen_regoutff : if USED_CTRL_REGS(i) = '1' and USED_CTRL_BITMASK(j) = '1' generate
process(CLK)
variable tmp : std_logic_vector(REGISTER_WIDTH-1 downto 0);
begin
if rising_edge(CLK) then
if RESET = '1' then
- buf_REGISTERS_OUT(j) <= RESET_REGISTER_OUT(j);
+ buf_REGISTERS_OUT(j) <= INIT_CTRL_REGS(j);
elsif REGISTERS_OUT_write_enable(i) = '1' then
- tmp := saved_Reg_high & API_DATA_IN;
+ tmp := saved_Reg_high & saved_Reg_low;
buf_REGISTERS_OUT(j) <= tmp(j-i*REGISTER_WIDTH);
end if;
end if;
end process;
end generate;
- gen_regoutnull : if USED_REGISTER_OUT(i) = '0' or BITMASK_REGISTER_OUT(j) = '0' generate
- buf_REGISTERS_OUT(j) <= RESET_REGISTER_OUT(j);
+ gen_regoutnull : if USED_CTRL_REGS(i) = '0' or USED_CTRL_BITMASK(j) = '0' generate
+ buf_REGISTERS_OUT(j) <= INIT_CTRL_REGS(j);
end generate;
end generate;
end generate;
+ buf_API_ERROR_PATTERN_OUT(31 downto 1) <= (others => '0');
+
API_READ_OUT <= buf_API_READ_OUT;
API_SEND_OUT <= buf_API_SEND_OUT;
API_WRITE_OUT <= buf_API_WRITE_OUT;
API_PACKET_NUM_OUT <= buf_API_PACKET_NUM_OUT;
API_DATA_OUT <= buf_API_DATA_OUT;
API_SHORT_TRANSFER_OUT <= buf_API_SHORT_TRANSFER_OUT;
- API_DTYPE_OUT <= (others => '0');
- API_MY_ADDRESS_OUT <= MY_ADDRESS;
- API_ERROR_PATTERN_OUT <= (others => '0');
+ API_DTYPE_OUT <= saved_operation;
+ API_ERROR_PATTERN_OUT <= buf_API_ERROR_PATTERN_OUT;
API_TARGET_ADDRESS_OUT <= (others => '0');
DAT_DATA_OUT <= buf_DAT_DATA_OUT;
DAT_READ_ENABLE_OUT <= buf_DAT_READ_ENABLE_OUT;
-
-
process(current_state)
begin
case current_state is
when HEADER_RECV => state_bits <= "001";
when REG_READ => state_bits <= "010";
when REG_WRITE => state_bits <= "011";
- when SEND_REPLY_DATA_finish => state_bits <= "100";
+ when SEND_REPLY_DATA_finish => state_bits <= "100";
when SEND_REPLY_SHORT_TRANSFER => state_bits <= "101";
- when SEND_REPLY_DATA => state_bits <= "110";
+ when ONE_READ => state_bits <= "110";
when others => state_bits <= "111";
end case;
end process;