--- /dev/null
+-------------------------------------------------------------------------------
+--MuPix Block for readout/controll of MuPix3 Sensorboard
+--T. Weber, University Mainz
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.numeric_std.all;
+use work.mupix_components.all;
+
+entity MuPix3_Board is
+ port(
+ --Clock signal
+ clk : in std_logic; --for MuPix Controll
+ fastclk : in std_logic; --to the Hitbus Histogram
+ reset : in std_logic;
+ --signals to and from MuPix 3 chip/board DACS
+ timestamp_from_mupix : in std_logic_vector(7 downto 0);
+ rowaddr_from_mupix : in std_logic_vector(5 downto 0);
+ coladdr_from_mupix : in std_logic_vector(5 downto 0);
+ priout_from_mupix : in std_logic;
+ sout_c_from_mupix : in std_logic;
+ sout_d_from_mupix : in std_logic;
+ hbus_form_mupix : in std_logic;
+ fpga_aux_from_board : in std_logic_vector(9 downto 0);
+ ldpix_to_mupix : out std_logic;
+ ldcol_to_mupix : out std_logic;
+ timestamp_to_mupix : out std_logic_vector(7 downto 0);
+ rdcol_to_mupix : out std_logic;
+ pulldown_to_mupix : out std_logic;
+ sin_to_mupix : out std_logic;
+ ck_d_to_mupix : out std_logic;
+ ck_c_to_mupix : out std_logic;
+ ld_c_to_mupix : out std_logic;
+ testpulse1_to_board : out std_logic;
+ testpulse2_to_board : out std_logic;
+ spi_din_to_board : out std_logic;
+ spi_clk_to_board : out std_logic;
+ spi_ld_to_board : out std_logic;
+ fpga_led_to_board : out std_logic_vector(3 downto 0);
+ fpga_aux_to_board : out std_logic_vector(9 downto 0);
+
+ --TRBv3 connections
+ LVL1_TRG_DATA_VALID_IN : in std_logic;
+ LVL1_VALID_TIMING_TRG_IN : in std_logic;
+ LVL1_VALID_NOTIMING_TRG_IN : in std_logic;
+ LVL1_INVALID_TRG_IN : in std_logic;
+ LVL1_TRG_TYPE_IN : in std_logic_vector(3 downto 0);
+ LVL1_TRG_NUMBER_IN : in std_logic_vector(15 downto 0);
+ LVL1_TRG_CODE_IN : in std_logic_vector(7 downto 0);
+ LVL1_TRG_INFORMATION_IN : in std_logic_vector(23 downto 0);
+ LVL1_INT_TRG_NUMBER_IN : in std_logic_vector(15 downto 0);
+
+ FEE_TRG_RELEASE_OUT : out std_logic;
+ FEE_TRG_STATUSBITS_OUT : out std_logic_vector(31 downto 0);
+ FEE_DATA_OUT : out std_logic_vector(31 downto 0);
+ FEE_DATA_WRITE_OUT : out std_logic;
+ FEE_DATA_FINISHED_OUT : out std_logic;
+ FEE_DATA_ALMOST_FULL_IN : in std_logic;
+
+ REGIO_ADDR_IN : in std_logic_vector(15 downto 0);
+ REGIO_DATA_IN : in std_logic_vector(31 downto 0);
+ REGIO_DATA_OUT : out std_logic_vector(31 downto 0);
+ REGIO_READ_ENABLE_IN : in std_logic;
+ REGIO_WRITE_ENABLE_IN : in std_logic;
+ REGIO_TIMEOUT_IN : in std_logic;
+ REGIO_DATAREADY_OUT : out std_logic;
+ REGIO_WRITE_ACK_OUT : out std_logic;
+ REGIO_NO_MORE_DATA_OUT : out std_logic;
+ REGIO_UNKNOWN_ADDR_OUT : out std_logic
+ );
+end MuPix3_Board;
+
+
+architecture Behavioral of MuPix3_Block is
+
+
+
+
+begin -- Behavioral
+
+
+ --Mupix 3 Chip Interface
+ mupix_interface_1 : mupix_interface
+ port map (
+ rstn => not Reset,
+ clk => clk,
+ ldpix => ldpix_to_mupix,
+ ldcol => ldcol_to_mupix,
+ rdcol => rdcol_to_mupix,
+ pulldown => pulldown_to_mupix,
+ timestamps => timestamp_to_mupix,
+ priout => priout_from_mupix,
+ hit_col => coladdr_from_mupix,
+ hit_row => rowaddr_from_mupix,
+ hit_time => timestamp_from_mupix,
+ memdata => memdata,
+ memwren => memwren,
+ ro_busy => ro_busy,
+ --add signal to indicate readout still in progress
+ roregister => writeregs(1),
+ roregwritten => regwritten(1),
+ rocontrolbits => writeregs(6),
+ timestampcontrolbits => writeregs(7),
+ generatehitswait => writeregs(8));
+
+ --SPI-Interface to Board DACs
+ spi_if_1 : spi_if
+ port map (
+ clk => clk,
+ reset_n => not Reset,
+ threshold_reg => writeregs(2)(15 downto 0),
+ injection1_reg => writeregs(3)(15 downto 0),
+ injection2_reg => writeregs(3)(31 downto 16),
+ wren => spi_wren,
+ spi_data => spi_din_to_board,
+ spi_clk => spi_clk_to_board,
+ spi_ld => spi_ld_to_board);
+
+ spi_wren <= '1' when regwritten(2) = '1' else '0'; --maybe add regwritten(3)
+
+ inj_gen : injection_generator
+ port map(
+ rstn => not reset,
+ clk => clk,
+ injection_register => writeregs(4),
+ reg_written => regwritten(4),
+ testpulse1 => testpulse1_to_board,
+ testpulse2 => testpulse2_to_board
+ );
+
+
+ sync_historeg : process
+ begin
+ wait until rising_edge(fastclk);
+ historegwriten_sync <= regwritten(9);
+ historegwriten_last <= historegwriten_sync;
+ if historegwriten_sync = '0' and historegwriten_last = '1' then
+ historeg <= writeregs(9);
+ end if;
+ end process sync_historeg;
+
+
+ HitbusHistogram_1 : HitbusHistogram
+ generic map (
+ HistogramRange => 10)
+ port map (
+ clk => fastclk,
+ Control => historeg,
+ trigger => fpga_aux_to_board(0),
+ hitbus => hbus_form_mupix,
+ DataValid => DataValidToFormatterFiFo,
+ BinHeight => BinHeightToFormatterFiFo);
+
+
+ write_mupix : process
+ begin
+ wait until rising_edge(clk);
+ sin_to_mupix <= writeregs(5)(0);
+ ck_c_to_mupix <= writeregs(5)(1);
+ ck_d_to_mupix <= writeregs(5)(2);
+ ld_c_to_mupix <= writeregs(5)(3);
+ end process write_mupix;
+
+
+end Behavioral;
--- /dev/null
+-----------------------------------------------------------------------------
+-- MUPIX3 readout interface
+--
+-- Niklaus Berger, Heidelberg University
+-- nberger@physi.uni-heidelberg.de
+--
+-----------------------------------------------------------------------------
+
+
+
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+use ieee.numeric_std.all;
+use work.mupix_comp.all;
+
+entity mupix_interface is
+ port (
+ rstn : in std_logic;
+ clk : in std_logic;
+ -- MUPIX IF
+ ldpix : out std_logic;
+ ldcol : out std_logic;
+ rdcol : out std_logic;
+ pulldown : out std_logic;
+ timestamps : out std_logic_vector(7 downto 0);
+ priout : in std_logic;
+ hit_col : in std_logic_vector(5 downto 0);
+ hit_row : in std_logic_vector(5 downto 0);
+ hit_time : in std_logic_vector(7 downto 0);
+
+ -- MEMORY IF
+ memdata : out std_logic_vector(31 downto 0);
+ memwren : out std_logic;
+ endofevent : out std_logic;
+
+ --Readout Indicator
+ ro_busy : out std_logic;
+ -- TLU IF
+ trig : in std_logic;
+ busy : out std_logic;
+ trigclk : out std_logic;
+
+ -- Configuration
+ roregister : in std_logic_vector(31 downto 0);
+ roregwritten : in std_logic;
+ rocontrolbits : in std_logic_vector(31 downto 0);
+ timestampcontrolbits : in std_logic_vector(31 downto 0);
+ generatehitswait : in std_logic_vector(31 downto 0);
+
+ -- test ports
+ testout : out std_logic_vector (127 downto 0);
+ testout_ena : out std_logic
+
+ );
+end mupix_interface;
+
+
+architecture RTL of mupix_interface is
+
+ type tlu_state_type is (reset, waiting, manual, triggered, rectrignum, waiting_for_ro);
+ signal tlustate : tlu_state_type;
+
+ signal trigclk_r : std_logic;
+ signal busy_r : std_logic;
+
+ type ro_state_type is (reset, waiting, readman, loadpix, pulld, loadcol, readcol, hitgenerator, hitgeneratorwait);
+ signal state : ro_state_type;
+
+ signal tlu_counter : std_logic_vector(4 downto 0);
+ signal trignum_shift : std_logic_vector(14 downto 0);
+ signal trignum : std_logic_vector(14 downto 0);
+ signal trignum_ena : std_logic;
+ signal trignum_ena_last : std_logic;
+ signal tlumanual : std_logic;
+
+ signal trigcounter : std_logic_vector(14 downto 0);
+
+ signal tlu_divider : std_logic_vector(4 downto 0);
+
+ signal delcounter : std_logic_vector(2 downto 0);
+
+ signal ro_busy_int : std_logic;
+
+ signal graycount : std_logic_vector(7 downto 0);
+
+ signal eventcounter : std_logic_vector(31 downto 0);
+
+ signal hitcounter : std_logic_vector(10 downto 0);
+
+
+ signal triggering : std_logic;
+ signal continousread : std_logic;
+ signal readnow : std_logic;
+ signal readmanual : std_logic;
+ signal reseteventcount : std_logic;
+ signal generatehit : std_logic;
+ signal generatehits : std_logic;
+ signal generatetriggeredhits : std_logic;
+
+ signal ngeneratehits : std_logic_vector(15 downto 0);
+ signal ngeneratehitscounter : std_logic_vector(15 downto 0);
+ signal generatehitswaitcounter : std_logic_vector(31 downto 0);
+
+ signal gen_hit_col : std_logic_vector(5 downto 0);
+ signal gen_hit_row : std_logic_vector(5 downto 0);
+ signal gen_hit_time : std_logic_vector(7 downto 0);
+
+ signal testoutro : std_logic_vector (127 downto 0);
+ signal testouttlu : std_logic_vector (127 downto 0);
+
+ signal resetgraycounter : std_logic;
+
+begin
+
+
+
+ process(rstn, clk)
+ begin
+ if(rstn = '0') then
+ triggering <= '0';
+ continousread <= '0';
+ readnow <= '0';
+ readmanual <= '0';
+ reseteventcount <= '0';
+ generatehit <= '0';
+ generatehits <= '0';
+ generatetriggeredhits <= '0';
+ ngeneratehits <= (others => '0');
+ elsif(clk'event and clk = '1') then
+ triggering <= roregister(0);
+ continousread <= roregister(1);
+ if(roregister(2) = '1' and roregwritten = '1') then
+ readnow <= '1';
+ else
+ readnow <= '0';
+ end if;
+ readmanual <= roregister(3);
+ if(roregister(4) = '1' and roregwritten = '1') then
+ reseteventcount <= '1';
+ else
+ reseteventcount <= '0';
+ end if;
+ if(roregister(5) = '1' and roregwritten = '1') then
+ generatehit <= '1';
+ else
+ generatehit <= '0';
+ end if;
+ generatehits <= roregister(6);
+ generatetriggeredhits <= roregister(8);
+ ngeneratehits <= roregister(31 downto 16);
+ end if;
+ end process;
+
+ trigclk <= trigclk_r;
+ busy <= busy_r;
+
+ tlu_if :
+ process(rstn, clk)
+ begin
+ if(rstn = '0') then
+ tlu_counter <= (others => '0');
+ busy_r <= '0';
+ trigclk_r <= '0';
+ tlustate <= reset;
+ trignum_ena <= '0';
+ testouttlu <= (others => '0');
+ trigcounter <= (others => '0');
+ tlumanual <= '0';
+ elsif(clk'event and clk = '1') then
+ tlumanual <= roregister(11);
+ testouttlu <= (others => '0');
+ testouttlu(48) <= trig;
+ testouttlu(49) <= trigclk_r;
+ testouttlu(50) <= busy_r;
+ testouttlu(46 downto 32) <= trignum;
+ testouttlu(30 downto 16) <= trigcounter;
+ case tlustate is
+ when reset =>
+ testouttlu(56) <= '1';
+ tlu_counter <= (others => '0');
+ busy_r <= '0';
+ trigclk_r <= '0';
+ tlustate <= waiting;
+ trignum_ena <= '0';
+ when waiting =>
+ testouttlu(57) <= '1';
+ tlu_counter <= (others => '0');
+ trigclk_r <= '0';
+ busy_r <= '0';
+ trignum_ena <= '0';
+ if(tlumanual = '1') then
+ tlustate <= manual;
+ elsif(trig = '1') then
+ busy_r <= '1';
+ tlustate <= triggered;
+ trignum_ena <= '0';
+ trigcounter <= trigcounter + '1';
+ end if;
+ when manual =>
+ testouttlu(61) <= '1';
+ if(tlumanual = '0') then
+ tlustate <= waiting;
+ end if;
+ busy_r <= roregister(9);
+ trigclk_r <= roregister(10);
+ tlustate <= manual;
+ when triggered =>
+ testouttlu(58) <= '1';
+ busy_r <= '1';
+ if(trig = '0') then
+ tlustate <= rectrignum;
+ trigclk_r <= '0';
+ tlu_divider <= "00000";
+ end if;
+ when rectrignum =>
+ testouttlu(59) <= '1';
+ tlu_divider <= tlu_divider + '1';
+ busy_r <= '1';
+ tlustate <= rectrignum;
+ trignum_ena <= trignum_ena;
+ if(tlu_divider = "11111") then
+ trigclk_r <= not trigclk_r;
+ if(trigclk_r = '1')then
+ trignum_shift(14) <= trig;
+ trignum_shift(13 downto 0) <= trignum_shift(14 downto 1);
+ tlu_counter <= tlu_counter + '1';
+ end if;
+ end if;
+ if(tlu_counter = "01111" and tlu_divider = "00000") then
+ trignum <= trignum_shift;
+ trignum_ena <= '1';
+ end if;
+ if(tlu_counter = "10000") then
+ tlustate <= waiting_for_ro;
+ trigclk_r <= '0';
+ end if;
+ when waiting_for_ro =>
+ testouttlu(60) <= '1';
+ busy_r <= '1';
+ if(ro_busy_int = '0') then
+ busy_r <= '0';
+ tlustate <= waiting;
+ end if;
+ end case;
+ end if;
+ end process;
+
+
+ testout_ena <= '1';
+
+ testout(127 downto 64) <= testoutro(127 downto 64);
+ testout(63 downto 16) <= testouttlu(63 downto 16);
+ testout(15 downto 0) <= testoutro(15 downto 0);
+
+ ro_statemachine :
+ process(rstn, clk)
+ begin
+
+ if(rstn = '0') then
+ state <= waiting;
+ ldpix <= '0';
+ ldcol <= '0';
+ rdcol <= '0';
+ pulldown <= '0';
+ memwren <= '0';
+ ro_busy_int <= '0';
+ eventcounter <= (others => '0');
+ testoutro <= (others => '0');
+ endofevent <= '0';
+ elsif(clk'event and clk = '1') then
+ testoutro <= (others => '0');
+ testoutro(124) <= priout;
+
+ case state is
+ when reset =>
+ testoutro(0) <= '1';
+ state <= waiting;
+ ldpix <= '0';
+ ldcol <= '0';
+ rdcol <= '0';
+ pulldown <= '0';
+ memwren <= '0';
+ ro_busy_int <= '0';
+ eventcounter <= (others => '0');
+ --timeoutcounter <= (others => '0');
+ endofevent <= '0';
+ when waiting =>
+ testoutro(1) <= '1';
+ memwren <= '0';
+ ro_busy_int <= '0';
+ endofevent <= '0';
+ hitcounter <= (others => '0');
+ --timeoutcounter <= (others => '0');
+ eventcounter <= eventcounter;
+ if(reseteventcount = '1') then
+ eventcounter <= (others => '0');
+ end if;
+ ldpix <= '0';
+ ldcol <= '0';
+ rdcol <= '0';
+ pulldown <= '0';
+ if(readmanual = '1') then
+ state <= readman;
+ elsif(continousread = '1' or readnow = '1' or (triggering = '1' and trig = '1' and generatetriggeredhits = '0' and busy_r = '0' and tlumanual = '0')) then
+ state <= loadpix;
+ ldpix <= '1';
+ delcounter <= "100";
+ eventcounter <= eventcounter + '1';
+ elsif(triggering = '1' and trig = '1' and generatetriggeredhits = '1' and busy_r = '0' and tlumanual = '0') then
+ state <= hitgenerator;
+ delcounter <= "100";
+ eventcounter <= eventcounter + '1';
+ elsif(generatehit = '1' or generatehits = '1') then
+ state <= hitgenerator;
+ delcounter <= "100";
+ eventcounter <= eventcounter + '1';
+ else
+ state <= waiting;
+ end if;
+
+ when readman =>
+ testoutro(9) <= '1';
+ ro_busy_int <= '1';
+ ldpix <= rocontrolbits(0);
+ pulldown <= rocontrolbits(1);
+ ldcol <= rocontrolbits(2);
+ rdcol <= rocontrolbits(3);
+ if(readmanual = '1') then
+ state <= readman;
+ else
+ state <= waiting;
+ end if;
+ endofevent <= '0';
+ when loadpix =>
+ ro_busy_int <= '1';
+ testoutro(2) <= '1';
+ ldpix <= '0';
+ delcounter <= delcounter - '1';
+ memwren <= '0';
+ state <= loadpix;
+ if(delcounter = "100") then -- write event header
+ memdata <= "11111010101111101010101110111010"; --0xFABEABBA
+ memwren <= '1';
+ elsif(delcounter = "011") then -- write event counter
+ memdata <= eventcounter;
+ memwren <= '1';
+ elsif(delcounter = "001" and triggering = '1' and trignum_ena = '1') then -- write trigger number
+ memdata <= "11001100110011000" & trignum; -- 0xCCCC foolowed by trignum
+ memwren <= '1';
+ elsif(delcounter = "001" and triggering = '1' and trignum_ena = '0') then -- wait for trigger number
+ delcounter <= delcounter;
+ elsif(delcounter = "001" and triggering = '0') then
+ memwren <= '1';
+ memdata <= x"00000000"; --add empty trigger
+ --number
+ end if;
+ if(delcounter = "000") then
+ state <= pulld;
+ pulldown <= '1';
+ delcounter <= "001";
+ end if;
+ endofevent <= '0';
+ when pulld =>
+ testoutro(3) <= '1';
+ memwren <= '0';
+ pulldown <= '0';
+ delcounter <= delcounter - '1';
+ state <= pulld;
+ if(delcounter = "000") then
+ state <= loadcol;
+ ldcol <= '1';
+ delcounter <= "001";
+ end if;
+ endofevent <= '0';
+ when loadcol =>
+ testoutro(4) <= '1';
+ memwren <= '0';
+ ldcol <= '0';
+ delcounter <= delcounter - '1';
+ state <= loadcol;
+ endofevent <= '0';
+ if(delcounter = "000" and priout = '1') then
+ state <= readcol;
+ rdcol <= '1';
+ delcounter <= "010";
+ elsif(delcounter = "000") then
+ -- end of event
+ memwren <= '1';
+ memdata <= "10111110111011111011111011101111"; --0xBEEFBEEF
+ endofevent <= '1';
+ state <= waiting;
+ end if;
+ when readcol =>
+ testoutro(5) <= '1';
+ rdcol <= '0';
+ delcounter <= delcounter - '1';
+ memwren <= '0';
+ state <= readcol;
+ endofevent <= '0';
+ if(delcounter = "010") then
+ memdata <= "111100001111" & hit_col & hit_row & hit_time; --0xF0F
+ memwren <= '1';
+ hitcounter <= hitcounter + '1';
+ state <= readcol;
+ elsif(delcounter = "000" and hitcounter = "11111111111") then
+ -- 2048 hits - force end of event
+ memwren <= '1';
+ memdata <= "10111110111011111011111011101111"; --0xBEEFBEEF
+ endofevent <= '1';
+ state <= waiting;
+ elsif(delcounter = "000" and priout = '1') then
+ state <= readcol;
+ rdcol <= '1';
+ delcounter <= "010";
+ elsif(delcounter = "000") then
+ state <= pulld;
+ pulldown <= '1';
+ delcounter <= "001";
+ end if;
+
+ when hitgenerator =>
+ ro_busy_int <= '1';
+ testoutro(6) <= '1';
+ state <= hitgenerator;
+ if(delcounter = "100") then -- write event header
+ state <= hitgenerator;
+ memdata <= "11111010101111101010101110111010"; --0xFABEABBA
+ memwren <= '1';
+ ngeneratehitscounter <= ngeneratehits;
+ generatehitswaitcounter <= generatehitswait;
+ gen_hit_col <= (others => '0');
+ gen_hit_row <= (others => '0');
+ gen_hit_time <= (others => '0');
+ delcounter <= delcounter - '1';
+ endofevent <= '0';
+ elsif(delcounter = "011") then -- write event counter
+ state <= hitgenerator;
+ memdata <= eventcounter;
+ memwren <= '1';
+ delcounter <= delcounter - '1';
+ endofevent <= '0';
+ elsif(delcounter = "010") then
+ state <= hitgenerator;
+ memwren <= '0';
+ delcounter <= delcounter - '1';
+ endofevent <= '0';
+ elsif(delcounter = "001" and triggering = '1' and trignum_ena = '1') then -- write trigger number
+ state <= hitgenerator;
+ memdata <= "11001100110011000" &trignum; -- 0xCCCC foolowed by trignum
+ memwren <= '1';
+ delcounter <= delcounter - '1';
+ endofevent <= '0';
+ -- elsif(delcounter = "001" and triggering = '1' and trignum_ena = '0' and timeoutcounter = "1111111111") then -- write fake trigger number
+ -- state <= hitgenerator;
+ -- memdata <= "1100110011001100" & "1111111111111111"; -- 0xCCCC foolowed by trignum
+ -- memwren <= '1';
+ -- delcounter <= delcounter - '1';
+ -- endofevent <= '0';
+ elsif(delcounter = "001" and triggering = '1' and trignum_ena = '0') then -- wait for trigger number
+ state <= hitgenerator;
+ memwren <= '0';
+ delcounter <= delcounter;
+ endofevent <= '0';
+ --timeoutcounter <= timeoutcounter + '1';
+ elsif(delcounter = "001" and triggering = '0') then
+ state <= hitgenerator;
+ memwren <= '1';
+ memdata <= x"00000000"; --add empty trigger
+ --number
+ delcounter <= delcounter - '1';
+ endofevent <= '0';
+ elsif(delcounter = "000" and ngeneratehitscounter > "0000000000000000") then
+ state <= hitgenerator;
+ delcounter <= delcounter;
+ ngeneratehitscounter <= ngeneratehitscounter - '1';
+ gen_hit_col <= gen_hit_col + "0101";
+ gen_hit_row <= gen_hit_row + "0111";
+ if(gen_hit_row > "10000") then
+ gen_hit_row <= "000000";
+ end if;
+ memdata <= "111100001111" & "0" & gen_hit_col(4 downto 0) & gen_hit_row & graycount; --0xF0F
+ memwren <= '1';
+ endofevent <= '0';
+ elsif(delcounter = "000" and ngeneratehitscounter = "0000000000000000" and generatehits = '0') then
+ state <= waiting;
+ -- end of event
+ memwren <= '1';
+ memdata <= "10111110111011111011111011101111"; --0xBEEFBEEF
+ endofevent <= '1';
+ elsif(delcounter = "000" and ngeneratehitscounter = "0000000000000000" and generatehits = '1') then
+ state <= hitgeneratorwait;
+ -- end of event
+ memwren <= '1';
+ memdata <= "10111110111011111011111011101111"; --0xBEEFBEEF
+ endofevent <= '1';
+ else
+ state <= hitgenerator;
+ memwren <= '0';
+ endofevent <= '0';
+ end if;
+
+ when hitgeneratorwait =>
+ ro_busy_int <= '0';
+ state <= hitgeneratorwait;
+ testoutro(7) <= '1';
+ memwren <= '0';
+ endofevent <= '0';
+ generatehitswaitcounter <= generatehitswaitcounter - '1';
+ if(conv_integer(generatehitswaitcounter) = 0)then
+ state <= hitgenerator;
+ delcounter <= "100";
+ eventcounter <= eventcounter + '1';
+ end if;
+
+ when others =>
+ testoutro(8) <= '1';
+ state <= waiting;
+ endofevent <= '0';
+ end case;
+ end if;
+ end process;
+
+ tsgen :
+ process(rstn, clk)
+ begin
+ if(rstn = '0') then
+ timestamps <= (others => '0');
+ elsif(clk'event and clk = '1') then
+ if(timestampcontrolbits(8) = '1') then
+ timestamps <= graycount;
+ else
+ timestamps <= timestampcontrolbits(7 downto 0);
+ end if;
+ end if;
+ end process;
+
+ resetgraycounter <= not rstn;
+
+ grcount : Graycounter
+ generic map(
+ COUNTWIDTH => 8
+ )
+ port map(
+ clk => clk,
+ reset => resetgraycounter,
+ sync_reset => timestampcontrolbits(9),
+ counter => graycount
+ );
+
+
+ ro_busy <= ro_busy_int;
+end RTL;
--- /dev/null
+-- Gray counter
+-- Niklaus Berger
+-- 15.5.2012
+
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+
+
+entity Graycounter is
+ generic (
+ COUNTWIDTH : integer := 8
+ );
+ port (
+ clk : in std_logic; -- clock
+ reset : in std_logic; -- asynchronous reset
+ sync_reset : in std_logic; -- synchronous reset
+
+ counter : out std_logic_vector(COUNTWIDTH-1 downto 0) -- counter
+ );
+end Graycounter;
+
+architecture rtl of Graycounter is
+
+ signal msb : std_logic;
+ signal counter_reg : std_logic_vector(COUNTWIDTH downto 0);
+ signal no_ones_below : std_logic_vector(COUNTWIDTH downto 0);
+
+begin
+
+ counter <= counter_reg(COUNTWIDTH downto 1);
+
+ msb <= counter_reg(COUNTWIDTH) or counter_reg(COUNTWIDTH-1);
+
+ process(clk, reset)
+ begin
+ if(reset = '1') then
+ counter_reg <= (others => '0');
+ counter_reg(0) <= '1';
+ elsif (clk'event and clk = '1') then
+ if (sync_reset = '1') then
+ counter_reg <= (others => '0');
+ counter_reg(0) <= '1';
+ else
+ counter_reg(0) <= not counter_reg(0);
+ for i in 1 to COUNTWIDTH-1 loop
+ counter_reg(i) <= counter_reg(i) xor (counter_reg(i-1) and no_ones_below(i-1));
+ end loop;
+ counter_reg(COUNTWIDTH) <= counter_reg(COUNTWIDTH) xor (msb and no_ones_below(COUNTWIDTH-1));
+ end if;
+ end if;
+ end process;
+
+ no_ones_below(0) <= '1';
+
+ process(counter_reg, no_ones_below)
+ begin
+ for j in 1 to COUNTWIDTH loop
+ no_ones_below(j) <= no_ones_below(j-1) and not counter_reg(j-1);
+ end loop;
+ end process;
+
+end rtl;
--- /dev/null
+-----------------------------------------------------------------------------
+-- MUPIX3 injection generator
+--
+-- Niklaus Berger, Heidelberg University
+-- nberger@physi.uni-heidelberg.de
+--
+-----------------------------------------------------------------------------
+
+
+
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+use work.mupix_comp.all;
+
+entity injection_generator is
+ port (
+ rstn : in std_logic;
+ clk : in std_logic;
+ injection_register : in std_logic_vector(31 downto 0);
+ reg_written : in std_logic;
+ testpulse1 : out std_logic;
+ testpulse2 : out std_logic
+ );
+end injection_generator;
+
+
+architecture rtl of injection_generator is
+
+ signal counter1 : std_logic_vector(15 downto 0);
+ signal counter2 : std_logic_vector(15 downto 0);
+
+
+begin
+
+ process(clk, rstn)
+ begin
+ if(rstn = '0') then
+
+ testpulse1 <= '0';
+ testpulse2 <= '0';
+
+ elsif(clk'event and clk = '1') then
+
+ if(reg_written = '1') then
+ counter1 <= injection_register(15 downto 0);
+ counter2 <= injection_register(31 downto 16);
+ end if;
+
+ if(counter1 > "00000000000000000") then
+ testpulse1 <= '1';
+ counter1 <= counter1 - '1';
+ else
+ testpulse1 <= '0';
+ end if;
+
+ if(counter2 > "00000000000000000") then
+ testpulse2 <= '1';
+ counter2 <= counter2 - '1';
+ else
+ testpulse2 <= '0';
+ end if;
+
+ end if;
+ end process;
+end rtl;
--- /dev/null
+--type definitions and components for MuPix readout
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+package mupix_components is
+
+ --MuPix Board entity with regio to trbv3
+ component MuPix3_Board
+ port (
+ clk : in std_logic;
+ fastclk : in std_logic;
+ reset : in std_logic;
+ timestamp_from_mupix : in std_logic_vector(7 downto 0);
+ rowaddr_from_mupix : in std_logic_vector(5 downto 0);
+ coladdr_from_mupix : in std_logic_vector(5 downto 0);
+ priout_from_mupix : in std_logic;
+ sout_c_from_mupix : in std_logic;
+ sout_d_from_mupix : in std_logic;
+ hbus_form_mupix : in std_logic;
+ fpga_aux_from_board : in std_logic_vector(9 downto 0);
+ ldpix_to_mupix : out std_logic;
+ ldcol_to_mupix : out std_logic;
+ timestamp_to_mupix : out std_logic_vector(7 downto 0);
+ rdcol_to_mupix : out std_logic;
+ pulldown_to_mupix : out std_logic;
+ sin_to_mupix : out std_logic;
+ ck_d_to_mupix : out std_logic;
+ ck_c_to_mupix : out std_logic;
+ ld_c_to_mupix : out std_logic;
+ testpulse1_to_board : out std_logic;
+ testpulse2_to_board : out std_logic;
+ spi_din_to_board : out std_logic;
+ spi_clk_to_board : out std_logic;
+ spi_ld_to_board : out std_logic;
+ fpga_led_to_board : out std_logic_vector(3 downto 0);
+ fpga_aux_to_board : out std_logic_vector(9 downto 0);
+ LVL1_TRG_DATA_VALID_IN : in std_logic;
+ LVL1_VALID_TIMING_TRG_IN : in std_logic;
+ LVL1_VALID_NOTIMING_TRG_IN : in std_logic;
+ LVL1_INVALID_TRG_IN : in std_logic;
+ LVL1_TRG_TYPE_IN : in std_logic_vector(3 downto 0);
+ LVL1_TRG_NUMBER_IN : in std_logic_vector(15 downto 0);
+ LVL1_TRG_CODE_IN : in std_logic_vector(7 downto 0);
+ LVL1_TRG_INFORMATION_IN : in std_logic_vector(23 downto 0);
+ LVL1_INT_TRG_NUMBER_IN : in std_logic_vector(15 downto 0);
+ FEE_TRG_RELEASE_OUT : out std_logic;
+ FEE_TRG_STATUSBITS_OUT : out std_logic_vector(31 downto 0);
+ FEE_DATA_OUT : out std_logic_vector(31 downto 0);
+ FEE_DATA_WRITE_OUT : out std_logic;
+ FEE_DATA_FINISHED_OUT : out std_logic;
+ FEE_DATA_ALMOST_FULL_IN : in std_logic;
+ REGIO_ADDR_IN : in std_logic_vector(15 downto 0);
+ REGIO_DATA_IN : in std_logic_vector(31 downto 0);
+ REGIO_DATA_OUT : out std_logic_vector(31 downto 0);
+ REGIO_READ_ENABLE_IN : in std_logic;
+ REGIO_WRITE_ENABLE_IN : in std_logic;
+ REGIO_TIMEOUT_IN : in std_logic;
+ REGIO_DATAREADY_OUT : out std_logic;
+ REGIO_WRITE_ACK_OUT : out std_logic;
+ REGIO_NO_MORE_DATA_OUT : out std_logic;
+ REGIO_UNKNOWN_ADDR_OUT : out std_logic);
+ end component;
+
+end mupix_components;
--- /dev/null
+----------------------------------------------------------------------------
+-- SPI IF
+-- Interface to the SPI bus controlling the three DACs on the mupix test board
+--
+-- Niklaus Berger, Heidelberg University
+-- nberger@physi.uni-heidelberg.de
+--
+--
+--
+-----------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+
+use work.mupix_comp.all;
+
+entity spi_if is
+ port(
+ clk : in std_logic;
+ reset_n : in std_logic;
+ threshold_reg : in std_logic_vector(15 downto 0);
+ injection1_reg : in std_logic_vector(15 downto 0);
+ injection2_reg : in std_logic_vector(15 downto 0);
+ wren : in std_logic;
+ spi_data : out std_logic;
+ spi_clk : out std_logic;
+ spi_ld : out std_logic
+ );
+end entity spi_if;
+
+
+
+architecture rtl of spi_if is
+
+ type state_type is (waiting, writing, loading);
+ signal state : state_type;
+
+ signal shiftregister : std_logic_vector(47 downto 0);
+ signal write_again : std_logic;
+
+ signal ckdiv : std_logic_vector(4 downto 0);
+
+
+
+ signal cyclecounter : std_logic_vector(7 downto 0);
+
+begin
+
+
+ process(clk, reset_n)
+
+ begin
+ if(reset_n = '0') then
+ ckdiv <= (others => '0');
+ cyclecounter <= (others => '0');
+ spi_data <= '0';
+ spi_clk <= '0';
+ spi_ld <= '0';
+ state <= waiting;
+ elsif(clk'event and clk = '1') then
+ case state is
+ when waiting =>
+ ckdiv <= (others => '0');
+ cyclecounter <= (others => '0');
+ spi_data <= '0';
+ spi_clk <= '0';
+ spi_ld <= '0';
+ state <= waiting;
+
+ if(wren = '1' or write_again = '1') then
+ shiftregister <= injection2_reg & injection1_reg & threshold_reg;
+ state <= writing;
+ write_again <= '0';
+ end if;
+ when writing =>
+ if(wren = '1') then
+ write_again <= '1';
+ end if;
+
+ ckdiv <= ckdiv + '1';
+ if(ckdiv = "00000") then
+ cyclecounter <= cyclecounter + '1';
+ if(cyclecounter(0) = '0') then -- even cycles: push data, clock at '0'
+ spi_data <= shiftregister(47);
+ shiftregister(47 downto 1) <= shiftregister(46 downto 0);
+ shiftregister(0) <= '0';
+ spi_clk <= '0';
+ end if;
+ if(cyclecounter(0) = '1') then --odd cycles:
+ spi_clk <= '1';
+ end if;
+ if(cyclecounter = "01100000") then -- we are done...
+ state <= loading;
+ spi_clk <= '1';
+ cyclecounter <= "00000000";
+ end if;
+ end if;
+ when loading =>
+ if(wren = '1') then
+ write_again <= '1';
+ end if;
+ ckdiv <= ckdiv + '1';
+ if(ckdiv = "00000") then
+ cyclecounter <= cyclecounter + '1';
+ if(cyclecounter = "00000000") then
+ spi_ld <= '1';
+ elsif(cyclecounter = "00000001") then
+ spi_clk <= '0';
+ elsif(cyclecounter = "00000010") then
+ spi_ld <= '0';
+ state <= waiting;
+ end if;
+ end if;
+ end case;
+ end if;
+ end process;
+
+end rtl;