]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
first compiling version of complete firmware. However untested in hardware and a...
authorTobias Weber <toweber86@gmail.com>
Thu, 8 Feb 2018 02:51:57 +0000 (03:51 +0100)
committerTobias Weber <toweber86@gmail.com>
Thu, 8 Feb 2018 02:51:57 +0000 (03:51 +0100)
base/trb3_periph_mupix8.lpf
mupix/.gitignore
mupix/Mupix8/sources/InputSynchronizer.vhd
mupix/Mupix8/sources/MupixBoard.vhd
mupix/Mupix8/sources/MupixBoardInterface.vhd
mupix/Mupix8/sources/MupixDataLink.vhd
mupix/Mupix8/sources/TriggerHandler.vhd
mupix/Mupix8/trb3_periph.prj
mupix/Mupix8/trb3_periph.vhd

index a1816f7574a930e5607c3428b263d55560762f48..78a65b76939c0a0e3d7957a6f91e23b8b260fa54 100644 (file)
@@ -112,6 +112,8 @@ IOBUF GROUP "LED_group" IO_TYPE=LVCMOS25 PULLMODE=NONE DRIVE=12;
 #################################################################
 #MuPix 8
 #################################################################
+LOCATE COMP "mupix_data_link/the_mupix_serdes/PCSD_INST" SITE "PCSB";
+
 LOCATE COMP "led_addon_0" SITE "P1";
 LOCATE COMP "led_addon_1" SITE "P2";
 LOCATE COMP "led_addon_2" SITE "T2";
index ad4f9f39a454adc427e5ec1d51236007a92703fc..7cce73c1648d03531396085d016975cc02b1a95f 100644 (file)
@@ -3,4 +3,5 @@ XilinxProjects
 .settings
 .library_mapping.xml
 .project
-.directory
\ No newline at end of file
+.directory
+vivado*
\ No newline at end of file
index e1eae6d44b34c1903190e4424d77afb83cfcf14e..dc859550c81931573cfe7468c51a5b7d8af6f01d 100644 (file)
@@ -8,18 +8,19 @@
  use ieee.numeric_std.all;
  
  entity InputSynchronizer is
-       generic(depth : integer := 2);
+       generic(depth : integer := 2;
+                   width : integer := 1);
        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
+               clk         : in  std_logic;   --input clock
+               rst         : in  std_logic;    --reset
+               input       : in  std_logic_vector(width - 1 downto 0); --asynchronous input signal
+               sync_output : out std_logic_vector(width - 1 downto 0)  --synchronized signal
        );
  end entity InputSynchronizer;
  
 architecture RTL of InputSynchronizer is
        
-       signal syncstage : std_logic_vector(depth - 1 downto 0) := (others => '0');
+       signal syncstage : std_logic_vector(width*depth - 1 downto 0) := (others => '0');
        
 begin
        
@@ -29,11 +30,11 @@ begin
                        if rst = '1' then
                                syncstage <= (others => '0');
                        else
-                               syncstage <= syncstage(depth - 2 downto 0) & input;
+                               syncstage <= syncstage((depth - 1)*width - 1 downto 0) & input;
                        end if;
                end if;
        end process sync_process;
        
-       sync_output <= syncstage(depth - 1);
+       sync_output <= syncstage(depth*width - 1 downto (depth - 1)*width);
        
 end architecture RTL;
index e5a03e06c72928b16aa626e2e8c2694c5715e3c9..3e86b3696346cbc16f87295d3cb7c7fcbc804bc8 100644 (file)
@@ -38,10 +38,10 @@ entity MupixBoard8 is
     hitbus              :  in  std_logic; --hitbus signal
     
     --connections to data fifos
-    --fifo_rden          : out  std_logic_vector(3 downto 0); -- read enable to mupix data FIFOs
-    --fifo_empty         : in std_logic_vector(3 downto 0); -- mupix data FIFO empty flags
-    --fifo_full          : in std_logic_vector(3 downto 0); -- mupix data FIFO full flags
-    --fifo_data          : in std_logic_vector(127 downto 0); -- mupix readout data from FIFOs
+    fifo_rden          : out  std_logic_vector(3 downto 0); -- read enable to mupix data FIFOs
+    fifo_empty         : in std_logic_vector(3 downto 0); -- mupix data FIFO empty flags
+    fifo_full          : in std_logic_vector(3 downto 0); -- mupix data FIFO full flags
+    fifo_data          : in std_logic_vector(127 downto 0); -- mupix readout data from FIFOs
     
     --resets
     timestampreset_in    : in std_logic;  --time stamp reset
@@ -195,10 +195,70 @@ architecture Behavioral of MupixBoard8 is
                        SLV_NO_MORE_DATA_OUT : out std_logic;
                        SLV_UNKNOWN_ADDR_OUT : out std_logic);
        end component MupixBoardDAC;
+       
+       component MupixTRBReadout
+               generic(
+                       g_mupix_links           : natural := 4;
+                       g_cyc_mem_address_width : integer := 13;
+                       g_datawidth             : integer := 32
+               );
+               port(
+                       clk                  : in  std_logic;
+                       rst                  : in  std_logic;
+                       fifo_empty           : in  std_logic_vector(g_mupix_links - 1 downto 0);
+                       fifo_full            : in  std_logic_vector(g_mupix_links - 1 downto 0);
+                       fifo_datain          : in  std_logic_vector(g_mupix_links*g_datawidth - 1 downto 0);
+                       fifo_rden            : out std_logic_vector(g_mupix_links - 1 downto 0);
+                       trb_trigger          : in  std_logic;
+                       dataout              : out std_logic_vector(g_datawidth - 1 downto 0);
+                       data_valid           : out std_logic;
+                       busy                 : out 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 MupixTRBReadout;
+       
+       component TriggerHandler
+               port(
+                       CLK_IN                      : in  std_logic;
+                       RESET_IN                    : in  std_logic;
+                       TIMING_TRIGGER_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);
+                       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_BUSY_BUFFER_READ_IN : in  std_logic;
+                       VALID_TRIGGER_OUT           : out 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 TriggerHandler;
 
 --signal declarations
 -- Bus Handler
-  constant NUM_PORTS : integer := 3;
+  constant NUM_PORTS : integer := 5;
 
   signal slv_read         : std_logic_vector(NUM_PORTS-1 downto 0);
   signal slv_write        : std_logic_vector(NUM_PORTS-1 downto 0);
@@ -209,7 +269,10 @@ architecture Behavioral of MupixBoard8 is
   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);
 
-       
+  signal trb_trigger_i       : std_logic;
+  signal mupixreadout_busy_i : std_logic;
+  signal mupixdata_valid_i   : std_logic;
+  signal mupixdata_i         : std_logic_vector(31 downto 0);
 
 begin  -- Behavioral
 
@@ -225,11 +288,15 @@ begin  -- Behavioral
           0      => x"0070",            -- Hitbus Histograms       
           1      => x"0080",            -- Mupix DAC and Pixel Control
           2      => x"0090",            -- Board Control
+          3      => x"0100",            -- mupix readout
+          4      => x"0120",            -- mupix readout
           others => x"0000"),
         PORT_ADDR_MASK => (
           0      => 4,                  -- HitBus Histograms        
           1      => 4,                  -- Mupix DAC and Pixel Control
           2      => 4,                  -- Board Control
+          3      => 8,                  -- mupix readout
+          4      => 8,                  -- mupix readout
           others => 0)
        --PORT_MASK_ENABLE => 1
       )
@@ -377,6 +444,62 @@ begin  -- Behavioral
                                        end if;
                                end process spi_output_pipe;
                                
