]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
partial commit of initial mupix 8 source code and test benches.
authorTobias Weber <toweber86@gmail.com>
Tue, 10 Oct 2017 08:47:42 +0000 (10:47 +0200)
committerTobias Weber <toweber86@gmail.com>
Tue, 10 Oct 2017 08:47:42 +0000 (10:47 +0200)
24 files changed:
base/trb3_periph_mupix6.lpf [moved from base/trb3_periph_mupix.lpf with 100% similarity]
mupix/Mupix8/sources/ADS1018SPI.vhd [new file with mode: 0644]
mupix/Mupix8/sources/BlockMemory.vhd [new file with mode: 0644]
mupix/Mupix8/sources/CRC.vhd [new file with mode: 0644]
mupix/Mupix8/sources/FIFO.vhd [new file with mode: 0644]
mupix/Mupix8/sources/GrayCounter.vhd [new file with mode: 0644]
mupix/Mupix8/sources/Histogram.vhd [new file with mode: 0644]
mupix/Mupix8/sources/HitbusHistogram.vhd [new file with mode: 0644]
mupix/Mupix8/sources/InputSynchronizer.vhd [new file with mode: 0644]
mupix/Mupix8/sources/LTC1658SPI.vhd [new file with mode: 0644]
mupix/Mupix8/sources/MupixBoard.vhd [new file with mode: 0644]
mupix/Mupix8/sources/MupixBoardDAC.vhd [new file with mode: 0644]
mupix/Mupix8/sources/MupixBoardInterface.vhd [new file with mode: 0644]
mupix/Mupix8/sources/PixelControl.vhd [new file with mode: 0644]
mupix/Mupix8/sources/SignalDelay.vhd [new file with mode: 0644]
mupix/Mupix8/sources/TestpulseGenerator.vhd [new file with mode: 0644]
mupix/Mupix8/sources/TriggerHandler.vhd [new file with mode: 0644]
mupix/Mupix8/tb/CRCTest.vhd [new file with mode: 0644]
mupix/Mupix8/tb/HitbusHistogramTest.vhd [new file with mode: 0644]
mupix/Mupix8/tb/LTC1658SPITest.vhd [new file with mode: 0644]
mupix/Mupix8/tb/MupixShiftReg.vhd [new file with mode: 0644]
mupix/Mupix8/tb/PixCtrlTest.vhd [new file with mode: 0644]
mupix/Mupix8/tb/TRBSimulation.vhd [new file with mode: 0644]
mupix/Mupix8/trb3_periph.vhd [new file with mode: 0644]

