From: hadeshyp Date: Mon, 12 Jan 2009 14:07:20 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: oldGBE~495 X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=f32733e7143ee1871cd913fb970c222783b236bf;p=trbnet.git *** empty log message *** --- diff --git a/basics/wide_adder.vhd b/basics/wide_adder.vhd new file mode 100644 index 0000000..b0bdd77 --- /dev/null +++ b/basics/wide_adder.vhd @@ -0,0 +1,102 @@ +--Adds up a given number of words, distributed over several clock cycles, + + + +LIBRARY ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.trb_net_std.all; + + +entity wide_adder is + generic( + WIDTH : integer := 16; + WORDS : integer := 16; --multiples of 2^parallel_adders only + PARALLEL_ADDERS : integer := 2 --2^n + ); + port( + CLK : in std_logic; + CLK_EN : in std_logic; + RESET : in std_logic; + INPUT_IN : in std_logic_vector(WIDTH*WORDS-1 downto 0); + START_IN : in std_logic; + VAL_ENABLE_IN: in std_logic_vector(WORDS-1 downto 0); + RESULT_OUT : out std_logic_vector(WIDTH-1 downto 0); + OVERFLOW_OUT : out std_logic; + READY_OUT : out std_logic + ); +end entity; + +architecture wide_adder_arch of wide_adder is + signal state : integer range 0 to WORDS/2**PARALLEL_ADDERS+2; + signal result : integer range 0 to 2**(WIDTH+PARALLEL_ADDERS)-1; + signal ready : std_logic; + signal overflow : std_logic; + + signal tmp_result : std_logic_vector(WIDTH+PARALLEL_ADDERS downto 0); +begin + + + + proc_result : process(CLK) + variable erg : integer range 0 to 2**(WIDTH+1)-1; + variable section : std_logic_vector(WIDTH*2**PARALLEL_ADDERS-1 downto 0); + begin + if rising_edge(CLK) then + if RESET = '1' then + state <= WORDS+PARALLEL_ADDERS; + overflow <= '0'; + ready <= '0'; + else + if START_IN = '1' then + state <= 0; + result <= 0; + ready <= '0'; + overflow <= '0'; + end if; + if (state) * 2**PARALLEL_ADDERS < WORDS then + gen_mux : for i in 0 to WIDTH*2**PARALLEL_ADDERS-1 loop + section(i) := INPUT_IN((state*2**PARALLEL_ADDERS)*WIDTH+i); + end loop; + erg := result; +-- if (WORDS/2**PARALLEL_ADDERS)*2**PARALLEL_ADDERS = WORDS then + gen_adders_simple : for i in 0 to 2**PARALLEL_ADDERS-1 loop + if VAL_ENABLE_IN(state*2**PARALLEL_ADDERS+i) = '1' then + erg := erg + to_integer(unsigned(section((i)*WIDTH+WIDTH-1 downto (i)*WIDTH))); + else + erg := erg; + end if; + end loop; +-- else +-- gen_adders_odd : for i in 0 to 2**PARALLEL_ADDERS-1 loop +-- if (state)*2**PARALLEL_ADDERS + i < WORDS then +-- erg := erg + to_integer(unsigned(section((i)*WIDTH+WIDTH-1 downto (i)*WIDTH))); +-- else +-- erg := erg; +-- end if; +-- end loop; +-- end if; + result <= erg; + state <= state + 1; + if (state*2**PARALLEL_ADDERS >= WORDS - 2**PARALLEL_ADDERS) then + ready <= '1'; + end if; + if erg >= 2**WIDTH then + overflow <= '1'; + end if; + end if; + end if; + end if; + end process; + +tmp_result <= std_logic_vector(to_unsigned(result,WIDTH+PARALLEL_ADDERS+1)); + + +OVERFLOW_OUT <= overflow; +RESULT_OUT <= tmp_result(WIDTH-1 downto 0); +READY_OUT <= ready; + + +end architecture; \ No newline at end of file diff --git a/special/trb_net_bridge_etrax_endpoint.vhd b/special/trb_net_bridge_etrax_endpoint.vhd index ea33983..7116010 100644 --- a/special/trb_net_bridge_etrax_endpoint.vhd +++ b/special/trb_net_bridge_etrax_endpoint.vhd @@ -211,6 +211,7 @@ architecture trb_net_bridge_etrax_endpoint_arch of trb_net_bridge_etrax_endpoint -- APL Control port APL_RUN_OUT : out std_logic; APL_MY_ADDRESS_IN : in std_logic_vector (15 downto 0); + APL_LENGTH_IN : in std_logic_vector (15 downto 0); APL_SEQNR_OUT : out std_logic_vector (7 downto 0); -- Internal direction port @@ -451,6 +452,7 @@ begin -- APL Control port APL_RUN_OUT => APL_RUN_OUT(2*i), APL_MY_ADDRESS_IN => APL_MY_ADDRESS_IN, + APL_LENGTH_IN => x"FFFF", APL_SEQNR_OUT => APL_SEQNR_OUT((2*i+1)*8-1 downto 2*i*8), -- Internal direction port INT_MASTER_DATAREADY_OUT => apl_to_buf_REPLY_DATAREADY(i), @@ -512,6 +514,7 @@ begin -- APL Control port APL_RUN_OUT => APL_RUN_OUT(2*i+1), APL_MY_ADDRESS_IN => APL_MY_ADDRESS_IN, + APL_LENGTH_IN => x"FFFF", APL_SEQNR_OUT => APL_SEQNR_OUT((2*i+2)*8-1 downto (2*i+1)*8), -- Internal direction port INT_MASTER_DATAREADY_OUT => apl_to_buf_INIT_DATAREADY(i), diff --git a/testbench/wide_adder_testbench.vhd b/testbench/wide_adder_testbench.vhd new file mode 100644 index 0000000..00ff5e8 --- /dev/null +++ b/testbench/wide_adder_testbench.vhd @@ -0,0 +1,71 @@ +LIBRARY ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.trb_net_std.all; + + +entity testbench is +end entity; + + +architecture test_arch of testbench is + + component wide_adder is + generic( + WIDTH : integer := 16; + WORDS : integer := 16; + PARALLEL_ADDERS : integer := 2 --2^n + ); + port( + CLK : in std_logic; + CLK_EN : in std_logic; + RESET : in std_logic; + INPUT_IN : in std_logic_vector(WIDTH*WORDS-1 downto 0); + START_IN : in std_logic; + VAL_ENABLE_IN: in std_logic_vector(WORDS-1 downto 0); + RESULT_OUT : out std_logic_vector(WIDTH-1 downto 0); + OVERFLOW_OUT : out std_logic; + READY_OUT : out std_logic + ); + end component; + +signal CLK : std_logic := '1'; +signal CLK_EN : std_logic := '1'; +signal RESET : std_logic := '1'; + +signal start : std_logic := '0'; +signal overflow : std_logic := '0'; +signal ready : std_logic := '0'; +signal result : std_logic_vector(15 downto 0); +signal input : std_logic_vector(255 downto 0); +signal enable : std_logic_vector(15 downto 0); + +begin +RESET <= '0' after 100 ns; +CLK <= not CLK after 5 ns; + +start <= '1' after 145 ns, '0' after 155 ns, '1' after 295 ns, '0' after 305 ns; +input <= x"8000_4000_2000_1000_0800_0400_0200_0100_0010_0020_0040_0080_0001_0002_0004_0001"; +enable <= "0111111111111111"; + + the_adder : wide_adder + generic map( + WIDTH => 16, + WORDS => 16, + PARALLEL_ADDERS => 2 + ) + port map( + CLK => CLK, + CLK_EN => CLK_EN, + RESET => RESET, + INPUT_IN => input, + START_IN => start, + VAL_ENABLE_IN => enable, + RESULT_OUT => result, + OVERFLOW_OUT => overflow, + READY_OUT => ready + ); + +end architecture; \ No newline at end of file diff --git a/trb_net16_endpoint_hades_full.vhd b/trb_net16_endpoint_hades_full.vhd index 57c440e..cc03805 100644 --- a/trb_net16_endpoint_hades_full.vhd +++ b/trb_net16_endpoint_hades_full.vhd @@ -75,7 +75,7 @@ entity trb_net16_endpoint_hades_full is --Data Port - IPU_NUMBER_OUT : out std_logic_vector (15 downto 0); + IPU_NUMBER_OUT : out std_logic_vector (15 downto 0); IPU_INFORMATION_OUT : out std_logic_vector (7 downto 0); --start strobe IPU_START_READOUT_OUT: out std_logic; @@ -89,6 +89,7 @@ entity trb_net16_endpoint_hades_full is IPU_LENGTH_IN : in std_logic_vector (15 downto 0); IPU_ERROR_PATTERN_IN : in std_logic_vector (31 downto 0); + -- Slow Control Data Port REGIO_COMMON_STAT_REG_IN : in std_logic_vector(std_COMSTATREG*32-1 downto 0) := (others => '0'); REGIO_COMMON_CTRL_REG_OUT : out std_logic_vector(std_COMCTRLREG*32-1 downto 0); diff --git a/trb_net16_hub_base.vhd b/trb_net16_hub_base.vhd index 3b923cd..9973b7e 100644 --- a/trb_net16_hub_base.vhd +++ b/trb_net16_hub_base.vhd @@ -9,7 +9,7 @@ use work.trb_net16_hub_func.all; entity trb_net16_hub_base is generic ( --hub control - HUB_CTRL_CHANNELNUM : integer range 0 to 3 := 0;--c_SLOW_CTRL_CHANNEL; + HUB_CTRL_CHANNELNUM : integer range 0 to 3 := c_SLOW_CTRL_CHANNEL; HUB_CTRL_DEPTH : integer range 0 to 6 := c_FIFO_BRAM; HUB_USED_CHANNELS : hub_channel_config_t := (c_YES,c_YES,c_YES,c_YES); USE_CHECKSUM : hub_channel_config_t := (c_YES,c_YES,c_YES,c_YES); @@ -184,6 +184,7 @@ architecture trb_net16_hub_base_arch of trb_net16_hub_base is 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); + singal HUBLOGIC_IPU_STAT_DEBUG : std_logic_vector (31 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); @@ -234,6 +235,40 @@ architecture trb_net16_hub_base_arch of trb_net16_hub_base is ); end component; + component trb_net16_hub_ipu_logic is + generic ( + POINT_NUMBER : integer range 2 to 32 := 3 + ); + port ( + CLK : in std_logic; + RESET : in std_logic; + CLK_EN : in std_logic; + --Internal interfaces to IOBufs + INIT_DATAREADY_IN : in std_logic_vector (POINT_NUMBER-1 downto 0); + INIT_DATA_IN : in std_logic_vector (c_DATA_WIDTH*POINT_NUMBER-1 downto 0); + INIT_PACKET_NUM_IN : in std_logic_vector (c_NUM_WIDTH*POINT_NUMBER-1 downto 0); + INIT_READ_OUT : out std_logic_vector (POINT_NUMBER-1 downto 0); + INIT_DATAREADY_OUT : out std_logic_vector (POINT_NUMBER-1 downto 0); + INIT_DATA_OUT : out std_logic_vector (c_DATA_WIDTH*POINT_NUMBER-1 downto 0); + INIT_PACKET_NUM_OUT : out std_logic_vector (c_NUM_WIDTH*POINT_NUMBER-1 downto 0); + INIT_READ_IN : in std_logic_vector (POINT_NUMBER-1 downto 0); + REPLY_DATAREADY_IN : in std_logic_vector (POINT_NUMBER-1 downto 0); + REPLY_DATA_IN : in std_logic_vector (c_DATA_WIDTH*POINT_NUMBER-1 downto 0); + REPLY_PACKET_NUM_IN : in std_logic_vector (c_NUM_WIDTH*POINT_NUMBER-1 downto 0); + REPLY_READ_OUT : out std_logic_vector (POINT_NUMBER-1 downto 0); + REPLY_DATAREADY_OUT : out std_logic_vector (POINT_NUMBER-1 downto 0); + REPLY_DATA_OUT : out std_logic_vector (c_DATA_WIDTH*POINT_NUMBER-1 downto 0); + REPLY_PACKET_NUM_OUT : out std_logic_vector (c_NUM_WIDTH*POINT_NUMBER-1 downto 0); + REPLY_READ_IN : in std_logic_vector (POINT_NUMBER-1 downto 0); + --Status ports + STAT_DEBUG : out std_logic_vector (31 downto 0); + STAT_POINTS_locked : out std_logic_vector (31 downto 0); + STAT_ERRORBITS : out std_logic_vector (31 downto 0); + CTRL : in std_logic_vector (15 downto 0); + CTRL_activepoints : in std_logic_vector (31 downto 0) := (others => '1') + ); + end component; + component trb_net16_io_multiplexer is port( -- Misc @@ -1103,38 +1138,73 @@ HUB_MED_CONNECTED(31 downto MII_NUMBER) <= (others => '1'); begin gen_logic : if HUB_USED_CHANNELS(i) = 1 generate HUB_CTRL_final_activepoints((i+1)*32-1 downto i*32) <= HUB_CTRL_activepoints((i+1)*32-1 downto i*32) and HUB_MED_CONNECTED; - HUBLOGIC : trb_net16_hub_logic - generic map ( - --media interfaces - POINT_NUMBER => point_num - ) - port map( - CLK => CLK, - RESET => RESET, - CLK_EN => CLK_EN, - INIT_DATAREADY_IN => HUB_INIT_DATAREADY_IN(next_point_num-1 downto first_point_num), - INIT_DATA_IN => HUB_INIT_DATA_IN(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH), - INIT_PACKET_NUM_IN => HUB_INIT_PACKET_NUM_IN(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH), - INIT_READ_OUT => HUB_INIT_READ_OUT(next_point_num-1 downto first_point_num), - INIT_DATAREADY_OUT => HUB_INIT_DATAREADY_OUT(next_point_num-1 downto first_point_num), - INIT_DATA_OUT => HUB_INIT_DATA_OUT(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH), - INIT_PACKET_NUM_OUT => HUB_INIT_PACKET_NUM_OUT(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH), - INIT_READ_IN => HUB_INIT_READ_IN(next_point_num-1 downto first_point_num), - REPLY_HEADER_OUT => HUB_REPLY_SEND_HEADER_OUT(next_point_num-1 downto first_point_num), - REPLY_DATAREADY_IN => HUB_REPLY_DATAREADY_IN(next_point_num-1 downto first_point_num), - REPLY_DATA_IN => HUB_REPLY_DATA_IN(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH), - REPLY_PACKET_NUM_IN => HUB_REPLY_PACKET_NUM_IN(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH), - REPLY_READ_OUT => HUB_REPLY_READ_OUT(next_point_num-1 downto first_point_num), - REPLY_DATAREADY_OUT => HUB_REPLY_DATAREADY_OUT(next_point_num-1 downto first_point_num), - REPLY_DATA_OUT => HUB_REPLY_DATA_OUT(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH), - REPLY_PACKET_NUM_OUT => HUB_REPLY_PACKET_NUM_OUT(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH), - REPLY_READ_IN => HUB_REPLY_READ_IN(next_point_num-1 downto first_point_num), - STAT => buf_HUB_STAT_CHANNEL((i+1)*16-1 downto i*16), - STAT_POINTS_locked => buf_STAT_POINTS_locked((i+1)*32-1 downto i*32), - STAT_ERRORBITS => open, - CTRL => HUB_CTRL_CHANNEL((i+1)*16-1 downto i*16), - CTRL_activepoints => HUB_CTRL_final_activepoints((i+1)*32-1 downto i*32) - ); + gen_select_logic1 : if i /= c_IPU_CHANNEL generate + HUBLOGIC : trb_net16_hub_logic + generic map ( + --media interfaces + POINT_NUMBER => point_num + ) + port map( + CLK => CLK, + RESET => RESET, + CLK_EN => CLK_EN, + INIT_DATAREADY_IN => HUB_INIT_DATAREADY_IN(next_point_num-1 downto first_point_num), + INIT_DATA_IN => HUB_INIT_DATA_IN(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH), + INIT_PACKET_NUM_IN => HUB_INIT_PACKET_NUM_IN(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH), + INIT_READ_OUT => HUB_INIT_READ_OUT(next_point_num-1 downto first_point_num), + INIT_DATAREADY_OUT => HUB_INIT_DATAREADY_OUT(next_point_num-1 downto first_point_num), + INIT_DATA_OUT => HUB_INIT_DATA_OUT(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH), + INIT_PACKET_NUM_OUT => HUB_INIT_PACKET_NUM_OUT(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH), + INIT_READ_IN => HUB_INIT_READ_IN(next_point_num-1 downto first_point_num), + REPLY_HEADER_OUT => HUB_REPLY_SEND_HEADER_OUT(next_point_num-1 downto first_point_num), + REPLY_DATAREADY_IN => HUB_REPLY_DATAREADY_IN(next_point_num-1 downto first_point_num), + REPLY_DATA_IN => HUB_REPLY_DATA_IN(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH), + REPLY_PACKET_NUM_IN => HUB_REPLY_PACKET_NUM_IN(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH), + REPLY_READ_OUT => HUB_REPLY_READ_OUT(next_point_num-1 downto first_point_num), + REPLY_DATAREADY_OUT => HUB_REPLY_DATAREADY_OUT(next_point_num-1 downto first_point_num), + REPLY_DATA_OUT => HUB_REPLY_DATA_OUT(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH), + REPLY_PACKET_NUM_OUT => HUB_REPLY_PACKET_NUM_OUT(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH), + REPLY_READ_IN => HUB_REPLY_READ_IN(next_point_num-1 downto first_point_num), + STAT => buf_HUB_STAT_CHANNEL((i+1)*16-1 downto i*16), + STAT_POINTS_locked => buf_STAT_POINTS_locked((i+1)*32-1 downto i*32), + STAT_ERRORBITS => open, + CTRL => HUB_CTRL_CHANNEL((i+1)*16-1 downto i*16), + CTRL_activepoints => HUB_CTRL_final_activepoints((i+1)*32-1 downto i*32) + ); + end generate; + gen_select_logic2 : if i = c_IPU_CHANNEL generate + HUBLOGIC : trb_net16_hub_ipu_logic + generic map ( + --media interfaces + POINT_NUMBER => point_num + ) + port map( + CLK => CLK, + RESET => RESET, + CLK_EN => CLK_EN, + INIT_DATAREADY_IN => HUB_INIT_DATAREADY_IN(next_point_num-1 downto first_point_num), + INIT_DATA_IN => HUB_INIT_DATA_IN(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH), + INIT_PACKET_NUM_IN => HUB_INIT_PACKET_NUM_IN(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH), + INIT_READ_OUT => HUB_INIT_READ_OUT(next_point_num-1 downto first_point_num), + INIT_DATAREADY_OUT => HUB_INIT_DATAREADY_OUT(next_point_num-1 downto first_point_num), + INIT_DATA_OUT => HUB_INIT_DATA_OUT(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH), + INIT_PACKET_NUM_OUT => HUB_INIT_PACKET_NUM_OUT(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH), + INIT_READ_IN => HUB_INIT_READ_IN(next_point_num-1 downto first_point_num), + REPLY_DATAREADY_IN => HUB_REPLY_DATAREADY_IN(next_point_num-1 downto first_point_num), + REPLY_DATA_IN => HUB_REPLY_DATA_IN(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH), + REPLY_PACKET_NUM_IN => HUB_REPLY_PACKET_NUM_IN(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH), + REPLY_READ_OUT => HUB_REPLY_READ_OUT(next_point_num-1 downto first_point_num), + REPLY_DATAREADY_OUT => HUB_REPLY_DATAREADY_OUT(next_point_num-1 downto first_point_num), + REPLY_DATA_OUT => HUB_REPLY_DATA_OUT(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH), + REPLY_PACKET_NUM_OUT => HUB_REPLY_PACKET_NUM_OUT(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH), + REPLY_READ_IN => HUB_REPLY_READ_IN(next_point_num-1 downto first_point_num), + STAT_DEBUG => HUBLOGIC_IPU_STAT_DEBUG(31 downto 0), + STAT_POINTS_locked => buf_STAT_POINTS_locked((i+1)*32-1 downto i*32), + STAT_ERRORBITS => open, + CTRL => HUB_CTRL_CHANNEL((i+1)*16-1 downto i*16), + CTRL_activepoints => HUB_CTRL_final_activepoints((i+1)*32-1 downto i*32) + ); + end generate; end generate; end generate; diff --git a/trb_net16_hub_ipu_logic.vhd b/trb_net16_hub_ipu_logic.vhd new file mode 100644 index 0000000..1bf0e2d --- /dev/null +++ b/trb_net16_hub_ipu_logic.vhd @@ -0,0 +1,843 @@ +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_hub_ipu_logic is + generic ( + --media interfaces + POINT_NUMBER : integer range 2 to 32 := 3 + ); + port ( + CLK : in std_logic; + RESET : in std_logic; + CLK_EN : in std_logic; + + --Internal interfaces to IOBufs + INIT_DATAREADY_IN : in std_logic_vector (POINT_NUMBER-1 downto 0); + INIT_DATA_IN : in std_logic_vector (c_DATA_WIDTH*POINT_NUMBER-1 downto 0); + INIT_PACKET_NUM_IN : in std_logic_vector (c_NUM_WIDTH*POINT_NUMBER-1 downto 0); + INIT_READ_OUT : out std_logic_vector (POINT_NUMBER-1 downto 0); + + INIT_DATAREADY_OUT : out std_logic_vector (POINT_NUMBER-1 downto 0); + INIT_DATA_OUT : out std_logic_vector (c_DATA_WIDTH*POINT_NUMBER-1 downto 0); + INIT_PACKET_NUM_OUT : out std_logic_vector (c_NUM_WIDTH*POINT_NUMBER-1 downto 0); + INIT_READ_IN : in std_logic_vector (POINT_NUMBER-1 downto 0); + + REPLY_DATAREADY_IN : in std_logic_vector (POINT_NUMBER-1 downto 0); + REPLY_DATA_IN : in std_logic_vector (c_DATA_WIDTH*POINT_NUMBER-1 downto 0); + REPLY_PACKET_NUM_IN : in std_logic_vector (c_NUM_WIDTH*POINT_NUMBER-1 downto 0); + REPLY_READ_OUT : out std_logic_vector (POINT_NUMBER-1 downto 0); + + REPLY_DATAREADY_OUT : out std_logic_vector (POINT_NUMBER-1 downto 0); + REPLY_DATA_OUT : out std_logic_vector (c_DATA_WIDTH*POINT_NUMBER-1 downto 0); + REPLY_PACKET_NUM_OUT : out std_logic_vector (c_NUM_WIDTH*POINT_NUMBER-1 downto 0); + REPLY_READ_IN : in std_logic_vector (POINT_NUMBER-1 downto 0); + + MY_ADDRESS_IN : in std_logic_vector (15 downto 0); + --Status ports + STAT_DEBUG : out std_logic_vector (31 downto 0); + STAT_POINTS_locked : out std_logic_vector (31 downto 0); + STAT_ERRORBITS : out std_logic_vector (31 downto 0); + CTRL : in std_logic_vector (15 downto 0); + CTRL_activepoints : in std_logic_vector (31 downto 0) := (others => '1') + ); +end entity; + +architecture trb_net16_hub_ipu_logic_arch of trb_net16_hub_ipu_logic is + + component trb_net16_sbuf is + generic ( + VERSION : integer := 0 + ); + port( + -- Misc + CLK : in std_logic; + RESET : in std_logic; + CLK_EN : in std_logic; + -- port to combinatorial logic + COMB_DATAREADY_IN : in STD_LOGIC; --comb logic provides data word + COMB_next_READ_OUT: out STD_LOGIC; --sbuf can read in NEXT cycle + COMB_READ_IN : in STD_LOGIC; --comb logic IS reading + COMB_DATA_IN : in STD_LOGIC_VECTOR (c_DATA_WIDTH-1 downto 0); -- Data word + COMB_PACKET_NUM_IN: in STD_LOGIC_VECTOR (c_NUM_WIDTH-1 downto 0); + -- Port to synchronous output. + SYN_DATAREADY_OUT : out STD_LOGIC; + SYN_DATA_OUT : out STD_LOGIC_VECTOR (c_DATA_WIDTH-1 downto 0); -- Data word + SYN_PACKET_NUM_OUT: out STD_LOGIC_VECTOR (c_NUM_WIDTH-1 downto 0); + SYN_READ_IN : in STD_LOGIC; + -- Status and control port + STAT_BUFFER : out STD_LOGIC + ); + end component; + component trb_net_priority_arbiter is + generic ( + WIDTH : integer := POINT_NUMBER + ); + port( + -- Misc + CLK : in std_logic; + RESET : in std_logic; + CLK_EN : in std_logic; + INPUT_IN : in STD_LOGIC_VECTOR (WIDTH-1 downto 0); + RESULT_OUT: out STD_LOGIC_VECTOR (WIDTH-1 downto 0); + ENABLE : in std_logic; + CTRL : in STD_LOGIC_VECTOR (9 downto 0) + ); + end component; + + component trb_net_ram_dp + 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 component; + + component wide_adder is + generic( + WIDTH : integer := 16; + WORDS : integer := 16; --multiples of 2^parallel_adders only + PARALLEL_ADDERS : integer := 2 --2^n + ); + port( + CLK : in std_logic; + CLK_EN : in std_logic; + RESET : in std_logic; + INPUT_IN : in std_logic_vector(WIDTH*WORDS-1 downto 0); + START_IN : in std_logic; + VAL_ENABLE_IN: in std_logic_vector(WORDS-1 downto 0); + RESULT_OUT : out std_logic_vector(WIDTH-1 downto 0); + OVERFLOW_OUT : out std_logic; + READY_OUT : out std_logic + ); + end component; + + +--signals init_pool + signal INIT_POOL_DATAREADY : std_logic; + signal INIT_POOL_READ : std_logic; + signal INIT_POOL_DATA : std_logic_vector(c_DATA_WIDTH-1 downto 0); + signal INIT_POOL_PACKET_NUM : std_logic_vector(c_NUM_WIDTH-1 downto 0); + signal init_has_read_from_pool : std_logic_vector(POINT_NUMBER-1 downto 0); + signal saved_INIT_TYPE, current_INIT_TYPE : std_logic_vector(2 downto 0); + + signal buf_INIT_READ_OUT : std_logic_vector(POINT_NUMBER-1 downto 0); + signal buf_REPLY_READ_OUT : std_logic_vector(POINT_NUMBER-1 downto 0); + signal REPLY_POOL_DATAREADY : std_logic; + signal REPLY_POOL_READ : std_logic; + signal REPLY_POOL_DATA : std_logic_vector(c_DATA_WIDTH-1 downto 0); + signal REPLY_POOL_PACKET_NUM : std_logic_vector(c_NUM_WIDTH-1 downto 0); + + signal current_reply_packet_type : std_logic_vector(2 downto 0); + signal saved_reply_packet_type : std_logic_vector(2 downto 0); + signal last_reply_packet_type : std_logic_vector(2 downto 0); + signal current_reply_reading_trm : std_logic_vector(POINT_NUMBER-1 downto 0); + signal reply_reading_F0 : std_logic_vector(POINT_NUMBER-1 downto 0); + signal reply_reading_F1 : std_logic_vector(POINT_NUMBER-1 downto 0); + signal reply_reading_F2 : std_logic_vector(POINT_NUMBER-1 downto 0); + signal reply_reading_F3 : std_logic_vector(POINT_NUMBER-1 downto 0); + signal reply_combined_trm_F1 : std_logic_vector(c_DATA_WIDTH-1 downto 0); + signal reply_combined_trm_F2 : std_logic_vector(c_DATA_WIDTH-1 downto 0); + signal reply_combined_trm_F3 : std_logic_vector(c_DATA_WIDTH-1 downto 0); + signal REPLY_MUX_real_reading : std_logic; + signal real_activepoints : std_logic_vector(POINT_NUMBER-1 downto 0); + signal hdrram_write_enable : std_logic_vector(POINT_NUMBER-1 downto 0); + signal hdrram_address : std_logic_vector(3*POINT_NUMBER-1 downto 0); + signal current_waiting_for_reply : std_logic_vector(POINT_NUMBER-1 downto 0); + signal next_current_waiting_for_reply : std_logic_vector(POINT_NUMBER-1 downto 0); + + signal reply_reading_HDR : std_logic_vector(POINT_NUMBER-1 downto 0); + signal reply_reading_DHDR : std_logic_vector(POINT_NUMBER-1 downto 0); + signal next_REPLY_reading_hdr : std_logic_vector(POINT_NUMBER-1 downto 0); + signal current_REPLY_reading_hdr : std_logic_vector(POINT_NUMBER-1 downto 0); + signal last_header_addr : std_logic_vector(c_NUM_WIDTH-1 downto 0); + signal last_header_data : std_logic_vector(POINT_NUMBER*c_DATA_WIDTH-1 downto 0); + signal reading_last_hdr,next_reading_last_hdr : std_logic_vector(POINT_NUMBER-1 downto 0); + +--general signals + signal locked, next_locked : std_logic; + signal get_locked, release_locked : std_logic; + signal got_trm : std_logic_vector(POINT_NUMBER-1 downto 0); + signal locking_point, next_locking_point : std_logic_vector(POINT_NUMBER-1 downto 0); + signal send_reply_trm : std_logic; + + signal init_locked, next_init_locked : std_logic; + signal get_init_locked, release_init_locked: std_logic; + + signal REPLY_MUX_reading : std_logic_vector(POINT_NUMBER-1 downto 0); + signal reply_arbiter_result,last_reply_arbiter_result : std_logic_vector(POINT_NUMBER-1 downto 0); + + type state_type is (IDLE, CHECK_DHDR, SENDING_DATA, SENDING_REPLY_TRM); + signal current_state, next_state : state_type; + signal packet_counter : std_logic_vector(c_NUM_WIDTH-1 downto 0); + signal data_counter : std_logic_vector(7 downto 0); + signal SEQ_NR : std_logic_vector(7 downto 0); + signal comb_REPLY_POOL_DATAREADY : std_logic; + signal comb_REPLY_POOL_DATA : std_logic_vector(c_DATA_WIDTH-1 downto 0); + signal comb_REPLY_POOL_PACKET_NUM : std_logic_vector(c_NUM_WIDTH-1 downto 0); + signal REPLY_POOL_next_read : std_logic; + signal comb_REPLY_POOL_next_read : std_logic; + + + signal reply_point_lock, next_point_lock : std_logic; + + signal comb_REPLY_muxed_DATAREADY : std_logic; + signal comb_REPLY_muxed_DATA : std_logic_vector(c_DATA_WIDTH-1 downto 0); + signal comb_REPLY_muxed_PACKET_NUM : std_logic_vector(c_NUM_WIDTH-1 downto 0); + signal reply_arbiter_CLK_EN : std_logic; + signal init_arbiter_CLK_EN : std_logic; + signal init_arbiter_ENABLE : std_logic; + signal init_arbiter_read_out : std_logic_vector(POINT_NUMBER-1 downto 0); + signal reply_arbiter_input : std_logic_vector(POINT_NUMBER-1 downto 0); + signal reply_arbiter_enable : std_logic; + + signal INIT_muxed_DATAREADY : std_logic; + signal INIT_muxed_DATA : std_logic_vector(c_DATA_WIDTH-1 downto 0); + signal INIT_muxed_PACKET_NUM : std_logic_vector(c_NUM_WIDTH-1 downto 0); + signal INIT_muxed_READ : std_logic; + signal comb_INIT_next_read : std_logic; + signal reply_fsm_state : std_logic_vector(7 downto 0); + + signal waiting_for_init_finish, next_waiting_for_init_finish : std_logic; + + signal waiting_for_DHDR_word : std_logic_vector(POINT_NUMBER-1 downto 0); + signal next_waiting_for_DHDR_word : std_logic_vector(POINT_NUMBER-1 downto 0); + + signal reply_adder_start : std_logic; + signal reply_adder_overflow : std_logic; + signal reply_adder_ready : std_logic; + signal reply_adder_val_enable : std_logic_vector(POINT_NUMBER-1 downto 0); + signal reply_adder_result : std_logic_vector(15 downto 0); + + +begin + + INIT_POOL_SBUF: trb_net16_sbuf + generic map ( + Version => std_SBUF_VERSION + ) + port map ( + CLK => CLK, + RESET => RESET, + CLK_EN => CLK_EN, + COMB_DATAREADY_IN => INIT_muxed_DATAREADY, + COMB_next_READ_OUT => comb_INIT_next_read, + COMB_READ_IN => INIT_muxed_READ, + COMB_DATA_IN => INIT_muxed_DATA, + COMB_PACKET_NUM_IN => INIT_muxed_PACKET_NUM, + SYN_DATAREADY_OUT => INIT_POOL_DATAREADY, + SYN_DATA_OUT => INIT_POOL_DATA, + SYN_PACKET_NUM_OUT => INIT_POOL_PACKET_NUM, + SYN_READ_IN => INIT_POOL_READ + ); + + process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + INIT_muxed_READ <= '0'; + else + INIT_muxed_READ <= comb_INIT_next_read; + end if; + end if; + end process; + + +--choosing reply point + INIT_ARBITER: trb_net_priority_arbiter + generic map (WIDTH => POINT_NUMBER) + port map ( + CLK => CLK, + RESET => RESET, + CLK_EN => init_arbiter_CLK_EN, + INPUT_IN => INIT_DATAREADY_IN, + RESULT_OUT => init_arbiter_read_out, + ENABLE => init_arbiter_ENABLE, + CTRL => (others => '0') + ); + init_arbiter_CLK_EN <= not locked; + init_arbiter_ENABLE <= not init_locked; + +--Datapool for Init-Channel + INIT_muxed_DATAREADY <= or_all(INIT_DATAREADY_IN and buf_INIT_READ_OUT) and not init_locked and INIT_muxed_READ; + INIT_POOL_READ <= and_all(INIT_READ_IN or init_has_read_from_pool or locking_point or not real_activepoints); + INIT_READ_OUT <= buf_INIT_READ_OUT; + + gen_iro : for i in 0 to POINT_NUMBER-1 generate + buf_INIT_READ_OUT(i) <= init_arbiter_read_out(i) and not init_locked and INIT_muxed_READ; + end generate; + + gen_init_pool_data0: for i in 0 to c_DATA_WIDTH-1 generate + process(INIT_DATA_IN, buf_INIT_READ_OUT) + variable VAR_INIT_POOL_DATA : std_logic; + begin + VAR_INIT_POOL_DATA := '0'; + gen_init_pool_data1 : for j in 0 to POINT_NUMBER-1 loop + VAR_INIT_POOL_DATA := VAR_INIT_POOL_DATA or (INIT_DATA_IN(j*c_DATA_WIDTH+i) and buf_INIT_READ_OUT(j)); + end loop; + INIT_muxed_DATA(i) <= VAR_INIT_POOL_DATA; + end process; + end generate; + + gen_init_pool_data2: for i in 0 to c_NUM_WIDTH-1 generate + process(INIT_PACKET_NUM_IN, buf_INIT_READ_OUT) + variable VAR_INIT_POOL_PACKET_NUM : std_logic; + begin + VAR_INIT_POOL_PACKET_NUM := '0'; + gen_init_pool_data3 : for j in 0 to POINT_NUMBER-1 loop + VAR_INIT_POOL_PACKET_NUM := VAR_INIT_POOL_PACKET_NUM or (INIT_PACKET_NUM_IN(j*c_NUM_WIDTH+i) and buf_INIT_READ_OUT(j)); + end loop; + INIT_muxed_PACKET_NUM(i) <= VAR_INIT_POOL_PACKET_NUM; + end process; + end generate; + + +--init_has_read signal + gen_hasread: for i in 0 to POINT_NUMBER-1 generate + process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' or INIT_POOL_READ = '1' then + init_has_read_from_pool(i) <= '0'; + elsif INIT_POOL_DATAREADY = '1' and INIT_READ_IN(i) = '1' then + init_has_read_from_pool(i) <= '1'; + end if; + end if; + end process; + end generate; + +--signals to obufs + gen_init_data_out: for i in 0 to POINT_NUMBER-1 generate + INIT_DATAREADY_OUT(i) <= INIT_POOL_DATAREADY and not init_has_read_from_pool(i) and real_activepoints(i) and not locking_point(i); + INIT_DATA_OUT((i+1)*c_DATA_WIDTH-1 downto i*c_DATA_WIDTH) <= INIT_POOL_DATA; + INIT_PACKET_NUM_OUT((i+1)*c_NUM_WIDTH-1 downto i*c_NUM_WIDTH) <= INIT_POOL_PACKET_NUM; + end generate; + + +--locked signals +--locked: transfer is running +--init_locked: waiting for reply channel to finish + + get_locked <= INIT_muxed_DATAREADY; + next_locked <= (get_locked or locked) and not release_locked; + next_locking_point <= (INIT_DATAREADY_IN) when (locked = '0' and REPLY_POOL_DATAREADY = '0') else locking_point; + --buf_INIT_READ_OUT and + + get_init_locked <= '1' when saved_INIT_TYPE = TYPE_TRM and INIT_muxed_PACKET_NUM = c_F3 else '0'; + release_init_locked <= release_locked; + next_init_locked <= (get_init_locked or init_locked) and not release_init_locked; + + + process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + locked <= '0'; + locking_point <= (others => '0'); + init_locked <= '0'; + else + locked <= next_locked; + locking_point <= next_locking_point; + init_locked <= next_init_locked; + end if; + end if; + end process; + +--saving necessary data +---------------------------------- + save_INIT_TYPE : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' or (INIT_muxed_DATAREADY = '1' and INIT_muxed_PACKET_NUM = c_F3) then + saved_INIT_TYPE <= TYPE_ILLEGAL; + elsif INIT_muxed_DATAREADY = '1' and INIT_muxed_PACKET_NUM = c_H0 then + saved_INIT_TYPE <= INIT_muxed_DATA(2 downto 0); + end if; + end if; + end process; + current_INIT_TYPE <= INIT_muxed_DATA(2 downto 0) when INIT_muxed_DATAREADY = '1' and INIT_muxed_PACKET_NUM = c_H0 + else saved_INIT_TYPE; + + save_SEQ_NR : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + SEQ_NR <= (others => '0'); + elsif INIT_POOL_PACKET_NUM = c_F3 and current_INIT_TYPE = TYPE_HDR then + SEQ_NR <= INIT_POOL_DATA(11 downto 4); + end if; + end if; + end process; + + + + +------------------------------ +--REPLY----------------------- +------------------------------ + + buf_REPLY_READ_OUT <= reply_reading_trm or reply_reading_HDR or reply_reading_DHDR or reply_mux_reading + when REPLY_POOL_next_read = '1' + else reply_reading_trm or reply_reading_HDR or reply_real_reading_DHDR; + REPLY_READ_OUT <= buf_REPLY_READ_OUT; + + send_reply_trm <= and_all(got_trm); + + +--save current packet type & number +----------------------------------- + + gen_reading_trmFn : for i in 0 to POINT_NUMBER-1 generate + reply_reading_F0(i) <= not REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+1) and not REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH) + and not REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+2) and REPLY_DATAREADY_IN(i); + reply_reading_F1(i) <= not REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+1) and REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH) + and not REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+2) and REPLY_DATAREADY_IN(i); + reply_reading_F2(i) <= REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+1) and not REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH) + and not REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+2) and REPLY_DATAREADY_IN(i); + reply_reading_F3(i) <= REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+1) and REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH) + and not REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+2) and REPLY_DATAREADY_IN(i); + + process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + saved_reply_packet_type((i+1)*3-1 downto i*3) <= TYPE_ILLEGAL; + last_reply_packet_type((i+1)*3-1 downto i*3) <= TYPE_ILLEGAL; + elsif REPLY_PACKET_NUM_IN((i+1)*c_NUM_WIDTH-1 downto i*c_NUM_WIDTH) = c_H0 then + saved_reply_packet_type((i+1)*3-1 downto i*3) <= REPLY_DATA_IN(2 downto 0); + last_reply_packet_type((i+1)*3-1 downto i*3) <= saved_reply_packet_type; + end if; + end if; + end process; + current_reply_packet_type((i+1)*3-1 downto i*3) <= REPLY_DATA_IN(i*c_DATA_WIDTH+2 downto i*c_DATA_WIDTH) + when (REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+2 downto i*c_NUM_WIDTH) = c_H0) + else saved_reply_packet_type((i+1)*3-1 downto i*3); + + current_reply_reading_HDR(i) <= '1' when current_reply_packet_type((i+1)*3-1 downto i*3) = TYPE_HDR else '0'; + current_reply_reading_DHDR(i) <= '1' when current_reply_packet_type((i+1)*3-1 downto i*3) = TYPE_DAT + and last_reply_packet_type((i+1)*3-1 downto i*3) = TYPE_HDR else '0'; + current_reply_reading_TRM(i) <= '1' when current_reply_packet_type((i+1)*3-1 downto i*3) = TYPE_TRM else '0'; + end generate; + +--saving (D)HDR +------------------------- + gen_saving_dhdr : for i in 0 to POINT_NUMBER-1 generate + hdrram_write_enable(i) <= current_reply_reading_HDR(i) and + (reply_reading_F0(i) or reply_reading_F1(i) or reply_reading_F2(i) or reply_reading_F3(i)); + hdrram_address(i*3+2 downto i*3) <= REPLY_PACKET_NUM_IN((i+1)*c_NUM_WIDTH-1 downto i*c_NUM_WIDTH); + hdrram_address(i*3+3) <= '1' when current_reply_reading_DHDR(i) else '0'; + + the_last_HDR_RAM : trb_net_ram_dp + generic map( + depth => 3, + width => 16 + ) + port map( + CLK => CLK, + wr1 => hdrram_write_enable(i), + a1 => hdrram_address(i*3+2 downto i*3), + din1 => REPLY_DATA_IN((i+1)*c_DATA_WIDTH-1 downto i*c_DATA_WIDTH), + dout1 => open, + a2 => last_dhdr_addr, + dout2 => last_dhdr_data((i+1)*c_DATA_WIDTH-1 downto i*c_DATA_WIDTH) + ); + end generate; + + the_ram_output_adder : wide_adder + generic map( + WIDTH => 16, + WORDS => POINT_NUMBER, + PARALLEL_ADDERS => 2 + ) + port map( + CLK => CLK, + CLK_EN => CLK_EN, + RESET => RESET, + INPUT_IN => last_dhdr_data, + START_IN => adder_start, + RESULT_OUT => adder_result, + OVERFLOW_OUT => adder_overflow, + READY_OUT => adder_ready + ); + + +--reading and merging TRM +---------------------------------- + + + gen_combining_trm : for j in 0 to c_DATA_WIDTH-1 generate + process(CLK) + variable tmpF1, tmpF2, tmpF3 : std_logic; + begin + if rising_edge(CLK) then + if RESET = '1' or locked = '0' then + reply_combined_trm_F1(j) <= '0'; + reply_combined_trm_F2(j) <= '0'; + reply_combined_trm_F3(j) <= '0'; + else + tmpF1 := '0'; + tmpF2 := '0'; + tmpF3 := '0'; + for i in 0 to POINT_NUMBER-1 loop + tmpF1 := tmpF1 or (REPLY_DATA_IN(i*c_DATA_WIDTH+j) and reply_reading_F1(i) and reply_reading_trm(i)); + tmpF2 := tmpF2 or (REPLY_DATA_IN(i*c_DATA_WIDTH+j) and reply_reading_F2(i) and reply_reading_trm(i)); + tmpF3 := tmpF3 or (REPLY_DATA_IN(i*c_DATA_WIDTH+j) and reply_reading_F3(i) and reply_reading_trm(i)); + end loop; + reply_combined_trm_F1(j) <= reply_combined_trm_F1(j) or tmpF1; + reply_combined_trm_F2(j) <= reply_combined_trm_F2(j) or tmpF2; + reply_combined_trm_F3(j) <= reply_combined_trm_F3(j) or tmpF3; + end if; + end if; + end process; + end generate; + + +--real_activepoints can be set between transfers only, but can be cleared at any time +---------------------------------- + gen_real_activepoints : process (CLK) + begin + if rising_edge(CLK) then + if locked = '0' then + real_activepoints <= CTRL_activepoints(POINT_NUMBER-1 downto 0); + else + real_activepoints <= real_activepoints and CTRL_activepoints(POINT_NUMBER-1 downto 0); + end if; + end if; + end process; + + +--count received TRM +---------------------------------- + gen_got_trm : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' or send_reply_trm = '1' or locked = '0' then + got_trm <= (others => '0'); + else + got_trm <= got_trm or locking_point or reading_trmF2 or not real_activepoints; + end if; + end if; + end process; + + +--REPLY Counters +---------------------------------- + --counter for 16bit words + gen_packet_counter : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' or locked = '0' then + packet_counter <= c_H0; + elsif comb_REPLY_POOL_DATAREADY = '1' then + if packet_counter = c_max_word_number then + packet_counter <= (others => '0'); + else + packet_counter <= packet_counter + 1; + end if; + end if; + end if; + end process; + + --counts data packets only + gen_data_counter : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' or reply_point_lock = '0' then + data_counter <= (others => '0'); + elsif comb_REPLY_POOL_DATAREADY = '1' and comb_REPLY_POOL_DATA(2 downto 0) = TYPE_DAT then + data_counter <= data_counter + 1; + end if; + end if; + end process; + +--REPLY select input +---------------------------------- + REPLY_ARBITER: trb_net_priority_arbiter + generic map ( + WIDTH => POINT_NUMBER + ) + port map ( + CLK => CLK, + RESET => RESET, + CLK_EN => reply_arbiter_CLK_EN, + INPUT_IN => reply_arbiter_input, + RESULT_OUT => reply_arbiter_result, + ENABLE => reply_arbiter_enable, --switched off during DHDR + CTRL => (others => '0') + ); + + reply_arbiter_input <= REPLY_DATAREADY_IN and not reply_reading_trm and not reply_reading_HDR and not reply_reading_DHDR; + reply_arbiter_CLK_EN <= not next_point_lock; + REPLY_MUX_reading <= reply_arbiter_result; + + + -- release is done after first packet of TRM + gen_reply_point_lock : process(reply_point_lock, comb_REPLY_muxed_PACKET_NUM, + REPLY_DATAREADY_IN, comb_REPLY_muxed_DATA, REPLY_MUX_reading) + begin + next_point_lock <= reply_point_lock; + --release lock if TRM is read + if comb_REPLY_muxed_PACKET_NUM = c_H0 and or_all(REPLY_MUX_reading and REPLY_DATAREADY_IN) = '1' then + if comb_REPLY_muxed_DATA(2 downto 0) = TYPE_TRM then + next_point_lock <= '0'; + else + next_point_lock <= '1'; + end if; + end if; + end process; + + gen_point_lock : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + reply_point_lock <= '0'; + else + reply_point_lock <=next_point_lock; + end if; + end if; + end process; + + + + + +--REPLY mux +---------------------------------- + gen_reply_mux1 : for i in 0 to c_DATA_WIDTH-1 generate + data_mux : process(REPLY_DATA_IN, REPLY_MUX_reading,last_header_data, reading_last_hdr) + variable tmp_data : std_logic; + begin + tmp_data := '0'; + gen_data_mux : for j in 0 to POINT_NUMBER-1 loop + tmp_data := tmp_data or (REPLY_DATA_IN(j*c_DATA_WIDTH+i) and REPLY_MUX_reading(j)) + or (last_header_data(j*c_DATA_WIDTH+i) and reading_last_hdr(j)); + end loop; + comb_REPLY_muxed_DATA(i) <= tmp_data; + end process; + end generate; + + gen_reply_mux2 : for i in 0 to c_NUM_WIDTH-1 generate + packet_num_mux : process(REPLY_PACKET_NUM_IN, REPLY_MUX_reading,packet_counter, reading_last_hdr) + variable tmp_pm : std_logic; + begin + tmp_pm := '0'; + gen_pm_mux : for j in 0 to POINT_NUMBER-1 loop + tmp_pm := tmp_pm or (REPLY_PACKET_NUM_IN(j*c_NUM_WIDTH+i) and REPLY_MUX_reading(j)) + or (packet_counter(i) and reading_last_hdr(j)); + end loop; + comb_REPLY_muxed_PACKET_NUM(i) <= tmp_pm; + end process; + end generate; + + comb_REPLY_muxed_DATAREADY <= (or_all(reply_arbiter_result and REPLY_DATAREADY_IN and not current_reply_reading_trm and not current_reply_reading_hdr) or or_all(reading_last_hdr)) and REPLY_POOL_next_read; + + + +--REPLY POOL state machine +---------------------------------- + reply_state_machine : process(REPLY_POOL_next_READ, current_state, packet_counter, REPLY_combined_trm_F0, + send_reply_trm, SEQ_NR, REPLY_combined_trm_F1, REPLY_combined_trm_F2, + comb_REPLY_muxed_DATAREADY, comb_REPLY_muxed_DATA, init_locked, + comb_REPLY_muxed_PACKET_NUM, waiting_for_init_finish, waiting_for_DHDR_word) + begin + release_locked <= '0'; + next_state <= current_state; + comb_REPLY_POOL_DATAREADY <= '0'; + comb_REPLY_POOL_PACKET_NUM <= packet_counter; + comb_REPLY_POOL_DATA <= (others => '0'); + next_waiting_for_init_finish <= waiting_for_init_finish; + next_waiting_for_DHDR_word <= waiting_for_DHDR_word; + hdrram_address <= "000"; + next_current_waiting_for_reply <= current_waiting_for_reply and not current_reply_reading_HDR; + reply_adder_start <= '0'; + reply_adder_val_enable <= (not locking_point and real_activepoints); + + case current_state is + when IDLE => --wait for init transfer + next_waiting_for_DHDR_word <= not (locking_point or not real_activepoints); + if locked = '1' then + next_current_waiting_for_reply <= (others => '1'); + next_state <= WAIT_FOR_HDR_DATA; + end if; + + when WAIT_FOR_HDR_DATA => --start writing HDR when first reply is received, stop waiting for length + case packet_counter is + when c_H0 => + comb_REPLY_POOL_DATA <= (others => '0'); + comb_REPLY_POOL_DATA(2 downto 0) <= TYPE_HDR; + comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read and not or_all(current_waiting_for_reply); + when c_F0 => + comb_REPLY_POOL_DATA <= MY_ADDRESS_IN; + comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read; + when c_F1 => + comb_REPLY_POOL_DATA <= x"FFFF"; --sender address is not known! + comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read; + when c_F2 => + comb_REPLY_POOL_DATAREADY <= '0'; + hdrram_address <= "011"; + if or_all(current_reply_reading_HDR or current_waiting_for_reply) = '0' then + next_state <= GEN_LENGTH; + reply_adder_start <= '1'; + end if; + when others => + null; + end case; + + when GEN_LENGTH => --now, all HDR are stored, calc sum of HDR lengths + hdrram_address <= "011"; + if reply_adder_ready = '1' then + case packet_counter is + when c_F2 => + comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read; + comb_REPLY_POOL_DATA <= reply_adder_result; + when c_F3 => + comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read; + comb_REPLY_POOL_DATA <= ????????????????????????????????????????????????????; + if REPLY_POOL_next_read = '1' then + next_state <= CHECK_DHDR_0; + end if; + end case; + end if; + + when CHECK_DHDR_0 => + if or_all(waiting_for_DHDR_word) = '0' and REPLY_POOL_next_read = '1' then + comb_REPLY_POOL_DATAREADY <= '1'; + comb_REPLY_POOL_DATA <= combined_DHDR_word; + comb_REPLY_POOL_PACKET_NUM <= c_F0; + next_waiting_for_DHDR_word <= not (locking_point or not real_activepoints); + + end if; + when SENDING_DATA => + comb_REPLY_POOL_DATAREADY <= comb_REPLY_muxed_DATAREADY; + comb_REPLY_POOL_DATA <= comb_REPLY_muxed_DATA; + comb_REPLY_POOL_PACKET_NUM <= comb_REPLY_muxed_PACKET_NUM; + if send_reply_trm = '1' then + next_state <= SENDING_REPLY_TRM; + end if; + when SENDING_REPLY_TRM => + comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read and not waiting_for_init_finish; + if waiting_for_init_finish = '1' and init_locked = '1' then + release_locked <= '1'; --release only when init has finished too + next_state <= SENDING_DATA; + next_waiting_for_init_finish <= '0'; + end if; + case packet_counter is + when c_F0 => + comb_REPLY_POOL_DATA <= (others => '0'); + when c_F1 => + comb_REPLY_POOL_DATA <= REPLY_combined_trm_F1; + when c_F2 => + comb_REPLY_POOL_DATA <= REPLY_combined_trm_F2; + when c_F3 => + comb_REPLY_POOL_DATA <= REPLY_combined_trm_F3; + if REPLY_POOL_next_read = '1' and (init_locked = '1') then + release_locked <= '1'; --release only when init has finished too + next_state <= IDLE; + elsif REPLY_POOL_next_read = '1' and init_locked = '0' then + next_waiting_for_init_finish <= '1'; + end if; + when c_H0 | others => + comb_REPLY_POOL_DATA <= (others => '0'); + comb_REPLY_POOL_DATA(2 downto 0) <= TYPE_TRM; + end case; + end case; + end process; + + reply_fsm_state(0) <= '1' when current_state = IDLE else '0'; + reply_fsm_state(1) <= '1' when current_state = CHECK_DHDR else '0'; + reply_fsm_state(2) <= '1' when current_state = SENDING_DATA else '0'; + reply_fsm_state(3) <= '1' when current_state = SENDING_REPLY_TRM else '0'; + + process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + current_state <= SENDING_DATA; + REPLY_POOL_next_read <= '0'; + waiting_for_init_finish <= '0'; + waiting_for_DHDR_word <= (others => '0'); + current_waiting_for_reply <= (others => '1'); + else + current_state <= next_state; + REPLY_POOL_next_read <= comb_REPLY_POOL_next_read; + waiting_for_init_finish <= next_waiting_for_init_finish; + waiting_for_DHDR_word <= next_waiting_for_DHDR_word; + current_waiting_for_reply <= next_current_waiting_for_reply; + end if; + end if; + end process; + + +--REPLY sbuf +-------------- + + REPLY_POOL_SBUF: trb_net16_sbuf + generic map ( + Version => 0 + ) + port map ( + CLK => CLK, + RESET => RESET, + CLK_EN => CLK_EN, + COMB_DATAREADY_IN => comb_REPLY_POOL_DATAREADY, + COMB_next_READ_OUT => comb_REPLY_POOL_next_read, + COMB_READ_IN => REPLY_POOL_next_read, + COMB_DATA_IN => comb_REPLY_POOL_DATA, + COMB_PACKET_NUM_IN => comb_REPLY_POOL_PACKET_NUM, + SYN_DATAREADY_OUT => REPLY_POOL_DATAREADY, + SYN_DATA_OUT => REPLY_POOL_DATA, + SYN_PACKET_NUM_OUT => REPLY_POOL_PACKET_NUM, + SYN_READ_IN => REPLY_POOL_READ + ); + +--REPLY output +-------------- + + gen_reply_data_out: for i in 0 to POINT_NUMBER-1 generate + REPLY_DATAREADY_OUT(i) <= REPLY_POOL_DATAREADY and locking_point(i); + REPLY_DATA_OUT((i+1)*c_DATA_WIDTH-1 downto i*c_DATA_WIDTH) <= REPLY_POOL_DATA; + REPLY_PACKET_NUM_OUT((i+1)*c_NUM_WIDTH-1 downto i*c_NUM_WIDTH) <= REPLY_POOL_PACKET_NUM; + end generate; + REPLY_POOL_READ <= or_all(REPLY_READ_IN and locking_point); + + + + +---------------------- +--Debugging +---------------------- + + STAT_DEBUG(0) <= got_trm(0); + STAT_DEBUG(1) <= got_trm(1); + STAT_DEBUG(2) <= REPLY_POOL_DATAREADY; + STAT_DEBUG(3) <= REPLY_DATAREADY_IN(0); + STAT_DEBUG(4) <= buf_REPLY_READ_OUT(0); + STAT_DEBUG(5) <= comb_REPLY_muxed_DATA(14); + + STAT_DEBUG(6) <= REPLY_DATA_IN(14); + STAT_DEBUG(7) <= REPLY_DATA_IN(30); + STAT_DEBUG(8) <= '0';--REPLY_DATA_IN(46); + STAT_DEBUG(9) <= locked; + STAT_DEBUG(13 downto 10) <= reply_fsm_state(3 downto 0); + STAT_DEBUG(15 downto 14) <= (others => '0'); + --STAT(15 downto 8) <= data_counter; + STAT_POINTS_locked(POINT_NUMBER-1 downto 0) <= not got_trm; + STAT_POINTS_locked(31 downto POINT_NUMBER) <= (others => '0'); + STAT_ERRORBITS <= REPLY_combined_trm_F1 & REPLY_combined_trm_F2; + + + +end architecture; diff --git a/trb_net16_ibuf.vhd b/trb_net16_ibuf.vhd index bb87f20..2703620 100644 --- a/trb_net16_ibuf.vhd +++ b/trb_net16_ibuf.vhd @@ -41,6 +41,7 @@ entity trb_net16_ibuf is INT_REPLY_READ_IN : in std_logic; INT_ERROR_OUT : out std_logic_vector (2 downto 0); -- Status and control port + STAT_BUFFER_COUNTER : out std_logic_vector (31 downto 0); STAT_BUFFER : out std_logic_vector (31 downto 0) ); end entity; @@ -143,6 +144,8 @@ architecture trb_net16_ibuf_arch of trb_net16_ibuf is signal fifo_read_before : std_logic; signal stat_sbufs : std_logic_vector(1 downto 0); signal counter_match : std_logic; + signal init_buffer_number : std_logic_vector(15 downto 0); + signal reply_buffer_number : std_logic_vector(15 downto 0); begin counter_match <= '1'; @@ -457,7 +460,7 @@ counter_match <= '1'; end process; gen_ack1 : if USE_ACKNOWLEDGE = 1 generate - reg_locked: process(CLK) + proc_reg_eob_out: process(CLK) begin if rising_edge(CLK) then if RESET = '1' then @@ -469,11 +472,27 @@ counter_match <= '1'; end if; end if; end process; + proc_count_buffers : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + init_buffer_number <= (others => '1'); + reply_buffer_number <= (others => '1'); + elsif CLK_EN = '1' then + if got_eob_init_out = '1' then + init_buffer_number <= init_buffer_number + 1; + end if; + if got_eob_reply_out = '1' then + reply_buffer_number <= reply_buffer_number + 1; + end if; + end if; + end if; + end process; end generate; - + STAT_BUFFER_COUNTER <= reply_buffer_number & init_buffer_number; -- make STAT_BUFFER STAT_BUFFER(3 downto 0) <= std_logic_vector(to_unsigned(DEPTH,4)); diff --git a/trb_net16_iobuf.vhd b/trb_net16_iobuf.vhd index a9ac779..75d40cb 100644 --- a/trb_net16_iobuf.vhd +++ b/trb_net16_iobuf.vhd @@ -154,6 +154,7 @@ architecture trb_net16_iobuf_arch of trb_net16_iobuf is INT_REPLY_READ_IN : in std_logic; INT_ERROR_OUT : out std_logic_vector (2 downto 0); -- Status and control port + STAT_BUFFER_COUNTER : out std_logic_vector (31 downto 0); STAT_BUFFER : out std_logic_vector (31 downto 0) ); end component; @@ -191,6 +192,7 @@ architecture trb_net16_iobuf_arch of trb_net16_iobuf is signal INITOBUF_stat_buffer, INITOBUF_ctrl_buffer: STD_LOGIC_VECTOR (31 downto 0); signal REPLYOBUF_stat_buffer, REPLYOBUF_ctrl_buffer: STD_LOGIC_VECTOR (31 downto 0); signal ibuf_dataready_in, ibuf_read_out : std_logic; + signal STAT_BUFFER_COUNTER : std_logic_vector (31 downto 0); begin GEN_IBUF: if IBUF_DEPTH>0 generate @@ -226,6 +228,7 @@ begin INT_REPLY_PACKET_NUM_OUT => INT_REPLY_PACKET_NUM_OUT, INT_REPLY_READ_IN => INT_REPLY_READ_IN, INT_ERROR_OUT => IBUF_error, + STAT_BUFFER_COUNTER => STAT_BUFFER_COUNTER, STAT_BUFFER(31 downto 0) => IBUF_stat_buffer ); end generate; @@ -375,10 +378,13 @@ STAT_IBUF_BUFFER <= IBUF_stat_buffer; -- build the CTRL register of the OBUFs INITOBUF_ctrl_buffer(9 downto 0) <= IBUF_stat_buffer(9 downto 0); - INITOBUF_ctrl_buffer(31 downto 10) <= (others => '0'); + INITOBUF_ctrl_buffer(15 downto 10) <= (others => '0'); + INITOBUF_ctrl_buffer(31 downto 16) <= STAT_BUFFER_COUNTER(15 downto 0); + REPLYOBUF_ctrl_buffer(7 downto 0) <= IBUF_stat_buffer(7 downto 0); REPLYOBUF_ctrl_buffer(9 downto 8) <= IBUF_stat_buffer(11 downto 10); - REPLYOBUF_ctrl_buffer(31 downto 10) <= (others => '0'); + REPLYOBUF_ctrl_buffer(15 downto 10) <= (others => '0'); + REPLYOBUF_ctrl_buffer(31 downto 16) <= STAT_BUFFER_COUNTER(31 downto 16); STAT_GEN <= (others => '0'); diff --git a/trb_net16_obuf.vhd b/trb_net16_obuf.vhd index eb2168e..6e28936 100644 --- a/trb_net16_obuf.vhd +++ b/trb_net16_obuf.vhd @@ -115,6 +115,8 @@ architecture trb_net16_obuf_arch of trb_net16_obuf is signal buf_MED_PACKET_NUM_OUT : std_logic_vector(c_NUM_WIDTH-1 downto 0); signal sbuf_status : std_logic; signal crc_match : std_logic; + signal buffer_number : std_logic_vector(15 downto 0); + begin -- gen_sbuf : if SECURE_MODE = 1 generate @@ -208,6 +210,9 @@ begin current_ACK_word(3 downto 0) <= SEND_BUFFER_SIZE_IN; elsif transfer_counter = c_F2 then current_EOB_word(DATA_COUNT_WIDTH-1 downto 0) <= CURRENT_DATA_COUNT; + elsif transfer_counter = c_F3 then + current_EOB_word(15 downto 0) <= buffer_number; + current_ACK_word(15 downto 0) <= CTRL_BUFFER(31 downto 16); elsif transfer_counter = c_H0 then current_NOP_word(2 downto 0) <= TYPE_ILLEGAL; current_ACK_word(2 downto 0) <= TYPE_ACK; @@ -269,7 +274,6 @@ begin current_ACK_word, current_EOB_word, INT_PACKET_NUM_IN, TRANSMITTED_BUFFERS, send_DATA, comb_next_read) begin - current_output_data_buffer <= current_NOP_word; current_output_num_buffer <= transfer_counter; next_INT_READ_OUT <= '1'; @@ -412,12 +416,16 @@ begin if rising_edge(CLK) then if RESET = '1' then TRANSMITTED_BUFFERS <= "00"; + buffer_number <= (others => '0'); elsif CLK_EN = '1' then if (increase_TRANSMITTED_BUFFERS = '1' and decrease_TRANSMITTED_BUFFERS = '0') then TRANSMITTED_BUFFERS <= TRANSMITTED_BUFFERS +1; elsif (increase_TRANSMITTED_BUFFERS = '0' and decrease_TRANSMITTED_BUFFERS = '1') then TRANSMITTED_BUFFERS <= TRANSMITTED_BUFFERS -1; end if; + if increase_TRANSMITTED_BUFFERS = '1' then + buffer_number <= buffer_number + 1; + end if; end if; end if; end process; diff --git a/trb_net_onewire.vhd b/trb_net_onewire.vhd index 212e726..57f059a 100644 --- a/trb_net_onewire.vhd +++ b/trb_net_onewire.vhd @@ -10,6 +10,7 @@ use work.trb_net_std.all; entity trb_net_onewire is generic( USE_TEMPERATURE_READOUT : integer range 0 to 1 := 1; + PARASITIC_MODE : integer range 0 to 1 := c_YES; CLK_PERIOD : integer := 10 --clk period in ns ); port( @@ -28,7 +29,7 @@ end entity; architecture trb_net_onewire_arch of trb_net_onewire is - constant MAX_COUNTER : integer := 2**17-1; + constant MAX_COUNTER : integer := 2**28-1; type state_t is (IDLE, SEND_RESET, WAIT_AFTER_RESET, SEND_ROM_COMMAND, READ_WAIT, WRITE_START, WRITE_WAIT, READ_BIT, READ_READ_ROM, SEND_CONV_TEMP, READ_CONV_TEMP, SEND_READ_TEMP, READ_READ_TEMP); @@ -53,9 +54,10 @@ architecture trb_net_onewire_arch of trb_net_onewire is signal skip_rom, next_skip_rom : std_logic; signal buf_TEMP_OUT : std_logic_vector(11 downto 0); signal buf_STAT : std_logic; + signal strong_pullup, next_strong_pullup : std_logic; begin - ONEWIRE <= '0' when output = '0' else 'Z'; + ONEWIRE <= '0' when output = '0' else '1' when strong_pullup = '1' else 'Z'; input <= ONEWIRE; bitcounter_vector <= conv_std_logic_vector(bitcounter,7); @@ -77,6 +79,7 @@ begin next_reading_temp <= reading_temp; next_recv_bit <= recv_bit; next_skip_rom <= skip_rom; + next_strong_pullup <= '0'; case state is --reset / presence when IDLE => @@ -128,6 +131,7 @@ begin if bitcounter_vector(3) = '1' then --send 8 bit next_state <= READ_CONV_TEMP; reset_bitcounter <= '1'; + reset_timecounter <= '1'; next_recv_bit <= '0'; else next_state <= WRITE_START; @@ -164,14 +168,25 @@ begin --reading sensor answers when READ_CONV_TEMP => --waiting for end of conversion - if recv_bit = '1' then - next_state <= IDLE; - if USE_TEMPERATURE_READOUT = 1 then - next_conv_temp <= '0'; - next_reading_temp <= '1'; + if PARASITIC_MODE = c_NO then + if recv_bit = '1' then --polling device for end of measurement + next_state <= IDLE; + if USE_TEMPERATURE_READOUT = 1 then + next_conv_temp <= '0'; + next_reading_temp <= '1'; + end if; + else + next_state <= READ_BIT; + end if; + elsif PARASITIC_MODE = c_YES then --waiting 1.3s, then start reading + next_strong_pullup <= '1'; + if is_time_reached(timecounter,130000000,CLK_PERIOD) = '1' then + next_state <= IDLE; + if USE_TEMPERATURE_READOUT = 1 then + next_conv_temp <= '0'; + next_reading_temp <= '1'; + end if; end if; - else - next_state <= READ_BIT; end if; when READ_READ_TEMP => @@ -271,6 +286,7 @@ begin send_bit <= '0'; output_tmp <= '0'; recv_bit <= '0'; + strong_pullup <= '0'; else recv_bit_ready <= next_recv_bit_ready; state <= next_state; @@ -278,6 +294,7 @@ begin output <= next_output; output_tmp <= next_output_tmp; recv_bit <= next_recv_bit; + strong_pullup <= next_strong_pullup; end if; end if; end process; diff --git a/trb_net_std.vhd b/trb_net_std.vhd index 5651a8f..bcb711e 100644 --- a/trb_net_std.vhd +++ b/trb_net_std.vhd @@ -19,6 +19,7 @@ package trb_net_std is --assigning channel names constant c_TRG_LVL1_CHANNEL : integer := 0; constant c_DATA_CHANNEL : integer := 1; + constant c_IPU_CHANNEL : integer := 1; constant c_UNUSED_CHANNEL : integer := 2; constant c_SLOW_CTRL_CHANNEL : integer := 3; @@ -213,11 +214,12 @@ package body trb_net_std is function is_time_reached (timer : integer; time : integer; period : integer) return std_logic is variable i : integer range 0 to 1 := 0; - variable t : std_logic_vector(16 downto 0) := conv_std_logic_vector(timer,17); + variable t : std_logic_vector(27 downto 0) := conv_std_logic_vector(timer,28); begin i := 0; if period = 10 then case time is + when 130000000 => if t(27) = '1' then i := 1; end if; when 640000 => if t(16) = '1' then i := 1; end if; when 80000 => if t(13) = '1' then i := 1; end if; when 10000 => if t(10) = '1' then i := 1; end if;