-                               
+       mupixreadout1 : entity work.MupixTRBReadout
+               generic map(
+                       g_mupix_links           => 4,
+                       g_cyc_mem_address_width => 12,
+                       g_datawidth             => 32
+               )
+               port map(
+                       clk                  => clk,
+                       rst                  => reset,
+                       fifo_empty           => fifo_empty,
+                       fifo_full            => fifo_full,
+                       fifo_datain          => fifo_data,
+                       fifo_rden            => fifo_rden,
+                       trb_trigger          => trb_trigger_i,
+                       dataout              => mupixdata_i,
+                       data_valid           => mupixdata_valid_i,
+                       busy                 => mupixreadout_busy_i,
+                       SLV_READ_IN          => slv_read(3),
+                       SLV_WRITE_IN         => slv_write(3),
+                       SLV_DATA_OUT         => slv_data_rd(3*32 + 31 downto 3*32),
+                       SLV_DATA_IN          => slv_data_wr(3*32 + 31 downto 3*32),
+                       SLV_ADDR_IN          => slv_addr(3*16 + 15 downto 3*16),
+                       SLV_ACK_OUT          => slv_ack(3),
+                       SLV_NO_MORE_DATA_OUT => slv_no_more_data(3),
+                       SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(3)
+               );
+               
+               triggerhandler1 : entity work.TriggerHandler
+                       port map(
+                               CLK_IN                      => clk,
+                               RESET_IN                    => reset,
+                               TIMING_TRIGGER_IN           => TIMING_TRG_IN,
+                               LVL1_TRG_DATA_VALID_IN      => LVL1_TRG_DATA_VALID_IN,
+                               LVL1_VALID_TIMING_TRG_IN    => LVL1_VALID_TIMING_TRG_IN,
+                               LVL1_VALID_NOTIMING_TRG_IN  => LVL1_VALID_NOTIMING_TRG_IN,
+                               LVL1_INVALID_TRG_IN         => LVL1_INVALID_TRG_IN,
+                               LVL1_TRG_TYPE_IN            => LVL1_TRG_TYPE_IN,
+                               LVL1_TRG_NUMBER_IN          => LVL1_TRG_NUMBER_IN,
+                               LVL1_TRG_CODE_IN            => LVL1_TRG_CODE_IN,
+                               FEE_DATA_OUT                => FEE_DATA_OUT,
+                               FEE_DATA_WRITE_OUT          => FEE_DATA_WRITE_OUT,
+                               FEE_DATA_FINISHED_OUT       => FEE_DATA_FINISHED_OUT,
+                               FEE_TRG_RELEASE_OUT         => FEE_TRG_RELEASE_OUT,
+                               FEE_TRG_STATUSBITS_OUT      => FEE_TRG_STATUSBITS_OUT,
+                               FEE_DATA_0_IN               => mupixdata_i,
+                               FEE_DATA_WRITE_0_IN         => mupixdata_valid_i,
+                               TRIGGER_BUSY_BUFFER_READ_IN => mupixreadout_busy_i,
+                               VALID_TRIGGER_OUT           => trb_trigger_i,
+                               SLV_READ_IN                     => slv_read(4),
+                               SLV_WRITE_IN                    => slv_write(4),
+                               SLV_DATA_OUT                    => slv_data_rd(4*32 + 31 downto 4*32),
+                               SLV_DATA_IN                     => slv_data_wr(4*32 + 31 downto 4*32),
+                               SLV_ADDR_IN                     => slv_addr(4*16 + 15 downto 4*16),
+                               SLV_ACK_OUT                     => slv_ack(4),
+                               SLV_NO_MORE_DATA_OUT            => slv_no_more_data(4),
+                               SLV_UNKNOWN_ADDR_OUT            => slv_unknown_addr(4)
+                       );
 
 end Behavioral;
index 6701d58a216ac481252c4a1621c3a81fac1390de..7c2f5734bda737c045a869bd63ad68776df3670f 100644 (file)
@@ -38,51 +38,51 @@ architecture rtl of MupixBoardInterface is
 
 
        component InputSynchronizer
-               generic(depth : integer);
+               generic(depth : integer := 2;
+                       width : integer := 1);
                port(
-                       clk         : in  std_logic;
-                       rst         : in  std_logic;
-                       input       : in  std_logic;
-                       sync_output : out std_logic
-               );
+               clk         : in  std_logic;  
+               rst         : in  std_logic; 
+               input       : in  std_logic_vector(width - 1 downto 0); 
+               sync_output : out std_logic_vector(width - 1 downto 0));
        end component InputSynchronizer;
        
 begin
 
        sync_ctrl_dout : component InputSynchronizer
-           generic map(depth => 2)
-               port map(clk_in, reset, ctrl_dout, ctrl_dout_sync);
+           generic map(depth => 2, width => 1)
+               port map(clk => clk_in, rst => reset, input(0) => ctrl_dout, sync_output(0) => 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);
+           generic map(depth => 2, width => 1)
+               port map(clk => clk_in, rst => reset, input(0) => spi_dout_adc, sync_output(0) => 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);
+           generic map(depth => 2, width => 1)
+               port map(clk => clk_in, rst => reset, input(0) => spi_dout_dac, sync_output(0) => spi_dout_dac_sync);
                
        sync_dac4_dout : component InputSynchronizer
-           generic map(depth => 2)
-               port map(clk_in, reset, dac4_dout, dac4_dout_sync);
+           generic map(depth => 2, width => 1)
+               port map(clk => clk_in, rst => reset, input(0) => dac4_dout, sync_output(0) => dac4_dout_sync);
                
        sync_hitbus : component InputSynchronizer
            generic map(depth => 2)
-               port map(clk_in, reset, hitbus, hitbus_sync);
+               port map(clk => clk_in, rst => reset, input(0) => hitbus, sync_output(0) => hitbus_sync);
                
        sync_trigger : component InputSynchronizer
-           generic map(depth => 2)
-               port map(clk_in, reset, trigger, trigger_sync);
+           generic map(depth => 2, width => 1)
+               port map(clk => clk_in, rst => reset, input(0) => trigger, sync_output(0) => trigger_sync);
                
        sync_hit : component InputSynchronizer
-           generic map(depth => 2)
-               port map(clk_in, reset, hit, hit_sync);
+           generic map(depth => 2, width => 1)
+               port map(clk => clk_in, rst => reset, input(0) => hit, sync_output(0) => hit_sync);
                
        sync_fast_hitbus : component InputSynchronizer
-           generic map(depth => 2)
-               port map(fast_clk_in, reset, hitbus, hitbus_sync_fast);
+           generic map(depth => 2, width => 1)
+               port map(clk => fast_clk_in, rst => reset, input(0) => hitbus, sync_output(0) => hitbus_sync_fast);
                
        sync_fast_trigger : component InputSynchronizer
            generic map(depth => 2)
-               port map(fast_clk_in, reset, trigger, trigger_sync_fast);       
+               port map(clk => fast_clk_in, rst => reset, input(0) => trigger, sync_output(0) => trigger_sync_fast);   
                
 end architecture rtl;
index 9db2fcb5c36c17c286d6ffa0da6f5f90251905e4..06a54262c4ab6acda576a99d1e5a901962e6add2 100644 (file)
@@ -29,7 +29,7 @@ entity MupixDataLink is
                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_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;
@@ -51,13 +51,24 @@ architecture rtl of MupixDataLink is
        constant c_serdes_fifo_large_rdcnt_width : integer := 11;
 
        signal data_from_serdes_i        : std_logic_vector(c_used_serdes_channels*c_serdes_data_width - 1 downto 0);
