--- /dev/null
+----------------------------------------------------------------------------------
+-- SPI Interface for the ADS1018 ADC on the mupix 8 sensorboard
+-- used for temperature measurement
+-- Tobias Weber
+-- Ruhr Unversitaet Bochum
+-----------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity ADS1018SPI is
+ generic(
+ fpga_clock_speed : integer := 1e8;
+ spi_clock_speed : integer := 1e4
+ );
+ port(
+ clk : in std_logic;
+ reset : in std_logic;
+ start_write : in std_logic; --start writing data to adc/start conversion
+ config_in : in std_logic_vector(15 downto 0); --config data to adc
+ spi_data_from_chip : in std_logic; --serial data from dac
+ spi_data_to_chip : out std_logic; --seral data to dac shift register
+ spi_data_out : out std_logic_vector(31 downto 0); --conversion data and config readback
+ spi_clk : out std_logic; --SPI interface clock
+ spi_ld : out std_logic); --SPI load/chip select
+end entity ADS1018SPI;
+
+architecture RTL of ADS1018SPI is
+
+begin
+
+end architecture RTL;
--- /dev/null
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.NUMERIC_STD.all;
+
+entity BlockMemory is
+ generic (
+ DataWidth : integer := 10; --data width
+ AddressWidth : integer := 10); --address width
+ port (
+ clk : in std_logic;-- clock
+ WrEn : in std_logic;-- write enable
+ WrAddr : in std_logic_vector(AddressWidth - 1 downto 0);-- write address
+ Din : in std_logic_vector(DataWidth - 1 downto 0);-- data in
+ ReAddr : in std_logic_vector(AddressWidth - 1 downto 0);--read address
+ Dout : out std_logic_vector(DataWidth - 1 downto 0));--data out (1 clock period delay)
+end BlockMemory;
+
+architecture Behavioral of BlockMemory is
+
+ type memory_type is array ((2**AddressWidth) - 1 downto 0) of std_logic_vector(DataWidth - 1 downto 0);
+ signal memory : memory_type := (others => (others => '0'));
+
+begin
+
+ MemoryControll : process(clk)
+ begin -- process MemoryControll
+ if rising_edge(clk) then
+ Dout <= memory(to_integer(unsigned(ReAddr))); --read memory
+ if(WrEn = '1') then
+ memory(to_integer(unsigned(WrAddr))) <= Din; -- write memory
+ end if;
+ end if;
+ end process MemoryControll;
+
+
+end Behavioral;
+
--- /dev/null
+-------------------------------------------------------------------------------
+--Computation of cyclic redundancy check
+--We use the CRC5 polynomial f(x) = 1 + x^2 + x^ 5 used by the USB2.0 protocol
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity CRC is
+ generic(
+ detect_enable_edge : boolean := false
+ );
+ port(
+ clk : in std_logic;
+ rst : in std_logic;
+ enable : in std_logic;
+ data_in : in std_logic;
+ crc_out : out std_logic_vector(4 downto 0));
+end entity CRC;
+
+architecture rtl of CRC is
+ signal lfsr : std_logic_vector(4 downto 0) := (others => '1');
+ signal edge_detect : std_logic_vector(1 downto 0) := (others => '0');
+begin
+
+ normal_gen : if detect_enable_edge = false generate
+ CRC_proc : process(clk) is
+ begin
+ if rising_edge(clk) then
+ if rst = '1' then
+ lfsr <= (others => '1');
+ else
+ lfsr <= lfsr;
+ if enable = '1' then
+ lfsr(0) <= lfsr(4) xor data_in;
+ lfsr(1) <= lfsr(0);
+ lfsr(2) <= (lfsr(4) xor data_in) xor lfsr(1);
+ lfsr(3) <= lfsr(2);
+ lfsr(4) <= lfsr(3);
+ end if;
+ end if;
+ end if;
+ end process CRC_proc;
+ end generate;
+
+ detect_enable_edge_gen : if detect_enable_edge = true generate
+ CRC_edge_proc : process(clk) is
+ begin
+ if rising_edge(clk) then
+ if rst = '1' then
+ lfsr <= (others => '1');
+ edge_detect <= (others => '0');
+ else
+ edge_detect <= edge_detect(0) & enable;
+ lfsr <= lfsr;
+ if edge_detect = "01" then
+ lfsr(0) <= lfsr(4) xor data_in;
+ lfsr(1) <= lfsr(0);
+ lfsr(2) <= (lfsr(4) xor data_in) xor lfsr(1);
+ lfsr(3) <= lfsr(2);
+ lfsr(4) <= lfsr(3);
+ end if;
+ end if;
+ end if;
+ end process CRC_edge_proc;
+ end generate;
+
+ crc_out <= lfsr;
+
+end architecture rtl;
\ No newline at end of file
--- /dev/null
+-------------------------------------------------------------------------------
+--Dummy implementation of FIFO for simulation
+--For production system use FPGA manufacturer IP core
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.NUMERIC_STD.all;
+
+entity STD_FIFO is
+ generic (
+ constant DATA_WIDTH : positive := 8;
+ constant FIFO_DEPTH : positive := 256
+ );
+ port (
+ CLK : in std_logic;
+ RST : in std_logic;
+ WriteEn : in std_logic;
+ DataIn : in std_logic_vector (DATA_WIDTH - 1 downto 0);
+ ReadEn : in std_logic;
+ DataOut : out std_logic_vector (DATA_WIDTH - 1 downto 0);
+ Empty : out std_logic;
+ Full : out std_logic
+ );
+end STD_FIFO;
+
+architecture Behavioral of STD_FIFO is
+
+begin
+
+ -- Memory Pointer Process
+ fifo_proc : process (CLK)
+ type FIFO_Memory is array (0 to FIFO_DEPTH - 1) of std_logic_vector (DATA_WIDTH - 1 downto 0);
+ variable Memory : FIFO_Memory;
+
+ variable Head : natural range 0 to FIFO_DEPTH - 1;
+ variable Tail : natural range 0 to FIFO_DEPTH - 1;
+
+ variable Looped : boolean;
+ begin
+ if rising_edge(CLK) then
+ if RST = '1' then
+ Head := 0;
+ Tail := 0;
+
+ Looped := false;
+
+ Full <= '0';
+ Empty <= '1';
+ else
+ if (ReadEn = '1') then
+ if ((Looped = true) or (Head /= Tail)) then
+ -- Update data output
+ DataOut <= Memory(Tail);
+
+ -- Update Tail pointer as needed
+ if (Tail = FIFO_DEPTH - 1) then
+ Tail := 0;
+
+ Looped := false;
+ else
+ Tail := Tail + 1;
+ end if;
+
+
+ end if;
+ end if;
+
+ if (WriteEn = '1') then
+ if ((Looped = false) or (Head /= Tail)) then
+ -- Write Data to Memory
+ Memory(Head) := DataIn;
+
+ -- Increment Head pointer as needed
+ if (Head = FIFO_DEPTH - 1) then
+ Head := 0;
+
+ Looped := true;
+ else
+ Head := Head + 1;
+ end if;
+ end if;
+ end if;
+
+ -- Update Empty and Full flags
+ if (Head = Tail) then
+ if Looped then
+ Full <= '1';
+ else
+ Empty <= '1';
+ end if;
+ else
+ Empty <= '0';
+ Full <= '0';
+ end if;
+ end if;
+ end if;
+ end process;
+
+end Behavioral;
--- /dev/null
+-- Gray counter
+-- Niklaus Berger
+-- 15.5.2012
+
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+entity Graycounter is
+ generic (
+ COUNTWIDTH : integer := 8
+ );
+ port (
+ clk : in std_logic; -- clock
+ reset : in std_logic; -- reset
+ clk_divcounter : in std_logic_vector(7 downto 0); -- clockdivider for
+ -- graycounter clock
+ counter : out std_logic_vector(COUNTWIDTH-1 downto 0) -- counter
+ );
+end Graycounter;
+
+architecture rtl of Graycounter is
+
+ signal msb : std_logic := '0';
+ signal counter_reg : std_logic_vector(COUNTWIDTH downto 0) := (others => '0');
+ signal no_ones_below : std_logic_vector(COUNTWIDTH downto 0) := "000000001";
+ signal clk_enable : std_logic := '0';
+ signal divcounter : unsigned(7 downto 0) := (others => '0');
+
+begin
+
+ counter <= counter_reg(COUNTWIDTH downto 1);
+
+ msb <= counter_reg(COUNTWIDTH) or counter_reg(COUNTWIDTH-1);
+
+ clock_divider_proc : process (clk) is
+ begin -- process clock_divider_proc
+ if rising_edge(clk) then
+ if reset = '1' then
+ divcounter <= (others => '0');
+ clk_enable <= '0';
+ else
+ divcounter <= divcounter + 1;
+ clk_enable <= '0';
+ if std_logic_vector(divcounter) = clk_divcounter then
+ clk_enable <= '1';
+ divcounter <= (others => '0');
+ end if;
+ end if;
+ end if;
+ end process clock_divider_proc;
+
+ process(clk)
+ begin
+ if rising_edge(clk) then
+ if (reset = '1') then
+ no_ones_below(0) <= '1';
+ counter_reg <= (others => '0');
+ counter_reg(0) <= '1';
+ else
+ if clk_enable = '1' then
+ 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));
+ else
+ counter_reg <= counter_reg;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ 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
+----------------------------------------------------------------------------
+-- Histogram using block memory
+-- Tobias Weber
+-- Ruhr Unversitaet Bochum
+-----------------------------------------------------------------------------
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.NUMERIC_STD.all;
+
+entity Histogram is
+ generic (
+ HistogramHeight : integer := 12; -- Bin Height 2**HistogramHeight
+ HistogramRange : integer := 10); -- Histogram Range 2**HistogramRange
+ port (
+ clk : in std_logic; --clock
+ reset : in std_logic; --reset
+ StartRun : in std_logic; --start acquiring data
+ StartRd : in std_logic; --start reading the histogram
+ ReadAddr : in std_logic_vector(HistogramRange - 1 downto 0); --read address
+ Wr : in std_logic; --write enable
+ BinSelect : in std_logic_vector(HistogramRange - 1 downto 0); --select bin to write data
+ DataValid : out std_logic; --output data is valid
+ BinHeight : out std_logic_vector(HistogramHeight - 1 downto 0)); --value of bin at ReadAddr
+end Histogram;
+
+architecture Behavioral of Histogram is
+
+ component BlockMemory
+ generic (
+ DataWidth : integer;
+ AddressWidth : integer);
+ port (
+ clk : in std_logic;
+ WrEn : in std_logic;
+ WrAddr : in std_logic_vector(AddressWidth - 1 downto 0);
+ Din : in std_logic_vector(DataWidth - 1 downto 0);
+ ReAddr : in std_logic_vector(AddressWidth - 1 downto 0);
+ Dout : out std_logic_vector(DataWidth - 1 downto 0));
+ end component;
+
+ type Histo_fsm_type is (idle, WriteHisto, ReadHisto, WaitOnMem, Clear);
+ signal Histo_fsm : Histo_fsm_type := idle;
+
+ signal MemWrAddr : std_logic_vector(HistogramRange - 1 downto 0);
+ signal MemRdAddr : std_logic_vector(HistogramRange - 1 downto 0);
+ signal MemWrEn : std_logic;
+ signal MemDIn : std_logic_vector(HistogramHeight - 1 downto 0);
+ signal MemDOut : std_logic_vector(HistogramHeight - 1 downto 0);
+
+ signal bincounter : unsigned(HistogramRange - 1 downto 0);
+ signal delcounter : integer range 0 to 1 := 0;
+ signal Overflow : std_logic := '0';
+
+begin
+
+ BlockMemory_1 : BlockMemory
+ generic map (
+ DataWidth => HistogramHeight,
+ AddressWidth => HistogramRange)
+ port map (
+ clk => clk,
+ WrEn => MemWrEn,
+ WrAddr => MemWrAddr,
+ Din => MemDIn,
+ ReAddr => MemRdAddr,
+ Dout => MemDOut);
+
+ Histogram : process(clk)
+ begin -- process Histogram
+ if rising_edge(clk) then
+ case Histo_fsm is
+ when idle =>
+ bincounter <= (others => '0');
+ MemRdAddr <= (others => '0');
+ MemWrAddr <= (others => '0');
+ MemDIn <= (others => '0');
+ MemWrEn <= '0';
+ DataValid <= '0';
+ if (Wr = '1' and StartRun = '1' and Overflow = '0') then
+ Histo_fsm <= WriteHisto;
+ MemRdAddr <= BinSelect;
+ elsif StartRd = '1' then
+ Histo_fsm <= WaitOnMem;
+ MemRdAddr <= ReadAddr;
+ elsif Reset = '1' then
+ Histo_fsm <= Clear;
+ Overflow <= '0';
+ else
+ Histo_fsm <= Idle;
+ end if;
+
+ when WriteHisto =>
+ if delcounter = 1 then
+ MemWrAddr <= MemRdAddr;
+ MemWrEn <= '1';
+ delcounter <= 0;
+ Histo_fsm <= idle;
+ if to_integer(unsigned(MemDOut)) = 2**HistogramHeight - 1 then
+ --Overflow detected stop writing histogram data
+ MemDIn <= MemDOut;
+ Overflow <= '1';
+ else
+ MemDIn <= std_logic_vector(unsigned(MemDOut) + 1);
+ Overflow <= '0';
+ end if;
+ else
+ delcounter <= delcounter + 1; --one clk read delay of memory
+ end if;
+
+ when WaitOnMem =>
+ Histo_fsm <= ReadHisto;
+
+ when ReadHisto =>
+ BinHeight <= MemDOut;
+ DataValid <= '1';
+ Histo_fsm <= idle;
+
+ when Clear =>
+ bincounter <= bincounter + 1;
+ MemWrAddr <= std_logic_vector(bincounter);
+ MemDIn <= (others => '0');
+ MemWrEn <= '1';
+ if to_integer(bincounter) = (2**HistogramRange - 1) then
+ Histo_fsm <= idle;
+ end if;
+ end case;
+ end if;
+ end process Histogram;
+
+end Behavioral;
+
--- /dev/null
+-------------------------------------------------------------------------------
+--Histogramming of Hitbus for Time over Threshold and Latency Measurement
+--Tobias Weber
+--Ruhr Universitaet Bochum
+-------------------------------------------------------------------------------
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.NUMERIC_STD.all;
+
+entity HitbusHistogram is
+ generic (
+ HistogramRange : integer := 8; --number of histogram bins 2**HistogramRange
+ PostOscillationWaitCycles : integer := 5);--number of clock cycles to wait after hit-bus signal went low
+ port (
+ clk : in std_logic; --clock
+ hitbus : in std_logic; --hit-bus signal
+ trigger : in std_logic; --external trigger e.g. from scintillator
+ SLV_READ_IN : in std_logic;
+ SLV_WRITE_IN : in std_logic;
+ SLV_DATA_OUT : out std_logic_vector(31 downto 0);
+ SLV_DATA_IN : in std_logic_vector(31 downto 0);
+ SLV_ADDR_IN : in std_logic_vector(15 downto 0);
+ SLV_ACK_OUT : out std_logic;
+ SLV_NO_MORE_DATA_OUT : out std_logic;
+ SLV_UNKNOWN_ADDR_OUT : out std_logic
+ );
+end HitbusHistogram;
+
+architecture Behavioral of HitbusHistogram is
+
+ component Histogram
+ generic (
+ HistogramHeight : integer;
+ HistogramRange : integer);
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+ StartRun : in std_logic;
+ StartRd : in std_logic;
+ ReadAddr : in std_logic_vector(HistogramRange - 1 downto 0);
+ Wr : in std_logic;
+ BinSelect : in std_logic_vector(HistogramRange - 1 downto 0);
+ DataValid : out std_logic;
+ BinHeight : out std_logic_vector(HistogramHeight - 1 downto 0));
+ end component;
+
+ component SignalDelay is
+ generic (
+ Width : integer;
+ Delay : integer);
+ port (
+ clk_in : in std_logic;
+ write_en_in : in std_logic;
+ delay_in : in std_logic_vector(Delay - 1 downto 0);
+ sig_in : in std_logic_vector(Width - 1 downto 0);
+ sig_out : out std_logic_vector(Width - 1 downto 0));
+ end component SignalDelay;
+
+ signal hitbus_i : std_logic_vector(1 downto 0);
+ signal trigger_i : std_logic_vector(1 downto 0);
+
+ --ToT Histogram
+ type hithisto_fsm_type is (idle, hitbus_high, wait_for_postOscillation);
+ signal hithisto_fsm : hithisto_fsm_type := idle;
+ signal hitbus_counter : unsigned(HistogramRange - 1 downto 0); --duration of hitbus high
+ signal postOscillationCounter : unsigned(HistogramRange - 1 downto 0);
+ signal hitbus_HistoWrAddr : std_logic_vector(HistogramRange - 1 downto 0);
+ signal hitbus_WriteBin : std_logic;
+ signal hitbus_BinValue : std_logic_vector(15 downto 0);
+
+
+ --Latency Histogram
+ type latency_fsm_type is (idle, waitforhitbus);
+ signal latency_fsm : latency_fsm_type := idle;
+ signal latency_counter : unsigned(HistogramRange - 1 downto 0); --duration of hitbus high
+ signal latency_HistoWrAddr : std_logic_vector(HistogramRange - 1 downto 0);
+ signal latency_WriteBin : std_logic;
+ signal latency_BinValue : std_logic_vector(15 downto 0);
+
+
+ --Histogram Ctrl
+ signal histo_ctrl : std_logic_vector(31 downto 0) := (others => '0');
+ signal histvalue : std_logic_vector(31 downto 0);
+ signal histvalue_valid : std_logic;
+ signal ReadAddr_i : std_logic_vector(HistogramRange - 1 downto 0);
+ signal ReadHisto : std_logic := '0';
+ signal reading_histo_mem : std_logic := '0'; --read in progress
+ signal readcounter : unsigned(HistogramRange - 1 downto 0) := (others => '0');
+ signal hitbus_wait : unsigned(HistogramRange - 1 downto 0) := (others => '0');
+
+ signal hitbus_delayed : std_logic;
+
+
+begin
+
+ Histogram_1 : Histogram
+ generic map (
+ HistogramHeight => 16, --change Max Height of Histogrambin here
+ HistogramRange => HistogramRange)
+ port map (
+ clk => clk,
+ reset => histo_ctrl(2),
+ StartRun => histo_ctrl(1),
+ StartRd => ReadHisto,
+ ReadAddr => ReadAddr_i,
+ Wr => hitbus_WriteBin,
+ BinSelect => hitbus_HistoWrAddr,
+ DataValid => histvalue_valid,
+ BinHeight => hitbus_BinValue);
+
+ Histogram_2 : Histogram
+ generic map (
+ HistogramHeight => 16,
+ HistogramRange => HistogramRange)
+ port map (
+ clk => clk,
+ reset => histo_ctrl(2),
+ StartRun => histo_ctrl(1),
+ StartRd => ReadHisto,
+ ReadAddr => ReadAddr_i,
+ Wr => latency_WriteBin,
+ BinSelect => latency_HistoWrAddr,
+ DataValid => open,
+ BinHeight => latency_BinValue);
+
+ SignalDelay_1: entity work.SignalDelay
+ generic map (
+ Width => 1,
+ Delay => 5)
+ port map (
+ clk_in => clk,
+ write_en_in => '1',
+ delay_in => std_logic_vector(to_unsigned(5, 5)),
+ sig_in(0) => hitbus,
+ sig_out(0) => hitbus_delayed);
+
+ -- purpose: hitbus and trigger edge detect
+ hitbus_edge_proc: process (clk) is
+ begin -- process hitbus_edge_proc
+ if rising_edge(clk) then
+ hitbus_i <= hitbus_i(0) & hitbus_delayed;
+ trigger_i <= trigger_i(0) & trigger;
+ end if;
+ end process hitbus_edge_proc;
+
+ -----------------------------------------------------------------------------
+ --Time over Threshold histogram
+ -----------------------------------------------------------------------------
+ HitBusHisto : process(clk)
+ begin -- process HitBusHisto
+ if rising_edge(clk) then
+ hitbus_WriteBin <= '0';
+ postOscillationCounter <= (others => '0');
+ hitbus_HistoWrAddr <= (others => '0');
+ case hithisto_fsm is
+ when idle =>
+ hitbus_counter <= (others => '0');
+ hithisto_fsm <= idle;
+ if hitbus_i = "01" then --rising edge on hitbus
+ hithisto_fsm <= hitbus_high;
+ end if;
+ when hitbus_high =>
+ hitbus_counter <= hitbus_counter + 1;
+ hithisto_fsm <= hitbus_high;
+ if hitbus_i = "10" then --falling edge
+ hithisto_fsm <= wait_for_postOscillation;
+ end if;
+ when wait_for_postOscillation =>
+ postOscillationCounter <= postOscillationCounter + 1;
+ if(to_integer(postOscillationCounter) = PostOscillationWaitCycles) then --wait 5 clock cycles
+ hitbus_WriteBin <= '1';
+ hitbus_HistoWrAddr <= std_logic_vector(hitbus_counter);
+ hithisto_fsm <= idle;
+ elsif(hitbus_i = "01") then --new rising edge, belongs to the same event
+ hitbus_counter <= hitbus_counter + postOscillationCounter + 1;
+ hithisto_fsm <= hitbus_high;
+ else
+ hithisto_fsm <= wait_for_postOscillation;
+ end if;
+ end case;
+ end if;
+ end process HitBusHisto;
+
+ -----------------------------------------------------------------------------
+ --Latency Histogram
+ -----------------------------------------------------------------------------
+ LatencyHisto : process(clk)
+ begin -- process LatencyHisto
+ if rising_edge(clk) then
+ latency_histoWraddr <= (others => '0');
+ latency_WriteBin <= '0';
+ case latency_fsm is
+ when idle =>
+ if trigger_i = "01" then
+ latency_fsm <= waitforhitbus;
+ latency_counter <= latency_counter + 1;
+ else
+ latency_fsm <= idle;
+ latency_counter <= (others => '0');
+ end if;
+
+ when waitforhitbus =>
+ latency_counter <= latency_counter + 1;
+ if hitbus_i = "01" then
+ latency_writebin <= '1';
+ latency_histoWraddr <= std_logic_vector(latency_counter);
+ latency_fsm <= idle;
+ elsif latency_counter = hitbus_wait then
+ latency_fsm <= idle;
+ else
+ latency_fsm <= waitforhitbus;
+ end if;
+ end case;
+ end if;
+ end process LatencyHisto;
+
+ -----------------------------------------------------------------------------
+ --TRB Slave Bus
+ --0x0070: Histogram Ctrl
+ --0x0071: Last ToT Value
+ --0x0072: Last Latency Value
+ --0x0073: Read Histograms
+ --0x0074: ReadCounter
+ --0x0075: snapshot of hitbus
+ --0x0076: max wait time for hitbus event after latency trigger has been seen
+ -----------------------------------------------------------------------------
+ SLV_BUS_HANDLER : process(clk)
+ begin -- process SLV_BUS_HANDLER
+ if rising_edge(clk) then
+ SLV_DATA_OUT <= (others => '0');
+ SLV_ACK_OUT <= '0';
+ SLV_UNKNOWN_ADDR_OUT <= '0';
+ SLV_NO_MORE_DATA_OUT <= '0';
+ histvalue <= latency_BinValue & hitbus_BinValue;
+
+ if reading_histo_mem = '1' then
+ ReadHisto <= '0';
+ if histvalue_valid = '1' then
+ SLV_DATA_OUT <= histvalue;
+ SLV_ACK_OUT <= '1';
+ reading_histo_mem <= '0';
+ readcounter <= readcounter + 1;
+ else
+ reading_histo_mem <= '1';
+ end if;
+
+ elsif SLV_READ_IN = '1' then
+ case SLV_ADDR_IN is
+ when x"0800" =>
+ SLV_DATA_OUT <= histo_ctrl;
+ SLV_ACK_OUT <= '1';
+ when x"0801" =>
+ SLV_DATA_OUT(31 downto 16) <= (others => '0');
+ SLV_DATA_OUT(HistogramRange - 1 downto 0) <= hitbus_HistoWrAddr;
+ SLV_ACK_OUT <= '1';
+ when x"0802" =>
+ SLV_DATA_OUT(31 downto 16) <= (others => '0');
+ SLV_DATA_OUT(HistogramRange - 1 downto 0) <= latency_histoWraddr;
+ SLV_ACK_OUT <= '1';
+ when x"0803" =>
+ ReadHisto <= '1';
+ ReadAddr_i <= std_logic_vector(readcounter);
+ reading_histo_mem <= '1';
+ when x"0804" =>
+ SLV_DATA_OUT(HistogramRange - 1 downto 0) <= std_logic_vector(readcounter);
+ SLV_ACK_OUT <= '1';
+ when x"0805" =>
+ SLV_DATA_OUT(0) <= hitbus;
+ SLV_ACK_OUT <= '1';
+ when x"0806" =>
+ SLV_DATA_OUT(HistogramRange - 1 downto 0) <= std_logic_vector(hitbus_wait);
+ SLV_ACK_OUT <= '1';
+ when others =>
+ SLV_UNKNOWN_ADDR_OUT <= '1';
+ end case;
+
+ elsif SLV_WRITE_IN = '1' then
+ case SLV_ADDR_IN is
+ when x"0800" =>
+ histo_ctrl <= SLV_DATA_IN;
+ SLV_ACK_OUT <= '1';
+ when x"0804" =>
+ readcounter <= unsigned(SLV_DATA_IN(HistogramRange - 1 downto 0));
+ SLV_ACK_OUT <= '1';
+ when x"0806" =>
+ hitbus_wait <= unsigned(SLV_DATA_IN(HistogramRange - 1 downto 0));
+ SLV_ACK_OUT <= '1';
+ when others =>
+ SLV_UNKNOWN_ADDR_OUT <= '1';
+ end case;
+
+ end if;
+ end if;
+
+ end process SLV_BUS_HANDLER;
+
+
+
+end Behavioral;
+
--- /dev/null
+----------------------------------------------------------------------------
+-- Synchronize input to signal to input clock domain
+-- Tobias Weber
+-- Ruhr Unversitaet Bochum
+-----------------------------------------------------------------------------
+ library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+
+ entity InputSynchronizer is
+ generic(depth : integer := 2);
+ port(
+ clk : in std_logic; --input clock
+ rst : in std_logic; --reset
+ input : in std_logic; --asynchronous input signal
+ sync_output : out std_logic --synchronized signal
+ );
+ end entity InputSynchronizer;
+
+architecture RTL of InputSynchronizer is
+
+ signal syncstage : std_logic_vector(depth - 1 downto 0) := (others => '0');
+
+begin
+
+ sync_process : process (clk) is
+ begin
+ if rising_edge(clk) then
+ if rst = '1' then
+ syncstage <= (others => '0');
+ else
+ syncstage <= syncstage(depth - 2 downto 0) & input;
+ end if;
+ end if;
+ end process sync_process;
+
+ sync_output <= syncstage(depth - 1);
+
+end architecture RTL;
--- /dev/null
+----------------------------------------------------------------------------------
+-- SPI Interface for the LTC1658 DACs on the mupix 8 sensorboard
+-- used for controlling threshold + injection voltage and temperature measurement
+-- Tobias Weber
+-- Ruhr Unversitaet Bochum
+-----------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity LTC1658SPI is
+ generic(
+ data_length : integer; -- bits in data word
+ fpga_clock_speed : integer;-- clock speed of FPGA
+ spi_clock_speed : integer);-- clock speed of SPI bus
+ port(
+ clk : in std_logic; --clock
+ reset : in std_logic; --reset
+ start_write : in std_logic; --start writing data to DAC
+ spi_data_in : in std_logic_vector(data_length - 1 downto 0); --data to write
+ spi_data_from_chip : in std_logic; --serial data from dac
+ spi_data_to_chip : out std_logic; --seral data to dac shift register
+ spi_data_out : out std_logic_vector(data_length - 1 downto 0); --data read from shift register
+ spi_clk : out std_logic; --SPI interface clock
+ spi_ld : out std_logic); --SPI load/chip select
+end entity LTC1658SPI;
+
+
+architecture rtl of LTC1658SPI is
+
+ constant max_cycles : integer := fpga_clock_speed/spi_clock_speed;
+
+ type state_type is (waiting, sendbit1, sendbit2, loading1, loading2);
+ signal state : state_type;
+
+ signal shiftregister_out : std_logic_vector(data_length - 1 downto 0);
+ signal shiftregister_in : std_logic_vector(data_length - 1 downto 0);
+ signal clkdiv : integer range 0 to max_cycles - 1;
+ signal clk_enable : std_logic;
+ signal clkdiv_reset : std_logic;
+ signal wordcounter : integer range data_length - 1 downto 0;
+
+
+begin
+
+ clkdiv_reset <= reset or start_write;
+
+ clk_div_proc : process(clk) is
+ begin
+ if rising_edge(clk) then
+ if clkdiv_reset = '1' then
+ clk_enable <= '0';
+ clkdiv <= 0;
+ else
+ if clkdiv = max_cycles - 1 then
+ clk_enable <= '1';
+ clkdiv <= 0;
+ else
+ clk_enable <= '0';
+ clkdiv <= clkdiv + 1;
+ end if;
+ end if;
+ end if;
+ end process clk_div_proc;
+
+ shift_out_proc : process(clk)
+ begin
+ if rising_edge(clk) then
+ if (reset = '1') then
+ wordcounter <= 0;
+ spi_data_to_chip <= '0';
+ spi_clk <= '0';
+ spi_ld <= '0';
+ shiftregister_in <= (others => '0');
+ state <= waiting;
+ else
+ case state is
+ when waiting =>
+ wordcounter <= 0;
+ spi_data_to_chip <= '0';
+ spi_clk <= '0';
+ spi_ld <= '0';
+ state <= waiting;
+ shiftregister_in <= (others => '0');
+ if start_write = '1' then
+ shiftregister_out <= spi_data_in;
+ state <= sendbit1;
+ end if;
+ when sendbit1 => --pull clock low and shift out new bit
+ spi_clk <= '0';
+ spi_data_to_chip <= shiftregister_out(data_length - 1);
+ if (clk_enable = '1') then
+ shiftregister_out(data_length - 1 downto 1) <= shiftregister_out(data_length - 2 downto 0);
+ shiftregister_out(0) <= '0';
+ state <= sendbit2;
+ end if;
+ when sendbit2 => --pull clock high
+ spi_clk <= '1';
+ if (clk_enable = '1') then
+ shiftregister_in <= shiftregister_in(data_length - 2 downto 0) & spi_data_from_chip;
+ if (wordcounter = data_length - 1) then -- we are done...
+ state <= loading1;
+ else
+ state <= sendbit1;
+ wordcounter <= wordcounter + 1;
+ end if;
+ end if;
+ when loading1 =>
+ spi_clk <= '1';
+ spi_ld <= '1';
+ if (clk_enable = '1') then
+ state <= loading2;
+ end if;
+ when loading2 =>
+ spi_clk <= '0';
+ spi_ld <= '1';
+ spi_data_to_chip <= '0';
+ if (clk_enable = '1') then
+ state <= waiting;
+ spi_data_out <= shiftregister_in;
+ end if;
+ end case;
+ end if;
+ end if;
+ end process shift_out_proc;
+
+
+end rtl;
--- /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.trb_net_std.all;
+use work.trb_net_components.all;
+use work.trb3_components.all;
+
+use work.StdTypes.all;
+
+entity MupixBoard is
+ port(
+ --Clock signal
+ clk : in std_logic;
+ fast_clk : in std_logic;
+ reset : in std_logic;
+
+ --slow control signals
+ testpulse : out std_logic; --generate injection pulse
+ ctrl_din : out std_logic; --serial data to mupix
+ ctrl_clk1 : out std_logic; --slow control clk1
+ ctrl_clk2 : out std_logic; --slow control clk2
+ ctrl_ld : out std_logic; --slow control load latched data
+ ctrl_dout : in std_logic; --serial data from mupix
+ ctrl_rb : out std_logic; --slow control readback??
+ spi_dout_adc : in std_logic; --adc serial data from board
+ spi_dout_dac : in std_logic; --dac serial data from board
+ dac4_dout : in std_logic; --serial data in from threshold dac
+ spi_clk : out std_logic; --serial clock
+ spi_din : out std_logic; --serial data out
+ spi_ld_tmp_dac : out std_logic; --load temperature dac
+ spi_ld_adc : out std_logic; --load adc
+ spi_ld_thres : out std_logic; --load threshold and injection dac
+ --slow data signals
+ hitbus : in std_logic; --hitbus signal
+ hit : in std_logic; --hit signal (replacement for priout?)
+ ldcol : out std_logic; --load column
+ rdcol : out std_logic; --read column
+ pull_down : out std_logic; --pull down
+ ldpix : out std_logic; --load pixel
+ --fast data signals
+ clkref : out std_logic; --reference clock
+ clkext : out std_logic; --external clock (difference to first one?)
+ syncres : out std_logic; --sync something
+ trigger : in std_logic; --external trigger
+ --data
+ data1_P : in std_logic; --data 1
+ data1_N : in std_logic;
+ data2_P : in std_logic; --data 2
+ data2_N : in std_logic;
+ data3_P : in std_logic; --data 3
+ data3_N : in std_logic;
+ data4_P : in std_logic; --this channel is muxed version of other three
+ data4_N : in std_logic;
+
+ --resets
+ timestampreset_in : in std_logic; --time stamp reset
+ eventcounterreset_in : in std_logic; --event number reset
+
+ --TRB trigger connections
+ TIMING_TRG_IN : in std_logic;
+ 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);
+
+ --TRB data connections
+ 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;
+
+ --TRB slow control connections
+ 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 MupixBoard;
+
+
+architecture Behavioral of MupixBoard is
+
+ component MupixBoardInterface
+ port(
+ clk_in : in std_logic;
+ fast_clk_in : in std_logic;
+ reset : in std_logic;
+ --input signals from mupix sensorboard
+ ctrl_dout : in std_logic; --serial data from mupix
+ spi_dout_adc : in std_logic; --adc serial data from board
+ spi_dout_dac : in std_logic; --dac serial data from board
+ dac4_dout : in std_logic; --serial data in from dac 4??
+ hitbus : in std_logic; --hitbus signal
+ hit : in std_logic; --hit signal (replacement for priout?)
+ trigger : in std_logic; --external trigger
+ --synchronized signals to FPGA logic
+ ctrl_dout_sync : out std_logic;
+ spi_dout_adc_sync : out std_logic;
+ spi_dout_dac_sync : out std_logic;
+ dac4_dout_sync : out std_logic;
+ hitbus_sync : out std_logic;
+ trigger_sync : out std_logic;
+ hitbus_sync_fast : out std_logic; --sampled with 200 MHz clock
+ trigger_sync_fast : out std_logic; --sampled with 200 MHz clock
+ hit_sync : out std_logic);
+ end component MupixBoardInterface;
+
+ signal ctrl_dout_sync : std_logic;
+ signal spi_dout_adc_sync : std_logic;
+ signal spi_dout_dac_sync : std_logic;
+ signal dac4_dout_sync : std_logic;
+ signal hitbus_sync : std_logic;
+ signal trigger_sync : std_logic;
+ signal hitbus_sync_fast : std_logic; --sampled with 200 MHz clock
+ signal trigger_sync_fast : std_logic; --sampled with 200 MHz clock
+ signal hit_sync : std_logic;
+
+ component HitbusHistogram
+ generic(
+ HistogramRange : integer;
+ PostOscillationWaitCycles : integer);
+ port(
+ clk : in std_logic;
+ hitbus : in std_logic;
+ trigger : in std_logic;
+ SLV_READ_IN : in std_logic;
+ SLV_WRITE_IN : in std_logic;
+ SLV_DATA_OUT : out std_logic_vector(31 downto 0);
+ SLV_DATA_IN : in std_logic_vector(31 downto 0);
+ SLV_ADDR_IN : in std_logic_vector(15 downto 0);
+ SLV_ACK_OUT : out std_logic;
+ SLV_NO_MORE_DATA_OUT : out std_logic;
+ SLV_UNKNOWN_ADDR_OUT : out std_logic
+ );
+ end component HitbusHistogram;
+
+ component PixelControl
+ generic(
+ fpga_clk_speed : integer;
+ spi_clk_speed : integer
+ );
+ port(
+ clk : in std_logic; --clock
+ reset : in std_logic; --reset
+ --mupix control
+ ctrl_din : out std_logic; --serial data to mupix
+ ctrl_clk1 : out std_logic; --slow control clock 1
+ ctrl_clk2 : out std_logic; --slow control clock 2
+ ctrl_load : out std_logic; --slow control load
+ ctrl_dout : in std_logic; --serial data from mupix
+ --TRB slow control
+ SLV_READ_IN : in std_logic;
+ SLV_WRITE_IN : in std_logic;
+ SLV_DATA_OUT : out std_logic_vector(31 downto 0);
+ SLV_DATA_IN : in std_logic_vector(31 downto 0);
+ SLV_ADDR_IN : in std_logic_vector(15 downto 0);
+ SLV_ACK_OUT : out std_logic;
+ SLV_NO_MORE_DATA_OUT : out std_logic;
+ SLV_UNKNOWN_ADDR_OUT : out std_logic);
+ end component PixelControl;
+
+ constant fpga_clk_speed : integer := 1e8; --100 MHz
+ constant mupix_spi_clk_speed : integer := 5e4;--50 kHz
+
+ component MupixBoardDAC is
+ port(
+ clk : in std_logic; --clock
+ reset : in std_logic; --reset
+ --DAC signals
+ spi_dout_dac : in std_logic; --dac serial data from board
+ dac4_dout : in std_logic; --serial data in from threshold dac
+ spi_dout_adc : in std_logic; --adc serial data from board
+ spi_clk : out std_logic; --serial clock
+ spi_din : out std_logic; --serial data out
+ spi_ld_tmp_dac : out std_logic; --load temperature dac
+ spi_ld_thres : out std_logic; --load threshold and injection dac
+ spi_ld_adc : out std_logic; --load adc
+ --TRB slow control
+ SLV_READ_IN : in std_logic;
+ SLV_WRITE_IN : in std_logic;
+ SLV_DATA_OUT : out std_logic_vector(31 downto 0);
+ SLV_DATA_IN : in std_logic_vector(31 downto 0);
+ SLV_ADDR_IN : in std_logic_vector(15 downto 0);
+ SLV_ACK_OUT : out std_logic;
+ SLV_NO_MORE_DATA_OUT : out std_logic;
+ SLV_UNKNOWN_ADDR_OUT : out std_logic);
+ end component MupixBoardDAC;
+
+--signal declarations
+-- Bus Handler
+ constant NUM_PORTS : integer := 3;
+
+ signal slv_read : std_logic_vector(NUM_PORTS-1 downto 0);
+ signal slv_write : std_logic_vector(NUM_PORTS-1 downto 0);
+ signal slv_no_more_data : std_logic_vector(NUM_PORTS-1 downto 0);
+ signal slv_ack : std_logic_vector(NUM_PORTS-1 downto 0);
+ signal slv_addr : std_logic_vector(NUM_PORTS*16-1 downto 0);
+ signal slv_data_rd : std_logic_vector(NUM_PORTS*32-1 downto 0);
+ signal slv_data_wr : std_logic_vector(NUM_PORTS*32-1 downto 0);
+ signal slv_unknown_addr : std_logic_vector(NUM_PORTS-1 downto 0);
+
+
+
+begin -- Behavioral
+
+-------------------------------------------------------------------------------
+-- Port Maps
+-------------------------------------------------------------------------------
+
+ THE_BUS_HANDLER : trb_net16_regio_bus_handler
+ generic map(
+ PORT_NUMBER => NUM_PORTS,
+
+ PORT_ADDRESSES => (
+ 0 => x"0070", -- Hitbus Histograms
+ 1 => x"0080", -- Mupix DAC and Pixel Control
+ 2 => x"0090", -- Board Control
+ others => x"0000"),
+ PORT_ADDR_MASK => (
+ 0 => 4, -- HitBus Histograms
+ 1 => 4, -- Mupix DAC and Pixel Control
+ 2 => 4, -- Board Control
+ others => 0)
+ --PORT_MASK_ENABLE => 1
+ )
+ port map(
+ CLK => CLK,
+ RESET => RESET,
+
+ DAT_ADDR_IN => REGIO_ADDR_IN,
+ DAT_DATA_IN => REGIO_DATA_IN,
+ DAT_DATA_OUT => REGIO_DATA_OUT,
+ DAT_READ_ENABLE_IN => REGIO_READ_ENABLE_IN,
+ DAT_WRITE_ENABLE_IN => REGIO_WRITE_ENABLE_IN,
+ DAT_TIMEOUT_IN => REGIO_TIMEOUT_IN,
+ DAT_DATAREADY_OUT => REGIO_DATAREADY_OUT,
+ DAT_WRITE_ACK_OUT => REGIO_WRITE_ACK_OUT,
+ DAT_NO_MORE_DATA_OUT => REGIO_NO_MORE_DATA_OUT,
+ DAT_UNKNOWN_ADDR_OUT => REGIO_UNKNOWN_ADDR_OUT,
+
+ -- Control Registers
+ BUS_READ_ENABLE_OUT => slv_read,
+ BUS_WRITE_ENABLE_OUT => slv_write,
+ BUS_DATA_OUT => slv_data_wr,
+ BUS_DATA_IN => slv_data_rd,
+ BUS_ADDR_OUT => slv_addr,
+ BUS_TIMEOUT_OUT => open,
+ BUS_DATAREADY_IN => slv_ack,
+ BUS_WRITE_ACK_IN => slv_ack,
+ BUS_NO_MORE_DATA_IN => slv_no_more_data,
+ BUS_UNKNOWN_ADDR_IN => slv_unknown_addr,
+
+ -- DEBUG
+ STAT_DEBUG => open
+ );
+
+ mupixboardinterface_1 : component MupixBoardInterface
+ port map(
+ clk_in => clk,
+ fast_clk_in => fast_clk,
+ reset => reset,
+ ctrl_dout => ctrl_dout,
+ spi_dout_adc => spi_dout_adc,
+ spi_dout_dac => spi_dout_dac,
+ dac4_dout => dac4_dout,
+ hitbus => hitbus,
+ hit => hit,
+ trigger => trigger,
+ ctrl_dout_sync => ctrl_dout_sync,
+ spi_dout_adc_sync => spi_dout_adc_sync,
+ spi_dout_dac_sync => spi_dout_dac_sync,
+ dac4_dout_sync => dac4_dout_sync,
+ hitbus_sync => hitbus_sync,
+ trigger_sync => trigger_sync,
+ hitbus_sync_fast => hitbus_sync_fast,
+ trigger_sync_fast => trigger_sync_fast,
+ hit_sync => hit_sync
+ );
+
+ hitbushistogram_1 : component HitbusHistogram
+ generic map(
+ HistogramRange => 10,
+ PostOscillationWaitCycles => 5
+ )
+ port map(
+ clk => clk,
+ hitbus => hitbus_sync,
+ trigger => trigger_sync,
+ SLV_READ_IN => slv_read(0),
+ SLV_WRITE_IN => slv_write(0),
+ SLV_DATA_OUT => slv_data_rd(0*32 + 31 downto 0*32),
+ SLV_DATA_IN => slv_data_wr(0*32 + 31 downto 0*32),
+ SLV_ADDR_IN => slv_addr(0*16 + 15 downto 0*16),
+ SLV_ACK_OUT => slv_ack(0),
+ SLV_NO_MORE_DATA_OUT => slv_no_more_data(0),
+ SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(0)
+ );
+
+ pixelcontrol_1 : component PixelControl
+ generic map(
+ fpga_clk_speed => fpga_clk_speed,
+ spi_clk_speed => mupix_spi_clk_speed
+ )
+ port map(
+ clk => clk,
+ reset => reset,
+ ctrl_din => ctrl_din,
+ ctrl_clk1 => ctrl_clk1,
+ ctrl_clk2 => ctrl_clk2,
+ ctrl_load => ctrl_ld,
+ ctrl_dout => ctrl_dout_sync,
+ SLV_READ_IN => slv_read(1),
+ SLV_WRITE_IN => slv_write(1),
+ SLV_DATA_OUT => slv_data_rd(1*32 + 31 downto 1*32),
+ SLV_DATA_IN => slv_data_wr(1*32 + 31 downto 1*32),
+ SLV_ADDR_IN => slv_addr(1*16 + 15 downto 1*16),
+ SLV_ACK_OUT => slv_ack(1),
+ SLV_NO_MORE_DATA_OUT => slv_no_more_data(1),
+ SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(1)
+ );
+
+ boardcontrol_1 : component MupixBoardDAC
+ port map(
+ clk => clk,
+ reset => reset,
+ spi_dout_dac => spi_dout_dac_sync,
+ dac4_dout => dac4_dout_sync,
+ spi_dout_adc => spi_dout_adc_sync,
+ spi_clk => spi_clk,
+ spi_din => spi_din,
+ spi_ld_tmp_dac => spi_ld_tmp_dac,
+ spi_ld_thres => spi_ld_thres,
+ spi_ld_adc => spi_ld_adc,
+ SLV_READ_IN => slv_read(2),
+ SLV_WRITE_IN => slv_write(2),
+ SLV_DATA_OUT => slv_data_rd(2*32 + 31 downto 2*32),
+ SLV_DATA_IN => slv_data_wr(2*32 + 31 downto 2*32),
+ SLV_ADDR_IN => slv_addr(2*16 + 15 downto 2*16),
+ SLV_ACK_OUT => slv_ack(2),
+ SLV_NO_MORE_DATA_OUT => slv_no_more_data(2),
+ SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(2)
+ );
+
+end Behavioral;
--- /dev/null
+-----------------------------------------------------------------------------------
+-- Collection of all SPI interfaces controlling threshold, injection and other DACs
+-- Tobias Weber
+-- Ruhr Unversitaet Bochum
+------------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity MupixBoardDAC is
+ port(
+ clk : in std_logic; --clock
+ reset : in std_logic; --reset
+ --DAC signals
+ spi_dout_dac : in std_logic; --dac serial data from board
+ dac4_dout : in std_logic; --serial data in from threshold dac
+ spi_dout_adc : in std_logic; --adc serial data from board
+ spi_clk : out std_logic; --serial clock
+ spi_din : out std_logic; --serial data out
+ spi_ld_tmp_dac : out std_logic; --load temperature dac
+ spi_ld_thres : out std_logic; --load threshold and injection dac
+ spi_ld_adc : out std_logic; --load adc
+ --TRB slow control
+ SLV_READ_IN : in std_logic;
+ SLV_WRITE_IN : in std_logic;
+ SLV_DATA_OUT : out std_logic_vector(31 downto 0);
+ SLV_DATA_IN : in std_logic_vector(31 downto 0);
+ SLV_ADDR_IN : in std_logic_vector(15 downto 0);
+ SLV_ACK_OUT : out std_logic;
+ SLV_NO_MORE_DATA_OUT : out std_logic;
+ SLV_UNKNOWN_ADDR_OUT : out std_logic);
+end entity MupixBoardDAC;
+
+architecture RTL of MupixBoardDAC is
+
+ component LTC1658SPI
+ generic(
+ data_length : integer;
+ fpga_clock_speed : integer;
+ spi_clock_speed : integer
+ );
+ port(
+ clk : in std_logic;
+ reset : in std_logic;
+ start_write : in std_logic;
+ spi_data_in : in std_logic_vector(data_length - 1 downto 0);
+ spi_data_from_chip : in std_logic;
+ spi_data_to_chip : out std_logic;
+ spi_data_out : out std_logic_vector(data_length - 1 downto 0);
+ spi_clk : out std_logic;
+ spi_ld : out std_logic
+ );
+ end component LTC1658SPI;
+
+ component ADS1018SPI
+ generic(
+ fpga_clock_speed : integer := 1e8;
+ spi_clock_speed : integer := 1e4
+ );
+ port(
+ clk : in std_logic;
+ reset : in std_logic;
+ start_write : in std_logic;
+ config_in : in std_logic_vector(15 downto 0);
+ spi_data_from_chip : in std_logic;
+ spi_data_to_chip : out std_logic;
+ spi_data_out : out std_logic_vector(31 downto 0);
+ spi_clk : out std_logic;
+ spi_ld : out std_logic
+ );
+ end component ADS1018SPI;
+
+ constant c_bits_threshold_dacs : integer := 64;--4*16 bit of the four DACs
+ signal start_write_threshold : std_logic;
+ signal spi_data_in_threshold : std_logic_vector(c_bits_threshold_dacs - 1 downto 0);
+ signal spi_data_to_chip_threshold : std_logic;
+ signal spi_data_out_threshold : std_logic_vector(c_bits_threshold_dacs - 1 downto 0);
+ signal spi_clk_threshold : std_logic;
+
+ constant c_bits_temperature_dac : integer := 16;
+ signal start_write_temperature : std_logic;
+ signal spi_data_in_temperature : std_logic_vector(c_bits_temperature_dac - 1 downto 0);
+ signal spi_data_to_chip_temperature : std_logic;
+ signal spi_data_out_temperature : std_logic_vector(c_bits_temperature_dac - 1 downto 0);
+ signal spi_clk_temperature_temperature : std_logic;
+
+ signal start_write_adc : std_logic;
+ signal config_adc : std_logic_vector(15 downto 0);
+ signal spi_data_to_chip_adc : std_logic;
+ signal spi_data_out_adc : std_logic_vector(31 downto 0);
+ signal spi_clk_adc : std_logic;
+
+
+
+begin
+
+ spi_din <= spi_data_to_chip_threshold or spi_data_to_chip_temperature or spi_data_to_chip_adc;
+ spi_clk <= spi_clk_threshold or spi_clk_temperature_temperature or spi_clk_adc;
+
+ threshold_injection_dac : entity work.LTC1658SPI
+ generic map(
+ data_length => c_bits_threshold_dacs,
+ fpga_clock_speed => 1e8, --100 MHz
+ spi_clock_speed => 5e4 --50 kHz
+ )
+ port map(
+ clk => clk,
+ reset => reset,
+ start_write => start_write_threshold,
+ spi_data_in => spi_data_in_threshold,
+ spi_data_from_chip => dac4_dout,
+ spi_data_to_chip => spi_data_to_chip_threshold,
+ spi_data_out => spi_data_out_threshold,
+ spi_clk => spi_clk_threshold,
+ spi_ld => spi_ld_thres
+ );
+
+ temperature_dac : entity work.LTC1658SPI
+ generic map(
+ data_length => c_bits_temperature_dac,
+ fpga_clock_speed => 1e8, --100 MHz
+ spi_clock_speed => 5e4 --50 kHz
+ )
+ port map(
+ clk => clk,
+ reset => reset,
+ start_write => start_write_temperature,
+ spi_data_in => spi_data_in_temperature,
+ spi_data_from_chip => spi_dout_dac,
+ spi_data_to_chip => spi_data_to_chip_temperature,
+ spi_data_out => spi_data_out_temperature,
+ spi_clk => spi_clk_temperature_temperature,
+ spi_ld => spi_ld_tmp_dac
+ );
+
+
+ temperature_adc : component ADS1018SPI
+ generic map(
+ fpga_clock_speed => 1e8,
+ spi_clock_speed => 5e4
+ )
+ port map(
+ clk => clk,
+ reset => reset,
+ start_write => start_write_adc,
+ config_in => config_adc,
+ spi_data_from_chip => spi_dout_adc,
+ spi_data_to_chip => spi_data_to_chip_adc,
+ spi_data_out => spi_data_out_adc,
+ spi_clk => spi_clk_adc,
+ spi_ld => spi_ld_adc
+ );
+ -----------------------------------------------------------------------------
+ --TRB Slave Bus
+ --0x0090: threshold high and low dacs, 31:16 threshold high, 15:0 threshold low
+ --0x0091: threshold pix dac and injection dac, 31:16 pix dac, 15:0 injection dac
+ --0x0092: readback threshold high and low dacs, 31:16 threshold high, 15:0 threshold low
+ --0x0093: readback threshold pix dac and injection dac, 31:16 pix dac, 15:0 injection dac
+ --0x0094: temperature dac
+ --0x0095: readback temperature dac
+ --0x0096: start write threshold and injection dacs bit
+ -----------------------------------------------------------------------------
+ SLV_BUS_HANDLER : process(clk)
+ begin -- process SLV_BUS_HANDLER
+ if rising_edge(clk) then
+ SLV_DATA_OUT <= (others => '0');
+ SLV_ACK_OUT <= '0';
+ SLV_UNKNOWN_ADDR_OUT <= '0';
+ SLV_NO_MORE_DATA_OUT <= '0';
+ start_write_threshold <= '0';
+
+ if SLV_READ_IN = '1' then
+ case SLV_ADDR_IN is
+ when x"0090" =>
+ SLV_DATA_OUT <= spi_data_in_threshold(63 downto 32);
+ SLV_ACK_OUT <= '1';
+ when x"0091" =>
+ SLV_DATA_OUT <= spi_data_in_threshold(31 downto 0);
+ SLV_ACK_OUT <= '1';
+ when x"0092" =>
+ SLV_DATA_OUT <= spi_data_out_threshold(63 downto 32);
+ SLV_ACK_OUT <= '1';
+ when x"0093" =>
+ SLV_DATA_OUT <= spi_data_out_threshold(31 downto 0);
+ SLV_ACK_OUT <= '1';
+ when x"0094" =>
+ SLV_DATA_OUT(15 downto 0) <= spi_data_in_temperature;
+ SLV_ACK_OUT <= '1';
+ when x"0095" =>
+ SLV_DATA_OUT(15 downto 0) <= spi_data_out_temperature;
+ SLV_ACK_OUT <= '1';
+ when others =>
+ SLV_UNKNOWN_ADDR_OUT <= '1';
+ end case;
+
+ elsif SLV_WRITE_IN = '1' then
+ case SLV_ADDR_IN is
+ when x"0090" =>
+ spi_data_in_threshold(63 downto 32) <= SLV_DATA_IN;
+ SLV_ACK_OUT <= '1';
+ when x"0091" =>
+ spi_data_in_threshold(31 downto 0) <= SLV_DATA_IN;
+ SLV_ACK_OUT <= '1';
+ when x"0094" =>
+ spi_data_in_temperature <= SLV_DATA_IN(15 downto 0);
+ start_write_temperature <= '1';
+ SLV_ACK_OUT <= '1';
+ when x"0096" =>
+ start_write_threshold <= '1';
+ SLV_ACK_OUT <= '1';
+ when others =>
+ SLV_UNKNOWN_ADDR_OUT <= '1';
+ end case;
+
+ end if;
+ end if;
+ end process SLV_BUS_HANDLER;
+
+end architecture RTL;
--- /dev/null
+----------------------------------------------------------------------------
+-- Synchronize signals from mupix board
+-- Tobias Weber
+-- Ruhr Unversitaet Bochum
+-----------------------------------------------------------------------------
+
+library ieee;
+use ieee.numeric_std.all;
+use ieee.std_logic_1164.all;
+
+entity MupixBoardInterface is
+ port(
+ clk_in : in std_logic; --slow clock
+ fast_clk_in : in std_logic; --fast clock
+ reset : in std_logic; --reset signal
+ --input signals from mupix sensorboard
+ ctrl_dout : in std_logic; --serial data from mupix
+ spi_dout_adc : in std_logic; --adc serial data from board
+ spi_dout_dac : in std_logic; --dac serial data from board
+ dac4_dout : in std_logic; --serial data in from dac 4??
+ hitbus : in std_logic; --hitbus signal
+ hit : in std_logic; --hit signal (replacement for priout?)
+ trigger : in std_logic; --external trigger
+ --synchronized signals to FPGA logic
+ ctrl_dout_sync : out std_logic;
+ spi_dout_adc_sync : out std_logic;
+ spi_dout_dac_sync : out std_logic;
+ dac4_dout_sync : out std_logic;
+ hitbus_sync : out std_logic;
+ trigger_sync : out std_logic;
+ hitbus_sync_fast : out std_logic; --sampled with 200 MHz clock
+ trigger_sync_fast : out std_logic; --sampled with 200 MHz clock
+ hit_sync : out std_logic);
+end entity MupixBoardInterface;
+
+
+architecture rtl of MupixBoardInterface is
+
+
+ component InputSynchronizer
+ generic(depth : integer);
+ port(
+ clk : in std_logic;
+ rst : in std_logic;
+ input : in std_logic;
+ sync_output : out std_logic
+ );
+ end component InputSynchronizer;
+
+begin
+
+ sync_ctrl_dout : component InputSynchronizer
+ generic map(depth => 2)
+ port map(clk_in, reset, ctrl_dout, ctrl_dout_sync);
+
+ sync_spi_dout_adc : component InputSynchronizer
+ generic map(depth => 2)
+ port map(clk_in, reset, spi_dout_adc, spi_dout_adc_sync);
+
+ sync_spi_dout_dac : component InputSynchronizer
+ generic map(depth => 2)
+ port map(clk_in, reset, spi_dout_dac, spi_dout_dac_sync);
+
+ sync_dac4_dout : component InputSynchronizer
+ generic map(depth => 2)
+ port map(clk_in, reset, dac4_dout, dac4_dout_sync);
+
+ sync_hitbus : component InputSynchronizer
+ generic map(depth => 2)
+ port map(clk_in, reset, hitbus, hitbus_sync);
+
+ sync_trigger : component InputSynchronizer
+ generic map(depth => 2)
+ port map(clk_in, reset, trigger, trigger_sync);
+
+ sync_hit : component InputSynchronizer
+ generic map(depth => 2)
+ port map(clk_in, reset, hit, hit_sync);
+
+ sync_fast_hitbus : component InputSynchronizer
+ generic map(depth => 2)
+ port map(fast_clk_in, reset, hitbus, hitbus_sync_fast);
+
+ sync_fast_trigger : component InputSynchronizer
+ generic map(depth => 2)
+ port map(fast_clk_in, reset, trigger, trigger_sync_fast);
+
+end architecture rtl;
--- /dev/null
+-------------------------------------------------------------------------------
+--Control of MuPix DACs and Pixel Tune DACs
+--T. Weber, Mainz Univesity
+-------------------------------------------------------------------------------
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.numeric_std.all;
+
+entity PixelControl is
+ generic(
+ fpga_clk_speed : integer := 1e8;
+ spi_clk_speed : integer := 1e4
+ );
+ port (
+ clk : in std_logic; --clock
+ reset : in std_logic; --reset
+ --mupix control
+ ctrl_din : out std_logic; --serial data to mupix
+ ctrl_clk1 : out std_logic; --slow control clock 1
+ ctrl_clk2 : out std_logic; --slow control clock 2
+ ctrl_load : out std_logic; --slow control load
+ ctrl_dout : in std_logic; --serial data from mupix
+ --TRB slow control
+ SLV_READ_IN : in std_logic;
+ SLV_WRITE_IN : in std_logic;
+ SLV_DATA_OUT : out std_logic_vector(31 downto 0);
+ SLV_DATA_IN : in std_logic_vector(31 downto 0);
+ SLV_ADDR_IN : in std_logic_vector(15 downto 0);
+ SLV_ACK_OUT : out std_logic;
+ SLV_NO_MORE_DATA_OUT : out std_logic;
+ SLV_UNKNOWN_ADDR_OUT : out std_logic);
+end PixelControl;
+
+architecture Behavioral of PixelControl is
+
+ constant fifo_word_width : integer := 32;
+
+ signal bitcounter : unsigned(15 downto 0) := (others => '0');--number of transmitted configuration bits
+ signal bitstosend : unsigned(15 downto 0) := (others => '0');--number of bits which need to be send
+ signal bitcouner_word : integer range 0 to fifo_word_width - 1 := 0; --index to current bit in word from fifo
+ signal controlConfig : std_logic_vector(15 downto 0) := (others => '0');--configuration control
+
+ --fifos storage of configuration bits
+ component STD_FIFO
+ generic(
+ DATA_WIDTH : positive := 8;
+ FIFO_DEPTH : positive := 256
+ );
+ port(
+ CLK : in std_logic;
+ RST : in std_logic;
+ WriteEn : in std_logic;
+ DataIn : in std_logic_vector(fifo_word_width - 1 downto 0);
+ ReadEn : in std_logic;
+ DataOut : out std_logic_vector(fifo_word_width - 1 downto 0);
+ Empty : out std_logic;
+ Full : out std_logic
+ );
+ end component STD_FIFO;
+
+ component CRC
+ generic(
+ detect_enable_edge : boolean := false
+ );
+ port(
+ clk : in std_logic;
+ rst : in std_logic;
+ enable : in std_logic;
+ data_in : in std_logic;
+ crc_out : out std_logic_vector(4 downto 0)
+ );
+ end component CRC;
+
+ signal WriteEn : std_logic;
+ signal DataIn : std_logic_vector (fifo_word_width - 1 downto 0);
+ signal ReadEn : std_logic;
+ signal DataOut : std_logic_vector (fifo_word_width - 1 downto 0);
+ signal Empty : std_logic;
+ signal Full : std_logic;
+
+ --clock enable signals
+ signal clk_enable : std_logic := '0';
+ constant clk_div_max : integer := fpga_clk_speed/spi_clk_speed - 1;
+ signal clk_div_counter : integer range 0 to clk_div_max := clk_div_max;
+
+ --send single configuration bit
+ type bit_send_fsm_type is (idle, sendbit1, sendbit2, sendbit3);
+ signal bit_send_fsm : bit_send_fsm_type := idle;
+ signal start_send, sending : std_logic;
+
+ --configuration state machine
+ type config_fsm_type is (idle, config, readfifo, waitfifo, load);
+ signal config_fsm : config_fsm_type := idle;
+
+ --check sum for data integrity
+ signal crc_correct : std_logic;
+ signal enable_crc_to_mupix : std_logic;
+ signal data_in_crc_to_mupix : std_logic;
+ signal crc_out_crc_to_mupix : std_logic_vector(4 downto 0);
+ signal reset_crc_to_mupix : std_logic;
+ signal enable_crc_from_mupix : std_logic;
+ signal data_in_crc_from_mupix : std_logic;
+ signal crc_out_crc_from_mupix : std_logic_vector(4 downto 0);
+ signal reset_crc_from_mupix : std_logic;
+
+ --control signals to mupix
+ signal mupix_ctrl_i, mupix_ctrl_reg : MupixSlowControl := MuPixSlowControlInit;
+
+
+begin -- Behavioral
+
+ fifo_1 : entity work.STD_FIFO
+ generic map(
+ DATA_WIDTH => fifo_word_width,
+ FIFO_DEPTH => 32
+ )
+ port map(
+ CLK => CLK,
+ RST => reset,
+ WriteEn => WriteEn,
+ DataIn => DataIn,
+ ReadEn => ReadEn,
+ DataOut => DataOut,
+ Empty => Empty,
+ Full => Full
+ );
+
+ --TODO: CRC checking logic
+ crc_in : entity work.CRC
+ generic map(detect_enable_edge => true)
+ port map(
+ clk => clk,
+ rst => reset_crc_to_mupix,
+ enable => enable_crc_to_mupix,
+ data_in => data_in_crc_to_mupix,
+ crc_out => crc_out_crc_to_mupix
+ );
+
+ reset_crc_to_mupix <= reset or controlConfig(2);
+
+ crc_out : entity work.CRC
+ generic map(detect_enable_edge => true)
+ port map(
+ clk => clk,
+ rst => reset_crc_from_mupix,
+ enable => enable_crc_from_mupix,
+ data_in => data_in_crc_from_mupix,
+ crc_out => crc_out_crc_from_mupix
+ );
+
+ reset_crc_from_mupix <= reset or controlConfig(3);
+
+ spi_clk_div_proc : process (clk) is
+ begin
+ if rising_edge(clk) then
+ if reset = '1' then
+ clk_enable <= '0';
+ clk_div_counter <= clk_div_max;
+ else
+ if clk_div_counter = 0 then
+ clk_div_counter <= clk_div_max;
+ clk_enable <= '1';
+ else
+ clk_div_counter <= clk_div_counter - 1;
+ clk_enable <= '0';
+ end if;
+ end if;
+ end if;
+ end process spi_clk_div_proc;
+
+
+ sendpixbit_proc : process (clk) is
+ begin
+ if rising_edge(clk) then
+ if reset = '1' then
+ mupix_ctrl_i.ck_c <= '0';
+ mupix_ctrl_i.ck_d <= '0';
+ mupix_ctrl_i.sin <= '0';
+ sending <= '0';
+ bit_send_fsm <= idle;
+ bitcounter <= (others => '0');
+ bitcouner_word <= fifo_word_width - 1;
+ else
+ if clk_enable = '1' then
+ mupix_ctrl_i.ck_c <= '0';
+ mupix_ctrl_i.ck_d <= '0';
+ mupix_ctrl_i.sin <= '0';
+ enable_crc_to_mupix <= '0';
+ enable_crc_from_mupix <= '0';
+ data_in_crc_from_mupix <= '0';
+ data_in_crc_to_mupix <= '0';
+ case bit_send_fsm is
+ when idle =>
+ bitcouner_word <= fifo_word_width - 1;
+ if start_send = '1' then
+ bit_send_fsm <= sendbit1;
+ sending <= '1';
+ else
+ bit_send_fsm <= idle;
+ sending <= '0';
+ end if;
+ when sendbit1 =>
+ mupix_ctrl_i.sin <= DataOut(bitcouner_word);
+ sending <= '1';
+ bit_send_fsm <= sendbit2;
+ when sendbit2 => --rising clock edge
+ mupix_ctrl_i.sin <= DataOut(bitcouner_word);
+ if controlConfig(0) = '1' then
+ mupix_ctrl_i.ck_d <= '1';
+ else
+ mupix_ctrl_i.ck_c <= '1';
+ end if;
+ enable_crc_to_mupix <= '1';
+ data_in_crc_to_mupix <= DataOut(bitcouner_word);
+ bit_send_fsm <= sendbit3;
+ sending <= '1';
+ when sendbit3 =>
+ sending <= '1';
+ mupix_ctrl_i.sin <= DataOut(bitcouner_word);
+ enable_crc_from_mupix <= '1';
+ if controlConfig(0) = '1' then
+ data_in_crc_from_mupix <= sout_d_from_mupix;
+ else
+ data_in_crc_from_mupix <= sout_c_from_mupix;
+ end if;
+ bitcouner_word <= bitcouner_word - 1;
+ bitcounter <= bitcounter + 1;
+ if bitcouner_word = 0 or bitcounter = bitstosend then
+ bit_send_fsm <= idle;
+ else
+ bit_send_fsm <= sendbit1;
+ end if;
+ end case;
+ end if;
+ end if;
+ end if;
+ end process sendpixbit_proc;
+
+
+ configure_proc : process (clk) is
+ variable hold_load_counter : integer range 0 to 7;
+ begin
+ if rising_edge(clk) then
+ if reset = '1' then
+ mupix_ctrl_i.ld_c <= '0';
+ config_fsm <= idle;
+ hold_load_counter := 0;
+ else
+ mupix_ctrl_i.ld_c <= '0';
+ ReadEn <= '0';
+ start_send <= '0';
+ case config_fsm is
+ when idle =>
+ hold_load_counter := 0;
+ if Empty = '0' then
+ config_fsm <= readfifo;
+ else
+ config_fsm <= idle;
+ end if;
+ when readfifo =>
+ if Empty = '0' then
+ ReadEn <= '1';
+ config_fsm <= waitfifo;
+ else
+ ReadEn <= '0';
+ config_fsm <= readfifo;
+ end if;
+ when waitfifo =>
+ config_fsm <= config;
+ if sending = '0' then
+ start_send <= '1';
+ config_fsm <= waitfifo;
+ else
+ start_send <= '0';
+ config_fsm <= config;
+ end if;
+ when config =>
+ if sending = '1' then
+ config_fsm <= config;
+ else
+ if bitcounter < bitstosend then
+ config_fsm <= readfifo;
+ else
+ if controlConfig(1) = '0' then
+ config_fsm <= load;
+ else
+ config_fsm <= idle;
+ end if;
+ end if;
+ end if;
+ when load =>
+ hold_load_counter := hold_load_counter + 1;
+ mupix_ctrl_i.ld_c <= '1';
+ if hold_load_counter = 7 then
+ mupix_ctrl_i.ld_c <= '0';
+ config_fsm <= idle;
+ else
+ config_fsm <= load;
+ end if;
+ end case;
+ end if;
+ end if;
+ end process configure_proc;
+
+
+ -----------------------------------------------------------------------------
+ --x0080: input to fifo (write)/current fifo output (read)
+ --x0081: current CRC check sum (read only)
+ --x0082: data fifo is full (read only)
+ --x0083: configure bit 0: configure chip dacs/pixel dacs,
+ -- bit 1: readback bit 32-16 number of config bits
+ -- bit 2: reset outgoing CRC sum
+ -- bit 3: reset incoming CRC sum
+ -----------------------------------------------------------------------------
+ SLV_BUS : process (clk)
+ begin -- process SLV_BUS
+ if rising_edge(clk) then
+
+ SLV_DATA_OUT <= (others => '0');
+ SLV_UNKNOWN_ADDR_OUT <= '0';
+ SLV_NO_MORE_DATA_OUT <= '0';
+ SLV_ACK_OUT <= '0';
+ DataIn <= (others => '0');
+ WriteEn <= '0';
+ if SLV_WRITE_IN = '1' then
+ case SLV_ADDR_IN is
+ when x"0080" =>
+ DataIn <= SLV_DATA_IN;
+ WriteEn <= '1';
+ SLV_ACK_OUT <= '1';
+ when x"0083" =>
+ controlConfig <= SLV_DATA_IN(15 downto 0);
+ bitstosend <= unsigned(SLV_DATA_IN(31 downto 16));
+ SLV_ACK_OUT <= '1';
+ when others =>
+ SLV_UNKNOWN_ADDR_OUT <= '1';
+ end case;
+
+ elsif SLV_READ_IN = '1' then
+ case SLV_ADDR_IN is
+ when x"0080" =>
+ SLV_DATA_OUT <= DataOut;
+ SLV_ACK_OUT <= '1';
+ when x"0081" =>
+ SLV_DATA_OUT(10 downto 0) <= crc_out_crc_from_mupix & crc_out_crc_to_mupix & crc_correct;
+ SLV_ACK_OUT <= '1';
+ when x"0082" =>
+ SLV_DATA_OUT(1 downto 0) <= Empty & Full;
+ SLV_ACK_OUT <= '1';
+ when x"0083" =>
+ SLV_DATA_OUT <= std_logic_vector(bitstosend) & controlConfig;
+ SLV_ACK_OUT <= '1';
+ when others =>
+ SLV_UNKNOWN_ADDR_OUT <= '1';
+ end case;
+ end if;
+ end if;
+ end process SLV_BUS;
+
+ crc_correct <= '1' when crc_out_crc_from_mupix = crc_out_crc_to_mupix else '0';
+
+ output_pipe : process (clk) is
+ begin
+ if rising_edge(clk) then
+ if reset = '1' then
+ mupix_ctrl_reg <= MuPixSlowControlInit;
+ else
+ mupix_ctrl_reg <= mupix_ctrl_i;
+ end if;
+ end if;
+ end process output_pipe;
+
+ --matching to outputs
+ mupix_ctrl <= mupix_ctrl_reg;
+
+end Behavioral;
+
+
--- /dev/null
+------------------------------------------------------------
+--Delay Signal for number of clock cycles given by delay_in
+--T. Weber
+------------------------------------------------------------
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.numeric_std.all;
+
+entity SignalDelay is
+ generic(
+ Width : integer := 1;
+ Delay : integer := 4 -- 2**Delay-1
+ );
+ port(
+ clk_in : in std_logic;
+ write_en_in : in std_logic;
+ delay_in : in std_logic_vector(Delay - 1 downto 0);
+ sig_in : in std_logic_vector(Width - 1 downto 0);
+ sig_out : out std_logic_vector(Width - 1 downto 0));
+end entity;
+
+architecture arch of SignalDelay is
+
+ signal writecounter : unsigned(Delay - 1 downto 0) := (others => '0');
+ signal readcounter : unsigned(Delay - 1 downto 0) := (others => '0');
+
+ type memory_t is array((2**Delay) - 1 downto 0) of std_logic_vector(Width - 1 downto 0);
+ signal memory : memory_t;
+
+begin
+
+ DelayProc : process(clk_in)
+ begin
+ if rising_edge(clk_in) then
+ if write_en_in = '1' then
+ memory(to_integer(writecounter)) <= sig_in;
+ writecounter <= writecounter + 1;
+ readcounter <= writecounter - unsigned(delay_in) + 2;
+ end if;
+ sig_out <= memory(to_integer(readcounter));
+ end if;
+ end process DelayProc;
+
+end architecture;
--- /dev/null
+-----------------------------------------------------------------------------
+-- MUPIX3 injection generator
+--
+-- Niklaus Berger, Heidelberg University
+-- nberger@physi.uni-heidelberg.de
+--
+-- Adepted to TRBv3 Readout: Tobias Weber, University Mainz
+-----------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity injection_generator is
+ port (
+ rst : in std_logic;
+ clk : in std_logic;
+ SLV_READ_IN : in std_logic;
+ SLV_WRITE_IN : in std_logic;
+ SLV_DATA_OUT : out std_logic_vector(31 downto 0);
+ SLV_DATA_IN : in std_logic_vector(31 downto 0);
+ SLV_ADDR_IN : in std_logic_vector(15 downto 0);
+ SLV_ACK_OUT : out std_logic;
+ SLV_NO_MORE_DATA_OUT : out std_logic;
+ SLV_UNKNOWN_ADDR_OUT : out std_logic;
+ testpulse1 : out std_logic;
+ testpulse2 : out std_logic
+ );
+end injection_generator;
+
+
+architecture rtl of injection_generator is
+
+ signal counter1 : unsigned(15 downto 0) := (others => '0');
+ signal counter2 : unsigned(15 downto 0) := (others => '0');
+
+ signal counter_from_slv : unsigned(31 downto 0);
+ signal slv_written : std_logic_vector(1 downto 0);
+
+
+ signal testpulse1_i : std_logic;
+ signal testpulse2_i : std_logic;
+ signal testpulse_busy : std_logic := '0';
+
+
+begin
+
+ process(clk, rst)
+ begin
+ if(rst = '1') then
+
+ testpulse1_i <= '0';
+ testpulse2_i <= '0';
+
+ elsif rising_edge(clk) then
+ if slv_written = "10" then
+ counter1 <= counter_from_slv(15 downto 0);
+ counter2 <= counter_from_slv(31 downto 16);
+ end if;
+
+ if(counter1 > x"0000") then
+ testpulse1_i <= '1';
+ counter1 <= counter1 - 1;
+ else
+ testpulse1_i <= '0';
+ end if;
+
+ if(counter2 > x"0000") then
+ testpulse2_i <= '1';
+ counter2 <= counter2 - 1;
+ else
+ testpulse2_i <= '0';
+ end if;
+
+ end if;
+ end process;
+
+ testpulse_busy <= '1' when testpulse2_i = '1' or testpulse1_i = '1' else '0';
+
+ SLV_HANDLER : process(clk)
+ begin
+ if rising_edge(clk) then
+ SLV_DATA_OUT <= (others => '0');
+ SLV_UNKNOWN_ADDR_OUT <= '0';
+ SLV_NO_MORE_DATA_OUT <= '0';
+ SLV_ACK_OUT <= '0';
+ slv_written <= slv_written(0) & SLV_WRITE_IN;
+
+ if SLV_READ_IN = '1' then
+ if SLV_ADDR_IN = x"0060" then
+ SLV_DATA_OUT(31 downto 16) <= std_logic_vector(counter2);
+ SLV_DATA_OUT(15 downto 0) <= std_logic_vector(counter1);
+ SLV_ACK_OUT <= '1';
+ else
+ SLV_UNKNOWN_ADDR_OUT <= '1';
+ end if;
+ end if;
+
+ if SLV_WRITE_IN = '1' then
+ if SLV_ADDR_IN = x"0060" then
+ if testpulse_busy = '0' then
+ counter_from_slv <= unsigned(SLV_DATA_IN);
+ SLV_ACK_OUT <= '1';
+ else
+ SLV_ACK_OUT <= '1';
+ end if;
+
+ else
+ SLV_UNKNOWN_ADDR_OUT <= '1';
+ end if;
+ end if;
+ end if;
+ end process SLV_HANDLER;
+
+--Output Signals
+ testpulse2 <= testpulse2_i;
+ testpulse1 <= testpulse1_i;
+
+end rtl;
--- /dev/null
+-----------------------------------------------------------------------------
+-- Trigger Handler for TRBnet
+-- Tobias Weber, University Mainz
+-----------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+--use work.trb_net_std.all;
+--use work.trb_net_components.all;
+--use work.trb3_components.all;
+
+entity TriggerHandler is
+ port (
+ CLK_IN : in std_logic;
+ RESET_IN : in std_logic;
+
+ --Input Triggers
+ TIMING_TRIGGER_IN : in std_logic; -- The raw timing Trigger Signal
+ LVL1_TRG_DATA_VALID_IN : in std_logic; -- Data Trigger is valid
+ LVL1_VALID_TIMING_TRG_IN : in std_logic; -- Timin Trigger is valid
+ LVL1_VALID_NOTIMING_TRG_IN : in std_logic; -- calib trigger w/o ref time
+ 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);
+
+ --Response from FEE
+ 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_TRG_RELEASE_OUT : out std_logic;
+ FEE_TRG_STATUSBITS_OUT : out std_logic_vector(31 downto 0);
+
+ FEE_DATA_0_IN : in std_logic_vector(31 downto 0);
+ FEE_DATA_WRITE_0_IN : in std_logic;
+
+ -- Trigger FeedBack
+ TRIGGER_BUSY_MUPIX_READ_IN : in std_logic;
+ TRIGGER_BUSY_FIFO_READ_IN : in std_logic;
+
+ -- OUT
+ VALID_TRIGGER_OUT : out std_logic;
+ TRIGGER_TIMING_OUT : out std_logic;
+ TRIGGER_STATUS_OUT : out std_logic;
+ FAST_CLEAR_OUT : out std_logic;--clear event buffer
+ FLUSH_BUFFER_OUT : out std_logic;
+
+ -- Slave bus
+ SLV_READ_IN : in std_logic;
+ SLV_WRITE_IN : in std_logic;
+ SLV_DATA_OUT : out std_logic_vector(31 downto 0);
+ SLV_DATA_IN : in std_logic_vector(31 downto 0);
+ SLV_ADDR_IN : in std_logic_vector(15 downto 0);
+ SLV_ACK_OUT : out std_logic;
+ SLV_NO_MORE_DATA_OUT : out std_logic;
+ SLV_UNKNOWN_ADDR_OUT : out std_logic);
+
+end entity TriggerHandler;
+
+
+architecture behavioral of TriggerHandler is
+
+--trigger
+ signal bypass_trigger : std_logic := '0';
+ signal reset_trigger_state : std_logic := '0';
+ signal reset_trigger_state_edge : std_logic_vector(1 downto 0) := "00";
+ signal valid_trigger_int : std_logic := '0';
+ signal timing_trigger_int : std_logic := '0';
+ signal timing_trigger_edge : std_logic_vector(1 downto 0) := "00";
+ signal status_trigger_int : std_logic := '0';
+ signal fast_clear_int : std_logic := '0';
+ signal flush_buffer_int : std_logic := '0';
+ signal trigger_busy_int : std_logic := '0';
+ signal mupix_readout_end_int : std_logic_vector(1 downto 0) := "00";
+ signal fifo_readout_end_int : std_logic_vector(1 downto 0) := "00";
+--fee
+ signal fee_data_int : std_logic_vector(31 downto 0) := (others => '0');
+ signal fee_data_write_int : std_logic := '0';
+ signal fee_data_finished_int : std_logic := '0';
+ signal fee_trg_release_int : std_logic := '0';
+ signal fee_trg_statusbit_int : std_logic_vector(31 downto 0) := (others => '0');
+--event buffer
+
+--registers
+ signal reset_trigger_counters : std_logic := '0';
+ signal reset_trigger_counters_edge : std_logic_vector(1 downto 0) := (others => '0');
+ signal trigger_rate_acc : unsigned(31 downto 0) := (others => '0');
+ signal trigger_rate_tot : unsigned(31 downto 0) := (others => '0');
+ signal trigger_rate_time_counter : unsigned(31 downto 0) := (others => '0');
+ signal invalid_trigger_counter : unsigned(31 downto 0) := (others => '0');
+ signal valid_trigger_counter : unsigned(31 downto 0) := (others => '0');
+ signal invalid_trigger_counter_t : unsigned(31 downto 0) := (others => '0');
+ signal valid_trigger_counter_t : unsigned(31 downto 0) := (others => '0');
+ signal trigger_handler_state : std_logic_vector(7 downto 0) := (others => '0');
+
+--trigger types
+ constant trigger_physics_type : std_logic_vector(3 downto 0) := x"1";
+ constant trigger_status_type : std_logic_vector(3 downto 0) := x"e";
+
+--trigger handler
+ type trigger_handler_type is (idle,
+ timing_trigger,
+ no_timing_trigger,
+ check_trigger_type,
+ status_trigger,
+ write_data_to_eventbuffer,
+ write_data_to_ipu,
+ trigger_release_a,
+ trigger_release_b,
+ trigger_release_c,
+ wait_trigger_release,
+ ignore,
+ wait_trigger_data_valid_a,
+ wait_trigger_data_valid_b);
+
+ type trigger_type_type is (t_timing,
+ t_physics,
+ t_status,
+ t_ignore,
+ t_unknown);
+
+ signal trigger_handler_fsm : trigger_handler_type := idle;
+ signal trigger_type : trigger_type_type := t_unknown;
+ signal wr_header_int : std_logic := '0';
+ signal wr_data_int : std_logic := '0';
+ signal wr_status_int : std_logic := '0';
+ signal wr_dummy_int : std_logic := '0';
+
+begin
+
+ Signal_Edge_Detect: process (CLK_IN) is
+ begin -- process Mupix_Readout_End_Detect
+ if rising_edge(CLK_IN) then
+ mupix_readout_end_int <= mupix_readout_end_int(0) & TRIGGER_BUSY_MUPIX_READ_IN;
+ fifo_readout_end_int <= fifo_readout_end_int(0) & TRIGGER_BUSY_FIFO_READ_IN;
+ timing_trigger_edge <= timing_trigger_edge(0) & TIMING_TRIGGER_IN;
+ reset_trigger_state_edge <= reset_trigger_state_edge(1) & reset_trigger_state;
+ end if;
+ end process Signal_Edge_Detect;
+
+ ------------------------------------------------------------
+ --Handling of LVL1 triggers
+ ------------------------------------------------------------
+ trigger_handler_proc: process is
+ begin -- process trigger_handler_proc
+ wait until rising_edge(clk_in);
+ valid_trigger_int <= '0';
+ timing_trigger_int <= '0';
+ status_trigger_int <= '0';
+ flush_buffer_int <= '0';
+ fee_data_finished_int <= '0';
+ fee_trg_release_int <= '0';
+ fee_trg_statusbit_int <= (others => '0');
+ fast_clear_int <= '0';
+ trigger_busy_int <= '1';
+ fast_clear_int <= '0';
+ fee_trg_release_int <= '0';
+ wr_header_int <= '0';
+ wr_data_int <= '0';
+ wr_status_int <= '0';
+ wr_dummy_int <= '0';
+ if LVL1_INVALID_TRG_IN = '1' or reset_trigger_state_edge = "01" then
+ fast_clear_int <= '1';
+ fee_trg_release_int <= '1';
+ trigger_handler_fsm <= idle;
+ else
+ case trigger_handler_fsm is
+ when idle =>
+ trigger_busy_int <= '0';
+ trigger_handler_state <= x"01";
+ if LVL1_VALID_TIMING_TRG_IN = '1' then
+ wr_header_int <= '1';
+ if bypass_trigger = '1' then
+ trigger_type <= t_ignore;
+ trigger_handler_fsm <= ignore;
+ else
+ trigger_type <= t_timing;
+ trigger_handler_fsm <= timing_trigger;
+ end if;
+ elsif(LVL1_VALID_NOTIMING_TRG_IN = '1') then
+ wr_header_int <= '1';
+ if bypass_trigger = '1' then
+ trigger_type <= t_ignore;
+ trigger_handler_fsm <= ignore;
+ else
+ trigger_handler_fsm <= check_trigger_type;
+ end if;
+ end if;
+
+ when check_trigger_type =>
+ trigger_handler_state <= x"02";
+ if(LVL1_TRG_DATA_VALID_IN = '1') then
+ if(LVL1_TRG_TYPE_IN = trigger_status_type) then
+ trigger_type <= t_status;
+ trigger_handler_fsm <= no_timing_trigger;
+ elsif(LVL1_TRG_TYPE_IN = trigger_physics_type) then
+ trigger_type <= t_physics;
+ trigger_handler_fsm <= no_timing_trigger;
+ else
+ --unknown trigger
+ trigger_type <= t_unknown;
+ trigger_handler_fsm <= no_timing_trigger;
+ end if;
+ else
+ trigger_handler_fsm <= check_trigger_type;
+ end if;
+
+ when timing_trigger =>--starts mupix readout fsm
+ trigger_handler_state <= x"03";
+ valid_trigger_int <= '1';
+ timing_trigger_int <= '1';
+ trigger_handler_fsm <= write_data_to_eventbuffer;
+
+ when no_timing_trigger =>
+ trigger_handler_state <= x"04";
+ if trigger_type = t_physics then
+ trigger_handler_fsm <= timing_trigger;
+ elsif trigger_type = t_status then
+ trigger_handler_fsm <= status_trigger;
+ else
+ trigger_handler_fsm <= ignore;
+ end if;
+
+ when ignore =>
+ wr_dummy_int <= '1'; --write a dummy value to identify
+ --inactive FEE
+ trigger_handler_state <= x"05";
+ trigger_handler_fsm <= wait_trigger_data_valid_b;
+
+ when status_trigger => --dummy implementation
+ trigger_handler_state <= x"06";
+ wr_status_int <= '1';
+ trigger_handler_fsm <= wait_trigger_data_valid_b;
+
+ when write_data_to_eventbuffer =>
+ trigger_handler_state <= x"07";
+ if mupix_readout_end_int = "10" then
+ trigger_handler_fsm <= write_data_to_ipu;
+ flush_buffer_int <= '1';
+ else
+ trigger_handler_fsm <= write_data_to_eventbuffer;
+ end if;
+
+ when write_data_to_ipu =>
+ trigger_handler_state <= x"0A";
+ wr_data_int <= '1';
+ if fifo_readout_end_int = "10" then
+ wr_data_int <= '0';
+ trigger_handler_fsm <= wait_trigger_data_valid_a;
+ else
+ trigger_handler_fsm <= write_data_to_ipu;
+ end if;
+
+ when wait_trigger_data_valid_a =>
+ trigger_handler_state <= x"0B";
+ if LVL1_TRG_DATA_VALID_IN = '1' then
+ trigger_handler_fsm <= wait_trigger_data_valid_b;
+ end if;
+
+ when wait_trigger_data_valid_b =>
+ trigger_handler_state <= x"0C";
+ trigger_handler_fsm <= trigger_release_a;
+
+ when trigger_release_a =>
+ trigger_handler_state <= x"0D";
+ trigger_handler_fsm <= trigger_release_b;
+
+ when trigger_release_b =>
+ trigger_handler_state <= x"0E";
+ fee_data_finished_int <= '1';
+ trigger_handler_fsm <= trigger_release_c;
+
+ when trigger_release_c =>
+ trigger_handler_state <= x"0F";
+ fee_trg_release_int <= '1';
+ trigger_handler_fsm <= wait_trigger_release;
+
+ when wait_trigger_release =>
+ if(LVL1_TRG_DATA_VALID_IN = '1') then
+ trigger_handler_fsm <= wait_trigger_release;
+ else
+ trigger_handler_fsm <= idle;
+ end if;
+ end case;
+ end if;
+ end process trigger_handler_proc;
+
+ ------------------------------------------------------------
+ --Data Output Mux
+ ------------------------------------------------------------
+ Data_Out_Mux: process (clk_in) is
+ begin -- process Data_Out_Mux
+ if rising_edge(clk_in) then
+ if wr_header_int = '1' then
+ fee_data_write_int <= '1';--header see Hades DAQ user guide
+ fee_data_int <= "001" & "0" & LVL1_TRG_TYPE_IN & LVL1_TRG_CODE_IN & LVL1_TRG_NUMBER_IN;
+ elsif wr_data_int = '1' then
+ fee_data_write_int <= FEE_DATA_WRITE_0_IN;
+ fee_data_int <= FEE_DATA_0_IN;
+ elsif wr_status_int = '1' then
+ fee_data_int <= x"deadbeef";
+ fee_data_write_int <= '1';
+ elsif wr_dummy_int = '1' then
+ fee_data_write_int <= '1' ;
+ fee_data_int <= x"fff00000";
+ else
+ fee_data_write_int <= '0';
+ fee_data_int <= (others => '1');
+ end if;
+ end if;
+ end process Data_Out_Mux;
+
+
+ ------------------------------------------------------------
+ --Trigger statistics
+ ------------------------------------------------------------
+ Trigger_Statistics_Proc: process (clk_in) is
+ begin -- process Trigger_Statistics_Proc
+ if rising_edge(CLK_IN) then
+ reset_trigger_counters_edge <= reset_trigger_counters_edge(0) & reset_trigger_counters;
+ if reset_trigger_counters_edge = "01" then
+ trigger_rate_acc <= (others => '0');
+ invalid_trigger_counter_t <= (others => '0');
+ valid_trigger_counter_t <= (others => '0');
+ trigger_rate_time_counter <= (others => '0');
+ end if;
+ if trigger_rate_time_counter < x"5f5e100" then--1s at 10ns clock period
+ --if trigger_rate_time_counter < x"000007e" then
+ trigger_rate_time_counter <= trigger_rate_time_counter + 1;
+ if valid_trigger_int = '1' then
+ valid_trigger_counter_t <= valid_trigger_counter_t + 1;
+ elsif LVL1_INVALID_TRG_IN = '1' or (trigger_busy_int = '1' and timing_trigger_edge = "01") then
+ invalid_trigger_counter_t <= invalid_trigger_counter_t + 1;
+ end if;
+ else
+ valid_trigger_counter <= valid_trigger_counter + valid_trigger_counter_t;
+ invalid_trigger_counter <= invalid_trigger_counter + invalid_trigger_counter_t;
+ trigger_rate_acc <= valid_trigger_counter_t;
+ trigger_rate_tot <= valid_trigger_counter_t + invalid_trigger_counter_t;
+ trigger_rate_time_counter <= (others => '0');
+ valid_trigger_counter_t <= (others => '0');
+ invalid_trigger_counter_t <= (others => '0');
+ end if;
+ end if;
+ end process Trigger_Statistics_Proc;
+
+ ------------------------------------------------------------
+ --TRB SLV-BUS Hanlder
+ ------------------------------------------------------------
+ --0x100: accepted trigger_rate
+ --0x101: total trigger_rate
+ --0x102: invalid triggers
+ --0x103: valid triggers
+ --0x104: trigger_handler_state
+ --0x105: reset counters
+ --0x106: reset trigger state machine
+ --0x107: bypass trigger signals flag
+
+ slv_bus_handler : process(CLK_IN)
+ begin
+ if rising_edge(CLK_IN) then
+ slv_data_out <= (others => '0');
+ slv_ack_out <= '0';
+ slv_no_more_data_out <= '0';
+ slv_unknown_addr_out <= '0';
+
+ if slv_write_in = '1' then
+ case SLV_ADDR_IN is
+ when x"0105" =>
+ reset_trigger_counters <= SLV_DATA_IN(0);
+ slv_ack_out <= '1';
+ when x"0106" =>
+ reset_trigger_state <= SLV_DATA_IN(0);
+ slv_ack_out <= '1';
+ when x"0107"=>
+ bypass_trigger <= SLV_DATA_IN(0);
+ slv_ack_out <= '1';
+ when others =>
+ slv_unknown_addr_out <= '1';
+ end case;
+
+ elsif slv_read_in = '1' then
+ case slv_addr_in is
+ when x"0100" =>
+ slv_data_out <= std_logic_vector(trigger_rate_acc);
+ slv_ack_out <= '1';
+ when x"0101" =>
+ slv_data_out <= std_logic_vector(trigger_rate_tot);
+ slv_ack_out <= '1';
+ when x"0102" =>
+ slv_data_out <= std_logic_vector(invalid_trigger_counter);
+ slv_ack_out <= '1';
+ when x"0103" =>
+ slv_data_out <= std_logic_vector(valid_trigger_counter);
+ slv_ack_out <= '1';
+ when x"0104" =>
+ slv_data_out <= x"000000" & trigger_handler_state;
+ slv_ack_out <= '1';
+ when x"0107" =>
+ slv_data_out(0) <= bypass_trigger;
+ slv_ack_out <= '1';
+ when others =>
+ slv_unknown_addr_out <= '1';
+ end case;
+
+ end if;
+ end if;
+ end process slv_bus_handler;
+
+ --map output signals
+ valid_trigger_out <= valid_trigger_int;
+ trigger_timing_out <= timing_trigger_int;
+ trigger_status_out <= status_trigger_int;
+ fast_clear_out <= fast_clear_int;
+ flush_buffer_out <= flush_buffer_int;
+ fee_data_out <= fee_data_int;
+ fee_data_write_out <= fee_data_write_int;
+ fee_data_finished_out <= fee_data_finished_int;
+ fee_trg_release_out <= fee_trg_release_int;
+ fee_trg_statusbits_out <= fee_trg_statusbit_int;
+
+end architecture behavioral;
--- /dev/null
+-------------------------------------------------------------------------------
+--Test bench for cyclic redundancy check computation
+--We use the CRC5 polynomial f(x) = 1 + x^2 + x^ 5 used by the USB2.0 protocol
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity CRCTest is
+end entity CRCTest;
+
+architecture simulation of CRCTest is
+
+ component CRC
+ port(
+ clk : in std_logic;
+ rst : in std_logic;
+ enable : in std_logic;
+ data_in : in std_logic;
+ crc_out : out std_logic_vector(4 downto 0)
+ );
+ end component CRC;
+
+ signal clk : std_logic;
+ signal rst : std_logic := '0';
+ signal enable : std_logic := '0';
+ signal data_in : std_logic := '0';
+ signal crc_out : std_logic_vector(4 downto 0);
+
+ constant clk_period : time := 10 ns;
+ constant message : std_logic_vector(10 downto 0) := "10100111010";
+
+begin
+
+ dut : entity work.CRC
+ port map(
+ clk => clk,
+ rst => rst,
+ enable => enable,
+ data_in => data_in,
+ crc_out => crc_out
+ );
+
+ clk_gen : process is
+ begin
+ clk <= '1';
+ wait for clk_period/2;
+ clk <= '0';
+ wait for clk_period/2;
+ end process clk_gen;
+
+ stimulus : process is
+ begin
+ wait for 50 ns;
+ for i in 10 downto 0 loop
+ enable <= '1';
+ data_in <= message(i);
+ wait for clk_period;
+ end loop;
+ enable <= '0';
+ assert crc_out = "11000" report "error during crc calculation" severity error;
+
+ wait;
+ end process stimulus;
+
+
+end architecture simulation;
--- /dev/null
+------------------------------------------------------------
+--! @file
+--! @brief Testbench for readout of Mupix 3-6
+--! @author Tobias Weber
+--! @date August 2017
+------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.TRBSimulationPkg.all;
+
+entity HitbusHistogramTest is
+end entity HitbusHistogramTest;
+
+architecture simulation of HitbusHistogramTest is
+
+ component HitbusHistogram
+ generic(
+ HistogramRange : integer := 6;
+ PostOscillationWaitCycles : integer := 5
+ );
+ port(
+ clk : in std_logic;
+ hitbus : in std_logic;
+ trigger : in std_logic;
+ SLV_READ_IN : in std_logic;
+ SLV_WRITE_IN : in std_logic;
+ SLV_DATA_OUT : out std_logic_vector(31 downto 0);
+ SLV_DATA_IN : in std_logic_vector(31 downto 0);
+ SLV_ADDR_IN : in std_logic_vector(15 downto 0);
+ SLV_ACK_OUT : out std_logic;
+ SLV_NO_MORE_DATA_OUT : out std_logic;
+ SLV_UNKNOWN_ADDR_OUT : out std_logic
+ );
+ end component HitbusHistogram;
+
+ constant HistogramRange : integer := 6;
+ constant PostOscillationWaitCycles : integer := 5;
+ constant clk_period : time := 10 ns;
+
+ signal clk : std_logic := '0';
+ signal hitbus : std_logic := '0';
+ signal trigger : std_logic := '0';
+ signal SLV_READ_IN : std_logic := '0';
+ signal SLV_WRITE_IN : std_logic := '0';
+ signal SLV_DATA_IN : std_logic_vector(31 downto 0) := (others => '0');
+ signal SLV_ADDR_IN : std_logic_vector(15 downto 0) := (others => '0');
+
+
+ signal SLV_DATA_OUT : std_logic_vector(31 downto 0);
+ signal SLV_ACK_OUT : std_logic;
+ signal SLV_NO_MORE_DATA_OUT : std_logic;
+ signal SLV_UNKNOWN_ADDR_OUT : std_logic;
+
+ procedure HitbusEvent(signal hitbus, trigger : out std_logic;
+ constant latency, tot1 : time;
+ constant postoscillation, tot2 : time := 0 ns) is
+ begin
+ trigger <= '1';
+ wait for latency;
+ trigger <= '0';
+ hitbus <= '1';
+ wait for tot1;
+ hitbus <= '0';
+ if postoscillation > 0 ns then
+ wait for postoscillation;
+ hitbus <= '1';
+ wait for tot2;
+ hitbus <= '0';
+ end if;
+ wait for 200 ns;
+ end procedure HitbusEvent;
+
+
+begin
+
+ HitbusHistogram_1 : entity work.HitbusHistogram
+ generic map(
+ HistogramRange => HistogramRange,
+ PostOscillationWaitCycles => PostOscillationWaitCycles
+ )
+ port map(
+ clk => clk,
+ hitbus => hitbus,
+ trigger => trigger,
+ SLV_READ_IN => SLV_READ_IN,
+ SLV_WRITE_IN => SLV_WRITE_IN,
+ SLV_DATA_OUT => SLV_DATA_OUT,
+ SLV_DATA_IN => SLV_DATA_IN,
+ SLV_ADDR_IN => SLV_ADDR_IN,
+ SLV_ACK_OUT => SLV_ACK_OUT,
+ SLV_NO_MORE_DATA_OUT => SLV_NO_MORE_DATA_OUT,
+ SLV_UNKNOWN_ADDR_OUT => SLV_UNKNOWN_ADDR_OUT
+ );
+
+ clk_gen : process is
+ begin
+ clk <= '1';
+ wait for clk_period/2;
+ clk <= '0';
+ wait for clk_period/2;
+ end process clk_gen;
+
+ stimulus : process is
+ begin
+ wait for 100 ns;
+ TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"000000FF", x"0806");
+ TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, std_logic_vector(to_unsigned(2, 32)), x"0800");
+ for i in 0 to 5 loop
+ HitbusEvent(hitbus, trigger, 50 ns, 100 ns);
+ end loop;
+ for i in 0 to 8 loop
+ HitbusEvent(hitbus, trigger, 50 ns, 120 ns);
+ end loop;
+ HitbusEvent(hitbus, trigger, 50 ns, 100 ns, 20 ns, 30 ns);--test post-oscillation
+ wait;
+ end process stimulus;
+
+
+end architecture simulation;
--- /dev/null
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity LTC1658SPITest is
+end entity LTC1658SPITest;
+
+architecture simulation of LTC1658SPITest is
+
+ component LTC1658SPI
+ generic(
+ data_length : integer;
+ fpga_clock_speed : integer;
+ spi_clock_speed : integer
+ );
+ port(
+ clk : in std_logic;
+ reset : in std_logic;
+ start_write : in std_logic;
+ spi_data_in : in std_logic_vector(data_length - 1 downto 0);
+ spi_data_from_chip : in std_logic;
+ spi_data_to_chip : out std_logic;
+ spi_data_out : out std_logic_vector(data_length - 1 downto 0);
+ spi_clk : out std_logic;
+ spi_ld : out std_logic
+ );
+ end component LTC1658SPI;
+
+
+ constant data_length : integer := 16;
+ constant clk_period : time := 10 ns;
+
+ signal clk : std_logic;
+ signal reset : std_logic := '0';
+ signal start_write : std_logic := '0';
+ signal spi_data_in : std_logic_vector(data_length - 1 downto 0);
+ signal spi_data_from_chip : std_logic := '0';
+ signal spi_data_to_chip : std_logic;
+ signal spi_data_out : std_logic_vector(data_length - 1 downto 0);
+ signal spi_clk : std_logic;
+ signal spi_ld : std_logic;
+
+ signal shiftreg : std_logic_vector(data_length - 1 downto 0) := (others => '0');
+
+begin
+
+ dut : entity work.LTC1658SPI
+ generic map(
+ data_length => data_length,
+ fpga_clock_speed => 100,
+ spi_clock_speed => 10
+ )
+ port map(
+ clk => clk,
+ reset => reset,
+ start_write => start_write,
+ spi_data_in => spi_data_in,
+ spi_data_from_chip => spi_data_from_chip,
+ spi_data_to_chip => spi_data_to_chip,
+ spi_data_out => spi_data_out,
+ spi_clk => spi_clk,
+ spi_ld => spi_ld
+ );
+
+ clk_gen : process is
+ begin
+ clk <= '0';
+ wait for clk_period/2;
+ clk <= '1';
+ wait for clk_period/2;
+ end process clk_gen;
+
+ ltcshiftreg : process(spi_clk) is
+ begin
+ if spi_clk'event and spi_clk = '1' then
+ spi_data_from_chip <= shiftreg(data_length - 1) after 5 ns;
+ shiftreg <= shiftreg(data_length - 2 downto 0) & spi_data_to_chip;
+ end if;
+ end process ltcshiftreg;
+
+
+ stimulus : process is
+ begin
+ wait for 100 ns;
+ spi_data_in <= x"AAAA";
+ start_write <= '1';
+ wait for clk_period;
+ start_write <= '0';
+ wait for 5 us;
+ spi_data_in <= x"BBBB";
+ start_write <= '1';
+ wait for clk_period;
+ start_write <= '0';
+ wait;
+ end process stimulus;
+
+
+
+end architecture simulation;
--- /dev/null
+------------------------------------------------------------
+--Simulation of mupix 6 shift register
+------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+entity MupixShiftReg is
+ generic(
+ pixeldac_shift_length : integer := 64;
+ chipdac_shift_length : integer := 16
+ );
+ port(
+ ck_c : in std_logic;
+ ck_d : in std_logic;
+ sin : in std_logic;
+ sout_c : out std_logic;
+ sout_d : out std_logic);
+end entity MupixShiftReg;
+
+architecture RTL of MupixShiftReg is
+
+ signal pixeldac_shift_reg : std_logic_vector(pixeldac_shift_length - 1 downto 0) := (others => '0');
+ signal chipdac_shift_reg : std_logic_vector(chipdac_shift_length - 1 downto 0) := (others => '0');
+
+begin
+
+ process(ck_c)
+ begin
+ if ck_c'event and ck_c = '1' then
+ pixeldac_shift_reg <= pixeldac_shift_reg(pixeldac_shift_length - 2 downto 0) & sin;
+ end if;
+ end process;
+
+ process(ck_d)
+ begin
+ if ck_d'event and ck_d = '1' then
+ chipdac_shift_reg <= chipdac_shift_reg(chipdac_shift_length - 2 downto 0) & sin;
+ end if;
+ end process;
+
+ sout_c <= pixeldac_shift_reg(pixeldac_shift_length - 1);
+ sout_d <= chipdac_shift_reg(chipdac_shift_length - 1);
+
+end architecture RTL;
+
--- /dev/null
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.numeric_std.all;
+
+use work.StdTypes.all;
+use work.TRBSimulationPkg.all;
+
+
+entity PixCtrlTest is
+end entity PixCtrlTest;
+
+architecture simulation of PixCtrlTest is
+
+ component PixCtr
+ generic(
+ fpga_clk_speed : integer := 1e8;
+ spi_clk_speed : integer := 1e4
+ );
+ port(
+ clk : in std_logic;
+ reset : in std_logic;
+ sout_c_from_mupix : in std_logic;
+ sout_d_from_mupix : in std_logic;
+ mupix_ctrl : out MupixSlowControl;
+ SLV_READ_IN : in std_logic;
+ SLV_WRITE_IN : in std_logic;
+ SLV_DATA_OUT : out std_logic_vector(31 downto 0);
+ SLV_DATA_IN : in std_logic_vector(31 downto 0);
+ SLV_ADDR_IN : in std_logic_vector(15 downto 0);
+ SLV_ACK_OUT : out std_logic;
+ SLV_NO_MORE_DATA_OUT : out std_logic;
+ SLV_UNKNOWN_ADDR_OUT : out std_logic
+ );
+ end component PixCtr;
+
+ component MupixShiftReg
+ generic(
+ pixeldac_shift_length : integer := 64;
+ chipdac_shift_length : integer := 16
+ );
+ port(
+ ck_c : in std_logic;
+ ck_d : in std_logic;
+ sin : in std_logic;
+ sout_c : out std_logic;
+ sout_d : out std_logic
+ );
+ end component MupixShiftReg;
+
+ signal clk : std_logic;
+ signal reset : std_logic := '0';
+ signal sout_c_from_mupix : std_logic := '0';
+ signal sout_d_from_mupix : std_logic := '0';
+ signal mupix_ctrl : MupixSlowControl;
+ signal SLV_READ_IN : std_logic := '0';
+ signal SLV_WRITE_IN : std_logic := '0';
+ signal SLV_DATA_OUT : std_logic_vector(31 downto 0);
+ signal SLV_DATA_IN : std_logic_vector(31 downto 0) := (others => '0');
+ signal SLV_ADDR_IN : std_logic_vector(15 downto 0) := (others => '0');
+ signal SLV_ACK_OUT : std_logic;
+ signal SLV_NO_MORE_DATA_OUT : std_logic;
+ signal SLV_UNKNOWN_ADDR_OUT : std_logic;
+
+ constant clk_period : time := 10 ns;
+
+begin
+
+ dut : entity work.PixCtr
+ generic map(
+ fpga_clk_speed => 1e8,
+ spi_clk_speed => 5e7
+ )
+ port map(
+ clk => clk,
+ reset => reset,
+ sout_c_from_mupix => sout_c_from_mupix,
+ sout_d_from_mupix => sout_d_from_mupix,
+ mupix_ctrl => mupix_ctrl,
+ SLV_READ_IN => SLV_READ_IN,
+ SLV_WRITE_IN => SLV_WRITE_IN,
+ SLV_DATA_OUT => SLV_DATA_OUT,
+ SLV_DATA_IN => SLV_DATA_IN,
+ SLV_ADDR_IN => SLV_ADDR_IN,
+ SLV_ACK_OUT => SLV_ACK_OUT,
+ SLV_NO_MORE_DATA_OUT => SLV_NO_MORE_DATA_OUT,
+ SLV_UNKNOWN_ADDR_OUT => SLV_UNKNOWN_ADDR_OUT
+ );
+
+ mupix : entity work.MupixShiftReg
+ generic map(
+ pixeldac_shift_length => 64,
+ chipdac_shift_length => 16
+ )
+ port map(
+ ck_c => mupix_ctrl.ck_c,
+ ck_d => mupix_ctrl.ck_d,
+ sin => mupix_ctrl.sin,
+ sout_c => sout_c_from_mupix,
+ sout_d => sout_d_from_mupix
+ );
+
+ clk_gen : process is
+ begin
+ clk <= '1';
+ wait for clk_period/2;
+ clk <= '0';
+ wait for clk_period/2;
+ end process clk_gen;
+
+ stimulus_gen : process is
+ begin
+ wait for 100 ns;
+ TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"004F0000",x"0083");
+ TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"BBBBBBBB",x"0080");
+ TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"AAAAAAAA",x"0080");
+ TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"CCCCCCCC",x"0080");
+ wait;
+ end process stimulus_gen;
+
+
+end architecture simulation;
--- /dev/null
+------------------------------------------------------------
+--! @file
+--! @brief Function and Procedures useful for TRB Simulation
+--! @author Tobias Weber
+--! @date August 2017
+------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+package TRBSimulationPkg is
+
+ procedure TRBRegisterWrite(signal SLV_Write : out std_logic;
+ signal SLV_Data : out std_logic_vector(31 downto 0);
+ signal SLV_Addr : out std_logic_vector(15 downto 0);
+ constant data : in std_logic_vector(31 downto 0);
+ constant addr : in std_logic_vector(15 downto 0);
+ constant clk_period : in time := 10 ns);
+
+ procedure TRBRegisterRead(signal SLV_Read : out std_logic;
+ signal SLV_Data : out std_logic_vector(31 downto 0);
+ signal SLV_Addr : out std_logic_vector(15 downto 0);
+ constant data : in std_logic_vector(31 downto 0);
+ constant addr : in std_logic_vector(15 downto 0);
+ constant clk_period : in time := 10 ns);
+
+end package TRBSimulationPkg;
+
+package body TRBSimulationPkg is
+
+ procedure TRBRegisterWrite(signal SLV_Write : out std_logic;
+ signal SLV_Data : out std_logic_vector(31 downto 0);
+ signal SLV_Addr : out std_logic_vector(15 downto 0);
+ constant data : in std_logic_vector(31 downto 0);
+ constant addr : in std_logic_vector(15 downto 0);
+ constant clk_period : in time := 10 ns) is
+ begin
+ SLV_Write <= '1';
+ SLV_Data <= data;
+ SLV_Addr <= addr;
+ wait for clk_period;
+ SLV_Write <= '0';
+ SLV_Data <= (others => '0');
+ SLV_Addr <= (others => '0');
+ wait for clk_period;
+ end TRBRegisterWrite;
+
+ procedure TRBRegisterRead(signal SLV_Read : out std_logic;
+ signal SLV_Data : out std_logic_vector(31 downto 0);
+ signal SLV_Addr : out std_logic_vector(15 downto 0);
+ constant data : in std_logic_vector(31 downto 0);
+ constant addr : in std_logic_vector(15 downto 0);
+ constant clk_period : in time := 10 ns) is
+ begin
+ SLV_Read <= '1';
+ SLV_Data <= data;
+ SLV_Addr <= addr;
+ wait for clk_period;
+ SLV_Read <= '0';
+ SLV_Data <= (others => '0');
+ SLV_Addr <= (others => '0');
+ wait for clk_period;
+ end procedure TRBRegisterRead;
+
+
+end TRBSimulationPkg;
\ No newline at end of file
--- /dev/null
+-------------------------------------------------------------------------------
+--trb3_periph for MuPix Version 8
+--Tobias Weber
+--Ruhr Universitaet Bochum
+-------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.trb3_components.all;
+use work.version.all;
+
+library ecp3;
+use ecp3.components.all;
+
+
+entity trb3_periph is
+ port(
+ --Clocks
+ CLK_GPLL_RIGHT : in std_logic; --Clock Manager 2/(2468), 200 MHz <-- MAIN CLOCK for FPGA
+ CLK_GPLL_LEFT : in std_logic; --Clock Manager 1/(2468), 125 MHz
+ CLK_PCLK_LEFT : in std_logic; --Clock Fan-out, 200/400 MHz <-- For TDC. Same oscillator as GPLL left!
+ CLK_PCLK_RIGHT : in std_logic; --Clock Fan-out, 200/400 MHz <-- For TDC. Same oscillator as GPLL right!
+ --Trigger
+ TRIGGER_LEFT : in std_logic; --left side trigger input from fan-out
+ TRIGGER_RIGHT : in std_logic; --right side trigger input from fan-out
+ --Serdes
+ CLK_SERDES_INT_LEFT : in std_logic; --Clock Manager 1/(1357), off, 125 MHz possible
+ CLK_SERDES_INT_RIGHT : in std_logic; --Clock Manager 2/(1357), 200 MHz, only in case of problems
+ SERDES_INT_TX : out std_logic_vector(3 downto 0);
+ SERDES_INT_RX : in std_logic_vector(3 downto 0);
+ SERDES_ADDON_TX : out std_logic_vector(11 downto 0);
+ SERDES_ADDON_RX : in std_logic_vector(11 downto 0);
+ --Inter-FPGA Communication
+ FPGA5_COMM : inout std_logic_vector(11 downto 0);
+ --Bit 0/1 input, serial link RX active
+ --Bit 2/3 output, serial link TX active
+
+ ---------------------------------------------------------------------------
+ -- BEGIN SenorBoard MuPix
+ ---------------------------------------------------------------------------
+ led_line : out std_logic_vector(3 downto 0); --leds on TRB addon board
+ spare_line : in std_logic_vector(5 downto 0); --spare lines
+ --slow control signals
+ testpulse : out std_logic; --generate injection pulse
+ ctrl_din : out std_logic; --serial data to mupix
+ ctrl_clk1 : out std_logic; --slow control clk1
+ ctrl_clk2 : out std_logic; --slow control clk2
+ ctrl_ld : out std_logic; --slow control load latched data
+ ctrl_dout : in std_logic; --serial data from mupix
+ ctrl_rb : out std_logic; --slow control readback??
+ spi_dout_adc : in std_logic; --adc serial data from board
+ spi_dout_dac : in std_logic; --dac serial data from board
+ spi_ld : out std_logic; --serial data load
+ spi_clk : out std_logic; --serial clock
+ spi_din : out std_logic; --serial data out
+ spi_ld_tmp_dac : out std_logic; --load temperature dac ??
+ spi_ld_adc : out std_logic; --load adc ??
+ dac4_dout : in std_logic; --serial data in from dac 4??
+ --slow data signals
+ hitbus : in std_logic; --hitbus signal
+ hit : in std_logic; --hit signal (replacement for priout?)
+ ldcol : out std_logic; --load column
+ rdcol : out std_logic; --read column
+ pull_down : out std_logic; --pull down
+ ldpix : out std_logic; --load pixel
+ --fast data signals
+ clkref : out std_logic; --reference clock
+ clkext : out std_logic; --external clock (difference to first one?)
+ syncres : out std_logic; --sync something
+ trigger : in std_logic; --external trigger
+ --fast data comes in via serdes addon (see above)
+
+ ---------------------------------------------------------------------------
+ -- END SensorBoard MuPix
+ ---------------------------------------------------------------------------
+ not_connected : out std_logic_vector(25 downto 0);
+
+ --Flash ROM & Reboot
+ FLASH_CLK : out std_logic;
+ FLASH_CS : out std_logic;
+ FLASH_DIN : out std_logic;
+ FLASH_DOUT : in std_logic;
+ PROGRAMN : out std_logic; --reboot FPGA
+ --Misc
+ TEMPSENS : inout std_logic; --Temperature Sensor
+ CODE_LINE : in std_logic_vector(1 downto 0);
+ LED_GREEN : out std_logic;
+ LED_ORANGE : out std_logic;
+ LED_RED : out std_logic;
+ LED_YELLOW : out std_logic;
+ SUPPL : in std_logic; --terminated diff pair, PCLK, Pads
+ --Test Connectors
+ TEST_LINE : out std_logic_vector(15 downto 0)
+ );
+
+ attribute syn_useioff : boolean;
+ --no IO-FF for LEDs relaxes timing constraints
+ attribute syn_useioff of LED_GREEN : signal is false;
+ attribute syn_useioff of LED_ORANGE : signal is false;
+ attribute syn_useioff of LED_RED : signal is false;
+ attribute syn_useioff of LED_YELLOW : signal is false;
+ attribute syn_useioff of TEMPSENS : signal is false;
+ attribute syn_useioff of PROGRAMN : signal is false;
+ attribute syn_useioff of CODE_LINE : signal is false;
+ attribute syn_useioff of TRIGGER_LEFT : signal is false;
+ attribute syn_useioff of TRIGGER_RIGHT : signal is false;
+ --important signals
+ attribute syn_useioff of FLASH_CLK : signal is true;
+ attribute syn_useioff of FLASH_CS : signal is true;
+ attribute syn_useioff of FLASH_DIN : signal is true;
+ attribute syn_useioff of FLASH_DOUT : signal is true;
+ attribute syn_useioff of FPGA5_COMM : signal is true;
+ attribute syn_useioff of TEST_LINE : signal is true;
+ --attribute syn_useioff of INP : signal is false;
+ --attribute syn_useioff of DAC_SDO : signal is true;
+ --attribute syn_useioff of DAC_SDI : signal is true;
+ --attribute syn_useioff of DAC_SCK : signal is true;
+ --attribute syn_useioff of DAC_CS : signal is true;
+
+
+end entity;
+
+
+architecture trb3_periph_arch of trb3_periph is
+ --Constants
+ constant REGIO_NUM_STAT_REGS : integer := 5;
+ constant REGIO_NUM_CTRL_REGS : integer := 3;
+ constant NumberFEECards : integer := 1;
+
+ attribute syn_keep : boolean;
+ attribute syn_preserve : boolean;
+
+ --Clock / Reset
+ signal clk_100_i : std_logic; --clock for main logic, 100 MHz, via Clock Manager and internal PLL
+ signal clk_200_i : std_logic; --clock for logic at 200 MHz, via Clock Manager and bypassed PLL
+ signal pll_lock : std_logic; --Internal PLL locked. E.g. used to reset all internal logic.
+ signal clear_i : std_logic;
+ signal reset_i : std_logic;
+ signal GSR_N : std_logic;
+ attribute syn_keep of GSR_N : signal is true;
+ attribute syn_preserve of GSR_N : signal is true;
+
+ --Media Interface
+ signal med_stat_op : std_logic_vector (1*16-1 downto 0);
+ signal med_ctrl_op : std_logic_vector (1*16-1 downto 0);
+ signal med_stat_debug : std_logic_vector (1*64-1 downto 0);
+ signal med_ctrl_debug : std_logic_vector (1*64-1 downto 0);
+ signal med_data_out : std_logic_vector (1*16-1 downto 0);
+ signal med_packet_num_out : std_logic_vector (1*3-1 downto 0);
+ signal med_dataready_out : std_logic;
+ signal med_read_out : std_logic;
+ signal med_data_in : std_logic_vector (1*16-1 downto 0);
+ signal med_packet_num_in : std_logic_vector (1*3-1 downto 0);
+ signal med_dataready_in : std_logic;
+ signal med_read_in : std_logic;
+
+ --LVL1 channel
+ signal timing_trg_received_i : std_logic;
+ signal trg_data_valid_i : std_logic;
+ signal trg_timing_valid_i : std_logic;
+ signal trg_notiming_valid_i : std_logic;
+ signal trg_invalid_i : std_logic;
+ signal trg_type_i : std_logic_vector(3 downto 0);
+ signal trg_number_i : std_logic_vector(15 downto 0);
+ signal trg_code_i : std_logic_vector(7 downto 0);
+ signal trg_information_i : std_logic_vector(23 downto 0);
+ signal trg_int_number_i : std_logic_vector(15 downto 0);
+ signal trg_multiple_trg_i : std_logic;
+ signal trg_timeout_detected_i : std_logic;
+ signal trg_spurious_trg_i : std_logic;
+ signal trg_missing_tmg_trg_i : std_logic;
+ signal trg_spike_detected_i : std_logic;
+
+ --Data channel
+ signal fee_trg_release_i : std_logic_vector(NumberFEECards-1 downto 0);
+ signal fee_trg_statusbits_i : std_logic_vector(NumberFEECards*32-1 downto 0);
+ signal fee_data_i : std_logic_vector(NumberFEECards*32-1 downto 0);
+ signal fee_data_write_i : std_logic_vector(NumberFEECards-1 downto 0);
+ signal fee_data_finished_i : std_logic_vector(NumberFEECards-1 downto 0);
+ signal fee_almost_full_i : std_logic_vector(NumberFEECards-1 downto 0);
+
+ --Slow Control channel
+ signal common_stat_reg : std_logic_vector(std_COMSTATREG*32-1 downto 0);
+ signal common_ctrl_reg : std_logic_vector(std_COMCTRLREG*32-1 downto 0);
+ signal stat_reg : std_logic_vector(32*2**REGIO_NUM_STAT_REGS-1 downto 0);
+ signal ctrl_reg : std_logic_vector(32*2**REGIO_NUM_CTRL_REGS-1 downto 0);
+ signal common_stat_reg_strobe : std_logic_vector(std_COMSTATREG-1 downto 0);
+ signal common_ctrl_reg_strobe : std_logic_vector(std_COMCTRLREG-1 downto 0);
+ signal stat_reg_strobe : std_logic_vector(2**REGIO_NUM_STAT_REGS-1 downto 0);
+ signal ctrl_reg_strobe : std_logic_vector(2**REGIO_NUM_CTRL_REGS-1 downto 0);
+
+ --RegIO
+ signal my_address : std_logic_vector (15 downto 0);
+ signal regio_addr_out : std_logic_vector (15 downto 0);
+ signal regio_read_enable_out : std_logic;
+ signal regio_write_enable_out : std_logic;
+ signal regio_data_out : std_logic_vector (31 downto 0);
+ signal regio_data_in : std_logic_vector (31 downto 0);
+ signal regio_dataready_in : std_logic;
+ signal regio_no_more_data_in : std_logic;
+ signal regio_write_ack_in : std_logic;
+ signal regio_unknown_addr_in : std_logic;
+ signal regio_timeout_out : std_logic;
+
+ --Timer
+ signal global_time : std_logic_vector(31 downto 0);
+ signal local_time : std_logic_vector(7 downto 0);
+ signal time_since_last_trg : std_logic_vector(31 downto 0);
+ signal timer_ticks : std_logic_vector(1 downto 0);
+
+ --Flash
+ signal spictrl_read_en : std_logic;
+ signal spictrl_write_en : std_logic;
+ signal spictrl_data_in : std_logic_vector(31 downto 0);
+ signal spictrl_addr : std_logic;
+ signal spictrl_data_out : std_logic_vector(31 downto 0);
+ signal spictrl_ack : std_logic;
+ signal spictrl_busy : std_logic;
+ signal spimem_read_en : std_logic;
+ signal spimem_write_en : std_logic;
+ signal spimem_data_in : std_logic_vector(31 downto 0);
+ signal spimem_addr : std_logic_vector(5 downto 0);
+ signal spimem_data_out : std_logic_vector(31 downto 0);
+ signal spimem_ack : std_logic;
+ signal spidac_read_en : std_logic;
+ signal spidac_write_en : std_logic;
+ signal spidac_data_in : std_logic_vector(31 downto 0);
+ signal spidac_addr : std_logic_vector(4 downto 0);
+ signal spidac_data_out : std_logic_vector(31 downto 0);
+ signal spidac_ack : std_logic;
+ signal spidac_busy : std_logic;
+
+ signal dac_cs_i : std_logic_vector(3 downto 0);
+ signal dac_sck_i : std_logic;
+ signal dac_sdi_i : std_logic;
+
+ signal spi_bram_addr : std_logic_vector(7 downto 0);
+ signal spi_bram_wr_d : std_logic_vector(7 downto 0);
+ signal spi_bram_rd_d : std_logic_vector(7 downto 0);
+ signal spi_bram_we : std_logic;
+
+ --FPGA Test
+ signal time_counter : unsigned(31 downto 0);
+
+ -- MuPix Regio Bus
+ signal mu_regio_addr_in_0 : std_logic_vector (15 downto 0);
+ signal mu_regio_data_in_0 : std_logic_vector (31 downto 0);
+ signal mu_regio_data_out_0 : std_logic_vector (31 downto 0);
+ signal mu_regio_read_enable_in_0 : std_logic;
+ signal mu_regio_write_enable_in_0 : std_logic;
+ signal mu_regio_timeout_in_0 : std_logic;
+ signal mu_regio_dataready_out_0 : std_logic;
+ signal mu_regio_write_ack_out_0 : std_logic;
+ signal mu_regio_no_more_data_out_0 : std_logic;
+ signal mu_regio_unknown_addr_out_0 : std_logic;
+
+ --common reset signals for mupix frontends
+ signal reset_timestamps_i : std_logic;
+ signal reset_eventcounters_i : std_logic;
+ signal resethandler_regio_addr_in_0 : std_logic_vector (15 downto 0);
+ signal resethandler_regio_data_in_0 : std_logic_vector (31 downto 0);
+ signal resethandler_regio_data_out_0 : std_logic_vector (31 downto 0);
+ signal resethandler_regio_read_enable_in_0 : std_logic;
+ signal resethandler_regio_write_enable_in_0 : std_logic;
+ signal resethandler_regio_timeout_in_0 : std_logic;
+ signal resethandler_regio_ack_out_0 : std_logic;
+ signal resethandler_regio_no_more_data_out_0 : std_logic;
+ signal resethandler_regio_unknown_addr_out_0 : std_logic;
+
+
+begin
+
+ --tie not connected outputs to 0
+ --not_connected(25 downto 18) <= (others => '0');
+ --not_connected(16 downto 0) <= (others => '0');
+---------------------------------------------------------------------------
+-- Reset Generation
+---------------------------------------------------------------------------
+
+ GSR_N <= pll_lock;
+
+ THE_RESET_HANDLER : trb_net_reset_handler
+ generic map(
+ RESET_DELAY => x"FEEE"
+ )
+ port map(
+ CLEAR_IN => '0', -- reset input (high active, async)
+ CLEAR_N_IN => '1', -- reset input (low active, async)
+ CLK_IN => clk_200_i, -- raw master clock, NOT from PLL/DLL!
+ SYSCLK_IN => clk_100_i, -- PLL/DLL remastered clock
+ PLL_LOCKED_IN => pll_lock, -- master PLL lock signal (async)
+ RESET_IN => '0', -- general reset signal (SYSCLK)
+ TRB_RESET_IN => med_stat_op(13), -- TRBnet reset signal (SYSCLK)
+ CLEAR_OUT => clear_i, -- async reset out, USE WITH CARE!
+ RESET_OUT => reset_i, -- synchronous reset out (SYSCLK)
+ DEBUG_OUT => open
+ );
+
+
+---------------------------------------------------------------------------
+-- Clock Handling
+---------------------------------------------------------------------------
+ THE_MAIN_PLL : pll_in200_out100
+ port map(
+ CLK => CLK_GPLL_RIGHT,
+ RESET => '0',
+ CLKOP => clk_100_i,
+ CLKOK => clk_200_i,
+ LOCK => pll_lock
+ );
+
+
+---------------------------------------------------------------------------
+-- The TrbNet media interface (to other FPGA)
+---------------------------------------------------------------------------
+ THE_MEDIA_UPLINK : trb_net16_med_ecp3_sfp
+ generic map(
+ SERDES_NUM => 1, --number of serdes in quad
+ EXT_CLOCK => c_NO, --use internal clock
+ USE_200_MHZ => c_YES, --run on 200 MHz clock
+ USE_125_MHZ => c_NO,
+ USE_CTC => c_NO
+ )
+ port map(
+ CLK => clk_200_i,
+ SYSCLK => clk_100_i,
+ RESET => reset_i,
+ CLEAR => clear_i,
+ CLK_EN => '1',
+ --Internal Connection
+ MED_DATA_IN => med_data_out,
+ MED_PACKET_NUM_IN => med_packet_num_out,
+ MED_DATAREADY_IN => med_dataready_out,
+ MED_READ_OUT => med_read_in,
+ MED_DATA_OUT => med_data_in,
+ MED_PACKET_NUM_OUT => med_packet_num_in,
+ MED_DATAREADY_OUT => med_dataready_in,
+ MED_READ_IN => med_read_out,
+ REFCLK2CORE_OUT => open,
+ --SFP Connection
+ SD_RXD_P_IN => SERDES_INT_RX(2),
+ SD_RXD_N_IN => SERDES_INT_RX(3),
+ SD_TXD_P_OUT => SERDES_INT_TX(2),
+ SD_TXD_N_OUT => SERDES_INT_TX(3),
+ SD_REFCLK_P_IN => open,
+ SD_REFCLK_N_IN => open,
+ SD_PRSNT_N_IN => FPGA5_COMM(0),
+ SD_LOS_IN => FPGA5_COMM(0),
+ SD_TXDIS_OUT => FPGA5_COMM(2),
+ -- Status and control port
+ STAT_OP => med_stat_op,
+ CTRL_OP => med_ctrl_op,
+ STAT_DEBUG => med_stat_debug,
+ CTRL_DEBUG => (others => '0')
+ );
+
+---------------------------------------------------------------------------
+-- Endpoint
+---------------------------------------------------------------------------
+ THE_ENDPOINT : trb_net16_endpoint_hades_full_handler
+ generic map(
+ REGIO_NUM_STAT_REGS => REGIO_NUM_STAT_REGS, --4, --16 stat reg
+ REGIO_NUM_CTRL_REGS => REGIO_NUM_CTRL_REGS, --3, --8 cotrol reg
+ ADDRESS_MASK => x"FFFF",
+ BROADCAST_BITMASK => x"FF",
+ BROADCAST_SPECIAL_ADDR => x"48",
+ REGIO_COMPILE_TIME => std_logic_vector(to_unsigned(VERSION_NUMBER_TIME, 32)),
+ REGIO_HARDWARE_VERSION => x"9100_6000",
+ REGIO_INIT_ADDRESS => x"1100",
+ REGIO_USE_VAR_ENDPOINT_ID => c_YES,
+ CLOCK_FREQUENCY => 125,
+ TIMING_TRIGGER_RAW => c_YES,
+ --Configure data handler
+ DATA_INTERFACE_NUMBER => NumberFEECards, --number of FEE Cards
+ DATA_BUFFER_DEPTH => 13, --13
+ DATA_BUFFER_WIDTH => 32,
+ DATA_BUFFER_FULL_THRESH => 2**13-800, --2**13-1024
+ TRG_RELEASE_AFTER_DATA => c_YES,
+ HEADER_BUFFER_DEPTH => 9,
+ HEADER_BUFFER_FULL_THRESH => 2**9-16
+ )
+ port map(
+ CLK => clk_100_i,
+ RESET => reset_i,
+ CLK_EN => '1',
+ MED_DATAREADY_OUT => med_dataready_out, -- open, --
+ MED_DATA_OUT => med_data_out, -- open, --
+ MED_PACKET_NUM_OUT => med_packet_num_out, -- open, --
+ MED_READ_IN => med_read_in,
+ MED_DATAREADY_IN => med_dataready_in,
+ MED_DATA_IN => med_data_in,
+ MED_PACKET_NUM_IN => med_packet_num_in,
+ MED_READ_OUT => med_read_out, -- open, --
+ MED_STAT_OP_IN => med_stat_op,
+ MED_CTRL_OP_OUT => med_ctrl_op,
+
+ --Timing trigger in
+ TRG_TIMING_TRG_RECEIVED_IN => timing_trg_received_i,
+ --LVL1 trigger to FEE
+ LVL1_TRG_DATA_VALID_OUT => trg_data_valid_i,
+ LVL1_VALID_TIMING_TRG_OUT => trg_timing_valid_i,
+ LVL1_VALID_NOTIMING_TRG_OUT => trg_notiming_valid_i,
+ LVL1_INVALID_TRG_OUT => trg_invalid_i,
+
+ LVL1_TRG_TYPE_OUT => trg_type_i,
+ LVL1_TRG_NUMBER_OUT => trg_number_i,
+ LVL1_TRG_CODE_OUT => trg_code_i,
+ LVL1_TRG_INFORMATION_OUT => trg_information_i,
+ LVL1_INT_TRG_NUMBER_OUT => trg_int_number_i,
+
+ --Information about trigger handler errors
+ TRG_MULTIPLE_TRG_OUT => trg_multiple_trg_i,
+ TRG_TIMEOUT_DETECTED_OUT => trg_timeout_detected_i,
+ TRG_SPURIOUS_TRG_OUT => trg_spurious_trg_i,
+ TRG_MISSING_TMG_TRG_OUT => trg_missing_tmg_trg_i,
+ TRG_SPIKE_DETECTED_OUT => trg_spike_detected_i,
+
+ --Response from FEE, i.e. MuPix
+ FEE_TRG_RELEASE_IN(0) => fee_trg_release_i(0),
+ FEE_TRG_STATUSBITS_IN(0*32+31 downto 0*32) => fee_trg_statusbits_i(0*32+31 downto 0*32),
+ FEE_DATA_IN(0*32+31 downto 0*32) => fee_data_i(0*32+31 downto 0*32),
+ FEE_DATA_WRITE_IN(0) => fee_data_write_i(0),
+ FEE_DATA_FINISHED_IN(0) => fee_data_finished_i(0),
+ FEE_DATA_ALMOST_FULL_OUT(0) => fee_almost_full_i(0),
+
+ -- Slow Control Data Port
+ REGIO_COMMON_STAT_REG_IN => common_stat_reg, --0x00
+ REGIO_COMMON_CTRL_REG_OUT => common_ctrl_reg, --0x20
+ REGIO_COMMON_STAT_STROBE_OUT => common_stat_reg_strobe,
+ REGIO_COMMON_CTRL_STROBE_OUT => common_ctrl_reg_strobe,
+ REGIO_STAT_REG_IN => stat_reg, --start 0x80
+ REGIO_CTRL_REG_OUT => ctrl_reg, --start 0xc0
+ REGIO_STAT_STROBE_OUT => stat_reg_strobe,
+ REGIO_CTRL_STROBE_OUT => ctrl_reg_strobe,
+ REGIO_VAR_ENDPOINT_ID(1 downto 0) => CODE_LINE,
+ REGIO_VAR_ENDPOINT_ID(15 downto 2) => (others => '0'),
+
+ BUS_ADDR_OUT => regio_addr_out,
+ BUS_READ_ENABLE_OUT => regio_read_enable_out,
+ BUS_WRITE_ENABLE_OUT => regio_write_enable_out,
+ BUS_DATA_OUT => regio_data_out,
+ BUS_DATA_IN => regio_data_in,
+ BUS_DATAREADY_IN => regio_dataready_in,
+ BUS_NO_MORE_DATA_IN => regio_no_more_data_in,
+ BUS_WRITE_ACK_IN => regio_write_ack_in,
+ BUS_UNKNOWN_ADDR_IN => regio_unknown_addr_in,
+ BUS_TIMEOUT_OUT => regio_timeout_out,
+ ONEWIRE_INOUT => TEMPSENS,
+ ONEWIRE_MONITOR_OUT => open,
+
+ TIME_GLOBAL_OUT => global_time,
+ TIME_LOCAL_OUT => local_time,
+ TIME_SINCE_LAST_TRG_OUT => time_since_last_trg,
+ TIME_TICKS_OUT => timer_ticks,
+
+ STAT_DEBUG_IPU => open,
+ STAT_DEBUG_1 => open,
+ STAT_DEBUG_2 => open,
+ STAT_DEBUG_DATA_HANDLER_OUT => open,
+ STAT_DEBUG_IPU_HANDLER_OUT => open,
+ STAT_TRIGGER_OUT => open,
+ CTRL_MPLEX => (others => '0'),
+ IOBUF_CTRL_GEN => (others => '0'),
+ STAT_ONEWIRE => open,
+ STAT_ADDR_DEBUG => open,
+ DEBUG_LVL1_HANDLER_OUT => open
+ );
+
+ timing_trg_received_i <= TRIGGER_LEFT;
+
+---------------------------------------------------------------------------
+-- AddOn
+---------------------------------------------------------------------------
+
+---------------------------------------------------------------------------
+-- Bus Handler
+---------------------------------------------------------------------------
+ THE_BUS_HANDLER : trb_net16_regio_bus_handler
+ generic map(
+ PORT_NUMBER => 4,
+ PORT_ADDRESSES => (0 => x"d000",
+ 1 => x"d100",
+ 2 => x"8000", --Mupix 0
+ 3 => x"c000", --Reset
+ others => x"0000"),
+ PORT_ADDR_MASK => (0 => 1,
+ 1 => 6,
+ 2 => 12,
+ 3 => 12,
+ others => 0)
+ )
+ port map(
+ CLK => clk_100_i,
+ RESET => reset_i,
+
+ DAT_ADDR_IN => regio_addr_out,
+ DAT_DATA_IN => regio_data_out,
+ DAT_DATA_OUT => regio_data_in,
+ DAT_READ_ENABLE_IN => regio_read_enable_out,
+ DAT_WRITE_ENABLE_IN => regio_write_enable_out,
+ DAT_TIMEOUT_IN => regio_timeout_out,
+ DAT_DATAREADY_OUT => regio_dataready_in,
+ DAT_WRITE_ACK_OUT => regio_write_ack_in,
+ DAT_NO_MORE_DATA_OUT => regio_no_more_data_in,
+ DAT_UNKNOWN_ADDR_OUT => regio_unknown_addr_in,
+
+ --Bus Handler (SPI CTRL)
+ BUS_READ_ENABLE_OUT(0) => spictrl_read_en,
+ BUS_WRITE_ENABLE_OUT(0) => spictrl_write_en,
+ BUS_DATA_OUT(0*32+31 downto 0*32) => spictrl_data_in,
+ BUS_ADDR_OUT(0*16) => spictrl_addr,
+ BUS_ADDR_OUT(0*16+15 downto 0*16+1) => open,
+ BUS_TIMEOUT_OUT(0) => open,
+ BUS_DATA_IN(0*32+31 downto 0*32) => spictrl_data_out,
+ BUS_DATAREADY_IN(0) => spictrl_ack,
+ BUS_WRITE_ACK_IN(0) => spictrl_ack,
+ BUS_NO_MORE_DATA_IN(0) => spictrl_busy,
+ BUS_UNKNOWN_ADDR_IN(0) => '0',
+
+ --Bus Handler (SPI Memory)
+ BUS_READ_ENABLE_OUT(1) => spimem_read_en,
+ BUS_WRITE_ENABLE_OUT(1) => spimem_write_en,
+ BUS_DATA_OUT(1*32+31 downto 1*32) => spimem_data_in,
+ BUS_ADDR_OUT(1*16+5 downto 1*16) => spimem_addr,
+ BUS_ADDR_OUT(1*16+15 downto 1*16+6) => open,
+ BUS_TIMEOUT_OUT(1) => open,
+ BUS_DATA_IN(1*32+31 downto 1*32) => spimem_data_out,
+ BUS_DATAREADY_IN(1) => spimem_ack,
+ BUS_WRITE_ACK_IN(1) => spimem_ack,
+ BUS_NO_MORE_DATA_IN(1) => '0',
+ BUS_UNKNOWN_ADDR_IN(1) => '0',
+
+ --Bus Handler (MuPix trb_net16_regio_bus_handler)
+ BUS_READ_ENABLE_OUT(2) => mu_regio_read_enable_in_0,
+ BUS_WRITE_ENABLE_OUT(2) => mu_regio_write_enable_in_0,
+ BUS_DATA_OUT(2*32+31 downto 2*32) => mu_regio_data_in_0,
+ BUS_ADDR_OUT(2*16+11 downto 2*16) => mu_regio_addr_in_0(11 downto 0),
+ BUS_ADDR_OUT(2*16+15 downto 2*16+12) => open,
+ BUS_TIMEOUT_OUT(2) => open,
+ BUS_DATA_IN(2*32+31 downto 2*32) => mu_regio_data_out_0,
+ BUS_DATAREADY_IN(2) => mu_regio_dataready_out_0,
+ BUS_WRITE_ACK_IN(2) => mu_regio_write_ack_out_0,
+ BUS_NO_MORE_DATA_IN(2) => mu_regio_no_more_data_out_0,
+ BUS_UNKNOWN_ADDR_IN(2) => mu_regio_unknown_addr_out_0,
+
+ --Common Reset
+ BUS_READ_ENABLE_OUT(3) => resethandler_regio_read_enable_in_0,
+ BUS_WRITE_ENABLE_OUT(3) => resethandler_regio_write_enable_in_0,
+ BUS_DATA_OUT(3*32+31 downto 3*32) => resethandler_regio_data_in_0,
+ BUS_ADDR_OUT(3*16+11 downto 3*16) => resethandler_regio_addr_in_0(11 downto 0),
+ BUS_ADDR_OUT(3*16+15 downto 3*16+12) => open,
+ BUS_TIMEOUT_OUT(3) => open,
+ BUS_DATA_IN(3*32+31 downto 3*32) => resethandler_regio_data_out_0,
+ BUS_DATAREADY_IN(3) => resethandler_regio_ack_out_0,
+ BUS_WRITE_ACK_IN(3) => resethandler_regio_ack_out_0,
+ BUS_NO_MORE_DATA_IN(3) => resethandler_regio_no_more_data_out_0,
+ BUS_UNKNOWN_ADDR_IN(3) => resethandler_regio_unknown_addr_out_0,
+
+ STAT_DEBUG => open
+ );
+
+---------------------------------------------------------------------------
+-- SPI / Flash
+---------------------------------------------------------------------------
+ THE_SPI_MASTER : spi_master
+ port map(
+ CLK_IN => clk_100_i,
+ RESET_IN => reset_i,
+ -- Slave bus
+ BUS_READ_IN => spictrl_read_en,
+ BUS_WRITE_IN => spictrl_write_en,
+ BUS_BUSY_OUT => spictrl_busy,
+ BUS_ACK_OUT => spictrl_ack,
+ BUS_ADDR_IN(0) => spictrl_addr,
+ BUS_DATA_IN => spictrl_data_in,
+ BUS_DATA_OUT => spictrl_data_out,
+ -- SPI connections
+ SPI_CS_OUT => FLASH_CS,
+ SPI_SDI_IN => FLASH_DOUT,
+ SPI_SDO_OUT => FLASH_DIN,
+ SPI_SCK_OUT => FLASH_CLK,
+ -- BRAM for read/write data
+ BRAM_A_OUT => spi_bram_addr,
+ BRAM_WR_D_IN => spi_bram_wr_d,
+ BRAM_RD_D_OUT => spi_bram_rd_d,
+ BRAM_WE_OUT => spi_bram_we,
+ -- Status lines
+ STAT => open
+ );
+
+ -- data memory for SPI accesses
+ THE_SPI_MEMORY : spi_databus_memory
+ port map(
+ CLK_IN => clk_100_i,
+ RESET_IN => reset_i,
+ -- Slave bus
+ BUS_ADDR_IN => spimem_addr,
+ BUS_READ_IN => spimem_read_en,
+ BUS_WRITE_IN => spimem_write_en,
+ BUS_ACK_OUT => spimem_ack,
+ BUS_DATA_IN => spimem_data_in,
+ BUS_DATA_OUT => spimem_data_out,
+ -- state machine connections
+ BRAM_ADDR_IN => spi_bram_addr,
+ BRAM_WR_D_OUT => spi_bram_wr_d,
+ BRAM_RD_D_IN => spi_bram_rd_d,
+ BRAM_WE_IN => spi_bram_we,
+ -- Status lines
+ STAT => open
+ );
+
+---------------------------------------------------------------------------
+-- Reboot FPGA
+---------------------------------------------------------------------------
+ THE_FPGA_REBOOT : fpga_reboot
+ port map(
+ CLK => clk_100_i,
+ RESET => reset_i,
+ DO_REBOOT => common_ctrl_reg(15),
+ PROGRAMN => PROGRAMN
+ );
+
+---------------------------------------------------------------------------
+-- LED
+---------------------------------------------------------------------------
+ LED_GREEN <= not med_stat_op(9);
+ LED_ORANGE <= not med_stat_op(10);
+ LED_RED <= timing_trg_received_i;
+ LED_YELLOW <= not med_stat_op(11);
+
+-----------------------------------------------------------------------------
+-- MuPix Frontend-Board
+-----------------------------------------------------------------------------
+ MuPix3_Board_0 : MuPix3_Board
+ port map (
+ clk => clk_100_i,
+ fast_clk => clk_200_i,
+ reset => reset_i,
+
+ timestampreset_in => reset_timestamps_i,
+ eventcounterreset_in => reset_eventcounters_i,
+
+ TIMING_TRG_IN => TRIGGER_RIGHT,
+ LVL1_TRG_DATA_VALID_IN => trg_data_valid_i,
+ LVL1_VALID_TIMING_TRG_IN => trg_timing_valid_i,
+ LVL1_VALID_NOTIMING_TRG_IN => trg_notiming_valid_i,
+ LVL1_INVALID_TRG_IN => trg_invalid_i,
+ LVL1_TRG_TYPE_IN => trg_type_i,
+ LVL1_TRG_NUMBER_IN => trg_number_i,
+ LVL1_TRG_CODE_IN => trg_code_i,
+ LVL1_TRG_INFORMATION_IN => trg_information_i,
+ LVL1_INT_TRG_NUMBER_IN => trg_int_number_i,
+
+ FEE_TRG_RELEASE_OUT => fee_trg_release_i(0),
+ FEE_TRG_STATUSBITS_OUT => fee_trg_statusbits_i(0*32+31 downto 0*32),
+ FEE_DATA_OUT => fee_data_i(0*32+31 downto 0*32),
+ FEE_DATA_WRITE_OUT => fee_data_write_i(0),
+ FEE_DATA_FINISHED_OUT => fee_data_finished_i(0),
+ FEE_DATA_ALMOST_FULL_IN => fee_almost_full_i(0),
+
+ REGIO_ADDR_IN => mu_regio_addr_in_0,
+ REGIO_DATA_IN => mu_regio_data_in_0,
+ REGIO_DATA_OUT => mu_regio_data_out_0,
+ REGIO_READ_ENABLE_IN => mu_regio_read_enable_in_0,
+ REGIO_WRITE_ENABLE_IN => mu_regio_write_enable_in_0,
+ REGIO_TIMEOUT_IN => mu_regio_timeout_in_0,
+ REGIO_DATAREADY_OUT => mu_regio_dataready_out_0,
+ REGIO_WRITE_ACK_OUT => mu_regio_write_ack_out_0,
+ REGIO_NO_MORE_DATA_OUT => mu_regio_no_more_data_out_0,
+ REGIO_UNKNOWN_ADDR_OUT => mu_regio_unknown_addr_out_0);
+
+ resethandler_1 : entity work.resethandler
+ port map (
+ CLK_IN => clk_100_i,
+ RESET_IN => reset_i,
+ TimestampReset_OUT => reset_timestamps_i,
+ EventCounterReset_OUT => reset_eventcounters_i,
+ SLV_READ_IN => resethandler_regio_read_enable_in_0,
+ SLV_WRITE_IN => resethandler_regio_write_enable_in_0,
+ SLV_DATA_OUT => resethandler_regio_data_out_0,
+ SLV_DATA_IN => resethandler_regio_data_in_0,
+ SLV_ADDR_IN => resethandler_regio_addr_in_0,
+ SLV_ACK_OUT => resethandler_regio_ack_out_0,
+ SLV_NO_MORE_DATA_OUT => resethandler_regio_no_more_data_out_0,
+ SLV_UNKNOWN_ADDR_OUT => resethandler_regio_unknown_addr_out_0);
+
+end architecture;