From 867653c22b071bf3f3ce980de5f7c9be000642b3 Mon Sep 17 00:00:00 2001 From: hadeshyp Date: Wed, 2 Apr 2008 13:08:32 +0000 Subject: [PATCH] added regIO for addresses, Jan --- testbench/trb_net16_dummy_apl.vhd | 8 +- trb_net16_addresses.vhd | 188 ++++++++++++++++ trb_net16_api_base.vhd | 6 +- trb_net16_hub_base.vhd | 73 ++++--- trb_net16_hub_logic.vhd | 32 +-- trb_net16_ibuf.vhd | 16 +- trb_net16_regIO.vhd | 341 +++++++++++++++++++----------- trb_net_ram.vhd | 19 +- trb_net_ram_16x8_dp.vhd | 48 +++++ trb_net_ram_dp.vhd | 42 ++++ trb_net_ram_true_dp.vhd | 44 ++++ trb_net_std.vhd | 3 +- 12 files changed, 636 insertions(+), 184 deletions(-) create mode 100644 trb_net16_addresses.vhd create mode 100644 trb_net_ram_16x8_dp.vhd create mode 100644 trb_net_ram_dp.vhd create mode 100644 trb_net_ram_true_dp.vhd diff --git a/testbench/trb_net16_dummy_apl.vhd b/testbench/trb_net16_dummy_apl.vhd index 1ce0a85..bf957ff 100644 --- a/testbench/trb_net16_dummy_apl.vhd +++ b/testbench/trb_net16_dummy_apl.vhd @@ -15,8 +15,8 @@ use work.trb_net_std.all; entity trb_net16_dummy_apl is generic ( TARGET_ADDRESS : std_logic_vector (15 downto 0) := x"F001"; - PREFILL_LENGTH : integer := 1; - TRANSFER_LENGTH : integer := 1 -- length of dummy data + PREFILL_LENGTH : integer := 2; + TRANSFER_LENGTH : integer := 2 -- length of dummy data -- might not work with transfer_length > api_fifo -- because of incorrect handling of fifo_full_in! @@ -67,7 +67,7 @@ begin -- address <= x"0008"; -- reghigh <= x"DEAD"; -- reglow <= x"AFFE"; - address <= x"0003"; + address <= x"AD01"; reghigh <= x"000B"; reglow <= x"000D"; @@ -84,7 +84,7 @@ begin end process; APL_READ_OUT <= '1'; --just read, do not check - APL_DTYPE_OUT <= "1001"; + APL_DTYPE_OUT <= "1111"; APL_ERROR_PATTERN_OUT <= x"12345678"; APL_TARGET_ADDRESS_OUT <= TARGET_ADDRESS; --APL_DATA_OUT <= reg_counter; diff --git a/trb_net16_addresses.vhd b/trb_net16_addresses.vhd new file mode 100644 index 0000000..b0a887e --- /dev/null +++ b/trb_net16_addresses.vhd @@ -0,0 +1,188 @@ +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 diff --git a/trb_net16_api_base.vhd b/trb_net16_api_base.vhd index abf7201..2df0631 100644 --- a/trb_net16_api_base.vhd +++ b/trb_net16_api_base.vhd @@ -18,7 +18,9 @@ entity trb_net16_api_base is USE_VENDOR_CORES : integer range 0 to 1 := c_YES; SECURE_MODE_TO_APL: integer range 0 to 1 := c_YES; SECURE_MODE_TO_INT: integer range 0 to 1 := c_YES; - APL_WRITE_4_PACKETS:integer range 0 to 1 := c_NO + APL_WRITE_4_PACKETS:integer range 0 to 1 := c_NO; + BROADCAST_BITMASK : std_logic_vector(7 downto 0) := x"FF" + --which bits must be set to accept a broadcast? ); port( @@ -653,7 +655,7 @@ begin slave_start <= '1'; end if; if INT_SLAVE_PACKET_NUM_IN = "10" then - if INT_SLAVE_DATA_IN = APL_MY_ADDRESS_IN or INT_SLAVE_DATA_IN = BROADCAST_ADDRESS then + if (INT_SLAVE_DATA_IN = APL_MY_ADDRESS_IN) or (and_all(not(not INT_SLAVE_DATA_IN and (x"FF" & BROADCAST_BITMASK))) = '1') then next_state_to_apl <= sa_MY_ADDR; slave_start <= '1'; else diff --git a/trb_net16_hub_base.vhd b/trb_net16_hub_base.vhd index 2235e0a..d9a7cd5 100644 --- a/trb_net16_hub_base.vhd +++ b/trb_net16_hub_base.vhd @@ -17,7 +17,8 @@ entity trb_net16_hub_base is 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; @@ -163,6 +164,7 @@ architecture trb_net16_hub_base_arch of trb_net16_hub_base is 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); @@ -397,22 +399,29 @@ end component; 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; @@ -422,24 +431,31 @@ end component; 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; @@ -1085,24 +1101,25 @@ HUB_MED_CONNECTED(31 downto MII_NUMBER) <= (others => '1'); 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, @@ -1121,8 +1138,8 @@ HUB_MED_CONNECTED(31 downto MII_NUMBER) <= (others => '1'); 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, @@ -1130,9 +1147,11 @@ HUB_MED_CONNECTED(31 downto MII_NUMBER) <= (others => '1'); 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 diff --git a/trb_net16_hub_logic.vhd b/trb_net16_hub_logic.vhd index 6dbf20f..dac162f 100644 --- a/trb_net16_hub_logic.vhd +++ b/trb_net16_hub_logic.vhd @@ -85,18 +85,19 @@ architecture trb_net16_hub_logic_arch of trb_net16_hub_logic is ); end component; - component trb_net_ram is + component trb_net_ram_dp generic( - depth : integer := 4; + depth : integer := 3; width : integer := 16 ); port( - CLK : in std_logic; - wr : in std_logic; - ain : in std_logic_vector(depth-1 downto 0); - din : in std_logic_vector(width-1 downto 0); - aout : in std_logic_vector(depth-1 downto 0); - dout : out std_logic_vector(width-1 downto 0) + CLK : in std_logic; + wr1 : in std_logic; + a1 : in std_logic_vector(depth-1 downto 0); + dout1 : out std_logic_vector(width-1 downto 0); + din1 : in std_logic_vector(width-1 downto 0); + a2 : in std_logic_vector(depth-1 downto 0); + dout2 : out std_logic_vector(width-1 downto 0) ); end component; @@ -396,18 +397,19 @@ STAT_ERRORBITS <= REPLY_combined_trm_F1 & REPLY_combined_trm_F2; current_REPLY_reading_hdr <= next_REPLY_reading_hdr or REPLY_reading_hdr; gen_saving_hdr : for i in 0 to POINT_NUMBER-1 generate - last_HDR_RAM : trb_net_ram + last_HDR_RAM : trb_net_ram_dp generic map( depth => 2, width => 16 ) port map( - CLK => CLK, - wr => REPLY_reading_hdr(i), - ain => REPLY_PACKET_NUM_IN((i+1)*c_NUM_WIDTH-1 downto i*c_NUM_WIDTH), - din => REPLY_DATA_IN((i+1)*c_DATA_WIDTH-1 downto i*c_DATA_WIDTH), - aout => last_header_addr(1 downto 0), - dout => last_header_data((i+1)*c_DATA_WIDTH-1 downto i*c_DATA_WIDTH) + CLK => CLK, + wr1 => REPLY_reading_hdr(i), + a1 => REPLY_PACKET_NUM_IN((i+1)*c_NUM_WIDTH-1 downto i*c_NUM_WIDTH), + din1 => REPLY_DATA_IN((i+1)*c_DATA_WIDTH-1 downto i*c_DATA_WIDTH), + dout1 => open, + a2 => last_header_addr(1 downto 0), + dout2 => last_header_data((i+1)*c_DATA_WIDTH-1 downto i*c_DATA_WIDTH) ); end generate; last_header_addr <= packet_counter; diff --git a/trb_net16_ibuf.vhd b/trb_net16_ibuf.vhd index 9a6db0f..f264515 100644 --- a/trb_net16_ibuf.vhd +++ b/trb_net16_ibuf.vhd @@ -120,8 +120,6 @@ architecture trb_net16_ibuf_arch of trb_net16_ibuf is signal tmp_INT_DATA_OUT: std_logic_vector(c_DATA_WIDTH-1 downto 0); signal tmp_INT_PACKET_NUM_OUT: std_logic_vector(c_NUM_WIDTH-1 downto 0); - signal reading_header : std_logic; - type ERROR_STATE is (IDLE, GOT_OVERFLOW_ERROR, GOT_UNDEFINED_ERROR); signal current_error_state, next_error_state : ERROR_STATE; signal next_rec_buffer_size_out, current_rec_buffer_size_out: std_logic_vector(3 downto 0); @@ -313,12 +311,18 @@ begin fifo_read <= not fifo_empty and not (fifo_read_before and not - ((INT_INIT_READ_IN and not current_fifo_packet_type(3)) - or (INT_REPLY_READ_IN and current_fifo_packet_type(3)) or throw_away)); + ((sbuf_init_free and not current_fifo_packet_type(3)) + or (sbuf_reply_free and current_fifo_packet_type(3)) + or throw_away)); if (fifo_read_before = '1' and (current_fifo_packet_type(2 downto 0) /= TYPE_EOB)) then - tmp_INT_INIT_DATAREADY_OUT <= sbuf_init_free and not current_fifo_packet_type(3); - tmp_INT_REPLY_DATAREADY_OUT <= sbuf_reply_free and current_fifo_packet_type(3); + if SECURE_MODE = 1 then + tmp_INT_INIT_DATAREADY_OUT <= (sbuf_init_free) and not current_fifo_packet_type(3); + tmp_INT_REPLY_DATAREADY_OUT <= (sbuf_reply_free ) and current_fifo_packet_type(3); + else + tmp_INT_INIT_DATAREADY_OUT <= not current_fifo_packet_type(3); + tmp_INT_REPLY_DATAREADY_OUT <= current_fifo_packet_type(3); + end if; end if; if last_fifo_read = '1' then diff --git a/trb_net16_regIO.vhd b/trb_net16_regIO.vhd index 6abf310..338f003 100644 --- a/trb_net16_regIO.vhd +++ b/trb_net16_regIO.vhd @@ -18,25 +18,26 @@ entity trb_net16_regIO is 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); @@ -55,23 +56,25 @@ entity trb_net16_regIO is 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; @@ -79,7 +82,7 @@ architecture trb_net16_regIO_arch of trb_net16_regIO is 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); @@ -87,9 +90,33 @@ architecture trb_net16_regIO_arch of trb_net16_regIO is ); 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); @@ -105,35 +132,79 @@ 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_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; @@ -142,20 +213,22 @@ begin 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 => @@ -165,8 +238,7 @@ begin 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; @@ -177,57 +249,108 @@ begin 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'; @@ -238,14 +361,14 @@ begin 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); @@ -253,30 +376,19 @@ begin 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; @@ -293,6 +405,10 @@ begin next_API_WRITE_OUT <= '1'; next_state <= SEND_REPLY_DATA_finish; end if; + + + + when others => next_state <= IDLE; end case; @@ -304,30 +420,19 @@ begin 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; @@ -337,45 +442,45 @@ begin 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; @@ -385,8 +490,6 @@ begin - - process(current_state) begin case current_state is @@ -394,9 +497,9 @@ begin 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; diff --git a/trb_net_ram.vhd b/trb_net_ram.vhd index 5ee0c66..cbc2abd 100644 --- a/trb_net_ram.vhd +++ b/trb_net_ram.vhd @@ -8,16 +8,15 @@ use work.trb_net_std.all; entity trb_net_ram is generic( - depth : integer := 3; - width : integer := 16 + depth : integer := 5; + width : integer := 32 ); port( - CLK : in std_logic; - wr : in std_logic; - ain : in std_logic_vector(depth-1 downto 0); - din : in std_logic_vector(width-1 downto 0); - aout : in std_logic_vector(depth-1 downto 0); - dout : out std_logic_vector(width-1 downto 0) + CLK : in std_logic; + wr : in std_logic; + a : in std_logic_vector(depth-1 downto 0); + dout : out std_logic_vector(width-1 downto 0); + din : in std_logic_vector(width-1 downto 0) ); end entity; @@ -30,9 +29,9 @@ begin begin if rising_edge(CLK) then if wr = '1' then - ram(conv_integer((ain))) <= din; + ram(conv_integer(a)) <= din; end if; - dout <= ram(conv_integer((aout))); + dout <= ram(conv_integer(a)); end if; end process; end architecture; diff --git a/trb_net_ram_16x8_dp.vhd b/trb_net_ram_16x8_dp.vhd new file mode 100644 index 0000000..6cc106d --- /dev/null +++ b/trb_net_ram_16x8_dp.vhd @@ -0,0 +1,48 @@ +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_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 entity; + +architecture trb_net_ram_16x8_dp_arch of trb_net_ram_16x8_dp is + type ram_t is array(0 to 7) of std_logic_vector(15 downto 0); + SIGNAL ram : ram_t := (INIT0, INIT1, INIT2, INIT3, INIT4, INIT5, INIT6, INIT7); +begin + + + process(CLK) + begin + if rising_edge(CLK) then + if wr1 = '1' then + ram((conv_integer(a1))) <= din1; + end if; + dout1 <= ram(conv_integer(a1)); + dout2 <= ram(conv_integer(a2)); + end if; + end process; + +end architecture; \ No newline at end of file diff --git a/trb_net_ram_dp.vhd b/trb_net_ram_dp.vhd new file mode 100644 index 0000000..c01dce1 --- /dev/null +++ b/trb_net_ram_dp.vhd @@ -0,0 +1,42 @@ +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_net_ram_dp is + generic( + depth : integer := 3; + width : integer := 16 + ); + port( + CLK : in std_logic; + wr1 : in std_logic; + a1 : in std_logic_vector(depth-1 downto 0); + dout1 : out std_logic_vector(width-1 downto 0); + din1 : in std_logic_vector(width-1 downto 0); + a2 : in std_logic_vector(depth-1 downto 0); + dout2 : out std_logic_vector(width-1 downto 0) + ); +end entity; + +architecture trb_net_ram_dp_arch of trb_net_ram_dp is + type ram_t is array(0 to 2**depth-1) of std_logic_vector(width-1 downto 0); + SIGNAL ram : ram_t ; +begin + + + process(CLK) + begin + if rising_edge(CLK) then + if wr1 = '1' then + ram((conv_integer(a1))) <= din1; + end if; + dout1 <= ram(conv_integer(a1)); + dout2 <= ram(conv_integer(a2)); + end if; + end process; + +end architecture; diff --git a/trb_net_ram_true_dp.vhd b/trb_net_ram_true_dp.vhd new file mode 100644 index 0000000..169e158 --- /dev/null +++ b/trb_net_ram_true_dp.vhd @@ -0,0 +1,44 @@ +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_net_ram_true_dp is + generic( + depth : integer := 5; + width : integer := 32 + ); + port( + CLK : in std_logic; + wr1 : in std_logic; + wr2 : in std_logic; + a1 : in std_logic_vector(depth-1 downto 0); + dout1 : out std_logic_vector(width-1 downto 0); + din1 : in std_logic_vector(width-1 downto 0); + a2 : in std_logic_vector(depth-1 downto 0); + din2 : in std_logic_vector(width-1 downto 0); + dout2 : out std_logic_vector(width-1 downto 0) + ); +end entity; + +architecture trb_net_ram_true_dp_arch of trb_net_ram_true_dp is + type ram_t is array(0 to 2**depth-1) of std_logic_vector(width-1 downto 0); + SIGNAL ram : ram_t; + +begin + process(CLK) + begin + if rising_edge(CLK) then + if wr1 = '1' then + ram(conv_integer(a1)) <= din1; + elsif wr2 = '1' then + ram(conv_integer(a2)) <= din2; + end if; + dout1 <= ram(conv_integer(a1)); + dout2 <= ram(conv_integer(a2)); + end if; + end process; +end architecture; diff --git a/trb_net_std.vhd b/trb_net_std.vhd index 605c68e..ead1e06 100644 --- a/trb_net_std.vhd +++ b/trb_net_std.vhd @@ -7,7 +7,6 @@ USE IEEE.std_logic_UNSIGNED.ALL; package trb_net_std is type channel_config_t is array(0 to 3) of integer; - -- some basic definitions for the whole network ----------------------------------------------- @@ -90,6 +89,8 @@ package trb_net_std is constant LINK_STARTUP_WORD : std_logic_vector(15 downto 0) := x"e110"; + constant SET_ADDRESS : std_logic_vector(7 downto 0) := x"AD"; + constant ACK_ADDRESS : std_logic_vector(15 downto 0) := x"5ADD"; function and_all (arg : std_logic_vector) -- 2.43.0