entity MupixDataLinkWithUnpacker is
generic (
- useRecoveredClock : integer range 0 to 1 := c_Yes);
+ g_useRecoveredClock : integer range 0 to 1 := c_Yes;
+ g_linkSimulation : integer range 0 to 1 := c_Yes
+ );
port(
sysclk : in std_logic; --trb system clock (typically 100 MHz)
dataclk : in std_logic; --mupix link clock from FPGA PLL(50 - 150 MHz)
sync_output : out std_logic_vector(width - 1 downto 0));
end component InputSynchronizer;
- component serdes_fifo -- regenerate if number of mupix hit bits changes
+ component serdes_fifo -- regenerate if number of mupix hit bits changes
port (
Data : in std_logic_vector(39 downto 0);
WrClock : in std_logic;
serdes_rst_qd_c : in std_logic); -- reset serdes, but nor pcs
end component mupix_serdes_new;
+ component mupix_serdes_sim is
+ generic (
+ USER_CONFIG_FILE : string);
+ port (
+ 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 (7 downto 0);
+ rx_k_ch0 : out std_logic;
+ rx_disp_err_ch0 : out std_logic;
+ rx_cv_err_ch0 : out std_logic;
+ word_align_en_ch0_c : in std_logic;
+ rx_pwrup_ch0_c : in std_logic;
+ rx_los_low_ch0_s : out std_logic;
+ rx_cdr_lol_ch0_s : out std_logic;
+ rx_div2_mode_ch0_c : in std_logic;
+ hdinp_ch1, hdinn_ch1 : in std_logic;
+ rxiclk_ch1 : in std_logic;
+ rx_full_clk_ch1 : out std_logic;
+ rx_half_clk_ch1 : out std_logic;
+ fpga_rxrefclk_ch1 : in std_logic;
+ rxdata_ch1 : out std_logic_vector (7 downto 0);
+ rx_k_ch1 : out std_logic;
+ rx_disp_err_ch1 : out std_logic;
+ rx_cv_err_ch1 : out std_logic;
+ word_align_en_ch1_c : in std_logic;
+ rx_pwrup_ch1_c : in std_logic;
+ rx_los_low_ch1_s : out std_logic;
+ rx_cdr_lol_ch1_s : out std_logic;
+ rx_div2_mode_ch1_c : in std_logic;
+ hdinp_ch2, hdinn_ch2 : in std_logic;
+ rxiclk_ch2 : in std_logic;
+ rx_full_clk_ch2 : out std_logic;
+ rx_half_clk_ch2 : out std_logic;
+ fpga_rxrefclk_ch2 : in std_logic;
+ rxdata_ch2 : out std_logic_vector (7 downto 0);
+ rx_k_ch2 : out std_logic;
+ rx_disp_err_ch2 : out std_logic;
+ rx_cv_err_ch2 : out std_logic;
+ word_align_en_ch2_c : in std_logic;
+ rx_pwrup_ch2_c : in std_logic;
+ rx_los_low_ch2_s : out std_logic;
+ rx_cdr_lol_ch2_s : out std_logic;
+ rx_div2_mode_ch2_c : in std_logic;
+ hdinp_ch3, hdinn_ch3 : in std_logic;
+ rxiclk_ch3 : in std_logic;
+ rx_full_clk_ch3 : out std_logic;
+ rx_half_clk_ch3 : out std_logic;
+ fpga_rxrefclk_ch3 : in std_logic;
+ rxdata_ch3 : out std_logic_vector (7 downto 0);
+ rx_k_ch3 : out std_logic;
+ rx_disp_err_ch3 : out std_logic;
+ rx_cv_err_ch3 : out std_logic;
+ word_align_en_ch3_c : in std_logic;
+ rx_pwrup_ch3_c : in std_logic;
+ rx_los_low_ch3_s : out std_logic;
+ rx_cdr_lol_ch3_s : out std_logic;
+ rx_div2_mode_ch3_c : in std_logic;
+ fpga_txrefclk : in std_logic;
+ tx_sync_qd_c : in std_logic;
+ refclk2fpga : out std_logic;
+ rst_n : in std_logic;
+ serdes_rst_qd_c : in std_logic);
+ end component mupix_serdes_sim;
+
component MupixUnpacker
generic(
g_hitsize : integer := 40;
begin
- gen_receive_clock_rec : if useRecoveredClock = c_Yes generate
+ gen_receive_clock_rec : if g_useRecoveredClock = c_Yes generate
clkrx <= rx_full_clock_i;
end generate;
- gen_receive_clock_norec : if useRecoveredClock = c_No generate
+ gen_receive_clock_norec : if g_useRecoveredClock = c_No generate
clkrx <= sysclk & sysclk & sysclk & sysclk;
end generate;
- -- not sure about correct clock distribution
- mupix_serdes_new : entity work.mupix_serdes_new
- generic map (
- USER_CONFIG_FILE => "mupix_serdes_new.txt")
- port map (
- hdinp_ch0 => mupix_data(0),
- hdinn_ch0 => mupix_data(1),
- rxiclk_ch0 => clkrx(0),
- rx_full_clk_ch0 => rx_full_clock_i(0),
- rx_half_clk_ch0 => open,
- fpga_rxrefclk_ch0 => dataclk,
- rxdata_ch0 => rx_data_i(1*8 - 1 downto 0*8),
- rx_k_ch0 => rx_komma_i(0),
- rx_disp_err_ch0 => rx_disp_err_i(0),
- rx_cv_err_ch0 => rx_dataerror_i(0),
- word_align_en_ch0_c => align_en_i(0),
- rx_pwrup_ch0_c => ch_powerup_i(0),
- rx_los_low_ch0_s => rx_sig_lost_i(0),
- rx_cdr_lol_ch0_s => rx_cdr_i(0),
- rx_div2_mode_ch0_c => ch_divmode_i(0),
- hdinp_ch1 => mupix_data(2),
- hdinn_ch1 => mupix_data(3),
- rxiclk_ch1 => clkrx(1),
- rx_full_clk_ch1 => rx_full_clock_i(1),
- rx_half_clk_ch1 => open,
- fpga_rxrefclk_ch1 => dataclk,
- rxdata_ch1 => rx_data_i(2*8 - 1 downto 1*8),
- rx_k_ch1 => rx_komma_i(1),
- rx_disp_err_ch1 => rx_disp_err_i(1),
- rx_cv_err_ch1 => rx_dataerror_i(1),
- word_align_en_ch1_c => align_en_i(1),
- rx_pwrup_ch1_c => ch_powerup_i(1),
- rx_los_low_ch1_s => rx_sig_lost_i(1),
- rx_cdr_lol_ch1_s => rx_cdr_i(1),
- rx_div2_mode_ch1_c => ch_divmode_i(1),
- hdinp_ch2 => mupix_data(4),
- hdinn_ch2 => mupix_data(5),
- rxiclk_ch2 => clkrx(2),
- rx_full_clk_ch2 => rx_full_clock_i(2),
- rx_half_clk_ch2 => open,
- fpga_rxrefclk_ch2 => dataclk,
- rxdata_ch2 => rx_data_i(3*8 - 1 downto 2*8),
- rx_k_ch2 => rx_komma_i(2),
- rx_disp_err_ch2 => rx_disp_err_i(2),
- rx_cv_err_ch2 => rx_dataerror_i(2),
- word_align_en_ch2_c => align_en_i(2),
- rx_pwrup_ch2_c => ch_powerup_i(2),
- rx_los_low_ch2_s => rx_sig_lost_i(2),
- rx_cdr_lol_ch2_s => rx_cdr_i(2),
- rx_div2_mode_ch2_c => ch_divmode_i(2),
- hdinp_ch3 => mupix_data(6),
- hdinn_ch3 => mupix_data(7),
- rxiclk_ch3 => clkrx(3),
- rx_full_clk_ch3 => rx_full_clock_i(3),
- rx_half_clk_ch3 => open,
- fpga_rxrefclk_ch3 => dataclk,
- rxdata_ch3 => rx_data_i(4*8 - 1 downto 3*8),
- rx_k_ch3 => rx_komma_i(3),
- rx_disp_err_ch3 => rx_disp_err_i(3),
- rx_cv_err_ch3 => rx_dataerror_i(3),
- word_align_en_ch3_c => align_en_i(3),
- rx_pwrup_ch3_c => ch_powerup_i(3),
- rx_los_low_ch3_s => rx_sig_lost_i(3),
- rx_cdr_lol_ch3_s => rx_cdr_i(3),
- rx_div2_mode_ch3_c => ch_divmode_i(3),
- fpga_txrefclk => dataclk,
- tx_sync_qd_c => '0', -- serializer reset (not needed for receiving)
- refclk2fpga => open,
- rst_n => '1', -- reset all channels including PCS (active
- -- low, not documented in maunal -> consult
- -- vhdl code of trbnet)
- serdes_rst_qd_c => reset_quad_i); -- reset all serdes channels but not PCS (active high)
+ gen_serdes_sim : if g_linkSimulation = c_Yes generate
+ mupix_serdes_sim : entity work.mupix_serdes_sim
+ generic map (
+ USER_CONFIG_FILE => "mupix_serdes_sim.txt")
+ port map (
+ hdinp_ch0 => mupix_data(0),
+ hdinn_ch0 => mupix_data(1),
+ rxiclk_ch0 => clkrx(0),
+ rx_full_clk_ch0 => rx_full_clock_i(0),
+ rx_half_clk_ch0 => open,
+ fpga_rxrefclk_ch0 => dataclk,
+ rxdata_ch0 => rx_data_i(1*8 - 1 downto 0*8),
+ rx_k_ch0 => rx_komma_i(0),
+ rx_disp_err_ch0 => rx_disp_err_i(0),
+ rx_cv_err_ch0 => rx_dataerror_i(0),
+ word_align_en_ch0_c => align_en_i(0),
+ rx_pwrup_ch0_c => ch_powerup_i(0),
+ rx_los_low_ch0_s => rx_sig_lost_i(0),
+ rx_cdr_lol_ch0_s => rx_cdr_i(0),
+ rx_div2_mode_ch0_c => ch_divmode_i(0),
+ hdinp_ch1 => mupix_data(2),
+ hdinn_ch1 => mupix_data(3),
+ rxiclk_ch1 => clkrx(1),
+ rx_full_clk_ch1 => rx_full_clock_i(1),
+ rx_half_clk_ch1 => open,
+ fpga_rxrefclk_ch1 => dataclk,
+ rxdata_ch1 => rx_data_i(2*8 - 1 downto 1*8),
+ rx_k_ch1 => rx_komma_i(1),
+ rx_disp_err_ch1 => rx_disp_err_i(1),
+ rx_cv_err_ch1 => rx_dataerror_i(1),
+ word_align_en_ch1_c => align_en_i(1),
+ rx_pwrup_ch1_c => ch_powerup_i(1),
+ rx_los_low_ch1_s => rx_sig_lost_i(1),
+ rx_cdr_lol_ch1_s => rx_cdr_i(1),
+ rx_div2_mode_ch1_c => ch_divmode_i(1),
+ hdinp_ch2 => mupix_data(4),
+ hdinn_ch2 => mupix_data(5),
+ rxiclk_ch2 => clkrx(2),
+ rx_full_clk_ch2 => rx_full_clock_i(2),
+ rx_half_clk_ch2 => open,
+ fpga_rxrefclk_ch2 => dataclk,
+ rxdata_ch2 => rx_data_i(3*8 - 1 downto 2*8),
+ rx_k_ch2 => rx_komma_i(2),
+ rx_disp_err_ch2 => rx_disp_err_i(2),
+ rx_cv_err_ch2 => rx_dataerror_i(2),
+ word_align_en_ch2_c => align_en_i(2),
+ rx_pwrup_ch2_c => ch_powerup_i(2),
+ rx_los_low_ch2_s => rx_sig_lost_i(2),
+ rx_cdr_lol_ch2_s => rx_cdr_i(2),
+ rx_div2_mode_ch2_c => ch_divmode_i(2),
+ hdinp_ch3 => mupix_data(6),
+ hdinn_ch3 => mupix_data(7),
+ rxiclk_ch3 => clkrx(3),
+ rx_full_clk_ch3 => rx_full_clock_i(3),
+ rx_half_clk_ch3 => open,
+ fpga_rxrefclk_ch3 => dataclk,
+ rxdata_ch3 => rx_data_i(4*8 - 1 downto 3*8),
+ rx_k_ch3 => rx_komma_i(3),
+ rx_disp_err_ch3 => rx_disp_err_i(3),
+ rx_cv_err_ch3 => rx_dataerror_i(3),
+ word_align_en_ch3_c => align_en_i(3),
+ rx_pwrup_ch3_c => ch_powerup_i(3),
+ rx_los_low_ch3_s => rx_sig_lost_i(3),
+ rx_cdr_lol_ch3_s => rx_cdr_i(3),
+ rx_div2_mode_ch3_c => ch_divmode_i(3),
+ fpga_txrefclk => dataclk,
+ tx_sync_qd_c => '0', -- serializer reset (not needed for receiving)
+ refclk2fpga => open,
+ rst_n => '1', -- reset all channels including PCS (active
+ -- low, not documented in maunal -> consult
+ -- vhdl code of trbnet)
+ serdes_rst_qd_c => reset_quad_i); -- reset all serdes channels but not PCS (active high)
+ end generate gen_serdes_sim;
+
+ gen_serdes_data : if g_linkSimulation = c_No generate
+ -- not sure about correct clock distribution
+ mupix_serdes_new : entity work.mupix_serdes_new
+ generic map (
+ USER_CONFIG_FILE => "mupix_serdes_new.txt")
+ port map (
+ hdinp_ch0 => mupix_data(0),
+ hdinn_ch0 => mupix_data(1),
+ rxiclk_ch0 => clkrx(0),
+ rx_full_clk_ch0 => rx_full_clock_i(0),
+ rx_half_clk_ch0 => open,
+ fpga_rxrefclk_ch0 => dataclk,
+ rxdata_ch0 => rx_data_i(1*8 - 1 downto 0*8),
+ rx_k_ch0 => rx_komma_i(0),
+ rx_disp_err_ch0 => rx_disp_err_i(0),
+ rx_cv_err_ch0 => rx_dataerror_i(0),
+ word_align_en_ch0_c => align_en_i(0),
+ rx_pwrup_ch0_c => ch_powerup_i(0),
+ rx_los_low_ch0_s => rx_sig_lost_i(0),
+ rx_cdr_lol_ch0_s => rx_cdr_i(0),
+ rx_div2_mode_ch0_c => ch_divmode_i(0),
+ hdinp_ch1 => mupix_data(2),
+ hdinn_ch1 => mupix_data(3),
+ rxiclk_ch1 => clkrx(1),
+ rx_full_clk_ch1 => rx_full_clock_i(1),
+ rx_half_clk_ch1 => open,
+ fpga_rxrefclk_ch1 => dataclk,
+ rxdata_ch1 => rx_data_i(2*8 - 1 downto 1*8),
+ rx_k_ch1 => rx_komma_i(1),
+ rx_disp_err_ch1 => rx_disp_err_i(1),
+ rx_cv_err_ch1 => rx_dataerror_i(1),
+ word_align_en_ch1_c => align_en_i(1),
+ rx_pwrup_ch1_c => ch_powerup_i(1),
+ rx_los_low_ch1_s => rx_sig_lost_i(1),
+ rx_cdr_lol_ch1_s => rx_cdr_i(1),
+ rx_div2_mode_ch1_c => ch_divmode_i(1),
+ hdinp_ch2 => mupix_data(4),
+ hdinn_ch2 => mupix_data(5),
+ rxiclk_ch2 => clkrx(2),
+ rx_full_clk_ch2 => rx_full_clock_i(2),
+ rx_half_clk_ch2 => open,
+ fpga_rxrefclk_ch2 => dataclk,
+ rxdata_ch2 => rx_data_i(3*8 - 1 downto 2*8),
+ rx_k_ch2 => rx_komma_i(2),
+ rx_disp_err_ch2 => rx_disp_err_i(2),
+ rx_cv_err_ch2 => rx_dataerror_i(2),
+ word_align_en_ch2_c => align_en_i(2),
+ rx_pwrup_ch2_c => ch_powerup_i(2),
+ rx_los_low_ch2_s => rx_sig_lost_i(2),
+ rx_cdr_lol_ch2_s => rx_cdr_i(2),
+ rx_div2_mode_ch2_c => ch_divmode_i(2),
+ hdinp_ch3 => mupix_data(6),
+ hdinn_ch3 => mupix_data(7),
+ rxiclk_ch3 => clkrx(3),
+ rx_full_clk_ch3 => rx_full_clock_i(3),
+ rx_half_clk_ch3 => open,
+ fpga_rxrefclk_ch3 => dataclk,
+ rxdata_ch3 => rx_data_i(4*8 - 1 downto 3*8),
+ rx_k_ch3 => rx_komma_i(3),
+ rx_disp_err_ch3 => rx_disp_err_i(3),
+ rx_cv_err_ch3 => rx_dataerror_i(3),
+ word_align_en_ch3_c => align_en_i(3),
+ rx_pwrup_ch3_c => ch_powerup_i(3),
+ rx_los_low_ch3_s => rx_sig_lost_i(3),
+ rx_cdr_lol_ch3_s => rx_cdr_i(3),
+ rx_div2_mode_ch3_c => ch_divmode_i(3),
+ fpga_txrefclk => dataclk,
+ tx_sync_qd_c => '0', -- serializer reset (not needed for receiving)
+ refclk2fpga => open,
+ rst_n => '1', -- reset all channels including PCS (active
+ -- low, not documented in maunal -> consult
+ -- vhdl code of trbnet)
+ serdes_rst_qd_c => reset_quad_i); -- reset all serdes channels but not PCS (active high)
+ end generate gen_serdes_data;
-- synchronize rx data signals into receive clock domain (maybe not
-- necessary, but should not do any harm)
sync_output => rx_data_sync((i + 1)*8 - 1 downto i*8));
end generate rx_data_gen;
-
+
-- synchronize status signals into trb clock domain
sync_los_low : InputSynchronizer
generic map(depth => 2, width => 4)
generic map (COUNTWIDTH => 32)
port map (
clk => clkrx(i),
- reset => rst,
+ reset => reset_counters_i,
inc_en => rx_disp_err_sync(i),
counter => disp_error_counter(i));
end generate disp_err_cnt_gen;
generic map (COUNTWIDTH => 32)
port map (
clk => clkrx(i),
- reset => rst,
+ reset => reset_counters_i,
inc_en => rx_dataerror_sync(i),
counter => data_error_counter(i));
end generate data_err_cnt_gen;
& rx_cdr_sync(serdes_channel_select)
& rx_sig_lost_sync(serdes_channel_select)
& link_sync_flag_i(serdes_channel_select);
+ when x"016b" =>
+ slv_ack_out <= '1';
+ slv_data_out(3 downto 0) <= link_sync_flag_i and not rx_dataerror_sync;
when others =>
slv_unknown_addr_out <= '1';
end case;
entity trb3_periph is
+ generic (
+ g_linksimulation : integer := c_Yes); -- do link simualtion, no for normal
+ -- data taking
port(
--Clocks
--CLK_GPLL_RIGHT : in std_logic; --Clock Manager 2/(2468), 200 MHz <-- MAIN CLOCK for FPGA
---------------------------------------------------------------------------
-- 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_addon : out std_logic_vector(3 downto 0); --trb addon board leds
--slow control signals
testpulse : out std_logic; --generate injection pulse
ctrl_din : out std_logic; --serial data to mupix
clkref : out std_logic;
syncres : out std_logic; --reset of mupix timestamps and counters
--fast data comes in via serdes addon (see above)
+ --link simulation
+ simlink : out std_logic;
+ simclk : out std_logic;
---------------------------------------------------------------------------
-- END SensorBoard MuPix
--Clock signal
clk : in std_logic;
fast_clk : in std_logic;
- data_clk : in std_logic;
+ data_clk : in std_logic;
reset : in std_logic;
--slow control signals
spi_ld_thres : out std_logic; --load threshold and injection dac
hitbus : in std_logic; --hitbus signal
- mupix_data : in std_logic_vector(7 downto 0);
- channel_status_led : out std_logic_vector(3 downto 0);
-
+ mupix_data : in std_logic_vector(7 downto 0);
+ channel_status_led : out std_logic_vector(3 downto 0);
+
--resets
timestampreset_in : in std_logic; --time stamp reset
eventcounterreset_in : in std_logic; --event number reset
SLV_UNKNOWN_ADDR_OUT : out std_logic);
end component resethandler;
- component pll_mupix_main
- port (CLK : in std_logic;
- CLKOP : out std_logic;
- LOCK : out std_logic);
- end component;
-
+ component LinkSimulation is
+ port (
+ trbclk : in std_logic;
+ sendclk : in std_logic;
+ reset : in std_logic;
+ data_out : out std_logic;
+ simclk : out std_logic;
+ dataclk : out std_logic);
+ end component LinkSimulation;
+
+ component MupixClocks is
+ port (
+ input_clock : in std_logic;
+ clkext : out std_logic;
+ clkref : out std_logic);
+ end component MupixClocks;
+
--Constants
constant REGIO_NUM_STAT_REGS : integer := 5;
constant REGIO_NUM_CTRL_REGS : integer := 3;
--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
signal clk_100_i : std_logic; --clock for main logic, 100 MHz, via Clock Manager and internal PLL
--dummy
signal dummy_counter : integer range 0 to 8 := 0;
- signal syncres_i : std_logic := '0';
+ signal syncres_i : std_logic := '0';
--mupix clocks
- signal mupix_clk_i : std_logic;
+ signal mupix_clk_i : std_logic;
+ signal sim_clk_i : std_logic;
begin
timestampreset_in => reset_timestamps_i,
eventcounterreset_in => reset_eventcounters_i,
- mupix_data => mupix_serdes_rx,
- channel_status_led => led_line,
-
+ mupix_data => mupix_serdes_rx,
+ channel_status_led => led_addon,
+
--slow control signals
testpulse => testpulse,
ctrl_din => ctrl_din,
SLV_NO_MORE_DATA_OUT => resethandler_regio_no_more_data_out_0,
SLV_UNKNOWN_ADDR_OUT => resethandler_regio_unknown_addr_out_0);
-
- mupix_main_pll_1 : pll_mupix_main
- port map (
- 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
- port map(
- SCLK => mupix_clk_i,
- DA => '1',
- DB => '0',
- Q => clkref);
+ -- generate clocks for normal data taking
+
+ -- generate logic for link simulation
+ gen_simulation: if g_linksimulation = c_Yes generate
+ LinkSimulation_1: entity work.LinkSimulation
+ port map (
+ trbclk => clk_100_i,
+ sendclk => CLK_PCLK_RIGHT,
+ reset => reset_i,
+ data_out => simlink,
+ simclk => simclk,
+ dataclk => mupix_clk_i);
+ end generate gen_simulation;
+
+ gen_data: if g_linksimulation = c_No generate
+ MupixClocks_1: entity work.MupixClocks
+ port map (
+ input_clock => CLK_PCLK_RIGHT,
+ clkext => mupix_clk_i,
+ clkref => clkref);
+
+ clkext <= mupix_clk_i;
+ end generate gen_data;
--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_i <= not syncres_i;
+ syncres_i <= not syncres_i;
dummy_counter <= 0;
else
dummy_counter <= dummy_counter + 1;
end process dummy_proc;
syncres <= syncres_i;
-
+
end architecture;