diff --git a/mupix/Mupix8/sources/ADS1018SPI.vhd b/mupix/Mupix8/sources/ADS1018SPI.vhd
new file mode 100644 (file)
index 0000000..0af2474
--- /dev/null
@@ -0,0 +1,32 @@
+----------------------------------------------------------------------------------
+-- 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;
diff --git a/mupix/Mupix8/sources/BlockMemory.vhd b/mupix/Mupix8/sources/BlockMemory.vhd
new file mode 100644 (file)
index 0000000..8be5746
--- /dev/null
@@ -0,0 +1,37 @@
+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;
+
diff --git a/mupix/Mupix8/sources/CRC.vhd b/mupix/Mupix8/sources/CRC.vhd
new file mode 100644 (file)
index 0000000..9803375
--- /dev/null
@@ -0,0 +1,70 @@
+-------------------------------------------------------------------------------
+--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
diff --git a/mupix/Mupix8/sources/FIFO.vhd b/mupix/Mupix8/sources/FIFO.vhd
new file mode 100644 (file)
index 0000000..2d286aa
--- /dev/null
@@ -0,0 +1,100 @@
+-------------------------------------------------------------------------------
+--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;
diff --git a/mupix/Mupix8/sources/GrayCounter.vhd b/mupix/Mupix8/sources/GrayCounter.vhd
new file mode 100644 (file)
index 0000000..2722c1a
--- /dev/null
@@ -0,0 +1,83 @@
+-- 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;
diff --git a/mupix/Mupix8/sources/Histogram.vhd b/mupix/Mupix8/sources/Histogram.vhd
new file mode 100644 (file)
index 0000000..e2e0e15
--- /dev/null
@@ -0,0 +1,131 @@
+----------------------------------------------------------------------------
+-- 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;
+
diff --git a/mupix/Mupix8/sources/HitbusHistogram.vhd b/mupix/Mupix8/sources/HitbusHistogram.vhd
new file mode 100644 (file)
index 0000000..191ddb1
--- /dev/null
@@ -0,0 +1,300 @@
+-------------------------------------------------------------------------------
+--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;
+
diff --git a/mupix/Mupix8/sources/InputSynchronizer.vhd b/mupix/Mupix8/sources/InputSynchronizer.vhd
new file mode 100644 (file)
index 0000000..e1eae6d
--- /dev/null
@@ -0,0 +1,39 @@
+----------------------------------------------------------------------------
+-- 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;
diff --git a/mupix/Mupix8/sources/LTC1658SPI.vhd b/mupix/Mupix8/sources/LTC1658SPI.vhd
new file mode 100644 (file)
index 0000000..20a6df9
--- /dev/null
@@ -0,0 +1,128 @@
+----------------------------------------------------------------------------------
+-- 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;
diff --git a/mupix/Mupix8/sources/MupixBoard.vhd b/mupix/Mupix8/sources/MupixBoard.vhd
new file mode 100644 (file)
index 0000000..c6c44f8
--- /dev/null
@@ -0,0 +1,362 @@
+-------------------------------------------------------------------------------
+--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;
diff --git a/mupix/Mupix8/sources/MupixBoardDAC.vhd b/mupix/Mupix8/sources/MupixBoardDAC.vhd
new file mode 100644 (file)
index 0000000..7690f23
--- /dev/null
@@ -0,0 +1,219 @@
+-----------------------------------------------------------------------------------
+-- 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;
diff --git a/mupix/Mupix8/sources/MupixBoardInterface.vhd b/mupix/Mupix8/sources/MupixBoardInterface.vhd
new file mode 100644 (file)
index 0000000..9d2c70f
--- /dev/null
@@ -0,0 +1,88 @@
+----------------------------------------------------------------------------
+-- 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;
diff --git a/mupix/Mupix8/sources/PixelControl.vhd b/mupix/Mupix8/sources/PixelControl.vhd
new file mode 100644 (file)
index 0000000..75b4aac
--- /dev/null
@@ -0,0 +1,378 @@
+-------------------------------------------------------------------------------
+--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;
+
+
diff --git a/mupix/Mupix8/sources/SignalDelay.vhd b/mupix/Mupix8/sources/SignalDelay.vhd
new file mode 100644 (file)
index 0000000..808b003
--- /dev/null
@@ -0,0 +1,44 @@
+------------------------------------------------------------
+--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;
diff --git a/mupix/Mupix8/sources/TestpulseGenerator.vhd b/mupix/Mupix8/sources/TestpulseGenerator.vhd
new file mode 100644 (file)
index 0000000..fab7a5d
--- /dev/null
@@ -0,0 +1,118 @@
+-----------------------------------------------------------------------------
+-- 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;
diff --git a/mupix/Mupix8/sources/TriggerHandler.vhd b/mupix/Mupix8/sources/TriggerHandler.vhd
new file mode 100644 (file)
index 0000000..dd260c5
--- /dev/null
@@ -0,0 +1,427 @@
+-----------------------------------------------------------------------------
+-- 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;
diff --git a/mupix/Mupix8/tb/CRCTest.vhd b/mupix/Mupix8/tb/CRCTest.vhd
new file mode 100644 (file)
index 0000000..46acdc1
--- /dev/null
@@ -0,0 +1,67 @@
+-------------------------------------------------------------------------------
+--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;
diff --git a/mupix/Mupix8/tb/HitbusHistogramTest.vhd b/mupix/Mupix8/tb/HitbusHistogramTest.vhd
new file mode 100644 (file)
index 0000000..b788f08
--- /dev/null
@@ -0,0 +1,120 @@
+------------------------------------------------------------
+--! @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;
diff --git a/mupix/Mupix8/tb/LTC1658SPITest.vhd b/mupix/Mupix8/tb/LTC1658SPITest.vhd
new file mode 100644 (file)
index 0000000..feb8703
--- /dev/null
@@ -0,0 +1,99 @@
+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;
diff --git a/mupix/Mupix8/tb/MupixShiftReg.vhd b/mupix/Mupix8/tb/MupixShiftReg.vhd
new file mode 100644 (file)
index 0000000..687d67f
--- /dev/null
@@ -0,0 +1,46 @@
+------------------------------------------------------------
+--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;
+
diff --git a/mupix/Mupix8/tb/PixCtrlTest.vhd b/mupix/Mupix8/tb/PixCtrlTest.vhd
new file mode 100644 (file)
index 0000000..798a27e
--- /dev/null
@@ -0,0 +1,121 @@
+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;
diff --git a/mupix/Mupix8/tb/TRBSimulation.vhd b/mupix/Mupix8/tb/TRBSimulation.vhd
new file mode 100644 (file)
index 0000000..2e8dfce
--- /dev/null
@@ -0,0 +1,66 @@
+------------------------------------------------------------
+--! @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
diff --git a/mupix/Mupix8/trb3_periph.vhd b/mupix/Mupix8/trb3_periph.vhd
new file mode 100644 (file)
index 0000000..ffe53db
--- /dev/null
@@ -0,0 +1,691 @@
+-------------------------------------------------------------------------------
+--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;