-       signal data_from_fifos_i         : std_logic_vector(127 downto 0);
        signal serdes_fifo_rdcnt_i       : std_logic_vector((c_used_serdes_channels - 1)*c_serdes_fifo_rdcnt_width - 1 downto 0);
        signal serdes_fifo_large_rdcnt_i : std_logic_vector(c_serdes_fifo_large_rdcnt_width - 1 downto 0);
        
        signal rx_los_low_s, rx_los_low_s_sync : std_logic_vector(c_used_serdes_channels - 1 downto 0);
        signal lsm_status_s, lsm_status_s_sync : std_logic_vector(c_used_serdes_channels - 1 downto 0);
        signal rx_cdr_lol_s, rx_cdr_lol_s_sync : std_logic_vector(c_used_serdes_channels - 1 downto 0);
+       signal rx_k                            : std_logic_vector(c_used_serdes_channels - 1 downto 0);
+       signal rx_disp_err                     : std_logic_vector(c_used_serdes_channels - 1 downto 0);
+       signal rx_cv_err                       : std_logic_vector(c_used_serdes_channels - 1 downto 0);
+       
+       signal refclk2core_i : std_logic;
+       signal rx_full_clk   : std_logic_vector(c_used_serdes_channels - 1 downto 0);
+       signal rx_half_clk   : std_logic_vector(c_used_serdes_channels - 1 downto 0);
+       signal rxclk         : std_logic;
+       signal rxrefclk      : std_logic; 
+       
+       signal fifo_wren     : std_logic_vector(3 downto 0) := (others => '0');
+       signal fifo_full_i   : std_logic_vector(3 downto 0) := (others => '0');
        
        component InputSynchronizer
                generic(depth : integer := 2;
@@ -104,20 +115,20 @@ architecture rtl of MupixDataLink is
                port(
                        ------------------                                                                                                                                                                                                                           
                        -- CH0 --                                                                                                                                                                                                                                    
-                       hdinp_ch0, hdinn_ch0 : in  std_logic;
-                       rxiclk_ch0           : in  std_logic;
-                       rx_full_clk_ch0      : out std_logic;
-                       rx_half_clk_ch0      : out std_logic;
-                       fpga_rxrefclk_ch0    : in  std_logic;
-                       rxdata_ch0           : out std_logic_vector(c_serdes_data_width - 1 downto 0);
-                       rx_k_ch0             : out std_logic;
-                       rx_disp_err_ch0      : out std_logic;
-                       rx_cv_err_ch0        : out std_logic;
-                       rx_pwrup_ch0_c       : in  std_logic;
-                       rx_los_low_ch0_s     : out std_logic;
-                       lsm_status_ch0_s     : out std_logic;
-                       rx_cdr_lol_ch0_s     : out std_logic;
-                       rx_div2_mode_ch0_c   : in  std_logic;
+                       hdinp_ch0, hdinn_ch0 : in  std_logic; -- input serial link
+                       rxiclk_ch0           : in  std_logic; -- rx clock for fifo bridge (should be sysclock?)
+                       rx_full_clk_ch0      : out std_logic; -- full receive clock from serdes
+                       rx_half_clk_ch0      : out std_logic; -- half receive clock from serdes
+                       fpga_rxrefclk_ch0    : in  std_logic; -- reference clock from fpga fabric 
+                       rxdata_ch0           : out std_logic_vector(c_serdes_data_width - 1 downto 0); -- received data
+                       rx_k_ch0             : out std_logic; -- control charactor indicator 
+                       rx_disp_err_ch0      : out std_logic; -- indicate disparity error
+                       rx_cv_err_ch0        : out std_logic; -- error in data 
+                       rx_pwrup_ch0_c       : in  std_logic; -- power up receivce channel
+                       rx_los_low_ch0_s     : out std_logic; -- signal loss on input
+                       lsm_status_ch0_s     : out std_logic; -- status of link state machine
+                       rx_cdr_lol_ch0_s     : out std_logic; -- clock recovery failure
+                       rx_div2_mode_ch0_c   : in  std_logic; -- enable clock div mode
                        -- CH1 --                                                                                                                                                                                                                                    
                        hdinp_ch1, hdinn_ch1 : in  std_logic;
                        rxiclk_ch1           : in  std_logic;
@@ -131,7 +142,7 @@ architecture rtl of MupixDataLink is
                        rx_pwrup_ch1_c       : in  std_logic;
                        rx_los_low_ch1_s     : out std_logic;
                        lsm_status_ch1_s     : out std_logic;
-                       rx_cdr_lol_ch1_s     : out std_logic;
+                       rx_cdr_lol_ch1_s     : out std_logic; 
                        rx_div2_mode_ch1_c   : in  std_logic;
                        -- CH2 --                                                                                                                                                                                                                                    
                        hdinp_ch2, hdinn_ch2 : in  std_logic;
@@ -173,6 +184,144 @@ architecture rtl of MupixDataLink is
        
 begin
        
+       rxclk    <= sysclk;
+       rxrefclk <= dataclk;
+       
+       the_mupix_serdes : mupix_serdes
+               generic map(
+                       USER_CONFIG_FILE => "mupix_serdes.txt"
+               )
+               port map(
+                       hdinp_ch0          => mupix_data(0),
+                       hdinn_ch0          => mupix_data(1),
+                       rxiclk_ch0         => rxclk,
+                       rx_full_clk_ch0    => rx_full_clk(0),
+                       rx_half_clk_ch0    => rx_half_clk(0),
+                       fpga_rxrefclk_ch0  => rxrefclk,
+                       rxdata_ch0         => data_from_serdes_i(c_serdes_data_width - 1 downto 0),
+                       rx_k_ch0           => rx_k(0),
+                       rx_disp_err_ch0    => rx_disp_err(0),
+                       rx_cv_err_ch0      => rx_cv_err(0),
+                       rx_pwrup_ch0_c     => '1',
+                       rx_los_low_ch0_s   => rx_los_low_s(0),
+                       lsm_status_ch0_s   => lsm_status_s(0),
+                       rx_cdr_lol_ch0_s   => rx_cdr_lol_s(0),
+                       rx_div2_mode_ch0_c => '0',
+                       hdinp_ch1          => mupix_data(2),
+                       hdinn_ch1          => mupix_data(3),
+                       rxiclk_ch1         => rxclk,
+                       rx_full_clk_ch1    => rx_full_clk(1),
+                       rx_half_clk_ch1    => rx_half_clk(1),
+                       fpga_rxrefclk_ch1  => rxrefclk,
+                       rxdata_ch1         => data_from_serdes_i(2*c_serdes_data_width - 1 downto 1*c_serdes_data_width),
+                       rx_k_ch1           => rx_k(1),
+                       rx_disp_err_ch1    => rx_disp_err(1),
+                       rx_cv_err_ch1      => rx_cv_err(1),
+                       rx_pwrup_ch1_c     => '1',
+                       rx_los_low_ch1_s   => rx_los_low_s(1),
+                       lsm_status_ch1_s   => lsm_status_s(1),
+                       rx_cdr_lol_ch1_s   => rx_cdr_lol_s(1),
+                       rx_div2_mode_ch1_c => '0',
+                       hdinp_ch2          => mupix_data(4),
+                       hdinn_ch2          => mupix_data(5),
+                       rxiclk_ch2         => rxclk,
+                       rx_full_clk_ch2    => rx_full_clk(2),
+                       rx_half_clk_ch2    => rx_half_clk(2),
+                       fpga_rxrefclk_ch2  => rxrefclk,
+                       rxdata_ch2         => data_from_serdes_i(3*c_serdes_data_width - 1 downto 2*c_serdes_data_width),
+                       rx_k_ch2           => rx_k(2),
+                       rx_disp_err_ch2    => rx_disp_err(2),
+                       rx_cv_err_ch2      => rx_cv_err(2),
+                       rx_pwrup_ch2_c     => '1',
+                       rx_los_low_ch2_s   => rx_los_low_s(2),
+                       lsm_status_ch2_s   => lsm_status_s(2),
+                       rx_cdr_lol_ch2_s   => rx_cdr_lol_s(2),
+                       rx_div2_mode_ch2_c => '0',
+                       hdinp_ch3          => mupix_data(6),
+                       hdinn_ch3          => mupix_data(7),
+                       rxiclk_ch3         => rxclk,
+                       rx_full_clk_ch3    => rx_full_clk(3),
+                       rx_half_clk_ch3    => rx_half_clk(3),
+                       fpga_rxrefclk_ch3  => rxrefclk,
+                       rxdata_ch3         => data_from_serdes_i(4*c_serdes_data_width - 1 downto 3*c_serdes_data_width),
+                       rx_k_ch3           => rx_k(3),
+                       rx_disp_err_ch3    => rx_disp_err(3),
+                       rx_cv_err_ch3      => rx_cv_err(3),
+                       rx_pwrup_ch3_c     => '1',
+                       rx_los_low_ch3_s   => rx_los_low_s(3),
+                       lsm_status_ch3_s   => lsm_status_s(3),
+                       rx_cdr_lol_ch3_s   => rx_cdr_lol_s(3),
+                       rx_div2_mode_ch3_c => '0',
+                       fpga_txrefclk      => dataclk,
+                       tx_sync_qd_c       => '0',
+                       refclk2fpga        => refclk2core_i,
+                       rst_n              => '1',
+                       serdes_rst_qd_c    => clear
+               );
+       
+       data_fifo_gen : for i in 0 to 2 generate
+               data_fifo : serdes_fifo
+                       port map(
+                               Data    => data_from_serdes_i((i + 1)*c_serdes_data_width - 1 downto i*c_serdes_data_width),
+                               WrClock => rxclk,
+                               RdClock => sysclk,
+                               WrEn    => fifo_wren(i),
+                               RdEn    => fifo_rden(i),
+                               Reset   => rst_fifo,
+                               RPReset => rst_fifo,
+                               Q       => fifo_data((i + 1)*32 - 1 downto i*32),
+                               RCNT    => serdes_fifo_rdcnt_i((i + 1)*c_serdes_fifo_rdcnt_width - 1 downto i*c_serdes_fifo_rdcnt_width),
+                               Empty   => fifo_empty(i),
+                               Full    => fifo_full_i(i)
+                       );
+       end generate data_fifo_gen;
+       
+       large_data_fifo : serdes_fifo_large
+               port map(
+                       Data    => data_from_serdes_i(4*c_serdes_data_width - 1 downto 3*c_serdes_data_width),
+                       WrClock => rxclk,
+                       RdClock => sysclk,
+                       WrEn    => fifo_wren(3),
+                       RdEn    => fifo_rden(3),
+                       Reset   => rst_fifo,
+                       RPReset => rst_fifo,
+                       Q       => fifo_data(4*32 - 1 downto 3*32),
+                       RCNT    => serdes_fifo_large_rdcnt_i,
+                       Empty   => fifo_empty(3),
+                       Full    => fifo_full_i(3)
+               );
+       
+       fifo_write_en : process(rx_k, fifo_full_i, lsm_status_s) is
+       begin
+               for i in 0 to c_used_serdes_channels - 1 loop
+                       fifo_wren(i) <= not rx_k(i) and not fifo_full_i(i) and lsm_status_s(i);
+               end loop;
+       end process fifo_write_en;
+       
+       
+       --serdes status to led
+       led_status : process (rx_los_low_s, lsm_status_s, rx_cdr_lol_s, rx_disp_err, rx_cv_err) is
+       begin
+               for i in 0 to c_used_serdes_channels - 1 loop
+                       channel_status_led(i) <= lsm_status_s(i) and not rx_cdr_lol_s(i) and not rx_los_low_s(i) and not
+                                                                        rx_disp_err(i) and not rx_cv_err(i);
+               end loop;
+       end process led_status;
+       
+       --synchronize status signals to trb clock domain
+       sync_lsm_status : component InputSynchronizer
+           generic map(depth => 2, width => c_used_serdes_channels)
+               port map(clk => sysclk, rst => rst, input => lsm_status_s, sync_output => lsm_status_s_sync);
+               
+       sync_los_low : component InputSynchronizer
+           generic map(depth => 2, width => c_used_serdes_channels)
+               port map(clk => sysclk, rst => rst, input => rx_los_low_s, sync_output => rx_los_low_s_sync);
+               
+       sync_cdr_lol : component InputSynchronizer
+           generic map(depth => 2, width => c_used_serdes_channels)
+               port map(clk => sysclk, rst => rst, input => rx_cdr_lol_s, sync_output => rx_cdr_lol_s_sync);
+               
+       
        SLV_BUS : process(sysclk) is
        begin
                if rising_edge(sysclk) then
@@ -182,57 +331,53 @@ begin
                                SLV_NO_MORE_DATA_OUT <= '0';
                                SLV_ACK_OUT          <= '0';
                        else
+                               SLV_DATA_OUT         <= (others => '0');
+                               SLV_UNKNOWN_ADDR_OUT <= '0';
+                               SLV_NO_MORE_DATA_OUT <= '0';
+                               SLV_ACK_OUT          <= '0';
                                if SLV_READ_IN = '1' then
                                        case SLV_ADDR_IN is
-                                               when x"0001" => --read counters are already synchronous to trb system clock
+                                               when x"0000" => --read counters are already synchronous to trb system clock
                                                        SLV_DATA_OUT(c_serdes_fifo_rdcnt_width - 1 downto 0) <= serdes_fifo_rdcnt_i(c_serdes_fifo_rdcnt_width - 1 downto 0);
                                                        SLV_ACK_OUT                                          <= '1';
-                                               when x"0002" =>
+                                               when x"0001" =>
                                                        SLV_DATA_OUT(c_serdes_fifo_rdcnt_width - 1 downto 0) <= serdes_fifo_rdcnt_i(2*c_serdes_fifo_rdcnt_width - 1 downto c_serdes_fifo_rdcnt_width);
                                                        SLV_ACK_OUT                                          <= '1';
-                                               when x"0003" =>
+                                               when x"0002" =>
                                                        SLV_DATA_OUT(c_serdes_fifo_rdcnt_width - 1 downto 0) <= serdes_fifo_rdcnt_i(3*c_serdes_fifo_rdcnt_width - 1 downto 2*c_serdes_fifo_rdcnt_width);
                                                        SLV_ACK_OUT                                          <= '1';
+                                               when x"0003" =>
+                                                       SLV_DATA_OUT(c_serdes_fifo_large_rdcnt_width - 1 downto 0) <= serdes_fifo_large_rdcnt_i;
+                                                       SLV_ACK_OUT                                                <= '1';
                                                when x"0004" =>
-                                                       SLV_DATA_OUT(c_serdes_fifo_rdcnt_width - 1 downto 0) <= serdes_fifo_large_rdcnt_i(c_serdes_fifo_large_rdcnt_width - 1 downto 0);
-                                                       SLV_ACK_OUT                                          <= '1';
+                                                       SLV_DATA_OUT(2 downto 0) <= rx_cdr_lol_s_sync(0) & rx_los_low_s_sync(0) & lsm_status_s_sync(0);
+                                                       SLV_DATA_OUT(4 downto 3) <= rx_disp_err(0) & rx_cv_err(0);
+                                                       SLV_ACK_OUT              <= '1';
                                                when x"0005" =>
-                                                       SLV_DATA_OUT(c_used_serdes_channels - 1 downto 0) <= lsm_status_s_sync;
-                                                       SLV_ACK_OUT                                       <= '1';
+                                                       SLV_DATA_OUT(2 downto 0) <= rx_cdr_lol_s_sync(1) & rx_los_low_s_sync(1) & lsm_status_s_sync(1);
+                                                       SLV_DATA_OUT(4 downto 3) <= rx_disp_err(1) & rx_cv_err(1);
+                                                       SLV_ACK_OUT              <= '1';
                                                when x"0006" =>
-                                                       SLV_DATA_OUT(c_used_serdes_channels - 1 downto 0) <= rx_los_low_s_sync;
-                                                       SLV_ACK_OUT                                       <= '1';
+                                                       SLV_DATA_OUT(2 downto 0) <= rx_cdr_lol_s_sync(2) & rx_los_low_s_sync(2) & lsm_status_s_sync(2);
+                                                       SLV_DATA_OUT(4 downto 3) <= rx_disp_err(2) & rx_cv_err(2);
+                                                       SLV_ACK_OUT              <= '1';
                                                when x"0007" =>
-                                                       SLV_DATA_OUT(c_used_serdes_channels - 1 downto 0) <= rx_cdr_lol_s_sync;
-                                                       SLV_ACK_OUT                                       <= '1';
+                                                       SLV_DATA_OUT(2 downto 0) <= rx_cdr_lol_s_sync(3) & rx_los_low_s_sync(3) & lsm_status_s_sync(3);
+                                                       SLV_DATA_OUT(4 downto 3) <= rx_disp_err(3) & rx_cv_err(3);
+                                                       SLV_ACK_OUT              <= '1';
                                                when others =>
                                                        SLV_UNKNOWN_ADDR_OUT <= '1';
                                        end case;
+                               elsif SLV_WRITE_IN = '1' then
+                                       SLV_UNKNOWN_ADDR_OUT <= '1';
                                end if;
                        end if;
                end if;
        end process SLV_BUS;
        
-       --serdes status to led
-       led_status : process (rx_los_low_s, lsm_status_s, rx_cdr_lol_s) is
-       begin
-               for i in 0 to c_used_serdes_channels - 1 loop
-                       channel_status_led(i) <= lsm_status_s(i) and not rx_cdr_lol_s(i) and not rx_los_low_s(i);
-               end loop;
-       end process led_status;
-       
-       --synchronize status signals to trb clock domain
-       sync_lsm_status : component InputSynchronizer
-           generic map(depth => 2, width => c_used_serdes_channels)
-               port map(clk => sysclk, rst => rst, input => lsm_status_s, sync_output => lsm_status_s_sync);
-               
-       sync_los_low : component InputSynchronizer
-           generic map(depth => 2, width => c_used_serdes_channels)
-               port map(clk => sysclk, rst => rst, input => rx_los_low_s, sync_output => rx_los_low_s_sync);
-               
-       sync_cdr_lol : component InputSynchronizer
-           generic map(depth => 2, width => c_used_serdes_channels)
-               port map(clk => sysclk, rst => rst, input => rx_cdr_lol_s, sync_output => rx_cdr_lol_s_sync);
-               
+       refclk2core <= refclk2core_i;
+       fifo_full   <= fifo_full_i;
+       clk_rx_half_out <= rx_full_clk(0);
+       clk_rx_full_out <= rx_half_clk(0);
        
-end architecture;
\ No newline at end of file
+end architecture;
index b32eac817d0f3d9ffc48f3ed50b7ac6b5693dbe2..83f299bdf53c2230e405b2fde5f72b459f734687 100644 (file)
@@ -122,139 +122,144 @@ begin
   Signal_Edge_Detect : process(CLK_IN) is
        begin                               -- process Mupix_Readout_End_Detect
                if rising_edge(CLK_IN) then
-                       buffer_readout_end_int   <= buffer_readout_end_int(0) & TRIGGER_BUSY_BUFFER_READ_IN;
-                       timing_trigger_edge      <= timing_trigger_edge(0) & TIMING_TRIGGER_IN;
-                       reset_trigger_state_edge <= reset_trigger_state_edge(1) & reset_trigger_state;
+                       if reset_in = '1' then
+                               buffer_readout_end_int   <= (others => '0');
+                               timing_trigger_edge      <= (others => '0');
+                               reset_trigger_state_edge <= (others => '0');
+                       else
+                               buffer_readout_end_int   <= buffer_readout_end_int(0) & TRIGGER_BUSY_BUFFER_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 if;
        end process Signal_Edge_Detect;
 
-  ------------------------------------------------------------
-  --Handling of LVL1 triggers
-  ------------------------------------------------------------
-  trigger_handler_proc : process is
+       ------------------------------------------------------------
+       --Handling of LVL1 triggers
+       ------------------------------------------------------------
+       trigger_handler_proc : process(clk_in) is
        begin                               -- process trigger_handler_proc
-               wait until rising_edge(clk_in);
-               valid_trigger_int     <= '0';
-               fee_data_finished_int <= '0';
-               fee_trg_release_int   <= '0';
-               fee_trg_statusbit_int <= (others => '0');
-               trigger_busy_int      <= '1';
-               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
-                       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;
+               if rising_edge(CLK_IN) then
+                       if reset_in = '1' or LVL1_INVALID_TRG_IN = '1' or reset_trigger_state_edge = "01" then
+                               valid_trigger_int     <= '0';
+                               fee_data_finished_int <= '0';
+                               fee_trg_release_int   <= '0';
+                               fee_trg_statusbit_int <= (others => '0');
+                               trigger_busy_int      <= '1';
+                               fee_trg_release_int   <= '0';
+                               wr_header_int         <= '0';
+                               wr_data_int           <= '0';
+                               wr_status_int         <= '0';
+                               wr_dummy_int          <= '0';
+                       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;
-                                       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;
+
+                                       when check_trigger_type =>
+                                               trigger_handler_state <= x"02";
+                                               if (LVL1_TRG_DATA_VALID_IN = '1') then
+                                                       if (LVL1_TRG_TYPE_IN = c_trigger_status_type) then
+                                                               trigger_type        <= t_status;
+                                                               trigger_handler_fsm <= no_timing_trigger;
+                                                       elsif (LVL1_TRG_TYPE_IN = c_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;
-                                       end if;
 
-                               when check_trigger_type =>
-                                       trigger_handler_state <= x"02";
-                                       if (LVL1_TRG_DATA_VALID_IN = '1') then
-                                               if (LVL1_TRG_TYPE_IN = c_trigger_status_type) then
-                                                       trigger_type        <= t_status;
-                                                       trigger_handler_fsm <= no_timing_trigger;
-                                               elsif (LVL1_TRG_TYPE_IN = c_trigger_physics_type) then
-                                                       trigger_type        <= t_physics;
-                                                       trigger_handler_fsm <= no_timing_trigger;
+                                       when timing_trigger => --starts mupix readout fsm
+                                               trigger_handler_state <= x"03";
+                                               valid_trigger_int     <= '1';
+                                               trigger_handler_fsm   <= write_data_to_ipu;
+
+                                       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
-                                                       --unknown trigger
-                                                       trigger_type        <= t_unknown;
-                                                       trigger_handler_fsm <= no_timing_trigger;
+                                                       trigger_handler_fsm <= ignore;
                                                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';
-                                       trigger_handler_fsm   <= write_data_to_ipu;
-
-                               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_ipu =>
+                                               trigger_handler_state <= x"0A";
+                                               wr_data_int           <= '1';
+                                               if buffer_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 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_ipu =>
-                                       trigger_handler_state <= x"0A";
-                                       wr_data_int           <= '1';
-                                       if buffer_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_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 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;
+                                       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 if;
        end process trigger_handler_proc;
 
@@ -264,55 +269,61 @@ begin
   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
+                       if Reset_in = '1' then
                                fee_data_write_int <= '0';
-                               fee_data_int       <= (others => '1');
+                               fee_data_int       <= (others => '0');
+                       else
+                               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 if;
        end process Data_Out_Mux;
 
   
   ------------------------------------------------------------
-  --Trigger statistics
-  ------------------------------------------------------------
-  Trigger_Statistics_Proc : process(clk_in) is
+       --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
+                       if reset_trigger_counters_edge = "01" or RESET_IN = '1' 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');
+                               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 if;
        end process Trigger_Statistics_Proc;
@@ -320,18 +331,18 @@ begin
   ------------------------------------------------------------
   --TRB SLV-BUS Hanlder
   ------------------------------------------------------------
-  --0x200: accepted trigger_rate
-  --0x201: total trigger_rate
-  --0x202: invalid triggers
-  --0x203: valid triggers
-  --0x204: trigger_handler_state
-  --0x205: reset counters
-  --0x206: reset trigger state machine
-  --0x207: bypass trigger signals flag
-  slv_bus_handler : process(CLK_IN)
+  --0x120: accepted trigger_rate
+  --0x121: total trigger_rate
+  --0x122: invalid triggers
+  --0x123: valid triggers
+  --0x124: trigger_handler_state
+  --0x125: reset counters
+  --0x126: reset trigger state machine
+  --0x127: 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';
@@ -339,13 +350,13 @@ begin
 
                        if slv_write_in = '1' then
                                case SLV_ADDR_IN is
-                                       when x"0205" =>
+                                       when x"0125" =>
                                                reset_trigger_counters <= SLV_DATA_IN(0);
                                                slv_ack_out            <= '1';
-                                       when x"0206" =>
+                                       when x"0126" =>
                                                reset_trigger_state <= SLV_DATA_IN(0);
                                                slv_ack_out         <= '1';
-                                       when x"0207" =>
+                                       when x"0127" =>
                                                bypass_trigger <= SLV_DATA_IN(0);
                                                slv_ack_out    <= '1';
                                        when others =>
@@ -354,28 +365,27 @@ begin
 
                        elsif slv_read_in = '1' then
                                case slv_addr_in is
-                                       when x"0200" =>
+                                       when x"0120" =>
                                                slv_data_out <= std_logic_vector(trigger_rate_acc);
                                                slv_ack_out  <= '1';
-                                       when x"0201" =>
+                                       when x"0121" =>
                                                slv_data_out <= std_logic_vector(trigger_rate_tot);
                                                slv_ack_out  <= '1';
-                                       when x"0202" =>
+                                       when x"0122" =>
                                                slv_data_out <= std_logic_vector(invalid_trigger_counter);
                                                slv_ack_out  <= '1';
-                                       when x"0203" =>
+                                       when x"0123" =>
                                                slv_data_out <= std_logic_vector(valid_trigger_counter);
                                                slv_ack_out  <= '1';
-                                       when x"0204" =>
+                                       when x"0124" =>
                                                slv_data_out <= x"000000" & trigger_handler_state;
                                                slv_ack_out  <= '1';
-                                       when x"0207" =>
+                                       when x"0127" =>
                                                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;
index 7133eae36e2cc75b8edfaef5af75bb1ee0699813..67d44de04960b643ff3de03de20362a9c163dc67 100644 (file)
@@ -144,6 +144,9 @@ add_file -vhdl -lib work "../../../trbnet/media_interfaces/trb_net16_med_ecp3_sf
 #ip cores for mupix design
 add_file -vhdl -lib "work" "../../base/cores/pll_in200_out100.vhd"
 add_file -vhdl -lib "work" "cores/pll_mupix_main.vhd"
+add_file -vhdl -lib "work" "cores/mupix_serdes.vhd"
+add_file -vhdl -lib "work" "cores/serdes_fifo_large.vhd"
+add_file -vhdl -lib "work" "cores/serdes_fifo.vhd"
 
 #MuPix Files
 add_file -vhdl -lib "work" "trb3_periph.vhd"
@@ -164,3 +167,9 @@ add_file -vhdl -lib "work" "sources/CRC.vhd"
 add_file -vhdl -lib "work" "sources/PixelControl.vhd"
 add_file -vhdl -lib "work" "sources/FIFO.vhd"
 add_file -vhdl -lib "work" "sources/ResetHandler.vhd"
+add_file -vhdl -lib "work" "sources/CircularMemory.vhd"
+add_file -vhdl -lib "work" "sources/ReadoutController.vhd"
+add_file -vhdl -lib "work" "sources/MupixTRBReadout.vhd"
+add_file -vhdl -lib "work" "sources/DataMux.vhd"
+add_file -vhdl -lib "work" "sources/MupixDataLink.vhd"
+add_file -vhdl -lib "work" "sources/TriggerHandler.vhd"
index 35ce9342e72b9c3edc871b635a0f7dc50953b05f..f27f423996c603dd23284bc28f7885dbafef81d5 100644 (file)
@@ -34,7 +34,7 @@ entity trb3_periph is
     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);
-    mupix_serdes_rx        : in    std_logic_vector(7 downto 0);
+    mupix_serdes_rx      : in    std_logic_vector(7 downto 0);
     --Inter-FPGA Communication
     FPGA5_COMM           : inout std_logic_vector(11 downto 0);
                                         --Bit 0/1 input, serial link RX active
@@ -43,37 +43,37 @@ entity trb3_periph is
     ---------------------------------------------------------------------------
     -- 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
-    led_addon           :  out std_logic_vector(3 downto 0);
+    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
+    led_addon      : out std_logic_vector(3 downto 0);
     --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_thres        :  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 
-    spi_dac4_dout       :  in  std_logic; --serial data in from dac 4
-    hitbus              :  in  std_logic; --hitbus
+    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_thres   : 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 
+    spi_dac4_dout  : in  std_logic;     --serial data in from dac 4
+    hitbus         : in  std_logic;     --hitbus
     --classic state machine signals (currently unused)
-    rd_ldcol            :  out std_logic;
-    rd_rdcol            :  out std_logic;
-    rd_ldpix            :  out std_logic;
-    rd_pulldown         :  out std_logic;
+    rd_ldcol       : out std_logic;
+    rd_rdcol       : out std_logic;
+    rd_ldpix       : out std_logic;
+    rd_pulldown    : out std_logic;
     -- fast signals
-    clkext              :  out std_logic;
-    clkref              :  out std_logic;
-    syncres             :  out std_logic; --reset of mupix timestamps and counters
+    clkext         : out std_logic;
+    clkref         : out std_logic;
+    syncres        : out std_logic;  --reset of mupix timestamps and counters
     --fast data comes in via serdes addon (see above)
-    
+
     ---------------------------------------------------------------------------
     -- END SensorBoard MuPix 
     ---------------------------------------------------------------------------
@@ -118,131 +118,140 @@ entity trb3_periph is
   --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
 
 
-   component MupixBoard8 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_cs_adc          :  out std_logic; --load adc 
-    spi_ld_thres        :  out std_logic; --load threshold and injection dac
-    hitbus              :  in  std_logic; --hitbus signal
-    
-    --connections to data fifos
-    --fifo_rden          : out  std_logic_vector(3 downto 0); 
-    --fifo_empty         : in std_logic_vector(3 downto 0); 
-    --fifo_full          : in std_logic_vector(3 downto 0);
-    --fifo_data          : in std_logic_vector(127 downto 0); 
-    
-    --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 component;
-    
-   component resethandler is
-     port (
-       CLK_IN                : in  std_logic;
-       RESET_IN              : in  std_logic;
-       TimestampReset_OUT    : out std_logic;
-       EventCounterReset_OUT : out 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 resethandler;
-      
-   -- component MupixDataLink is
-   -- port(
-   --  sysclk             : in  std_logic; 
-   --      dataclk            : in  std_logic; 
-   --      rst                : in  std_logic; 
-   --      clear              : in  std_logic; 
-   --      rst_fifo           : in  std_logic; 
-   --      mupix_data         : in  std_logic_vector(7 downto 0); 
-   --      refclk2core        : out std_logic; 
-   --      clk_rx_half_out    : out std_logic; 
-   --      clk_rx_full_out    : out std_logic; 
-   --      fifo_rden          : in  std_logic_vector(3 downto 0); 
-   --      fifo_empty         : out std_logic_vector(3 downto 0); 
-   --      fifo_full          : out std_logic_vector(3 downto 0); 
-   --      fifo_data          : out std_logic_vector(127 downto 0); 
-   --      channel_status_led : out std_logic_vector(3 downto 0));
-   -- end component MupixDataLink;
-
-   component pll_mupix_main
-    port (CLK: in std_logic; 
-          CLKOP: out std_logic; 
-          LOCK: out std_logic);
-    end component;
-   
+  component MupixBoard8 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_cs_adc     : out std_logic;   --load adc 
+      spi_ld_thres   : out std_logic;   --load threshold and injection dac
+      hitbus         : in  std_logic;   --hitbus signal
+
+      --connections to data fifos
+      fifo_rden  : out std_logic_vector(3 downto 0);
+      fifo_empty : in  std_logic_vector(3 downto 0);
+      fifo_full  : in  std_logic_vector(3 downto 0);
+      fifo_data  : in  std_logic_vector(127 downto 0);
+
+      --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 component;
+
+  component resethandler is
+    port (
+      CLK_IN                : in  std_logic;
+      RESET_IN              : in  std_logic;
+      TimestampReset_OUT    : out std_logic;
+      EventCounterReset_OUT : out 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 resethandler;
+
+  component MupixDataLink is
+    port(
+      sysclk               : in  std_logic;
+      dataclk              : in  std_logic;
+      rst                  : in  std_logic;
+      clear                : in  std_logic;
+      rst_fifo             : in  std_logic;
+      mupix_data           : in  std_logic_vector(7 downto 0);
+      refclk2core          : out std_logic;
+      clk_rx_half_out      : out std_logic;
+      clk_rx_full_out      : out std_logic;
+      fifo_rden            : in  std_logic_vector(3 downto 0);
+      fifo_empty           : out std_logic_vector(3 downto 0);
+      fifo_full            : out std_logic_vector(3 downto 0);
+      fifo_data            : out std_logic_vector(127 downto 0);
+      channel_status_led   : out std_logic_vector(3 downto 0);
+      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 MupixDataLink;
+
+  component pll_mupix_main
+    port (CLK   : in  std_logic;
+          CLKOP : out std_logic;
+          LOCK  : out std_logic);
+  end component;
+
   --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;
-  attribute ODDRAPPS : string;
-  attribute ODDRAPPS of mupix_oddr_1       : label is "SCLK_ALIGNED";
-  attribute ODDRAPPS of mupix_oddr_2       : label is "SCLK_ALIGNED";
+  --attributes for clock output ddr buffers
+  attribute syn_keep                 : boolean;
+  attribute syn_preserve             : boolean;
+  attribute ODDRAPPS                 : string;
+  attribute ODDRAPPS of mupix_oddr_1 : label is "SCLK_ALIGNED";
+  attribute ODDRAPPS of mupix_oddr_2 : label is "SCLK_ALIGNED";
 
 
   --Clock / Reset
@@ -368,7 +377,19 @@ architecture trb3_periph_arch of trb3_periph is
   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;
-  
+
+  -- MuPix data link Regio Bus
+  signal mupixdata_regio_addr_in_0          : std_logic_vector (15 downto 0);
+  signal mupixdata_regio_data_in_0          : std_logic_vector (31 downto 0);
+  signal mupixdata_regio_data_out_0         : std_logic_vector (31 downto 0);
+  signal mupixdata_regio_read_enable_in_0   : std_logic;
+  signal mupixdata_regio_write_enable_in_0  : std_logic;
+  signal mupixdata_regio_timeout_in_0       : std_logic;
+  signal mupixdata_regio_dataready_out_0    : std_logic;
+  signal mupixdata_regio_ack_out_0          : std_logic;
+  signal mupixdata_regio_no_more_data_out_0 : std_logic;
+  signal mupixdata_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;
@@ -382,24 +403,24 @@ architecture trb3_periph_arch of trb3_periph is
   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;
-  
+
   --connections between mupix data fifos and mupix board
-   signal fifo_rden_i          : std_logic_vector(3 downto 0); 
-   signal fifo_empty_i         : std_logic_vector(3 downto 0); 
-   signal fifo_full_i          : std_logic_vector(3 downto 0); 
-   signal fifo_data_i          : std_logic_vector(127 downto 0); 
-  
+  signal fifo_rden_i  : std_logic_vector(3 downto 0);
+  signal fifo_empty_i : std_logic_vector(3 downto 0);
+  signal fifo_full_i  : std_logic_vector(3 downto 0);
+  signal fifo_data_i  : std_logic_vector(127 downto 0);
+
   --dummy
   signal dummy_counter : integer range 0 to 8 := 0;
   signal mupix_clk_i   : std_logic;
-  
+
 begin
 
-  rd_ldcol            <= '0';
-  rd_rdcol            <= '0';
-  rd_ldpix            <= '0';
-  rd_pulldown         <= '0';
-  
+  rd_ldcol    <= '0';
+  rd_rdcol    <= '0';
+  rd_ldpix    <= '0';
+  rd_pulldown <= '0';
+
 ---------------------------------------------------------------------------
 -- Reset Generation
 ---------------------------------------------------------------------------
@@ -498,10 +519,10 @@ begin
       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_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
+      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
@@ -510,14 +531,14 @@ begin
       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_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_READ_OUT       => med_read_out,                -- open,  --
       MED_STAT_OP_IN     => med_stat_op,
       MED_CTRL_OP_OUT    => med_ctrl_op,
 
@@ -604,17 +625,19 @@ begin
 ---------------------------------------------------------------------------
   THE_BUS_HANDLER : trb_net16_regio_bus_handler
     generic map(
-      PORT_NUMBER                                                => 4,
-      PORT_ADDRESSES                                             => (0 => x"d000", --spi master
-                                                          1      => x"d100", --spi memory
-                                                          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_NUMBER               => 5,
+      PORT_ADDRESSES            => (0 => x"d000",  -- spi master
+                         1      => x"d100",        -- spi memory
+                         2      => x"8000",        -- Mupix 0
+                         3      => x"9000",        -- data link from mupix
+                         4      => x"c000",        -- Reset
+                         others => x"0000"),
+      PORT_ADDR_MASK            => (0 => 1,
+                         1      => 6,
+                         2      => 12,
+                         3      => 12,           
+                         4      => 12,
+                         others => 0)
       )
     port map(
       CLK   => clk_100_i,
@@ -669,19 +692,32 @@ begin
       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),
+
+      --mupix data link
+      BUS_READ_ENABLE_OUT(3)               => mupixdata_regio_read_enable_in_0,
+      BUS_WRITE_ENABLE_OUT(3)              => mupixdata_regio_write_enable_in_0,
+      BUS_DATA_OUT(3*32+31 downto 3*32)    => mupixdata_regio_data_in_0,
+      BUS_ADDR_OUT(3*16+11 downto 3*16)    => mupixdata_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,
+      BUS_DATA_IN(3*32+31 downto 3*32)     => mupixdata_regio_data_out_0,
+      BUS_DATAREADY_IN(3)                  => mupixdata_regio_dataready_out_0,
+      BUS_WRITE_ACK_IN(3)                  => mupixdata_regio_ack_out_0,
+      BUS_NO_MORE_DATA_IN(3)               => mupixdata_regio_no_more_data_out_0,
+      BUS_UNKNOWN_ADDR_IN(3)               => mupixdata_regio_unknown_addr_out_0,
+
+      --Common Reset
+      BUS_READ_ENABLE_OUT(4)               => resethandler_regio_read_enable_in_0,
+      BUS_WRITE_ENABLE_OUT(4)              => resethandler_regio_write_enable_in_0,
+      BUS_DATA_OUT(4*32+31 downto 4*32)    => resethandler_regio_data_in_0,
+      BUS_ADDR_OUT(4*16+11 downto 4*16)    => resethandler_regio_addr_in_0(11 downto 0),
+      BUS_ADDR_OUT(4*16+15 downto 4*16+12) => open,
+      BUS_TIMEOUT_OUT(4)                   => open,
+      BUS_DATA_IN(4*32+31 downto 4*32)     => resethandler_regio_data_out_0,
+      BUS_DATAREADY_IN(4)                  => resethandler_regio_ack_out_0,
+      BUS_WRITE_ACK_IN(4)                  => resethandler_regio_ack_out_0,
+      BUS_NO_MORE_DATA_IN(4)               => resethandler_regio_no_more_data_out_0,
+      BUS_UNKNOWN_ADDR_IN(4)               => resethandler_regio_unknown_addr_out_0,
 
       STAT_DEBUG => open
       );
@@ -760,35 +796,35 @@ begin
 -----------------------------------------------------------------------------
   MupixBoard8_0 : MupixBoard8
     port map (
-      clk                  => clk_100_i,
-      fast_clk             => clk_200_i,
-      reset                => reset_i,
-      
+      clk      => clk_100_i,
+      fast_clk => clk_200_i,
+      reset    => reset_i,
+
       timestampreset_in    => reset_timestamps_i,
       eventcounterreset_in => reset_eventcounters_i,
-      
-    --  fifo_rden          => fifo_rden_i,
-    --  fifo_empty         => fifo_empty_i,
-    --  fifo_full          => fifo_full_i,
-    --  fifo_data          => fifo_data_i,
-      
+
+      fifo_rden          => fifo_rden_i,
+      fifo_empty         => fifo_empty_i,
+      fifo_full          => fifo_full_i,
+      fifo_data          => fifo_data_i,
+
       --slow control signals
-      testpulse           => testpulse,
-      ctrl_din            => ctrl_din,
-      ctrl_clk1           => ctrl_clk1,
-      ctrl_clk2           => ctrl_clk2,
-      ctrl_ld             => ctrl_ld,
-      ctrl_dout           => ctrl_dout,
-      ctrl_rb             => ctrl_rb,
-      spi_dout_adc        => spi_dout_adc,
-      spi_dout_dac        => spi_dout_dac,
-      dac4_dout           => spi_dac4_dout,
-      spi_clk             => spi_clk,
-      spi_din             => spi_din,
-      spi_ld_tmp_dac      => spi_ld_tmp_dac,
-      spi_cs_adc          => spi_ld_adc,
-      spi_ld_thres        => spi_ld_thres,
-      hitbus              => hitbus,
+      testpulse      => testpulse,
+      ctrl_din       => ctrl_din,
+      ctrl_clk1      => ctrl_clk1,
+      ctrl_clk2      => ctrl_clk2,
+      ctrl_ld        => ctrl_ld,
+      ctrl_dout      => ctrl_dout,
+      ctrl_rb        => ctrl_rb,
+      spi_dout_adc   => spi_dout_adc,
+      spi_dout_dac   => spi_dout_dac,
+      dac4_dout      => spi_dac4_dout,
+      spi_clk        => spi_clk,
+      spi_din        => spi_din,
+      spi_ld_tmp_dac => spi_ld_tmp_dac,
+      spi_cs_adc     => spi_ld_adc,
+      spi_ld_thres   => spi_ld_thres,
+      hitbus         => hitbus,
 
       TIMING_TRG_IN              => TRIGGER_RIGHT,
       LVL1_TRG_DATA_VALID_IN     => trg_data_valid_i,
@@ -818,27 +854,35 @@ begin
       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);
-      
-      
-   -- mupix_data_link_1 : entity work.MupixDataLink
-   --  port map(
-   --      sysclk          =>   clk_100_i,
-   --          dataclk         =>   mupix_clk_i,
-   --          rst             =>   reset_i,
-   --          clear           =>   clear_i,
-   --          rst_fifo        =>   reset_mupixdata_i,
-   --          mupix_data      =>   mupix_serdes_rx,
-   --          refclk2core     =>   open,
-   --          clk_rx_half_out =>   open,
-   --          clk_rx_full_out =>   open,
-   --          fifo_rden       =>   fifo_rden_i,  
-   --          fifo_empty      =>   fifo_empty_i, 
-   --          fifo_full       =>   fifo_full_i, 
-   --          fifo_data       =>   fifo_data_i,  
-   --          --misc
-  --           channel_status_led => led_addon);
-
-  led_addon <= (others => '1');
+
+
+  mupix_data_link : entity work.MupixDataLink
+    port map(
+      sysclk             => clk_100_i,
+      dataclk            => mupix_clk_i,
+      rst                => reset_i,
+      clear              => clear_i,
+      rst_fifo           => reset_mupixdata_i,
+      mupix_data         => mupix_serdes_rx,
+      refclk2core        => open,
+      clk_rx_half_out    => open,
+      clk_rx_full_out    => open,
+      fifo_rden          => fifo_rden_i,
+      fifo_empty         => fifo_empty_i,
+      fifo_full          => fifo_full_i,
+      fifo_data          => fifo_data_i,
+      --misc
+      channel_status_led => led_addon,
+      --trb slow control
+      SLV_READ_IN           => mupixdata_regio_read_enable_in_0,
+      SLV_WRITE_IN          => mupixdata_regio_write_enable_in_0,
+      SLV_DATA_OUT          => mupixdata_regio_data_out_0,
+      --SLV_DATA_IN           => mupixdata_regio_data_in_0,
+      SLV_ADDR_IN           => mupixdata_regio_addr_in_0,
+      SLV_ACK_OUT           => mupixdata_regio_ack_out_0,
+      SLV_NO_MORE_DATA_OUT  => mupixdata_regio_no_more_data_out_0,
+      SLV_UNKNOWN_ADDR_OUT  => mupixdata_regio_unknown_addr_out_0);
+
 
   resethandler_1 : entity work.resethandler
     port map (
@@ -855,42 +899,40 @@ begin
       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);
-      
- --clkext <= clk_100_i;
- --clkref <= clk_100_i;
- mupix_main_pll_1 : pll_mupix_main
+
+  
+  mupix_main_pll_1 : pll_mupix_main
     port map (
-    CLK=> CLK_PCLK_RIGHT, 
-    CLKOP=> mupix_clk_i, 
-    LOCK=> open);
- mupix_oddr_1 : ODDRXD1
+      CLK   => CLK_PCLK_RIGHT,
+      CLKOP => mupix_clk_i,
+      LOCK  => open);
+
 mupix_oddr_1 : ODDRXD1
     port map(
-        SCLK => mupix_clk_i,
-        DA   => '1',
-        DB   => '0',
-        Q    => clkext);
-        
- mupix_oddr_2 : ODDRXD1
+      SCLK => mupix_clk_i,
+      DA   => '1',
+      DB   => '0',
+      Q    => clkext);
+
 mupix_oddr_2 : ODDRXD1
     port map(
-        SCLK => mupix_clk_i,
-        DA   => '1',
-        DB   => '0',
-        Q    => clkref);
- --dummy process to test syncres
- dummy_proc : process(clk_100_i)
- begin
+      SCLK => mupix_clk_i,
+      DA   => '1',
+      DB   => '0',
+      Q    => clkref);
+
 --dummy process to test syncres
 dummy_proc : process(clk_100_i)
 begin
     if rising_edge(clk_100_i) then
       if dummy_counter = 7 then
-        syncres <= not syncres;
+        syncres       <= not syncres;
         dummy_counter <= 0;
       else
-        syncres <= syncres;
+        syncres       <= syncres;
         dummy_counter <= dummy_counter + 1;
       end if;
     end if;
- end process dummy_proc;
 end process dummy_proc;
 
 end architecture;