--- /dev/null
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use ieee.std_logic_arith.all;\r
+use ieee.std_logic_unsigned.all;\r
+\r
+entity ipu_dummy is\r
+ port( CLK_IN : in std_logic; -- 100MHz local clock\r
+ CLEAR_IN : in std_logic;\r
+ RESET_IN : in std_logic; -- synchronous reset\r
+ -- Slow control signals \r
+ MIN_COUNT_IN : in std_logic_vector(15 downto 0); -- minimum counter value\r
+ MAX_COUNT_IN : in std_logic_vector(15 downto 0); -- maximum counter value\r
+ CTRL_IN : in std_logic_vector(7 downto 0); -- control bits from slow control\r
+ -- IPU channel connections\r
+ IPU_NUMBER_IN : in std_logic_vector(15 downto 0); -- trigger tag\r
+ IPU_INFORMATION_IN : in std_logic_vector(7 downto 0); -- trigger information\r
+ IPU_START_READOUT_IN : in std_logic; -- gimme data!\r
+ IPU_DATA_OUT : out std_logic_vector(31 downto 0); -- detector data, equipped with DHDR\r
+ IPU_DATAREADY_OUT : out std_logic; -- data is valid\r
+ IPU_READOUT_FINISHED_OUT : out std_logic; -- no more data, end transfer, send TRM\r
+ IPU_READ_IN : in std_logic; -- read strobe, low every second cycle \r
+ IPU_LENGTH_OUT : out std_logic_vector(15 downto 0); -- length of data packet (32bit words) (?)\r
+ IPU_ERROR_PATTERN_OUT : out std_logic_vector(31 downto 0); -- error pattern\r
+ -- DHDR buffer\r
+ LVL1_FIFO_RD_OUT : out std_logic;\r
+ LVL1_FIFO_EMPTY_IN : in std_logic;\r
+ LVL1_FIFO_NUMBER_IN : in std_logic_vector(15 downto 0);\r
+ LVL1_FIFO_CODE_IN : in std_logic_vector(7 downto 0);\r
+ LVL1_FIFO_INFORMATION_IN : in std_logic_vector(7 downto 0);\r
+ LVL1_FIFO_TYPE_IN : in std_logic_vector(3 downto 0);\r
+ -- Debug signals\r
+ DBG_BSM_OUT : out std_logic_vector(7 downto 0);\r
+ DBG_OUT : out std_logic_vector(63 downto 0)\r
+ );\r
+end;\r
+\r
+architecture behavioral of ipu_dummy is\r
+\r
+ \r
+ -- state machine definitions\r
+ type STATES is (SLEEP,CHKF,DELF0,DELF1,SHDR,DDATA,SDATA,DONE); \r
+ signal CURRENT_STATE, NEXT_STATE: STATES;\r
+\r
+ -- signals\r
+ signal debug : std_logic_vector(63 downto 0);\r
+\r
+ signal rnd_count : std_logic_vector(15 downto 0); -- pseudo random counter for data length\r
+\r
+ signal random : std_logic_vector(15 downto 0); -- currently available random length\r
+\r
+ signal data_count : std_logic_vector(15 downto 0); -- data length to be used in this IPU readout cycle\r
+ signal data_done_comb : std_logic;\r
+ signal data_done : std_logic;\r
+\r
+ signal ipu_data : std_logic_vector(31 downto 0);\r
+ signal ipu_error : std_logic_vector(31 downto 0);\r
+\r
+ -- state machine signals\r
+ signal bsm_x : std_logic_vector(7 downto 0);\r
+ signal ld_data_count_x : std_logic;\r
+ signal ld_data_count : std_logic; -- load data counter with current random\r
+ signal ce_data_count_x : std_logic;\r
+ signal ce_data_count : std_logic; -- decrement data counter\r
+ signal rd_fifo_x : std_logic;\r
+ signal rd_fifo : std_logic; -- read DHDR FIFO from LVL1\r
+ signal send_data_x : std_logic;\r
+ signal send_data : std_logic; -- packet data to be sent\r
+ signal send_dhdr_x : std_logic;\r
+ signal send_dhdr : std_logic; -- DHDR to be sent\r
+ signal data_ready_x : std_logic;\r
+ signal data_ready : std_logic; -- IPU_DATAREADY_OUT\r
+ signal data_finished_x : std_logic;\r
+ signal data_finished : std_logic; -- IPU_READOUT_FINISHED_OUT\r
+\r
+ signal next_trgnum_match : std_logic;\r
+ signal trgnum_match : std_logic;\r
+\r
+begin\r
+\r
+---------------------------------------------------------------------------\r
+-- Random counter (to be improved, just a simple binary counter now)\r
+---------------------------------------------------------------------------\r
+THE_RND_COUNT_PROC: process( clk_in )\r
+begin\r
+ if ( clear_in = '1' ) then\r
+ rnd_count <= (others => '0');\r
+ elsif( rising_edge(clk_in) ) then\r
+ rnd_count <= rnd_count + 1;\r
+ if( rnd_count = max_count_in ) then\r
+ rnd_count <= min_count_in;\r
+ end if;\r
+ end if;\r
+end process THE_RND_COUNT_PROC;\r
+\r
+---------------------------------------------------------------------------\r
+-- data length counter, storage register for ipu_length\r
+---------------------------------------------------------------------------\r
+THE_DATA_LENGTH_COUNTER: process( clear_in, clk_in )\r
+begin\r
+ if ( clear_in = '1' ) then\r
+ data_count <= (others => '0');\r
+ data_done <= '0';\r
+ random <= (others => '0');\r
+ elsif( rising_edge(clk_in) ) then\r
+ if ( reset_in = '1' ) then\r
+ data_count <= (others => '0');\r
+ random <= (others => '0');\r
+ elsif( ld_data_count = '1' ) then\r
+ data_count <= rnd_count;\r
+ random <= rnd_count;\r
+ elsif( ce_data_count = '1' ) then\r
+ data_count <= data_count - 1;\r
+ end if;\r
+ data_done <= data_done_comb;\r
+ end if;\r
+end process THE_DATA_LENGTH_COUNTER;\r
+\r
+data_done_comb <= '1' when ( data_count = x"0000" ) else '0';\r
+\r
+---------------------------------------------------------------------------\r
+-- Statemachine\r
+---------------------------------------------------------------------------\r
+\r
+-- state registers\r
+STATE_MEM: process( clk_in, clear_in ) \r
+begin\r
+ if( clear_in = '1' ) then\r
+ CURRENT_STATE <= SLEEP;\r
+ ld_data_count <= '0';\r
+ ce_data_count <= '0';\r
+ rd_fifo <= '0';\r
+ send_data <= '0';\r
+ send_dhdr <= '0';\r
+ data_ready <= '0';\r
+ data_finished <= '0';\r
+ elsif( rising_edge(clk_in) ) then\r
+ if( reset_in = '1' ) then\r
+ CURRENT_STATE <= SLEEP;\r
+ ld_data_count <= '0';\r
+ ce_data_count <= '0';\r
+ rd_fifo <= '0';\r
+ send_data <= '0';\r
+ send_dhdr <= '0';\r
+ data_ready <= '0';\r
+ data_finished <= '0';\r
+ else\r
+ CURRENT_STATE <= NEXT_STATE;\r
+ ld_data_count <= ld_data_count_x;\r
+ ce_data_count <= ce_data_count_x;\r
+ rd_fifo <= rd_fifo_x;\r
+ send_data <= send_data_x;\r
+ send_dhdr <= send_dhdr_x;\r
+ data_ready <= data_ready_x;\r
+ data_finished <= data_finished_x;\r
+ end if;\r
+ end if;\r
+end process STATE_MEM;\r
+\r
+-- state transitions\r
+STATE_TRANSFORM: process( CURRENT_STATE, ipu_start_readout_in, lvl1_fifo_empty_in,\r
+ ipu_read_in, data_ready, data_done )\r
+begin\r
+ NEXT_STATE <= SLEEP; -- avoid latches\r
+ ld_data_count_x <= '0';\r
+ ce_data_count_x <= '0';\r
+ rd_fifo_x <= '0';\r
+ send_data_x <= '0';\r
+ send_dhdr_x <= '0';\r
+ data_ready_x <= '0';\r
+ data_finished_x <= '0';\r
+ case CURRENT_STATE is\r
+ when SLEEP => if( ipu_start_readout_in = '1' ) then\r
+ NEXT_STATE <= CHKF;\r
+ ld_data_count_x <= '1';\r
+ rd_fifo_x <= '1';\r
+ else\r
+ NEXT_STATE <= SLEEP;\r
+ end if;\r
+ when CHKF => if( lvl1_fifo_empty_in = '0' ) then\r
+ NEXT_STATE <= DELF0;\r
+ else\r
+ NEXT_STATE <= CHKF;\r
+ rd_fifo_x <= '1';\r
+ end if;\r
+ when DELF0 => NEXT_STATE <= DELF1;\r
+ when DELF1 => NEXT_STATE <= SHDR;\r
+ send_dhdr_x <= '1';\r
+ when SHDR => if ( (data_ready = '1') and (ipu_read_in = '1') and (data_done = '0') ) then\r
+ NEXT_STATE <= DDATA;\r
+ ce_data_count_x <= '1';\r
+ elsif( (data_ready = '1') and (ipu_read_in = '1') and (data_done = '1') ) then\r
+ NEXT_STATE <= DONE;\r
+ data_finished_x <= '1';\r
+ else\r
+ NEXT_STATE <= SHDR;\r
+ data_ready_x <= '1';\r
+ send_dhdr_x <= '1';\r
+ end if;\r
+ when DDATA => if( data_done = '0' ) then \r
+ NEXT_STATE <= SDATA;\r
+ send_data_x <= '1';\r
+ else\r
+ NEXT_STATE <= DONE;\r
+ data_finished_x <= '1';\r
+ end if;\r
+ when SDATA => if( (ipu_read_in = '1') and (data_ready = '1') ) then\r
+ NEXT_STATE <= DDATA;\r
+ ce_data_count_x <= '1';\r
+ else\r
+ NEXT_STATE <= SDATA;\r
+ data_ready_x <= '1';\r
+ send_data_x <= '1';\r
+ end if;\r
+ when DONE => if( ipu_start_readout_in = '0' ) then\r
+ NEXT_STATE <= SLEEP;\r
+ else\r
+ NEXT_STATE <= DONE;\r
+ end if;\r
+ \r
+ when others => NEXT_STATE <= SLEEP;\r
+ end case;\r
+end process STATE_TRANSFORM;\r
+\r
+-- state decodings\r
+STATE_DECODING: process( CURRENT_STATE )\r
+begin\r
+ case CURRENT_STATE is\r
+ when SLEEP => bsm_x <= x"00";\r
+ when CHKF => bsm_x <= x"01";\r
+ when DELF0 => bsm_x <= x"02";\r
+ when DELF1 => bsm_x <= x"03";\r
+ when SHDR => bsm_x <= x"04";\r
+ when DDATA => bsm_x <= x"05";\r
+ when SDATA => bsm_x <= x"06";\r
+ when DONE => bsm_x <= x"07";\r
+ when others => bsm_x <= x"ff";\r
+ end case;\r
+end process STATE_DECODING;\r
+\r
+---------------------------------------------------------------------------\r
+-- Data multiplexer\r
+---------------------------------------------------------------------------\r
+THE_DATA_MUX: process( clk_in )\r
+begin\r
+ if( rising_edge(clk_in) ) then\r
+ if ( send_dhdr = '1' ) then\r
+ ipu_data(31 downto 29) <= b"000"; -- reserved bits\r
+ ipu_data(28) <= '0'; -- was PACK_BIT\r
+ ipu_data(27 downto 24) <= lvl1_fifo_type_in; -- trigger type\r
+ ipu_data(23 downto 16) <= lvl1_fifo_code_in; -- trigger random\r
+ ipu_data(15 downto 0) <= lvl1_fifo_number_in; -- trigger number \r
+ elsif( send_data = '1' ) then\r
+ ipu_data(31 downto 16) <= x"dead";\r
+ ipu_data(15 downto 0) <= data_count;\r
+ else\r
+ ipu_data <= x"affed00f";\r
+ end if;\r
+ trgnum_match <= next_trgnum_match;\r
+ end if;\r
+end process THE_DATA_MUX;\r
+\r
+-- Check trigger number against IPU number\r
+next_trgnum_match <= '1' when ( ipu_number_in = lvl1_fifo_number_in ) else '0';\r
+\r
+-- IPU error pattern\r
+ipu_error(31 downto 25) <= (others => '0');\r
+ipu_error(24) <= not trgnum_match;\r
+ipu_error(23 downto 16) <= (others => '0');\r
+ipu_error(15 downto 0) <= (others => '0'); -- common error / status bits\r
+\r
+---------------------------------------------------------------------------\r
+-- DEBUG signals\r
+---------------------------------------------------------------------------\r
+debug(63 downto 43) <= (others => '0');\r
+\r
+debug(42 downto 23) <= ipu_data(19 downto 0);\r
+debug(22) <= '0';\r
+debug(21) <= data_finished;\r
+debug(20) <= data_ready;\r
+debug(19) <= rd_fifo;\r
+debug(18) <= ipu_read_in;\r
+debug(17) <= ipu_start_readout_in;\r
+debug(16) <= ld_data_count;\r
+debug(15) <= send_dhdr;\r
+debug(14) <= send_data;\r
+debug(13) <= ce_data_count;\r
+debug(12) <= data_done;\r
+debug(11 downto 8) <= data_count(3 downto 0);\r
+debug(7 downto 4) <= rnd_count(3 downto 0);\r
+debug(3 downto 0) <= bsm_x(3 downto 0);\r
+\r
+---------------------------------------------------------------------------\r
+-- output signals\r
+---------------------------------------------------------------------------\r
+lvl1_fifo_rd_out <= rd_fifo;\r
+ipu_data_out <= ipu_data;\r
+ipu_dataready_out <= data_ready;\r
+ipu_readout_finished_out <= data_finished;\r
+ipu_length_out <= random;\r
+ipu_error_pattern_out <= ipu_error;\r
+\r
+dbg_out <= debug;\r
+dbg_bsm_out <= bsm_x;\r
+\r
+end behavioral;\r
+ \r
+\r
+--THE_LVL1_INFO_FIFO : fifo_512x36\r
+-- port map(\r
+-- Data(15 downto 0) => LVL1_TRG_NUMBER_OUT(i*16+15 downto i*16),\r
+-- Data(23 downto 16) => LVL1_TRG_CODE_OUT(i*8+7 downto i*8),\r
+-- Data(31 downto 24) => LVL1_TRG_INFORMATION_OUT(i*8+7 downto i*8),\r
+-- Data(35 downto 32) => LVL1_TRG_TYPE_OUT(i*4+3 downto i*4),\r
+-- Clock => CLK,\r
+-- WrEn => LVL1_TRG_RECEIVED_rising(i),\r
+-- RdEn => trigger_information_read(i),\r
+-- Reset => reset,\r
+-- Q(15 downto 0) => trigger_number(i*16+15 downto i*16)\r
+-- Q(23 downto 16) => trigger_code(i*8+7 downto i*8),\r
+-- Q(31 downto 24) => trigger_information(i*8+7 downto i*8),\r
+-- Q(35 downto 32) => trigger_type(i*4+3 downto i*4),\r
+-- Empty => lvl1_fifo_empty(i),\r
+-- Full => lvl1_fifo_full(i)\r
+\r
+\r
signal reset_i : std_logic;
+signal HUB_MED_CTRL_OP : std_logic_vector(mii*16-1 downto 0);
+signal reset_i_mux_io : std_logic;
begin
SYNC_RESET_MUX_IO : process(CLK)
begin
if rising_edge(CLK) then
- reset_i <= MED_STAT_OP(14+2*16) or RESET;
+ reset_i <= MED_STAT_OP(mii*16+13) or RESET;
+ reset_i_mux_io <= MED_STAT_OP(mii*16+14) or reset_i;
end if;
end process;
+
+--generate media resync
+ gen_resync : for i in 0 to mii-1 generate
+ MED_CTRL_OP(13+i*16 downto i*16) <= (others => '0');
+ MED_CTRL_OP(14+i*16) <= HUB_MED_CTRL_OP(14+i*16);
+ MED_CTRL_OP(15+i*16) <= MED_STAT_OP(mii*16+15);
+ end generate;
+ MED_CTRL_OP(13+mii*16 downto mii*16) <= (others => '0');
+ MED_CTRL_OP(14+mii*16) <= '0';
+ MED_CTRL_OP(15+mii*16) <= MED_STAT_OP(mii*16+15);
+
+
+
---------------------------------------------------------------------
-- Connecting I/O
---------------------------------------------------------------------
HARDWARE_VERSION => HARDWARE_VERSION,
CLOCK_FREQUENCY => CLOCK_FREQUENCY,
USE_ONEWIRE => USE_ONEWIRE,
- MII_NUMBER => MII_NUMBER-1,
+ MII_NUMBER => mii,
MII_IBUF_DEPTH => MII_IBUF_DEPTH,
MII_IS_UPLINK => MII_IS_UPLINK,
MII_IS_DOWNLINK => MII_IS_DOWNLINK,
MED_PACKET_NUM_IN => med_packet_num_in(mii*3-1 downto 0),
MED_READ_OUT => med_read_out(mii-1 downto 0),
MED_STAT_OP => med_stat_op(mii*16-1 downto 0),
- MED_CTRL_OP => med_ctrl_op(mii*16-1 downto 0),
+ MED_CTRL_OP => HUB_MED_CTRL_OP(mii*16-1 downto 0),
INT_INIT_DATAREADY_OUT => hub_init_dataready_out,
INT_INIT_DATA_OUT => hub_init_data_out,
port map(
-- Misc
CLK => CLK,
- RESET => reset_i,
+ RESET => reset_i_mux_io,
CLK_EN => CLK_EN,
-- Media direction port
MED_INIT_DATAREADY_OUT => io_dataready_out(0),
port map(
-- Misc
CLK => CLK,
- RESET => reset_i,
+ RESET => reset_i_mux_io,
CLK_EN => CLK_EN,
-- Media direction port
MED_INIT_DATAREADY_OUT => io_dataready_out(2),
port map (
-- Misc
CLK => CLK ,
- RESET => reset_i,
+ RESET => reset_i_mux_io,
CLK_EN => CLK_EN,
-- Media direction port
MED_INIT_DATAREADY_OUT => io_dataready_out(4),
port map(
-- Misc
CLK => CLK,
- RESET => reset_i,
+ RESET => reset_i_mux_io,
CLK_EN => CLK_EN,
-- Media direction port
MED_INIT_DATAREADY_OUT => io_dataready_out(6),
MPLEX: trb_net16_io_multiplexer
port map (
CLK => CLK,
- RESET => reset_i,
+ RESET => reset_i_mux_io,
CLK_EN => CLK_EN,
MED_DATAREADY_IN => MED_DATAREADY_IN(2),
MED_DATA_IN => MED_DATA_IN(47 downto 32),