Commit f9caafdd authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

Initial commit, just to test the wr-node. Original repo will be converted from SVN to git

parents
*.*\#
\#*
.\#*
*.*~
hdl/ip_cores/*
modelsim.ini
*.wlf
*.vstf
work
*.bak
syn/*
transcript
\ No newline at end of file
modules = {"local": [
"hdl/wr_spec_tdc/hdl/rtl",
"hdl/wr_spec_tdc/hdl/top/spec"] };
files = ["acam_databus_interface.vhd",
"acam_timecontrol_interface.vhd",
"carrier_info.vhd",
"circular_buffer.vhd",
"clks_rsts_manager.vhd",
"data_engine.vhd",
"data_formatting.vhd",
"decr_counter.vhd",
"fmc_tdc_core.vhd",
"fmc_tdc_mezzanine.vhd",
"free_counter.vhd",
"incr_counter.vhd",
"irq_generator.vhd",
"leds_manager.vhd",
"local_pps_gen.vhd",
"reg_ctrl.vhd",
"start_retrig_ctrl.vhd",
"tdc_eic.vhd",
"wrabbit_sync.vhd"];
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- acam_databus_interface |
-- |
---------------------------------------------------------------------------------------------------
-- File acam_databus_interface.vhd |
-- |
-- Description The unit interfaces with the ACAM chip pins for the configuration of the registers|
-- and the acquisition of the timestamps. |
-- The ACAM proprietary interface is converted to a WISHBONE classic interface, with |
-- which the unit communicates with the data_engine unit. |
-- The WISHBONE master is implemented in the data_engine and the slave in this unit. |
-- |
-- ___________ ____________ ___________ |
-- | |___WRn_______| | | | |
-- | |___RDn_______| |___stb______| | |
-- | |___CSn_______| |___cyc______| | |
-- | ACAM |___OEn_______| acam_ |___we_______| data_ | |
-- | |___EF________| databus_ |___ack______| engine | |
-- | | | interface |___adr______| | |
-- | |___ADR_______| |___datI_____| | |
-- | |___DatabusIO_| |___datO_____| | |
-- |___________| |____________| |___________| |
-- |
-- |
----------------------------------------------/!\-------------------------------------------------|
-- In order for the core to be able to keep retreiving timestamps from the ACAM at the ACAM's |
-- maximun speed (31.25 M timestamps/ sec), it needs to complete one retreival per |
-- 4 * clk_i cycles = 4 * 8 ns = 32 ns. To achieve that the core is allowing 16 ns from the moment|
-- it activates the rd_n_o signal until the ACAM ef signal is updated. ACAM's specification |
-- defines that the maximum ef set time is 11.8 ns; this allows for >4 ns for the signals routing.|
-- To make sure this constraint is met, the Xilinx design map option "Pack IO Registers/Lathes |
-- into IOBs" should be enabled. |
--------------------------------------------------------------------------------------------------|
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 08/2013 |
-- Version v1 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 10/2011 v0.1 GP First version |
-- 04/2012 v0.11 EG Revamping; Comments added, signals renamed |
-- 08/2013 v1. EG cs_n_o always active |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.std_logic_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
-- Specific library
library work;
use work.tdc_core_pkg.all; -- definitions of types, constants, entities
--=================================================================================================
-- Entity declaration for acam_databus_interface
--=================================================================================================
entity acam_databus_interface is
port
-- INPUTS
-- Signals from the clk_rst_manager unit
(clk_i : in std_logic; -- 125 MHz clock
rst_i : in std_logic; -- global reset
-- Signals from the ACAM chip
ef1_i : in std_logic; -- FIFO1 empty flag
ef2_i : in std_logic; -- FIFO2 empty flag
data_bus_io : inout std_logic_vector(27 downto 0);
-- Signals from the data_engine unit
cyc_i : in std_logic; -- WISHBONE cycle
stb_i : in std_logic; -- WISHBONE strobe
we_i : in std_logic; -- WISHBONE write enable
adr_i : in std_logic_vector(7 downto 0); -- address of ACAM to write to/ read from (only 4 LSB are output)
dat_i : in std_logic_vector(31 downto 0); -- data to load to ACAM (only 28 LSB are output)
-- OUTPUTS
-- signals internal to the chip: interface with other modules
ef1_o : out std_logic; -- ACAM FIFO1 empty flag (bouble registered with clk_i)
ef1_meta_o : out std_logic; -- ACAM FIFO1 empty flag (after 1 clk_i register)
ef2_o : out std_logic; -- ACAM FIFO2 empty flag (bouble registered with clk_i)
ef2_meta_o : out std_logic; -- ACAM FIFO2 empty flag (after 1 clk_i register)
-- Signals to ACAM interface
adr_o : out std_logic_vector(3 downto 0); -- ACAM address
cs_n_o : out std_logic; -- ACAM chip select, active low; it can always remain active
oe_n_o : out std_logic; -- ACAM output enble, active low
rd_n_o : out std_logic; -- ACAM read enable, active low
wr_n_o : out std_logic; -- ACAM write enable, active low
-- Signals to the data_engine unit
ack_o : out std_logic; -- WISHBONE ack
dat_o : out std_logic_vector(31 downto 0)); -- ef1 & ef2 & 0 & 0 & 28 bits ACAM data_bus_io
end acam_databus_interface;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of acam_databus_interface is
type t_acam_interface is (IDLE, RD_START, RD_FETCH, RD_ACK, WR_START, WR_PUSH, WR_ACK);
signal acam_data_st, nxt_acam_data_st : t_acam_interface;
signal ef1_synch, ef2_synch : std_logic_vector(1 downto 0) := (others =>'1');
signal ack, rd, rd_extend : std_logic;
signal wr, wr_extend, wr_remove : std_logic;
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
---------------------------------------------------------------------------------------------------
-- Input Synchronizers --
---------------------------------------------------------------------------------------------------
input_registers: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' then
ef1_synch <= (others =>'1');
ef2_synch <= (others =>'1');
else
ef1_synch <= ef1_i & ef1_synch(1);
ef2_synch <= ef2_i & ef2_synch(1);
end if;
end if;
end process;
---------------------------------------------------------------------------------------------------
-- FSM --
---------------------------------------------------------------------------------------------------
-- The following state machine implements the slave side of the WISHBONE interface
-- and converts the signals for the ACAM proprietary bus interface. The interface respects the
-- timings specified in page 7 of the ACAM datasheet.
databus_access_seq_fsm: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' then
acam_data_st <= IDLE;
else
acam_data_st <= nxt_acam_data_st;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
databus_access_comb_fsm: process (acam_data_st, stb_i, cyc_i, we_i)
begin
case acam_data_st is
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when IDLE =>
-----------------------------------------------
ack <= '0';
rd_extend <= '0';
wr_extend <= '0';
wr_remove <= '0';
-----------------------------------------------
if stb_i = '1' and cyc_i = '1' then
if we_i = '1' then
nxt_acam_data_st <= WR_START;
else
nxt_acam_data_st <= RD_START;
end if;
else
nxt_acam_data_st <= IDLE;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when RD_START =>
-----------------------------------------------
ack <= '0';
rd_extend <= '1';
wr_extend <= '0';
wr_remove <= '0';
-----------------------------------------------
nxt_acam_data_st <= RD_FETCH;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when RD_FETCH =>
-----------------------------------------------
ack <= '0';
rd_extend <= '1';
wr_extend <= '0';
wr_remove <= '0';
-----------------------------------------------
nxt_acam_data_st <= RD_ACK;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when RD_ACK =>
-----------------------------------------------
ack <= '1';
rd_extend <= '0';
wr_extend <= '0';
wr_remove <= '0';
-----------------------------------------------
nxt_acam_data_st <= IDLE;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when WR_START =>
-----------------------------------------------
ack <= '0';
rd_extend <= '0';
wr_extend <= '1';
wr_remove <= '0';
-----------------------------------------------
nxt_acam_data_st <= WR_PUSH;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when WR_PUSH =>
-----------------------------------------------
ack <= '0';
rd_extend <= '0';
wr_extend <= '0';
wr_remove <= '1';
-----------------------------------------------
nxt_acam_data_st <= WR_ACK;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when WR_ACK =>
-----------------------------------------------
ack <= '1';
rd_extend <= '0';
wr_extend <= '0';
wr_remove <= '0';
-----------------------------------------------
nxt_acam_data_st <= IDLE;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when others =>
-----------------------------------------------
ack <= '0';
rd_extend <= '0';
wr_extend <= '0';
wr_remove <= '0';
-----------------------------------------------
nxt_acam_data_st <= IDLE;
end case;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
ack_o <= ack;
-- to the 28 bits databus output we add the ef flags to arrive to a 32 bits word
dat_o <= ef1_synch(0) & ef2_synch(0) & "00" & data_bus_io;
---------------------------------------------------------------------------------------------------
-- Outputs to ACAM --
---------------------------------------------------------------------------------------------------
output_registers: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' then
cs_n_o <= '1';
rd_n_o <= '1';
wr_n_o <= '1';
else
cs_n_o <= '0';
rd_n_o <= not(rd);
wr_n_o <= not(wr);
end if;
end if;
end process;
oe_n_o <= '1';
rd <= ((stb_i and cyc_i and not(we_i)) or rd_extend) and (not(ack));
wr <= ((stb_i and cyc_i and we_i) or wr_extend) and (not(wr_remove)) and (not(ack));
-- the wr signal has to be removed to respect the ACAM specs
data_bus_io <= dat_i(27 downto 0) when we_i='1' else (others =>'Z');
adr_o <= adr_i(3 downto 0);
---------------------------------------------------------------------------------------------------
-- EF to the data_engine --
---------------------------------------------------------------------------------------------------
ef1_o <= ef1_synch(0); -- ef1 after two synchronization registers
ef1_meta_o <= ef1_synch(1); -- ef1 after one synchronization register
ef2_o <= ef2_synch(0); -- ef1 after two synchronization registers
ef2_meta_o <= ef2_synch(1); -- ef1 after one synchronization register
end rtl;
--=================================================================================================
-- architecture end
--=================================================================================================
---------------------------------------------------------------------------------------------------
-- E N D O F F I L E
---------------------------------------------------------------------------------------------------
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- acam_timecontrol_interface |
-- |
---------------------------------------------------------------------------------------------------
-- File acam_timecontrol_interface.vhd |
-- |
-- Description interface with the ACAM chip pins for control and timing |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 04/2012 |
-- Version v0.11 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 05/2011 v0.1 GP First version |
-- 04/2012 v0.11 EG Revamping; Comments added, signals renamed |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions-- Specific library
-- Specific library
library work;
use work.tdc_core_pkg.all; -- definitions of types, constants, entities
use work.gencores_pkg.all;
--=================================================================================================
-- Entity declaration for acam_timecontrol_interface
--=================================================================================================
entity acam_timecontrol_interface is
port
-- INPUTS
-- Signals from the clk_rst_manager unit
(clk_i : in std_logic; -- 125 MHz clock
rst_i : in std_logic; -- reset
acam_refclk_r_edge_p_i : in std_logic; -- pulse upon ACAM RefClk rising edge
utc_p_i : in std_logic; ----------------
state_active_p_i : in std_logic;
deactivate_acq_p_i : in std_logic; --
-- Signals from the ACAM chip
err_flag_i : in std_logic; -- ACAM error flag, active HIGH; through ACAM config
-- reg 11 is set to report for any HitFIFOs full flags
int_flag_i : in std_logic; -- ACAM interrupt flag, active HIGH; through ACAM config
-- reg 12 it is set to the MSB of Start#
-- Signals from the reg_ctrl unit
activate_acq_p_i : in std_logic; -- signal from GN4124/VME to start following the ACAM chip
-- for tstamps aquisition
window_delay_i : in std_logic_vector(31 downto 0); -- eva: not needed
-- OUTPUTS
-- Signals to the ACAM chip
start_from_fpga_o : out std_logic;
stop_dis_o : out std_logic;
-- Signals to the
acam_errflag_r_edge_p_o : out std_logic; -- ACAM ErrFlag rising edge
acam_errflag_f_edge_p_o : out std_logic; -- ACAM ErrFlag falling edge
acam_intflag_f_edge_p_o : out std_logic);-- ACAM IntFlag falling edge
end acam_timecontrol_interface;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of acam_timecontrol_interface is
constant constant_delay : unsigned(31 downto 0) := x"00000004";
-- the delay between the referenc clock and the start window is the Total Delay
-- the Total delay is always obtained by adding the constant delay and the
-- window delay configured by the PCI-e
-- the start_from_fpga_o signal is generated in the middle of the start window
signal counter_reset : std_logic;
signal total_delay, counter_value : std_logic_vector(31 downto 0);
signal int_flag_synch, err_flag_synch : std_logic_vector(2 downto 0);
signal start_trig_received, waitingfor_refclk_i : std_logic;
signal window_start, window_prepulse : std_logic;
signal start_trig_r : std_logic_vector(2 downto 0);
signal start_trig_edge : std_logic;
signal start_pulse, wait_for_utc, rst_n, acam_intflag_f_edge_p, wait_for_state_active : std_logic;
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
---------------------------------------------------------------------------------------------------
-- IntFlag and ERRflag Input Synchronizers --
---------------------------------------------------------------------------------------------------
rst_n <= not(rst_i);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
sync_err_flag: process (clk_i) -- synchronisation registers for ERR external signal
begin
if rising_edge (clk_i) then
if rst_i ='1' then
err_flag_synch <= (others => '0');
int_flag_synch <= (others => '0');
else
err_flag_synch <= err_flag_i & err_flag_synch(2 downto 1);
int_flag_synch <= int_flag_i & int_flag_synch(2 downto 1);
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
acam_errflag_f_edge_p_o <= not(err_flag_synch(1)) and err_flag_synch(0);
acam_errflag_r_edge_p_o <= err_flag_synch(1) and not(err_flag_synch(0));
acam_intflag_f_edge_p <= not(int_flag_synch(1)) and int_flag_synch(0);
acam_intflag_f_edge_p_o <= acam_intflag_f_edge_p;
---------------------------------------------------------------------------------------------------
-- start_from_fpga_o generation --
---------------------------------------------------------------------------------------------------
-- send the pulse upon the utc
start_pulse_from_fpga: process (clk_i) -- start pulse in the middle of the
begin -- de-assertion window of StartDisable
if rising_edge (clk_i) then
if rst_i ='1' or deactivate_acq_p_i = '1' then
wait_for_utc <= '0';
start_pulse <= '0';
wait_for_state_active <= '0';
stop_dis_o <= '1';
else
if activate_acq_p_i = '1' then
wait_for_utc <= '1';
start_pulse <= '0';
elsif utc_p_i = '1' and wait_for_utc = '1' then
wait_for_utc <= '0';
start_pulse <= '1';
wait_for_state_active <= '1';
elsif wait_for_state_active = '1' and state_active_p_i = '1' then -- data_engine starts following acam ef
stop_dis_o <= '0';
wait_for_state_active <= '0';
else
start_pulse <= '0';
end if;
end if;
end if;
end process;
extend_pulse : gc_extend_pulse
generic map (g_width => 4)
port map
(clk_i => clk_i,
rst_n_i => rst_n,
pulse_i => start_pulse,
extended_o => start_from_fpga_o);
---------------------------------------------------------------------------------------------------
-- start_from_fpga_o generation --
---------------------------------------------------------------------------------------------------
-- Generation of the start pulse and the enable window:
-- the start pulse originates from an internal signal at the same time, the StartDis is de-asserted.
-- After many tests with the ACAM chip, the start Disable feature doesn't seem to be stable.
-- It has therefore been decided to avoid its usage. The generation of the window is maintained
-- to allow the control of the delay between the Start_From_FPGA pulse and the ACAM RefClk edge
window_delayer_counter: decr_counter -- all signals are synchronized
generic map -- to the refclk_i of the ACAM
(width => 32) -- But their delays are configurable.
port map
(clk_i => clk_i,
rst_i => rst_i,
counter_top_i => total_delay,
counter_load_i => window_prepulse,
counter_is_zero_o => window_start,
counter_o => open);
window_prepulse <= waitingfor_refclk_i and acam_refclk_r_edge_p_i;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
window_active_counter: incr_counter -- Defines the de-assertion window
generic map -- for the StartDisable signal
(width => 32)
port map
(clk_i => clk_i,
rst_i => counter_reset,
counter_top_i => x"00000004",
counter_incr_en_i => start_trig_received,
counter_is_full_o => open,
counter_o => counter_value);
counter_reset <= rst_i or window_start;
total_delay <= std_logic_vector(unsigned(window_delay_i)+constant_delay);
-- start_pulse_from_fpga: process (clk_i) -- start pulse in the middle of the
-- begin -- de-assertion window of StartDisable
-- if rising_edge (clk_i) then
-- if rst_i ='1' then
-- start_from_fpga_o <= '0';
-- elsif counter_value >= x"00000001" and counter_value <= x"00000002" then
-- start_from_fpga_o <= '1';
-- else
-- start_from_fpga_o <= '0';
-- end if;
-- end if;
-- end process;
-- Synchronization of the activate_acq_p with the acam_refclk_p_i
ready_to_trigger: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' then
waitingfor_refclk_i <= '0';
elsif start_trig_edge ='1' then
waitingfor_refclk_i <= '1';
elsif acam_refclk_r_edge_p_i ='1' then
waitingfor_refclk_i <= '0';
end if;
end if;
end process;
actual_trigger_received: process (clk_i) -- signal needed to exclude the generation of
begin -- the start_from_fpga_o after a general rst_i
if rising_edge (clk_i) then
if rst_i ='1' then
start_trig_received <= '0';
elsif window_start ='1' then
start_trig_received <= '1';
elsif counter_value = x"00000004" then
start_trig_received <= '0';
end if;
end if;
end process;
start_trig_pulse: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' then
start_trig_r <= (others=>'0');
else
start_trig_r <= activate_acq_p_i & start_trig_r(2 downto 1);
end if;
end if;
end process;
start_trig_edge <= start_trig_r(1) and not(start_trig_r(0));
end architecture rtl;
--=================================================================================================
-- architecture end
--=================================================================================================
---------------------------------------------------------------------------------------------------
-- E N D O F F I L E
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Misc Info about Carrier
---------------------------------------------------------------------------------------
-- File : carrier_info.vhd
-- Author : auto-generated by wbgen2 from carrier_info.wb
-- Created : 01/22/14 15:17:10
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE carrier_info.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity carrier_info is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(1 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
-- Port for std_logic_vector field: 'PCB revision' in reg: 'Carrier type and PCB version'
carrier_info_carrier_pcb_rev_i : in std_logic_vector(3 downto 0);
-- Port for std_logic_vector field: 'Reserved register' in reg: 'Carrier type and PCB version'
carrier_info_carrier_reserved_i : in std_logic_vector(11 downto 0);
-- Port for std_logic_vector field: 'Carrier type' in reg: 'Carrier type and PCB version'
carrier_info_carrier_type_i : in std_logic_vector(15 downto 0);
-- Port for BIT field: 'FMC presence' in reg: 'Status'
carrier_info_stat_fmc_pres_i : in std_logic;
-- Port for BIT field: 'GN4142 core P2L PLL status' in reg: 'Status'
carrier_info_stat_p2l_pll_lck_i : in std_logic;
-- Port for BIT field: 'System clock PLL status' in reg: 'Status'
carrier_info_stat_sys_pll_lck_i : in std_logic;
-- Port for BIT field: 'DDR3 calibration status' in reg: 'Status'
carrier_info_stat_ddr3_cal_done_i : in std_logic;
-- Port for std_logic_vector field: 'Reserved' in reg: 'Status'
carrier_info_stat_reserved_i : in std_logic_vector(27 downto 0);
-- Port for BIT field: 'Green LED' in reg: 'Control'
carrier_info_ctrl_led_green_o : out std_logic;
-- Port for BIT field: 'Red LED' in reg: 'Control'
carrier_info_ctrl_led_red_o : out std_logic;
-- Port for BIT field: 'DAC clear' in reg: 'Control'
carrier_info_ctrl_dac_clr_n_o : out std_logic;
-- Port for std_logic_vector field: 'Reserved' in reg: 'Control'
carrier_info_ctrl_reserved_o : out std_logic_vector(28 downto 0);
-- Ports for BIT field: 'State of the reset line' in reg: 'Reset Register'
carrier_info_rst_fmc0_n_o : out std_logic;
carrier_info_rst_fmc0_n_i : in std_logic;
carrier_info_rst_fmc0_n_load_o : out std_logic;
-- Port for std_logic_vector field: 'Reserved' in reg: 'Reset Register'
carrier_info_rst_reserved_o : out std_logic_vector(30 downto 0)
);
end carrier_info;
architecture syn of carrier_info is
signal carrier_info_ctrl_led_green_int : std_logic ;
signal carrier_info_ctrl_led_red_int : std_logic ;
signal carrier_info_ctrl_dac_clr_n_int : std_logic ;
signal carrier_info_ctrl_reserved_int : std_logic_vector(28 downto 0);
signal carrier_info_rst_reserved_int : std_logic_vector(30 downto 0);
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(1 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
wrdata_reg <= wb_dat_i;
bwsel_reg <= wb_sel_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
carrier_info_ctrl_led_green_int <= '0';
carrier_info_ctrl_led_red_int <= '0';
carrier_info_ctrl_dac_clr_n_int <= '0';
carrier_info_ctrl_reserved_int <= "00000000000000000000000000000";
carrier_info_rst_fmc0_n_load_o <= '0';
carrier_info_rst_reserved_int <= "0000000000000000000000000000000";
elsif rising_edge(clk_sys_i) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
carrier_info_rst_fmc0_n_load_o <= '0';
ack_in_progress <= '0';
else
carrier_info_rst_fmc0_n_load_o <= '0';
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(1 downto 0) is
when "00" =>
if (wb_we_i = '1') then
end if;
rddata_reg(3 downto 0) <= carrier_info_carrier_pcb_rev_i;
rddata_reg(15 downto 4) <= carrier_info_carrier_reserved_i;
rddata_reg(31 downto 16) <= carrier_info_carrier_type_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "01" =>
if (wb_we_i = '1') then
end if;
rddata_reg(0) <= carrier_info_stat_fmc_pres_i;
rddata_reg(1) <= carrier_info_stat_p2l_pll_lck_i;
rddata_reg(2) <= carrier_info_stat_sys_pll_lck_i;
rddata_reg(3) <= carrier_info_stat_ddr3_cal_done_i;
rddata_reg(31 downto 4) <= carrier_info_stat_reserved_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (wb_we_i = '1') then
carrier_info_ctrl_led_green_int <= wrdata_reg(0);
carrier_info_ctrl_led_red_int <= wrdata_reg(1);
carrier_info_ctrl_dac_clr_n_int <= wrdata_reg(2);
carrier_info_ctrl_reserved_int <= wrdata_reg(31 downto 3);
end if;
rddata_reg(0) <= carrier_info_ctrl_led_green_int;
rddata_reg(1) <= carrier_info_ctrl_led_red_int;
rddata_reg(2) <= carrier_info_ctrl_dac_clr_n_int;
rddata_reg(31 downto 3) <= carrier_info_ctrl_reserved_int;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "11" =>
if (wb_we_i = '1') then
carrier_info_rst_fmc0_n_load_o <= '1';
carrier_info_rst_reserved_int <= wrdata_reg(31 downto 1);
end if;
rddata_reg(0) <= carrier_info_rst_fmc0_n_i;
rddata_reg(31 downto 1) <= carrier_info_rst_reserved_int;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_dat_o <= rddata_reg;
-- PCB revision
-- Reserved register
-- Carrier type
-- FMC presence
-- GN4142 core P2L PLL status
-- System clock PLL status
-- DDR3 calibration status
-- Reserved
-- Green LED
carrier_info_ctrl_led_green_o <= carrier_info_ctrl_led_green_int;
-- Red LED
carrier_info_ctrl_led_red_o <= carrier_info_ctrl_led_red_int;
-- DAC clear
carrier_info_ctrl_dac_clr_n_o <= carrier_info_ctrl_dac_clr_n_int;
-- Reserved
carrier_info_ctrl_reserved_o <= carrier_info_ctrl_reserved_int;
-- State of the reset line
carrier_info_rst_fmc0_n_o <= wrdata_reg(0);
-- Reserved
carrier_info_rst_reserved_o <= carrier_info_rst_reserved_int;
rwaddr_reg <= wb_adr_i;
wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i);
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- circular_buffer |
-- |
---------------------------------------------------------------------------------------------------
-- File circular_buffer.vhd |
-- |
-- Description Dual port RAM circular buffer for timestamp storage; contains the RAM block and |
-- the WISHBONE slave interfaces: |
-- o The data_formatting unit is writing 128-bit long timestamps, using a WISHBONE |
-- classic interface. The unit implements a WISHBONE classic slave. |
-- As figure 1 indicates, from this side the memory is of size: 255 * 128. |
-- o The GN4124/VME core is reading 32-bit words. Readings take place using |
-- pipelined WISHBONE interface. For the PCi-e interface, Direct Memory Access can|
-- take place on this side. The unit implements the WISHBONE pipelined slave. |
-- As figure 1 indicates, from this side the memory is of size: 1024 * 32. |
-- |
-- Note also that in principle the data_formatting unit is only writing in the RAM |
-- and the GN4124/VME core is only reading from it. |
-- |
-- |
-- RAM as seen from the RAM as seen from the |
-- data_formatting unit GN4124/VME core |
-- ____________________________________________________________ _______________ |
-- 0 | 128 bits | 0 | 32 bits | |
-- |____________________________________________________________| |_______________| |
-- 1 | 128 bits | 1 | 32 bits | |
-- |____________________________________________________________| |_______________| |
-- . | 128 bits | 2 | 32 bits | |
-- |____________________________________________________________| <==> |_______________| |
-- . | 128 bits | 3 | 32 bits | |
-- |____________________________________________________________| |_______________| |
-- | 128 bits | 4 | 32 bits | |
-- 255|____________________________________________________________| |_______________| |
-- . | 32 bits | |
-- |_______________| |
-- . | 32 bits | |
-- |_______________| |
-- . | 32 bits | |
-- |_______________| |
-- . | 32 bits | |
-- |_______________| |
-- 1021 | 32 bits | |
-- |_______________| |
-- 1022 | 32 bits | |
-- |_______________| |
-- 1023 | 32 bits | |
-- |_______________| |
-- Figuure 1: RAM configuration |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 04/2012 |
-- Version v0.11 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 10/2011 v0.1 GP First version |
-- 04/2012 v0.11 EG Revamping; Comments added, signals renamed |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.std_logic_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
-- Specific library
library work;
use work.tdc_core_pkg.all; -- definitions of types, constants, entities
--=================================================================================================
-- Entity declaration for circular_buffer
--=================================================================================================
entity circular_buffer is
port
-- INPUTS
-- Signal from the clk_rst_manager
(clk_i : in std_logic; -- 125 MHz clock; same for both ports
-- Signals from the data_formatting unit (WISHBONE classic): timestamps writing
tstamp_wr_rst_i : in std_logic; -- timestamp writing WISHBONE reset
tstamp_wr_stb_i : in std_logic; -- timestamp writing WISHBONE strobe
tstamp_wr_cyc_i : in std_logic; -- timestamp writing WISHBONE cycle
tstamp_wr_we_i : in std_logic; -- timestamp writing WISHBONE write enable
tstamp_wr_adr_i : in std_logic_vector(7 downto 0); -- adr 8 bits long 2^8 = 255
tstamp_wr_dat_i : in std_logic_vector(127 downto 0); -- timestamp 128 bits long
-- Signals from the GN4124/VME core unit (WISHBONE pipelined): timestamps reading
tdc_mem_wb_rst_i : in std_logic; -- timestamp reading WISHBONE reset
tdc_mem_wb_stb_i : in std_logic; -- timestamp reading WISHBONE strobe
tdc_mem_wb_cyc_i : in std_logic; -- timestamp reading WISHBONE cycle
tdc_mem_wb_we_i : in std_logic; -- timestamp reading WISHBONE write enable; not used
tdc_mem_wb_adr_i : in std_logic_vector(31 downto 0); -- adr 10 bits long 2^10 = 1024
tdc_mem_wb_dat_i : in std_logic_vector(31 downto 0); -- not used
-- OUTPUTS
-- Signals to the data_formatting unit (WISHBONE classic): timestamps writing
tstamp_wr_ack_p_o : out std_logic; -- timestamp writing WISHBONE classic acknowledge
tstamp_wr_dat_o : out std_logic_vector(127 downto 0); -- not used
-- Signals to the GN4124/VME core unit (WISHBONE pipelined): timestamps reading
tdc_mem_wb_ack_o : out std_logic; -- timestamp reading WISHBONE pepelined acknowledge
tdc_mem_wb_dat_o : out std_logic_vector(31 downto 0); -- 32 bit words
tdc_mem_wb_stall_o : out std_logic); -- timestamp reading WISHBONE pipelined stall
end circular_buffer;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of circular_buffer is
type t_wb_wr is (IDLE, MEM_ACCESS, MEM_ACCESS_AND_ACKNOWLEDGE, ACKNOWLEDGE);
signal tstamp_rd_wb_st, nxt_tstamp_rd_wb_st : t_wb_wr;
signal tstamp_wr_ack_p : std_logic;
signal tstamp_rd_we, tstamp_wr_we : std_logic_vector(0 downto 0);
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
---------------------------------------------------------------------------------------------------
-- TIMESTAMP WRITINGS WISHBONE CLASSIC ACK --
---------------------------------------------------------------------------------------------------
-- WISHBONE classic interface compatible slave
classic_interface: process (clk_i)
begin
if rising_edge (clk_i) then
if tstamp_wr_rst_i ='1' then
tstamp_wr_ack_p <= '0';
elsif tstamp_wr_stb_i = '1' and tstamp_wr_cyc_i = '1' and tstamp_wr_ack_p = '0' then
tstamp_wr_ack_p <= '1'; -- a new 1 clk-wide ack is given for each stb
else
tstamp_wr_ack_p <= '0';
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
tstamp_wr_ack_p_o <= tstamp_wr_ack_p;
---------------------------------------------------------------------------------------------------
-- TIMESTAMP READINGS WISHBONE PIPELINE ACK --
---------------------------------------------------------------------------------------------------
-- FSM for the generation of the pipelined WISHBONE ACK signal.
-- Note that the first output from the memory comes 2 clk cycles after the address setting.
-- CLK : --|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__
-- STB : _____|-----------------------------------|_________________
-- CYC : _____|-----------------------------------|_________________
-- ADR : <ADR0><ADR1><ADR2><ADR3><ADR4><ADR5>
-- ACK : _________________|-----------------------------------|_____
-- DATO: <DAT0><DAT1><DAT2><DAT3><DAT4><DAT5>
WB_pipe_ack_fsm_seq: process (clk_i)
begin
if rising_edge (clk_i) then
if tdc_mem_wb_rst_i ='1' then
tstamp_rd_wb_st <= IDLE;
else
tstamp_rd_wb_st <= nxt_tstamp_rd_wb_st;
end if;
end if;
end process;
---------------------------------------------------------------------------------------------------
WB_pipe_ack_fsm_comb: process (tstamp_rd_wb_st, tdc_mem_wb_stb_i, tdc_mem_wb_cyc_i)
begin
case tstamp_rd_wb_st is
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when IDLE =>
-----------------------------------------------
tdc_mem_wb_ack_o <= '0';
-----------------------------------------------
if tdc_mem_wb_stb_i = '1' and tdc_mem_wb_cyc_i = '1' then
nxt_tstamp_rd_wb_st <= MEM_ACCESS;
else
nxt_tstamp_rd_wb_st <= IDLE;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when MEM_ACCESS =>
-----------------------------------------------
tdc_mem_wb_ack_o <= '0';
-----------------------------------------------
if tdc_mem_wb_stb_i = '1' and tdc_mem_wb_cyc_i = '1' then
nxt_tstamp_rd_wb_st <= MEM_ACCESS_AND_ACKNOWLEDGE;
else
nxt_tstamp_rd_wb_st <= ACKNOWLEDGE;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when MEM_ACCESS_AND_ACKNOWLEDGE =>
-----------------------------------------------
tdc_mem_wb_ack_o <= '1';
-----------------------------------------------
if tdc_mem_wb_stb_i = '1' and tdc_mem_wb_cyc_i = '1' then
nxt_tstamp_rd_wb_st <= MEM_ACCESS_AND_ACKNOWLEDGE;
else
nxt_tstamp_rd_wb_st <= ACKNOWLEDGE;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when ACKNOWLEDGE =>
-----------------------------------------------
tdc_mem_wb_ack_o <= '1';
-----------------------------------------------
if tdc_mem_wb_stb_i = '1' and tdc_mem_wb_cyc_i = '1' then
nxt_tstamp_rd_wb_st <= MEM_ACCESS;
else
nxt_tstamp_rd_wb_st <= IDLE;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when others =>
-----------------------------------------------
tdc_mem_wb_ack_o <= '0';
-----------------------------------------------
nxt_tstamp_rd_wb_st <= IDLE;
end case;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
tdc_mem_wb_stall_o <= '0';
---------------------------------------------------------------------------------------------------
-- DUAL PORT BLOCK RAM --
---------------------------------------------------------------------------------------------------
memory_block: blk_mem_circ_buff_v6_4
port map(
-- Port A: attached to the data_formatting unit
clka => clk_i,
addra => tstamp_wr_adr_i(7 downto 0), -- 2^8 = 256 addresses
dina => tstamp_wr_dat_i, -- 128-bit long timestamps
ena => tstamp_wr_cyc_i,
wea => tstamp_wr_we,
douta => tstamp_wr_dat_o, -- not used
-- Port B: attached to the GN4124/VME_core unit
clkb => clk_i,
addrb => tdc_mem_wb_adr_i(9 downto 0),-- 2^10 = 1024 addresses
dinb => tdc_mem_wb_dat_i, -- not used
enb => tdc_mem_wb_cyc_i,
web => tstamp_rd_we, -- not used
--------------------------------------------------
doutb => tdc_mem_wb_dat_o); -- 32-bit long words
--------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
tstamp_wr_we(0) <= tstamp_wr_we_i;
tstamp_rd_we(0) <= tdc_mem_wb_we_i;
end architecture rtl;
--=================================================================================================
-- architecture end
--=================================================================================================
---------------------------------------------------------------------------------------------------
-- E N D O F F I L E
---------------------------------------------------------------------------------------------------
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- clks_rsts_manager |
-- |
---------------------------------------------------------------------------------------------------
-- File clks_rsts_manager.vhd |
-- |
-- Description Independent block that uses the clk_sys_i to parametrize the PLL and DAC on the |
-- TDC mezzanine. |
-- |
-- The PLL is programmed to generate a 125 MHz clock that arrives to the FPGA and |
-- is used by all the other units of the TDC core. |
-- It is also programmed to generates a 31.25 MHz clock which is the reference clock |
-- for the ACAM chip. |
-- The registers for programming the PLL are hard-coded in this unit. |
-- |
-- Regarding the DAC, it needs one 23-bit-long word for its configuration. This |
-- word along with the command for the configuration can be sent through the |
-- PCIe/VME interface, or automatically through the White Rabbit core. |
-- |
-- Note that the PLL needs to be configured on the falling edges of the sclk clock, |
-- whereas the DAC on the rising edges. |
-- |
-- The unit is also responsible for the generation of a global internal reset signal |
-- for the TDC core. This internal reset is triggered by a GN4124/VME interface |
-- reset or by a Power On Reset at startup. The idea is to keep this reset asserted |
-- until the 125 MHz clock signal received from the PLL is stable (PLL lock). |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 02/2014 |
-- Version v0.4 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 05/2011 v0.1 GP First version |
-- 04/2012 v0.2 EG Added DFFs to the pll_sdi_o, pll_cs_n_o outputs |
-- Changed completely the internal reset generation; now it depends |
-- on the pll_status activation |
-- General revamping, comments added, signals renamed |
-- 05/2012 v0.3 EG Added logic for DAC configuration |
-- 02/2014 v0.4 EG Correction for the DAC on rising edges; added wrabbit support |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions-- Specific library
-- Specific libraries
library work;
use work.tdc_core_pkg.all; -- definitions of types, constants, entities
library UNISIM;
use UNISIM.vcomponents.all;
--=================================================================================================
-- Entity declaration for clks_rsts_manager
--=================================================================================================
entity clks_rsts_manager is
generic
(nb_of_reg : integer := 68);
port
-- INPUTS
-- Clock signal from carrier board
(clk_sys_i : in std_logic; -- 20MHz VCXO on carrier board or 62.5MHz from Xilinx PLL
-- Clock signals from the TDC mezzanine PLL
acam_refclk_p_i : in std_logic; -- 31.25 MHz differential clock generated by
acam_refclk_n_i : in std_logic; -- the mezzanine PLL, same as ACAM's input clock
tdc_125m_clk_p_i : in std_logic; -- 125 MHz clock generated by the mezzanine PLL;
tdc_125m_clk_n_i : in std_logic; -- clock of all other TDC core logic
-- Other signals from the TDC mezzanine PLL
pll_status_i : in std_logic; -- PLL lock detect
pll_sdo_i : in std_logic; -- not used
-- Reset signal from the GN4124/VME interface
rst_n_i : in std_logic; -- GN4124/VME interface reset
-- Signals from the reg_ctrl unit for the reconfiguration of the DAC
send_dac_word_p_i : in std_logic; -- pulse upon PCIe/VME request for a DAC reconfiguration
dac_word_i : in std_logic_vector(23 downto 0); -- DAC Vout = Vref (dac_word/65536)
-- Signals from the white rabbit unit for the reconfiguration of the DAC
wrabbit_dac_value_i : in std_logic_vector(23 downto 0);
wrabbit_dac_wr_p_i : in std_logic;
-- OUTPUTS
-- Signals to the rest of the modules of the TDC core
tdc_125m_clk_o : out std_logic; -- 125 MHZ clock
internal_rst_o : out std_logic; -- global reset, synched to tdc_125m_clk_o,
-- /!\ asserted until the 125 MHZ clock from the PLL becomes available
-- Signals to the SPI interface for the PLL and DAC
pll_cs_n_o : out std_logic; -- SPI PLL chip select
pll_dac_sync_n_o : out std_logic; -- SPI DAC chip select
pll_sdi_o : out std_logic; -- SPI data
pll_sclk_o : out std_logic; -- SPI clock
-- Signal to the one_hz_gen and acam_timecontrol_interface units
acam_refclk_r_edge_p_o : out std_logic; -- pulse upon acam_refclk rising edge
-- Signal to the leds_manager unit
pll_status_o : out std_logic); -- PLL lock detect
end clks_rsts_manager;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of clks_rsts_manager is
-- PLL and DAC configuration state machine
subtype t_wd is std_logic_vector(15 downto 0);
subtype t_byte is std_logic_vector(7 downto 0);
type t_instr is array (nb_of_reg-1 downto 0) of t_wd;
type t_stream is array (nb_of_reg-1 downto 0) of t_byte;
type t_pll_init_st is (config_start, sending_dac_word, sending_pll_instruction, sending_pll_data, rest, done);
signal nxt_config_st : t_pll_init_st;
signal config_st : t_pll_init_st := config_start;
signal config_reg : t_stream;
signal addr : t_instr;
signal pll_word_being_sent : t_wd;
-- Counting of bits and bytes that are being sent
signal pll_bit_being_sent, dac_bit_being_sent : std_logic;
signal bit_being_sent : std_logic;
signal pll_bit_index : integer range 15 downto 0;
signal pll_byte_index : integer range nb_of_reg-1 downto 0;
signal dac_bit_index : integer range 23 downto 0;
signal dac_word : std_logic_vector(23 downto 0);
signal send_dac_word_r_edge_p, dac_only : std_logic;
signal pll_cs_n, dac_cs_n : std_logic;
-- Synchronizers
signal pll_status_synch, internal_rst_synch : std_logic_vector (1 downto 0);
signal rst_in_synch : std_logic_vector (1 downto 0) := "11";
signal acam_refclk_synch, send_dac_word_p_synch : std_logic_vector (2 downto 0);
-- Clock buffers
signal tdc_clk_buf : std_logic;
signal tdc_clk, acam_refclk : std_logic;
-- Resets
signal rst : std_logic;
signal rst_cnt : unsigned(7 downto 0) := "00000000";
-- SCLK generation
signal sclk : std_logic;
signal sclk_r_edge, sclk_f_edge, sclk_d1, sclk_d2: std_logic;
signal divider : unsigned(7 downto 0) := "00000000";
-- The PLL circuit AD9516-4 needs to be configured through 68 registers.
-- The values and addresses are obtained through the dedicated Analog Devices software & the datasheet.
constant REG_000 : t_byte := x"18";
constant REG_001 : t_byte := x"00";
constant REG_002 : t_byte := x"10";
constant REG_003 : t_byte := x"C3";
constant REG_004 : t_byte := x"00";
constant REG_010 : t_byte := x"7C";
constant REG_011 : t_byte := x"01";
constant REG_012 : t_byte := x"00";
constant REG_013 : t_byte := x"03";
constant REG_014 : t_byte := x"09";
constant REG_015 : t_byte := x"00";
constant REG_016 : t_byte := x"04";
constant REG_017 : t_byte := x"B4"; -- PLL_STATUS
constant REG_018 : t_byte := x"07";
constant REG_019 : t_byte := x"00";
constant REG_01A : t_byte := x"00";
constant REG_01B : t_byte := x"00";
constant REG_01C : t_byte := x"02";
constant REG_01D : t_byte := x"00";
constant REG_01E : t_byte := x"00";
constant REG_01F : t_byte := x"0E";
constant REG_0A0 : t_byte := x"01";
constant REG_0A1 : t_byte := x"00";
constant REG_0A2 : t_byte := x"00";
constant REG_0A3 : t_byte := x"01";
constant REG_0A4 : t_byte := x"00";
constant REG_0A5 : t_byte := x"00";
constant REG_0A6 : t_byte := x"01";
constant REG_0A7 : t_byte := x"00";
constant REG_0A8 : t_byte := x"00";
constant REG_0A9 : t_byte := x"01";
constant REG_0AA : t_byte := x"00";
constant REG_0AB : t_byte := x"00";
constant REG_0F0 : t_byte := x"0A";
constant REG_0F1 : t_byte := x"0A";
constant REG_0F2 : t_byte := x"0A";
constant REG_0F3 : t_byte := x"0A";
constant REG_0F4 : t_byte := x"0A";
constant REG_0F5 : t_byte := x"0A";
constant REG_140 : t_byte := x"42"; -----REF_CLK
constant REG_141 : t_byte := x"5A";
constant REG_142 : t_byte := x"43";
constant REG_143 : t_byte := x"42";
constant REG_190 : t_byte := x"00";
constant REG_191 : t_byte := x"80";
constant REG_192 : t_byte := x"00";
constant REG_193 : t_byte := x"00";
constant REG_194 : t_byte := x"80";
constant REG_195 : t_byte := x"00";
constant REG_196 : t_byte := x"00";
constant REG_197 : t_byte := x"80";
constant REG_198 : t_byte := x"00";
constant REG_199 : t_byte := x"22";
constant REG_19A : t_byte := x"00";
constant REG_19B : t_byte := x"11";
constant REG_19C : t_byte := x"00";
constant REG_19D : t_byte := x"00";
constant REG_19E : t_byte := x"22";
constant REG_19F : t_byte := x"00";
constant REG_1A0 : t_byte := x"11";
constant REG_1A1 : t_byte := x"20";
constant REG_1A2 : t_byte := x"00";
constant REG_1A3 : t_byte := x"00";
constant REG_1E0 : t_byte := x"00";
constant REG_1E1 : t_byte := x"02";
constant REG_230 : t_byte := x"00";
constant REG_231 : t_byte := x"00";
constant REG_232 : t_byte := x"01";
constant SIM_RST : std_logic_vector(31 downto 0):= x"00000400";
constant SYN_RST : std_logic_vector(31 downto 0):= x"00004E20";
-- this value may still need adjustment according to the dispersion
-- in the performance of the PLL observed during the production tests
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
---------------------------------------------------------------------------------------------------
-- Clock buffers instantiations --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
tdc_clk125_ibuf : IBUFDS
generic map
(DIFF_TERM => true, -- Differential Termination
IBUF_LOW_PWR => false, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
IOSTANDARD => "DEFAULT")
port map
(O => tdc_clk_buf, -- Buffer output
I => tdc_125m_clk_p_i, -- Diff_p buffer input (connect directly to top-level port)
IB => tdc_125m_clk_n_i);-- Diff_n buffer input (connect directly to top-level port)
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
tdc_clk125_gbuf : BUFG
port map
(O => tdc_clk,
I => tdc_clk_buf);
-- -- -- -- -- -- -- --
tdc_125m_clk_o <= tdc_clk;
---------------------------------------------------------------------------------------------------
-- Reset generation for 125 MHz logic --
---------------------------------------------------------------------------------------------------
-- The following processes generate an internal reset signal for the TDC mezzanine core.
-- This internal reset is triggered by a GN4124/VME interface reset or by a Power On Reset at startup.
-- The idea is to keep this reset asserted until the 125 MHz clock signal received from the TDC
-- mezzanine PLL is stable.
---------------------------------------------------------------------------------------------------
-- Synchronous process rst_n_i_synchronizer: Synchronization of the input reset signal rst_n_i,
-- coming from the GN4124/VME interface or a PoR, to the clk_sys_i, using a set of 2 registers.
-- Note that the removal of the reset signal is synchronised.
PoR_synchronizer: process (clk_sys_i)
begin
if rising_edge (clk_sys_i) then
rst_in_synch <= rst_in_synch(0) & not rst_n_i;
end if;
end process;
---------------------------------------------------------------------------------------------------
-- Synchronous process pll_status_synchronizer: Synchronization of the pll_status_i input to the
-- clk_sys_i, using a set of 2 registers.
pll_status_synchronizer: process (clk_sys_i)
begin
if rising_edge (clk_sys_i) then
if rst_in_synch(1) = '1' then
pll_status_synch <= (others => '0');
else
pll_status_synch <= pll_status_synch(0) & pll_status_i;
end if;
end if;
end process;
-- -- -- -- -- -- -- --
pll_status_o <= pll_status_synch(1);
---------------------------------------------------------------------------------------------------
-- Synchronous process rst_generation: Generation of a reset signal for as long as the PLL
-- on the TDC board is not locked. As soon as the pll_status is received this internal reset
-- is released. Note that the level of the pll_status signal rather than its rising edge is used,
-- as in the case of a GN4124/VME reset during operation the PLL will remain locked, therefore no
-- rising edge would be detected.
rst_generation: process (clk_sys_i)
begin
if rising_edge (clk_sys_i) then
if rst_in_synch(1) = '1' then
rst <= '1';
else
if pll_status_synch(1) = '1' then
if rst_cnt = "11111111" then
rst <= '0';
else
rst <= '1';
rst_cnt <= rst_cnt+1;
end if;
else
rst <= '1';
rst_cnt <= "00000000";
end if;
end if;
end if;
end process;
---------------------------------------------------------------------------------------------------
-- Synchronous process internal_rst_synchronizer: Synchronization of the above generated rst signal
-- to the 125MHz tdc_clk, using a set of 2 registers.
Internal_rst_synchronizer: process (tdc_clk)
begin
if rising_edge (tdc_clk) then
internal_rst_synch <= internal_rst_synch(0) & rst;
end if;
end process;
-- -- -- -- -- -- -- --
internal_rst_o <= internal_rst_synch(1);
---------------------------------------------------------------------------------------------------
-- ACAM Reference Clock --
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
acam_refclk31M25_ibuf : IBUFDS
generic map
(DIFF_TERM => true, -- Differential Termination
IBUF_LOW_PWR => false, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
IOSTANDARD => "DEFAULT")
port map
(O => acam_refclk,
I => acam_refclk_p_i, -- Diff_p buffer input (connect directly to top-level port)
IB => acam_refclk_n_i);-- Diff_n buffer input (connect directly to top-level port)
---------------------------------------------------------------------------------------------------
acam_refclk_synchronizer: process (tdc_clk)
begin
if rising_edge (tdc_clk) then
if internal_rst_synch(1) = '1' then
acam_refclk_synch <= (others => '0');
else
acam_refclk_synch <= acam_refclk_synch(1 downto 0) & acam_refclk;
end if;
end if;
end process;
-- -- -- -- -- --
acam_refclk_r_edge_p_o <= (not acam_refclk_synch(2)) and acam_refclk_synch(1);
---------------------------------------------------------------------------------------------------
-- DAC configuration --
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- Synchronous process send_dac_word_p_synchronizer: Synchronization of the send_dac_word_p_o
-- input to the clk_sys_i, using a set of 3 registers.
send_dac_word_p_synchronizer: process (clk_sys_i)
begin
if rising_edge (clk_sys_i) then
if rst_in_synch(1) = '1' then
send_dac_word_p_synch <= (others => '0');
else
send_dac_word_p_synch <= send_dac_word_p_synch(1 downto 0) & send_dac_word_p_i;
end if;
end if;
end process;
-- -- -- -- -- -- -- --
send_dac_word_r_edge_p <= (not send_dac_word_p_synch(2)) and send_dac_word_p_synch(1);
---------------------------------------------------------------------------------------------------
-- Synchronous process dac_word_reg: selection of the word to be sent to the DAC.
-- Upon initialization the default word is being sent; otherwise the word received through the VME
-- interface on the DAC_WORD register.
dac_word_reg: process (clk_sys_i)
begin
if rising_edge (clk_sys_i) then
if rst_in_synch(1) = '1' then
dac_word <= c_DEFAULT_DAC_WORD;
elsif send_dac_word_r_edge_p = '1' then
dac_word <= dac_word_i;
elsif wrabbit_dac_wr_p_i = '1' then
dac_word <= wrabbit_dac_value_i;
end if;
end if;
end process;
---------------------------------------------------------------------------------------------------
-- FSM for configuration of the DAC and PLL --
---------------------------------------------------------------------------------------------------
-- Configuration of the PLL and of the DAC on the TDC mezzanine board.
-- The PLL is configured:
-- after the powering-up of the board or after a GN4124/VME reset (rst_n_i).
-- The DAC is configured:
-- after the powering-up of the board or after a GN4124/VME reset (rst_n_i) or
-- after a GN4124/VME command for the reconfiguration of the DAC (send_dac_word_p_i) or
-- after a White Rabbit command for the reconfiguration of the DAC(wrabbit_dac_wr_p_i)
---------------------------------------------------------------------------------------------------
pll_dac_initialization_seq: process (clk_sys_i)
begin
if rising_edge (clk_sys_i) then
if rst_in_synch(1) = '1' or send_dac_word_r_edge_p = '1' then
config_st <= config_start;
dac_only <= '0';
elsif wrabbit_dac_wr_p_i = '1' then
config_st <= config_start;
dac_only <= '1';
else
config_st <= nxt_config_st;
end if;
end if;
end process;
---------------------------------------------------------------------------------------------------
pll_dac_initialization_comb: process (config_st, dac_bit_index, pll_byte_index, pll_bit_index, sclk,
sclk_r_edge, sclk_f_edge)
begin
case config_st is
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when config_start =>
-----------------------------------
pll_cs_n <= '1';
dac_cs_n <= '1';
-----------------------------------
if sclk_r_edge = '1' then
nxt_config_st <= sending_dac_word;
else
nxt_config_st <= config_start;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when sending_dac_word =>
-----------------------------------
pll_cs_n <= '1';
dac_cs_n <= '0';
-----------------------------------
if dac_bit_index = 0 and sclk_f_edge = '1' and dac_only = '0' then
nxt_config_st <= sending_pll_instruction;
elsif dac_bit_index = 0 and sclk_f_edge = '1' and dac_only = '1' then
nxt_config_st <= done;
else
nxt_config_st <= sending_dac_word;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when sending_pll_instruction =>
-----------------------------------
pll_cs_n <= '0';
dac_cs_n <= '1';
-----------------------------------
if pll_bit_index = 0 and sclk_r_edge = '1' then
nxt_config_st <= sending_pll_data;
else
nxt_config_st <= sending_pll_instruction;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when sending_pll_data =>
-----------------------------------
pll_cs_n <= '0';
dac_cs_n <= '1';
-----------------------------------
if pll_bit_index = 0 and sclk_r_edge = '1' then
nxt_config_st <= rest;
else
nxt_config_st <= sending_pll_data;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when rest =>
-----------------------------------
pll_cs_n <= '1';
dac_cs_n <= '1';
-----------------------------------
if sclk_r_edge = '1' then
if pll_byte_index = 0 then
nxt_config_st <= done;
else
nxt_config_st <= sending_pll_instruction;
end if;
else
nxt_config_st <= rest;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when done =>
-----------------------------------
pll_cs_n <= '1';
dac_cs_n <= '1';
-----------------------------------
nxt_config_st <= done;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when others =>
-----------------------------------
pll_cs_n <= '1';
dac_cs_n <= '1';
-----------------------------------
nxt_config_st <= config_start;
end case;
end process;
---------------------------------------------------------------------------------------------------
pll_sclk_generator: process (clk_sys_i) -- transitions take place on the falling edge of sclk
begin
if rising_edge (clk_sys_i) then
if rst_in_synch(1) = '1' then
sclk <= '0';
sclk_d1 <= '0';
sclk_d2 <= '0';
else
sclk_d1 <= sclk;
sclk_d2 <= sclk_d1;
if divider(2) = '1' then
sclk <= '0';
else
sclk <= '1';
end if;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
sclk_r_edge <= (not sclk_d2) and sclk_d1;
sclk_f_edge <= sclk_d2 and (not sclk_d1);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_in_synch(1) = '1' then
divider <= (others => '0');
else
if(divider = "111") then
divider <= (others => '0');
else
divider <= divider + 1;
end if;
end if;
end if;
end process;
---------------------------------------------------------------------------------------------------
pll_index_control: process (clk_sys_i) -- counting of bits that are sent on the rising edges
begin
if rising_edge (clk_sys_i) then
if rst_in_synch(1) = '1' then
pll_bit_index <= 15;
elsif pll_cs_n = '1' then
pll_bit_index <= 15;
elsif sclk_r_edge = '1' then
if pll_bit_index = 0 then
pll_bit_index <= 7;
else
pll_bit_index <= pll_bit_index -1;
end if;
end if;
if rst_in_synch(1) = '1' then
pll_byte_index <= nb_of_reg -1;
elsif config_st = rest and sclk_r_edge = '1' then
if pll_byte_index = 0 then
pll_byte_index <= nb_of_reg-1;
else
pll_byte_index <= pll_byte_index -1;
end if;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
pll_bit_being_sent <= pll_word_being_sent(pll_bit_index);
pll_word_being_sent <= addr(pll_byte_index) when config_st = sending_pll_instruction
else x"00" & config_reg(pll_byte_index);
---------------------------------------------------------------------------------------------------
dac_index_control: process (clk_sys_i)
begin
if rising_edge (clk_sys_i) then -- counting of bits that are sent on the falling edges
if rst_in_synch(1) = '1' then
dac_bit_index <= 23;
elsif dac_cs_n = '1' and sclk_f_edge = '1' then
dac_bit_index <= 23;
elsif dac_cs_n = '0' and sclk_f_edge = '1' then
if dac_bit_index = 0 then
dac_bit_index <= 23;
else
dac_bit_index <= dac_bit_index - 1;
end if;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
dac_bit_being_sent <= dac_word(dac_bit_index);
bit_being_sent <= dac_bit_being_sent when dac_cs_n = '0' else pll_bit_being_sent;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
pll_sdi_o <= bit_being_sent;
pll_dac_sync_n_o <= dac_cs_n;
pll_cs_n_o <= pll_cs_n;
pll_sclk_o <= sclk_d1;
---------------------------------------------------------------------------------------------------
-- Assignment of the values to be sent for the configurations of the PLL --
---------------------------------------------------------------------------------------------------
-- According to the data sheet the register 232 should be written last to validate the transfer
-- from the buffer to the valid registers. The 16-bit instruction word indicates always a write
-- cycle of byte.
-- -- -- -- -- -- -- -- -- -- -- -- -- --
addr(0) <= x"0232";
addr(1) <= x"0000";
addr(2) <= x"0001";
addr(3) <= x"0002";
addr(4) <= x"0003";
addr(5) <= x"0004";
--------------------------
addr(6) <= x"0010";
addr(7) <= x"0011";
addr(8) <= x"0012";
addr(9) <= x"0013";
addr(10) <= x"0014";
addr(11) <= x"0015";
addr(12) <= x"0016";
addr(13) <= x"0017";
addr(14) <= x"0018";
addr(15) <= x"0019";
addr(16) <= x"001A";
addr(17) <= x"001B";
addr(18) <= x"001C";
addr(19) <= x"001D";
addr(20) <= x"001E";
addr(21) <= x"001F";
--------------------------
addr(22) <= x"00A0";
addr(23) <= x"00A1";
addr(24) <= x"00A2";
addr(25) <= x"00A3";
addr(26) <= x"00A4";
addr(27) <= x"00A5";
addr(28) <= x"00A6";
addr(29) <= x"00A7";
addr(30) <= x"00A8";
addr(31) <= x"00A9";
addr(32) <= x"00AA";
addr(33) <= x"00AB";
--------------------------
addr(34) <= x"00F0";
addr(35) <= x"00F1";
addr(36) <= x"00F2";
addr(37) <= x"00F3";
addr(38) <= x"00F4";
addr(39) <= x"00F5";
--------------------------
addr(40) <= x"0140";
addr(41) <= x"0141";
addr(42) <= x"0142";
addr(43) <= x"0143";
--------------------------
addr(44) <= x"0190";
addr(45) <= x"0191";
addr(46) <= x"0192";
addr(47) <= x"0193";
addr(48) <= x"0194";
addr(49) <= x"0195";
addr(50) <= x"0196";
addr(51) <= x"0197";
addr(52) <= x"0198";
--------------------------
addr(53) <= x"0199";
addr(54) <= x"019A";
addr(55) <= x"019B";
addr(56) <= x"019C";
addr(57) <= x"019D";
addr(58) <= x"019E";
addr(59) <= x"019F";
--------------------------
addr(60) <= x"01A0";
addr(61) <= x"01A1";
addr(62) <= x"01A2";
addr(63) <= x"01A3";
--------------------------
addr(64) <= x"01E0";
addr(65) <= x"01E1";
--------------------------
addr(66) <= x"0230";
addr(67) <= x"0231";
-- -- -- -- -- -- -- -- -- -- -- -- -- --
config_reg(0) <= REG_232;
config_reg(1) <= REG_000;
config_reg(2) <= REG_001;
config_reg(3) <= REG_002;
config_reg(4) <= REG_003;
config_reg(5) <= REG_004;
--------------------------
config_reg(6) <= REG_010;
config_reg(7) <= REG_011;
config_reg(8) <= REG_012;
config_reg(9) <= REG_013;
config_reg(10) <= REG_014;
config_reg(11) <= REG_015;
config_reg(12) <= REG_016;
config_reg(13) <= REG_017;
config_reg(14) <= REG_018;
config_reg(15) <= REG_019;
config_reg(16) <= REG_01A;
config_reg(17) <= REG_01B;
config_reg(18) <= REG_01C;
config_reg(19) <= REG_01D;
config_reg(20) <= REG_01E;
config_reg(21) <= REG_01F;
--------------------------
config_reg(22) <= REG_0A0;
config_reg(23) <= REG_0A1;
config_reg(24) <= REG_0A2;
config_reg(25) <= REG_0A3;
config_reg(26) <= REG_0A4;
config_reg(27) <= REG_0A5;
config_reg(28) <= REG_0A6;
config_reg(29) <= REG_0A7;
config_reg(30) <= REG_0A8;
config_reg(31) <= REG_0A9;
config_reg(32) <= REG_0AA;
config_reg(33) <= REG_0AB;
--------------------------
config_reg(34) <= REG_0F0;
config_reg(35) <= REG_0F1;
config_reg(36) <= REG_0F2;
config_reg(37) <= REG_0F3;
config_reg(38) <= REG_0F4;
config_reg(39) <= REG_0F5;
--------------------------
config_reg(40) <= REG_140;
config_reg(41) <= REG_141;
config_reg(42) <= REG_142;
config_reg(43) <= REG_143;
--------------------------
config_reg(44) <= REG_190;
config_reg(45) <= REG_191;
config_reg(46) <= REG_192;
config_reg(47) <= REG_193;
config_reg(48) <= REG_194;
config_reg(49) <= REG_195;
config_reg(50) <= REG_196;
config_reg(51) <= REG_197;
config_reg(52) <= REG_198;
--------------------------
config_reg(53) <= REG_199;
config_reg(54) <= REG_19A;
config_reg(55) <= REG_19B;
config_reg(56) <= REG_19C;
config_reg(57) <= REG_19D;
config_reg(58) <= REG_19E;
config_reg(59) <= REG_19F;
--------------------------
config_reg(60) <= REG_1A0;
config_reg(61) <= REG_1A1;
config_reg(62) <= REG_1A2;
config_reg(63) <= REG_1A3;
--------------------------
config_reg(64) <= REG_1E0;
config_reg(65) <= REG_1E1;
--------------------------
config_reg(66) <= REG_230;
config_reg(67) <= REG_231;
-- -- -- -- -- -- -- -- -- -- -- -- -- --
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
\ No newline at end of file
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- data_engine |
-- |
---------------------------------------------------------------------------------------------------
-- File data_engine.vhd |
-- |
-- Description The unit is managing: |
-- o the timestamps' acquisition from the ACAM, |
-- o the writing of the ACAM configuration, |
-- o the reading back of the ACAM configuration. |
-- |
-- The signals: activate_acq, deactivate_acq, |
-- acam_wr_config, acam_rst |
-- acam_rdbk_config, acam_rdbk_status, acam_rdbk_ififo1, |
-- acam_rdbk_ififo2, acam_rdbk_start01 |
-- coming from the reg_ctrl unit determine the actions of this unit. |
-- |
-- o In acquisition mode (activate_acq = 1) the unit monitors permanently the empty |
-- flags (ef1, ef2) of the ACAM iFIFOs, reads timestamps accordingly and then |
-- sends them to the data_formatting unit for them to endup in the circular_buffer|
-- o To configure the ACAM or read back its configuration registers, the unit should|
-- be in inactive mode (deactivate_acq = 1). |
-- |
-- For all types of interactions with the ACAM chip, the unit acts as a WISHBONE |
-- master fetching/ sending data from/to the ACAM interface. |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 04/2012 |
-- Version v0.11 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 06/2011 v0.1 GP First version |
-- 04/2012 v0.11 EG Revamping; Comments added, signals renamed |
-- 14/2014 v1 EG added state RD_START01 |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.std_logic_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
-- Specific library
library work;
use work.tdc_core_pkg.all; -- definitions of types, constants, entities
--=================================================================================================
-- Entity declaration for data_engine
--=================================================================================================
entity data_engine is
port
-- INPUTS
-- Signals from the clk_rst_manager
(clk_i : in std_logic; -- 125 MHz
rst_i : in std_logic; -- global reset
-- Signals from the reg_ctrl unit: communication with GN4124/VME for registers configuration
activate_acq_p_i : in std_logic; -- activates tstamps aquisition
deactivate_acq_p_i : in std_logic; -- for configuration readings/ writings
acam_wr_config_p_i : in std_logic; -- enables writing acam_config_i values to ACAM regs 0-7, 11, 12, 14
acam_rst_p_i : in std_logic; -- enables writing c_RESET_WORD to ACAM reg 4
acam_rdbk_config_p_i : in std_logic; -- enables reading of ACAM regs 0-7, 11, 12, 14
acam_rdbk_status_p_i : in std_logic; -- enables reading of ACAM reg 12
acam_rdbk_ififo1_p_i : in std_logic; -- enables reading of ACAM reg 8
acam_rdbk_ififo2_p_i : in std_logic; -- enables reading of ACAM reg 9
acam_rdbk_start01_p_i: in std_logic; -- enables reading of ACAM reg 10
acam_config_i : in config_vector; -- array keeping values for ACAM regs 0-7, 11, 12, 14
-- as received from the GN4124/VME interface
-- Signals from the acam_databus_interface unit: empty FIFO flags
acam_ef1_i : in std_logic; -- empty fifo 1 (fully synched signal; ef1 after 2 DFFs)
acam_ef1_meta_i : in std_logic; -- empty fifo 1 (possibly metestable; ef1 after 1 DFF)
acam_ef2_i : in std_logic; -- empty fifo 2 (fully synched signal; ef2 after 2 DFFs)
acam_ef2_meta_i : in std_logic; -- empty fifo 2 (possibly metestable; ef2 after 1 DFF)
-- Signals from the acam_databus_interface unit: communication with ACAM for configuration or tstamps retreival
acam_ack_i : in std_logic; -- WISHBONE ack
acam_dat_i : in std_logic_vector(31 downto 0); -- tstamps or rdbk regs
-- includes ef1 & ef2 & 0 & 0 & 28 bits ACAM data_bus_io
start_from_fpga_i : in std_logic;
-- OUTPUTS
state_active_p_o : out std_logic;
-- Signals to the acam_databus_interface unit: communication with ACAM for configuration or tstamps retreival
acam_adr_o : out std_logic_vector(7 downto 0); -- address of reg/ FIFO to write/ read
acam_cyc_o : out std_logic; -- WISHBONE cycle
acam_stb_o : out std_logic; -- WISHBONE strobe
acam_dat_o : out std_logic_vector(31 downto 0);-- values to write to ACAM regs
acam_we_o : out std_logic; -- WISHBONE write (enabled only for reg writings)
-- Signals to the reg_ctrl unit: communication with GN4124/VME for registers configuration
acam_config_rdbk_o : out config_vector; -- array keeping values read from ACAM regs 0-7, 11, 12, 14
acam_ififo1_o : out std_logic_vector(31 downto 0);-- keeps value read from ACAM reg 8
acam_ififo2_o : out std_logic_vector(31 downto 0);-- keeps value read from ACAM reg 9
acam_start01_o : out std_logic_vector(31 downto 0);-- keeps value read from ACAM reg 10
-- Signals to the data_formatting unit: ACAM fine times
acam_tstamp1_o : out std_logic_vector(31 downto 0);-- includes ef1 & ef2 & 0 & 0 & 28 bits tstamp from FIFO1
acam_tstamp2_o : out std_logic_vector(31 downto 0);-- includes ef1 & ef2 & 0 & 0 & 28 bits tstamp from FIFO2
acam_tstamp1_ok_p_o : out std_logic; -- indication of a valid tstamp1
acam_tstamp2_ok_p_o : out std_logic); -- indication of a valid tstamp2
end data_engine;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of data_engine is
type engine_state_ty is (ACTIVE, INACTIVE, GET_STAMP1, GET_STAMP2, WR_CONFIG, RDBK_CONFIG,
RD_STATUS, RD_IFIFO1, RD_IFIFO2, RD_START01, WR_RESET, WAIT_FOR_START01, WAIT_START_FROM_FPGA, WAIT_UTC);
signal engine_st, nxt_engine_st : engine_state_ty;
signal acam_cyc, acam_stb, acam_we : std_logic;
signal acam_adr : std_logic_vector(7 downto 0);
signal config_adr_c : unsigned(7 downto 0);
signal acam_config_rdbk : config_vector;
signal reset_word : std_logic_vector(31 downto 0);
signal acam_config_reg4 : std_logic_vector(31 downto 0);
signal time_c_full_p, time_c_en : std_logic;
signal time_c_rst : std_logic;
signal time_c : std_logic_vector(31 downto 0);
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
---------------------------------------------------------------------------------------------------
-- FSM --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- data_engine_fsm_seq FSM: the state machine is divided in three parts (a clocked process
-- to store the current state, a combinatorial process to manage state transitions and finally a
-- combinatorial process to manage the output signals), which are the three processes that follow.
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Synchronous process: storage of the current state of the FSM
data_engine_fsm_seq: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' then
engine_st <= INACTIVE;
else
engine_st <= nxt_engine_st;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Combinatorial process
data_engine_fsm_comb: process (engine_st, activate_acq_p_i, deactivate_acq_p_i, acam_ef1_i, acam_adr,
acam_ef2_i, acam_ef1_meta_i, acam_ef2_meta_i, acam_wr_config_p_i,
acam_rdbk_config_p_i, acam_rdbk_status_p_i, acam_ack_i, acam_rst_p_i,
acam_rdbk_ififo1_p_i, acam_rdbk_ififo2_p_i, acam_rdbk_start01_p_i)
begin
case engine_st is
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- from the INACTIVE state modifications/readings of the ACAM configuration can be initiated;
-- all interactions here refer to transfers between the ACAM and locally this core.
-- All the interactions between the GN4124/VME interface and this core take place at the
-- the reg_ctrl unit.
when INACTIVE =>
-----------------------------------------------
acam_cyc <= '0';
acam_stb <= '0';
acam_we <= '0';
time_c_en <= '0';
time_c_rst <= '1';
-----------------------------------------------
if activate_acq_p_i = '1' then -- activation of timestamps acquisition
nxt_engine_st <= WAIT_START_FROM_FPGA;
elsif acam_wr_config_p_i = '1' then
nxt_engine_st <= WR_CONFIG; -- loading of ACAM config (local-> ACAM)
elsif acam_rdbk_config_p_i = '1' then
nxt_engine_st <= RDBK_CONFIG;-- readback of ACAM config (ACAM->local acam_config_rdbk( downto ))
elsif acam_rdbk_status_p_i = '1' then
nxt_engine_st <= RD_STATUS; -- reading of ACAM status reg (ACAM->local acam_config_rdbk(9))
elsif acam_rdbk_ififo1_p_i = '1' then
nxt_engine_st <= RD_IFIFO1; -- reading of ACAM last iFIFO1 timestamp (ACAM->local acam_ififo1)
-- this option is available for debugging purposes only
elsif acam_rdbk_ififo2_p_i = '1' then
nxt_engine_st <= RD_IFIFO2; -- reading of ACAM last iFIFO2 timestamp (ACAM->local acam_ififo2)
-- this option is available for debugging purposes only
elsif acam_rdbk_start01_p_i = '1' then
nxt_engine_st <= RD_START01; -- reading of ACAM Start01 reg (ACAM->local acam_start01)
-- this option is available for debugging purposes only
elsif acam_rst_p_i = '1' then
nxt_engine_st <= WR_RESET; -- loading of ACAM config reg 4 with rst word (local reset_word ->ACAM DAT_o)
else
nxt_engine_st <= INACTIVE;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- ACTIVE, GET_STAMP1, GET_STAMP2: intensive acquisition of timestamps from ACAM.
-- ACAM can receive and tag pulses with an overall rate up to 31.25 MHz;
-- therefore locally, running with a 125 MHz clk, in order to be able to receive timestamps
-- as fast as they arrive, it is needed to use up to 4 clk cycles to retreive each of them.
-- Timestamps are received as soon as the ef1, ef2 flags are at zero (indicating that the
-- iFIFOs are not empty!). In order to avoid metastabilities locally, the ef signals are
-- synchronized using a set of two registers.
-- _______ ___________________________________________________
-- | | ____ ____
-- |_____ef____|______| |____ef_meta____| |_____ef_synched
-- ACAM | | |DFF1| |DFF2|
-- | | |\ | |\ |
-- | | |/___| |/___|
-- _______| |___________________________________________________
--
-- In the beginning the output of the second synchronizer flip-flop (ef_synch2) is used,
-- as falling edges in the ef signals can arrive randomly at any moment and metastabilities
-- could occur in the first flip-flop. On the other hand, after this first falling edge, the
-- output ef_synch1 of the first flip-flop could be used since ef rising edges are not
-- random any more and depend on the rdn signal generated locally by the
-- acam_databus_interface unit. Following ACAM documentation (pg 7, Figure 2) 2 clk cycles
-- = 16 ns after an rdn falling edge the ef_synch1 should be stable.
--
-- Using the ef_synch1 signal instead of the ef_synch2 makes it possible to realise
-- timestamps' aquisitions from ACAM in just 4 clk cycles.
-- clk --|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__
-- ef ------|_______________________________________________________|--------------
-- ef_meta -----------|_____________________________________________________|-----------
-- ef_synched -----------------|_____________________________________________________|-----
-- stb _______________________|-----------------------------------------------|_____
-- adr _______________________| iFIFO adr set
-- rdn -----------------------------|_________________|-----|_______________________
-- data valid ^ ^
-- ack _________________________________________|-----|_________________|-----|_____
-- data retrieval ^ ^
-- ef check ^
-- It is first checked if iFIFO1 is not empty, and if so a timestamp is retreived from it.
-- Then iFIFO2 is checked and if it is not empty a timestamp is retreived from it.
-- The alternation between the two FIFOs takes place until they are both empty.
-- The retreival of a timestamp from any of the FIFOs takes place
when WAIT_START_FROM_FPGA => -- wait until the start_from_fpga_p_o is sent (according to the utc_p)
-----------------------------------------------
acam_cyc <= '0';
acam_stb <= '0';
acam_we <= '0';
time_c_en <= '0';
time_c_rst <= '1';
-----------------------------------------------
if start_from_fpga_i = '1' then
nxt_engine_st <= WAIT_FOR_START01;
else
nxt_engine_st <= WAIT_START_FROM_FPGA;
end if;
when WAIT_FOR_START01 => -- wait for some time until the acam Start01 is available
-----------------------------------------------
acam_cyc <= '0';
acam_stb <= '0';
acam_we <= '0';
time_c_en <= '1';
time_c_rst <= '0';
-----------------------------------------------
if time_c = x"00004000" then
nxt_engine_st <= RD_START01;
else
nxt_engine_st <= WAIT_FOR_START01;
end if;
when RD_START01 => -- read now the acam Start01
-----------------------------------------------
acam_cyc <= '1';
acam_stb <= '1';
acam_we <= '0';
time_c_en <= '1';
time_c_rst <= '0';
-----------------------------------------------
if acam_ack_i ='1' then
nxt_engine_st <= WAIT_UTC;
else
nxt_engine_st <= RD_START01;
end if;
when WAIT_UTC => -- wait until the next utc comes; now the offsets of the start_retrig_ctrl unit are defined
-- the acam is disabled during this period
-----------------------------------------------
acam_cyc <= '0';
acam_stb <= '0';
acam_we <= '0';
time_c_en <= '1';
time_c_rst <= '0';
-----------------------------------------------
if time_c_full_p ='1' then
nxt_engine_st <= ACTIVE;
else
nxt_engine_st <= WAIT_UTC;
end if;
when ACTIVE =>
-----------------------------------------------
acam_cyc <= '0';
acam_stb <= '0';
acam_we <= '0';
time_c_en <= '0';
time_c_rst <= '1';
-----------------------------------------------
if deactivate_acq_p_i = '1' then
nxt_engine_st <= INACTIVE;
elsif acam_ef1_i = '0' then -- new tstamp in iFIFO1
nxt_engine_st <= GET_STAMP1;
elsif acam_ef2_i = '0' then -- new tstamp in iFIFO2
nxt_engine_st <= GET_STAMP2;
else
nxt_engine_st <= ACTIVE;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when GET_STAMP1 =>
-----------------------------------------------
acam_cyc <= '1';
acam_stb <= '1';
acam_we <= '0';
-----------------------------------------------
time_c_en <= '0';
time_c_rst <= '0';
if deactivate_acq_p_i = '1' then
nxt_engine_st <= INACTIVE;
elsif acam_ack_i ='1' then
if acam_ef2_i = '0' then
nxt_engine_st <= GET_STAMP2;
elsif acam_ef1_meta_i ='0' then
nxt_engine_st <= GET_STAMP1;
else
nxt_engine_st <= ACTIVE;
end if;
else
nxt_engine_st <= GET_STAMP1;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when GET_STAMP2 =>
-----------------------------------------------
acam_cyc <= '1';
acam_stb <= '1';
acam_we <= '0';
time_c_en <= '0';
time_c_rst <= '0';
-----------------------------------------------
if deactivate_acq_p_i = '1' then
nxt_engine_st <= INACTIVE;
elsif acam_ack_i ='1' then
if acam_ef1_i ='0' then
nxt_engine_st <= GET_STAMP1;
elsif acam_ef2_meta_i ='0' then
nxt_engine_st <= GET_STAMP2;
else
nxt_engine_st <= ACTIVE;
end if;
else
nxt_engine_st <= GET_STAMP2;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when WR_CONFIG =>
-----------------------------------------------
acam_cyc <= '1';
acam_stb <= '1';
acam_we <= '1';
time_c_en <= '0';
time_c_rst <= '0';
-----------------------------------------------
if acam_ack_i = '1' and acam_adr = x"0E" then -- last address
nxt_engine_st <= INACTIVE;
else
nxt_engine_st <= WR_CONFIG;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when RDBK_CONFIG =>
-----------------------------------------------
acam_cyc <= '1';
acam_stb <= '1';
acam_we <= '0';
time_c_en <= '0';
time_c_rst <= '0';
-----------------------------------------------
if acam_ack_i = '1' and acam_adr = x"0E" then -- last address
nxt_engine_st <= INACTIVE;
else
nxt_engine_st <= RDBK_CONFIG;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when RD_STATUS =>
-----------------------------------------------
acam_cyc <= '1';
acam_stb <= '1';
acam_we <= '0';
-----------------------------------------------
if acam_ack_i ='1' then
nxt_engine_st <= INACTIVE;
else
nxt_engine_st <= RD_STATUS;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when RD_IFIFO1 =>
-----------------------------------------------
acam_cyc <= '1';
acam_stb <= '1';
acam_we <= '0';
time_c_en <= '0';
time_c_rst <= '0';
-----------------------------------------------
if acam_ack_i ='1' then
nxt_engine_st <= INACTIVE;
else
nxt_engine_st <= RD_IFIFO1;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when RD_IFIFO2 =>
-----------------------------------------------
acam_cyc <= '1';
acam_stb <= '1';
acam_we <= '0';
time_c_en <= '0';
time_c_rst <= '0';
-----------------------------------------------
if acam_ack_i ='1' then
nxt_engine_st <= INACTIVE;
else
nxt_engine_st <= RD_IFIFO2;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when WR_RESET =>
-----------------------------------------------
acam_cyc <= '1';
acam_stb <= '1';
acam_we <= '1';
time_c_en <= '0';
time_c_rst <= '0';
-----------------------------------------------
if acam_ack_i ='1' then
nxt_engine_st <= INACTIVE;
else
nxt_engine_st <= WR_RESET;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when others =>
-----------------------------------------------
acam_cyc <= '0';
acam_stb <= '0';
acam_we <= '0';
time_c_en <= '0';
time_c_rst <= '0';
-----------------------------------------------
nxt_engine_st <= INACTIVE;
end case;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- --
acam_cyc_o <= acam_cyc;
acam_stb_o <= acam_stb;
acam_we_o <= acam_we;
---------------------------------------------------------------------------------------------------
-- Address generation (acam_adr_o) for ACAM readings/ writings --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- adr_generation: according to the state of the FSM this process generates the acam_adr_o output
-- that specifies the ACAM register or FIFO to write to/read from.
adr_generation: process (engine_st, config_adr_c)
begin
case engine_st is
when INACTIVE =>
acam_adr <= x"00";
when ACTIVE =>
acam_adr <= x"00";
when GET_STAMP1 =>
acam_adr <= std_logic_vector(c_ACAM_REG8_ADR); -- FIFO1: ACAM reg 8
when GET_STAMP2 =>
acam_adr <= std_logic_vector(c_ACAM_REG9_ADR); -- FIFO2: ACAM reg 9
when WR_CONFIG =>
acam_adr <= std_logic_vector(config_adr_c); -- sweeps through ACAM reg 0-7, 11, 12, 14
when RDBK_CONFIG=>
acam_adr <= std_logic_vector(config_adr_c); -- sweeps through ACAM reg 0-7, 11, 12, 14
when RD_STATUS =>
acam_adr <= std_logic_vector(c_ACAM_REG12_ADR); -- status: ACAM reg 12
when RD_IFIFO1 =>
acam_adr <= std_logic_vector(c_ACAM_REG8_ADR); -- FIFO1: ACAM reg 8
when RD_IFIFO2 =>
acam_adr <= std_logic_vector(c_ACAM_REG9_ADR); -- FIFO2: ACAM reg 9
when RD_START01 =>
acam_adr <= std_logic_vector(c_ACAM_REG10_ADR); -- START01: ACAM reg 10
when WR_RESET =>
acam_adr <= std_logic_vector(c_ACAM_REG4_ADR); -- reset: ACAM reg 4
when others =>
acam_adr <= x"00";
end case;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- --
acam_adr_o <= acam_adr;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- config_adr_c: counter used for the sweeping though the ACAM configuration addresses.
-- counter counting: 0-> 1-> 2-> 3-> 4-> 5-> 6-> 7-> 11-> 12-> 14
config_adr_counter: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i = '1' or acam_wr_config_p_i = '1' or acam_rdbk_config_p_i = '1' then
config_adr_c <= unsigned (c_ACAM_REG0_ADR);
elsif acam_ack_i ='1' then
if config_adr_c = unsigned (c_ACAM_REG14_ADR) then
config_adr_c <= unsigned (c_ACAM_REG14_ADR);
elsif config_adr_c = unsigned (c_ACAM_REG12_ADR) then
config_adr_c <= unsigned (c_ACAM_REG14_ADR);
elsif config_adr_c = unsigned (c_ACAM_REG7_ADR) then
config_adr_c <= unsigned (c_ACAM_REG11_ADR);
else
config_adr_c <= config_adr_c + 1;
end if;
end if;
end if;
end process;
---------------------------------------------------------------------------------------------------
-- Values (acam_dat_o) for ACAM config writings --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- data_config_decoder: according to the acam_adr this process generates the acam_dat_o output
-- with the new value to be loaded to the corresponding ACAM reg. The values come from the
-- acam_config_i vector that keeps what has been loaded from the GN4124 interface.
data_config_decoder: process(acam_adr, engine_st, acam_config_i, reset_word)
begin
case acam_adr is
when c_ACAM_REG0_ADR =>
acam_dat_o <= acam_config_i(0);
when c_ACAM_REG1_ADR =>
acam_dat_o <= acam_config_i(1);
when c_ACAM_REG2_ADR =>
acam_dat_o <= acam_config_i(2);
when c_ACAM_REG3_ADR =>
acam_dat_o <= acam_config_i(3);
when c_ACAM_REG4_ADR => -- in reg 4 there are bits (0-21, 24-27) defining normal config settings
-- and there are also bits (22&23) initiating ACAM resets
if engine_st = WR_RESET then
acam_dat_o <= reset_word;
else
acam_dat_o <= acam_config_i(4);
end if;
when c_ACAM_REG5_ADR =>
acam_dat_o <= acam_config_i(5);
when c_ACAM_REG6_ADR =>
acam_dat_o <= acam_config_i(6);
when c_ACAM_REG7_ADR =>
acam_dat_o <= acam_config_i(7);
when c_ACAM_REG11_ADR =>
acam_dat_o <= acam_config_i(8);
when c_ACAM_REG12_ADR =>
acam_dat_o <= acam_config_i(9);
when c_ACAM_REG14_ADR =>
acam_dat_o <= acam_config_i(10);
when others =>
acam_dat_o <= (others =>'0');
end case;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
acam_config_reg4 <= acam_config_i(4);
reset_word <= acam_config_reg4(31 downto 24) & "01" & acam_config_reg4(21 downto 0);
-- reg 4 bit 22: MasterReset :'1' = general reset excluding config regs
-- reg 4 bit 23: PartialReset: would initiate a general reset excluding
-- config regs&FIFOs, but this option is not used
---------------------------------------------------------------------------------------------------
-- Aquisition of ACAM Timestamps or Reedback Registers --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- data_readback_decoder: after reading accesses to the ACAM (acam_we=0), the process recuperates
-- the ACAM data and according to the acam_adr_o stores them to the corresponding registers.
-- In the case of timestamps aquisition, the acam_tstamp1_ok_p_o, acam_tstamp2_ok_p_o pulses are
-- generated that when active, indicate a valid timestamp. Note that for timing reasons
-- the signals acam_tstamp1_o, acam_tstamp2_o are not the outputs of flip-flops.
data_readback_decoder: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' then
acam_config_rdbk(0) <= (others => '0');
acam_config_rdbk(1) <= (others => '0');
acam_config_rdbk(2) <= (others => '0');
acam_config_rdbk(3) <= (others => '0');
acam_config_rdbk(4) <= (others => '0');
acam_config_rdbk(5) <= (others => '0');
acam_config_rdbk(6) <= (others => '0');
acam_config_rdbk(7) <= (others => '0');
acam_config_rdbk(8) <= (others => '0');
acam_config_rdbk(9) <= (others => '0');
acam_config_rdbk(10) <= (others => '0');
acam_ififo1_o <= (others => '0');
acam_ififo2_o <= (others => '0');
acam_start01_o <= (others => '0');
elsif acam_cyc = '1' and acam_stb = '1' and acam_ack_i = '1' and acam_we = '0' then
if acam_adr = c_ACAM_REG0_ADR then
acam_config_rdbk(0) <= acam_dat_i;
end if;
if acam_adr = c_ACAM_REG1_ADR then
acam_config_rdbk(1) <= acam_dat_i;
end if;
if acam_adr = c_ACAM_REG2_ADR then
acam_config_rdbk(2) <= acam_dat_i;
end if;
if acam_adr = c_ACAM_REG3_ADR then
acam_config_rdbk(3) <= acam_dat_i;
end if;
if acam_adr = c_ACAM_REG4_ADR then
acam_config_rdbk(4) <= acam_dat_i;
end if;
if acam_adr = c_ACAM_REG5_ADR then
acam_config_rdbk(5) <= acam_dat_i;
end if;
if acam_adr = c_ACAM_REG6_ADR then
acam_config_rdbk(6) <= acam_dat_i;
end if;
if acam_adr = c_ACAM_REG7_ADR then
acam_config_rdbk(7) <= acam_dat_i;
end if;
if acam_adr = c_ACAM_REG11_ADR then
acam_config_rdbk(8) <= acam_dat_i;
end if;
if acam_adr = c_ACAM_REG12_ADR then
acam_config_rdbk(9) <= acam_dat_i;
end if;
if acam_adr = c_ACAM_REG14_ADR then
acam_config_rdbk(10) <= acam_dat_i;
end if;
if acam_adr = c_ACAM_REG8_ADR then
acam_ififo1_o <= acam_dat_i;
end if;
if acam_adr = c_ACAM_REG9_ADR then
acam_ififo2_o <= acam_dat_i;
end if;
if acam_adr = c_ACAM_REG10_ADR then
acam_start01_o <= acam_dat_i;
end if;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
acam_tstamp1_o <= acam_dat_i;
acam_tstamp1_ok_p_o <= '1' when (acam_ack_i ='1' and engine_st = GET_STAMP1) else '0';
acam_tstamp2_o <= acam_dat_i;
acam_tstamp2_ok_p_o <= '1' when (acam_ack_i ='1' and engine_st = GET_STAMP2) else '0';
acam_config_rdbk_o <= acam_config_rdbk;
time_counter: incr_counter
generic map
(width => 32)
port map
(clk_i => clk_i,
rst_i => time_c_rst,
counter_top_i => x"0EE6B280",
counter_incr_en_i => time_c_en,
counter_is_full_o => time_c_full_p,
counter_o => time_c);
state_active_p_o <= time_c_full_p;
end architecture rtl;
--=================================================================================================
-- architecture end
--=================================================================================================
---------------------------------------------------------------------------------------------------
-- E N D O F F I L E
---------------------------------------------------------------------------------------------------
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- data_formatting |
-- |
---------------------------------------------------------------------------------------------------
-- File data_formatting.vhd |
-- |
-- Description Timestamp data formatting. |
-- Formats in a 128-bit word the |
-- o fine timestamps coming directly from the ACAM |
-- o plus the coarse timing internally measured in the core |
-- o plus the UTC time internally kept in the core |
-- and writes the word to the circular buffer |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 07/2013 |
-- Version v2.1 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 05/2011 v0.1 GP First version |
-- 04/2012 v0.11 EG Revamping; Comments added, signals renamed |
-- 04/2013 v1 EG Fixed bug when timestamop comes on the first retrigger after a new |
-- second; fixed bug on rollover that is a bit delayed wrt ACAM IrFlag |
-- 07/2013 v2 EG Cleaner writing with adition of intermediate DFF on the acam_tstamp |
-- calculations |
-- 09/2013 v2.1 EG added wr_index clearing upon dacapo_c_rst_p_i pulse; before only the |
-- dacapo_counter was being reset with the dacapo_c_rst_p_i |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions-- Specific library
-- Specific library
library work;
use work.tdc_core_pkg.all; -- definitions of types, constants, entities
--=================================================================================================
-- Entity declaration for data_formatting
--=================================================================================================
entity data_formatting is
port
-- INPUTS
-- Signal from the clk_rst_manager
(clk_i : in std_logic; -- 125 MHz clk
rst_i : in std_logic; -- general reset
-- Signals from the circular_buffer unit: WISHBONE classic
tstamp_wr_wb_ack_i : in std_logic; -- tstamp writing WISHBONE acknowledge
tstamp_wr_dat_i : in std_logic_vector(127 downto 0); -- not used
-- Signals from the data_engine unit
acam_tstamp1_ok_p_i : in std_logic; -- tstamp1 valid indicator
acam_tstamp1_i : in std_logic_vector(31 downto 0); -- 32 bits tstamp to be treated and stored;
-- includes ef1 & ef2 & 0 & 0 & 28 bits tstamp from FIFO1
acam_tstamp2_ok_p_i : in std_logic; -- tstamp2 valid indicator
acam_tstamp2_i : in std_logic_vector(31 downto 0); -- 32 bits tstamp to be treated and stored;
-- includes ef1 & ef2 & 0 & 0 & 28 bits tstamp from FIFO2
-- Signals from the reg_ctrl unit
dacapo_c_rst_p_i : in std_logic; -- instruction from GN4124/VME to clear dacapo flag
deactivate_chan_i : in std_logic_vector(4 downto 0); -- instruction from GN4124/VME to stop registering tstamps from a specific channel
-- Signals from the one_hz_gen unit
utc_i : in std_logic_vector(31 downto 0); -- local UTC time
-- Signals from the start_retrig_ctrl unit
roll_over_incr_recent_i : in std_logic;
clk_i_cycles_offset_i : in std_logic_vector(31 downto 0);
roll_over_nb_i : in std_logic_vector(31 downto 0);
retrig_nb_offset_i : in std_logic_vector(31 downto 0);
-- Signal from the one_hz_generator unit
utc_p_i : in std_logic;
-- OUTPUTS
-- Signals to the circular_buffer unit: WISHBONE classic
tstamp_wr_wb_cyc_o : out std_logic; -- tstamp writing WISHBONE cycle
tstamp_wr_wb_stb_o : out std_logic; -- tstamp writing WISHBONE strobe
tstamp_wr_wb_we_o : out std_logic; -- tstamp writing WISHBONE write enable
tstamp_wr_wb_adr_o : out std_logic_vector(7 downto 0); -- WISHBONE adr to write to
tstamp_wr_dat_o : out std_logic_vector(127 downto 0); -- tstamp to write
-- Signal to the irq_generator unit
tstamp_wr_p_o : out std_logic; -- pulse upon storage of a new tstamp
acam_channel_o : out std_logic_vector(2 downto 0); --
-- Signal to the reg_ctrl unit
wr_index_o : out std_logic_vector(31 downto 0)); -- index of last byte written
-- note that the index is provided
-- #bytes, as the GN4124/VME expects
-- (not in #128-bits-words)
end data_formatting;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of data_formatting is
constant c_MULTIPLY_BY_SIXTEEN : std_logic_vector(3 downto 0) := "0000";
-- ACAM timestamp fields
signal acam_channel : std_logic_vector(2 downto 0);
signal acam_slope, acam_fifo_ef : std_logic;
signal acam_fine_timestamp : std_logic_vector(16 downto 0);
signal acam_start_nb : unsigned(7 downto 0);
-- timestamp manipulations
signal un_acam_start_nb, un_clk_i_cycles_offset : unsigned(31 downto 0);
signal un_roll_over, un_nb_of_retrig, un_retrig_nb_offset : unsigned(31 downto 0);
signal un_nb_of_cycles, un_retrig_from_roll_over : unsigned(31 downto 0);
signal acam_start_nb_32 : unsigned(31 downto 0);
-- final timestamp fields
signal full_timestamp : std_logic_vector(127 downto 0);
signal metadata, local_utc, coarse_time, fine_time : std_logic_vector(31 downto 0);
-- circular buffer timestamp writings WISHBONE interface
signal tstamp_wr_cyc, tstamp_wr_stb, tstamp_wr_we : std_logic;
-- circular buffer counters
signal dacapo_counter : unsigned(19 downto 0);
signal wr_index : unsigned(7 downto 0);
-- coarse time calculations
signal tstamp_on_first_retrig_case1 : std_logic;
signal tstamp_on_first_retrig_case2 : std_logic;
signal un_previous_clk_i_cycles_offset : unsigned(31 downto 0);
signal un_previous_retrig_nb_offset : unsigned(31 downto 0);
signal un_previous_roll_over_nb : unsigned(31 downto 0);
signal un_current_retrig_nb_offset, un_current_roll_over_nb : unsigned(31 downto 0);
signal un_current_retrig_from_roll_over : unsigned(31 downto 0);
signal un_acam_fine_time :unsigned(31 downto 0);
signal previous_utc : std_logic_vector(31 downto 0);
signal acam_timestamps : unsigned (23 downto 0);
signal coarse_zero : std_logic;
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
---------------------------------------------------------------------------------------------------
-- WISHBONE STB, CYC, WE, ADR --
---------------------------------------------------------------------------------------------------
-- WISHBONE_master_signals: Generation of the WISHBONE classic signals STB, CYC, WE that initiate
-- writes to the circular_buffer memory. Upon acam_tstamp1_ok_p_i or acam_tstamp2_ok_p_i activation
-- the process activates the STB, CYC, WE signals and waits for an ACK; as soon as the ACK arrives
-- (and the tstamps are written in the memory) STB, CYC and WE are deactivated and a new
-- acam_tstamp1_ok_p_i or acam_tstamp2_ok_p_i pulse is awaited to initiate a new write cycle.
-- Reminder: timestamps (acam_tstamp1_ok_p_i or acam_tstamp2_ok_p_i pulses) can arrive at maximum
-- every 4 clk_i cycles (31.25 MHz).
-- clk_i : __|-|__|-|__|-|__|-|__|-|__|-|__|-|__|-|__|-|__|-|__|-|__ ...
-- acam_tstamp1_ok_p : ____________|----|______________|----|___________________ ...
-- tstamp_wr_wb_dat : _________________< one tstamp >< another tstamp > ...
-- tstamp_wr_wb_adr : address 0 >< address 1 >< address 2...
-- tstamp_wr_stb : _________________|--------|_________|---------|__________ ...
-- tstamp_wr_ack : ______________________|---|______________|----|__________ ...
WISHBONE_master_signals: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i = '1' then
tstamp_wr_stb <= '0';
tstamp_wr_cyc <= '0';
tstamp_wr_we <= '0';
elsif acam_tstamp1_ok_p_i = '1' then
if deactivate_chan_i = "00000" then
tstamp_wr_stb <= '1';
tstamp_wr_cyc <= '1';
tstamp_wr_we <= '1';
else
if deactivate_chan_i = "00001" and acam_tstamp1_i(27 downto 26) = "00" then
tstamp_wr_stb <= '0';
tstamp_wr_cyc <= '0';
tstamp_wr_we <= '0';
elsif deactivate_chan_i = "00010" and acam_tstamp1_i(27 downto 26) = "01" then
tstamp_wr_stb <= '0';
tstamp_wr_cyc <= '0';
tstamp_wr_we <= '0';
elsif deactivate_chan_i = "00100" and acam_tstamp1_i(27 downto 26) = "10" then
tstamp_wr_stb <= '0';
tstamp_wr_cyc <= '0';
tstamp_wr_we <= '0';
elsif deactivate_chan_i = "01000" and acam_tstamp1_i(27 downto 26) = "11" then
tstamp_wr_stb <= '0';
tstamp_wr_cyc <= '0';
tstamp_wr_we <= '0';
else
tstamp_wr_stb <= '1';
tstamp_wr_cyc <= '1';
tstamp_wr_we <= '1';
end if;
end if;
elsif acam_tstamp2_ok_p_i = '1' then
if deactivate_chan_i = "10000" then
tstamp_wr_stb <= '0';
tstamp_wr_cyc <= '0';
tstamp_wr_we <= '0';
else
tstamp_wr_stb <= '1';
tstamp_wr_cyc <= '1';
tstamp_wr_we <= '1';
end if;
elsif tstamp_wr_wb_ack_i = '1' then
tstamp_wr_stb <= '0';
tstamp_wr_cyc <= '0';
tstamp_wr_we <= '0';
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- tstamp_wr_wb_adr: the process keeps track of the place in the memory the next timestamp is to be
-- written; wr_index indicates which one is the next address to write to.
-- The index is also used by the GN4124 host to configure the DMA coherently (DMALENR register)
tstamp_wr_wb_adr: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' or dacapo_c_rst_p_i = '1' then
wr_index <= (others => '0');
elsif tstamp_wr_cyc = '1' and tstamp_wr_stb = '1' and tstamp_wr_we = '1' and tstamp_wr_wb_ack_i = '1' then
if wr_index = c_CIRCULAR_BUFF_SIZE - 1 then
wr_index <= (others => '0'); -- when memory completed, restart from the beginning
else
wr_index <= wr_index + 1; -- otherwise write to the next one
end if;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
tstamp_wr_p_o <= tstamp_wr_cyc and tstamp_wr_stb and tstamp_wr_we and tstamp_wr_wb_ack_i;
tstamp_wr_wb_adr_o <= std_logic_vector(wr_index);
wr_index_o <= std_logic_vector(dacapo_counter) & std_logic_vector(wr_index) & c_MULTIPLY_BY_SIXTEEN;
-- "& c_MULTIPLY_BY_SIXTEEN" for the convertion to the number of 8-bits-words
-- for the configuration of the DMA
---------------------------------------------------------------------------------------------------
-- Da Capo flag --
---------------------------------------------------------------------------------------------------
-- dacapo_counter_update: the Da Capo counter indicates the number of times the circular buffer
-- has been written completely; it can be cleared by the GN4124/VME host.
dacapo_counter_update: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' or dacapo_c_rst_p_i = '1' then
dacapo_counter <= (others => '0');
elsif tstamp_wr_cyc = '1' and tstamp_wr_stb = '1' and tstamp_wr_we = '1' and
tstamp_wr_wb_ack_i = '1' and wr_index = c_CIRCULAR_BUFF_SIZE - 1 then
dacapo_counter <= dacapo_counter + 1;
end if;
end if;
end process;
---------------------------------------------------------------------------------------------------
-- Final Timestamp Formatting --
---------------------------------------------------------------------------------------------------
-- tstamp_formatting: slicing of the 32-bits word acam_tstamp1_i and acam_tstamp2_i as received
-- from the data_engine unit, to construct the final timestamps to be stored in the circular_buffer
-- acam_tstamp1_i, acam_tstamp2_i have the following structure:
-- [16:0] Stop-Start \
-- [17] Slope \ ACAM 28 bits word
-- [25:18] Start number /
-- [27:26] Channel Code /
-- [28] 0 \
-- [29] 0 \ empty and load flags (added by the acam_databus_interface unit)
-- [30] ef2 /
-- [31] ef1 /
-- The final timestamp written in the circular_buffer is a 128-bits word divided in four
-- 32-bits words with the following structure:
-- [31:0] Fine time to be added to the Coarse time: "00..00" & 16 bit Stop-Start;
-- each bit represents 81.03 ps
-- [63:32] Coarse time within the current second, caclulated from the: Start number,
-- clk_i_cycles_offset_i, retrig_nb_offset_i, roll_over_nb_i
-- each bit represents 8 ns
-- [95:64] Local UTC time coming from the one_hz_generator;
-- each bit represents 1s
-- [127:96] Metadata for each timestamp: Slope(rising or falling tstamp), Channel
tstamp_formatting: process (clk_i) -- ACAM data handling DFF #2 (DFF #1 refers to the registering of the acam_tstamp1/2_ok_p)
begin
if rising_edge (clk_i) then
if rst_i ='1' then
acam_channel <= (others => '0');
acam_fifo_ef <= '0';
acam_fine_timestamp <= (others => '0');
acam_slope <= '0';
acam_start_nb <= (others => '0');
elsif acam_tstamp1_ok_p_i = '1' then
acam_channel <= "0" & acam_tstamp1_i(27 downto 26);
acam_fifo_ef <= acam_tstamp1_i(31);
acam_fine_timestamp <= acam_tstamp1_i(16 downto 0);
acam_slope <= acam_tstamp1_i(17);
acam_start_nb <= unsigned(acam_tstamp1_i(25 downto 18))-1;
elsif acam_tstamp2_ok_p_i ='1' then
acam_channel <= "1" & acam_tstamp2_i(27 downto 26);
acam_fifo_ef <= acam_tstamp2_i(30);
acam_fine_timestamp <= acam_tstamp2_i(16 downto 0);
acam_slope <= acam_tstamp2_i(17);
acam_start_nb <= unsigned(acam_tstamp2_i(25 downto 18))-1;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
reg_info_of_previous_sec: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i = '1' then
un_previous_clk_i_cycles_offset <= (others => '0');
un_previous_retrig_nb_offset <= (others => '0');
un_previous_roll_over_nb <= (others => '0');
previous_utc <= (others => '0');
elsif utc_p_i = '1' then
un_previous_clk_i_cycles_offset <= unsigned(clk_i_cycles_offset_i);
un_previous_retrig_nb_offset <= unsigned(retrig_nb_offset_i);
un_previous_roll_over_nb <= unsigned(roll_over_nb_i);
previous_utc <= utc_i;
end if;
end if;
end process;
dummy: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' then
acam_timestamps <= (others => '0');
elsif acam_tstamp1_ok_p_i = '1' or acam_tstamp2_ok_p_i = '1' then
acam_timestamps <= acam_timestamps+1;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- all the values needed for the calculations have to be converted to unsigned
un_acam_fine_time <= unsigned(fine_time);
acam_start_nb_32 <= x"000000" & acam_start_nb;
un_acam_start_nb <= unsigned(acam_start_nb_32);
un_current_retrig_nb_offset <= unsigned(retrig_nb_offset_i);
un_current_roll_over_nb <= unsigned(roll_over_nb_i);
un_current_retrig_from_roll_over <= shift_left(un_current_roll_over_nb-1, 8) when roll_over_incr_recent_i = '1' and un_acam_start_nb > 192
else shift_left(un_current_roll_over_nb, 8);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- The following process makes essential calculations for the definition of the coarse time.
-- Regarding the signals: un_clk_i_cycles_offset, un_retrig_nb_offset, local_utc it has to be defined
-- if the values that characterize the current second or the one previous to it should be used.
-- In the case where: a timestamp came on the same retgigger after a new second
-- (un_current_retrig_from_roll_over is 0 and un_acam_start_nb = un_current_retrig_nb_offset)
-- the values of the previous second should be used.
-- Also, according to the ACAM documentation there is an indeterminacy to whether the fine time refers
-- to the previous retrigger or the current one. The equation described on line 386 describes
-- the case where: a timestamp came on the same retgigger after a new second but the ACAM assigned
-- it to the previous retrigger (the "un_current_retrig_from_roll_over = 0" describes that a new second
-- has arrived; the "un_acam_fine_time > 6318" desribes a fine time that is referred to the previous retrigger;
-- 6318 * 81ps = 512ns which is a complete ACAM retrigger).
-- Regarding the un_retrig_from_roll_over, i.e. number of roll-overs of the ACAM-internal-start-retrigger-counter,
-- it has to be converted to a number of internal start retriggers, multiplying by 256 i.e. shifting left!
-- Note that if a new tstamp has arrived from the ACAM when the roll_over has just been increased, there are chances
-- the tstamp belongs to the previous roll-over value. This is because the moment the IrFlag is taken into account
-- in the FPGA is different from the moment the tstamp has arrived to the ACAM (several clk_i cycles to empty ACAM FIFOs).
-- So if in a timestamp the start_nb from the ACAM is close to the upper end (close to 255) and on the moment the timestamp
-- is being treated in the FPGA the IrFlag has recently been tripped it means that for the formatting of the tstamp the
-- previous value of the roll_over_c should be considered (before the IrFlag tripping).
-- Eva: have to calculate better the amount of tstamps that could have been accumulated before the rollover changes;
-- the current value we put "192" is not well studied for all cases!!
coarse_time_intermed_calcul: process (clk_i) -- ACAM data handling DFF #3; at the next cycle (#4) the data is written in memory
begin
if rising_edge (clk_i) then
if rst_i ='1' then
un_clk_i_cycles_offset <= (others => '0');
un_retrig_nb_offset <= (others => '0');
un_retrig_from_roll_over <= (others => '0');
local_utc <= (others => '0');
coarse_zero <= '0';
else
-- ACAM tstamp arrived on the same retgigger after a new second
if (un_acam_start_nb+un_current_retrig_from_roll_over = un_current_retrig_nb_offset) or
(un_acam_start_nb = un_current_retrig_nb_offset-1 and un_acam_fine_time > 6318 and (un_current_retrig_from_roll_over = 0) ) then
coarse_zero <= '1';
un_clk_i_cycles_offset <= un_previous_clk_i_cycles_offset;
un_retrig_nb_offset <= un_previous_retrig_nb_offset;
local_utc <= previous_utc;
-- ACAM tstamp arrived when roll_over has just increased
--if roll_over_incr_recent_i = '1' and un_acam_start_nb > 192 then
-- un_retrig_from_roll_over <= shift_left(un_previous_roll_over_nb-1, 8);
--else
un_retrig_from_roll_over <= shift_left(un_previous_roll_over_nb, 8);
--end if;
else
un_clk_i_cycles_offset <= unsigned(clk_i_cycles_offset_i);
un_retrig_nb_offset <= unsigned(retrig_nb_offset_i);
local_utc <= utc_i;
coarse_zero <= '0';
if roll_over_incr_recent_i = '1' and un_acam_start_nb > 192 then
un_retrig_from_roll_over <= shift_left(unsigned(roll_over_nb_i)-1, 8);
else
un_retrig_from_roll_over <= shift_left(unsigned(roll_over_nb_i), 8);
end if;
end if;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- the number of internal start retriggers actually occurred is calculated by subtracting the offset number
-- already present when the one_hz_pulse arrives, and adding the start nb provided by the ACAM.
un_nb_of_retrig <= un_retrig_from_roll_over - (un_retrig_nb_offset) + un_acam_start_nb;
-- finally, the coarse time is obtained by multiplying by the number of clk_i cycles in an internal
-- start retrigger period and adding the number of clk_i cycles still to be discounted when the
-- one_hz_pulse arrives.
un_nb_of_cycles <= shift_left(un_nb_of_retrig, c_ACAM_RETRIG_PERIOD_SHIFT) + un_clk_i_cycles_offset;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- coarse time: expressed as the number of 125 MHz clock cycles since the last one_hz_pulse.
-- Since the clk_i and the pulse are derived from the same PLL, any offset between them is constant
-- and will cancel when subtracting timestamps.
coarse_time <= std_logic_vector(un_nb_of_cycles);-- when coarse_zero = '0' else std_logic_vector(64-unsigned(clk_i_cycles_offset_i));
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- fine time: directly provided by ACAM as a number of BINs since the last internal retrigger
fine_time <= x"000" & "000" & acam_fine_timestamp;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- metadata: information about the timestamp
metadata <= std_logic_vector(acam_start_nb(7 downto 0)) & -- std_logic_vector(un_previous_retrig_nb_offset(7 downto 0)) & -- for debugging (24 MSbits)
coarse_zero &--acam_fifo_ef & roll_over_incr_recent_i & "0" & -- for debugging (3 bits)
std_logic_vector(un_retrig_nb_offset(7 downto 0)) & std_logic_vector(roll_over_nb_i(9 downto 0)) &
acam_slope & roll_over_incr_recent_i & acam_channel; -- 5 LSbits-----------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
full_timestamp(31 downto 0) <= fine_time;
full_timestamp(63 downto 32) <= coarse_time;
full_timestamp(95 downto 64) <= local_utc;
full_timestamp(127 downto 96) <= metadata;
tstamp_wr_dat_o <= full_timestamp;
---------------------------------------------------------------------------------------------------
-- Outputs --
---------------------------------------------------------------------------------------------------
-- wr_pointer_o <= dacapo_flag & std_logic_vector(wr_index(g_width-6 downto 0)) & x"0";
tstamp_wr_wb_cyc_o <= tstamp_wr_cyc;
tstamp_wr_wb_stb_o <= tstamp_wr_stb;
tstamp_wr_wb_we_o <= tstamp_wr_we;
acam_channel_o <= acam_channel;
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
\ No newline at end of file
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- decr_counter |
-- |
---------------------------------------------------------------------------------------------------
-- File decr_counter.vhd |
-- |
-- Description Stop counter. Configurable "counter_top_i" and "width". |
-- "Current count value" and "counting done" signals available. |
-- "Counter done" signal asserted simultaneous to "current count value = 0". |
-- Countdown is launched each time "counter_load_i" is asserted for one clock tick. |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 04/2012 |
-- Version v0.11 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 05/2011 v0.1 GP First version |
-- 04/2012 v0.11 EG Revamping; Comments added, signals renamed |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
--=================================================================================================
-- Entity declaration for decr_counter
--=================================================================================================
entity decr_counter is
generic
(width : integer := 32); -- default size
port
-- INPUTS
-- Signals from the clk_rst_manager
(clk_i : in std_logic;
rst_i : in std_logic;
-- Signals from any unit
counter_load_i : in std_logic; -- loads counter with counter_top_i value
counter_top_i : in std_logic_vector(width-1 downto 0); -- counter start value
-- OUTPUTS
-- Signals to any unit
counter_o : out std_logic_vector(width-1 downto 0);
counter_is_zero_o : out std_logic); -- counter empty indication
end decr_counter;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of decr_counter is
constant zeroes : unsigned(width-1 downto 0):=(others=>'0');
signal one : unsigned(width-1 downto 0);
signal counter : unsigned(width-1 downto 0) := (others=>'0'); -- init to avoid sim warnings
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
decr_counting: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i = '1' then
counter_is_zero_o <= '0';
counter <= zeroes;
elsif counter_load_i = '1' then
counter_is_zero_o <= '0';
counter <= unsigned(counter_top_i) - "1";
elsif counter = zeroes then
counter_is_zero_o <= '0';
counter <= zeroes;
elsif counter = one then
counter_is_zero_o <= '1';
counter <= counter - "1";
else
counter_is_zero_o <= '0';
counter <= counter - "1";
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
counter_o <= std_logic_vector(counter);
one <= zeroes + "1";
end architecture rtl;
--=================================================================================================
-- architecture end
--=================================================================================================
---------------------------------------------------------------------------------------------------
-- E N D O F F I L E
---------------------------------------------------------------------------------------------------
\ No newline at end of file
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- fmc_tdc_core |
-- |
---------------------------------------------------------------------------------------------------
-- File fmc_tdc_core.vhd |
-- |
-- Description The TDC core top level instanciates all the modules needed to provide to the |
-- GN4124/VME interface the timestamps generated in the ACAM chip. |
-- |
-- Figure 1 shows the architecture of this core. |
-- |
-- Each timestamp is a 128-bit word with the following structure: |
-- [31:0] Fine time | each bit represents 81.03 ps |
-- [63:32] Coarse time within the current second | each bit represents 8 ns |
-- [95:64] Local UTC time | each bit represents 1 s |
-- [127:96] Metadata | rising/falling tstamp, Channel |
-- |
-- As the structure indicates, each timestamp is referred to a UTC second; the coarse|
-- and fine time indicate with 81.03 ps resolution the amount of time passed after |
-- the last UTC second. The one_hz_gen unit is responsible for keeping the UTC time; |
-- currently this timekeeping depends on a TDC local oscillator, but future upgrades |
-- of the core would provide White Rabbit accuracy. |
-- Timestamps are formated to the structure above within the data_formatting unit and|
-- are stored in the circular_buffer, where the GN4124/VME core have direct access |
-- |
-- In this application, the ACAM is used in I-Mode which provides unlimited measuring|
-- range with internal start retriggers. ACAM's counter of retriggers however is not |
-- large enough and there is the need to follow the retriggers inside the core; the |
-- start_retrig_ctrl unit is responsible for that. |
-- |
-- The acam_databus_interface implements the communication with the ACAM for its |
-- configuration as well as for the timestamps retreival. |
-- The acam_timecontrol_interface is mainly responsible for delivering to the ACAM |
-- the start pulse, to which all timestamps are related. |
-- |
-- The regs_ctrl implements the communication with the GN4124/VME interface for the |
-- configuration of this core and of the ACAM. |
-- The data_engine is managing the transfering of the configuration registers from |
-- the regs_ctrl to the ACAM chip; it is also managing the timestamps' |
-- acquisition from the ACAM chip, making it available to the data_formatting unit. |
-- |
-- The core is providing an interrupt in any of the following 3 cases: |
-- o accumulation of timestamps larger than the settable threshold |
-- o more time passed than the settable time threshold and >=1 timestamps arrived |
-- o error occured in the ACAM chip |
-- |
-- The clks_rsts_manager unit is providing 125 MHz clock and resets to the core. |
-- _________________________________________________________ |
-- | | |
-- | ________________ ____________ | |
-- | | ____________ | | | ___________ | |
-- | | | | | | | | | | |
-- | | | ACAM time | | | | | irq gen | | |
-- | | | ctrl | | | | |___________| | |
-- | | |____________| | | | ___________ | ______ |
-- | | ____________ | | | | | | | | |
-- | | | | | | data | | | | | | |
-- | | | ACAM data | | | engine | | | | | | |
-- | | | ctrl | | | | | | | | | |
-- | | |____________| | | | | regs | | --> | | |
-- | |________________| | | | ctrl | | <-- | | |
-- ACAM <-- | fine time | | | | | | | |
-- chip --> | ____________ | | | | | | VME/ | |
-- | | | | | | | | |GN4124| |
-- | | start | | | | | | | core | |
-- | | retrig | | | | | | | | |
-- | |____________| | | | | | | | |
-- | coarse time | | | | | | | |
-- | | | | | | | | |
-- | ____________ |____________| |___________| | | | |
-- | | | ___________ | | | |
-- | | 1 Hz gen | ____________ | | | | | |
-- | |____________| | | | circular | | --> | | |
-- | UTC time | data | | buffer | | <-- | | |
-- | | formating | | | | | | |
-- | _________________ |____________| |___________| | | | |
-- | |____TDC LEDs_____| | |______| |
-- | | |
-- |_________________________________________________________| |
-- TDC core |
-- _________________________________________________________ |
-- | | |
-- | clks_rsts_manager | |
-- |_________________________________________________________| |
-- |
-- Figure 1: TDC core architecture |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 09/2013 |
-- Version v5.1 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 05/2011 v1 GP First version |
-- 06/2012 v2 EG Revamping; Comments added, signals renamed |
-- removed LEDs from top level |
-- new GN4124 core integrated |
-- carrier 1 wire master added |
-- mezzanine I2C master added |
-- mezzanine 1 wire master added |
-- interrupts generator added |
-- changed generation of rst_i |
-- DAC reconfiguration+needed regs added |
-- 06/2012 v3 EG Changes for v2 of TDC mezzanine |
-- Several pinout changes, |
-- acam_ref_clk LVDS instead of CMOS, |
-- no PLL_LD only PLL_STATUS |
-- 04/2013 v4 EG created fmc_tdc_core module; before was all on fmc_tdc_core |
-- 07/2013 v5 EG removed the clks_rsts_manager from the core; will go to top level |
-- 09/2013 v5.1EG added block of comments and archirecture drawing |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.tdc_core_pkg.all;
use work.gencores_pkg.all;
use work.wishbone_pkg.all;
use work.wrcore_pkg.all;
use work.genram_pkg.all;
--=================================================================================================
-- Entity declaration for fmc_tdc_core
--=================================================================================================
entity fmc_tdc_core is
generic
(g_span : integer := 32; -- address span in bus interfaces
g_width : integer := 32; -- data width in bus interfaces
values_for_simul : boolean := FALSE); -- this generic is set to TRUE
-- when instantiated in a test-bench
port
(-- Clock and reset
clk_125m_i : in std_logic; -- 125 MHz clk from the PLL on the TDC mezz
rst_i : in std_logic; -- global reset, synched to clk_125m_i
acam_refclk_r_edge_p_i : in std_logic; -- rising edge on 31.25MHz ACAM reference clock
send_dac_word_p_o : out std_logic; -- command from GN4124/VME to reconfigure the TDC mezz DAC with dac_word_o
dac_word_o : out std_logic_vector(23 downto 0); -- new DAC configuration word from GN4124/VME
-- Signals for the timing interface with the ACAM on TDC mezzanine
start_from_fpga_o : out std_logic; -- start pulse
err_flag_i : in std_logic; -- error flag
int_flag_i : in std_logic; -- interrupt flag
start_dis_o : out std_logic; -- start disable, not used
stop_dis_o : out std_logic; -- disables all acam channels
-- Signals for the data interface with the ACAM on TDC mezzanine
data_bus_io : inout std_logic_vector(27 downto 0);
address_o : out std_logic_vector(3 downto 0);
cs_n_o : out std_logic; -- chip select for ACAM
oe_n_o : out std_logic; -- output enable for ACAM
rd_n_o : out std_logic; -- read signal for ACAM
wr_n_o : out std_logic; -- write signal for ACAM
ef1_i : in std_logic; -- empty flag of ACAM iFIFO1
ef2_i : in std_logic; -- empty flag of ACAM iFIFO2
-- Signals for the Input Logic on TDC mezzanine
enable_inputs_o : out std_logic; -- enables all 5 inputs
term_en_1_o : out std_logic; -- Ch.1 termination enable of 50 Ohm termination
term_en_2_o : out std_logic; -- Ch.2 termination enable of 50 Ohm termination
term_en_3_o : out std_logic; -- Ch.3 termination enable of 50 Ohm termination
term_en_4_o : out std_logic; -- Ch.4 termination enable of 50 Ohm termination
term_en_5_o : out std_logic; -- Ch.5 termination enable of 50 Ohm termination
-- LEDs on TDC mezzanine
tdc_led_status_o : out std_logic; -- amber led on front pannel, division of clk_125m_i
tdc_led_trig1_o : out std_logic; -- amber led on front pannel, Ch.1 termination
tdc_led_trig2_o : out std_logic; -- amber led on front pannel, Ch.2 termination
tdc_led_trig3_o : out std_logic; -- amber led on front pannel, Ch.3 termination
tdc_led_trig4_o : out std_logic; -- amber led on front pannel, Ch.4 termination
tdc_led_trig5_o : out std_logic; -- amber led on front pannel, Ch.5 termination
-- TDC input signals, also arriving to the FPGA; not used currently
tdc_in_fpga_1_i : in std_logic; -- TDC input Ch.1, not used
tdc_in_fpga_2_i : in std_logic; -- TDC input Ch.2, not used
tdc_in_fpga_3_i : in std_logic; -- TDC input Ch.3, not used
tdc_in_fpga_4_i : in std_logic; -- TDC input Ch.4, not used
tdc_in_fpga_5_i : in std_logic; -- TDC input Ch.5, not used
-- Interrupts
irq_tstamp_p_o : out std_logic; -- if amount of tstamps > tstamps_threshold
irq_time_p_o : out std_logic; -- if 0 < amount of tstamps < tstamps_threshold and time > time_threshold
irq_acam_err_p_o : out std_logic; -- if ACAM err_flag_i is activated
-- White Rabbit control and status registers
wrabbit_status_reg_i : in std_logic_vector(g_width-1 downto 0);
wrabbit_ctrl_reg_o : out std_logic_vector(g_width-1 downto 0);
-- White Rabbit timing
wrabbit_synched_i : in std_logic;
wrabbit_tai_p_i : in std_logic;
wrabbit_tai_i : in std_logic_vector(31 downto 0);
-- WISHBONE bus interface with the GN4124/VME core for the configuration of the TDC core
tdc_config_wb_adr_i : in std_logic_vector(g_span-1 downto 0); -- WISHBONE classic address
tdc_config_wb_dat_i : in std_logic_vector(g_width-1 downto 0); -- WISHBONE classic data in
tdc_config_wb_stb_i : in std_logic; -- WISHBONE classic strobe
tdc_config_wb_we_i : in std_logic; -- WISHBONE classic write enable
tdc_config_wb_cyc_i : in std_logic; -- WISHBONE classic cycle
tdc_config_wb_ack_o : out std_logic; -- WISHBONE classic acknowledge
tdc_config_wb_dat_o : out std_logic_vector(g_width-1 downto 0); -- WISHBONE classic data out
-- WISHBONE bus interface with the GN4124/VME core for the retrieval of the timestamps from the TDC core memory
tdc_mem_wb_adr_i : in std_logic_vector(31 downto 0); -- WISHBONE pipelined address
tdc_mem_wb_dat_i : in std_logic_vector(31 downto 0); -- WISHBONE pipelined data in
tdc_mem_wb_stb_i : in std_logic; -- WISHBONE pipelined strobe
tdc_mem_wb_we_i : in std_logic; -- WISHBONE pipelined write enable
tdc_mem_wb_cyc_i : in std_logic; -- WISHBONE pipelined cycle
tdc_mem_wb_ack_o : out std_logic; -- WISHBONE pipelined acknowledge
tdc_mem_wb_dat_o : out std_logic_vector(31 downto 0); -- WISHBONE pipelined data out
tdc_mem_wb_stall_o : out std_logic; -- WISHBONE pipelined stall
direct_timestamp_o : out std_logic_vector(127 downto 0);
direct_timestamp_stb_o : out std_logic
);
end fmc_tdc_core;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of fmc_tdc_core is
-- ACAM communication
signal acm_adr : std_logic_vector(7 downto 0);
signal acm_cyc, acm_stb, acm_we, acm_ack : std_logic;
signal acm_dat_r, acm_dat_w : std_logic_vector(g_width-1 downto 0);
signal acam_ef1, acam_ef2, acam_ef1_meta, acam_ef2_meta : std_logic;
signal acam_errflag_f_edge_p, acam_errflag_r_edge_p : std_logic;
signal acam_intflag_f_edge_p : std_logic;
signal acam_tstamp1, acam_tstamp2 : std_logic_vector(g_width-1 downto 0);
signal acam_tstamp1_ok_p, acam_tstamp2_ok_p : std_logic;
-- control unit
signal activate_acq_p, deactivate_acq_p, load_acam_config : std_logic;
signal read_acam_config, read_acam_status, read_ififo1 : std_logic;
signal read_ififo2, read_start01, reset_acam, load_utc : std_logic;
signal clear_dacapo_counter, roll_over_incr_recent : std_logic;
signal deactivate_chan : std_logic_vector(4 downto 0);
signal pulse_delay, window_delay, clk_period : std_logic_vector(g_width-1 downto 0);
signal starting_utc, acam_inputs_en : std_logic_vector(g_width-1 downto 0);
signal acam_ififo1, acam_ififo2, acam_start01 : std_logic_vector(g_width-1 downto 0);
signal irq_tstamp_threshold, irq_time_threshold : std_logic_vector(g_width-1 downto 0);
signal local_utc, wr_index : std_logic_vector(g_width-1 downto 0);
signal acam_config, acam_config_rdbk : config_vector;
signal tstamp_wr_p, start_from_fpga, state_active_p : std_logic;
-- retrigger control
signal clk_i_cycles_offset, roll_over_nb, retrig_nb_offset: std_logic_vector(g_width-1 downto 0);
signal local_utc_p : std_logic;
signal current_retrig_nb : std_logic_vector(g_width-1 downto 0);
-- UTC
signal utc_p : std_logic;
signal utc, wrabbit_ctrl_reg : std_logic_vector(g_width-1 downto 0);
-- circular buffer
signal circ_buff_class_adr : std_logic_vector(7 downto 0);
signal circ_buff_class_stb, circ_buff_class_cyc : std_logic;
signal circ_buff_class_we, circ_buff_class_ack : std_logic;
signal circ_buff_class_data_wr, circ_buff_class_data_rd : std_logic_vector(4*g_width-1 downto 0);
-- LEDs
signal acam_channel : std_logic_vector(5 downto 0);
signal tdc_in_fpga_1, tdc_in_fpga_2, tdc_in_fpga_3 : std_logic_vector(1 downto 0);
signal tdc_in_fpga_4, tdc_in_fpga_5 : std_logic_vector(1 downto 0);
signal acam_tstamp_channel : std_logic_vector(2 downto 0);
-- Chipscope
component chipscope_ila
port (
CONTROL : inout std_logic_vector(35 downto 0);
CLK : in std_logic;
TRIG0 : in std_logic_vector(31 downto 0);
TRIG1 : in std_logic_vector(31 downto 0);
TRIG2 : in std_logic_vector(31 downto 0);
TRIG3 : in std_logic_vector(31 downto 0));
end component;
component chipscope_icon
port (
CONTROL0 : inout std_logic_vector (35 downto 0));
end component;
signal CONTROL : std_logic_vector(35 downto 0);
signal CLK : std_logic;
signal TRIG0 : std_logic_vector(31 downto 0);
signal TRIG1 : std_logic_vector(31 downto 0);
signal TRIG2 : std_logic_vector(31 downto 0);
signal TRIG3 : std_logic_vector(31 downto 0);
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
---------------------------------------------------------------------------------------------------
-- TDC REGISTERS CONTROLLER --
---------------------------------------------------------------------------------------------------
reg_control_block: reg_ctrl
generic map
(g_span => g_span,
g_width => g_width)
port map
(clk_i => clk_125m_i,
rst_i => rst_i,
tdc_config_wb_adr_i => tdc_config_wb_adr_i,
tdc_config_wb_dat_i => tdc_config_wb_dat_i,
tdc_config_wb_stb_i => tdc_config_wb_stb_i,
tdc_config_wb_we_i => tdc_config_wb_we_i,
tdc_config_wb_cyc_i => tdc_config_wb_cyc_i,
tdc_config_wb_ack_o => tdc_config_wb_ack_o,
tdc_config_wb_dat_o => tdc_config_wb_dat_o,
activate_acq_p_o => activate_acq_p,
deactivate_acq_p_o => deactivate_acq_p,
acam_wr_config_p_o => load_acam_config,
acam_rdbk_config_p_o => read_acam_config,
acam_rdbk_status_p_o => read_acam_status,
acam_rdbk_ififo1_p_o => read_ififo1,
acam_rdbk_ififo2_p_o => read_ififo2,
acam_rdbk_start01_p_o => read_start01,
acam_rst_p_o => reset_acam,
load_utc_p_o => load_utc,
dacapo_c_rst_p_o => clear_dacapo_counter,
deactivate_chan_o => deactivate_chan,
acam_config_rdbk_i => acam_config_rdbk,
acam_ififo1_i => acam_ififo1,
acam_ififo2_i => acam_ififo2,
acam_start01_i => acam_start01,
local_utc_i => utc,
irq_code_i => x"00000000",
core_status_i => x"00000000",
wr_index_i => wr_index,
wrabbit_status_reg_i => wrabbit_status_reg_i,
wrabbit_ctrl_reg_o => wrabbit_ctrl_reg,
acam_config_o => acam_config,
starting_utc_o => starting_utc,
acam_inputs_en_o => acam_inputs_en,
start_phase_o => window_delay,
irq_tstamp_threshold_o=> irq_tstamp_threshold,
irq_time_threshold_o => irq_time_threshold,
send_dac_word_p_o => send_dac_word_p_o,
dac_word_o => dac_word_o,
one_hz_phase_o => pulse_delay);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
wrabbit_ctrl_reg_o <= wrabbit_ctrl_reg;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- termination enable registers
term_enable_regs: process (clk_125m_i)
begin
if rising_edge (clk_125m_i) then
if rst_i = '1' then
enable_inputs_o <= '0';
term_en_5_o <= '0';
term_en_4_o <= '0';
term_en_3_o <= '0';
term_en_2_o <= '0';
term_en_1_o <= '0';
else
enable_inputs_o <= acam_inputs_en(7);
term_en_5_o <= acam_inputs_en(4);
term_en_4_o <= acam_inputs_en(3);
term_en_3_o <= acam_inputs_en(2);
term_en_2_o <= acam_inputs_en(1);
term_en_1_o <= acam_inputs_en(0);
end if;
end if;
end process;
---------------------------------------------------------------------------------------------------
-- LOCAL ONE HZ GENERATOR --
---------------------------------------------------------------------------------------------------
local_one_second_block: local_pps_gen
generic map
(g_width => g_width)
port map
(acam_refclk_r_edge_p_i => acam_refclk_r_edge_p_i,
clk_i => clk_125m_i,
clk_period_i => clk_period,
load_utc_p_i => load_utc,
pulse_delay_i => pulse_delay,
rst_i => rst_i,
starting_utc_i => starting_utc,
local_utc_o => local_utc,
local_utc_p_o => local_utc_p);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
clk_period <= c_SIM_CLK_PERIOD when values_for_simul else c_SYN_CLK_PERIOD;
---------------------------------------------------------------------------------------------------
-- ACAM TIMECONTROL INTERFACE --
---------------------------------------------------------------------------------------------------
acam_timing_block: acam_timecontrol_interface
port map
(err_flag_i => err_flag_i,
int_flag_i => int_flag_i,
start_from_fpga_o => start_from_fpga,
stop_dis_o => stop_dis_o,
acam_refclk_r_edge_p_i => acam_refclk_r_edge_p_i,
utc_p_i => utc_p,
clk_i => clk_125m_i,
activate_acq_p_i => activate_acq_p,
state_active_p_i => state_active_p,
deactivate_acq_p_i => deactivate_acq_p,
rst_i => rst_i,
window_delay_i => window_delay,
acam_errflag_f_edge_p_o => acam_errflag_f_edge_p,
acam_errflag_r_edge_p_o => acam_errflag_r_edge_p,
acam_intflag_f_edge_p_o => acam_intflag_f_edge_p);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
start_from_fpga_o <= start_from_fpga;
---------------------------------------------------------------------------------------------------
-- ACAM DATABUS INTERFACE --
---------------------------------------------------------------------------------------------------
acam_data_block: acam_databus_interface
port map
(ef1_i => ef1_i,
ef2_i => ef2_i,
data_bus_io => data_bus_io,
adr_o => address_o,
cs_n_o => cs_n_o,
oe_n_o => oe_n_o,
rd_n_o => rd_n_o,
wr_n_o => wr_n_o,
ef1_o => acam_ef1,
ef1_meta_o => acam_ef1_meta,
ef2_o => acam_ef2,
ef2_meta_o => acam_ef2_meta,
clk_i => clk_125m_i,
rst_i => rst_i,
adr_i => acm_adr,
cyc_i => acm_cyc,
dat_i => acm_dat_w,
stb_i => acm_stb,
we_i => acm_we,
ack_o => acm_ack,
dat_o => acm_dat_r);
---------------------------------------------------------------------------------------------------
-- ACAM START RETRIGGER CONTROLLER --
---------------------------------------------------------------------------------------------------
start_retrigger_block: start_retrig_ctrl
generic map
(g_width => g_width)
port map
(acam_intflag_f_edge_p_i => acam_intflag_f_edge_p,
clk_i => clk_125m_i,
utc_p_i => utc_p,
rst_i => rst_i,
current_retrig_nb_o => current_retrig_nb,
roll_over_incr_recent_o => roll_over_incr_recent,
clk_i_cycles_offset_o => clk_i_cycles_offset,
roll_over_nb_o => roll_over_nb,
retrig_nb_offset_o => retrig_nb_offset);
---------------------------------------------------------------------------------------------------
-- DATA ENGINE --
---------------------------------------------------------------------------------------------------
data_engine_block: data_engine
port map
(acam_ack_i => acm_ack,
acam_dat_i => acm_dat_r,
acam_adr_o => acm_adr,
acam_cyc_o => acm_cyc,
acam_dat_o => acm_dat_w,
acam_stb_o => acm_stb,
acam_we_o => acm_we,
clk_i => clk_125m_i,
rst_i => rst_i,
acam_ef1_i => acam_ef1,
acam_ef1_meta_i => acam_ef1_meta,
acam_ef2_i => acam_ef2,
acam_ef2_meta_i => acam_ef2_meta,
activate_acq_p_i => activate_acq_p,
deactivate_acq_p_i => deactivate_acq_p,
acam_wr_config_p_i => load_acam_config,
acam_rdbk_config_p_i => read_acam_config,
acam_rdbk_status_p_i => read_acam_status,
acam_rdbk_ififo1_p_i => read_ififo1,
acam_rdbk_ififo2_p_i => read_ififo2,
acam_rdbk_start01_p_i => read_start01,
acam_rst_p_i => reset_acam,
acam_config_i => acam_config,
start_from_fpga_i => start_from_fpga,
state_active_p_o => state_active_p,
acam_config_rdbk_o => acam_config_rdbk,
acam_ififo1_o => acam_ififo1,
acam_ififo2_o => acam_ififo2,
acam_start01_o => acam_start01,
acam_tstamp1_o => acam_tstamp1,
acam_tstamp1_ok_p_o => acam_tstamp1_ok_p,
acam_tstamp2_o => acam_tstamp2,
acam_tstamp2_ok_p_o => acam_tstamp2_ok_p);
---------------------------------------------------------------------------------------------------
-- DATA FORMATTING --
---------------------------------------------------------------------------------------------------
data_formatting_block: data_formatting
port map
(clk_i => clk_125m_i,
rst_i => rst_i,
tstamp_wr_wb_ack_i => circ_buff_class_ack,
tstamp_wr_dat_i => circ_buff_class_data_rd,
tstamp_wr_wb_adr_o => circ_buff_class_adr,
tstamp_wr_wb_cyc_o => circ_buff_class_cyc,
tstamp_wr_dat_o => circ_buff_class_data_wr,
tstamp_wr_wb_stb_o => circ_buff_class_stb,
tstamp_wr_wb_we_o => circ_buff_class_we,
acam_tstamp1_i => acam_tstamp1,
acam_tstamp1_ok_p_i => acam_tstamp1_ok_p,
acam_tstamp2_i => acam_tstamp2,
acam_tstamp2_ok_p_i => acam_tstamp2_ok_p,
dacapo_c_rst_p_i => clear_dacapo_counter,
deactivate_chan_i => deactivate_chan,
roll_over_incr_recent_i => roll_over_incr_recent,
clk_i_cycles_offset_i => clk_i_cycles_offset,
roll_over_nb_i => roll_over_nb,
retrig_nb_offset_i => retrig_nb_offset,
utc_p_i => utc_p,
utc_i => utc,
tstamp_wr_p_o => tstamp_wr_p,
acam_channel_o => acam_tstamp_channel,
wr_index_o => wr_index);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
utc <= wrabbit_tai_i when wrabbit_synched_i = '1' else local_utc;
utc_p <= wrabbit_tai_p_i when wrabbit_synched_i = '1' else local_utc_p;
direct_timestamp_stb_o <= circ_buff_class_cyc and circ_buff_class_stb and circ_buff_class_ack;
direct_timestamp_o <= circ_buff_class_data_wr;
---------------------------------------------------------------------------------------------------
-- INTERRUPTS GENERATOR --
---------------------------------------------------------------------------------------------------
interrupts_generator: irq_generator
generic map
(g_width => 32)
port map
(clk_i => clk_125m_i,
rst_i => rst_i,
irq_tstamp_threshold_i => irq_tstamp_threshold,
irq_time_threshold_i => irq_time_threshold,
acam_errflag_r_edge_p_i => acam_errflag_r_edge_p,
activate_acq_p_i => activate_acq_p,
deactivate_acq_p_i => deactivate_acq_p,
tstamp_wr_p_i => tstamp_wr_p,
irq_tstamp_p_o => irq_tstamp_p_o,
irq_time_p_o => irq_time_p_o,
irq_acam_err_p_o => irq_acam_err_p_o);
---------------------------------------------------------------------------------------------------
-- CIRCULAR BUFFER --
---------------------------------------------------------------------------------------------------
circular_buffer_block: circular_buffer
port map
(clk_i => clk_125m_i,
tstamp_wr_rst_i => rst_i,
tstamp_wr_adr_i => circ_buff_class_adr,
tstamp_wr_cyc_i => circ_buff_class_cyc,
tstamp_wr_dat_i => circ_buff_class_data_wr,
tstamp_wr_stb_i => circ_buff_class_stb,
tstamp_wr_we_i => circ_buff_class_we,
tstamp_wr_ack_p_o => circ_buff_class_ack,
tstamp_wr_dat_o => circ_buff_class_data_rd,
tdc_mem_wb_rst_i => rst_i,
tdc_mem_wb_adr_i => tdc_mem_wb_adr_i,
tdc_mem_wb_cyc_i => tdc_mem_wb_cyc_i,
tdc_mem_wb_dat_i => tdc_mem_wb_dat_i,
tdc_mem_wb_stb_i => tdc_mem_wb_stb_i,
tdc_mem_wb_we_i => tdc_mem_wb_we_i,
tdc_mem_wb_ack_o => tdc_mem_wb_ack_o,
tdc_mem_wb_dat_o => tdc_mem_wb_dat_o,
tdc_mem_wb_stall_o => tdc_mem_wb_stall_o);
---------------------------------------------------------------------------------------------------
-- TDC LEDs --
---------------------------------------------------------------------------------------------------
TDCboard_leds: leds_manager
generic map
(g_width => 32,
values_for_simul => values_for_simul)
port map
(clk_i => clk_125m_i,
rst_i => rst_i,
utc_p_i => local_utc_p,
acam_inputs_en_i => acam_inputs_en,
acam_channel_i => acam_channel,
tstamp_wr_p_i => tstamp_wr_p,
tdc_led_status_o => tdc_led_status_o,
tdc_led_trig1_o => tdc_led_trig1_o,
tdc_led_trig2_o => tdc_led_trig2_o,
tdc_led_trig3_o => tdc_led_trig3_o,
tdc_led_trig4_o => tdc_led_trig4_o,
tdc_led_trig5_o => tdc_led_trig5_o);
acam_channel <= "000" & acam_tstamp_channel;
---------------------------------------------------------------------------------------------------
-- ACAM start_dis, not used --
---------------------------------------------------------------------------------------------------
start_dis_o <= '0';
---------------------------------------------------------------------------------------------------
-- CHIPSCOPE --
---------------------------------------------------------------------------------------------------
-- chipscope_ila_1 : chipscope_ila
-- port map (
-- CONTROL => CONTROL,
-- CLK => clk_125m_i,
-- TRIG0 => TRIG0,
-- TRIG1 => TRIG1,
-- TRIG2 => TRIG2,
-- TRIG3 => TRIG3);
--chipscope_icon_1 : chipscope_icon
-- port map (
-- CONTROL0 => CONTROL);
TRIG0(0) <= utc_p;
TRIG0(1) <= ef1_i;
TRIG0(2) <= int_flag_i;
TRIG0(3) <= acam_intflag_f_edge_p;
TRIG0(16 downto 4) <= roll_over_nb(12 downto 0);
TRIG0(17) <= start_from_fpga;
TRIG0(25 downto 18) <= retrig_nb_offset(7 downto 0);
TRIG0(31 downto 26) <= clk_i_cycles_offset(5 downto 0);
TRIG1(30 downto 0) <= acam_tstamp1(30 downto 0);
TRIG1(31) <= acam_tstamp1_ok_p;
TRIG2(31 downto 0) <= utc(31 downto 0);
TRIG3(0) <= tdc_in_fpga_1_i;
TRIG3(31 downto 1) <= current_retrig_nb(30 downto 0);
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- fmc_tdc_mezzanine |
-- |
---------------------------------------------------------------------------------------------------
-- File fmc_tdc_mezzanine.vhd |
-- |
-- Description The unit combines |
-- o the TDC core |
-- o the I2C core for the communication with the TDC board EEPROM |
-- o the OneWire core for the communication with the TDC board UniqueID&Thermeter |
-- o the Embedded Ibterrupt Controller core that concentrates several interrupt |
-- sources into one WISHBONE interrupt request line. |
-- |
-- For the interconnection between the GN4124/VME core and the different cores (TDC, |
-- I2C, 1W, EIC) the unit instantiates an SDB crossbar. |
-- |
-- Note that the TDC core has two WISHBONE buses, one for the configuration (of the |
-- core itself and of the ACAM) and one for the retrieval of the timestamps from the |
-- memory. |
-- |
-- Note that the SPI interface for the DAC on the TDC board is implemented in the |
-- clcks_rsts_manager;no access to the DAC is provided through GN4124/VME interface |
-- |
-- Note that the TDC core uses word addressing, whereas the GN4124/VME cores use byte|
-- addressing |
-- _______________________________ |
-- | FMC TDC mezzanine | |
-- | ________________ ___ | |
-- | | | | | | |
-- ACAM chip <--> | | TDC core | | | | <--> |
-- | |________________| | S | | |
-- | ________________ | | | |
-- | | | | | | |
-- EEPROM chip <--> | | I2C core | | | | <--> |
-- | |________________| | | | |
-- | ________________ | D | | GN4124/VME core |
-- | | | | | | |
-- 1W chip <--> | | 1W core | | | | <--> |
-- | |________________| | | | |
-- | ________________ | | | |
-- | | | | B | | |
-- | | EIC | | | | <--> |
-- | |________________| |___| | |
-- | | |
-- |_______________________________| |
-- ^ ^ |
-- | 125 MHz rst | |
-- __|________________________|___ |
-- | | |
-- DAC chip <--> | clks_rsts_manager | |
-- PLL chip |_______________________________| |
-- |
-- Figure 1: FMC TDC mezzanine architecture and |
-- connection with the clks_rsts_manager unit |
-- |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 01/2014 |
-- Version v2 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 07/2013 v1 EG First version |
-- 01/2014 v2 EG Different output for the timestamp data |
-- 01/2014 v3 EG Removed option for timestamps retrieval through DMA |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.tdc_core_pkg.all;
use work.gencores_pkg.all;
use work.wishbone_pkg.all;
--=================================================================================================
-- Entity declaration for fmc_tdc_mezzanine
--=================================================================================================
entity fmc_tdc_mezzanine is
generic
(g_span : integer := 32;
g_width : integer := 32;
values_for_simul : boolean := FALSE);
port
-- TDC core
(-- Closk reset62.5
clk_sys_i : in std_logic;
rst_sys_n_i : in std_logic;
-- Signals from the clks_rsts_manager unit
clk_ref_0_i : in std_logic;
rst_ref_0_i : in std_logic;
acam_refclk_r_edge_p_i : in std_logic;
send_dac_word_p_o : out std_logic;
dac_word_o : out std_logic_vector(23 downto 0);
-- Interface with ACAM
start_from_fpga_o : out std_logic;
err_flag_i : in std_logic;
int_flag_i : in std_logic;
start_dis_o : out std_logic;
stop_dis_o : out std_logic;
data_bus_io : inout std_logic_vector(27 downto 0);
address_o : out std_logic_vector(3 downto 0);
cs_n_o : out std_logic;
oe_n_o : out std_logic;
rd_n_o : out std_logic;
wr_n_o : out std_logic;
ef1_i : in std_logic;
ef2_i : in std_logic;
-- Channels termination
enable_inputs_o : out std_logic;
term_en_1_o : out std_logic;
term_en_2_o : out std_logic;
term_en_3_o : out std_logic;
term_en_4_o : out std_logic;
term_en_5_o : out std_logic;
-- TDC board LEDs
tdc_led_status_o : out std_logic;
tdc_led_trig1_o : out std_logic;
tdc_led_trig2_o : out std_logic;
tdc_led_trig3_o : out std_logic;
tdc_led_trig4_o : out std_logic;
tdc_led_trig5_o : out std_logic;
-- Input pulses arriving also to the FPGA, currently not treated
tdc_in_fpga_1_i : in std_logic;
tdc_in_fpga_2_i : in std_logic;
tdc_in_fpga_3_i : in std_logic;
tdc_in_fpga_4_i : in std_logic;
tdc_in_fpga_5_i : in std_logic;
-- White Rabbit core
wrabbit_link_up_i : in std_logic;
wrabbit_time_valid_i : in std_logic;
wrabbit_cycles_i : in std_logic_vector(27 downto 0);
wrabbit_utc_i : in std_logic_vector(31 downto 0);
wrabbit_utc_p_o : out std_logic;
wrabbit_clk_aux_lock_en_o : out std_logic;
wrabbit_clk_aux_locked_i : in std_logic;
wrabbit_clk_dmtd_locked_i : in std_logic;
wrabbit_dac_value_i : in std_logic_vector(23 downto 0);
wrabbit_dac_wr_p_i : in std_logic;
-- WISHBONE interface with the GN4124/VME_core
-- for the core configuration | timestamps retrieval | core interrupts | 1Wire | I2C
wb_tdc_csr_adr_i : in std_logic_vector(31 downto 0);
wb_tdc_csr_dat_i : in std_logic_vector(31 downto 0);
wb_tdc_csr_cyc_i : in std_logic;
wb_tdc_csr_sel_i : in std_logic_vector(3 downto 0);
wb_tdc_csr_stb_i : in std_logic;
wb_tdc_csr_we_i : in std_logic;
wb_tdc_csr_dat_o : out std_logic_vector(31 downto 0);
wb_tdc_csr_ack_o : out std_logic;
wb_tdc_csr_stall_o : out std_logic;
wb_irq_o : out std_logic;
-- I2C EEPROM interface
i2c_scl_o : out std_logic;
i2c_scl_oen_o : out std_logic;
i2c_scl_i : in std_logic;
i2c_sda_oen_o : out std_logic;
i2c_sda_o : out std_logic;
i2c_sda_i : in std_logic;
-- 1-Wire interface
one_wire_b : inout std_logic;
-- For debug: interrupt pulses from TDC core
irq_tstamp_p_o : out std_logic;
irq_time_p_o : out std_logic;
irq_acam_err_p_o : out std_logic;
direct_timestamp_o : out std_logic_vector(127 downto 0);
direct_timestamp_stb_o : out std_logic
);
end fmc_tdc_mezzanine;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of fmc_tdc_mezzanine is
---------------------------------------------------------------------------------------------------
-- SDB CONSTANTS --
---------------------------------------------------------------------------------------------------
-- Note: All address in sdb and crossbar are BYTE addresses!
-- Master ports on the wishbone crossbar
constant c_NUM_WB_MASTERS : integer := 5;
constant c_WB_SLAVE_TDC_ONEWIRE : integer := 0; -- TDC mezzanine board UnidueID&Thermometer 1-wire
constant c_WB_SLAVE_TDC_CORE_CONFIG : integer := 1; -- TDC core configuration registers
constant c_WB_SLAVE_TDC_EIC : integer := 2; -- TDC interrupts
constant c_WB_SLAVE_TDC_I2C : integer := 3; -- TDC mezzanine board system EEPROM I2C
constant c_WB_SLAVE_TSTAMP_MEM : integer := 4; -- Access to TDC core memory for timestamps retrieval
-- Slave port on the wishbone crossbar
constant c_NUM_WB_SLAVES : integer := 1;
-- Wishbone master(s)
constant c_WB_MASTER : integer := 0;
-- sdb header address
constant c_SDB_ADDRESS : t_wishbone_address := x"00000000";
-- WISHBONE crossbar layout
constant c_INTERCONNECT_LAYOUT : t_sdb_record_array(4 downto 0) :=
(0 => f_sdb_embed_device(c_ONEWIRE_SDB_DEVICE, x"00010000"),
1 => f_sdb_embed_device(c_TDC_CONFIG_SDB_DEVICE, x"00011000"),
2 => f_sdb_embed_device(c_TDC_EIC_DEVICE, x"00012000"),
3 => f_sdb_embed_device(c_I2C_SDB_DEVICE, x"00013000"),
4 => f_sdb_embed_device(c_TDC_MEM_SDB_DEVICE, x"00014000"));
---------------------------------------------------------------------------------------------------
-- Signals --
---------------------------------------------------------------------------------------------------
-- resets
signal general_rst_n, rst_ref_0_n: std_logic;
-- Wishbone buse(s) from crossbar master port(s)
signal cnx_master_out : t_wishbone_master_out_array(c_NUM_WB_MASTERS-1 downto 0);
signal cnx_master_in : t_wishbone_master_in_array (c_NUM_WB_MASTERS-1 downto 0);
-- Wishbone buse(s) to crossbar slave port(s)
signal cnx_slave_out : t_wishbone_slave_out_array(c_NUM_WB_SLAVES-1 downto 0);
signal cnx_slave_in : t_wishbone_slave_in_array (c_NUM_WB_SLAVES-1 downto 0);
-- Wishbone bus from additional registers
signal xreg_slave_out : t_wishbone_slave_out;
signal xreg_slave_in : t_wishbone_slave_in;
-- WISHBONE addresses
signal tdc_core_wb_adr : std_logic_vector(31 downto 0);
signal tdc_mem_wb_adr : std_logic_vector(31 downto 0);
-- 1-wire
signal mezz_owr_en, mezz_owr_i : std_logic_vector(0 downto 0);
-- I2C
signal sys_scl_in, sys_scl_out : std_logic;
signal sys_scl_oe_n, sys_sda_in : std_logic;
signal sys_sda_out, sys_sda_oe_n : std_logic;
-- IRQ
signal irq_tstamp_p, irq_time_p : std_logic;
signal irq_acam_err_p : std_logic;
-- WRabbit
signal reg_to_wr, reg_from_wr : std_logic_vector(31 downto 0);
signal wrabbit_utc_p : std_logic;
signal wrabbit_synched : std_logic;
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
rst_ref_0_n <= not(rst_ref_0_i);
---------------------------------------------------------------------------------------------------
-- CSR WISHBONE CROSSBAR --
---------------------------------------------------------------------------------------------------
-- CSR wishbone address decoder
-- 0x10000 -> TDC core configuration
-- 0x11000 -> TDC mezzanine board 1-Wire
-- 0x12000 -> EIC for TDC core
-- 0x13000 -> TDC mezzanine board EEPROM I2C
-- 0x14000 -> TDC core timestamps retreival
-- Additional register to help timing
cmp_xwb_reg : xwb_register_link
port map
(clk_sys_i => clk_ref_0_i,
rst_n_i => rst_ref_0_n,
slave_i => xreg_slave_in,
slave_o => xreg_slave_out,
master_i => cnx_slave_out(c_WB_MASTER),
master_o => cnx_slave_in(c_WB_MASTER));
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Unused wishbone signals
wb_tdc_csr_dat_o <= xreg_slave_out.dat;
wb_tdc_csr_ack_o <= xreg_slave_out.ack;
wb_tdc_csr_stall_o <= xreg_slave_out.stall;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Connect crossbar slave port to entity port
xreg_slave_in.adr <= wb_tdc_csr_adr_i;
xreg_slave_in.dat <= wb_tdc_csr_dat_i;
xreg_slave_in.sel <= wb_tdc_csr_sel_i;
xreg_slave_in.stb <= wb_tdc_csr_stb_i;
xreg_slave_in.we <= wb_tdc_csr_we_i;
xreg_slave_in.cyc <= wb_tdc_csr_cyc_i;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
cmp_sdb_crossbar : xwb_sdb_crossbar
generic map
(g_num_masters => c_NUM_WB_SLAVES,
g_num_slaves => c_NUM_WB_MASTERS,
g_registered => true,
g_wraparound => true,
g_layout => c_INTERCONNECT_LAYOUT,
g_sdb_addr => c_SDB_ADDRESS)
port map
(clk_sys_i => clk_ref_0_i,
rst_n_i => rst_ref_0_n,
slave_i => cnx_slave_in,
slave_o => cnx_slave_out,
master_i => cnx_master_in,
master_o => cnx_master_out);
---------------------------------------------------------------------------------------------------
-- TDC CORE --
---------------------------------------------------------------------------------------------------
cmp_tdc_core: fmc_tdc_core
generic map
(g_span => g_span,
g_width => g_width,
values_for_simul => FALSE)
port map
(-- clks, rst
clk_125m_i => clk_ref_0_i,
rst_i => rst_ref_0_i,
acam_refclk_r_edge_p_i => acam_refclk_r_edge_p_i,
-- DAC configuration
send_dac_word_p_o => send_dac_word_p_o,
dac_word_o => dac_word_o,
-- ACAM
start_from_fpga_o => start_from_fpga_o,
err_flag_i => err_flag_i,
int_flag_i => int_flag_i,
start_dis_o => start_dis_o,
stop_dis_o => stop_dis_o,
data_bus_io => data_bus_io,
address_o => address_o,
cs_n_o => cs_n_o,
oe_n_o => oe_n_o,
rd_n_o => rd_n_o,
wr_n_o => wr_n_o,
ef1_i => ef1_i,
ef2_i => ef2_i,
-- Input channels enable
enable_inputs_o => enable_inputs_o,
term_en_1_o => term_en_1_o,
term_en_2_o => term_en_2_o,
term_en_3_o => term_en_3_o,
term_en_4_o => term_en_4_o,
term_en_5_o => term_en_5_o,
-- Input channels to FPGA (not used currently)
tdc_in_fpga_1_i => tdc_in_fpga_1_i,
tdc_in_fpga_2_i => tdc_in_fpga_2_i,
tdc_in_fpga_3_i => tdc_in_fpga_3_i,
tdc_in_fpga_4_i => tdc_in_fpga_4_i,
tdc_in_fpga_5_i => tdc_in_fpga_5_i,
-- TDC board LEDs
tdc_led_status_o => tdc_led_status_o,
tdc_led_trig1_o => tdc_led_trig1_o,
tdc_led_trig2_o => tdc_led_trig2_o,
tdc_led_trig3_o => tdc_led_trig3_o,
tdc_led_trig4_o => tdc_led_trig4_o,
tdc_led_trig5_o => tdc_led_trig5_o,
-- Interrupts
irq_tstamp_p_o => irq_tstamp_p,
irq_time_p_o => irq_time_p,
irq_acam_err_p_o => irq_acam_err_p,
-- WR stuff
wrabbit_tai_i => wrabbit_utc_i,
wrabbit_tai_p_i => wrabbit_utc_p,
wrabbit_synched_i => wrabbit_synched,
wrabbit_status_reg_i => reg_from_wr,
wrabbit_ctrl_reg_o => reg_to_wr,
-- WISHBONE CSR for core configuration
tdc_config_wb_adr_i => tdc_core_wb_adr,
tdc_config_wb_dat_i => cnx_master_out(c_WB_SLAVE_TDC_CORE_CONFIG).dat,
tdc_config_wb_stb_i => cnx_master_out(c_WB_SLAVE_TDC_CORE_CONFIG).stb,
tdc_config_wb_we_i => cnx_master_out(c_WB_SLAVE_TDC_CORE_CONFIG).we,
tdc_config_wb_cyc_i => cnx_master_out(c_WB_SLAVE_TDC_CORE_CONFIG).cyc,
tdc_config_wb_dat_o => cnx_master_in(c_WB_SLAVE_TDC_CORE_CONFIG).dat,
tdc_config_wb_ack_o => cnx_master_in(c_WB_SLAVE_TDC_CORE_CONFIG).ack,
-- WISHBONE for timestamps transfer
tdc_mem_wb_adr_i => tdc_mem_wb_adr,--wb_tdc_mem_adr_i,
tdc_mem_wb_dat_i => cnx_master_out(c_WB_SLAVE_TSTAMP_MEM).dat,
tdc_mem_wb_stb_i => cnx_master_out(c_WB_SLAVE_TSTAMP_MEM).stb,
tdc_mem_wb_we_i => cnx_master_out(c_WB_SLAVE_TSTAMP_MEM).we,
tdc_mem_wb_cyc_i => cnx_master_out(c_WB_SLAVE_TSTAMP_MEM).cyc,
tdc_mem_wb_ack_o => cnx_master_in(c_WB_SLAVE_TSTAMP_MEM).ack,
tdc_mem_wb_dat_o => cnx_master_in(c_WB_SLAVE_TSTAMP_MEM).dat,
tdc_mem_wb_stall_o => cnx_master_in(c_WB_SLAVE_TSTAMP_MEM).stall,
direct_timestamp_o => direct_timestamp_o,
direct_timestamp_stb_o => direct_timestamp_stb_o);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Convert byte address into word address
tdc_core_wb_adr <= "00" & cnx_master_out(c_WB_SLAVE_TDC_CORE_CONFIG).adr(31 downto 2);
tdc_mem_wb_adr <= "00" & cnx_master_out(c_WB_SLAVE_TSTAMP_MEM).adr(31 downto 2);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Unused wishbone signals
cnx_master_in(c_WB_SLAVE_TDC_CORE_CONFIG).err <= '0';
cnx_master_in(c_WB_SLAVE_TDC_CORE_CONFIG).rty <= '0';
cnx_master_in(c_WB_SLAVE_TDC_CORE_CONFIG).stall <= '0';
cnx_master_in(c_WB_SLAVE_TDC_CORE_CONFIG).int <= '0';
cnx_master_in(c_WB_SLAVE_TSTAMP_MEM).err <= '0';
cnx_master_in(c_WB_SLAVE_TSTAMP_MEM).rty <= '0';
cnx_master_in(c_WB_SLAVE_TSTAMP_MEM).int <= '0';
---------------------------------------------------------------------------------------------------
-- WHITE RABBIT STUFF --
---------------------------------------------------------------------------------------------------
cmp_wrabbit_synch: wrabbit_sync
generic map
(g_simulation => false,
g_with_wrabbit_core => true)
port map
(clk_sys_i => clk_sys_i,
rst_n_sys_i => rst_sys_n_i,
clk_ref_i => clk_ref_0_i,
rst_n_ref_i => rst_ref_0_n,
wrabbit_dac_value_i => wrabbit_dac_value_i,
wrabbit_dac_wr_p_i => wrabbit_dac_wr_p_i,
wrabbit_link_up_i => wrabbit_link_up_i,
wrabbit_time_valid_i => wrabbit_time_valid_i,
wrabbit_clk_aux_lock_en_o => wrabbit_clk_aux_lock_en_o,
wrabbit_clk_aux_locked_i => wrabbit_clk_aux_locked_i,
wrabbit_clk_dmtd_locked_i => '1', -- FIXME
wrabbit_synched_o => wrabbit_synched,
wrabbit_reg_i => reg_to_wr, -- synced to 125MHz mezzanine
wrabbit_reg_o => reg_from_wr); -- synced to 125MHz mezzanine
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
wrabbit_one_hz_pulse : process(clk_ref_0_i)
begin
if rising_edge(clk_ref_0_i) then
if((wrabbit_clk_aux_locked_i = '1')) then --and g_with_wrabbit_core) then
if unsigned(wrabbit_cycles_i) = unsigned(c_SYN_CLK_PERIOD) -1 then
wrabbit_utc_p <= '1';
else
wrabbit_utc_p <= '0';
end if;
else
wrabbit_utc_p <= '0';
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
wrabbit_utc_p_o <= wrabbit_utc_p;
---------------------------------------------------------------------------------------------------
-- TDC Mezzanine Board UniqueID&Thermometer OneWire --
---------------------------------------------------------------------------------------------------
cmp_fmc_onewire : xwb_onewire_master
generic map
(g_interface_mode => PIPELINED,
g_address_granularity => BYTE,
g_num_ports => 1,
g_ow_btp_normal => "5.0",
g_ow_btp_overdrive => "1.0")
port map
(clk_sys_i => clk_ref_0_i,
rst_n_i => rst_ref_0_n,
slave_i => cnx_master_out(c_WB_SLAVE_TDC_ONEWIRE),
slave_o => cnx_master_in(c_WB_SLAVE_TDC_ONEWIRE),
desc_o => open,
owr_pwren_o => open,
owr_en_o => mezz_owr_en,
owr_i => mezz_owr_i);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
one_wire_b <= '0' when mezz_owr_en(0) = '1' else 'Z';
mezz_owr_i(0) <= one_wire_b;
---------------------------------------------------------------------------------------------------
-- WBGEN2 EMBEDDED INTERRUPTS CONTROLLER --
---------------------------------------------------------------------------------------------------
-- IRQ sources
-- 0 -> number of accumulated timestamps reached threshold
-- 1 -> number of seconds passed reached threshold and number of accumulated tstamps > 0
-- 2 -> ACAM error
cmp_tdc_eic : tdc_eic
port map
(clk_sys_i => clk_ref_0_i,
rst_n_i => rst_ref_0_n,
wb_adr_i => cnx_master_out(c_WB_SLAVE_TDC_EIC).adr(3 downto 2),
wb_dat_i => cnx_master_out(c_WB_SLAVE_TDC_EIC).dat,
wb_dat_o => cnx_master_in(c_WB_SLAVE_TDC_EIC).dat,
wb_cyc_i => cnx_master_out(c_WB_SLAVE_TDC_EIC).cyc,
wb_sel_i => cnx_master_out(c_WB_SLAVE_TDC_EIC).sel,
wb_stb_i => cnx_master_out(c_WB_SLAVE_TDC_EIC).stb,
wb_we_i => cnx_master_out(c_WB_SLAVE_TDC_EIC).we,
wb_ack_o => cnx_master_in(c_WB_SLAVE_TDC_EIC).ack,
wb_stall_o => cnx_master_in(c_WB_SLAVE_TDC_EIC).stall,
wb_int_o => wb_irq_o,
irq_tdc_tstamps_i => irq_tstamp_p,
irq_tdc_time_i => irq_time_p,
irq_tdc_acam_err_i => irq_acam_err_p);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Unused wishbone signals
cnx_master_in(c_WB_SLAVE_TDC_EIC).err <= '0';
cnx_master_in(c_WB_SLAVE_TDC_EIC).rty <= '0';
cnx_master_in(c_WB_SLAVE_TDC_EIC).int <= '0';
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Only for debug
irq_tstamp_p_o <= irq_tstamp_p;
irq_time_p_o <= irq_time_p;
irq_acam_err_p_o <= irq_acam_err_p;
---------------------------------------------------------------------------------------------------
-- TDC Mezzanine Board EEPROM I2C --
---------------------------------------------------------------------------------------------------
cmp_I2C_master : xwb_i2c_master
generic map
(g_interface_mode => PIPELINED,
g_address_granularity => BYTE)
port map
(clk_sys_i => clk_ref_0_i,
rst_n_i => rst_ref_0_n,
slave_i => cnx_master_out(c_WB_SLAVE_TDC_I2C),
slave_o => cnx_master_in(c_WB_SLAVE_TDC_I2C),
desc_o => open,
scl_pad_i => i2c_scl_i,
scl_pad_o => sys_scl_out,
scl_padoen_o => sys_scl_oe_n,
sda_pad_i => i2c_sda_i,
sda_pad_o => sys_sda_out,
sda_padoen_o => sys_sda_oe_n);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
i2c_sda_oen_o <= sys_sda_oe_n;
i2c_sda_o <= sys_sda_out;
i2c_scl_oen_o <= sys_scl_oe_n;
i2c_scl_o <= sys_scl_out;
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- free_counter |
-- |
---------------------------------------------------------------------------------------------------
-- File free_counter.vhd |
-- |
-- Description Free running counter. Configurable "counter_top_i" and "width". |
-- "Current count value" and "counting done" signal available. |
-- "Counting done" signal asserted simultaneous to "current count value = 0". |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 04/2012 |
-- Version v0.11 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 05/2011 v0.1 GP First version |
-- 04/2012 v0.11 EG Revamping; Comments added, signals renamed |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
--=================================================================================================
-- Entity declaration for free_counter
--=================================================================================================
entity free_counter is
generic
(width : integer := 32); -- default size
port
-- INPUTS
-- Signals from the clk_rst_manager
(clk_i : in std_logic;
rst_i : in std_logic;
-- Signals from any unit
counter_en_i : in std_logic; -- enables counting
counter_top_i : in std_logic_vector(width-1 downto 0); -- start value;
-- when zero is reached counter reloads
-- start value and restarts counting
-- OUTPUTS
-- Signals to any unit
counter_o : out std_logic_vector(width-1 downto 0);
counter_is_zero_o : out std_logic); -- empty counter indication
end free_counter;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of free_counter is
constant zeroes : unsigned(width-1 downto 0):=(others=>'0');
signal counter : unsigned(width-1 downto 0):=(others=>'0'); -- init to avoid sim warnings
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
decr_counting: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i = '1' then
counter_is_zero_o <= '0';
counter <= unsigned(counter_top_i) - "1";
elsif counter = zeroes then
counter_is_zero_o <= '0';
counter <= unsigned(counter_top_i) - "1";
elsif counter_en_i = '1' then
if counter = zeroes + "1" then
counter_is_zero_o <= '1';
counter <= counter - "1";
else
counter_is_zero_o <= '0';
counter <= counter - "1";
end if;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
counter_o <= std_logic_vector(counter);
end architecture rtl;
--=================================================================================================
-- architecture end
--=================================================================================================
---------------------------------------------------------------------------------------------------
-- E N D O F F I L E
---------------------------------------------------------------------------------------------------
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- incr_counter |
-- |
---------------------------------------------------------------------------------------------------
-- File incr_counter.vhd |
-- |
-- Description Stop counter. Configurable "counter_top_i" and "width". |
-- "Current count value" and "counting done" signals available. |
-- "Counting done" signal asserted simultaneous to"current count value=counter_top_i"|
-- Needs a rst_i to restart. |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 04/2012 |
-- Version v0.11 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 05/2011 v0.1 GP First version |
-- 04/2012 v0.11 EG Revamping; Comments added, signals renamed |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
--=================================================================================================
-- Entity declaration for incr_counter
--=================================================================================================
entity incr_counter is
generic
(width : integer := 32); -- default size
port
-- INPUTS
-- Signals from the clk_rst_manager
(clk_i : in std_logic;
rst_i : in std_logic;
-- Signals from any unit
counter_top_i : in std_logic_vector(width-1 downto 0); -- max value to be counted; when reached
-- counter stays at it, until a reset
counter_incr_en_i : in std_logic; -- enables counting
-- OUTPUTS
-- Signals to any unit
counter_o : out std_logic_vector(width-1 downto 0);
counter_is_full_o : out std_logic); -- counter reahed counter_top_i value
end incr_counter;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of incr_counter is
constant zeroes : unsigned(width-1 downto 0) := (others=>'0');
signal counter : unsigned(width-1 downto 0) := (others=>'0'); -- init to avoid sim warnings
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
incr_counting: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i = '1' then
counter_is_full_o <= '0';
counter <= zeroes;
elsif counter = unsigned (counter_top_i) then
counter_is_full_o <= '1';
counter <= unsigned (counter_top_i);
elsif counter_incr_en_i ='1' then
if counter = unsigned(counter_top_i) - "1" then
counter_is_full_o <= '1';
counter <= counter + "1";
else
counter_is_full_o <= '0';
counter <= counter + "1";
end if;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
counter_o <= std_logic_vector(counter);
end architecture rtl;
--=================================================================================================
-- architecture end
--=================================================================================================
---------------------------------------------------------------------------------------------------
-- E N D O F F I L E
---------------------------------------------------------------------------------------------------
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- irq_generator |
-- |
---------------------------------------------------------------------------------------------------
-- File irq_generator.vhd |
-- |
-- Description Interrupts generator: the unit generates three interrups: |
-- |
-- o irq_tstamp_p_o is a 1-clk_i-long pulse generated when the amount of |
-- timestamps written in the circular_buffer, since the last interrupt or since |
-- the startup of the aquisition, exceeds the GN4124/VME settable threshold |
-- irq_tstamp_threshold. |
-- |
-- o irq_time_p_o is a 1-clk_i-long pulse generated when some timestamps have been |
-- written in the circular_buffer (>=1 timestamp) and the amount of time passed |
-- since the last interrupt or since the aquisition startup, exceeds the |
-- GN4124/VME settable threshold irq_time_threshold. The threshold is in ms. |
-- |
-- o irq_acam_err_p_o is a 1-clk_i-long pulse generated when the ACAM Hit FIFOS are|
-- full (according to ACAM configuration register 11) |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 08/2013 |
-- Version v1 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 05/2012 v0.1 EG First version |
-- 04/2013 v0.2 EG line 170 added "irq_time_threshold_i > 0"; if the user doesn t want the |
-- time interrupts he sets the irq_time_threshold reg to zero; same goes |
-- for number-of-tstamps interrupts, users sets to zero to disable them |
-- 08/2013 v1 EG time irq concept in milliseconds rather than seconds |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions-- Specific library
-- Specific library
library work;
use work.tdc_core_pkg.all; -- definitions of types, constants, entities
--=================================================================================================
-- Entity declaration for irq_generator
--=================================================================================================
entity irq_generator is
generic
(g_width : integer := 32);
port
-- INPUTS
-- Signal from the clks_rsts_manager
(clk_i : in std_logic; -- 125 MHz clk
rst_i : in std_logic; -- global reset
irq_tstamp_threshold_i : in std_logic_vector(g_width-1 downto 0); -- GN4124/VME settable threshold
irq_time_threshold_i : in std_logic_vector(g_width-1 downto 0); -- GN4124/VME settable threshold
-- Signal from the acam_timecontrol_interface
acam_errflag_r_edge_p_i : in std_logic; -- ACAM ErrFlag rising edge; through the ACAM config reg 11
-- the ERRflag is configured to follow the full flags of the
-- Hit FIFOs; this would translate to data loss
-- Signal from the reg_ctrl unit
activate_acq_p_i : in std_logic; -- activates tstamps aquisition from ACAM
deactivate_acq_p_i : in std_logic; -- deactivates tstamps aquisition
-- Signals from the data_formatting unit
tstamp_wr_p_i : in std_logic; -- pulse upon storage of a new timestamp
-- OUTPUTS
-- Signals to the wb_irq_controller
irq_tstamp_p_o : out std_logic; -- active if amount of tstamps > tstamps_threshold
irq_time_p_o : out std_logic; -- active if amount of tstamps < tstamps_threshold but time > time_threshold
irq_acam_err_p_o : out std_logic); -- active if ACAM err_flag_i is active
end irq_generator;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of irq_generator is
constant ZERO : std_logic_vector (8 downto 0):= "000000000";
type t_irq_st is (IDLE, TSTAMP_AND_TIME_COUNTING, RAISE_IRQ_TSTAMP, RAISE_IRQ_TIME);
signal irq_st, nxt_irq_st : t_irq_st;
signal tstamps_c_rst, time_c_rst : std_logic;
signal tstamps_c_en, time_c_en : std_logic;
signal tstamps_c_incr_en, time_c_incr_en : std_logic;
signal tstamps_c : std_logic_vector(8 downto 0);
signal time_c : std_logic_vector(g_width-1 downto 0);
signal one_ms_passed_p : std_logic;
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
---------------------------------------------------------------------------------------------------
-- INTERRUPTS GENERATOR FSM --
---------------------------------------------------------------------------------------------------
IRQ_generator_seq: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' then
irq_st <= IDLE;
else
irq_st <= nxt_irq_st;
end if;
end if;
end process;
---------------------------------------------------------------------------------------------------
IRQ_generator_comb: process (irq_st, activate_acq_p_i, deactivate_acq_p_i, tstamps_c,
irq_tstamp_threshold_i, irq_time_threshold_i, time_c)
begin
case irq_st is
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when IDLE =>
-----------------------------------------------
irq_tstamp_p_o <= '0';
irq_time_p_o <= '0';
tstamps_c_rst <= '1';
time_c_rst <= '1';
tstamps_c_en <= '0';
time_c_en <= '0';
-----------------------------------------------
if activate_acq_p_i = '1' then
nxt_irq_st <= TSTAMP_AND_TIME_COUNTING;
else
nxt_irq_st <= IDLE;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when TSTAMP_AND_TIME_COUNTING =>
-----------------------------------------------
irq_tstamp_p_o <= '0';
irq_time_p_o <= '0';
tstamps_c_rst <= '0';
time_c_rst <= '0';
tstamps_c_en <= '1';
time_c_en <= '1';
-----------------------------------------------
if deactivate_acq_p_i = '1' then
nxt_irq_st <= IDLE;
elsif tstamps_c > ZERO and tstamps_c >= irq_tstamp_threshold_i(8 downto 0) then -- not >= ZERO!!
nxt_irq_st <= RAISE_IRQ_TSTAMP;
elsif unsigned(irq_time_threshold_i) > 0 and time_c >= irq_time_threshold_i and tstamps_c > ZERO then
nxt_irq_st <= RAISE_IRQ_TIME;
else
nxt_irq_st <= TSTAMP_AND_TIME_COUNTING;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when RAISE_IRQ_TSTAMP =>
-----------------------------------------------
irq_tstamp_p_o <= '1';
irq_time_p_o <= '0';
tstamps_c_rst <= '1';
time_c_rst <= '1';
tstamps_c_en <= '0';
time_c_en <= '0';
-----------------------------------------------
if deactivate_acq_p_i = '1' then
nxt_irq_st <= IDLE;
else
nxt_irq_st <= TSTAMP_AND_TIME_COUNTING;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when RAISE_IRQ_TIME =>
-----------------------------------------------
irq_tstamp_p_o <= '0';
irq_time_p_o <= '1';
tstamps_c_rst <= '1';
time_c_rst <= '1';
tstamps_c_en <= '0';
time_c_en <= '0';
-----------------------------------------------
if deactivate_acq_p_i = '1' then
nxt_irq_st <= IDLE;
else
nxt_irq_st <= TSTAMP_AND_TIME_COUNTING;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when others =>
-----------------------------------------------
irq_tstamp_p_o <= '0';
irq_time_p_o <= '0';
tstamps_c_rst <= '1';
time_c_rst <= '1';
tstamps_c_en <= '0';
time_c_en <= '0';
-----------------------------------------------
nxt_irq_st <= IDLE;
end case;
end process;
---------------------------------------------------------------------------------------------------
-- TIMESTAMPS COUNTER --
---------------------------------------------------------------------------------------------------
-- Incremental counter counting the amount of timestamps written since the last interrupt or the
-- last reset. The counter counts up to 255.
tstamps_counter: incr_counter
generic map
(width => 9)--(c_CIRCULAR_BUFF_SIZE'length)) -- 9 digits, counting up to 255
port map
(clk_i => clk_i,
rst_i => tstamps_c_rst,
counter_top_i => "100000000",
counter_incr_en_i => tstamps_c_incr_en,
counter_is_full_o => open,
-------------------------------------------
counter_o => tstamps_c);
-------------------------------------------
tstamps_c_incr_en <= tstamps_c_en and tstamp_wr_p_i;
---------------------------------------------------------------------------------------------------
-- TIME COUNTER --
---------------------------------------------------------------------------------------------------
-- Incremental counter counting the time in milliseconds since the last interrupt or the last reset.
time_counter: incr_counter
generic map
(width => g_width)
port map
(clk_i => clk_i,
rst_i => time_c_rst,
counter_top_i => x"FFFFFFFF",
counter_incr_en_i => time_c_incr_en,
counter_is_full_o => open,
-------------------------------------------
counter_o => time_c);
-------------------------------------------
time_c_incr_en <= time_c_en and one_ms_passed_p;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
millisec_counter: free_counter
generic map
(width => g_width)
port map
(clk_i => clk_i,
rst_i => rst_i,
counter_en_i => '1',
counter_top_i => x"0001E848", -- 125'000 clk_i cycles = 1 ms
-------------------------------------------
counter_is_zero_o => one_ms_passed_p,
counter_o => open);
-------------------------------------------
---------------------------------------------------------------------------------------------------
-- ACAM ErrFlag IRQ --
---------------------------------------------------------------------------------------------------
irq_acam_err_p_o <= acam_errflag_r_edge_p_i;
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
\ No newline at end of file
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- leds_manager |
-- |
---------------------------------------------------------------------------------------------------
-- File leds_manager.vhd |
-- |
-- Description Generation of the signals that drive the LEDs on the TDC mezzanine. |
-- There are 6 LEDs on the front panel of the TDC mezzanine board: |
-- ______ |
-- | | |
-- | O O | 1, 2 |
-- | O O | 3, 4 |
-- | O O | 5, 6 |
-- |______| |
-- |
-- TDC LED 1 orange: division of the 125 MHz clock; one hz pulses |
-- TDC LED 2 orange: Channel 1 termination enable |
-- TDC LED 3 orange: Channel 2 termination enable |
-- TDC LED 4 orange: Channel 3 termination enable |
-- TDC LED 5 orange: Channel 4 termination enable |
-- TDC LED 6 orange: Channel 5 termination enable |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Date 05/2012 |
-- Version v0.1 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 05/2012 v0.1 EG First version |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
-- Specific libraries
library work;
use work.tdc_core_pkg.all; -- definitions of types, constants, entities
use work.gencores_pkg.all;
--=================================================================================================
-- Entity declaration for leds_manager
--=================================================================================================
entity leds_manager is
generic
(g_width : integer := 32;
values_for_simul : boolean := FALSE);
port
-- INPUTS
-- Signals from the clks_rsts_manager
(clk_i : in std_logic; -- 125 MHz clock
rst_i : in std_logic; -- core internal reset, synched with 125 MHz clk
-- Signal from the one_hz_generator unit
utc_p_i : in std_logic;
-- Signal from the reg_ctrl unit
acam_inputs_en_i : in std_logic_vector(g_width-1 downto 0); -- enable for the ACAM channels;
-- activation comes through dedicated reg c_ACAM_INPUTS_EN_ADR
-- Signal for debugging
acam_channel_i : in std_logic_vector(5 downto 0); -- for debugging, currently not used
tstamp_wr_p_i : in std_logic;
-- OUTPUTS
-- Signals to the LEDs on the TDC front panel
tdc_led_status_o : out std_logic; -- TDC LED 1: division of 125 MHz
tdc_led_trig1_o : out std_logic; -- TDC LED 2: Channel 1 termination enable
tdc_led_trig2_o : out std_logic; -- TDC LED 3: Channel 2 termination enable
tdc_led_trig3_o : out std_logic; -- TDC LED 4: Channel 3 termination enable
tdc_led_trig4_o : out std_logic; -- TDC LED 5: Channel 4 termination enable
tdc_led_trig5_o : out std_logic); -- TDC LED 6: Channel 5 termination enable
end leds_manager;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of leds_manager is
signal tdc_led_blink_done : std_logic;
signal visible_blink_length : std_logic_vector(g_width-1 downto 0);
signal rst_n, blink_led1, blink_led2 : std_logic;
signal ch1, ch2, ch3, ch4, ch5 : std_logic;
signal blink_led3, blink_led4, blink_led5 : std_logic;
signal tstamp_wr_p, blink_led : std_logic;
signal acam_channel : std_logic_vector(5 downto 0);
begin
---------------------------------------------------------------------------------------------------
-- TDC FRONT PANEL LED 1 --
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
tdc_status_led_blink_counter: decr_counter
port map
(clk_i => clk_i,
rst_i => rst_i,
counter_load_i => utc_p_i,
counter_top_i => visible_blink_length,
counter_is_zero_o => tdc_led_blink_done,
counter_o => open);
---------------------------------------------------------------------------------------------------
tdc_status_led_gener: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' then
tdc_led_status_o <= '0';
elsif utc_p_i ='1' then
tdc_led_status_o <= '1';
elsif tdc_led_blink_done = '1' then
tdc_led_status_o <= '0';
end if;
end if;
end process;
visible_blink_length <= c_BLINK_LGTH_SIM when values_for_simul else c_BLINK_LGTH_SYN;
---------------------------------------------------------------------------------------------------
-- TDC FRONT PANEL LEDs 2-6 --
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
rst_n <= not(rst_i);
led_1to5_outputs: process (clk_i)
begin
if rising_edge (clk_i) then
tdc_led_trig1_o <= blink_led1; --acam_inputs_en_i(0) and blink_led1;
tdc_led_trig2_o <= blink_led2; --acam_inputs_en_i(1) and blink_led2;
tdc_led_trig3_o <= blink_led3; --acam_inputs_en_i(2) and blink_led3;
tdc_led_trig4_o <= blink_led4; --acam_inputs_en_i(3) and blink_led4;
tdc_led_trig5_o <= blink_led5; --acam_inputs_en_i(4) and blink_led5;
end if;
end process;
pulse_generator: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i = '1' then
acam_channel <= (others => '0');
tstamp_wr_p <= '0';
ch1 <= '0';
ch2 <= '0';
ch3 <= '0';
ch4 <= '0';
ch5 <= '0';
else
acam_channel <= acam_channel_i;
tstamp_wr_p <= tstamp_wr_p_i;
if tstamp_wr_p = '1' and acam_inputs_en_i(7) = '1' then
if acam_channel(2 downto 0) = "000" then
ch1 <= '1';
ch2 <= '0';
ch3 <= '0';
ch4 <= '0';
ch5 <= '0';
elsif acam_channel(2 downto 0) = "001" then
ch1 <= '0';
ch2 <= '1';
ch3 <= '0';
ch4 <= '0';
ch5 <= '0';
elsif acam_channel(2 downto 0) = "010" then
ch1 <= '0';
ch2 <= '0';
ch3 <= '1';
ch4 <= '0';
ch5 <= '0';
elsif acam_channel(2 downto 0) = "011" then
ch1 <= '0';
ch2 <= '0';
ch3 <= '0';
ch4 <= '1';
ch5 <= '0';
else
ch1 <= '0';
ch2 <= '0';
ch3 <= '0';
ch4 <= '0';
ch5 <= '1';
end if;
else
ch1 <= '0';
ch2 <= '0';
ch3 <= '0';
ch4 <= '0';
ch5 <= '0';
end if;
end if;
end if;
end process;
cmp_extend_ch1_pulse: gc_extend_pulse
generic map
(g_width => 5000000)
port map
(clk_i => clk_i,
rst_n_i => rst_n,
pulse_i => ch1,
extended_o => blink_led1);
cmp_extend_ch2_pulse: gc_extend_pulse
generic map
(g_width => 5000000)
port map
(clk_i => clk_i,
rst_n_i => rst_n,
pulse_i => ch2,
extended_o => blink_led2);
cmp_extend_ch3_pulse: gc_extend_pulse
generic map
(g_width => 5000000)
port map
(clk_i => clk_i,
rst_n_i => rst_n,
pulse_i => ch3,
extended_o => blink_led3);
cmp_extend_ch4_pulse: gc_extend_pulse
generic map
(g_width => 5000000)
port map
(clk_i => clk_i,
rst_n_i => rst_n,
pulse_i => ch4,
extended_o => blink_led4);
cmp_extend_ch5_pulse: gc_extend_pulse
generic map
(g_width => 5000000)
port map
(clk_i => clk_i,
rst_n_i => rst_n,
pulse_i => ch5,
extended_o => blink_led5);
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
\ No newline at end of file
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- local_pps_gen |
-- |
---------------------------------------------------------------------------------------------------
-- File local_pps_gen.vhd |
-- |
-- Description Generates one pulse every second synchronously with the ACAM reference clock. |
-- The phase with the reference clock can be adjusted (eva: think that is not needed)|
-- It also keeps track of the UTC time based on the local clock. |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 04/2012 |
-- Version v0.11 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 05/2011 v0.1 GP First version |
-- 04/2012 v0.11 EG Revamping; Comments added, signals renamed |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions-- Specific library
-- Specific library
library work;
use work.tdc_core_pkg.all; -- definitions of types, constants, entities
--=================================================================================================
-- Entity declaration for local_pps_gen
--=================================================================================================
entity local_pps_gen is
generic
(g_width : integer := 32);
port
-- INPUTS
-- Signals from the clk_rst_manager unit
(clk_i : in std_logic;
rst_i : in std_logic;
acam_refclk_r_edge_p_i : in std_logic;
clk_period_i : in std_logic_vector(g_width-1 downto 0); -- nb of clock periods for 1s
-- Signals from the reg_ctrl unit
load_utc_p_i : in std_logic; -- enables loading of the local UTC time with starting_utc_i value
starting_utc_i : in std_logic_vector(g_width-1 downto 0); -- value coming from the GN4124/VME
pulse_delay_i : in std_logic_vector(g_width-1 downto 0); -- nb of clock periods phase delay
-- with respect to reference clock
-- OUTPUTS
-- Signal to data_formatting and reg_ctrl units
local_utc_o : out std_logic_vector(g_width-1 downto 0); -- tstamp current second
-- Signal to start_retrig_ctrl unit
local_utc_p_o : out std_logic); -- pulse upon new second
end local_pps_gen;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of local_pps_gen is
constant constant_delay : unsigned(g_width-1 downto 0) := x"00000004";
signal local_utc : unsigned(g_width-1 downto 0);
signal one_hz_p_pre : std_logic;
signal one_hz_p_post : std_logic;
signal onesec_counter_en : std_logic;
signal total_delay : std_logic_vector(g_width-1 downto 0);
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
---------------------------------------------------------------------------------------------------
-- 1 sec counting --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- clk_periods_counter: generation of a 1 clk-long pulse every second.
-- The first pulse occurs one second after the startup of the acam_refclk
-- bits 27-31 not used.
clk_periods_counter: free_counter
generic map
(width => g_width)
port map
(clk_i => clk_i,
rst_i => rst_i,
counter_en_i => onesec_counter_en,
counter_top_i => clk_period_i,
-------------------------------------------
counter_is_zero_o => one_hz_p_pre,
counter_o => open);
-------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
clk_periods_counter_en_trigger: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' then
onesec_counter_en <= '0';
elsif acam_refclk_r_edge_p_i ='1' then
onesec_counter_en <= '1'; -- stays at 1 after the first acam_refclk pulse
end if;
end if;
end process;
---------------------------------------------------------------------------------------------------
-- Load UTC time --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- utc_counter: generation of a 1 clk-long pulse every second
utc_counter: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' then
local_utc <= (others => '0');
elsif load_utc_p_i = '1' then
local_utc <= unsigned(starting_utc_i); -- loading of local_utc with incoming starting_utc_i
elsif one_hz_p_post = '1' then -- new second counted; local_utc updated
local_utc <= local_utc + 1;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
local_utc_o <= std_logic_vector(local_utc);
---------------------------------------------------------------------------------------------------
-- Delays --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
pulse_delayer_counter: decr_counter -- delays the one_hz_p_pre pulse for total_delay clk_i ticks
generic map
(width => g_width)
port map
(clk_i => clk_i,
rst_i => rst_i,
counter_load_i => one_hz_p_pre,
counter_top_i => total_delay,
-------------------------------------------
counter_is_zero_o => one_hz_p_post,
counter_o => open);
-------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
total_delay <= std_logic_vector(unsigned(pulse_delay_i)+constant_delay);
local_utc_p_o <= one_hz_p_post;
end architecture rtl;
--=================================================================================================
-- architecture end
--=================================================================================================
---------------------------------------------------------------------------------------------------
-- E N D O F F I L E
---------------------------------------------------------------------------------------------------
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- reg_ctrl |
-- |
---------------------------------------------------------------------------------------------------
-- File reg_ctrl.vhd |
-- |
-- Description Interfaces with the GN4124/VME core for the configuration of the ACAM chip and of |
-- the TDC core. Data transfers take place between the GN4124/VME interface and |
-- locally the TDC core. The unit implements a WISHBONE slave. |
-- |
-- Through WISHBONE writes, the unit receives: |
-- o the ACAM configuration registers which are then made available to the |
-- data_engine and acam_databus_interface units to be transfered to the ACAM chip|
-- o the local configuration registers (eg irq_thresholds, channels_enable) that |
-- are then made available to the different units of this design |
-- o the control register that defines the action to be taken in the core; the |
-- register is decoded and the corresponding signals are made available to the |
-- different units in the design. |
-- |
-- Through WISHBONE reads, the unit transmits: |
-- o the ACAM configuration registers readback from the ACAM chip |
-- o status registers coming from different units of the TDC core |
-- |
-- All the registers are of size 32 bits, as the WISHBONE data bus |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 08/2012 |
-- Version v1 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 10/2011 v0.1 GP First version |
-- 04/2012 v0.11 EG Revamping; Comments added, signals renamed |
-- 08/2012 v1 EG added register reg_adr_pipe0 for slack timing reasons |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.std_logic_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
-- Specific library
library work;
use work.tdc_core_pkg.all; -- definitions of types, constants, entities
--=================================================================================================
-- Entity declaration for reg_ctrl
--=================================================================================================
entity reg_ctrl is
generic
(g_span : integer := 32;
g_width : integer := 32);
port
-- INPUTS
-- Signals from the clks_rsts_manager unit
(clk_i : in std_logic; -- 125 MHz
rst_i : in std_logic; -- global reset, synched to clk_i
-- Signals from the GN4124/VME_core unit: WISHBONE for regs transfer
tdc_config_wb_adr_i : in std_logic_vector(g_span-1 downto 0); -- WISHBONE address
tdc_config_wb_cyc_i : in std_logic; -- WISHBONE cycle
tdc_config_wb_dat_i : in std_logic_vector(g_width-1 downto 0); -- WISHBONE data in
tdc_config_wb_stb_i : in std_logic; -- WISHBONE strobe
tdc_config_wb_we_i : in std_logic; -- WISHBONE write enable
-- Signals from the data_engine unit: configuration regs read back from the ACAM
acam_config_rdbk_i : in config_vector; -- array keeping values read back from ACAM regs 0-7, 11, 12, 14
acam_ififo1_i : in std_logic_vector(g_width-1 downto 0); -- keeps value read back from ACAM reg 8; for debug reasons only
acam_ififo2_i : in std_logic_vector(g_width-1 downto 0); -- keeps value read back from ACAM reg 9; for debug reasons only
acam_start01_i : in std_logic_vector(g_width-1 downto 0); -- keeps value read back from ACAM reg 10; for debug reasons only
-- Signals from the data_formatting unit
wr_index_i : in std_logic_vector(g_width-1 downto 0); -- index of the last circular_buffer adr written
-- Signals from the one_hz_gen unit
local_utc_i : in std_logic_vector(g_width-1 downto 0); -- local utc time
-- Signals not used so far
core_status_i : in std_logic_vector(g_width-1 downto 0); -- TDC core status word
irq_code_i : in std_logic_vector(g_width-1 downto 0); -- TDC core interrupt code word
-- White Rabbit status
wrabbit_status_reg_i : in std_logic_vector(g_width-1 downto 0); --
-- OUTPUTS
-- Signals to the GN4124/VME_core unit: WISHBONE for regs transfer
tdc_config_wb_ack_o : out std_logic; -- WISHBONE acknowledge
tdc_config_wb_dat_o : out std_logic_vector(g_width-1 downto 0); -- WISHBONE data out
-- Signals to the data_engine unit: config regs for the ACAM
acam_config_o : out config_vector;
-- Signals to the data_engine unit: TDC core functionality
activate_acq_p_o : out std_logic; -- activates tstamps aquisition from ACAM
deactivate_acq_p_o : out std_logic; -- activates ACAM configuration readings/ writings
acam_wr_config_p_o : out std_logic; -- enables writing to ACAM regs 0-7, 11, 12, 14
acam_rdbk_config_p_o : out std_logic; -- enables reading of ACAM regs 0-7, 11, 12, 14
acam_rst_p_o : out std_logic; -- enables writing the c_RESET_WORD to ACAM reg 4
acam_rdbk_status_p_o : out std_logic; -- enables reading of ACAM reg 12
acam_rdbk_ififo1_p_o : out std_logic; -- enables reading of ACAM reg 8
acam_rdbk_ififo2_p_o : out std_logic; -- enables reading of ACAM reg 9
acam_rdbk_start01_p_o : out std_logic; -- enables reading of ACAM reg 10
-- Signal to the data_formatting unit
dacapo_c_rst_p_o : out std_logic; -- clears the dacapo counter
deactivate_chan_o : out std_logic_vector(4 downto 0); -- stops registering timestamps from a specific channel
-- Signals to the clks_resets_manager unit
send_dac_word_p_o : out std_logic; -- initiates the reconfiguration of the DAC
dac_word_o : out std_logic_vector(23 downto 0);
-- Signal to the one_hz_gen unit
load_utc_p_o : out std_logic;
starting_utc_o : out std_logic_vector(g_width-1 downto 0);
irq_tstamp_threshold_o: out std_logic_vector(g_width-1 downto 0); -- threshold in number of timestamps
irq_time_threshold_o : out std_logic_vector(g_width-1 downto 0); -- threshold in number of ms
one_hz_phase_o : out std_logic_vector(g_width-1 downto 0); -- for debug only
-- Signal to the TDC mezzanine board
acam_inputs_en_o : out std_logic_vector(g_width-1 downto 0); -- enables all five input channels
-- White Rabbit control
wrabbit_ctrl_reg_o : out std_logic_vector(g_width-1 downto 0); --
-- Signal to the acam_timecontrol_interface unit -- eva: i think it s not needed
start_phase_o : out std_logic_vector(g_width-1 downto 0));
end reg_ctrl;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of reg_ctrl is
signal acam_config : config_vector;
signal reg_adr,reg_adr_pipe0 : std_logic_vector(7 downto 0);
signal starting_utc, acam_inputs_en, start_phase : std_logic_vector(g_width-1 downto 0);
signal ctrl_reg, one_hz_phase, irq_tstamp_threshold : std_logic_vector(g_width-1 downto 0);
signal irq_time_threshold : std_logic_vector(g_width-1 downto 0);
signal clear_ctrl_reg, send_dac_word_p : std_logic;
signal dac_word : std_logic_vector(23 downto 0);
signal pulse_extender_en : std_logic;
signal pulse_extender_c : std_logic_vector(2 downto 0);
signal dat_out, wrabbit_ctrl_reg, deactivate_chan : std_logic_vector(g_span-1 downto 0);
signal tdc_config_wb_ack_o_pipe0 : std_logic;
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
reg_adr <= tdc_config_wb_adr_i(7 downto 0); -- we are interested in addresses 0:5000 to 0:50FC
---------------------------------------------------------------------------------------------------
-- WISHBONE ACK to GN4124/VME_core --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- TDCconfig_ack_generator: generation of the WISHBONE acknowledge signal for the
-- interactions with the GN4124/VME_core.
TDCconfig_ack_generator: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i = '1' then
tdc_config_wb_ack_o <= '0';
tdc_config_wb_ack_o_pipe0 <= '0';
elsif(tdc_config_wb_cyc_i = '0') then
tdc_config_wb_ack_o <= '0';
tdc_config_wb_ack_o_pipe0 <= '0';
else
tdc_config_wb_ack_o <= tdc_config_wb_ack_o_pipe0;
tdc_config_wb_ack_o_pipe0 <= tdc_config_wb_stb_i and tdc_config_wb_cyc_i;
end if;
end if;
end process;
---------------------------------------------------------------------------------------------------
-- Reception of ACAM Configuration Registers --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- ACAM_config_reg_reception: reception from the GN4124/VME interface of the configuration registers
-- to be loaded to the ACAM chip. The received data is stored in the acam_config vector which is
-- input to the data_engine and the acam_databus_interface units for the further transfer to the
-- ACAM chip.
ACAM_config_reg_reception: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i = '1' then
acam_config(0) <= (others =>'0');
acam_config(1) <= (others =>'0');
acam_config(2) <= (others =>'0');
acam_config(3) <= (others =>'0');
acam_config(4) <= (others =>'0');
acam_config(5) <= (others =>'0');
acam_config(6) <= (others =>'0');
acam_config(7) <= (others =>'0');
acam_config(8) <= (others =>'0');
acam_config(9) <= (others =>'0');
acam_config(10) <= (others =>'0');
elsif tdc_config_wb_cyc_i = '1' and tdc_config_wb_stb_i = '1' and tdc_config_wb_we_i = '1' then -- WISHBONE writes
if reg_adr = c_ACAM_REG0_ADR then
acam_config(0) <= tdc_config_wb_dat_i;
end if;
if reg_adr = c_ACAM_REG1_ADR then
acam_config(1) <= tdc_config_wb_dat_i;
end if;
if reg_adr = c_ACAM_REG2_ADR then
acam_config(2) <= tdc_config_wb_dat_i;
end if;
if reg_adr = c_ACAM_REG3_ADR then
acam_config(3) <= tdc_config_wb_dat_i;
end if;
if reg_adr = c_ACAM_REG4_ADR then
acam_config(4) <= tdc_config_wb_dat_i;
end if;
if reg_adr = c_ACAM_REG5_ADR then
acam_config(5) <= tdc_config_wb_dat_i;
end if;
if reg_adr = c_ACAM_REG6_ADR then
acam_config(6) <= tdc_config_wb_dat_i;
end if;
if reg_adr = c_ACAM_REG7_ADR then
acam_config(7) <= tdc_config_wb_dat_i;
end if;
if reg_adr = c_ACAM_REG11_ADR then
acam_config(8) <= tdc_config_wb_dat_i;
end if;
if reg_adr = c_ACAM_REG12_ADR then
acam_config(9) <= tdc_config_wb_dat_i;
end if;
if reg_adr = c_ACAM_REG14_ADR then
acam_config(10) <= tdc_config_wb_dat_i;
end if;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- --
acam_config_o <= acam_config;
---------------------------------------------------------------------------------------------------
-- Reception of TDC core Configuration Registers --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- TDCcore_config_reg_reception: reception from the GN4124/VME interface of the configuration
-- registers to be loaded locally.
-- The following information is received:
-- o acam_inputs_en : for the activation of the TDC input channels
-- o irq_tstamp_threshold : for the activation of GN4124/VME interrupts based on the number of timestamps
-- o irq_time_threshold : for the activation of GN4124/VME interrupts based on the time elapsed
-- o starting_utc : definition of the current UTC time
-- o starting_utc : definition of the current UTC time
-- o one_hz_phase : eva: think it s not used
-- o start_phase : eva: think it s not used
TDCcore_config_reg_reception: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' then
acam_inputs_en <= (others =>'0');
starting_utc <= (others =>'0');
start_phase <= (others =>'0');
one_hz_phase <= (others =>'0');
irq_tstamp_threshold <= x"00000100"; -- default 256 timestamps: full memory
irq_time_threshold <= x"000000C8"; -- default 200 ms
dac_word <= c_DEFAULT_DAC_WORD; -- default DAC Vout = 1.65
elsif tdc_config_wb_cyc_i = '1' and tdc_config_wb_stb_i = '1' and tdc_config_wb_we_i = '1' then -- WISHBONE writes
if reg_adr = c_STARTING_UTC_ADR then
starting_utc <= tdc_config_wb_dat_i;
end if;
if reg_adr = c_ACAM_INPUTS_EN_ADR then
acam_inputs_en <= tdc_config_wb_dat_i;
end if;
if reg_adr = c_START_PHASE_ADR then
start_phase <= tdc_config_wb_dat_i;
end if;
if reg_adr = c_ONE_HZ_PHASE_ADR then
one_hz_phase <= tdc_config_wb_dat_i;
end if;
if reg_adr = c_IRQ_TSTAMP_THRESH_ADR then
irq_tstamp_threshold <= tdc_config_wb_dat_i;
end if;
if reg_adr = c_IRQ_TIME_THRESH_ADR then
irq_time_threshold <= tdc_config_wb_dat_i;
end if;
if reg_adr = c_DAC_WORD_ADR then
dac_word <= tdc_config_wb_dat_i(23 downto 0);
end if;
if reg_adr = c_WRABBIT_CTRL_ADR then
wrabbit_ctrl_reg <= tdc_config_wb_dat_i;
end if;
if reg_adr = c_DEACT_CHAN_ADR then
deactivate_chan <= tdc_config_wb_dat_i;
end if;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- --
starting_utc_o <= starting_utc;
acam_inputs_en_o <= acam_inputs_en;
start_phase_o <= start_phase;
one_hz_phase_o <= one_hz_phase;
irq_tstamp_threshold_o <= irq_tstamp_threshold;
irq_time_threshold_o <= irq_time_threshold;
dac_word_o <= dac_word;
wrabbit_ctrl_reg_o <= wrabbit_ctrl_reg;
deactivate_chan_o <= deactivate_chan(4 downto 0);
---------------------------------------------------------------------------------------------------
-- Reception of TDC core Control Register --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- TDCcore_ctrl_reg_reception: reception from the GN4124/VME interface of the control register that
-- defines the action to be taken by the TDC core.
-- Note that only one bit of the register should be written at a time. The process receives
-- the register, defines the action to be taken and after 1 clk cycle clears the register.
TDCcore_ctrl_reg_reception: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i = '1' then
ctrl_reg <= (others =>'0');
clear_ctrl_reg <= '0';
elsif clear_ctrl_reg = '1' then
ctrl_reg <= (others =>'0');
clear_ctrl_reg <= '0';
elsif tdc_config_wb_cyc_i = '1' and tdc_config_wb_stb_i = '1' and tdc_config_wb_we_i = '1' then -- WISHBONE writes
if reg_adr = c_CTRL_REG_ADR then
ctrl_reg <= tdc_config_wb_dat_i;
clear_ctrl_reg <= '1';
end if;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- --
activate_acq_p_o <= ctrl_reg(0);
deactivate_acq_p_o <= ctrl_reg(1);
acam_wr_config_p_o <= ctrl_reg(2);
acam_rdbk_config_p_o <= ctrl_reg(3);
acam_rdbk_status_p_o <= ctrl_reg(4);
acam_rdbk_ififo1_p_o <= ctrl_reg(5);
acam_rdbk_ififo2_p_o <= ctrl_reg(6);
acam_rdbk_start01_p_o <= ctrl_reg(7);
acam_rst_p_o <= ctrl_reg(8);
load_utc_p_o <= ctrl_reg(9);
dacapo_c_rst_p_o <= ctrl_reg(10) or ctrl_reg(1); -- dacapo register reset when the acquisition is deactivated
send_dac_word_p <= ctrl_reg(11);
-- ctrl_reg bits 12 to 31 not used for the moment!
-- -- -- -- -- -- -- -- -- -- -- --
-- Pulse_stretcher: Increases the width of the send_dac_word_p pulse so that it can be sampled
-- by the 20 MHz clock of the clks_rsts_manager that is communicating with the DAC.
Pulse_stretcher: incr_counter
generic map
(width => 3)
port map
(clk_i => clk_i,
rst_i => send_dac_word_p,
counter_top_i => "111",
counter_incr_en_i => pulse_extender_en,
counter_is_full_o => open,
counter_o => pulse_extender_c);
-- -- -- -- -- -- -- -- -- -- -- --
pulse_extender_en <= '1' when pulse_extender_c < "111" else '0';
send_dac_word_p_o <= pulse_extender_en;
---------------------------------------------------------------------------------------------------
-- Delivery of ACAM and TDC core Readback Registers --
---------------------------------------------------------------------------------------------------
-- TDCcore_ctrl_reg_reception: Delivery to the GN4124/VME interface of all the readable registers,
-- including those of the ACAM and the TDC core.
-- Note: pipelining of the address for timing/slack reasons
WISHBONEreads: process (clk_i)
begin
if rising_edge (clk_i) then
--if tdc_config_wb_cyc_i = '1' and tdc_config_wb_stb_i = '1' and tdc_config_wb_we_i = '0' then -- WISHBONE reads
-- tdc_config_wb_dat_o <= dat_out;
reg_adr_pipe0 <= reg_adr;
tdc_config_wb_dat_o <= dat_out;
--end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
with reg_adr_pipe0 select dat_out <=
-- regs written by the GN4124/VME interface
acam_config(0) when c_ACAM_REG0_ADR,
acam_config(1) when c_ACAM_REG1_ADR,
acam_config(2) when c_ACAM_REG2_ADR,
acam_config(3) when c_ACAM_REG3_ADR,
acam_config(4) when c_ACAM_REG4_ADR,
acam_config(5) when c_ACAM_REG5_ADR,
acam_config(6) when c_ACAM_REG6_ADR,
acam_config(7) when c_ACAM_REG7_ADR,
acam_config(8) when c_ACAM_REG11_ADR,
acam_config(9) when c_ACAM_REG12_ADR,
acam_config(10) when c_ACAM_REG14_ADR,
-- regs read from the ACAM
acam_config_rdbk_i(0) when c_ACAM_REG0_RDBK_ADR,
acam_config_rdbk_i(1) when c_ACAM_REG1_RDBK_ADR,
acam_config_rdbk_i(2) when c_ACAM_REG2_RDBK_ADR,
acam_config_rdbk_i(3) when c_ACAM_REG3_RDBK_ADR,
acam_config_rdbk_i(4) when c_ACAM_REG4_RDBK_ADR,
acam_config_rdbk_i(5) when c_ACAM_REG5_RDBK_ADR,
acam_config_rdbk_i(6) when c_ACAM_REG6_RDBK_ADR,
acam_config_rdbk_i(7) when c_ACAM_REG7_RDBK_ADR,
acam_ififo1_i when c_ACAM_REG8_RDBK_ADR,
acam_ififo2_i when c_ACAM_REG9_RDBK_ADR,
acam_start01_i when c_ACAM_REG10_RDBK_ADR,
acam_config_rdbk_i(8) when c_ACAM_REG11_RDBK_ADR,
acam_config_rdbk_i(9) when c_ACAM_REG12_RDBK_ADR,
acam_config_rdbk_i(10) when c_ACAM_REG14_RDBK_ADR,
-- regs written by the GN4124/VME interface
starting_utc when c_STARTING_UTC_ADR,
acam_inputs_en when c_ACAM_INPUTS_EN_ADR,
start_phase when c_START_PHASE_ADR,
one_hz_phase when c_ONE_HZ_PHASE_ADR,
irq_tstamp_threshold when c_IRQ_TSTAMP_THRESH_ADR,
irq_time_threshold when c_IRQ_TIME_THRESH_ADR,
x"00" & dac_word when c_DAC_WORD_ADR,
-- regs written locally by the TDC core units
local_utc_i when c_LOCAL_UTC_ADR,
irq_code_i when c_IRQ_CODE_ADR,
wr_index_i when c_WR_INDEX_ADR,
core_status_i when c_CORE_STATUS_ADR,
-- White Rabbit regs
wrabbit_status_reg_i when c_WRABBIT_STATUS_ADR,
wrabbit_ctrl_reg when c_WRABBIT_CTRL_ADR,
deactivate_chan when c_DEACT_CHAN_ADR,
-- others
x"C0FFEEEE" when others;
end architecture rtl;
--=================================================================================================
-- architecture end
--=================================================================================================
---------------------------------------------------------------------------------------------------
-- E N D O F F I L E
---------------------------------------------------------------------------------------------------
\ No newline at end of file
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- start_retrig_ctrl |
-- |
---------------------------------------------------------------------------------------------------
-- File start_retrig_ctrl.vhd |
-- |
-- Description The unit provides the main components for the calculation of the "Coarse time" of |
-- the final timestamps. These components are sent to the data_formatting unit where |
-- the actual Coarse time calculation takes place. |
-- |
-- As a reminder, the final timestamp is a 128-bits word divided in four 32-bits |
-- words with the following structure: |
-- |
-- [127:96] Timestamp Metadata (ex. Channel, Slope) |
-- |
-- [95:64] Local UTC time from the one_hz_generator; each bit represents 1 s |
-- |
-- [63:32] Coarse time within the current second; each bit represents 8 ns |
-- |
-- [31:0] Fine time to be added to the Coarse time: provided directly by ACAM; |
-- each bit represents 81.03 ps |
-- |
-- In I-Mode the ACAM chip provides unlimited measuring range with internal start |
-- retriggers. ACAM is programmed to retrigger every (16*acam_clk_period) = |
-- (64*clk_i_period) = 512 ns; the StartTimer in ACAM Reg 4 is set to 15. It counts |
-- the number of retriggers after a Start pulse and upon the arrival of a Stop pulse |
-- and it sends this number in the "Start#" field of the timestamp. |
-- Unfortunately ACAM's counter of the retriggers has only 8 bits and can count up |
-- to 256 retriggers. Within one second (our UTC time) there can be up to |
-- 1,953,125 retriggers, which is >> 256 and actually corresponds to 7629 overflows |
-- of the ACAM counter. Therefore there is the need to follow ACAM and keep track of |
-- the overflows. The ACAM Interrupt flag (IrFlag pin 59) has been set to follow the |
-- highest bit of the Start# (through the ACAM Reg 12 bit 26) and like this we |
-- manage to count retriggers synchronously to ACAM itself. |
-- For simplification, in the following figure we assume that two Stop signals arrive|
-- after less than 256 ACAM internal retriggers. Therefore in the timestamps that |
-- ACAM will give the Start# field will represent the exact amount of retriggers |
-- after the Start pulse. |
-- Note that the interval between this external Start pulse and the first internal |
-- retrigger may vary; it is measured by the ACAM chip and stored as Start01 in ACAM |
-- Reg 10. Moreover, there is the StartOff1 offset added to each Hit time by ACAM |
-- (this does not appear in this figure) made available in ACAM Reg 5. |
-- However, in this TDC core application we are only interested in time differences |
-- between Stop pulses (ex. Stop2 - Stop1) and not in the precise arrival time of a |
-- Stop pulse. Since now both Start01 and StartOff1 are stable numbers affecting |
-- equally all the Stop pulses, they would disappear during the subtraction (which |
-- takes place at the software side) and therefore thay are used in our calculations.|
-- |
-- Start ____|-|__________________________________________________________________________ |
-- Retriggers ________________|-|________________|-|________________|-|________________|-|_____ |
-- Stop1 _________________________________________________|-|_____________________________ |
-- Hit1 <-------------> |
-- Stop2 _____________________________________________________________________________|-|_ |
-- Hit2 <--> |
-- Start01 <----------> |
-- |
-- Coming back now to our timestamp format {UTC second, Coarse time, Fine time}, we |
-- have to somehow assosiate ACAM retriggers to the UTC time. Actually, ACAM has no |
-- knowledge of the UTC time and the arrival of a new second happens completely |
-- independently. As the following figure shows the final timestamp of a Stop pulse |
-- is defined by the current UTC time plus the amount of time between that UTC and |
-- the Stop pulse: (2)+(3). Part (3) is provided exclusively by the ACAM chip in the |
-- Start# and Hit time fields of the timestamp. The sum of (1)+(2) is multiples of |
-- 256 ACAM retriggers and can be defined by following the ACAM output IrFlag. |
-- Now Part (1), is the one that associates the arrival of a UTC second with the ACAM|
-- time counting and is defined in this unit by following the ACAM retriggers. |
-- |
-- IrFlag ______________|--------------|______________|-------------|... _____________|--- |
-- ___________________________ ___________________________ _____________ |
-- new UTC sec| _|-|_ || | | |
-- Stop1 | || | ... | _|-|_ |
-- |___________________________||___________________________| |______________ |
-- (1) |
-- |----------------| |
-- (2) |
-- |---------------------------------------------| |
-- (3) |
-- |-------| |
-- |
-- To conclude, the final Coarse time is: (Part(2) + Part(3)_Start#)*Retrigger period|
-- and the Fine time is : Part(3)_Hit |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 04/2012 |
-- Version v0.11 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 07/2011 v0.1 GP First version |
-- 04/2012 v0.11 EG Revamping; Comments added, signals renamed |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions-- Specific library
-- Specific library
library work;
use work.tdc_core_pkg.all; -- definitions of types, constants, entities
--=================================================================================================
-- Entity declaration for start_retrig_ctrl
--=================================================================================================
entity start_retrig_ctrl is
generic
(g_width : integer := 32);
port
-- INPUTS
-- Signal from the clk_rst_manager
(clk_i : in std_logic;
rst_i : in std_logic;
-- Signal from the acam_timecontrol_interface
acam_intflag_f_edge_p_i : in std_logic;
-- Signal from the one_hz_generator unit
utc_p_i : in std_logic;
-- OUTPUTS
-- Signals to the data_formatting unit
current_retrig_nb_o : out std_logic_vector(g_width-1 downto 0);
roll_over_incr_recent_o : out std_logic;
clk_i_cycles_offset_o : out std_logic_vector(g_width-1 downto 0);
roll_over_nb_o : out std_logic_vector(g_width-1 downto 0);
retrig_nb_offset_o : out std_logic_vector(g_width-1 downto 0));
end start_retrig_ctrl;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of start_retrig_ctrl is
signal clk_i_cycles_offset : std_logic_vector(g_width-1 downto 0);
signal current_cycles : std_logic_vector(g_width-1 downto 0);
signal current_retrig_nb : std_logic_vector(g_width-1 downto 0);
signal retrig_nb_offset : std_logic_vector(g_width-1 downto 0);
signal retrig_p : std_logic;
signal roll_over_c : std_logic_vector(g_width-1 downto 0);
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
-- retrigger # : 0 1 127 128 255 256 257 383 384 385 511 512 513
-- retriggers : _|____|____...____|____|____...____|____|____|____...___|____|____|____...____|____|____|___
-- IrFlag : __________________|---------------------|____________________|---------------------|________
-- IrFlag_f_edge_p : ______________________________________|-|________________________________________|-|________
-- retrig_p : |-|__|-|__ ... __|-|__|-|__ ... __|-|__|-|__|-|__ ...__|-|__|-|__|-|___ ...__|-|__|-|__|-|___
-- current_retrig_nb: 0 1 127 128 255 0 1 127 128 129 255 0 1
-- utc_p_i : _____________________|-|_______________________________________________________________
-- roll_over_c : 0 1 2
-- retrig_nb_offset : 127
-- clk_i_cycles_offs: |..| (counts clk_i cycles from the pulse to the end of this retrigger)
--
-- At the moment that a new second arrives through the utc_p_i, we:
-- o keep note of the current_retrig_nb, 127 in this case (stored in retrig_nb_offset)
-- o keep note of the current_cycles, that is the number of clk_i cycles between the utc_p_i
-- and the next (128th) retrigger (stored in clk_i_cycles_offset)
-- o reinitialize the roll_over_c counter which starts counting rollovers of the current_retrig_nb
--
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- In this more macroscopic example we have included a Stop pulse arriving to the ACAM chip.
-- Each one of the n boxes represents 256 ACAM internal retriggers, which through the IrFlag are
-- synchronous with the counters in this unit. The coarse time is the amount of clk_i cycles
-- between the utc_p_i pulse and the ACAM Stop pulse. To the coarse time we then have to add the
-- fine time, which is the very precise 81ps resolution time measured by the ACAM. Note that the
-- ACAM can only provide timing information within the last box: the Start# (bits 25:18) indicates
-- the amount of internal retriggers and the Hit (bits 16:0) indicates the fine timing. The time
-- difference between the utc_p_i pulse and the last box is calculated through the counters of
-- this unit: roll_over_c, retrig_nb_offset, clk_i_cycles_offset.
-- Note that since the counting in the roll_over_c starts from 0, we do not need to subtract 1
-- so as not to consider the last, n-th, box. Similarly, for the retrig_nb_offset and ACAM Start#,
-- to calculate the amount of complete retriggers that have preceded the arrival of the
-- utc_p_i and the Stop pulse respectively, we would have to subtract 1, but since counting
-- starts from zero, we don't.
-- Finally, note that the the current_cycles counter is a decreasing counter giving the amount of
-- clk_i cycles between the resing edge of the one_hz_pulse_i and the next retrigger.
-- Note that in this project we are only interested in time differences between
-- _______________________________________ _________________________________________ ____________________
-- utc_p_i | _|-|_ || | |
-- ACAM Stop pulse | || | | _|-|_
-- | || | ... |
-- roll_over_c | 0 ||1 | |n-1
-- |_______________________________________||_________________________________________| |____________________
-- (1)
-- |----------------------------|
-- (2)
-- |-----------------------------------------------------------|
-- (3)
-- |--------|
-- (1): ((retrig_nb_offset + 1) * retrig_period) - (clk_i_cycles_offset)
-- (2): (roll_over_c * 256 * retrig_period) - (the amount that (1) represents)
-- (3): from ACAM tstamps: (Start# * retrig_period) + (Fine time: Hit)
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- These two counters keep a track of the current internal start retrigger
-- of the ACAM in parallel with the ACAM itself. Counting up to c_ACAM_RETRIG_PERIOD = 64
retrig_period_counter: free_counter -- retrigger periods
generic map
(width => g_width)
port map
(clk_i => clk_i,
rst_i => acam_intflag_f_edge_p_i,
counter_en_i => '1',
counter_top_i => c_ACAM_RETRIG_PERIOD,
-------------------------------------------
counter_is_zero_o => retrig_p,
counter_o => current_cycles);
-------------------------------------------
retrig_nb_counter: incr_counter -- number of retriggers counting from 0 to 255 and restarting
generic map -- through the acam_intflag_f_edge_p_i
(width => g_width)
port map
(clk_i => clk_i,
rst_i => acam_intflag_f_edge_p_i,
counter_top_i => x"00000100",
counter_incr_en_i => retrig_p,
counter_is_full_o => open,
-------------------------------------------
counter_o => current_retrig_nb);
-------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- This counter keeps track of the number of overflows of the ACAM counter within one second
roll_over_counter: incr_counter
generic map
(width => g_width)
port map
(clk_i => clk_i,
rst_i => utc_p_i,
counter_top_i => x"FFFFFFFF",
counter_incr_en_i => acam_intflag_f_edge_p_i,
counter_is_full_o => open,
counter_o => roll_over_c);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- When a new second starts, all values are captured and stored as offsets.
-- when a timestamp arrives, these offsets will be subtracted in order
-- to base the final timestamp with respect to the current second.
capture_offset: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' then
clk_i_cycles_offset <= (others=>'0');
retrig_nb_offset <= (others=>'0');
elsif utc_p_i = '1' then
clk_i_cycles_offset <= current_cycles;
retrig_nb_offset <= current_retrig_nb;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- outputs
roll_over_incr_recent_o <= '1' when unsigned(current_retrig_nb) < 64 else '0';
clk_i_cycles_offset_o <= clk_i_cycles_offset;
retrig_nb_offset_o <= retrig_nb_offset;
roll_over_nb_o <= roll_over_c;
current_retrig_nb_o <= current_retrig_nb; ----------------
end architecture rtl;
--=================================================================================================
-- architecture end
--=================================================================================================
---------------------------------------------------------------------------------------------------
-- E N D O F F I L E
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for TDC EIC
---------------------------------------------------------------------------------------
-- File : output.vhd
-- Author : auto-generated by wbgen2 from tdc_eic.wb
-- Created : 01/21/14 15:13:26
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE tdc_eic.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wbgen2_pkg.all;
entity tdc_eic is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(1 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
wb_int_o : out std_logic;
irq_tdc_tstamps_i : in std_logic;
irq_tdc_time_i : in std_logic;
irq_tdc_acam_err_i : in std_logic
);
end tdc_eic;
architecture syn of tdc_eic is
signal eic_idr_int : std_logic_vector(2 downto 0);
signal eic_idr_write_int : std_logic ;
signal eic_ier_int : std_logic_vector(2 downto 0);
signal eic_ier_write_int : std_logic ;
signal eic_imr_int : std_logic_vector(2 downto 0);
signal eic_isr_clear_int : std_logic_vector(2 downto 0);
signal eic_isr_status_int : std_logic_vector(2 downto 0);
signal eic_irq_ack_int : std_logic_vector(2 downto 0);
signal eic_isr_write_int : std_logic ;
signal irq_inputs_vector_int : std_logic_vector(2 downto 0);
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(1 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
wrdata_reg <= wb_dat_i;
bwsel_reg <= wb_sel_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
eic_idr_write_int <= '0';
eic_ier_write_int <= '0';
eic_isr_write_int <= '0';
elsif rising_edge(clk_sys_i) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
eic_idr_write_int <= '0';
eic_ier_write_int <= '0';
eic_isr_write_int <= '0';
ack_in_progress <= '0';
else
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(1 downto 0) is
when "00" =>
if (wb_we_i = '1') then
eic_idr_write_int <= '1';
end if;
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "01" =>
if (wb_we_i = '1') then
eic_ier_write_int <= '1';
end if;
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (wb_we_i = '1') then
end if;
rddata_reg(2 downto 0) <= eic_imr_int(2 downto 0);
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "11" =>
if (wb_we_i = '1') then
eic_isr_write_int <= '1';
end if;
rddata_reg(2 downto 0) <= eic_isr_status_int(2 downto 0);
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_dat_o <= rddata_reg;
-- extra code for reg/fifo/mem: Interrupt disable register
eic_idr_int(2 downto 0) <= wrdata_reg(2 downto 0);
-- extra code for reg/fifo/mem: Interrupt enable register
eic_ier_int(2 downto 0) <= wrdata_reg(2 downto 0);
-- extra code for reg/fifo/mem: Interrupt status register
eic_isr_clear_int(2 downto 0) <= wrdata_reg(2 downto 0);
-- extra code for reg/fifo/mem: IRQ_CONTROLLER
eic_irq_controller_inst : wbgen2_eic
generic map (
g_num_interrupts => 3,
g_irq00_mode => 0,
g_irq01_mode => 0,
g_irq02_mode => 0,
g_irq03_mode => 0,
g_irq04_mode => 0,
g_irq05_mode => 0,
g_irq06_mode => 0,
g_irq07_mode => 0,
g_irq08_mode => 0,
g_irq09_mode => 0,
g_irq0a_mode => 0,
g_irq0b_mode => 0,
g_irq0c_mode => 0,
g_irq0d_mode => 0,
g_irq0e_mode => 0,
g_irq0f_mode => 0,
g_irq10_mode => 0,
g_irq11_mode => 0,
g_irq12_mode => 0,
g_irq13_mode => 0,
g_irq14_mode => 0,
g_irq15_mode => 0,
g_irq16_mode => 0,
g_irq17_mode => 0,
g_irq18_mode => 0,
g_irq19_mode => 0,
g_irq1a_mode => 0,
g_irq1b_mode => 0,
g_irq1c_mode => 0,
g_irq1d_mode => 0,
g_irq1e_mode => 0,
g_irq1f_mode => 0
)
port map (
clk_i => clk_sys_i,
rst_n_i => rst_n_i,
irq_i => irq_inputs_vector_int,
irq_ack_o => eic_irq_ack_int,
reg_imr_o => eic_imr_int,
reg_ier_i => eic_ier_int,
reg_ier_wr_stb_i => eic_ier_write_int,
reg_idr_i => eic_idr_int,
reg_idr_wr_stb_i => eic_idr_write_int,
reg_isr_o => eic_isr_status_int,
reg_isr_i => eic_isr_clear_int,
reg_isr_wr_stb_i => eic_isr_write_int,
wb_irq_o => wb_int_o
);
irq_inputs_vector_int(0) <= irq_tdc_tstamps_i;
irq_inputs_vector_int(1) <= irq_tdc_time_i;
irq_inputs_vector_int(2) <= irq_tdc_acam_err_i;
rwaddr_reg <= wb_adr_i;
wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i);
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
-------------------------------------------------------------------------------
-- Title : Counter Sync signal generator
-- Project : Fine Delay FMC (fmc-delay-1ns-4cha)
-------------------------------------------------------------------------------
-- File : wrabbit_sync.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 2011-08-24
-- Last update: 2012-11-26
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Generates the internal time base used to synchronize the TDC
-- and programmable pulse generators to an internal or WR-provided timescale.
-- Also interfaces the FD core with an optional White Rabbit PTP core.
-------------------------------------------------------------------------------
--
-- Copyright (c) 2011 CERN / BE-CO-HT
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-08-24 1.0 twlostow Created
-- 2012-02-16 1.1 twlostow built-in WR sync FSM (untested)
-------------------------------------------------------------------------------
library ieee;
-- Standard library
library IEEE;
use IEEE.std_logic_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
-- Specific library
library work;
use work.tdc_core_pkg.all; -- definitions of types, constants, entities
use work.genram_pkg.all;
use work.gencores_pkg.all;
entity wrabbit_sync is
generic (
-- when true, reduces some timeouts to speed up simulations
g_simulation : boolean;
g_with_wrabbit_core : boolean);
port(
clk_sys_i : in std_logic;
rst_n_sys_i : in std_logic;
clk_ref_i : in std_logic;
rst_n_ref_i : in std_logic;
-------------------------------------------------------------------------------
-- White Rabbit Counter sync input
-------------------------------------------------------------------------------
wrabbit_dac_value_i : in std_logic_vector(23 downto 0);
wrabbit_dac_wr_p_i : in std_logic;
wrabbit_link_up_i : in std_logic;
-- when HI, wrabbit_utc_i and wrabbit_coarse_i contain a valid time value and
-- clk_ref_i is in-phase with the remote WR master
wrabbit_time_valid_i : in std_logic; -- this is i te clk_ref_0 domain, no??
-- 1: tells the WR core to lock the FMC's local oscillator to the WR
-- reference clock. 0: keep the oscillator free running.
wrabbit_clk_aux_lock_en_o : out std_logic;
-- 1: FMC's Local oscillator locked to WR reference
wrabbit_clk_aux_locked_i : in std_logic;
-- 1: Carrier's DMTD clock is locked (to WR reference or local FMC oscillator)
wrabbit_clk_dmtd_locked_i : in std_logic;
wrabbit_synched_o : out std_logic;
-- Wishbone regs
wrabbit_reg_i : in std_logic_vector(31 downto 0);
wrabbit_reg_o : out std_logic_vector(31 downto 0));
end wrabbit_sync;
architecture behavioral of wrabbit_sync is
-- System clock frequency in Hz
constant c_SYS_CLK_FREQ : integer := 125000000;
-- FSM timeout period calculation
impure function f_eval_timeout return integer is
begin
if(g_simulation) then
return 100;
else
return c_SYS_CLK_FREQ/1000; -- 1ms state timeout
end if;
end f_eval_timeout;
constant c_wrabbit_STATE_TIMEOUT : integer := f_eval_timeout;
-- FSM
type t_wrabbit_sync_state is (wrabbit_CORE_OFFLINE, wrabbit_WAIT_READY, wrabbit_SYNCING, wrabbit_SYNCED);
signal wrabbit_state : t_wrabbit_sync_state;
signal wrabbit_state_changed : std_logic;
signal csync_wrabbit_sysclk : std_logic;
signal wrabbit_state_syncing, wrabbit_en : std_logic;
signal wrabbit_clk_aux_lock_en : std_logic;
-- FSM timeout counter
signal tmo_restart, tmo_hit : std_logic;
signal tmo_cntr : unsigned(f_log2_size(c_wrabbit_STATE_TIMEOUT)-1 downto 0);
-- synchronizers
signal wrabbit_en_sync, time_valid : std_logic_vector (1 downto 0);
signal clk_aux_locked, link_up : std_logic_vector (1 downto 0);
signal state_syncing, clk_aux_lock_en : std_logic_vector (1 downto 0);
-- aux
signal dac_p_c : unsigned(23 downto 0);
begin -- behavioral
p_dac_p_counter : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_sys_i = '0' then
dac_p_c <= (others => '0');
else
if dac_p_c = "111111111111111111111111" then
dac_p_c <= (others => '0');
elsif wrabbit_dac_wr_p_i = '1' then
dac_p_c <= dac_p_c + 1;
end if;
end if;
end if;
end process;
p_timeout_counter : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_sys_i = '0' or tmo_restart = '1' or tmo_hit = '1' then
tmo_cntr <= (others => '0');
tmo_hit <= '0';
else
tmo_cntr <= tmo_cntr + 1;
if(tmo_cntr = c_wrabbit_STATE_TIMEOUT) then
tmo_hit <= '1';
end if;
end if;
end if;
end process;
tmo_restart <= wrabbit_state_changed;
input_synchronizer: process (clk_sys_i)
begin
if rising_edge (clk_sys_i) then
if rst_n_sys_i = '0' then
wrabbit_en_sync <= (others => '0');
else
wrabbit_en_sync <= wrabbit_en_sync(0) & wrabbit_reg_i(0);
end if;
end if;
end process;
wrabbit_en <= wrabbit_en_sync(1);
p_whiterabbit_fsm : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_sys_i = '0' then
csync_wrabbit_sysclk <= '0';
wrabbit_clk_aux_lock_en <= '0';
wrabbit_state <= wrabbit_CORE_OFFLINE;
wrabbit_state_changed <= '0';
else
case wrabbit_state is
when wrabbit_CORE_OFFLINE =>
wrabbit_clk_aux_lock_en <= '0';
if(wrabbit_link_up_i = '1' and tmo_hit = '1') then
wrabbit_state <= wrabbit_WAIT_READY;
wrabbit_state_changed <= '1';
else
wrabbit_state_changed <= '0';
end if;
when wrabbit_WAIT_READY =>
wrabbit_clk_aux_lock_en <= '0';
if(wrabbit_link_up_i = '0') then
wrabbit_state <= wrabbit_CORE_OFFLINE;
wrabbit_state_changed <= '1';
elsif(wrabbit_time_valid_i = '1' and tmo_hit = '1' and wrabbit_en = '1') then
wrabbit_state_changed <= '1';
wrabbit_state <= wrabbit_SYNCING;
else
wrabbit_state_changed <= '0';
end if;
when wrabbit_SYNCING =>
wrabbit_clk_aux_lock_en <= '1';
if(wrabbit_time_valid_i = '0' or wrabbit_en = '0') then
wrabbit_state <= wrabbit_WAIT_READY;
wrabbit_state_changed <= '1';
elsif(wrabbit_clk_aux_locked_i = '1' and tmo_hit = '1') then
wrabbit_state <= wrabbit_SYNCED;
csync_wrabbit_sysclk <= '1';
wrabbit_state_changed <= '1';
else
wrabbit_state_changed <= '0';
end if;
when wrabbit_SYNCED =>
csync_wrabbit_sysclk <= '0';
if(wrabbit_time_valid_i = '0' or wrabbit_en = '0' or wrabbit_clk_aux_locked_i = '0') then
wrabbit_state <= wrabbit_SYNCING;
wrabbit_state_changed <= '1';
else
wrabbit_state_changed <= '0';
end if;
end case;
end if;
end if;
end process;
outputs_synchronizer: process (clk_ref_i)
begin
if rising_edge (clk_ref_i) then
if rst_n_ref_i = '0' then
clk_aux_locked <= (others => '0');
link_up <= (others => '0');
state_syncing <= (others => '0');
clk_aux_lock_en <= (others => '0');
time_valid <= (others => '0');
else
clk_aux_locked <= clk_aux_locked(0) & wrabbit_clk_aux_locked_i;
link_up <= link_up(0) & wrabbit_link_up_i;
state_syncing <= state_syncing(0) & wrabbit_state_syncing;
clk_aux_lock_en <= clk_aux_lock_en(0) & wrabbit_clk_aux_lock_en;
time_valid <= time_valid(0) & wrabbit_time_valid_i;
end if;
end if;
end process;
wrabbit_synched_o <= clk_aux_locked(1);
wrabbit_state_syncing <= '1' when (wrabbit_state = wrabbit_SYNCING or wrabbit_state = wrabbit_SYNCED) else '0';
wrabbit_clk_aux_lock_en_o <= clk_aux_lock_en(1);
wrabbit_reg_o(0) <= '1'; -- reserved
wrabbit_reg_o(1) <= '1'; -- reserved
wrabbit_reg_o(2) <= link_up(1);
wrabbit_reg_o(3) <= state_syncing(1);
wrabbit_reg_o(4) <= clk_aux_locked(1);
wrabbit_reg_o(5) <= time_valid(1);
wrabbit_reg_o(6) <= wrabbit_reg_i(0);
wrabbit_reg_o(7) <= clk_aux_locked(1);
wrabbit_reg_o(8) <= time_valid(1);
wrabbit_reg_o(9) <= clk_aux_lock_en(1);
wrabbit_reg_o(15 downto 10) <= std_logic_vector(dac_p_c(5 downto 0));
wrabbit_reg_o(31 downto 16) <= wrabbit_dac_value_i(15 downto 0);
end behavioral;
#
# Mezzanine top level pin assignment file:
# syntax: pin FMC_pin_name Core_Pin_name IO_Standard
# % is replaced with FMC number if the carrier supports more than 1 mezzanine
#
mezzanine fmc-tdc-v3
pin clk0m2c_p ft%_acam_refclk_p_i lvds_25
pin clk0m2c_n ft%_acam_refclk_n_i lvds_25
pin clk1m2c_p ft%_tdc_125m_clk_p_i lvds_25
pin clk1m2c_n ft%_tdc_125m_clk_n_i lvds_25
pin la_n30 ft%_tdc_led_trig1_o lvcmos25
pin la_p32 ft%_tdc_led_trig2_o lvcmos25
pin la_n32 ft%_tdc_led_trig3_o lvcmos25
pin la_p0 ft%_term_en_1_o lvcmos25
pin la_n0 ft%_term_en_2_o lvcmos25
pin la_p16 ft%_ef1_i lvcmos25
pin la_n16 ft%_ef2_i lvcmos25
pin la_p20 ft%_term_en_3_o lvcmos25
pin la_n20 ft%_term_en_4_o lvcmos25
pin la_p22 ft%_term_en_5_o lvcmos25
pin la_n22 ft%_tdc_led_status_o lvcmos25
pin la_p31 ft%_tdc_led_trig4_o lvcmos25
pin la_n31 ft%_tdc_led_trig5_o lvcmos25
pin la_p23 ft%_pll_sclk_o lvcmos25
pin la_n23 ft%_pll_dac_sync_n_o lvcmos25
pin la_p26 ft%_pll_cs_n_o lvcmos25
pin la_n26 ft%_cs_n_o lvcmos25
pin la_p15 ft%_err_flag_i lvcmos25
pin la_n15 ft%_int_flag_i lvcmos25
pin la_p25 ft%_start_dis_o lvcmos25
pin la_n25 ft%_stop_dis_o lvcmos25
pin la_n27 ft%_pll_sdo_i lvcmos25
pin la_n29 ft%_pll_status_i lvcmos25
pin la_p27 ft%_pll_sdi_o lvcmos25
pin la_p29 ft%_start_from_fpga_o lvcmos25
pin la_n14 ft%_data_bus_io[27] lvcmos25
pin la_p14 ft%_data_bus_io[26] lvcmos25
pin la_n13 ft%_data_bus_io[25] lvcmos25
pin la_p13 ft%_data_bus_io[24] lvcmos25
pin la_n11 ft%_data_bus_io[23] lvcmos25
pin la_p11 ft%_data_bus_io[22] lvcmos25
pin la_n12 ft%_data_bus_io[21] lvcmos25
pin la_p12 ft%_data_bus_io[20] lvcmos25
pin la_n10 ft%_data_bus_io[19] lvcmos25
pin la_p10 ft%_data_bus_io[18] lvcmos25
pin la_n9 ft%_data_bus_io[17] lvcmos25
pin la_p9 ft%_data_bus_io[16] lvcmos25
pin la_n7 ft%_data_bus_io[15] lvcmos25
pin la_p7 ft%_data_bus_io[14] lvcmos25
pin la_n5 ft%_data_bus_io[13] lvcmos25
pin la_p5 ft%_data_bus_io[12] lvcmos25
pin la_n8 ft%_data_bus_io[11] lvcmos25
pin la_p8 ft%_data_bus_io[10] lvcmos25
pin la_n6 ft%_data_bus_io[9] lvcmos25
pin la_p6 ft%_data_bus_io[8] lvcmos25
pin la_n1 ft%_data_bus_io[7] lvcmos25
pin la_n4 ft%_data_bus_io[6] lvcmos25
pin la_p1 ft%_data_bus_io[5] lvcmos25
pin la_p4 ft%_data_bus_io[4] lvcmos25
pin la_n3 ft%_data_bus_io[3] lvcmos25
pin la_p3 ft%_data_bus_io[2] lvcmos25
pin la_n2 ft%_data_bus_io[1] lvcmos25
pin la_p2 ft%_data_bus_io[0] lvcmos25
pin la_n19 ft%_address_o[3] lvcmos25
pin la_p19 ft%_address_o[2] lvcmos25
pin la_n18 ft%_address_o[1] lvcmos25
pin la_p18 ft%_address_o[0] lvcmos25
pin la_p21 ft%_oe_n_o lvcmos25
pin la_n17 ft%_rd_n_o lvcmos25
pin la_p17 ft%_wr_n_o lvcmos25
pin la_p33 ft%_enable_inputs_o lvcmos25
pin la_n33 ft%_mezz_one_wire_b lvcmos25
#eof
#
# Carrier FMC pins description file
#
# Syntax:
# carrier carrier_name numeber_of_fmc_slots
# pin FMC_Slot signal_name FPGA_pin
carrier spec 1
pin 0 clk1m2c_p L20 #
pin 0 clk1m2c_n L22 #
pin 0 clk0m2c_p E16 #
pin 0 clk0m2c_n F16 #
pin 0 la_p33 C19
pin 0 la_p32 B20
pin 0 la_p31 D17
pin 0 la_p30 V17
pin 0 la_p29 W17
pin 0 la_p28 Y16
pin 0 la_p27 AA18
pin 0 la_p26 Y17
pin 0 la_p25 T15
pin 0 la_p24 W14
pin 0 la_p23 AA16
pin 0 la_p22 R13
pin 0 la_p21 V13
pin 0 la_p20 R11
pin 0 la_p19 Y15
pin 0 la_p18 T12
pin 0 la_p17 Y13
pin 0 la_p16 W12
pin 0 la_p15 V11
pin 0 la_p14 AA4
pin 0 la_p13 Y9
pin 0 la_p12 T10
pin 0 la_p11 W10
pin 0 la_p10 AA8
pin 0 la_p9 Y7
pin 0 la_p8 R9
pin 0 la_p7 U9
pin 0 la_p6 Y5
pin 0 la_p5 AA6
pin 0 la_p4 T8
pin 0 la_p3 V7
pin 0 la_p2 W6
pin 0 la_p1 AA12
pin 0 la_p0 Y11
pin 0 la_n33 A19
pin 0 la_n32 A20
pin 0 la_n31 C18
pin 0 la_n30 W18
pin 0 la_n29 Y18
pin 0 la_n28 W15
pin 0 la_n27 AB18
pin 0 la_n26 AB17
pin 0 la_n25 U15
pin 0 la_n24 Y14
pin 0 la_n23 AB16
pin 0 la_n22 T14
pin 0 la_n21 W13
pin 0 la_n20 T11
pin 0 la_n19 AB15
pin 0 la_n18 U12
pin 0 la_n17 AB13
pin 0 la_n16 Y12
pin 0 la_n15 W11
pin 0 la_n14 AB4 #
pin 0 la_n13 AB9
pin 0 la_n12 U10
pin 0 la_n11 Y10
pin 0 la_n10 AB8
pin 0 la_n9 AB7
pin 0 la_n8 R8
pin 0 la_n7 V9
pin 0 la_n6 AB5 #
pin 0 la_n5 AB6 #
pin 0 la_n4 U8 #
pin 0 la_n3 W8 #
pin 0 la_n2 Y6 #
pin 0 la_n1 AB12 #
pin 0 la_n0 AB11 #
#eof
#
# Carrier FMC pins description file
#
# Syntax:
# carrier carrier_name numeber_of_fmc_slots
# pin FMC_Slot signal_name FPGA_pin
carrier svec-v0 2
pin 0 clk1m2c_p E16
pin 0 clk1m2c_n D16
pin 0 clk0m2c_p H15
pin 0 clk0m2c_n G15
pin 0 la_p33 J12
pin 0 la_p32 H11
pin 0 la_p31 L11
pin 0 la_p30 J13
pin 0 la_p29 F9
pin 0 la_p28 L12
pin 0 la_p27 M13
pin 0 la_p26 L14
pin 0 la_p25 F11
pin 0 la_p24 G10
pin 0 la_p23 M15
pin 0 la_p22 F13
pin 0 la_p21 G12
pin 0 la_p20 F15
pin 0 la_p19 G14
pin 0 la_p18 J14
pin 0 la_p17 B15
pin 0 la_p16 F19
pin 0 la_p15 H16
pin 0 la_p14 F17
pin 0 la_p13 G18
pin 0 la_p12 F21
pin 0 la_p11 G20
pin 0 la_p10 L21
pin 0 la_p9 M20
pin 0 la_p8 F23
pin 0 la_p7 G22
pin 0 la_p6 B25
pin 0 la_p5 M19
pin 0 la_p4 D24
pin 0 la_p3 E25
pin 0 la_p2 J22
pin 0 la_p1 H21
pin 0 la_p0 C16
pin 0 la_n33 H12
pin 0 la_n32 G11
pin 0 la_n31 K11
pin 0 la_n30 H13
pin 0 la_n29 E9
pin 0 la_n28 K12
pin 0 la_n27 L13
pin 0 la_n26 K14
pin 0 la_n25 E11
pin 0 la_n24 F10
pin 0 la_n23 K15
pin 0 la_n22 E13
pin 0 la_n21 F12
pin 0 la_n20 E15
pin 0 la_n19 F14
pin 0 la_n18 H14
pin 0 la_n17 A15
pin 0 la_n16 E19
pin 0 la_n15 G16
pin 0 la_n14 E17
pin 0 la_n13 F18
pin 0 la_n12 E21
pin 0 la_n11 F20
pin 0 la_n10 K21
pin 0 la_n9 L20
pin 0 la_n8 E23
pin 0 la_n7 F22
pin 0 la_n6 A25
pin 0 la_n5 L19
pin 0 la_n4 C24
pin 0 la_n3 D25
pin 0 la_n2 H22
pin 0 la_n1 G21
pin 0 la_n0 A16
pin 1 clk1m2c_p AH16
pin 1 clk1m2c_n AK16
pin 1 clk0m2c_p AF16
pin 1 clk0m2c_n AG16
pin 1 la_p33 AA19
pin 1 la_p32 W19
pin 1 la_p31 Y21
pin 1 la_p30 W20
pin 1 la_p29 AC24
pin 1 la_p28 AA22
pin 1 la_p27 AB20
pin 1 la_p26 AC19
pin 1 la_p25 AB17
pin 1 la_p24 AB21
pin 1 la_p23 AF25
pin 1 la_p22 AE24
pin 1 la_p21 AD22
pin 1 la_p20 AE19
pin 1 la_p19 AE23
pin 1 la_p18 AE21
pin 1 la_p17 AC16
pin 1 la_p16 AB14
pin 1 la_p15 Y17
pin 1 la_p14 Y15
pin 1 la_p13 AC15
pin 1 la_p12 AE15
pin 1 la_p11 Y16
pin 1 la_p10 Y14
pin 1 la_p9 W14
pin 1 la_p8 AB12
pin 1 la_p7 AD12
pin 1 la_p6 AD10
pin 1 la_p5 AE11
pin 1 la_p4 AJ15
pin 1 la_p3 AE13
pin 1 la_p2 AC11
pin 1 la_p1 AG8
pin 1 la_p0 AJ17
pin 1 la_n33 AB19
pin 1 la_n32 Y19
pin 1 la_n31 AA21
pin 1 la_n30 Y20
pin 1 la_n29 AD24
pin 1 la_n28 AC22
pin 1 la_n27 AC20
pin 1 la_n26 AD19
pin 1 la_n25 AD17
pin 1 la_n24 AC21
pin 1 la_n23 AG25
pin 1 la_n22 AF24
pin 1 la_n21 AE22
pin 1 la_n20 AF19
pin 1 la_n19 AF23
pin 1 la_n18 AF21
pin 1 la_n17 AD16
pin 1 la_n16 AC14
pin 1 la_n15 AA17
pin 1 la_n14 AA15
pin 1 la_n13 AD15
pin 1 la_n12 AF15
pin 1 la_n11 AB16
pin 1 la_n10 AA14
pin 1 la_n9 Y13
pin 1 la_n8 AC12
pin 1 la_n7 AE12
pin 1 la_n6 AE10
pin 1 la_n5 AF11
pin 1 la_n4 AK15
pin 1 la_n3 AF13
pin 1 la_n2 AD11
pin 1 la_n1 AH8
pin 1 la_n0 AK17
#eof
#!/usr/bin/python
import re, os
def find_first(cond, l):
x = filter(cond, l)
if len(x):
return x[0]
else:
return None
class MezzaninePin:
def __init__(self, fmc_line=None, port_name=None, io_standard=None):
self.fmc_line = fmc_line
self.port_name = port_name
self.io_standard = io_standard
def parse(self, s):
self.fmc_line = s[1]
self.port_name = s[2]
self.io_standard= s[3]
def __str__(self):
return "FMC Pin: name %s port %s io %s" % ( self.fmc_line, self.port_name, self.io_standard)
class CarrierPin:
def __init__(self, fmc_line=None, fmc_slot=None, fpga_pin=None):
self.fmc_slot = fmc_slot
self.fmc_line = fmc_line
self.fpga_pin = fpga_pin
def parse(self, s):
self.fmc_slot = int(s[1], 10)
self.fmc_line = s[2]
self.fpga_pin = s[3]
def __str__(self):
return "Carrier Pin: name %s slot %d pin %s" % ( self.fmc_line, self.fmc_slot, self.fpga_pin)
class Carrier:
def __init__(self, name, num_slots):
self.name = name
self.num_slots = num_slots
self.pins = []
def add_pin(self, pin):
self.pins.append(pin)
class Mezzanine:
def __init__(self, name):
self.name = name
self.pins = []
def add_pin(self, pin):
self.pins.append(pin)
class UCFGen:
desc_files_path = ["./", "./pin_defs"];
def __init__(self):
self.carriers = []
self.mezzanines = []
pass
def load_desc_file(self, name):
lines=open(name,"r").read().splitlines()
print(name)
import re
m_ncomments = re.compile("^\s*([^#]+)\s*#?.*$")
car = mez = None
for l in lines:
m=re.match(m_ncomments, l)
if not m:
continue
print(m.group(1))
tokens = m.group(1).split()
command = tokens[0]
if(command == "carrier"):
car = Carrier(tokens[1], int(tokens[2], 10))
elif(command == "mezzanine"):
mez = Mezzanine(tokens[1])
elif(command == "pin"):
if(car):
p=CarrierPin()
p.parse(tokens)
car.add_pin(p)
elif(mez):
p=MezzaninePin()
p.parse(tokens)
mez.add_pin(p)
else:
raise Exception("%s: define a carrier/mezzanine before defining pins." % name)
else:
raise Exception("%s: Unrecognized command '%s'." % (name, command))
if(car):
self.carriers.append(car)
elif(mez):
self.mezzanines.append(mez)
def load_descs(self):
for d in self.desc_files_path:
if not os.path.isdir(d):
continue
for f in os.listdir(d):
fname=d+"/"+f
if(os.path.isfile(fname) and fname.endswith(".pins")):
self.load_desc_file(fname)
# print("Loaded %d carrier and %d mezzanine pin descriptions." % ( len(self.carriers), len(self.mezzanines)))
def dump_descs(self):
print("Supported carriers:")
for c in self.carriers:
print("* %s" % c.name)
print("Supported mezzanines:")
for m in self.mezzanines:
print("* %s" % m.name)
def generate_ucf(self, ucf_filename, carrier_name, slot_mappings):
f = None
try:
f = open(ucf_filename,"r")
except:
pass
ucf_user=[]
if f:
ucf_lines=f.read().splitlines()
usermode = True
for l in ucf_lines:
if(l == "# <ucfgen_start>"):
usermode = False
if(usermode):
ucf_user.append(l)
if (l == "# <ucfgen_end>"):
usermode = True
f.close()
car = find_first(lambda car: car.name == carrier_name, self.carriers)
if not car:
raise Exception("Unsupported carrier: %s" % carrier_name)
ucf_ours=[]
ucf_ours.append("")
ucf_ours.append("# <ucfgen_start>")
ucf_ours.append("")
ucf_ours.append("# This section has bee generated automatically by ucfgen.py. Do not hand-modify if not really necessary.")
slot = 0
for mapping in slot_mappings:
if not mapping:
continue
mez = find_first(lambda mez: mez.name == mapping, self.mezzanines)
if not mez:
raise Exception("Unsupported mezzanine: %s " % mapping)
print("Found mezzanine %s for slot %d." % (mez.name, slot))
if(car.num_slots > 1):
slot_str = str(slot)
else:
slot_str=""
ucf_ours.append("# ucfgen pin assignments for mezzanine %s slot %d" % (mapping, slot))
for p in mez.pins:
p_carrier = find_first(lambda f : f.fmc_line == p.fmc_line and f.fmc_slot == slot, car.pins)
if (not p_carrier):
raise Exception("Mezzanine FMC line %s not defined in the carrier description" % p.fmc_line)
print(p.port_name.replace("%", slot_str))
ucf_ours.append("NET \"%s\" LOC = \"%s\";" % ( p.port_name.replace("%", slot_str), p_carrier.fpga_pin))
ucf_ours.append("NET \"%s\" IOSTANDARD = \"%s\";" % ( p.port_name.replace("%", slot_str), p.io_standard.upper()))
slot=slot+1
ucf_ours.append("# <ucfgen_end>")
f_out = open(ucf_filename, "w")
for l in ucf_user:
f_out.write(l+"\n")
for l in ucf_ours:
f_out.write(l+"\n")
f_out.close()
print("Successfully updated UCF file %s" % ucf_filename)
def usage():
import getopt, sys
print("Ucfgen, a trivial script for automatizing Xilinx UCF FMC Mezzanine-Carrier pin assignments.\n")
print("usage: %s [options] ucf_file" % sys.argv[0])
print("Options:")
print(" -h, --help: print this message");
print(" -c, --carrier <type>: select carrier type");
print(" -m, --mezzanine <slot:type>: select <type> of mezzanine inserted into carrier slot <slot>");
print(" -l, --list: list supported carriers and mezzanines");
def main():
import getopt, sys, os
if len(sys.argv) == 1:
print("Missing command line option. Type %s --help for spiritual guidance." % sys.argv[0])
sys.exit(0)
try:
opts, args = getopt.getopt(sys.argv[1:], "hlo:m:c:", ["help", "list", "output=", "mezzanine=slot:type", "carrier="])
except getopt.GetoptError, err:
print str(err)
usage()
sys.exit(1)
output = None
carrier = None
u = UCFGen()
u.desc_files_path.append(os.path.dirname(os.path.realpath(sys.argv[0])))
u.load_descs()
mezzanines=[]
for i in range(0,128):
mezzanines.append(None)
for o, a in opts:
if o in [ "-h", "--help" ]:
usage()
sys.exit()
elif o in ("-l", "--list"):
u.dump_descs()
sys.exit()
elif o in ("-c", "--carrier"):
carrier = a
elif o in ("-m", "--mezzanine"):
t=a.split(":")
mezzanines[int(t[0])] = t[1]
else:
assert False, "unhandled option"
ucf_name = sys.argv[len(sys.argv)-1]
u.generate_ucf(ucf_name, carrier, mezzanines)
main()
#u.generate_ucf("svec_top.ucf", "svec-v0", [ "fmc-delay-v4", "fmc-delay-v4" ])
\ No newline at end of file
-------------------------------------------------------------------------------
-- acam_test.vec
-------------------------------------------------------------------------------
-- Select the GN4124 Primary BFM
model 0
-- Initialize the BFM to its default state
init
-------------------------------------------------------------------------------
-- Initialize the Primary GN412x BFM model
-------------------------------------------------------------------------------
-- These address ranges will generate traffic from the BFM to the FPGA
-- bar BAR ADDR SIZE VC TC S
bar 0 0000000000000000 00100000 0 7 0
-- This allocates a RAM block inside the BFM for the FPGA to access
-- bfm_bar BAR ADDR SIZE
bfm_bar 0 0000000040000000 20000000
bfm_bar 1 0000000020000000 20000000
-- Drive reset to the FPGA
reset %d320
-- Wait until the FPGA is un-reset and ready for traffic on the local bus
wait %d50000
-- Drive reset to the FPGA
reset %d320
-- Wait until the FPGA is un-reset and ready for traffic on the local bus
wait %d60000
-------------------------------------------------------------------------------
-- Access the tdc core register space
-------------------------------------------------------------------------------
-- the following writes will go out in a single packet
-- Gonzalo: 3 writings outside of the BAR defined memory space to check that
-- the BFM model does not forward them to the Local bus
wr 0000000040000808 F 0001F04C
wait %d50
wr 0000000040000800 F 00021040
wait %d50
wr 0000000040000800 F 00025000
wait %d50
-- Gonzalo: 5 reads inside Matthieu's core memory space to check that the core
-- does not forward them to the wishbone bus
rd 0000000000000000 F 0000A0A1
wait %d20
rd 0000000000000004 F 0000A0A2
wait %d20
rd 0000000000000008 F 0000A0A3
wait %d20
rd 000000000000000C F 0000A0A4
wait %d20
rd 0000000000000010 F 0000A0A5
wait %d60
-- Gonzalo: actual wr and rd for test
wr 0000000000005000 F 0000FC81
wait %d50
wr 000000000000502C F 00FF0000
wait %d50
rd 0000000000080000 F 0000FC81
wait %d50
rd 000000000008002C F 00FF0000
wait %d50
wr 0000000000080030 F 04000000
wait %d50
rd 0000000000080030 F 04000000
wait %d50
-------------------------------------------------------------------------------
-- acam_test.vec
-------------------------------------------------------------------------------
-- Select the GN4124 Primary BFM
model 0
-- Initialize the BFM to its default state
init
-------------------------------------------------------------------------------
-- Initialize the Primary GN412x BFM model
-------------------------------------------------------------------------------
-- These address ranges will generate traffic from the BFM to the FPGA
-- bar BAR ADDR SIZE VC TC S
bar 0 0000000000000000 00100000 0 7 0
-- This allocates a RAM block inside the BFM for the FPGA to access
-- bfm_bar BAR ADDR SIZE
bfm_bar 0 0000000040000000 20000000
bfm_bar 1 0000000020000000 20000000
-- Drive reset to the FPGA
reset %d320
-- Wait until the FPGA is un-reset and ready for traffic on the local bus
wait %d50000
-- Drive reset to the FPGA
reset %d320
-- Wait until the FPGA is un-reset and ready for traffic on the local bus
wait %d60000
-------------------------------------------------------------------------------
-- Access the tdc core register space
-------------------------------------------------------------------------------
-- the following writes will go out in a single packet
---- Gonzalo: 3 writings outside of the BAR defined memory space to check that
---- the BFM model does not forward them to the Local bus
--wr 0000000040000808 F 0001F04C
--wait %d20
--wr 0000000040000800 F 00021040
--wait %d20
--wr 0000000040000800 F 00025000
--wait %d60
---- Gonzalo: 3 reads inside Matthieu's core memory space to check that the core
---- does not forward them to the wishbone bus
--rd 0000000000000000 F 0000A0A1
--wait %d20
--rd 0000000000000004 F 0000A0A2
--wait %d20
--rd 0000000000000008 F 0000A0A3
--wait %d60
-- Gonzalo: actual wr and rd on the application memory space for test
-- writing stuff on the TDC config
--wr 0000000000005000 F 00000040
--wait %d20
--wr 0000000000005004 F 00000000
--wait %d20
--wr 0000000000005008 F 00000000
--wait %d60
-- writing stuff for the ACAM config
wr 0000000000005000 F 01F0FC81
wait %d20
wr 0000000000005004 F 00000000
wait %d20
wr 0000000000005008 F 00000E02
wait %d60
-- loading the utc time
wr 00000000000050FC F 00000200
wait %d200
-- loading the acam config
wr 00000000000050FC F 00000004
wait %d200
-- reading back the acam config
wr 00000000000050FC F 00000008
wait %d200
-- activate acquisition
wr 00000000000050FC F 00000001
wait %d540000
-- read circular buffer wr pointer
rd 000000000000509C F 00000000
wait %d200
-- prepare and launch DMA transfer
wr 000000000000000C F 36EF8000
wait %d20
wr 0000000000000014 F 00000210
wait %d100
wr 0000000000000000 F 00000001
wait %d100
-- deactivate acquisition
wr 00000000000800FC F 00000002
wait %d200
-- read acam status
wr 00000000000800FC F 00000010
wait %d100
rd 0000000000080070 F 00000000
wait %d100
-- read acam ififo1
wr 00000000000800FC F 00000020
wait %d100
rd 0000000000080060 F 00000000
wait %d100
-- read acam ififo2
wr 00000000000800FC F 00000040
wait %d100
rd 0000000000080064 F 00000000
wait %d100
-- read acam start01 register
wr 00000000000800FC F 00000080
wait %d100
rd 0000000000080068 F 00000000
wait %d100
-- reset acam
wr 00000000000800FC F 00000100
wait %d200
--rd 0000000000080000 F 00001234
--wait %d20
--rd 0000000000080004 F 00005678
--wait %d20
--rd 0000000000080008 F 0000abcd
--wait %d20
--rd 000000000008000C F 0000ef90
--wait %d60
--
--wr 00000000000800FC F 00000001
--wait %d100
--wr 00000000000800FC F 00000002
--wait %d100
---- Gonzalo: registers inside Matthieu's core memory space are written with the
---- settings for DMA transfer
--
---- Start address on the carrier local memory
--wr 0000000000000008 F 00000000
--wait %d20
--
---- Start addresses on the PCI host memory
--wr 000000000000000C F 0000A0A4
--wait %d20
--wr 0000000000000010 F 0000A0A5
--wait %d20
--
---- Transfer length
--wr 0000000000000014 F 00000060
--wait %d20
--
---- Chain control
--wr 0000000000000020 F 00000000
--wait %d60
--
---- Start transfer through the Control register and check through the status register
--wr 0000000000000000 F 00000001
--wait %d100
--rd 0000000000000004 F 00000001
--wait %d100
--
--
-------------------------------------------------------------------------------
-- acam_test.vec
-------------------------------------------------------------------------------
-- Select the GN4124 Primary BFM
model 0
-- Initialize the BFM to its default state
init
-------------------------------------------------------------------------------
-- Initialize the Primary GN412x BFM model
-------------------------------------------------------------------------------
-- These address ranges will generate traffic from the BFM to the FPGA
-- bar BAR ADDR SIZE VC TC S
bar 0 0000000000000000 00100000 0 7 0
-- This allocates a RAM block inside the BFM for the FPGA to access
-- bfm_bar BAR ADDR SIZE
bfm_bar 0 0000000040000000 20000000
bfm_bar 1 0000000020000000 20000000
-- Drive reset to the FPGA
reset %d320
-- Wait until the FPGA is un-reset and ready for traffic on the local bus
wait %d50000
-- Drive reset to the FPGA
reset %d320
-- Wait until the FPGA is un-reset and ready for traffic on the local bus
wait %d60000
-------------------------------------------------------------------------------
-- Access the tdc core register space
-------------------------------------------------------------------------------
-- the following writes will go out in a single packet
-- Gonzalo: 3 writings outside of the BAR defined memory space to check that
-- the BFM model does not forward them to the Local bus
wr 0000000040000808 F 0001F04C
wait %d20
wr 0000000040000800 F 00021040
wait %d20
wr 0000000040000800 F 00025000
wait %d60
-- Gonzalo: 3 reads inside Matthieu's core memory space to check that the core
-- does not forward them to the wishbone bus
rd 0000000000000000 F 0000A0A1
wait %d20
rd 0000000000000004 F 0000A0A2
wait %d20
rd 0000000000000008 F 0000A0A3
wait %d60
-- Gonzalo: actual wr and rd on the application memory space for test
wr 0000000000080000 F 00001234
wait %d20
wr 0000000000080004 F 00005678
wait %d20
wr 0000000000080008 F 0000abcd
wait %d20
wr 000000000008000C F 0000ef90
wait %d60
rd 0000000000080000 F 00001234
wait %d20
rd 0000000000080004 F 00005678
wait %d20
rd 0000000000080008 F 0000abcd
wait %d20
rd 000000000008000C F 0000ef90
wait %d60
wr 0000000000080100 F 00000001
wait %d100
wr 0000000000080100 F 00000002
wait %d100
-- Gonzalo: registers inside Matthieu's core memory space are written with the
-- settings for DMA transfer
-- Start address on the carrier local memory
wr 0000000000000008 F 00000000
wait %d20
-- Start addresses on the PCI host memory
wr 000000000000000C F 0000A0A4
wait %d20
wr 0000000000000010 F 0000A0A5
wait %d20
-- Transfer length
wr 0000000000000014 F 00000060
wait %d20
-- Chain control
wr 0000000000000020 F 00000000
wait %d60
-- Start transfer through the Control register and check through the status register
wr 0000000000000000 F 00000001
wait %d100
rd 0000000000000004 F 00000001
wait %d100
2600 us 1 5 us
800 us 2 505 ns
162 ps 3 505 ns
500 us 4 505 ns
400 ps 1 505 ns
18 ps 5 505 ns
600 ns 1 100 ps
110 ps 2 100 ps
110 ps 3 100 ps
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
<header>
<!-- ISE source project file created by Project Navigator. -->
<!-- -->
<!-- This file contains project source information including a list of -->
<!-- project source files, project and process properties. This file, -->
<!-- along with the project source files, is sufficient to open and -->
<!-- implement in ISE Project Navigator. -->
<!-- -->
<!-- Copyright (c) 1995-2011 Xilinx, Inc. All rights reserved. -->
</header>
<version xil_pn:ise_version="13.4" xil_pn:schema_version="2"/>
<files>
<file xil_pn:name="../../ip_cores/gnum_core/p2l_dma_master.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="36"/>
<association xil_pn:name="Implementation" xil_pn:seqID="1"/>
</file>
<file xil_pn:name="../../ip_cores/gnum_core/p2l_decode32.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="38"/>
<association xil_pn:name="Implementation" xil_pn:seqID="3"/>
</file>
<file xil_pn:name="../../ip_cores/gnum_core/l2p_dma_master.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="40"/>
<association xil_pn:name="Implementation" xil_pn:seqID="5"/>
</file>
<file xil_pn:name="../../ip_cores/gnum_core/l2p_arbiter.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="41"/>
<association xil_pn:name="Implementation" xil_pn:seqID="6"/>
</file>
<file xil_pn:name="../../ip_cores/gnum_core/gn4124_core_pkg.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="6"/>
<association xil_pn:name="Implementation" xil_pn:seqID="9"/>
</file>
<file xil_pn:name="../../ip_cores/gnum_core/dma_controller_wb_slave.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="17"/>
<association xil_pn:name="Implementation" xil_pn:seqID="10"/>
</file>
<file xil_pn:name="../../ip_cores/gnum_core/dma_controller.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="42"/>
<association xil_pn:name="Implementation" xil_pn:seqID="11"/>
</file>
<file xil_pn:name="../../ip_cores/gnum_core/wbmaster32.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="33"/>
<association xil_pn:name="Implementation" xil_pn:seqID="12"/>
</file>
<file xil_pn:name="../../ip_cores/gnum_core/serdes_n_to_1_s2_se.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="14"/>
<association xil_pn:name="Implementation" xil_pn:seqID="13"/>
</file>
<file xil_pn:name="../../ip_cores/gnum_core/serdes_n_to_1_s2_diff.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="15"/>
<association xil_pn:name="Implementation" xil_pn:seqID="14"/>
</file>
<file xil_pn:name="../../ip_cores/gnum_core/serdes_1_to_n_data_s2_se.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="16"/>
<association xil_pn:name="Implementation" xil_pn:seqID="17"/>
</file>
<file xil_pn:name="../../ip_cores/gnum_core/serdes_1_to_n_clk_pll_s2_diff.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="34"/>
<association xil_pn:name="Implementation" xil_pn:seqID="18"/>
</file>
<file xil_pn:name="../../top/spec/top_tdc.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="54"/>
<association xil_pn:name="Implementation" xil_pn:seqID="19"/>
</file>
<file xil_pn:name="../../top/spec/tdc_core_pkg.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="7"/>
<association xil_pn:name="Implementation" xil_pn:seqID="20"/>
</file>
<file xil_pn:name="../../rtl/reg_ctrl.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="22"/>
<association xil_pn:name="Implementation" xil_pn:seqID="22"/>
</file>
<file xil_pn:name="../../rtl/one_hz_gen.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="23"/>
<association xil_pn:name="Implementation" xil_pn:seqID="23"/>
</file>
<file xil_pn:name="../../rtl/data_formatting.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="26"/>
<association xil_pn:name="Implementation" xil_pn:seqID="24"/>
</file>
<file xil_pn:name="../../rtl/data_engine.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="27"/>
<association xil_pn:name="Implementation" xil_pn:seqID="25"/>
</file>
<file xil_pn:name="../../rtl/circular_buffer.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="28"/>
<association xil_pn:name="Implementation" xil_pn:seqID="27"/>
</file>
<file xil_pn:name="../../rtl/acam_timecontrol_interface.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="29"/>
<association xil_pn:name="Implementation" xil_pn:seqID="28"/>
</file>
<file xil_pn:name="../../rtl/acam_databus_interface.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="30"/>
<association xil_pn:name="Implementation" xil_pn:seqID="29"/>
</file>
<file xil_pn:name="../../rtl/incr_counter.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="9"/>
<association xil_pn:name="Implementation" xil_pn:seqID="30"/>
</file>
<file xil_pn:name="../../rtl/free_counter.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="10"/>
<association xil_pn:name="Implementation" xil_pn:seqID="31"/>
</file>
<file xil_pn:name="../../testbench/spec/gnum_model/cmd_router.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="57"/>
<association xil_pn:name="Implementation" xil_pn:seqID="34"/>
</file>
<file xil_pn:name="../../testbench/spec/gnum_model/util.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="8"/>
<association xil_pn:name="Implementation" xil_pn:seqID="35"/>
</file>
<file xil_pn:name="../../testbench/spec/gnum_model/mem_model.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="45"/>
<association xil_pn:name="Implementation" xil_pn:seqID="36"/>
</file>
<file xil_pn:name="../../testbench/spec/gnum_model/gn412x_bfm.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="56"/>
<association xil_pn:name="Implementation" xil_pn:seqID="37"/>
</file>
<file xil_pn:name="../../testbench/spec/gnum_model/cmd_router1.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="46"/>
<association xil_pn:name="Implementation" xil_pn:seqID="38"/>
</file>
<file xil_pn:name="../../testbench/spec/gnum_model/textutil.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="19"/>
<association xil_pn:name="Implementation" xil_pn:seqID="39"/>
</file>
<file xil_pn:name="../../testbench/spec/acam_data_model.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="48"/>
<association xil_pn:name="Implementation" xil_pn:seqID="40"/>
</file>
<file xil_pn:name="../../testbench/spec/tb_tdc.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="59"/>
<association xil_pn:name="Implementation" xil_pn:seqID="41"/>
</file>
<file xil_pn:name="../../testbench/spec/start_stop_gen.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="55"/>
<association xil_pn:name="Implementation" xil_pn:seqID="42"/>
</file>
<file xil_pn:name="../../testbench/spec/acam_timing_model.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="47"/>
<association xil_pn:name="Implementation" xil_pn:seqID="43"/>
</file>
<file xil_pn:name="../../testbench/spec/acam_model.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="58"/>
<association xil_pn:name="Implementation" xil_pn:seqID="44"/>
</file>
<file xil_pn:name="../../testbench/spec/acam_fifo_model.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="20"/>
<association xil_pn:name="Implementation" xil_pn:seqID="45"/>
</file>
<file xil_pn:name="../../ip_cores/mem_core/blk_mem_circ_buff_v6_4.xco" xil_pn:type="FILE_COREGEN">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="12"/>
<association xil_pn:name="Implementation" xil_pn:seqID="76"/>
</file>
<file xil_pn:name="../../ip_cores/mem_core/blk_mem_circ_buff_v6_4_flist.txt" xil_pn:type="FILE_USERDOC"/>
<file xil_pn:name="../../rtl/start_retrig_ctrl.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="21"/>
<association xil_pn:name="Implementation" xil_pn:seqID="52"/>
</file>
<file xil_pn:name="../../rtl/clks_rsts_manager.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="50"/>
<association xil_pn:name="Implementation" xil_pn:seqID="53"/>
</file>
<file xil_pn:name="../../rtl/decr_counter.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="11"/>
<association xil_pn:name="Implementation" xil_pn:seqID="54"/>
</file>
<file xil_pn:name="../../rtl/fmc_tdc_core.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="49"/>
<association xil_pn:name="Implementation" xil_pn:seqID="55"/>
</file>
<file xil_pn:name="../../rtl/irq_generator.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="25"/>
<association xil_pn:name="Implementation" xil_pn:seqID="59"/>
</file>
<file xil_pn:name="../../rtl/leds_manager.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="24"/>
<association xil_pn:name="Implementation" xil_pn:seqID="60"/>
</file>
<file xil_pn:name="../../ip_cores/gnum_core/gn4124_core.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="53"/>
<association xil_pn:name="Implementation" xil_pn:seqID="67"/>
</file>
<file xil_pn:name="../../ip_cores/gnum_core/l2p_ser.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="39"/>
<association xil_pn:name="Implementation" xil_pn:seqID="68"/>
</file>
<file xil_pn:name="../../ip_cores/gnum_core/p2l_des.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="37"/>
<association xil_pn:name="Implementation" xil_pn:seqID="69"/>
</file>
<file xil_pn:name="../../ip_cores/gnum_core/pulse_sync_rtl.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="35"/>
<association xil_pn:name="Implementation" xil_pn:seqID="70"/>
</file>
<file xil_pn:name="../../ip_cores/gnum_core/xilinx_cores/generic_async_fifo_wrapper.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="13"/>
<association xil_pn:name="Implementation" xil_pn:seqID="71"/>
</file>
<file xil_pn:name="../../ip_cores/wishbone/wb_crossbar/xwb_sdb_crossbar.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="51"/>
<association xil_pn:name="Implementation" xil_pn:seqID="74"/>
</file>
<file xil_pn:name="../../ip_cores/wishbone/wb_crossbar/sdb_rom.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="32"/>
<association xil_pn:name="Implementation" xil_pn:seqID="75"/>
</file>
<file xil_pn:name="../../ip_cores/wishbone/wb_crossbar/xwb_crossbar.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="31"/>
<association xil_pn:name="Implementation" xil_pn:seqID="76"/>
</file>
<file xil_pn:name="../../ip_cores/wishbone/wishbone_pkg.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="2"/>
<association xil_pn:name="Implementation" xil_pn:seqID="85"/>
</file>
<file xil_pn:name="../../ip_cores/wishbone/carrier_csr.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="52"/>
<association xil_pn:name="Implementation" xil_pn:seqID="86"/>
</file>
<file xil_pn:name="../../ip_cores/wishbone/wb_slave_adapter/wb_slave_adapter.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="0"/>
<association xil_pn:name="Implementation" xil_pn:seqID="87"/>
</file>
<file xil_pn:name="../../ip_cores/genrams/genram_pkg.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="1"/>
<association xil_pn:name="Implementation" xil_pn:seqID="95"/>
</file>
<file xil_pn:name="../../top/spec/sdb_meta_pkg.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="3"/>
<association xil_pn:name="Implementation" xil_pn:seqID="96"/>
</file>
<file xil_pn:name="../../ip_cores/common/gencores_pkg.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="43"/>
<association xil_pn:name="Implementation" xil_pn:seqID="99"/>
</file>
<file xil_pn:name="../../top/spec/wb_irq_controller/irq_controller_regs.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="18"/>
<association xil_pn:name="Implementation" xil_pn:seqID="115"/>
</file>
<file xil_pn:name="../../top/spec/wb_irq_controller/irq_controller.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="44"/>
<association xil_pn:name="Implementation" xil_pn:seqID="116"/>
</file>
<file xil_pn:name="../../ip_cores/gnum_core/xilinx_cores/fifo_64x512.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="4"/>
<association xil_pn:name="Implementation" xil_pn:seqID="133"/>
</file>
<file xil_pn:name="../../ip_cores/gnum_core/xilinx_cores/fifo_32x512.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="5"/>
<association xil_pn:name="Implementation" xil_pn:seqID="134"/>
</file>
<file xil_pn:name="../../ip_cores/mem_core/blk_mem_gen_v6_3_flist.txt" xil_pn:type="FILE_USERDOC"/>
<file xil_pn:name="../../ip_cores/mem_core/blk_mem_gen_v6_1_flist.txt" xil_pn:type="FILE_USERDOC"/>
<file xil_pn:name="../../ip_cores/mem_core/blk_mem_gen_v6_2_flist.txt" xil_pn:type="FILE_USERDOC"/>
<file xil_pn:name="../../ip_cores/mem_core/blk_mem_circ_buff_v6_4.xise" xil_pn:type="FILE_COREGENISE">
<association xil_pn:name="Implementation" xil_pn:seqID="77"/>
</file>
</files>
<properties>
<property xil_pn:name="AES Initial Vector spartan6" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="AES Key (Hex String) spartan6" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Add I/O Buffers" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Allow Logic Optimization Across Hierarchy" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Allow SelectMAP Pins to Persist" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Allow Unexpanded Blocks" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Allow Unmatched LOC Constraints" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Allow Unmatched Timing Group Constraints" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Analysis Effort Level" xil_pn:value="Standard" xil_pn:valueState="default"/>
<property xil_pn:name="Asynchronous To Synchronous" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Auto Implementation Compile Order" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Auto Implementation Top" xil_pn:value="false" xil_pn:valueState="non-default"/>
<property xil_pn:name="Automatic BRAM Packing" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Automatically Insert glbl Module in the Netlist" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Automatically Run Generate Target PROM/ACE File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="BRAM Utilization Ratio" xil_pn:value="100" xil_pn:valueState="default"/>
<property xil_pn:name="Bring Out Global Set/Reset Net as a Port" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Bring Out Global Tristate Net as a Port" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Bus Delimiter" xil_pn:value="&lt;>" xil_pn:valueState="default"/>
<property xil_pn:name="Case" xil_pn:value="Maintain" xil_pn:valueState="default"/>
<property xil_pn:name="Case Implementation Style" xil_pn:value="None" xil_pn:valueState="default"/>
<property xil_pn:name="Change Device Speed To" xil_pn:value="-3" xil_pn:valueState="default"/>
<property xil_pn:name="Change Device Speed To Post Trace" xil_pn:value="-3" xil_pn:valueState="default"/>
<property xil_pn:name="Combinatorial Logic Optimization" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Compile EDK Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Compile SIMPRIM (Timing) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Compile UNISIM (Functional) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Compile XilinxCoreLib (CORE Generator) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Compile for HDL Debugging" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin Done" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Pin Program" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Configuration Rate spartan6" xil_pn:value="2" xil_pn:valueState="default"/>
<property xil_pn:name="Correlate Output to Input Design" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create ASCII Configuration File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create Binary Configuration File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create Bit File" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Create I/O Pads from Ports" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create IEEE 1532 Configuration File spartan6" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create Logic Allocation File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create Mask File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Create ReadBack Data Files" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Cross Clock Analysis" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="DSP Utilization Ratio" xil_pn:value="100" xil_pn:valueState="default"/>
<property xil_pn:name="Delay Values To Be Read from SDF" xil_pn:value="Setup Time" xil_pn:valueState="default"/>
<property xil_pn:name="Device" xil_pn:value="xc6slx45t" xil_pn:valueState="non-default"/>
<property xil_pn:name="Device Family" xil_pn:value="Spartan6" xil_pn:valueState="non-default"/>
<property xil_pn:name="Device Speed Grade/Select ABS Minimum" xil_pn:value="-3" xil_pn:valueState="default"/>
<property xil_pn:name="Disable Detailed Package Model Insertion" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Do Not Escape Signal and Instance Names in Netlist" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Done (Output Events)" xil_pn:value="Default (4)" xil_pn:valueState="default"/>
<property xil_pn:name="Drive Awake Pin During Suspend/Wake Sequence spartan6" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Drive Done Pin High" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable BitStream Compression" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Cyclic Redundancy Checking (CRC) spartan6" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Debugging of Serial Mode BitStream" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable External Master Clock spartan6" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Hardware Co-Simulation" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Internal Done Pipe" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Message Filtering" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Multi-Pin Wake-Up Suspend Mode spartan6" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Multi-Threading" xil_pn:value="Off" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Multi-Threading par spartan6" xil_pn:value="Off" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Outputs (Output Events)" xil_pn:value="Default (5)" xil_pn:valueState="default"/>
<property xil_pn:name="Enable Suspend/Wake Global Set/Reset spartan6" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Encrypt Bitstream spartan6" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Encrypt Key Select spartan6" xil_pn:value="BBRAM" xil_pn:valueState="default"/>
<property xil_pn:name="Equivalent Register Removal Map" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Equivalent Register Removal XST" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Essential Bits" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Evaluation Development Board" xil_pn:value="None Specified" xil_pn:valueState="default"/>
<property xil_pn:name="Exclude Compilation of Deprecated EDK Cores" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Exclude Compilation of EDK Sub-Libraries" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Extra Cost Tables Map" xil_pn:value="0" xil_pn:valueState="default"/>
<property xil_pn:name="Extra Effort (Highest PAR level only)" xil_pn:value="None" xil_pn:valueState="default"/>
<property xil_pn:name="FPGA Start-Up Clock" xil_pn:value="CCLK" xil_pn:valueState="default"/>
<property xil_pn:name="FSM Encoding Algorithm" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="FSM Style" xil_pn:value="LUT" xil_pn:valueState="default"/>
<property xil_pn:name="Filter Files From Compile Order" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Flatten Output Netlist" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Functional Model Target Language ArchWiz" xil_pn:value="VHDL" xil_pn:valueState="default"/>
<property xil_pn:name="Functional Model Target Language Coregen" xil_pn:value="VHDL" xil_pn:valueState="default"/>
<property xil_pn:name="Functional Model Target Language Schematic" xil_pn:value="VHDL" xil_pn:valueState="default"/>
<property xil_pn:name="GTS Cycle During Suspend/Wakeup Sequence spartan6" xil_pn:value="4" xil_pn:valueState="default"/>
<property xil_pn:name="GWE Cycle During Suspend/Wakeup Sequence spartan6" xil_pn:value="5" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Architecture Only (No Entity Declaration)" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Asynchronous Delay Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Clock Region Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Constraints Interaction Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Constraints Interaction Report Post Trace" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Datasheet Section" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Datasheet Section Post Trace" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Detailed MAP Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Multiple Hierarchical Netlist Files" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Post-Place &amp; Route Power Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Post-Place &amp; Route Simulation Model" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate RTL Schematic" xil_pn:value="Yes" xil_pn:valueState="default"/>
<property xil_pn:name="Generate SAIF File for Power Optimization/Estimation Par" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Testbench File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Timegroups Section" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generate Timegroups Section Post Trace" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generics, Parameters" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Global Optimization Goal" xil_pn:value="AllClockNets" xil_pn:valueState="default"/>
<property xil_pn:name="Global Optimization map spartan6" xil_pn:value="Off" xil_pn:valueState="default"/>
<property xil_pn:name="Global Set/Reset Port Name" xil_pn:value="GSR_PORT" xil_pn:valueState="default"/>
<property xil_pn:name="Global Tristate Port Name" xil_pn:value="GTS_PORT" xil_pn:valueState="default"/>
<property xil_pn:name="Hierarchy Separator" xil_pn:value="/" xil_pn:valueState="default"/>
<property xil_pn:name="ISim UUT Instance Name" xil_pn:value="UUT" xil_pn:valueState="default"/>
<property xil_pn:name="Ignore User Timing Constraints Map" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Ignore User Timing Constraints Par" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Implementation Top" xil_pn:value="Architecture|tb_tdc|behavioral" xil_pn:valueState="non-default"/>
<property xil_pn:name="Implementation Top File" xil_pn:value="../../testbench/spec/tb_tdc.vhd" xil_pn:valueState="non-default"/>
<property xil_pn:name="Implementation Top Instance Path" xil_pn:value="/tb_tdc" xil_pn:valueState="non-default"/>
<property xil_pn:name="Include 'uselib Directive in Verilog File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Include SIMPRIM Models in Verilog File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Include UNISIM Models in Verilog File" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Include sdf_annotate task in Verilog File" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Incremental Compilation" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Insert Buffers to Prevent Pulse Swallowing" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Instantiation Template Target Language Xps" xil_pn:value="VHDL" xil_pn:valueState="default"/>
<property xil_pn:name="JTAG Pin TCK" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="JTAG Pin TDI" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="JTAG Pin TDO" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="JTAG Pin TMS" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Keep Hierarchy" xil_pn:value="No" xil_pn:valueState="default"/>
<property xil_pn:name="LUT Combining Map" xil_pn:value="Off" xil_pn:valueState="default"/>
<property xil_pn:name="LUT Combining Xst" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Language" xil_pn:value="VHDL" xil_pn:valueState="default"/>
<property xil_pn:name="Last Applied Goal" xil_pn:value="Balanced" xil_pn:valueState="default"/>
<property xil_pn:name="Last Applied Strategy" xil_pn:value="Xilinx Default (unlocked)" xil_pn:valueState="default"/>
<property xil_pn:name="Last Unlock Status" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Launch SDK after Export" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Library for Verilog Sources" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Load glbl" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Manual Implementation Compile Order" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Map Slice Logic into Unused Block RAMs" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Mask Pins for Multi-Pin Wake-Up Suspend Mode spartan6" xil_pn:value="0x00" xil_pn:valueState="default"/>
<property xil_pn:name="Max Fanout" xil_pn:value="100000" xil_pn:valueState="default"/>
<property xil_pn:name="Maximum Compression" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Maximum Number of Lines in Report" xil_pn:value="1000" xil_pn:valueState="default"/>
<property xil_pn:name="Maximum Signal Name Length" xil_pn:value="20" xil_pn:valueState="default"/>
<property xil_pn:name="Move First Flip-Flop Stage" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Move Last Flip-Flop Stage" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="MultiBoot: Insert IPROG CMD in the Bitfile spartan6" xil_pn:value="Enable" xil_pn:valueState="default"/>
<property xil_pn:name="MultiBoot: Next Configuration Mode spartan6" xil_pn:value="001" xil_pn:valueState="default"/>
<property xil_pn:name="MultiBoot: Starting Address for Golden Configuration spartan6" xil_pn:value="0x00000000" xil_pn:valueState="default"/>
<property xil_pn:name="MultiBoot: Starting Address for Next Configuration spartan6" xil_pn:value="0x00000000" xil_pn:valueState="default"/>
<property xil_pn:name="MultiBoot: Use New Mode for Next Configuration spartan6" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="MultiBoot: User-Defined Register for Failsafe Scheme spartan6" xil_pn:value="0x0000" xil_pn:valueState="default"/>
<property xil_pn:name="Mux Extraction" xil_pn:value="Yes" xil_pn:valueState="default"/>
<property xil_pn:name="Netlist Hierarchy" xil_pn:value="As Optimized" xil_pn:valueState="default"/>
<property xil_pn:name="Netlist Translation Type" xil_pn:value="Timestamp" xil_pn:valueState="default"/>
<property xil_pn:name="Number of Clock Buffers" xil_pn:value="16" xil_pn:valueState="default"/>
<property xil_pn:name="Number of Paths in Error/Verbose Report" xil_pn:value="3" xil_pn:valueState="default"/>
<property xil_pn:name="Number of Paths in Error/Verbose Report Post Trace" xil_pn:value="3" xil_pn:valueState="default"/>
<property xil_pn:name="Optimization Effort" xil_pn:value="Normal" xil_pn:valueState="default"/>
<property xil_pn:name="Optimization Effort spartan6" xil_pn:value="Normal" xil_pn:valueState="default"/>
<property xil_pn:name="Optimization Goal" xil_pn:value="Speed" xil_pn:valueState="default"/>
<property xil_pn:name="Optimize Instantiated Primitives" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Other Bitgen Command Line Options spartan6" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Compiler Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Compiler Options Fit" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Compiler Options Map" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Compiler Options Par" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Compiler Options Translate" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Compxlib Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Map Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other NETGEN Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Ngdbuild Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Place &amp; Route Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Simulator Commands Behavioral" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Simulator Commands Post-Map" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Simulator Commands Post-Route" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other Simulator Commands Post-Translate" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other XPWR Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Other XST Command Line Options" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Output Extended Identifiers" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Output File Name" xil_pn:value="tb_tdc" xil_pn:valueState="default"/>
<property xil_pn:name="Overwrite Compiled Libraries" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Pack I/O Registers into IOBs" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Pack I/O Registers/Latches into IOBs" xil_pn:value="Off" xil_pn:valueState="default"/>
<property xil_pn:name="Package" xil_pn:value="fgg484" xil_pn:valueState="default"/>
<property xil_pn:name="Perform Advanced Analysis" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Perform Advanced Analysis Post Trace" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Place &amp; Route Effort Level (Overall)" xil_pn:value="High" xil_pn:valueState="default"/>
<property xil_pn:name="Place And Route Mode" xil_pn:value="Normal Place and Route" xil_pn:valueState="default"/>
<property xil_pn:name="Place MultiBoot Settings into Bitstream spartan6" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Placer Effort Level Map" xil_pn:value="High" xil_pn:valueState="default"/>
<property xil_pn:name="Placer Extra Effort Map" xil_pn:value="None" xil_pn:valueState="default"/>
<property xil_pn:name="Port to be used" xil_pn:value="Auto - default" xil_pn:valueState="default"/>
<property xil_pn:name="Post Map Simulation Model Name" xil_pn:value="tb_tdc_map.vhd" xil_pn:valueState="default"/>
<property xil_pn:name="Post Place &amp; Route Simulation Model Name" xil_pn:value="tb_tdc_timesim.vhd" xil_pn:valueState="default"/>
<property xil_pn:name="Post Synthesis Simulation Model Name" xil_pn:value="tb_tdc_synthesis.vhd" xil_pn:valueState="default"/>
<property xil_pn:name="Post Translate Simulation Model Name" xil_pn:value="tb_tdc_translate.vhd" xil_pn:valueState="default"/>
<property xil_pn:name="Power Reduction Map spartan6" xil_pn:value="Off" xil_pn:valueState="default"/>
<property xil_pn:name="Power Reduction Par" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Power Reduction Xst" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Preferred Language" xil_pn:value="VHDL" xil_pn:valueState="non-default"/>
<property xil_pn:name="Produce Verbose Report" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Project Description" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Project Generator" xil_pn:value="ProjNav" xil_pn:valueState="default"/>
<property xil_pn:name="Property Specification in Project File" xil_pn:value="Store all values" xil_pn:valueState="default"/>
<property xil_pn:name="RAM Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="RAM Style" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="ROM Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="ROM Style" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Read Cores" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Reduce Control Sets" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Regenerate Core" xil_pn:value="Under Current Project Setting" xil_pn:valueState="default"/>
<property xil_pn:name="Register Balancing" xil_pn:value="No" xil_pn:valueState="default"/>
<property xil_pn:name="Register Duplication Map" xil_pn:value="Off" xil_pn:valueState="default"/>
<property xil_pn:name="Register Duplication Xst" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Register Ordering spartan6" xil_pn:value="4" xil_pn:valueState="default"/>
<property xil_pn:name="Release Write Enable (Output Events)" xil_pn:value="Default (6)" xil_pn:valueState="default"/>
<property xil_pn:name="Rename Design Instance in Testbench File to" xil_pn:value="UUT" xil_pn:valueState="default"/>
<property xil_pn:name="Rename Top Level Architecture To" xil_pn:value="Structure" xil_pn:valueState="default"/>
<property xil_pn:name="Rename Top Level Entity to" xil_pn:value="tb_tdc" xil_pn:valueState="default"/>
<property xil_pn:name="Rename Top Level Module To" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Report Fastest Path(s) in Each Constraint" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Report Fastest Path(s) in Each Constraint Post Trace" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Report Paths by Endpoint" xil_pn:value="3" xil_pn:valueState="default"/>
<property xil_pn:name="Report Paths by Endpoint Post Trace" xil_pn:value="3" xil_pn:valueState="default"/>
<property xil_pn:name="Report Type" xil_pn:value="Verbose Report" xil_pn:valueState="default"/>
<property xil_pn:name="Report Type Post Trace" xil_pn:value="Verbose Report" xil_pn:valueState="default"/>
<property xil_pn:name="Report Unconstrained Paths" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Report Unconstrained Paths Post Trace" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Reset On Configuration Pulse Width" xil_pn:value="100" xil_pn:valueState="default"/>
<property xil_pn:name="Resource Sharing" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Retain Hierarchy" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Retry Configuration if CRC Error Occurs spartan6" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Run Design Rules Checker (DRC)" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Run for Specified Time" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Run for Specified Time Map" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Run for Specified Time Par" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Run for Specified Time Translate" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Safe Implementation" xil_pn:value="No" xil_pn:valueState="default"/>
<property xil_pn:name="Security" xil_pn:value="Enable Readback and Reconfiguration" xil_pn:valueState="default"/>
<property xil_pn:name="Selected Module Instance Name" xil_pn:value="/tb_tdc" xil_pn:valueState="non-default"/>
<property xil_pn:name="Selected Simulation Root Source Node Behavioral" xil_pn:value="work.tb_tdc" xil_pn:valueState="non-default"/>
<property xil_pn:name="Selected Simulation Root Source Node Post-Map" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Selected Simulation Root Source Node Post-Route" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Selected Simulation Root Source Node Post-Translate" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Selected Simulation Source Node" xil_pn:value="UUT" xil_pn:valueState="default"/>
<property xil_pn:name="Set SPI Configuration Bus Width spartan6" xil_pn:value="1" xil_pn:valueState="default"/>
<property xil_pn:name="Setup External Master Clock Division spartan6" xil_pn:value="1" xil_pn:valueState="default"/>
<property xil_pn:name="Shift Register Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Shift Register Minimum Size spartan6" xil_pn:value="2" xil_pn:valueState="default"/>
<property xil_pn:name="Show All Models" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Simulation Model Target" xil_pn:value="VHDL" xil_pn:valueState="default"/>
<property xil_pn:name="Simulation Run Time ISim" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
<property xil_pn:name="Simulation Run Time Map" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
<property xil_pn:name="Simulation Run Time Par" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
<property xil_pn:name="Simulation Run Time Translate" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
<property xil_pn:name="Simulator" xil_pn:value="ISim (VHDL/Verilog)" xil_pn:valueState="default"/>
<property xil_pn:name="Slice Utilization Ratio" xil_pn:value="100" xil_pn:valueState="default"/>
<property xil_pn:name="Specify 'define Macro Name and Value" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Specify Top Level Instance Names Behavioral" xil_pn:value="work.tb_tdc" xil_pn:valueState="default"/>
<property xil_pn:name="Specify Top Level Instance Names Post-Map" xil_pn:value="Default" xil_pn:valueState="default"/>
<property xil_pn:name="Specify Top Level Instance Names Post-Route" xil_pn:value="Default" xil_pn:valueState="default"/>
<property xil_pn:name="Specify Top Level Instance Names Post-Translate" xil_pn:value="Default" xil_pn:valueState="default"/>
<property xil_pn:name="Speed Grade" xil_pn:value="-3" xil_pn:valueState="default"/>
<property xil_pn:name="Starting Placer Cost Table (1-100) Map spartan6" xil_pn:value="1" xil_pn:valueState="default"/>
<property xil_pn:name="Synthesis Tool" xil_pn:value="XST (VHDL/Verilog)" xil_pn:valueState="default"/>
<property xil_pn:name="Target Simulator" xil_pn:value="Please Specify" xil_pn:valueState="default"/>
<property xil_pn:name="Timing Mode Map" xil_pn:value="Performance Evaluation" xil_pn:valueState="default"/>
<property xil_pn:name="Timing Mode Par" xil_pn:value="Performance Evaluation" xil_pn:valueState="default"/>
<property xil_pn:name="Top-Level Module Name in Output Netlist" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Top-Level Source Type" xil_pn:value="HDL" xil_pn:valueState="default"/>
<property xil_pn:name="Trim Unconnected Signals" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Tristate On Configuration Pulse Width" xil_pn:value="0" xil_pn:valueState="default"/>
<property xil_pn:name="Unused IOB Pins" xil_pn:value="Pull Down" xil_pn:valueState="default"/>
<property xil_pn:name="Use 64-bit PlanAhead on 64-bit Systems" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Use Clock Enable" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Project File Behavioral" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Project File Post-Map" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Project File Post-Route" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Project File Post-Translate" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Simulation Command File Behavioral" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Simulation Command File Map" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Simulation Command File Par" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Simulation Command File Translate" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Waveform Configuration File Behav" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Waveform Configuration File Map" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Waveform Configuration File Par" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Custom Waveform Configuration File Translate" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use DSP Block spartan6" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Use LOC Constraints" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Use RLOC Constraints" xil_pn:value="Yes" xil_pn:valueState="default"/>
<property xil_pn:name="Use Smart Guide" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Use Synchronous Reset" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Use Synchronous Set" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Use Synthesis Constraints File" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="User Browsed Strategy Files" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="UserID Code (8 Digit Hexadecimal)" xil_pn:value="0xFFFFFFFF" xil_pn:valueState="default"/>
<property xil_pn:name="VCCAUX Voltage Level spartan6" xil_pn:value="2.5V" xil_pn:valueState="default"/>
<property xil_pn:name="VHDL Source Analysis Standard" xil_pn:value="VHDL-93" xil_pn:valueState="default"/>
<property xil_pn:name="Value Range Check" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Verilog 2001 Xst" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Verilog Macros" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Wait for DCM and PLL Lock (Output Events) spartan6" xil_pn:value="Default (NoWait)" xil_pn:valueState="default"/>
<property xil_pn:name="Wakeup Clock spartan6" xil_pn:value="Startup Clock" xil_pn:valueState="default"/>
<property xil_pn:name="Watchdog Timer Value spartan6" xil_pn:value="0xFFFF" xil_pn:valueState="default"/>
<property xil_pn:name="Working Directory" xil_pn:value="." xil_pn:valueState="non-default"/>
<property xil_pn:name="Write Timing Constraints" xil_pn:value="false" xil_pn:valueState="default"/>
<!-- -->
<!-- The following properties are for internal use only. These should not be modified.-->
<!-- -->
<property xil_pn:name="PROP_BehavioralSimTop" xil_pn:value="Architecture|tb_tdc|behavioral" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_DesignName" xil_pn:value="newfmctdc" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_DevFamilyPMName" xil_pn:value="spartan6" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_FPGAConfiguration" xil_pn:value="FPGAConfiguration" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_PostFitSimTop" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_PostMapSimTop" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_PostParSimTop" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_PostSynthSimTop" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_PostXlateSimTop" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_PreSynthesis" xil_pn:value="PreSynthesis" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_intProjectCreationTimestamp" xil_pn:value="2012-02-23T10:13:31" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_intWbtProjectID" xil_pn:value="243C892F40BA46AEB0B289A48EEA2D35" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_intWorkingDirLocWRTProjDir" xil_pn:value="Same" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_intWorkingDirUsed" xil_pn:value="No" xil_pn:valueState="non-default"/>
</properties>
<bindings/>
<libraries/>
<autoManagedFiles>
<!-- The following files are identified by `include statements in verilog -->
<!-- source files and are automatically managed by Project Navigator. -->
<!-- -->
<!-- Do not hand-edit this section, as it will be overwritten when the -->
<!-- project is analyzed based on files automatically identified as -->
<!-- include files. -->
</autoManagedFiles>
</project>
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
-- Created by : G. Penacoba
-- Creation Date: June 2011
-- Description: reproduced roughly the functionality of the acam:
-- handles the FIFO and the data communication handshake
-- Modified by:
-- Modification Date:
-- Modification consisted on:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity acam_data_model is
port(
start01_i : in std_logic_vector(16 downto 0);
timestamp_for_fifo1 : in std_logic_vector(27 downto 0);
timestamp_for_fifo2 : in std_logic_vector(27 downto 0);
address_i : in std_logic_vector(3 downto 0);
cs_n_i : in std_logic;
oe_n_i : in std_logic;
rd_n_i : in std_logic;
wr_n_i : in std_logic;
data_bus_o : out std_logic_vector(27 downto 0);
ef1_o : out std_logic;
ef2_o : out std_logic;
lf1_o : out std_logic;
lf2_o : out std_logic
);
end acam_data_model;
architecture behavioral of acam_data_model is
component acam_fifo_model
generic(
size : integer;
full_threshold : integer;
empty_threshold : integer
);
port(
data_input : in std_logic_vector(27 downto 0);
rd_fifo : in std_logic;
data_output : out std_logic_vector(27 downto 0);
empty : out std_logic;
full : out std_logic
);
end component;
constant ts_ad : time:= 2000 ps; -- minimum address setup time
constant th_ad : time:= 0 ps; -- minimum address hold time
constant tpw_rl : time:= 6000 ps; -- minimum read low time
constant tpw_rh : time:= 6000 ps; -- minimum read high time
constant tpw_wl : time:= 6000 ps; -- minimum write low time
constant tpw_wh : time:= 6000 ps; -- minimum write high time
constant tv_dr : time:= 11800 ps; -- maximum read data valid time
constant th_dr : time:= 4000 ps; -- minimum read data hold time
constant ts_dw : time:= 5000 ps; -- minimum write data setup time
constant th_dw : time:= 4000 ps; -- minimum write data hold time
constant ts_csn : time:= 0 ps; -- minimum chip select setup time
constant th_csn : time:= 0 ps; -- minimum chip select hold time
constant ts_ef : time:= 11800 ps; -- maximum empty flag set time
signal address : std_logic_vector(3 downto 0);
signal cs_n : std_logic;
signal oe_n : std_logic;
signal rd_n : std_logic;
signal wr_n : std_logic;
signal data_bus : std_logic_vector(27 downto 0):= (others =>'Z');
signal ef1 : std_logic;
signal ef2 : std_logic;
signal lf1 : std_logic;
signal lf2 : std_logic;
signal address_change_time : time:= 0 ps;
signal data_change_time : time:= 0 ps;
signal cs_falling_time : time:= 0 ps;
signal cs_rising_time : time:= 0 ps;
signal rd_falling_time : time:= 0 ps;
signal rd_rising_time : time:= 0 ps;
signal wr_falling_time : time:= 0 ps;
signal wr_rising_time : time:= 0 ps;
signal start01 : std_logic_vector(16 downto 0);
signal data_for_bus : std_logic_vector(27 downto 0);
signal data_from_fifo1 : std_logic_vector(27 downto 0);
signal data_from_fifo2 : std_logic_vector(27 downto 0);
signal rd_fifo1 : std_logic;
signal rd_fifo2 : std_logic;
begin
read: process
begin
wait until rd_n ='0';
if cs_n ='0' then
wait for tv_dr;
data_bus <= data_for_bus;
end if;
wait until rd_n ='1';
if cs_n ='0' then
wait for th_dr;
data_bus <= (others =>'Z');
end if;
end process;
data_mux: process(address, data_from_fifo1, data_from_fifo2, start01, rd_n, cs_n)
begin
case address is
when x"8" =>
data_for_bus <= data_from_fifo1;
if rd_n ='0' and cs_n ='0' then
rd_fifo1 <= '1';
rd_fifo2 <= '0';
else
rd_fifo1 <= '0';
rd_fifo2 <= '0';
end if;
when x"9" =>
data_for_bus <= data_from_fifo2;
if rd_n ='0' and cs_n ='0' then
rd_fifo1 <= '0';
rd_fifo2 <= '1';
else
rd_fifo1 <= '0';
rd_fifo2 <= '0';
end if;
when x"A" =>
data_for_bus <= "00000000000" & start01;
rd_fifo1 <= '0';
rd_fifo2 <= '0';
when others =>
data_for_bus <= (others => 'Z');
rd_fifo1 <= '0';
rd_fifo2 <= '0';
end case;
end process;
interface_fifo1: acam_fifo_model
generic map(
size => 256,
full_threshold => 10,
empty_threshold => 1
)
port map(
data_input => timestamp_for_fifo1,
rd_fifo => rd_fifo1,
data_output => data_from_fifo1,
empty => ef1,
full => lf1
);
interface_fifo2: acam_fifo_model
generic map(
size => 256,
full_threshold => 10,
empty_threshold => 1
)
port map(
data_input => timestamp_for_fifo2,
rd_fifo => rd_fifo2,
data_output => data_from_fifo2,
empty => ef2,
full => lf2
);
start01 <= start01_i;
address <= address_i;
cs_n <= cs_n_i;
oe_n <= oe_n_i;
rd_n <= rd_n_i;
wr_n <= wr_n_i;
data_bus_o <= data_bus;
ef1_o <= ef1;
ef2_o <= ef2;
lf1_o <= lf1;
lf2_o <= lf2;
address_timing: process(address)
begin
address_change_time <= now;
end process;
data_timing: process(address)
begin
data_change_time <= now;
end process;
read_timing: process(rd_n)
begin
if falling_edge(rd_n) then
rd_falling_time <= now;
end if;
if rising_edge(rd_n) then
rd_rising_time <= now;
end if;
end process;
write_timing: process(wr_n)
begin
if falling_edge(wr_n) then
wr_falling_time <= now;
end if;
if rising_edge(wr_n) then
wr_rising_time <= now;
end if;
end process;
chip_select_timing: process(cs_n)
begin
if falling_edge(cs_n) then
cs_falling_time <= now;
end if;
if rising_edge(cs_n) then
cs_rising_time <= now;
end if;
end process;
reporting_read_times: process(rd_falling_time, rd_rising_time)
begin
if rd_rising_time - rd_falling_time < tpw_rl
and rd_rising_time - rd_falling_time > 0 ps
and now /= 0 ps then
report LF & " #### Timing error in read signal when reading: minimum low time not respected" & LF
severity warning;
end if;
if rd_falling_time - rd_rising_time < tpw_rh
and rd_falling_time - rd_rising_time > 0 ps
and now /= 0 ps then
report LF & " #### Timing error in read signal when reading: minimum high time not respected" & LF
severity warning;
end if;
end process;
reporting_write_times: process(wr_falling_time, wr_rising_time)
begin
if wr_rising_time - wr_falling_time < tpw_wl
and wr_rising_time - wr_falling_time > 0 ps
and now /= 0 ps then
report LF & " #### Timing error in read signal when writing: minimum low time not respected" & LF
severity warning;
end if;
if wr_falling_time - wr_rising_time < tpw_wh
and wr_falling_time - wr_rising_time > 0 ps
and now /= 0 ps then
report " #### Timing error in read signal when writing: minimum high time not respected" & LF
severity warning;
end if;
end process;
reporting_setup_rd: process(rd_falling_time)
begin
if rd_falling_time - address_change_time < ts_ad and now /= 0 ps then
report LF & " #### Timing error in address bus when reading: minimum setup time not respected" & LF
severity warning;
end if;
if rd_falling_time - cs_falling_time < ts_csn and now /= 0 ps then
report LF & " #### Timing error in chip select signal when reading: minimum setup time not respected" & LF
severity warning;
end if;
end process;
reporting_setup_wr: process(wr_falling_time)
begin
if wr_falling_time - address_change_time < ts_ad and now /= 0 ps then
report LF & " #### Timing error in address bus when writing: minimum setup time not respected" & LF
severity warning;
end if;
if wr_falling_time - cs_falling_time < ts_csn then
report LF & " #### Timing error in chip select signal when writing: minimum setup time not respected" & LF
severity warning;
end if;
end process;
reporting_hold_ad: process(address_change_time)
begin
if address_change_time - rd_rising_time < th_ad and now /= 0 ps then
report LF & " #### Timing error in address bus when reading: minimum hold time not respected" & LF
severity warning;
end if;
if address_change_time - wr_rising_time < th_ad and now /= 0 ps then
report LF & " #### Timing error in address bus when writing: minimum hold time not respected" & LF
severity warning;
end if;
end process;
reporting_hold_cs: process(cs_rising_time)
begin
if cs_rising_time - rd_rising_time < th_csn and now /= 0 ps then
report LF & " #### Timing error in chip select signal when reading: minimum hold time not respected" & LF
severity warning;
end if;
if cs_rising_time - wr_rising_time < th_csn and now /= 0 ps then
report LF & " #### Timing error in chip select signal when writing: minimum hold time not respected" & LF
severity warning;
end if;
end process;
reporting_data_setup_wr: process(wr_rising_time)
begin
if wr_rising_time - data_change_time < ts_dw and now /= 0 ps then
report LF & " #### Timing error in data bus when writing: minimum setup time not respected" & LF
severity warning;
end if;
end process;
reporting_data_hold_wr: process(data_change_time)
begin
if data_change_time - wr_rising_time < th_dw and now /= 0 ps then
report LF & " #### Timing error in data bus when writing: minimum hold time not respected" & LF
severity warning;
end if;
end process;
end behavioral;
-- Created by : G. Penacoba
-- Creation Date: June 2011
-- Description: reproduces roughly the functionality of the acam:
-- handles the FIFO and the data communication handshake
-- Modified by:
-- Modification Date:
-- Modification consisted on:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity acam_fifo_model is
generic(
size : integer;
full_threshold : integer;
empty_threshold : integer
);
port(
data_input : in std_logic_vector(27 downto 0);
rd_fifo : in std_logic;
data_output : out std_logic_vector(27 downto 0);
empty : out std_logic;
full : out std_logic
);
end acam_fifo_model;
architecture behavioral of acam_fifo_model is
constant ts_ef : time:= 11800 ps; -- maximum empty flag set time
subtype index is natural range size-1 downto 0;
subtype memory_cell is std_logic_vector(27 downto 0);
type memory_block is array (natural range size-1 downto 0) of memory_cell;
signal fifo : memory_block;
signal wr_pointer : index:= 0;
signal rd_pointer : index:= 0;
signal level : index:= 0;
begin
writing: process(data_input)
begin
if now /= 0 ps then
fifo(wr_pointer) <= data_input;
if wr_pointer = size-1 then
wr_pointer <= 0;
else
wr_pointer <= wr_pointer + 1;
end if;
end if;
end process;
reading: process(rd_fifo)
begin
if rising_edge(rd_fifo) then
data_output <= fifo(rd_pointer);
if rd_pointer = size-1 then
rd_pointer <= 0 after ts_ef;
else
rd_pointer <= rd_pointer + 1 after ts_ef;
end if;
end if;
-- if falling_edge(rd_fifo) then
-- if rd_pointer = size-1 then
-- rd_pointer <= 0;
-- else
-- rd_pointer <= rd_pointer + 1;
-- end if;
-- end if;
end process;
flags: process(level)
begin
if level > full_threshold then
full <= '1';
else
full <= '0';
end if;
if level < empty_threshold then
empty <= '1';
else
empty <= '0';
end if;
end process;
filling_level: process(rd_pointer, wr_pointer)
begin
if wr_pointer >= rd_pointer then
level <= wr_pointer - rd_pointer;
else
level <= wr_pointer + 256 - rd_pointer;
end if;
end process;
-- process(level)
-- begin
-- report " filling level " & integer'image(level) & LF &
-- " rd_pointer " & integer'image(rd_pointer) & LF &
-- " wr_pointer " & integer'image(wr_pointer) & LF;
-- end process;
corruption_reporting_reading: process(rd_pointer)
begin
if now /= 0 ps then
if rd_pointer = wr_pointer then
report LF & " #### Interface FIFO is empty: no further reading should be performed" & LF
severity warning;
end if;
end if;
end process;
corruption_reporting_writing: process(wr_pointer)
begin
if now /= 0 ps then
if rd_pointer = wr_pointer then
report LF & " #### Interface FIFO is full: no further writing should be performed" & LF
severity warning;
end if;
end if;
end process;
end behavioral;
-- Creation Date: May 2011
-- Description: reproduced roughly the functionality of the acam:
-- Modified by:
-- Modification Date:
-- Modification consisted on:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity acam_model is
generic(
start_retrig_period : time:= 3200 ns;
refclk_period : time:= 32 ns
);
port(
tstart_i : in std_logic;
tstop1_i : in std_logic;
tstop2_i : in std_logic;
tstop3_i : in std_logic;
tstop4_i : in std_logic;
tstop5_i : in std_logic;
startdis_i : in std_logic;
stopdis_i : in std_logic;
int_flag_o : out std_logic;
err_flag_o : out std_logic;
address_i : in std_logic_vector(3 downto 0);
cs_n_i : in std_logic;
oe_n_i : in std_logic;
rd_n_i : in std_logic;
wr_n_i : in std_logic;
data_bus_io : inout std_logic_vector(27 downto 0);
ef1_o : out std_logic;
ef2_o : out std_logic;
lf1_o : out std_logic;
lf2_o : out std_logic
);
end acam_model;
architecture behavioral of acam_model is
component acam_timing_model
generic(
refclk_period : time:= 32 ns;
start_retrig_period : time:= 3200 ns
);
port(
tstart_i : in std_logic;
tstop1_i : in std_logic;
tstop2_i : in std_logic;
tstop3_i : in std_logic;
tstop4_i : in std_logic;
tstop5_i : in std_logic;
startdis_i : in std_logic;
stopdis_i : in std_logic;
err_flag_o : out std_logic;
int_flag_o : out std_logic;
start01_o : out std_logic_vector(16 downto 0);
timestamp_for_fifo1 : out std_logic_vector(27 downto 0);
timestamp_for_fifo2 : out std_logic_vector(27 downto 0)
);
end component;
component acam_data_model
port(
start01_i : in std_logic_vector(16 downto 0);
timestamp_for_fifo1 : in std_logic_vector(27 downto 0);
timestamp_for_fifo2 : in std_logic_vector(27 downto 0);
address_i : in std_logic_vector(3 downto 0);
cs_n_i : in std_logic;
oe_n_i : in std_logic;
rd_n_i : in std_logic;
wr_n_i : in std_logic;
data_bus_o : out std_logic_vector(27 downto 0);
ef1_o : out std_logic;
ef2_o : out std_logic;
lf1_o : out std_logic;
lf2_o : out std_logic
);
end component;
signal timestamp_for_fifo1 : std_logic_vector(27 downto 0);
signal timestamp_for_fifo2 : std_logic_vector(27 downto 0);
signal start01 : std_logic_vector(16 downto 0);
begin
timing_block: acam_timing_model
generic map(
refclk_period => refclk_period,
start_retrig_period => start_retrig_period
)
port map(
tstart_i => tstart_i,
tstop1_i => tstop1_i,
tstop2_i => tstop2_i,
tstop3_i => tstop3_i,
tstop4_i => tstop4_i,
tstop5_i => tstop5_i,
startdis_i => startdis_i,
stopdis_i => stopdis_i,
err_flag_o => err_flag_o,
int_flag_o => int_flag_o,
start01_o => start01,
timestamp_for_fifo1 => timestamp_for_fifo1,
timestamp_for_fifo2 => timestamp_for_fifo2
);
data_block: acam_data_model
port map(
start01_i => start01,
timestamp_for_fifo1 => timestamp_for_fifo1,
timestamp_for_fifo2 => timestamp_for_fifo2,
address_i => address_i,
cs_n_i => cs_n_i,
oe_n_i => oe_n_i,
rd_n_i => rd_n_i,
wr_n_i => wr_n_i,
data_bus_o => data_bus_io,
ef1_o => ef1_o,
ef2_o => ef2_o,
lf1_o => lf1_o,
lf2_o => lf2_o
);
end behavioral;
-- Created by : G. Penacoba
-- Creation Date: May 2011
-- Description: reproduced roughly the functionality of the acam:
-- measures the time between input pulses.
-- Modified by:
-- Modification Date:
-- Modification consisted on:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity acam_timing_model is
generic(
refclk_period : time:= 32 ns;
start_retrig_period : time:= 3200 ns
);
port(
tstart_i : in std_logic;
tstop1_i : in std_logic;
tstop2_i : in std_logic;
tstop3_i : in std_logic;
tstop4_i : in std_logic;
tstop5_i : in std_logic;
startdis_i : in std_logic;
stopdis_i : in std_logic;
err_flag_o : out std_logic;
int_flag_o : out std_logic;
start01_o : out std_logic_vector(16 downto 0);
timestamp_for_fifo1 : out std_logic_vector(27 downto 0);
timestamp_for_fifo2 : out std_logic_vector(27 downto 0)
);
end acam_timing_model;
architecture behavioral of acam_timing_model is
constant resolution : time:= 81 ps;
signal tstart : std_logic;
signal tstop1 : std_logic;
signal tstop2 : std_logic;
signal tstop3 : std_logic;
signal tstop4 : std_logic;
signal tstop5 : std_logic;
signal startdis : std_logic;
signal stopdis : std_logic;
signal intflag : std_logic;
signal start01_reg : std_logic_vector(16 downto 0);
signal start01 : time:= 0 ps;
signal start_trig : time:= 0 ps;
signal stop1_trig : time:= 0 ps;
signal stop2_trig : time:= 0 ps;
signal stop3_trig : time:= 0 ps;
signal stop4_trig : time:= 0 ps;
signal stop5_trig : time:= 0 ps;
signal stop1 : time:= 0 ps;
signal stop2 : time:= 0 ps;
signal stop3 : time:= 0 ps;
signal stop4 : time:= 0 ps;
signal stop5 : time:= 0 ps;
signal start_nb1 : integer:=0;
signal start_nb2 : integer:=0;
signal start_nb3 : integer:=0;
signal start_nb4 : integer:=0;
signal start_nb5 : integer:=0;
signal start_retrig_nb : integer:=0;
signal start_retrig_p : std_logic;
begin
listening: process (tstart, tstop1, tstop2, tstop3, tstop4, tstop5)
begin
if rising_edge(tstart) then
if startdis ='0' then
start_trig <= now;
end if;
end if;
if rising_edge(tstop1) then
if stopdis ='0' then
stop1_trig <= now;
end if;
end if;
if rising_edge(tstop2) then
if stopdis ='0' then
stop2_trig <= now;
end if;
end if;
if rising_edge(tstop3) then
if stopdis ='0' then
stop3_trig <= now;
end if;
end if;
if rising_edge(tstop4) then
if stopdis ='0' then
stop4_trig <= now;
end if;
end if;
if rising_edge(tstop5) then
if stopdis ='0' then
stop5_trig <= now;
end if;
end if;
end process;
measuring1: process(stop1_trig)
begin
if start_retrig_nb > 1 then
stop1 <= (stop1_trig-start_trig-start01)-((start_retrig_nb-1)*start_retrig_period);
elsif start_retrig_nb = 1 then
stop1 <= (stop1_trig-start_trig-start01);
else
stop1 <= (stop1_trig-start_trig);
end if;
start_nb1 <= start_retrig_nb mod 256;
end process;
measuring2: process(stop2_trig)
begin
if start_retrig_nb > 1 then
stop2 <= (stop2_trig-start_trig-start01)-((start_retrig_nb-1)*start_retrig_period);
elsif start_retrig_nb = 1 then
stop2 <= (stop2_trig-start_trig-start01);
else
stop2 <= (stop2_trig-start_trig);
end if;
start_nb2 <= start_retrig_nb mod 256;
end process;
measuring3: process(stop3_trig)
begin
if start_retrig_nb > 1 then
stop3 <= (stop3_trig-start_trig-start01)-((start_retrig_nb-1)*start_retrig_period);
elsif start_retrig_nb = 1 then
stop3 <= (stop3_trig-start_trig-start01);
else
stop3 <= (stop3_trig-start_trig);
end if;
start_nb3 <= start_retrig_nb mod 256;
end process;
measuring4: process(stop4_trig)
begin
if start_retrig_nb > 1 then
stop4 <= (stop4_trig-start_trig-start01)-((start_retrig_nb-1)*start_retrig_period);
elsif start_retrig_nb = 1 then
stop4 <= (stop4_trig-start_trig-start01);
else
stop4 <= (stop4_trig-start_trig);
end if;
start_nb4 <= start_retrig_nb mod 256;
end process;
measuring5: process(stop5_trig)
begin
if start_retrig_nb > 1 then
stop5 <= (stop5_trig-start_trig-start01)-((start_retrig_nb-1)*start_retrig_period);
elsif start_retrig_nb = 1 then
stop5 <= (stop5_trig-start_trig-start01);
else
stop5 <= (stop5_trig-start_trig);
end if;
start_nb5 <= start_retrig_nb mod 256;
end process;
measuring_start01: process(start_retrig_p)
begin
if rising_edge(start_retrig_p) then
if start_retrig_nb = 0 then
start01 <= now - start_trig;
end if;
end if;
end process;
writing_fifo1: process (tstop1, tstop2, tstop3, tstop4)
begin
if falling_edge(tstop1) then
timestamp_for_fifo1(27 downto 26) <= "00";
timestamp_for_fifo1(25 downto 18) <= std_logic_vector(to_unsigned(start_nb1,8));
timestamp_for_fifo1(17) <= '1';
timestamp_for_fifo1(16 downto 0) <= std_logic_vector(to_unsigned(stop1/resolution,17));
start01_reg <= std_logic_vector(to_unsigned(start01/resolution,17));
report " Timestamp for interface FIFO 1:" & LF &
"===============================" & LF &
"Channel 1" & LF &
"Start number: " & integer'image(start_nb1) & LF &
"Time Interval: " & integer'image(stop1/resolution) & LF &
"Start01: " & integer'image(start01/resolution) & LF;
end if;
if falling_edge(tstop2) then
timestamp_for_fifo1(27 downto 26) <= "01";
timestamp_for_fifo1(25 downto 18) <= std_logic_vector(to_unsigned(start_nb2,8));
timestamp_for_fifo1(17) <= '1';
timestamp_for_fifo1(16 downto 0) <= std_logic_vector(to_unsigned(stop2/resolution,17));
start01_reg <= std_logic_vector(to_unsigned(start01/resolution,17));
report " Timestamp for interface FIFO 1:" & LF &
"===============================" & LF &
"Channel 2" & LF &
"Start number: " & integer'image(start_nb2) & LF &
"Time Interval: " & integer'image(stop2/resolution) & LF &
"Start01: " & integer'image(start01/resolution) & LF;
end if;
if falling_edge(tstop3) then
timestamp_for_fifo1(27 downto 26) <= "10";
timestamp_for_fifo1(25 downto 18) <= std_logic_vector(to_unsigned(start_nb3,8));
timestamp_for_fifo1(17) <= '1';
timestamp_for_fifo1(16 downto 0) <= std_logic_vector(to_unsigned(stop3/resolution,17));
start01_reg <= std_logic_vector(to_unsigned(start01/resolution,17));
report " Timestamp for interface FIFO 1:" & LF &
"===============================" & LF &
"Channel 3" & LF &
"Start number: " & integer'image(start_nb3) & LF &
"Time Interval: " & integer'image(stop3/resolution) & LF &
"Start01: " & integer'image(start01/resolution) & LF;
end if;
if falling_edge(tstop4) then
timestamp_for_fifo1(27 downto 26) <= "11";
timestamp_for_fifo1(25 downto 18) <= std_logic_vector(to_unsigned(start_nb4,8));
timestamp_for_fifo1(17) <= '1';
timestamp_for_fifo1(16 downto 0) <= std_logic_vector(to_unsigned(stop4/resolution,17));
start01_reg <= std_logic_vector(to_unsigned(start01/resolution,17));
report " Timestamp for interface FIFO 1:" & LF &
"===============================" & LF &
"Channel 4" & LF &
"Start number: " & integer'image(start_nb4) & LF &
"Time Interval: " & integer'image(stop4/resolution) & LF &
"Start01: " & integer'image(start01/resolution) & LF;
end if;
end process;
writing_fifo2: process (tstop5)
begin
if falling_edge(tstop5) then
timestamp_for_fifo2(27 downto 26) <= "00";
timestamp_for_fifo2(25 downto 18) <= std_logic_vector(to_unsigned(start_nb5,8));
timestamp_for_fifo2(17) <= '1';
timestamp_for_fifo2(16 downto 0) <= std_logic_vector(to_unsigned(stop5/resolution,17));
start01_reg <= std_logic_vector(to_unsigned(start01/resolution,17));
report " Timestamp for interface FIFO 2:" & LF &
"===============================" & LF &
"Channel 5" & LF &
"Start number: " & integer'image(start_nb5) & LF &
"Time Interval: " & integer'image(stop5/resolution) & LF &
"Start01: " & integer'image(start01/resolution) & LF;
end if;
end process;
start_retrigger_pulses: process
begin
start_retrig_p <= '0' after 333 ps;
wait for start_retrig_period/4;
start_retrig_p <= '1' after 333 ps;
wait for start_retrig_period/4;
start_retrig_p <= '0' after 333 ps;
wait for start_retrig_period/2;
end process;
start_nb_counter: process(tstart, start_retrig_p)
begin
if rising_edge(tstart) then
start_retrig_nb <= 0;
elsif rising_edge(start_retrig_p) then
start_retrig_nb <= start_retrig_nb + 1;
end if;
end process;
interrupt_flag: process(start_retrig_nb)
begin
if (start_retrig_nb mod 256) > 127 then
intflag <= '1';
else
intflag <= '0';
end if;
end process;
tstart <= tstart_i;
tstop1 <= tstop1_i;
tstop2 <= tstop2_i;
tstop3 <= tstop3_i;
tstop4 <= tstop4_i;
tstop5 <= tstop5_i;
startdis <= startdis_i;
stopdis <= stopdis_i;
int_flag_o <= intflag;
start01_o <= start01_reg;
end behavioral;
library IEEE;
use IEEE.std_logic_1164.all;
use std.textio.all;
--library std_developerskit;
--use std_developerskit.std_iopak.all;
use work.util.all;
use work.textutil.all;
--==========================================================================--
--
-- *MODULE << cmd_router >>
--
-- *Description : This module routes commands to all command driven modules
-- in the simulation. It instanciates N_FILES instances of
-- cmd_router1 and agregates the outputs to control N_BFM BFMs.
--
-- *History: M. Alford (originaly created 1993 with subsequent updates)
--
--==========================================================================--
--==========================================================================--
-- Operation
--
-- This module opens a text file and passes commands to individual vhdl models.
--
--==========================================================================--
entity cmd_router is
generic( N_BFM : integer := 8;
N_FILES : integer := 3;
FIFO_DEPTH : integer := 16;
STRING_MAX : integer := 256
);
port( CMD : out string(1 to STRING_MAX);
CMD_REQ : out bit_vector(N_BFM-1 downto 0);
CMD_ACK : in bit_vector(N_BFM-1 downto 0);
CMD_ERR : in bit_vector(N_BFM-1 downto 0);
CMD_CLOCK_EN : out boolean
);
end cmd_router;
architecture MODEL of cmd_router is
component cmd_router1
generic( N_BFM : integer := 8;
FIFO_DEPTH : integer := 8;
STRING_MAX : integer := 256;
FILENAME : string :="cmdfile.vec"
);
port( CMD : out STRING(1 to STRING_MAX);
CMD_REQ : out bit_vector(N_BFM-1 downto 0);
CMD_ACK : in bit_vector(N_BFM-1 downto 0);
CMD_ERR : in bit_vector(N_BFM-1 downto 0);
CMD_CLOCK_EN : out boolean;
CMD_DONE_IN : in boolean;
CMD_DONE_OUT : out boolean
);
end component; -- cmd_router1
type FILE_ARRAY is array (natural range <>) of string(1 to 31);
type CMD_ARRAY is array (natural range <>) of string(CMD'range);
type CMD_REQ_ARRAY is array (natural range <>) of bit_vector(N_BFM-1 downto 0);
type integer_vector is array (natural range <>) of integer;
type boolean_vector is array (natural range <>) of boolean;
constant MAX_FILES : integer := 10;
constant FILENAMES : FILE_ARRAY(0 to MAX_FILES-1) := (others=>"data_vectors/atdc_test_cmd0.vec");
-- , "data_vectors/acam_test_cmd1.vec");
-- "data_vectors/acam_test_cmd2.vec", "data_vectors/acam_test_cmd3.vec",
-- "data_vectors/acam_test_cmd4.vec", "data_vectors/acam_test_cmd5.vec",
-- "data_vectors/acam_test_cmd6.vec", "data_vectors/acam_test_cmd7.vec",
-- "data_vectors/acam_test_cmd8.vec", "data_vectors/acam_test_cmd9.vec" );
signal CMDo : CMD_ARRAY(N_FILES-1 downto 0);
signal REQ : bit_vector(CMD_REQ'range);
signal CMD_REQo : CMD_REQ_ARRAY(N_FILES-1 downto 0);
signal CMD_ACKi : CMD_REQ_ARRAY(N_FILES-1 downto 0);
signal CMD_ACK_MASK : CMD_REQ_ARRAY(N_FILES-1 downto 0); -- 1 bit_vector per file to mask CMD_ACK
signal CMD_CLOCK_ENo : boolean_vector(N_FILES-1 downto 0);
signal CMD_ALL_DONE : boolean;
signal CMD_DONE_OUT : boolean_vector(N_FILES-1 downto 0);
function or_reduce(ARG: bit_vector) return bit is
variable result: bit;
begin
result := '0';
for i in ARG'range loop
result := result or ARG(i);
end loop;
return result;
end;
function or_reduce(ARG: boolean_vector) return boolean is
variable result: boolean;
begin
result := FALSE;
for i in ARG'range loop
result := result or ARG(i);
end loop;
return result;
end;
function and_reduce(ARG: boolean_vector) return boolean is
variable result: boolean;
begin
result := TRUE;
for i in ARG'range loop
result := result and ARG(i);
end loop;
return result;
end;
begin
-----------------------------------------------------------------------------
-- Instanciate 1 cmd_router1 per file to be processed
-----------------------------------------------------------------------------
G1 : for i in 0 to N_FILES-1 generate
U1 : cmd_router1
generic map
( N_BFM => N_BFM,
FIFO_DEPTH => FIFO_DEPTH,
STRING_MAX => STRING_MAX,
FILENAME => FILENAMES(i)
)
port map
( CMD => CMDo(i),
CMD_REQ => CMD_REQo(i),
CMD_ACK => CMD_ACKi(i),
CMD_ERR => CMD_ERR,
CMD_CLOCK_EN => CMD_CLOCK_ENo(i),
CMD_DONE_IN => CMD_ALL_DONE,
CMD_DONE_OUT => CMD_DONE_OUT(i)
);
end generate;
-----------------------------------------------------------------------------
-- Multiplex the commands from the cmd_router1 modules
-----------------------------------------------------------------------------
process
variable vDONE : boolean;
begin
CMD <= (others => '0');
wait on CMD_REQo;
vDONE := FALSE;
while(not vDONE) loop
vDONE := TRUE;
for i in 0 to N_FILES-1 loop -- Loop on each file
if(or_reduce(CMD_REQo(i)) = '1') then -- this file wants to do a command
vDONE := FALSE;
--
-- if the ACK is already on from another cmd_router1
--
while(or_reduce(CMD_REQo(i) and CMD_ACK) = '1') loop
wait on CMD_ACK;
end loop;
--
-- Do the request
--
CMD <= CMDo(i);
REQ <= CMD_REQo(i);
--
-- Wait for the ACK
--
wait until(CMD_ACK'event and (or_reduce(CMD_ACK and REQ) = '1'));
--
-- send the ack to the proper file
--
for j in 0 to N_FILES-1 loop
if(i = j) then -- enable this one
CMD_ACK_MASK(j) <= CMD_ACK_MASK(j) or REQ;
else
CMD_ACK_MASK(j) <= CMD_ACK_MASK(j) and not REQ;
end if;
end loop;
--
-- Wait for the request to de-assert
--
while(or_reduce(CMD_REQo(i) and REQ) = '1') loop
wait on CMD_REQo;
end loop;
REQ <= (others => '0');
end if;
end loop;
end loop;
end process;
process(CMD_ACK, CMD_ACK_MASK)
begin
for i in 0 to N_FILES-1 loop -- Loop on each file
CMD_ACKi(i) <= CMD_ACK and CMD_ACK_MASK(i);
end loop;
end process;
CMD_REQ <= REQ;
CMD_ALL_DONE <= and_reduce(CMD_DONE_OUT);
CMD_CLOCK_EN <= CMD_CLOCK_ENo(0);
end MODEL;
library IEEE;
use IEEE.std_logic_1164.all;
use std.textio.all;
--library std_developerskit;
--use std_developerskit.std_iopak.all;
use work.util.all;
use work.textutil.all;
--==========================================================================--
--
-- *MODULE << model1 >>
--
-- *Description : This module routes commands to all command driven modules
-- in the simulation.
--
-- *History: M. Alford (originaly created 1993 with subsequent updates)
--
--==========================================================================--
--==========================================================================--
-- Operation
--
-- This module opens a text file and passes commands to individual vhdl models.
--
--==========================================================================--
entity cmd_router1 is
generic( N_BFM : integer := 8;
FIFO_DEPTH : integer := 8;
STRING_MAX : integer := 256;
FILENAME : string :="cmdfile.vec"
);
port( CMD : out STRING(1 to STRING_MAX);
CMD_REQ : out bit_vector(N_BFM-1 downto 0);
CMD_ACK : in bit_vector(N_BFM-1 downto 0);
CMD_ERR : in bit_vector(N_BFM-1 downto 0);
CMD_CLOCK_EN : out boolean;
CMD_DONE_IN : in boolean;
CMD_DONE_OUT : out boolean
);
end cmd_router1;
architecture MODEL of cmd_router1 is
type STRING_ARRAY is array (FIFO_DEPTH-1 downto 0) of STRING(1 to STRING_MAX);
type FD_ARRAY is array (N_BFM-1 downto 0) of STRING_ARRAY;
type integer_vector is array (natural range <>) of integer;
signal FD : FD_ARRAY;
signal ERR_CNT : integer;
signal PUSH_PTR : integer_vector(N_BFM-1 downto 0);
signal POP_PTR : integer_vector(N_BFM-1 downto 0);
signal SET_CHAN : std_ulogic;
signal POP_INIT : std_ulogic;
signal CMD_REQo : bit_vector(CMD_REQ'range);
signal LINE_NUM : integer;
begin
PUSH_PROCESS : process
file FOUT : text open write_mode is "usc.lst";
file stim_file : text open read_mode is FILENAME;
file out_file : text open write_mode is "STD_OUTPUT";
-------- For VHDL-87
-- file stim_file : text is in FILENAME;
-- file out_file : text is out "STD_OUTPUT";
variable input_line : line;
variable output_line : line;
variable tmp_lout : line;
variable command : string(1 to 8);
variable tmp_str : string(1 to STRING_MAX);
variable input_str : string(1 to STRING_MAX);
variable i : integer;
variable CHANNEL : integer;
variable S_PTR : integer;
variable vLINE_NUM : integer;
variable vPUSH_PTR : integer_vector(N_BFM-1 downto 0);
variable DONE : boolean;
variable EOS : integer;
variable ERR : integer;
begin
-----------------------------------------------------------------------------
-- Main Loop
-----------------------------------------------------------------------------
vLINE_NUM := 0;
PUSH_PTR <= (others => 0);
vPUSH_PTR := (others => 0);
CHANNEL := 0;
CMD_CLOCK_EN <= TRUE;
SET_CHAN <= '0';
CMD_DONE_OUT <= FALSE;
if(POP_INIT /= '1') then
wait until(POP_INIT'event and (POP_INIT = '1'));
end if;
ST_LOOP: while not endfile(stim_file) loop
readline(stim_file, input_line);
S_PTR := 1;
vLINE_NUM := vLINE_NUM + 1;
LINE_NUM <= vLINE_NUM;
-- Copy the line
input_str := (others => ' ');
input_str(1 to 6) := To_Strn(vLINE_NUM, 6);
input_str(7 to 8) := string'(": ");
input_str(9 to input_line'length+8) := string'(input_line.all);
while(input_str(S_PTR) /= ':') loop
S_PTR := S_PTR + 1;
end loop;
S_PTR := S_PTR + 1;
sget_token(input_str, S_PTR, command);
SET_CHAN <= '1';
for j in STRING_MAX downto 1 loop
if(input_str(j) /= ' ') then
EOS := j;
exit;
end if;
end loop;
---------------------------
-- "model" command ?
---------------------------
if(command(1 to 5) = "model") then
sget_int(input_str, S_PTR, i);
write(tmp_lout, FILENAME);
write(tmp_lout, input_str(1 to EOS));
writeline(out_file, tmp_lout);
if((i >= N_BFM) or (i < 0)) then
CHANNEL := N_BFM-1;
write(tmp_lout, string'("ERROR: Invalid Channel "));
write(tmp_lout, i);
writeline(out_file, tmp_lout);
else
CHANNEL := i;
end if;
---------------------------
-- "sync" command ?
---------------------------
elsif(command(1 to 4) = "sync") then
loop
DONE := TRUE;
for i in PUSH_PTR'reverse_range loop
if((vPUSH_PTR(i) /= POP_PTR(i)) or (CMD_ACK(i) /= '0')) then
DONE := FALSE;
end if;
end loop;
if(DONE) then
exit;
end if;
wait on POP_PTR, CMD_ACK;
end loop;
write(tmp_lout, FILENAME);
write(tmp_lout, input_str(1 to EOS));
writeline(out_file, tmp_lout);
---------------------------
-- "gsync" and "ckoff" command ?
---------------------------
elsif((command(1 to 5) = "gsync") or (command(1 to 5) = "ckoff")) then
write(tmp_lout, FILENAME);
write(tmp_lout, string'(": entering the gsync command"));
writeline(out_file, tmp_lout);
loop
DONE := TRUE;
for i in PUSH_PTR'reverse_range loop
if((vPUSH_PTR(i) /= POP_PTR(i)) or (CMD_ACK(i) /= '0')) then
DONE := FALSE;
end if;
end loop;
if(DONE) then
exit;
end if;
wait on POP_PTR, CMD_ACK;
end loop;
CMD_DONE_OUT <= TRUE;
-- wait for the external CMD_DONE_IN to be done
while (not CMD_DONE_IN) loop
wait on CMD_DONE_IN;
end loop;
CMD_DONE_OUT <= FALSE;
write(tmp_lout, FILENAME);
write(tmp_lout, input_str(1 to EOS));
writeline(out_file, tmp_lout);
if (command(1 to 5) = "ckoff") then
CMD_CLOCK_EN <= FALSE;
end if;
write(tmp_lout, FILENAME);
write(tmp_lout, string'(": gsync command is DONE"));
writeline(out_file, tmp_lout);
--------------------
-- ckon
--------------------
elsif (command(1 to 4) = "ckon") then
CMD_CLOCK_EN <= TRUE;
write(tmp_lout, FILENAME);
write(tmp_lout, input_str(1 to EOS));
writeline(out_file, tmp_lout);
---------------------------
-- put the line in the FIFO
---------------------------
else
FD(CHANNEL)(vPUSH_PTR(CHANNEL)) <= input_str;
vPUSH_PTR(CHANNEL) := vPUSH_PTR(CHANNEL) + 1;
if(vPUSH_PTR(CHANNEL) >= FIFO_DEPTH) then
vPUSH_PTR(CHANNEL) := 0;
end if;
if(vPUSH_PTR(CHANNEL) = POP_PTR(CHANNEL)) then -- The FIFO is full
wait until(POP_PTR'event and (vPUSH_PTR(CHANNEL) /= POP_PTR(CHANNEL)));
end if;
PUSH_PTR(CHANNEL) <= vPUSH_PTR(CHANNEL);
end if;
end loop;
loop
DONE := TRUE;
for i in POP_PTR'reverse_range loop
if((POP_PTR(i) /= vPUSH_PTR(i)) or (CMD_ACK(i) = '1')) then -- FIFO channel not empty
DONE := FALSE;
end if;
end loop;
if(DONE) then
exit;
end if;
wait on CMD_ACK, POP_PTR;
end loop;
CMD_DONE_OUT <= TRUE;
write(output_line, string'("******************************* Test Finished *******************************"));
writeline(out_file, output_line);
write(output_line, string'("* Total Errors for "));
write(output_line, FILENAME);
write(output_line, string'(": "));
write(output_line, err_cnt);
writeline(out_file, output_line);
write(output_line, string'("*****************************************************************************"));
writeline(out_file, output_line);
file_close(stim_file); -- Close File
loop
wait for 100000 us;
end loop;
end process;
-----------------------------------------------------------------------------
-- POP Process
-----------------------------------------------------------------------------
POP_PROCESS : process
variable vPOP_PTR : integer_vector(POP_PTR'range);
variable DONE : boolean;
file out_file : text open write_mode is "STD_OUTPUT";
-------- For VHDL-87
-- file out_file : text is out "STD_OUTPUT";
variable tmp_lout : line;
variable CHAR_PTR : integer;
variable EOS : integer;
begin
CHAR_PTR := 1;
ERR_CNT <= 0;
POP_PTR <= (others => 0);
vPOP_PTR := (others => 0);
CMD_REQo <= (others => '0');
POP_INIT <= '1';
if(SET_CHAN /= '1') then
wait until(SET_CHAN'event and (SET_CHAN = '1'));
end if;
loop
DONE := FALSE;
loop
DONE := TRUE;
for i in POP_PTR'reverse_range loop
if((vPOP_PTR(i) /= PUSH_PTR(i)) and (CMD_ACK(i) = '0')) then -- FIFO channel not empty
CMD <= FD(i)(vPOP_PTR(i));
CMD_REQo(i) <= '1';
for j in STRING_MAX downto 1 loop
if(FD(i)(vPOP_PTR(i))(j) /= ' ') then
EOS := j;
exit;
end if;
end loop;
write(tmp_lout, FILENAME);
write(tmp_lout, FD(i)(vPOP_PTR(i))(1 to EOS));
writeline(out_file, tmp_lout);
if(CMD_ACK(i) /= '1') then
wait until(CMD_ACK'event and (CMD_ACK(i) = '1'));
end if;
CMD_REQo(i) <= '0';
DONE := FALSE;
vPOP_PTR(i) := vPOP_PTR(i) + 1;
if(vPOP_PTR(i) >= FIFO_DEPTH) then
vPOP_PTR(i) := 0;
end if;
POP_PTR(i) <= vPOP_PTR(i);
end if;
end loop;
if(DONE) then
exit;
end if;
end loop;
wait on PUSH_PTR, CMD_ACK;
end loop;
end process;
CMD_REQ <= CMD_REQo;
end MODEL;
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
library IEEE;
use IEEE.std_logic_1164.all;
use std.textio.all;
use work.util.all;
-----------------------------------------------------------------------------
-- *Module : textutil
--
-- *Description : Improved Free-format string and line manipulation
--
-- *History: M. Alford (originaly created 1993 with subsequent updates)
-----------------------------------------------------------------------------
package textutil is
procedure read_token(L : inout line; X : out STRING);
procedure sget_token(S : in string; P : inout integer; X : out STRING);
procedure sget_vector(S : in string; P : inout integer; VEC : out STD_ULOGIC_VECTOR);
procedure sget_vector_64(S : in string; P : inout integer; VEC : out STD_ULOGIC_VECTOR);
procedure sget_int(S : in string; P : inout integer; X : out integer);
function hex_char_to_vector(C : in character) return STD_ULOGIC_VECTOR;
function vector_to_hex_char(V : in STD_ULOGIC_VECTOR) return character;
function is_hex(C : in character) return BOOLEAN;
function hex_char_to_int(C : in character) return integer;
procedure read_vector(L : inout line; VEC : out STD_ULOGIC_VECTOR);
procedure read_int(L : inout line; I : out integer);
procedure write_hex_vector(L : inout line; V : in STD_ULOGIC_VECTOR);
function to_str(constant V: in STD_ULOGIC_VECTOR) return STRING;
function to_str(constant V: in STD_ULOGIC) return STRING;
function to_str(constant val : in INTEGER) return STRING;
function to_strn(constant val : in INTEGER; constant n : in INTEGER) return STRING;
end textutil;
package body textutil is
-----------------------------------------------------------------------------
-- *Module : read_token
--
-- *Description : Skip over spaces then load a token string from a line
-- until either the string is full or the token is finished
-- (i.e. another space). The output string is padded out
-- with blanks at the end if the token length is less then
-- the full string length.
-----------------------------------------------------------------------------
procedure read_token(L : inout line; X : out STRING) is
variable char : character;
begin
if(L'length > 0) then
char := ' ';
while((char = ' ') and (L'length > 0)) loop -- Skip spaces
read(L, char);
end loop;
for i in X'low to X'high loop
X(i) := char;
if(char /= ' ') then
if(L'length > 0) then
read(L, char);
else
char := ' ';
end if;
end if;
end loop;
else
assert false report "Couldn't read a token from file"
severity error;
end if;
end read_token;
-----------------------------------------------------------------------------
-- *Module : sget_token
--
-- *Description : Same as read_token except for strings.
-----------------------------------------------------------------------------
procedure sget_token(S : in string; P : inout integer; X : out STRING) is
variable char : character;
begin
if(S'length > P) then
char := ' ';
while((char = ' ') and (S'length >= P)) loop -- Skip spaces
char := S(P);
P := P + 1;
end loop;
for i in X'low to X'high loop
X(i) := char;
if(char /= ' ') then
if(S'length > P) then
char := S(P);
P := P + 1;
else
char := ' ';
end if;
end if;
end loop;
else
assert false report "Couldn't read a token from a string"
severity error;
end if;
end sget_token;
-----------------------------------------------------------------------------
-- *Module : hex_char_to_vector
--
-- *Description : Convert a hex character to a vector
-----------------------------------------------------------------------------
function hex_char_to_vector(C : in character) return STD_ULOGIC_VECTOR is
variable X : STD_ULOGIC_VECTOR( 3 downto 0);
begin
case C is
when '0' => X := "0000";
when '1' => X := "0001";
when '2' => X := "0010";
when '3' => X := "0011";
when '4' => X := "0100";
when '5' => X := "0101";
when '6' => X := "0110";
when '7' => X := "0111";
when '8' => X := "1000";
when '9' => X := "1001";
when 'A' => X := "1010";
when 'B' => X := "1011";
when 'C' => X := "1100";
when 'D' => X := "1101";
when 'E' => X := "1110";
when 'F' => X := "1111";
when 'a' => X := "1010";
when 'b' => X := "1011";
when 'c' => X := "1100";
when 'd' => X := "1101";
when 'e' => X := "1110";
when 'f' => X := "1111";
when others =>
X := "0000";
assert false report "Invalid Hex Character"
severity error;
end case;
return(X);
end hex_char_to_vector;
-----------------------------------------------------------------------------
-- *Module : vector_to_hex_char
--
-- *Description : Convert a vector to a hex character. Only uses low 4 bits.
-----------------------------------------------------------------------------
function vector_to_hex_char(V : in STD_ULOGIC_VECTOR) return character is
variable C : character;
variable VV : STD_ULOGIC_VECTOR(3 downto 0);
begin
if(V'length < 4) then
VV := To_X01(V(V'low + 3 downto V'low));
else
VV := To_X01(V(V'low + V'length - 1 downto V'low));
end if;
case VV is
when "0000" => C := '0';
when "0001" => C := '1';
when "0010" => C := '2';
when "0011" => C := '3';
when "0100" => C := '4';
when "0101" => C := '5';
when "0110" => C := '6';
when "0111" => C := '7';
when "1000" => C := '8';
when "1001" => C := '9';
when "1010" => C := 'A';
when "1011" => C := 'B';
when "1100" => C := 'C';
when "1101" => C := 'D';
when "1110" => C := 'E';
when "1111" => C := 'F';
when others => C := 'X';
end case;
return(C);
end vector_to_hex_char;
-----------------------------------------------------------------------------
-- *Module : is_hex
--
-- *Description : report if a char is ASCII hex
-----------------------------------------------------------------------------
function is_hex(C : in character) return BOOLEAN is
variable X : boolean;
begin
case C is
when '0' => X := TRUE;
when '1' => X := TRUE;
when '2' => X := TRUE;
when '3' => X := TRUE;
when '4' => X := TRUE;
when '5' => X := TRUE;
when '6' => X := TRUE;
when '7' => X := TRUE;
when '8' => X := TRUE;
when '9' => X := TRUE;
when 'A' => X := TRUE;
when 'B' => X := TRUE;
when 'C' => X := TRUE;
when 'D' => X := TRUE;
when 'E' => X := TRUE;
when 'F' => X := TRUE;
when 'a' => X := TRUE;
when 'b' => X := TRUE;
when 'c' => X := TRUE;
when 'd' => X := TRUE;
when 'e' => X := TRUE;
when 'f' => X := TRUE;
when others =>
X := FALSE;
end case;
return(X);
end is_hex;
-----------------------------------------------------------------------------
-- *Module : hex_char_to_int
--
-- *Description : Convert a hex character to an integer
-----------------------------------------------------------------------------
function hex_char_to_int(C : in character) return integer is
variable X : integer;
begin
case C is
when '0' => X := 0;
when '1' => X := 1;
when '2' => X := 2;
when '3' => X := 3;
when '4' => X := 4;
when '5' => X := 5;
when '6' => X := 6;
when '7' => X := 7;
when '8' => X := 8;
when '9' => X := 9;
when 'A' => X := 10;
when 'B' => X := 11;
when 'C' => X := 12;
when 'D' => X := 13;
when 'E' => X := 14;
when 'F' => X := 15;
when 'a' => X := 10;
when 'b' => X := 11;
when 'c' => X := 12;
when 'd' => X := 13;
when 'e' => X := 14;
when 'f' => X := 15;
when others =>
X := 0;
assert false report "Invalid Hex Character"
severity error;
end case;
return(X);
end hex_char_to_int;
-----------------------------------------------------------------------------
-- *Module : read_vector
--
-- *Description : load a vector from the input line in a free floating format
-----------------------------------------------------------------------------
procedure read_vector(L : inout line; VEC : out STD_ULOGIC_VECTOR) is
variable char : character;
variable base : integer;
variable q : integer;
variable v : STD_ULOGIC_VECTOR(31 downto 0);
begin
if(L'length > 0) then
char := ' ';
while(char = ' ') loop -- Skip spaces
read(L, char);
end loop;
base := 16; -- Hex is the default
if(char = '%') then -- determine base
read(L, char);
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
elsif(char = 'd' or char = 'D') then
base := 10;
else
assert false report "Unsupported Base detected when reading a Vector"
severity error;
end if;
read(L, char);
end if;
q := 0;
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
while(is_hex(char) and not (L'length = 0)) loop
read(L, char);
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
end if;
end loop;
end if;
if(q < 0) then
q := q-2147483648;
V(30 downto 0) := to_vector(q, 31);
V(31) := '1';
else
V(30 downto 0) := to_vector(q, 31);
V(31) := '0';
end if;
VEC := V((VEC'high - VEC'low) downto 0);
else
assert false report "Couldn't read a vector"
severity error;
end if;
end read_vector;
-----------------------------------------------------------------------------
-- *Module : sget_vector
--
-- *Description : Same as sget_vector except for strings
-----------------------------------------------------------------------------
procedure sget_vector(S : in string; P : inout integer; VEC : out STD_ULOGIC_VECTOR) is
variable char : character;
variable base : integer;
variable q : integer;
variable v : STD_ULOGIC_VECTOR(31 downto 0);
begin
while(S(P) = ' ') loop -- Skip spaces
if(P >= S'length) then
P := S'length;
exit;
end if;
P := P + 1;
end loop;
if(S'length > P) then
char := S(P);
if(char = '"') then -- read in as a literal
q := v'high;
v := (others => 'U');
VEC := v(VEC'range);
char := ' ';
P := P + 1;
while((char /= '"') and not (S'length = P)) loop
char := S(P);
P := P + 1;
case char is
when '0' =>
v(q) := '0';
when '1' =>
v(q) := '1';
when 'L' | 'l' =>
v(q) := 'L';
when 'H' | 'h' =>
v(q) := 'H';
when 'Z' | 'z' =>
v(q) := 'Z';
when 'X' | 'x' =>
v(q) := 'X';
when 'U' | 'u' =>
v(q) := 'U';
when others =>
-- char := '"';
exit;
end case;
q := q - 1;
end loop;
if(v'high-q < 2) then -- only a single bit was read
VEC(VEC'low) := v(v'high);
elsif((v'high - q) > VEC'length) then -- too many bits
VEC := v(q+VEC'length downto q+1);
else -- the number of bits read is same or less than required
VEC(v'high-q-1+VEC'low downto VEC'low) := v(v'high downto q+1);
end if;
else
base := 16; -- Hex is the default
if(char = '%') then -- determine base
P := P + 1;
char := S(P);
P := P + 1;
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
elsif(char = 'd' or char = 'D') then
base := 10;
else
assert false report "Unsupported Base detected when reading a Vector"
severity error;
end if;
elsif((char = '0') and ((S(P+1) = 'x') or (S(P+1) = 'X'))) then
P := P + 2;
end if;
q := 0;
char := S(P);
if(is_hex(char)) then
while(is_hex(char) and not (S'length = P)) loop
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
end if;
P := P + 1;
char := S(P);
end loop;
end if;
if(q < 0) then
q := q-2147483648;
V(30 downto 0) := to_vector(q, 31);
V(31) := '1';
else
V(30 downto 0) := to_vector(q, 31);
V(31) := '0';
end if;
VEC := V((VEC'high - VEC'low) downto 0);
end if;
else
assert false report "Couldn't read a vector"
severity error;
V := (others => '0');
VEC := V((VEC'high - VEC'low) downto 0);
end if;
end sget_vector;
-----------------------------------------------------------------------------
-- *Module : sget_vector_64
--
-- *Description : Same as sget_vector except can handle 64 bit quantities and hex or binary base (no base 10)
-----------------------------------------------------------------------------
procedure sget_vector_64(S : in string; P : inout integer; VEC : out STD_ULOGIC_VECTOR) is
variable char : character;
variable base : integer;
variable q : integer;
variable v : STD_ULOGIC_VECTOR(63 downto 0);
begin
while(S(P) = ' ') loop -- Skip spaces
if(P >= S'length) then
P := S'length;
exit;
end if;
P := P + 1;
end loop;
if(S'length > P) then
char := S(P);
if(char = '"') then -- read in as a literal
q := v'high;
v := (others => 'U');
VEC := v(VEC'range);
char := ' ';
P := P + 1;
while((char /= '"') and not (S'length = P)) loop
char := S(P);
P := P + 1;
case char is
when '0' =>
v(q) := '0';
when '1' =>
v(q) := '1';
when 'L' | 'l' =>
v(q) := 'L';
when 'H' | 'h' =>
v(q) := 'H';
when 'Z' | 'z' =>
v(q) := 'Z';
when 'X' | 'x' =>
v(q) := 'X';
when 'U' | 'u' =>
v(q) := 'U';
when others =>
-- char := '"';
exit;
end case;
q := q - 1;
end loop;
if(v'high-q < 2) then -- only a single bit was read
VEC(VEC'low) := v(v'high);
elsif((v'high - q) > VEC'length) then -- too many bits
VEC := v(q+VEC'length downto q+1);
else -- the number of bits read is same or less than required
VEC(v'high-q-1+VEC'low downto VEC'low) := v(v'high downto q+1);
end if;
else
base := 16; -- Hex is the default
if(char = '%') then -- determine base
P := P + 1;
char := S(P);
P := P + 1;
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
else
assert false report "Unsupported Base detected when reading a Vector"
severity error;
end if;
char := S(P);
-- P := P + 1;
elsif((char = '0') and ((S(P+1) = 'x') or (S(P+1) = 'X'))) then
P := P + 2;
end if;
v := (others => '0');
char := S(P);
if(base = 2) then
while(((char = '0') or (char = '1')) and not (P > S'length)) loop
if(char = '0') then
v := v(v'high-1 downto 0) & '0';
else
v := v(v'high-1 downto 0) & '1';
end if;
P := P + 1;
char := S(P);
end loop;
else
while(is_hex(char) and not (P > S'length)) loop
if(is_hex(char)) then
v := v(v'high-4 downto 0) & hex_char_to_vector(char);
end if;
P := P + 1;
char := S(P);
end loop;
end if;
VEC := V((VEC'high - VEC'low) downto 0);
end if;
else
assert false report "Couldn't read a vector"
severity error;
V := (others => '0');
VEC := V((VEC'high - VEC'low) downto 0);
end if;
end sget_vector_64;
-----------------------------------------------------------------------------
-- *Module : read_int
--
-- *Description : load an integer from the input line in a free floating format
-----------------------------------------------------------------------------
procedure read_int(L : inout line; I : out integer) is
variable char : character;
variable base : integer;
variable q : integer;
begin
if(L'length > 0) then
char := ' ';
while(char = ' ') loop -- Skip spaces
read(L, char);
end loop;
base := 16; -- Hex is the default
if(char = '%') then -- determine base
read(L, char);
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
elsif(char = 'd' or char = 'D') then
base := 10;
else
assert false report "Unsupported Base detected when reading an integer"
severity error;
end if;
read(L, char);
end if;
q := 0;
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
while(is_hex(char) and not (L'length = 0)) loop
read(L, char);
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
end if;
end loop;
end if;
I := q;
else
assert false report "Couldn't read an integer"
severity error;
end if;
end read_int;
-----------------------------------------------------------------------------
-- *Module : sget_int
--
-- *Description : Same as read_int except for strings
-----------------------------------------------------------------------------
procedure sget_int(S : in string; P : inout integer; X : out integer) is
variable char : character;
variable base : integer;
variable q : integer;
begin
if(S'length > P) then
char := ' ';
while(char = ' ') loop -- Skip spaces
char := S(P);
P := P + 1;
end loop;
base := 16; -- Hex is the default
if(char = '%') then -- determine base
char := S(P);
P := P + 1;
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
elsif(char = 'd' or char = 'D') then
base := 10;
else
assert false report "Unsupported Base detected when reading an integer"
severity error;
end if;
char := S(P);
P := P + 1;
end if;
q := 0;
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
while(is_hex(char) and not (S'length = P)) loop
char := S(P);
P := P + 1;
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
end if;
end loop;
end if;
X := q;
else
assert false report "Couldn't read an integer"
severity error;
end if;
end sget_int;
-----------------------------------------------------------------------------
-- *Module : write_hex_vector
--
-- *Description : writes out a vector as hex
-----------------------------------------------------------------------------
procedure write_hex_vector(L : inout line; V : in STD_ULOGIC_VECTOR) is
variable C : character;
variable VV : STD_ULOGIC_VECTOR(((V'length + 3)/4) * 4 - 1 downto 0);
begin
VV := (others => '0');
VV(V'length -1 downto 0) := V;
for i in VV'length/4 - 1 downto 0 loop
C := vector_to_hex_char(VV(i*4+3 downto i*4));
write(L, C);
end loop;
end write_hex_vector;
-----------------------------------------------------------------------------
-- *Module : to_str
--
-- *Description : Converts a STD_ULOGIC_VECTOR to a string of the same length
-----------------------------------------------------------------------------
function to_str(constant V: in STD_ULOGIC_VECTOR) return STRING is
variable S : STRING(1 to V'length);
variable sp : integer;
begin
sp := 1;
for i in V'range loop
case V(i) is
when '1' | 'H' =>
S(sp) := '1';
when '0' | 'L' =>
S(sp) := '0';
when others =>
S(sp) := 'X';
end case;
sp := sp + 1;
end loop;
return(S);
end to_str;
-----------------------------------------------------------------------------
-- *Module : to_str
--
-- *Description : Converts a STD_ULOGIC to a string
-----------------------------------------------------------------------------
function to_str(constant V: in STD_ULOGIC) return STRING is
-- variable S : STRING(1);
begin
case V is
when '1' | 'H' =>
return("1");
when '0' | 'L' =>
return("0");
when others =>
return("X");
end case;
return("X");
end to_str;
-----------------------------------------------------------------------------
-- *Module : to_str
--
-- *Description : Converts a integer to a string
-----------------------------------------------------------------------------
function to_str(constant val : in INTEGER) return STRING is
variable result : STRING(11 downto 1) := "-2147483648"; -- smallest integer and longest string
variable tmp : INTEGER;
variable pos : NATURAL := 1;
variable digit : NATURAL;
begin
-- for the smallest integer MOD does not seem to work...
--if val = -2147483648 then : compilation error with Xilinx tools...
if val < -2147483647 then
pos := 12;
else
tmp := abs(val);
loop
digit := abs(tmp MOD 10);
tmp := tmp / 10;
result(pos) := character'val(character'pos('0') + digit);
pos := pos + 1;
exit when tmp = 0;
end loop;
if val < 0 then
result(pos) := '-';
pos := pos + 1;
end if;
end if;
return result((pos-1) downto 1);
end to_str;
-----------------------------------------------------------------------------
-- *Module : to_strn
--
-- *Description : Converts an integer to a string of length N
-----------------------------------------------------------------------------
function to_strn(constant val : in INTEGER; constant n : in INTEGER) return STRING is
variable result : STRING(11 downto 1) := "-2147483648"; -- smallest integer and longest string
variable tmp : INTEGER;
variable pos : NATURAL := 1;
variable digit : NATURAL;
begin
-- for the smallest integer MOD does not seem to work...
--if val = -2147483648 then : compilation error with Xilinx tools...
if val < -2147483647 then
pos := 12;
else
result := (others => ' ');
tmp := abs(val);
loop
digit := abs(tmp MOD 10);
tmp := tmp / 10;
result(pos) := character'val(character'pos('0') + digit);
pos := pos + 1;
exit when tmp = 0;
end loop;
if val < 0 then
result(pos) := '-';
pos := pos + 1;
end if;
end if;
return result(n downto 1);
end to_strn;
end textutil;
library ieee;
use ieee.std_logic_1164.all;
--library synopsys;
--use synopsys.arithmetic.all;
package UTIL is
function to_mvl ( b: in boolean ) return STD_ULOGIC;
function to_mvl ( i: in integer ) return STD_ULOGIC;
function to_vector(input,num_bits:integer) return STD_ULOGIC_VECTOR;
-- function to_signed( b: in std_ulogic_vector ) return signed;
-- function to_std_ulogic_vector( b: in signed ) return std_ulogic_vector;
-- function std_logic_to_std_ulogic( b: in std_logic ) return std_ulogic;
-- function std_ulogic_to_std_logic( b: in std_ulogic ) return std_logic;
function "and"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC) return STD_ULOGIC_VECTOR;
function "and"(l: STD_ULOGIC; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
function "and"(l: STD_ULOGIC_VECTOR; r: BOOLEAN) return STD_ULOGIC_VECTOR;
function "and"(l: BOOLEAN; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
function "and"(l: BOOLEAN; r: STD_ULOGIC) return STD_ULOGIC;
function "and"(l: STD_ULOGIC; r: BOOLEAN) return STD_ULOGIC;
function exp(input: STD_ULOGIC; num_bits: integer) return STD_ULOGIC_VECTOR;
function exp(input: STD_ULOGIC_VECTOR; num_bits: integer) return STD_ULOGIC_VECTOR;
function conv_integer ( ARG: in STD_ULOGIC_VECTOR ) return integer;
function "+"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC) return STD_ULOGIC_VECTOR;
-- function "+"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
-- function "-"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC) return STD_ULOGIC_VECTOR;
-- function "-"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
function to_int(l: std_ulogic_vector) return natural;
function to_int(l: std_ulogic) return natural;
function and_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function nand_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function or_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function nor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function xor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function xnor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function ge ( l, r : STD_ULOGIC_VECTOR ) return BOOLEAN;
function gt ( l, r : STD_ULOGIC_VECTOR ) return BOOLEAN;
function lt ( l, r : STD_ULOGIC_VECTOR ) return BOOLEAN;
function eq ( l, r : STD_ULOGIC_VECTOR ) return BOOLEAN;
function maximum ( arg1, arg2 : INTEGER) return INTEGER;
function minimum ( arg1, arg2 : INTEGER) return INTEGER;
procedure keep(signal X: inout STD_LOGIC);
function log2(A: in integer) return integer;
-------------------------------------------------------------------
-- Declaration of Synthesis directive attributes
-------------------------------------------------------------------
ATTRIBUTE synthesis_return : string ;
end UTIL;
package body UTIL is
--------------------------------------------------------------------
-- function to_signed ( b: in std_ulogic_vector ) return signed is
-- variable result : signed(b'range);
-- begin
-- for i in b'range loop
-- result(i) := b(i);
-- end loop;
-- return result;
-- end to_signed;
--------------------------------------------------------------------
-- function to_std_ulogic_vector ( b: in signed ) return std_ulogic_vector is
-- variable result : std_ulogic_vector(b'range);
-- begin
-- for i in b'range loop
-- result(i) := b(i);
-- end loop;
-- return result;
-- end to_std_ulogic_vector;
--------------------------------------------------------------------
function to_mvl ( b: in boolean ) return STD_ULOGIC is
begin
if ( b = TRUE ) then
return( '1' );
else
return( '0' );
end if;
end to_mvl;
--------------------------------------------------------------------
function to_mvl ( i: in integer ) return STD_ULOGIC is
begin
if ( i = 1 ) then
return( '1' );
else
return( '0' );
end if;
end to_mvl;
--------------------------------------------------------------------
function "and"(l: STD_ULOGIC; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
variable rr: STD_ULOGIC_vector(r'range);
begin
if (l = '1') then
rr := r;
else
rr := (others => '0');
end if;
return(rr);
end;
--------------------------------------------------------------------
function "and"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC) return STD_ULOGIC_VECTOR is
variable ll: STD_ULOGIC_vector(l'range);
begin
if (r = '1') then
ll := l;
else
ll := (others => '0');
end if;
return(ll);
end;
--------------------------------------------------------------------
function "and"(l: BOOLEAN; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
variable rr: STD_ULOGIC_vector(r'range);
begin
if (l) then
rr := r;
else
rr := (others => '0');
end if;
return(rr);
end;
--------------------------------------------------------------------
function "and"(l: STD_ULOGIC_VECTOR; r: BOOLEAN) return STD_ULOGIC_VECTOR is
variable ll: STD_ULOGIC_vector(l'range);
begin
if (r) then
ll := l;
else
ll := (others => '0');
end if;
return(ll);
end;
--------------------------------------------------------------------
function "and"(l: BOOLEAN; r: STD_ULOGIC) return STD_ULOGIC is
variable ll: STD_ULOGIC;
begin
if (l) then
ll := r;
else
ll := '0';
end if;
return(ll);
end;
--------------------------------------------------------------------
function "and"(l: STD_ULOGIC; r: BOOLEAN) return STD_ULOGIC is
variable ll: STD_ULOGIC;
begin
if (r) then
ll := l;
else
ll := '0';
end if;
return(ll);
end;
--------------------------------------------------------------------
-- function std_ulogic_to_std_logic(b : std_ulogic) return std_logic is
-- variable result: std_logic;
-- begin
-- result := b;
-- return result;
-- end;
--------------------------------------------------------------------
-- function std_logic_to_std_ulogic(b : std_logic) return std_ulogic is
-- variable result: std_ulogic;
-- begin
-- result := b;
-- return result;
-- end;
--------------------------------------------------------------------
function to_vector(input,num_bits: integer) return std_ulogic_vector is
variable vec: std_ulogic_vector(num_bits-1 downto 0);
variable a: integer;
begin
a := input;
for i in 0 to num_bits-1 loop
if ((a mod 2) = 1) then
vec(i) := '1';
else
vec(i) := '0';
end if;
a := a / 2;
end loop;
return vec;
end to_vector;
-- FUNCTION to_vector(input,num_bits:integer) RETURN STD_ULOGIC_VECTOR IS
-- VARIABLE result:STD_ULOGIC_VECTOR(num_bits-1 DOWNTO 0);
-- VARIABLE weight:integer;
-- VARIABLE temp:integer;
-- BEGIN
-- weight := 2**(num_bits-1);
-- temp := input;
-- FOR i in result'HIGH DOWNTO result'LOW LOOP
-- IF temp >= weight THEN
-- result(i) := '1';
-- temp := temp - weight;
-- ELSE
-- result(i) := '0';
-- END IF;
-- weight := weight/2;
-- END LOOP;
-- RETURN result;
-- END to_vector;
--------------------------------------------------------------------
-- exp: Expand one bit into many
--------------------------------------------------------------------
FUNCTION exp(input:STD_ULOGIC; num_bits:integer) RETURN STD_ULOGIC_VECTOR IS
VARIABLE result:STD_ULOGIC_VECTOR(num_bits-1 DOWNTO 0);
BEGIN
FOR i in result'HIGH DOWNTO result'LOW LOOP
result(i) := input;
END LOOP;
RETURN result;
END exp;
--------------------------------------------------------------------
-- exp: Expand n bits into m bits
--------------------------------------------------------------------
FUNCTION exp(input:STD_ULOGIC_VECTOR; num_bits:integer) RETURN STD_ULOGIC_VECTOR IS
VARIABLE result:STD_ULOGIC_VECTOR(num_bits-1 DOWNTO 0);
BEGIN
result(input'high-input'low downto 0) := input;
result(num_bits-1 downto input'high-input'low+1) := (others => '0');
RETURN result;
END exp;
--------------------------------------------------------------------
-- conv_integer
--------------------------------------------------------------------
function conv_integer ( ARG: in STD_ULOGIC_VECTOR ) return integer is
variable result: INTEGER;
begin
assert ARG'length <= 31
report "ARG is too large in CONV_INTEGER"
severity FAILURE;
result := 0;
for i in ARG'range loop
result := result * 2;
if(ARG(i) = 'H' or ARG(i) = '1') then
result := result + 1;
end if;
end loop;
return result;
end;
--------------------------------------------------------------------
-- "+" Increment function
--------------------------------------------------------------------
function "+"(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC) return STD_ULOGIC_VECTOR is
variable Q: STD_ULOGIC_VECTOR(L'range);
variable A: STD_ULOGIC;
begin
A := R;
for i in L'low to L'high loop
Q(i) := L(i) xor A;
A := A and L(i);
end loop;
return Q;
end;
--------------------------------------------------------------------
-- "+" adder function
--------------------------------------------------------------------
-- function "+"(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
-- variable Q : SIGNED(L'range);
-- variable result: STD_ULOGIC_VECTOR(L'range);
-- begin
-- Q := to_signed(L) + to_signed(R);
-- result := to_std_ulogic_vector(Q);
-- return result;
-- end;
--------------------------------------------------------------------
-- "-" Decrement function
--------------------------------------------------------------------
-- function "-"(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC) return STD_ULOGIC_VECTOR is
-- variable Q: STD_ULOGIC_VECTOR(L'range);
-- variable A: STD_ULOGIC;
-- begin
-- A := R;
-- for i in L'low to L'high loop
-- Q(i) := L(i) xor A;
-- A := A and not L(i);
-- end loop;
-- return Q;
-- end;
--------------------------------------------------------------------
-- "-" subtractor function
--------------------------------------------------------------------
-- function "-"(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
-- variable Q : SIGNED(L'range);
-- variable result: STD_ULOGIC_VECTOR(L'range);
-- begin
-- Q := to_signed(L) - to_signed(R);
-- result := to_std_ulogic_vector(Q);
-- return result;
-- end;
--------------------------------------------------------------------
-- to_int : Convert std_ulogic_vector to an integer
--------------------------------------------------------------------
function to_int(l: std_ulogic_vector) return natural is
variable result: natural := 0;
begin
for t1 in l'range loop
result := result * 2;
if (l(t1) = '1') or (l(t1) = 'H') then
result := result + 1;
end if;
end loop;
return result;
end to_int;
--------------------------------------------------------------------
-- to_int : Convert std_ulogic_vector to an integer
--------------------------------------------------------------------
function to_int(l: std_ulogic) return natural is
variable result: natural := 0;
begin
if (l = '1') or (l = 'H') then
result := 1;
else
result := 0;
end if;
return result;
end to_int;
--------------------------------------------------------------------
-- Reduce Functions
--------------------------------------------------------------------
function and_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
variable result: STD_ULOGIC;
begin
result := '1';
for i in ARG'range loop
result := result and ARG(i);
end loop;
return result;
end;
function nand_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
begin
return not and_reduce(ARG);
end;
function or_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
variable result: STD_ULOGIC;
begin
result := '0';
for i in ARG'range loop
result := result or ARG(i);
end loop;
return result;
end;
function nor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
begin
return not or_reduce(ARG);
end;
function xor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
variable result: STD_ULOGIC;
begin
result := '0';
for i in ARG'range loop
result := result xor ARG(i);
end loop;
return result;
end;
function xnor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
begin
return not xor_reduce(ARG);
end;
--------------------------------------------------------------------
-- Some useful generic functions
--------------------------------------------------------------------
--//// Zero Extend ////
--
-- Function zxt
--
FUNCTION zxt( q : STD_ULOGIC_VECTOR; i : INTEGER ) RETURN STD_ULOGIC_VECTOR IS
VARIABLE qs : STD_ULOGIC_VECTOR (1 TO i);
VARIABLE qt : STD_ULOGIC_VECTOR (1 TO q'length);
-- Hidden function. Synthesis directives are present in its callers
BEGIN
qt := q;
IF i < q'length THEN
qs := qt( (q'length-i+1) TO qt'right);
ELSIF i > q'length THEN
qs := (OTHERS=>'0');
qs := qs(1 TO (i-q'length)) & qt;
ELSE
qs := qt;
END IF;
RETURN qs;
END;
FUNCTION maximum (arg1,arg2:INTEGER) RETURN INTEGER IS
BEGIN
IF(arg1 > arg2) THEN
RETURN(arg1) ;
ELSE
RETURN(arg2) ;
END IF;
END ;
FUNCTION minimum (arg1,arg2:INTEGER) RETURN INTEGER IS
BEGIN
IF(arg1 < arg2) THEN
RETURN(arg1) ;
ELSE
RETURN(arg2) ;
END IF;
END ;
--------------------------------------------------------------------
-- Comparision functions
--------------------------------------------------------------------
--
-- Equal functions.
--
TYPE stdlogic_boolean_table IS ARRAY(std_ulogic, std_ulogic) OF BOOLEAN;
CONSTANT eq_table : stdlogic_boolean_table := (
--
----------------------------------------------------------------------------
-- | U X 0 1 Z W L H D | |
--
----------------------------------------------------------------------------
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | 0 |
( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | 1 |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | L |
( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | H |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
);
FUNCTION eq ( l, r : STD_LOGIC ) RETURN BOOLEAN IS
-- Equal for two logic types
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "EQ" ;
BEGIN
result := eq_table( l, r );
RETURN result ;
END;
FUNCTION eq ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
CONSTANT ml : INTEGER := maximum( l'length, r'length );
VARIABLE lt : STD_ULOGIC_VECTOR ( 1 TO ml );
VARIABLE rt : STD_ULOGIC_VECTOR ( 1 TO ml );
-- Arithmetic Equal for two Unsigned vectors
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "EQ" ;
BEGIN
lt := zxt( l, ml );
rt := zxt( r, ml );
FOR i IN lt'range LOOP
IF NOT eq( lt(i), rt(i) ) THEN
result := FALSE;
RETURN result ;
END IF;
END LOOP;
RETURN TRUE;
END;
TYPE std_ulogic_fuzzy_state IS ('U', 'X', 'T', 'F', 'N');
TYPE std_ulogic_fuzzy_state_table IS ARRAY ( std_ulogic, std_ulogic ) OF std_ulogic_fuzzy_state;
CONSTANT ge_fuzzy_table : std_ulogic_fuzzy_state_table := (
-- ----------------------------------------------------
-- | U X 0 1 Z W L H D | |
-- ----------------------------------------------------
( 'U', 'U', 'N', 'U', 'U', 'U', 'N', 'U', 'U' ), -- | U |
( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | X |
( 'U', 'X', 'N', 'F', 'X', 'X', 'N', 'F', 'X' ), -- | 0 |
( 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N', 'N' ), -- | 1 |
( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | Z |
( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | W |
( 'U', 'X', 'N', 'F', 'X', 'X', 'N', 'F', 'X' ), -- | L |
( 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N', 'N' ), -- | H |
( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ) -- | D |
);
FUNCTION ge ( L,R : std_ulogic_vector ) RETURN boolean IS
CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
VARIABLE lt : std_ulogic_vector ( 1 to ml );
VARIABLE rt : std_ulogic_vector ( 1 to ml );
VARIABLE res : std_ulogic_fuzzy_state;
-- Greater-than-or-equal for two Unsigned vectors
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "GTE" ;
begin
lt := zxt( l, ml );
rt := zxt( r, ml );
FOR i IN lt'RANGE LOOP
res := ge_fuzzy_table( lt(i), rt(i) );
CASE res IS
WHEN 'U' => RETURN FALSE;
WHEN 'X' => RETURN FALSE;
WHEN 'T' => RETURN TRUE;
WHEN 'F' => RETURN FALSE;
WHEN OTHERS => null;
END CASE;
END LOOP;
result := TRUE ;
RETURN result;
end ;
--
-- Greater Than functions.
--
CONSTANT gtb_table : stdlogic_boolean_table := (
--
----------------------------------------------------------------------------
-- | U X 0 1 Z W L H D | |
--
----------------------------------------------------------------------------
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | 0 |
( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | 1 |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | L |
( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | H |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
);
FUNCTION gt ( l, r : std_logic ) RETURN BOOLEAN IS
-- Greater-than for two logic types
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "GT" ;
BEGIN
result := gtb_table( l, r );
RETURN result ;
END ;
FUNCTION gt ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
CONSTANT ml : INTEGER := maximum( l'length, r'length );
VARIABLE lt : STD_ULOGIC_VECTOR ( 1 TO ml );
VARIABLE rt : STD_ULOGIC_VECTOR ( 1 TO ml );
-- Greater-than for two logic unsigned vectors
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "GT" ;
BEGIN
lt := zxt( l, ml );
rt := zxt( r, ml );
FOR i IN lt'range LOOP
IF NOT eq( lt(i), rt(i) ) THEN
result := gt( lt(i), rt(i) );
RETURN result ;
END IF;
END LOOP;
RETURN FALSE;
END;
--
-- Less Than functions.
--
CONSTANT ltb_table : stdlogic_boolean_table := (
--
----------------------------------------------------------------------------
-- | U X 0 1 Z W L H D | |
--
----------------------------------------------------------------------------
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | 0 |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | 1 |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | L |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | H |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
);
FUNCTION lt ( l, r : STD_LOGIC ) RETURN BOOLEAN IS
-- Less-than for two logic types
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "LT" ;
BEGIN
result := ltb_table( l, r );
RETURN result ;
END;
FUNCTION lt ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
CONSTANT ml : INTEGER := maximum( l'length, r'length );
VARIABLE ltt : STD_ULOGIC_VECTOR ( 1 TO ml );
VARIABLE rtt : STD_ULOGIC_VECTOR ( 1 TO ml );
-- Less-than for two Unsigned vectors
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "LT" ;
BEGIN
ltt := zxt( l, ml );
rtt := zxt( r, ml );
FOR i IN ltt'range LOOP
IF NOT eq( ltt(i), rtt(i) ) THEN
result := lt( ltt(i), rtt(i) );
RETURN result ;
END IF;
END LOOP;
RETURN FALSE;
END;
--------------------------------------------------------------------
-- "keep" Retain Last value when floated
--------------------------------------------------------------------
procedure keep(signal X: inout STD_LOGIC) is
begin
if(X = 'Z') then
if(X'last_value = '0') then
X <= 'L';
elsif(X'last_value = '1') then
X <= 'H';
else
X <= 'Z';
end if;
else
X <= 'Z';
end if;
end keep;
---------------------------------------------------------------------
-- log base 2 function
---------------------------------------------------------------------
function log2 ( A: in integer ) return integer is
variable B : integer;
begin
B := 1;
for i in 0 to 31 loop
if not ( A > B ) then
return ( i );
exit;
end if;
B := B * 2;
end loop;
end log2;
end UTIL;
-- Created by : G. Penacoba
-- Creation Date: May 2011
-- Description: generates start and stop pulses for test-bench
-- Modified by:
-- Modification Date:
-- Modification consisted on:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.std_logic_textio.all;
use std.textio.all;
entity start_stop_gen is
port(
tstart_o : out std_logic;
tstop1_o : out std_logic;
tstop2_o : out std_logic;
tstop3_o : out std_logic;
tstop4_o : out std_logic;
tstop5_o : out std_logic
);
end start_stop_gen;
architecture behavioral of start_stop_gen is
signal tstart : std_logic:='0';
signal tstop1 : std_logic:='0';
signal tstop2 : std_logic:='0';
signal tstop3 : std_logic:='0';
signal tstop4 : std_logic:='0';
signal tstop5 : std_logic:='0';
signal pulse_channel : integer;
signal pulse_length : time;
begin
-- process reading the schedule of frame exchange from a text file
------------------------------------------------------------------
sequence: process
file sequence_file : text open read_mode is "data_vectors/pulses.txt";
variable sequence_line : line;
variable interval_time : time;
variable coma : string(1 to 1);
variable pulse_ch : integer;
variable pulse_lgth : time;
begin
readline (sequence_file, sequence_line);
read (sequence_line, interval_time);
read (sequence_line, coma);
read (sequence_line, pulse_ch);
read (sequence_line, coma);
read (sequence_line, pulse_lgth);
wait for interval_time;
pulse_channel <= pulse_ch;
pulse_length <= pulse_lgth;
if endfile(sequence_file) then
file_close(sequence_file);
wait;
end if;
end process;
start_extender: process
begin
wait until pulse_channel = 0;
tstart <= '1';
wait for pulse_length;
tstart <= '0';
end process;
stop1_extender: process
begin
wait until pulse_channel = 1;
tstop1 <= '1';
wait for pulse_length;
tstop1 <= '0';
end process;
stop2_extender: process
begin
wait until pulse_channel = 2;
tstop2 <= '1';
wait for pulse_length;
tstop2 <= '0';
end process;
stop3_extender: process
begin
wait until pulse_channel = 3;
tstop3 <= '1';
wait for pulse_length;
tstop3 <= '0';
end process;
stop4_extender: process
begin
wait until pulse_channel = 4;
tstop4 <= '1';
wait for pulse_length;
tstop4 <= '0';
end process;
stop5_extender: process
begin
wait until pulse_channel = 5;
tstop5 <= '1';
wait for pulse_length;
tstop5 <= '0';
end process;
tstart_o <= tstart;
tstop1_o <= tstop1;
tstop2_o <= tstop2;
tstop3_o <= tstop3;
tstop4_o <= tstop4;
tstop5_o <= tstop5;
end behavioral;
----------------------------------------------------------------------------------------------------
-- CERN-BE-CO-HT
----------------------------------------------------------------------------------------------------
--
-- unit name : TDC test-bench (tb_tdc)
-- author : G. Penacoba
-- date : May 2011
-- version : Revision 1
-- description : top module for test-bench
-- dependencies:
-- references :
-- modified by :
--
----------------------------------------------------------------------------------------------------
-- last changes:
----------------------------------------------------------------------------------------------------
-- to do:
----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity tb_tdc is
end tb_tdc;
architecture behavioral of tb_tdc is
component top_tdc
generic(
g_span : integer :=32;
g_width : integer :=32;
values_for_simul : boolean :=FALSE
);
port(
-- interface with GNUM circuit
rst_n_a_i : in std_logic;
-- P2L Direction
p2l_clk_p_i : in std_logic; -- Receiver Source Synchronous Clock+
p2l_clk_n_i : in std_logic; -- Receiver Source Synchronous Clock-
p2l_data_i : in std_logic_vector(15 downto 0); -- Parallel receive data
p2l_dframe_i: in std_logic; -- Receive Frame
p2l_valid_i : in std_logic; -- Receive Data Valid
p2l_rdy_o : out std_logic; -- Rx Buffer Full Flag
p_wr_req_i : in std_logic_vector(1 downto 0); -- PCIe Write Request
p_wr_rdy_o : out std_logic_vector(1 downto 0); -- PCIe Write Ready
rx_error_o : out std_logic; -- Receive Error
vc_rdy_i : in std_logic_vector(1 downto 0); -- Virtual channel ready
-- L2P Direction
l2p_clk_p_o : out std_logic; -- Transmitter Source Synchronous Clock+
l2p_clk_n_o : out std_logic; -- Transmitter Source Synchronous Clock-
l2p_data_o : out std_logic_vector(15 downto 0); -- Parallel transmit data
l2p_dframe_o: out std_logic; -- Transmit Data Frame
l2p_valid_o : out std_logic; -- Transmit Data Valid
l2p_edb_o : out std_logic; -- Packet termination and discard
l2p_rdy_i : in std_logic; -- Tx Buffer Full Flag
l_wr_rdy_i : in std_logic_vector(1 downto 0); -- Local-to-PCIe Write
p_rd_d_rdy_i: in std_logic_vector(1 downto 0); -- PCIe-to-Local Read Response Data Ready
tx_error_i : in std_logic; -- Transmit Error
irq_p_o : out std_logic; -- Interrupt request pulse to GN4124 GPIO
-- interface signals with PLL circuit
acam_refclk_p_i : in std_logic;
acam_refclk_n_i : in std_logic;
--pll_ld_i : in std_logic;
--pll_refmon_i : in std_logic;
pll_sdo_i : in std_logic;
pll_status_i : in std_logic;
pll_cs_o : out std_logic;
pll_dac_sync_o : out std_logic;
pll_sdi_o : out std_logic;
pll_sclk_o : out std_logic;
tdc_clk_p_i : in std_logic;
tdc_clk_n_i : in std_logic;
-- interface signals with acam (timing)
err_flag_i : in std_logic;
int_flag_i : in std_logic;
start_dis_o : out std_logic;
start_from_fpga_o : out std_logic;
stop_dis_o : out std_logic;
-- interface signals with acam (data)
data_bus_io : inout std_logic_vector(27 downto 0);
ef1_i : in std_logic;
ef2_i : in std_logic;
--lf1_i : in std_logic;
--lf2_i : in std_logic;
address_o : out std_logic_vector(3 downto 0);
cs_n_o : out std_logic;
oe_n_o : out std_logic;
rd_n_o : out std_logic;
wr_n_o : out std_logic;
-- other signals on the tdc card
tdc_in_fpga_1_i : in std_logic;
tdc_in_fpga_2_i : in std_logic;
tdc_in_fpga_3_i : in std_logic;
tdc_in_fpga_4_i : in std_logic;
tdc_in_fpga_5_i : in std_logic;
enable_inputs_o : out std_logic;
tdc_led_status_o : out std_logic;
tdc_led_trig1_o : out std_logic;
tdc_led_trig2_o : out std_logic;
tdc_led_trig3_o : out std_logic;
tdc_led_trig4_o : out std_logic;
tdc_led_trig5_o : out std_logic;
carrier_one_wire_b : inout std_logic;
sys_scl_b : inout std_logic;
sys_sda_b : inout std_logic;
mezz_one_wire_b : inout std_logic;
pcb_ver_i : in std_logic_vector(3 downto 0);
prsnt_m2c_n_i : in std_logic;
-- other signals on the spec card
spec_aux0_i : in std_logic;
spec_aux1_i : in std_logic;
spec_aux2_o : out std_logic;
spec_aux3_o : out std_logic;
spec_aux4_o : out std_logic;
spec_aux5_o : out std_logic;
spec_led_green_o : out std_logic;
spec_led_red_o : out std_logic;
spec_clk_i : in std_logic
);
end component;
component acam_model
generic(
start_retrig_period : time:= 3200 ns;
refclk_period : time:= 32 ns
);
port(
tstart_i : in std_logic;
tstop1_i : in std_logic;
tstop2_i : in std_logic;
tstop3_i : in std_logic;
tstop4_i : in std_logic;
tstop5_i : in std_logic;
startdis_i : in std_logic;
stopdis_i : in std_logic;
int_flag_o : out std_logic;
err_flag_o : out std_logic;
address_i : in std_logic_vector(3 downto 0);
cs_n_i : in std_logic;
oe_n_i : in std_logic;
rd_n_i : in std_logic;
wr_n_i : in std_logic;
data_bus_io : inout std_logic_vector(27 downto 0);
ef1_o : out std_logic;
ef2_o : out std_logic;
lf1_o : out std_logic;
lf2_o : out std_logic
);
end component;
component start_stop_gen
port(
tstart_o : out std_logic;
tstop1_o : out std_logic;
tstop2_o : out std_logic;
tstop3_o : out std_logic;
tstop4_o : out std_logic;
tstop5_o : out std_logic
);
end component;
-----------------------------------------------------------------------------
-- GN4124 Local Bus Model
-----------------------------------------------------------------------------
component GN412X_BFM
generic
(
STRING_MAX : integer := 256; -- Command string maximum length
T_LCLK : time := 10 ns; -- Local Bus Clock Period
T_P2L_CLK_DLY : time := 2 ns; -- Delay from LCLK to P2L_CLK
INSTANCE_LABEL : string := "GN412X_BFM"; -- Label string to be used as a prefix for messages from the model
MODE_PRIMARY : boolean := true -- TRUE for BFM acting as GN412x, FALSE for BFM acting as the DUT
);
port
(
--=========================================================--
-------------------------------------------------------------
-- CMD_ROUTER Interface
--
CMD : in string(1 to STRING_MAX);
CMD_REQ : in bit;
CMD_ACK : out bit;
CMD_CLOCK_EN : in boolean;
--=========================================================--
-------------------------------------------------------------
-- GN412x Signal I/O
-------------------------------------------------------------
-- This is the reset input to the BFM
--
RSTINn : in std_logic;
-------------------------------------------------------------
-- Reset outputs to DUT
--
RSTOUT18n : out std_logic;
RSTOUT33n : out std_logic;
-------------------------------------------------------------
----------------- Local Bus Clock ---------------------------
------------------------------------------------------------- __ Direction for primary mode
-- / \
LCLK, LCLKn : inout std_logic; -- Out
-------------------------------------------------------------
----------------- Local-to-PCI Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
L2P_CLKp, L2P_CLKn : inout std_logic; -- In
-------------------------------------------------------------
-- L2P DDR Link
--
L2P_DATA : inout std_logic_vector(15 downto 0); -- In -- Parallel Transmit Data.
L2P_DFRAME : inout std_logic; -- In -- Transmit Data Frame.
L2P_VALID : inout std_logic; -- In -- Transmit Data Valid.
L2P_EDB : inout std_logic; -- In -- End-of-Packet Bad Flag.
-------------------------------------------------------------
-- L2P SDR Controls
--
L_WR_RDY : inout std_logic_vector(1 downto 0); -- Out -- Local-to-PCIe Write.
P_RD_D_RDY : inout std_logic_vector(1 downto 0); -- Out -- PCIe-to-Local Read Response Data Ready.
L2P_RDY : inout std_logic; -- Out -- Tx Buffer Full Flag.
TX_ERROR : inout std_logic; -- Out -- Transmit Error.
-------------------------------------------------------------
----------------- PCIe-to-Local Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
P2L_CLKp, P2L_CLKn : inout std_logic; -- Out -- P2L Source Synchronous Clock.
-------------------------------------------------------------
-- P2L DDR Link
--
P2L_DATA : inout std_logic_vector(15 downto 0); -- Out -- Parallel Receive Data.
P2L_DFRAME : inout std_logic; -- Out -- Receive Frame.
P2L_VALID : inout std_logic; -- Out -- Receive Data Valid.
-------------------------------------------------------------
-- P2L SDR Controls
--
P2L_RDY : inout std_logic; -- In -- Rx Buffer Full Flag.
P_WR_REQ : inout std_logic_vector(1 downto 0); -- Out -- PCIe Write Request.
P_WR_RDY : inout std_logic_vector(1 downto 0); -- In -- PCIe Write Ready.
RX_ERROR : inout std_logic; -- In -- Receive Error.
VC_RDY : inout std_logic_vector(1 downto 0); -- Out -- Virtual Channel Ready Status.
-------------------------------------------------------------
-- GPIO signals
--
GPIO : inout std_logic_vector(15 downto 0)
);
end component; --GN412X_BFM;
-----------------------------------------------------------------------------
-- CMD_ROUTER component
-----------------------------------------------------------------------------
component cmd_router
generic(N_BFM : integer := 8;
N_FILES : integer := 3;
FIFO_DEPTH : integer := 8;
STRING_MAX : integer := 256
);
port(CMD : out string(1 to STRING_MAX);
CMD_REQ : out bit_vector(N_BFM-1 downto 0);
CMD_ACK : in bit_vector(N_BFM-1 downto 0);
CMD_ERR : in bit_vector(N_BFM-1 downto 0);
CMD_CLOCK_EN : out boolean
);
end component; --cmd_router;
constant pll_clk_period : time:= 8 ns;
constant g_width : integer:= 32;
constant g_span : integer:= 32;
constant spec_clk_period : time:= 50 ns;
constant start_retrig_period : time:= 512 ns;
-- Number of Models receiving commands
constant N_BFM : integer := 1; -- 0 : GN412X_BFM in Model Mode
-- -- 1 : GN412X_BFM in DUT mode
-- Number of files to feed BFMs
constant N_FILES : integer := 1;
--
-- Depth of the command FIFO for each model
constant FIFO_DEPTH : integer := 16;
--
-- Maximum width of a command string
constant STRING_MAX : integer := 256;
signal acam_refclk_i : std_logic:='0';
signal acam_refclk_n_i : std_logic:='1';
signal tdc_clk_p_i : std_logic:='0';
signal tdc_clk_n_i : std_logic:='1';
signal spec_clk_i : std_logic:='0';
signal pll_ld_i : std_logic;
signal pll_refmon_i : std_logic;
signal pll_sdo_i : std_logic;
signal pll_status_i : std_logic;
signal pll_cs_o : std_logic;
signal pll_dac_sync_o : std_logic;
signal pll_sdi_o : std_logic;
signal pll_sclk_o : std_logic;
signal mute_inputs : std_logic;
signal address_o : std_logic_vector(3 downto 0);
signal cs_n_o : std_logic;
signal data_bus_io : std_logic_vector(27 downto 0);
signal ef1_i : std_logic;
signal ef2_i : std_logic;
signal err_flag_i : std_logic;
signal int_flag_i : std_logic;
signal lf1_i : std_logic;
signal lf2_i : std_logic;
signal oe_n_o : std_logic;
signal rd_n_o : std_logic;
signal start_dis_o : std_logic;
signal start_from_fpga_o : std_logic;
signal stop_dis_o : std_logic;
signal wr_n_o : std_logic;
--signal tstart : std_logic;
signal tstop1 : std_logic;
signal tstop2 : std_logic;
signal tstop3 : std_logic;
signal tstop4 : std_logic;
signal tstop5 : std_logic;
signal dummy_tstop5 : std_logic;
signal tdc_in_fpga_5 : std_logic;
signal tdc_led_status : std_logic;
signal tdc_led_trig1 : std_logic;
signal tdc_led_trig2 : std_logic;
signal tdc_led_trig3 : std_logic;
signal tdc_led_trig4 : std_logic;
signal tdc_led_trig5 : std_logic;
signal spec_aux0_i : std_logic;
signal spec_aux1_i : std_logic;
signal spec_aux2_o : std_logic;
signal spec_aux3_o : std_logic;
signal spec_aux4_o : std_logic;
signal spec_aux5_o : std_logic;
signal spec_led_green : std_logic;
signal spec_led_red : std_logic;
-- GN4124 interface
signal rst_n : std_logic;
signal irq_p : std_logic;
signal spare : std_logic;
signal RSTINn : std_logic;
signal RSTOUT18n : std_logic;
signal RSTOUT33n : std_logic;
signal LCLK, LCLKn : std_logic;
signal P2L_CLKp, P2L_CLKn : std_logic;
signal P2L_DATA : std_logic_vector(15 downto 0);
signal P2L_DATA_32 : std_logic_vector(31 downto 0); -- For monitoring use
signal P2L_DFRAME : std_logic;
signal P2L_VALID : std_logic;
signal P2L_RDY : std_logic;
signal P_WR_REQ : std_logic_vector(1 downto 0);
signal P_WR_RDY : std_logic_vector(1 downto 0);
signal RX_ERROR : std_logic;
signal VC_RDY : std_logic_vector(1 downto 0);
signal L2P_CLKp, L2P_CLKn : std_logic;
signal L2P_DATA : std_logic_vector(15 downto 0);
signal L2P_DATA_32 : std_logic_vector(31 downto 0); -- For monitoring use
signal L2P_DFRAME : std_logic;
signal L2P_VALID : std_logic;
signal L2P_EDB : std_logic;
signal L2P_RDY : std_logic;
signal L_WR_RDY : std_logic_vector(1 downto 0);
signal P_RD_D_RDY : std_logic_vector(1 downto 0);
signal TX_ERROR : std_logic;
signal GPIO : std_logic_vector(15 downto 0);
-----------------------------------------------------------------------------
-- Command Router Signals
-----------------------------------------------------------------------------
signal CMD : string(1 to STRING_MAX);
signal CMD_REQ : bit_vector(N_BFM-1 downto 0);
signal CMD_ACK : bit_vector(N_BFM-1 downto 0);
signal CMD_ERR : bit_vector(N_BFM-1 downto 0);
signal CMD_CLOCK_EN : boolean;
begin
dut: top_tdc
generic map(
g_span => 32,
g_width => 32,
values_for_simul => TRUE
)
port map(
-- interface with GNUM circuit
rst_n_a_i => rst_n,
p2l_clk_p_i => p2l_clkp,
p2l_clk_n_i => p2l_clkn,
p2l_data_i => p2l_data,
p2l_dframe_i => p2l_dframe,
p2l_valid_i => p2l_valid,
p2l_rdy_o => p2l_rdy,
p_wr_req_i => p_wr_req,
p_wr_rdy_o => p_wr_rdy,
rx_error_o => rx_error,
vc_rdy_i => vc_rdy,
l2p_clk_p_o => l2p_clkp,
l2p_clk_n_o => l2p_clkn,
l2p_data_o => l2p_data,
l2p_dframe_o => l2p_dframe,
l2p_valid_o => l2p_valid,
l2p_edb_o => l2p_edb,
l2p_rdy_i => l2p_rdy,
l_wr_rdy_i => l_wr_rdy,
p_rd_d_rdy_i => p_rd_d_rdy,
tx_error_i => tx_error,
irq_p_o => irq_p,
-- interface with PLL circuit
acam_refclk_p_i => acam_refclk_i,
acam_refclk_n_i => acam_refclk_n_i,
--pll_ld_i => pll_ld_i,
--pll_refmon_i => pll_refmon_i,
pll_sdo_i => pll_sdo_i,
pll_status_i => pll_status_i,
pll_cs_o => pll_cs_o,
pll_dac_sync_o => pll_dac_sync_o,
pll_sdi_o => pll_sdi_o,
pll_sclk_o => pll_sclk_o,
tdc_clk_p_i => tdc_clk_p_i,
tdc_clk_n_i => tdc_clk_n_i,
-- interface signals with acam (timing)
int_flag_i => int_flag_i,
err_flag_i => err_flag_i,
start_dis_o => start_dis_o,
start_from_fpga_o => start_from_fpga_o,
stop_dis_o => stop_dis_o,
-- interface signals with acam (data)
data_bus_io => data_bus_io,
ef1_i => ef1_i,
ef2_i => ef2_i,
--lf1_i => lf1_i,
--lf2_i => lf2_i,
address_o => address_o,
cs_n_o => cs_n_o,
oe_n_o => oe_n_o,
rd_n_o => rd_n_o,
wr_n_o => wr_n_o,
-- other signals on the tdc card
tdc_in_fpga_5_i => tdc_in_fpga_5,
tdc_in_fpga_1_i => '0',
tdc_in_fpga_2_i => '0',
tdc_in_fpga_3_i => '0',
tdc_in_fpga_4_i => '0',
enable_inputs_o => mute_inputs,
tdc_led_status_o => tdc_led_status,
tdc_led_trig1_o => tdc_led_trig1,
tdc_led_trig2_o => tdc_led_trig2,
tdc_led_trig3_o => tdc_led_trig3,
tdc_led_trig4_o => tdc_led_trig4,
tdc_led_trig5_o => tdc_led_trig5,
-- other signals on the spec card
carrier_one_wire_b => open,
sys_scl_b => open,
sys_sda_b => open,
mezz_one_wire_b => open,
pcb_ver_i => (others => '0'),
prsnt_m2c_n_i => '0',
spec_aux0_i => spec_aux0_i,
spec_aux1_i => spec_aux1_i,
spec_aux2_o => spec_aux2_o,
spec_aux3_o => spec_aux3_o,
spec_aux4_o => spec_aux4_o,
spec_aux5_o => spec_aux5_o,
spec_led_green_o => spec_led_green,
spec_led_red_o => spec_led_red,
spec_clk_i => spec_clk_i
);
acam: acam_model
generic map(
start_retrig_period => start_retrig_period,
refclk_period => pll_clk_period/4
)
port map(
tstart_i => start_from_fpga_o,
tstop1_i => tstop1,
tstop2_i => tstop2,
tstop3_i => tstop3,
tstop4_i => tstop4,
tstop5_i => tstop5,
-- tstop5_i => dummy_tstop5,
startdis_i => start_dis_o,
stopdis_i => stop_dis_o,
int_flag_o => int_flag_i,
address_i => address_o,
cs_n_i => cs_n_o,
oe_n_i => oe_n_o,
rd_n_i => rd_n_o,
wr_n_i => wr_n_o,
data_bus_io => data_bus_io,
ef1_o => ef1_i,
ef2_o => ef2_i,
err_flag_o => err_flag_i,
lf1_o => lf1_i,
lf2_o => lf2_i
);
pulses_generator: start_stop_gen
port map(
tstart_o => open,
tstop1_o => tstop1,
tstop2_o => tstop2,
tstop3_o => tstop3,
tstop4_o => tstop4,
tstop5_o => tstop5
);
CMD_ERR <= (others => '0');
UC : cmd_router
generic map
(N_BFM => N_BFM,
N_FILES => N_FILES,
FIFO_DEPTH => FIFO_DEPTH,
STRING_MAX => STRING_MAX
)
port map
(CMD => CMD,
CMD_REQ => CMD_REQ,
CMD_ACK => CMD_ACK,
CMD_ERR => CMD_ERR,
CMD_CLOCK_EN => CMD_CLOCK_EN
);
-----------------------------------------------------------------------------
-- GN412x BFM - PRIMARY
-----------------------------------------------------------------------------
U0 : gn412x_bfm
generic map
(
STRING_MAX => STRING_MAX,
-- T_LCLK => 5 ns,
-- T_LCLK => 10 ns,
T_LCLK => 6.25 ns,
T_P2L_CLK_DLY => 2 ns,
INSTANCE_LABEL => "U0(Primary GN412x): ",
MODE_PRIMARY => true
)
port map
(
--=========================================================--
-------------------------------------------------------------
-- CMD_ROUTER Interface
--
CMD => CMD,
CMD_REQ => CMD_REQ(0),
CMD_ACK => CMD_ACK(0),
CMD_CLOCK_EN => CMD_CLOCK_EN,
--=========================================================--
-------------------------------------------------------------
-- GN412x Signal I/O
-------------------------------------------------------------
-- This is the reset input to the BFM
--
RSTINn => RSTINn,
-------------------------------------------------------------
-- Reset outputs to DUT
--
RSTOUT18n => RSTOUT18n,
RSTOUT33n => RSTOUT33n,
-------------------------------------------------------------
----------------- Local Bus Clock ---------------------------
-------------------------------------------------------------
--
LCLK => LCLK,
LCLKn => LCLKn,
-------------------------------------------------------------
----------------- Local-to-PCI Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
L2P_CLKp => L2P_CLKp,
L2P_CLKn => L2P_CLKn,
-------------------------------------------------------------
-- L2P DDR Link
--
L2P_DATA => L2P_DATA,
L2P_DFRAME => L2P_DFRAME,
L2P_VALID => L2P_VALID,
L2P_EDB => L2P_EDB,
-------------------------------------------------------------
-- L2P SDR Controls
--
L_WR_RDY => L_WR_RDY,
P_RD_D_RDY => P_RD_D_RDY,
L2P_RDY => L2P_RDY,
TX_ERROR => TX_ERROR,
-------------------------------------------------------------
----------------- PCIe-to-Local Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
P2L_CLKp => P2L_CLKp,
P2L_CLKn => P2L_CLKn,
-------------------------------------------------------------
-- P2L DDR Link
--
P2L_DATA => P2L_DATA,
P2L_DFRAME => P2L_DFRAME,
P2L_VALID => P2L_VALID,
-------------------------------------------------------------
-- P2L SDR Controls
--
P2L_RDY => P2L_RDY,
P_WR_REQ => P_WR_REQ,
P_WR_RDY => P_WR_RDY,
RX_ERROR => RX_ERROR,
VC_RDY => VC_RDY,
GPIO => gpio
); -- GN412X_BFM;
tdc_pll_clock: process
begin
if pll_cs_o ='1' and rst_n ='1' then
tdc_clk_p_i <= not (tdc_clk_p_i) after 1 ns;
tdc_clk_n_i <= not (tdc_clk_n_i) after 1 ns;
pll_status_i <= '1';
end if;
wait for pll_clk_period/2;
end process;
tdc_ref_clock: process
begin
if pll_cs_o ='1' and rst_n ='1' then
acam_refclk_i <= not (acam_refclk_i) after 3 ns;
end if;
wait for pll_clk_period*2;
end process;
acam_refclk_n_i <= not acam_refclk_i;
spec_clock: process
begin
spec_clk_i <= not (spec_clk_i) after 1 ns;
wait for spec_clk_period/2;
end process;
rst_n <= RSTOUT18n;
GPIO(0) <= irq_p;
GPIO(1) <= spare;
tdc_in_fpga_5 <= tstop5;
spec_aux0_i <= '1';
spec_aux1_i <= '1';
end behavioral;
files = ["fmc_tdc_wrapper.vhd",
"tdc_core_pkg.vhd",
"fmc_tdc_direct_readout.vhd",
"fmc_tdc_direct_readout_slave.vhd",
"fmc_tdc_direct_readout_slave_pkg.vhd"
];
#!/bin/bash
wbgen2 -V fmc_tdc_direct_readout_slave.vhd -H record -p fmc_tdc_direct_readout_slave_pkg.vhd -K regs.vh -s defines -C fmctdc-direct.h fmc_tdc_direct_readout_slave.wb
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.gencores_pkg.all;
use work.tdc_core_pkg.all;
use work.wishbone_pkg.all;
use work.dr_wbgen2_pkg.all;
entity fmc_tdc_direct_readout is
port
(
clk_tdc_i : in std_logic;
rst_tdc_n_i : in std_logic;
clk_sys_i : in std_logic;
rst_sys_n_i : in std_logic;
direct_timestamp_i : in std_logic_vector(127 downto 0);
direct_timestamp_wr_i : in std_logic;
direct_slave_i : in t_wishbone_slave_in;
direct_slave_o : out t_wishbone_slave_out
);
end entity;
architecture rtl of fmc_tdc_direct_readout is
component fmc_tdc_direct_readout_wb_slave is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(2 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
clk_tdc_i : in std_logic;
regs_i : in t_dr_in_registers;
regs_o : out t_dr_out_registers);
end component fmc_tdc_direct_readout_wb_slave;
constant c_num_channels : integer := 5;
type t_channel_state is record
enable : std_logic;
timeout : unsigned(23 downto 0);
fifo_wr : std_logic;
end record;
type t_channel_state_array is array(0 to c_num_channels-1) of t_channel_state;
signal c : t_channel_state_array;
signal regs_out : t_dr_out_registers;
signal regs_in : t_dr_in_registers;
signal ts_cycles : std_logic_vector(31 downto 0);
signal ts_seconds : std_logic_vector(31 downto 0);
signal ts_bins : std_logic_vector(17 downto 0);
signal ts_edge : std_logic;
signal ts_channel : std_logic_vector(2 downto 0);
begin
ts_channel <= direct_timestamp_i(98 downto 96);
ts_edge <= direct_timestamp_i(100);
ts_seconds <= direct_timestamp_i(95 downto 64);
ts_cycles <= direct_timestamp_i(63 downto 32);
ts_bins <= direct_timestamp_i(17 downto 0);
U_WB_Slave : fmc_tdc_direct_readout_wb_slave
port map (
rst_n_i => rst_sys_n_i,
clk_sys_i => clk_sys_i,
wb_adr_i => direct_slave_i.adr(4 downto 2),
wb_dat_i => direct_slave_i.dat,
wb_dat_o => direct_slave_o.dat,
wb_cyc_i => direct_slave_i.cyc,
wb_sel_i => direct_slave_i.sel,
wb_stb_i => direct_slave_i.stb,
wb_we_i => direct_slave_i.we,
wb_ack_o => direct_slave_o.ack,
wb_stall_o => direct_slave_o.stall,
clk_tdc_i => clk_tdc_i,
regs_i => regs_in,
regs_o => regs_out);
direct_slave_o.err <= '0';
direct_slave_o.rty <= '0';
regs_in.fifo_cycles_i <= ts_cycles;
regs_in.fifo_edge_i <= '1';
regs_in.fifo_seconds_i <= ts_seconds;
regs_in.fifo_channel_i <= '0'&ts_channel;
regs_in.fifo_bins_i <= ts_bins;
gen_channels : for i in 0 to c_num_channels-1 generate
p_dead_time : process (clk_tdc_i)
begin
if rising_edge(clk_tdc_i) then
if rst_tdc_n_i = '0' then
c(i).timeout <= (others => '0');
c(i).enable <= '0';
c(i).fifo_wr <= '0';
else
c(i).enable <= regs_out.chan_enable_o(i);
if c(i).enable = '1' then
if unsigned(ts_channel) = i and ts_edge = '1' and c(i).timeout = 0 then
c(i).timeout <= unsigned(regs_out.dead_time_o);
c(i).fifo_wr <= '1';
elsif c(i).timeout /= 0 then
c(i).fifo_wr <= '0';
c(i).timeout <= c(i).timeout - 1;
end if;
else
c(i).fifo_wr <= '0';
c(i).timeout <= (others => '0');
end if;
end if;
end if;
end process;
end generate gen_channels;
p_fifo_write : process(clk_tdc_i)
begin
if rising_edge(clk_tdc_i) then
if rst_tdc_n_i = '0' then
regs_in.fifo_wr_req_i <= '0';
else
for i in 0 to c_num_channels-1 loop
regs_in.fifo_wr_req_i <= c(i).fifo_wr and not regs_out.fifo_wr_full_o;
end loop;
end if;
end if;
end process;
end rtl;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for TDC Direct Readout WB Slave
---------------------------------------------------------------------------------------
-- File : fmc_tdc_direct_readout_slave.vhd
-- Author : auto-generated by wbgen2 from fmc_tdc_direct_readout_slave.wb
-- Created : Thu May 15 14:23:14 2014
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fmc_tdc_direct_readout_slave.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wbgen2_pkg.all;
use work.dr_wbgen2_pkg.all;
entity fmc_tdc_direct_readout_wb_slave is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(2 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
clk_tdc_i : in std_logic;
regs_i : in t_dr_in_registers;
regs_o : out t_dr_out_registers
);
end fmc_tdc_direct_readout_wb_slave;
architecture syn of fmc_tdc_direct_readout_wb_slave is
signal dr_fifo_rst_n : std_logic ;
signal dr_fifo_in_int : std_logic_vector(86 downto 0);
signal dr_fifo_out_int : std_logic_vector(86 downto 0);
signal dr_fifo_rdreq_int : std_logic ;
signal dr_fifo_rdreq_int_d0 : std_logic ;
signal dr_chan_enable_int : std_logic_vector(4 downto 0);
signal dr_dead_time_int : std_logic_vector(23 downto 0);
signal dr_fifo_full_int : std_logic ;
signal dr_fifo_empty_int : std_logic ;
signal dr_fifo_usedw_int : std_logic_vector(7 downto 0);
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(2 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
wrdata_reg <= wb_dat_i;
bwsel_reg <= wb_sel_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
dr_chan_enable_int <= "00000";
dr_dead_time_int <= "000000000000000000000000";
dr_fifo_rdreq_int <= '0';
elsif rising_edge(clk_sys_i) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
ack_in_progress <= '0';
else
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(2 downto 0) is
when "000" =>
if (wb_we_i = '1') then
dr_chan_enable_int <= wrdata_reg(4 downto 0);
end if;
rddata_reg(4 downto 0) <= dr_chan_enable_int;
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "001" =>
if (wb_we_i = '1') then
dr_dead_time_int <= wrdata_reg(23 downto 0);
end if;
rddata_reg(23 downto 0) <= dr_dead_time_int;
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "010" =>
if (wb_we_i = '1') then
end if;
if (dr_fifo_rdreq_int_d0 = '0') then
dr_fifo_rdreq_int <= not dr_fifo_rdreq_int;
else
rddata_reg(31 downto 0) <= dr_fifo_out_int(31 downto 0);
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end if;
when "011" =>
if (wb_we_i = '1') then
end if;
rddata_reg(31 downto 0) <= dr_fifo_out_int(63 downto 32);
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "100" =>
if (wb_we_i = '1') then
end if;
rddata_reg(17 downto 0) <= dr_fifo_out_int(81 downto 64);
rddata_reg(18) <= dr_fifo_out_int(82);
rddata_reg(22 downto 19) <= dr_fifo_out_int(86 downto 83);
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "101" =>
if (wb_we_i = '1') then
end if;
rddata_reg(16) <= dr_fifo_full_int;
rddata_reg(17) <= dr_fifo_empty_int;
rddata_reg(7 downto 0) <= dr_fifo_usedw_int;
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_dat_o <= rddata_reg;
-- extra code for reg/fifo/mem: Readout FIFO
dr_fifo_in_int(31 downto 0) <= regs_i.fifo_seconds_i;
dr_fifo_in_int(63 downto 32) <= regs_i.fifo_cycles_i;
dr_fifo_in_int(81 downto 64) <= regs_i.fifo_bins_i;
dr_fifo_in_int(82) <= regs_i.fifo_edge_i;
dr_fifo_in_int(86 downto 83) <= regs_i.fifo_channel_i;
dr_fifo_rst_n <= rst_n_i;
dr_fifo_INST : wbgen2_fifo_async
generic map (
g_size => 256,
g_width => 87,
g_usedw_size => 8
)
port map (
wr_req_i => regs_i.fifo_wr_req_i,
wr_full_o => regs_o.fifo_wr_full_o,
wr_empty_o => regs_o.fifo_wr_empty_o,
wr_usedw_o => regs_o.fifo_wr_usedw_o,
rd_full_o => dr_fifo_full_int,
rd_empty_o => dr_fifo_empty_int,
rd_usedw_o => dr_fifo_usedw_int,
rd_req_i => dr_fifo_rdreq_int,
rst_n_i => dr_fifo_rst_n,
wr_clk_i => clk_tdc_i,
rd_clk_i => clk_sys_i,
wr_data_i => dr_fifo_in_int,
rd_data_o => dr_fifo_out_int
);
-- Channel enable
regs_o.chan_enable_o <= dr_chan_enable_int;
-- Dead time (8ns ticks)
regs_o.dead_time_o <= dr_dead_time_int;
-- extra code for reg/fifo/mem: FIFO 'Readout FIFO' data output register 0
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
dr_fifo_rdreq_int_d0 <= '0';
elsif rising_edge(clk_sys_i) then
dr_fifo_rdreq_int_d0 <= dr_fifo_rdreq_int;
end if;
end process;
-- extra code for reg/fifo/mem: FIFO 'Readout FIFO' data output register 1
-- extra code for reg/fifo/mem: FIFO 'Readout FIFO' data output register 2
rwaddr_reg <= wb_adr_i;
wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i);
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
peripheral
{
name = "TDC Direct Readout WB Slave";
hdl_entity = "fmc_tdc_direct_readout_wb_slave";
prefix = "dr";
fifo_reg {
name = "Readout FIFO";
prefix = "FIFO";
direction = CORE_TO_BUS;
size = 256;
flags_bus = {FIFO_EMPTY, FIFO_FULL, FIFO_COUNT, FIFO_RESET};
flags_dev = {FIFO_EMPTY, FIFO_FULL, FIFO_COUNT, FIFO_RESET};
clock = "clk_tdc_i";
field {
name = "Seconds";
prefix = "SECONDS";
type = SLV;
size = 32;
};
field {
name = "Cycles";
prefix = "CYCLES";
type = SLV;
size = 32;
};
field {
name = "Bins";
prefix = "BINS";
type = SLV;
size = 18;
};
field {
name = "Edge";
prefix = "EDGE";
type = BIT;
};
field {
name = "Channel";
prefix = "CHANNEL";
type = SLV;
size = 4;
};
};
reg {
name = "Channel Enable Register";
prefix = "CHAN_ENABLE";
clock = "clk_tdc_i";
field {
name = "Channel enable";
size = 5;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Dead Time Register";
prefix = "DEAD_TIME";
clock = "clk_tdc_i";
field {
name = "Dead time (8ns ticks)";
size = 24;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
};
\ No newline at end of file
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for TDC Direct Readout WB Slave
---------------------------------------------------------------------------------------
-- File : fmc_tdc_direct_readout_slave_pkg.vhd
-- Author : auto-generated by wbgen2 from fmc_tdc_direct_readout_slave.wb
-- Created : Thu May 15 14:23:14 2014
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fmc_tdc_direct_readout_slave.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wbgen2_pkg.all;
package dr_wbgen2_pkg is
-- Input registers (user design -> WB slave)
type t_dr_in_registers is record
fifo_wr_req_i : std_logic;
fifo_seconds_i : std_logic_vector(31 downto 0);
fifo_cycles_i : std_logic_vector(31 downto 0);
fifo_bins_i : std_logic_vector(17 downto 0);
fifo_edge_i : std_logic;
fifo_channel_i : std_logic_vector(3 downto 0);
end record;
constant c_dr_in_registers_init_value: t_dr_in_registers := (
fifo_wr_req_i => '0',
fifo_seconds_i => (others => '0'),
fifo_cycles_i => (others => '0'),
fifo_bins_i => (others => '0'),
fifo_edge_i => '0',
fifo_channel_i => (others => '0')
);
-- Output registers (WB slave -> user design)
type t_dr_out_registers is record
fifo_wr_full_o : std_logic;
fifo_wr_empty_o : std_logic;
fifo_wr_usedw_o : std_logic_vector(7 downto 0);
chan_enable_o : std_logic_vector(4 downto 0);
dead_time_o : std_logic_vector(23 downto 0);
end record;
constant c_dr_out_registers_init_value: t_dr_out_registers := (
fifo_wr_full_o => '0',
fifo_wr_empty_o => '0',
fifo_wr_usedw_o => (others => '0'),
chan_enable_o => (others => '0'),
dead_time_o => (others => '0')
);
function "or" (left, right: t_dr_in_registers) return t_dr_in_registers;
function f_x_to_zero (x:std_logic) return std_logic;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector;
end package;
package body dr_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
if x = '1' then
return '1';
else
return '0';
end if;
end function;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
begin
for i in 0 to x'length-1 loop
if(x(i) = 'X' or x(i) = 'U') then
tmp(i):= '0';
else
tmp(i):=x(i);
end if;
end loop;
return tmp;
end function;
function "or" (left, right: t_dr_in_registers) return t_dr_in_registers is
variable tmp: t_dr_in_registers;
begin
tmp.fifo_wr_req_i := f_x_to_zero(left.fifo_wr_req_i) or f_x_to_zero(right.fifo_wr_req_i);
tmp.fifo_seconds_i := f_x_to_zero(left.fifo_seconds_i) or f_x_to_zero(right.fifo_seconds_i);
tmp.fifo_cycles_i := f_x_to_zero(left.fifo_cycles_i) or f_x_to_zero(right.fifo_cycles_i);
tmp.fifo_bins_i := f_x_to_zero(left.fifo_bins_i) or f_x_to_zero(right.fifo_bins_i);
tmp.fifo_edge_i := f_x_to_zero(left.fifo_edge_i) or f_x_to_zero(right.fifo_edge_i);
tmp.fifo_channel_i := f_x_to_zero(left.fifo_channel_i) or f_x_to_zero(right.fifo_channel_i);
return tmp;
end function;
end package body;
--_________________________________________________________________________________________________
-- |
-- |SPEC TDC| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- spec_top_fmc_tdc |
-- |
---------------------------------------------------------------------------------------------------
-- File spec_top_fmc_tdc.vhd |
-- |
-- Description TDC top level for a SPEC carrier. Figure 1 shows the architecture of the unit. |
-- |
-- For the communication with the PCIe, the ohwr.org GN4124 core is instantiated. |
-- |
-- The TDC mezzanine core is instantiated for the communication with the TDC board. |
-- The VIC core is forwarding the interrupts coming from the TDC mezzanine core to |
-- the GN4124 core. |
-- The carrier_info module provides general information on the SPEC PCB version, PLLs |
-- locking state etc. |
-- The 1-Wire core provides communication with the SPEC Thermometer&UniqueID chip. |
-- All the cores communicate with the GN4124 core through the SDB crossbar. The SDB |
-- crossbar is responsible for managing the acess to the GN4124 core. |
-- |
-- The speed of all the cores (TDC mezzanine, VIC, carrier csr, 1-Wire as well as |
-- the GN4124 core) is 125MHz. |
-- |
-- The 125MHz clock comes from the PLL located on the TDC mezzanine board. |
-- The clks_rsts_manager unit is responsible for automatically configuring the PLL |
-- upon the FPGA startup or after a PCIe reset, using the 20MHz VCXO on the SPEC |
-- carrier board. The clks_rsts_manager is keeping all the rest of the logic under |
-- reset until the PLL gets locked. |
-- |
-- __________________________________________________________________ |
-- ________ | ___ _____ | |
-- | | | ___________________ | | | | | |
-- | PLL |<->| | clks rsts manager | | | | | | |
-- | DAC | | |___________________| | | | | | |
-- | | | ____________________________ | | | | | |
-- | | | | | \ | | | | | |
-- | ACAM |<->| | TDC mezzanine | \ | | | | | |
-- |________| | |--|____________________________| \ | | | G | | |
-- TDC mezz | | \ | | | | | |
-- | | ____________________________ | S | | N | | |
-- | |->| | | | | | | |
-- | | Vector Interrupt Controller| ---- | D | <--> | 4 | | |
-- | |____________________________| | | | | | |
-- | | B | | 1 | | |
-- | ____________________________ | | | | | |
-- | | | | | | 2 | | |
-- SPEC 1Wire <->| | 1-Wire | ---- | | | | | |
-- | |____________________________| | | | 4 | | |
-- | / | | | | | |
-- | ____________________________ / | | | | | |
-- | | | / | | | | | |
-- | | carrier_info | / | | | | | |
-- | |____________________________| | | | | | |
-- | |___| |_____| | |
-- | | |
-- | ______________________________________________ | |
-- SPEC LEDs <->| |___________________LEDs_______________________| | |
-- | | |
-- |__________________________________________________________________| |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 01/2014 |
-- Version v5 (see sdb_meta_pkg) |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 05/2011 v1 GP First version |
-- 06/2012 v2 EG Revamping; Comments added, signals renamed |
-- removed LEDs from top level |
-- new GN4124 core integrated |
-- carrier 1 wire master added |
-- mezzanine I2C master added |
-- mezzanine 1 wire master added |
-- interrupts generator added |
-- changed generation of rst_125m_mezz |
-- DAC reconfiguration+needed regs added |
-- 06/2012 v3 EG Changes for v2 of TDC mezzanine |
-- Several pinout changes, |
-- acam_ref_clk LVDS instead of CMOS, |
-- no PLL_LD only PLL_STATUS |
-- 04/2013 v4 EG added SDB; fixed bugs in data_formatting; added carrier CSR information |
-- 01/2014 v5 EG added VIC and EIC in the TDC mezzanine |
-- |
----------------------------------------------/!\-------------------------------------------------|
-- Note for eva: Remember the design is synthesised with Synplify Premier with DP (tdc_syn.prj) |
-- For PAR use the tdc_par_script.tcl commands in Xilinx ISE! |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.tdc_core_pkg.all;
use work.gencores_pkg.all;
use work.wishbone_pkg.all;
library UNISIM;
use UNISIM.vcomponents.all;
--=================================================================================================
-- Entity declaration for spec_top_fmc_tdc
--=================================================================================================
entity fmc_tdc_wrapper is
generic
(g_simulation : boolean := false); -- this generic is set to TRUE
-- when instantiated in a test-bench
port
(
clk_sys_i : in std_logic;
rst_sys_n_i : in std_logic;
rst_n_a_i : in std_logic;
-- Interface with the PLL AD9516 and DAC AD5662 on TDC mezzanine
pll_sclk_o : out std_logic; -- SPI clock
pll_sdi_o : out std_logic; -- data line for PLL and DAC
pll_cs_o : out std_logic; -- PLL chip select
pll_dac_sync_o : out std_logic; -- DAC chip select
pll_sdo_i : in std_logic; -- not used for the moment
pll_status_i : in std_logic; -- PLL Digital Lock Detect, active high
tdc_clk_125m_p_i : in std_logic; -- 125 MHz differential clock: system clock
tdc_clk_125m_n_i : in std_logic; -- 125 MHz differential clock: system clock
acam_refclk_p_i : in std_logic; -- 31.25 MHz differential clock: ACAM ref clock
acam_refclk_n_i : in std_logic; -- 31.25 MHz differential clock: ACAM ref clock
-- Timing interface with the ACAM on TDC mezzanine
start_from_fpga_o : out std_logic; -- start signal
err_flag_i : in std_logic; -- error flag
int_flag_i : in std_logic; -- interrupt flag
start_dis_o : out std_logic; -- start disable, not used
stop_dis_o : out std_logic; -- stop disable, not used
-- Data interface with the ACAM on TDC mezzanine
data_bus_io : inout std_logic_vector(27 downto 0);
address_o : out std_logic_vector(3 downto 0);
cs_n_o : out std_logic; -- chip select for ACAM
oe_n_o : out std_logic; -- output enable for ACAM
rd_n_o : out std_logic; -- read signal for ACAM
wr_n_o : out std_logic; -- write signal for ACAM
ef1_i : in std_logic; -- empty flag iFIFO1
ef2_i : in std_logic; -- empty flag iFIFO2
-- Enable of input Logic on TDC mezzanine
enable_inputs_o : out std_logic; -- enables all 5 inputs
term_en_1_o : out std_logic; -- Ch.1 termination enable of 50 Ohm termination
term_en_2_o : out std_logic; -- Ch.2 termination enable of 50 Ohm termination
term_en_3_o : out std_logic; -- Ch.3 termination enable of 50 Ohm termination
term_en_4_o : out std_logic; -- Ch.4 termination enable of 50 Ohm termination
term_en_5_o : out std_logic; -- Ch.5 termination enable of 50 Ohm termination
-- LEDs on TDC mezzanine
tdc_led_status_o : out std_logic; -- amber led on front pannel, division of 125 MHz tdc_clk
tdc_led_trig1_o : out std_logic; -- amber led on front pannel, Ch.1 enable
tdc_led_trig2_o : out std_logic; -- amber led on front pannel, Ch.2 enable
tdc_led_trig3_o : out std_logic; -- amber led on front pannel, Ch.3 enable
tdc_led_trig4_o : out std_logic; -- amber led on front pannel, Ch.4 enable
tdc_led_trig5_o : out std_logic; -- amber led on front pannel, Ch.5 enable
-- Input Logic on TDC mezzanine (not used currently)
tdc_in_fpga_1_i : in std_logic; -- Ch.1 for ACAM, also received by FPGA
tdc_in_fpga_2_i : in std_logic; -- Ch.2 for ACAM, also received by FPGA
tdc_in_fpga_3_i : in std_logic; -- Ch.3 for ACAM, also received by FPGA
tdc_in_fpga_4_i : in std_logic; -- Ch.4 for ACAM, also received by FPGA
tdc_in_fpga_5_i : in std_logic; -- Ch.5 for ACAM, also received by FPGA
-- I2C EEPROM interface on TDC mezzanine
mezz_scl_b : inout std_logic;
mezz_sda_b : inout std_logic;
-- 1-wire interface on TDC mezzanine
mezz_one_wire_b : inout std_logic;
---------------------------------------------------------------------------
-- WhiteRabbit time/frequency sync (see WR Core documentation)
---------------------------------------------------------------------------
tm_link_up_i : in std_logic;
tm_time_valid_i : in std_logic;
tm_cycles_i : in std_logic_vector(27 downto 0);
tm_tai_i : in std_logic_vector(39 downto 0);
tm_clk_aux_lock_en_o : out std_logic;
tm_clk_aux_locked_i : in std_logic;
tm_clk_dmtd_locked_i : in std_logic;
tm_dac_value_i : in std_logic_vector(23 downto 0);
tm_dac_wr_i : in std_logic;
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
direct_slave_i : in t_wishbone_slave_in;
direct_slave_o : out t_wishbone_slave_out;
irq_o : out std_logic
); -- Mezzanine presence (active low)
end fmc_tdc_wrapper;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of fmc_tdc_wrapper is
-----------------------------------------------------------------
-- Signals --
---------------------------------------------------------------------------------------------------
-- WRabbit clocks
signal clk_62m5_sys, clk_125m_mezz : std_logic;
signal rst_125m_mezz_n, rst_125m_mezz : std_logic;
signal acam_refclk_r_edge_p : std_logic;
-- DAC configuration through PCIe/VME
signal send_dac_word_p : std_logic;
signal dac_word : std_logic_vector(23 downto 0);
-- WRabbit time
signal pll_sclk, pll_sdi, pll_dac_sync : std_logic;
signal tdc_slave_in : t_wishbone_slave_in;
signal tdc_slave_out : t_wishbone_slave_out;
signal fmc_eic_irq : std_logic;
signal fmc_eic_irq_synch : std_logic_vector(1 downto 0);
signal tdc_scl_out, tdc_scl_oen, tdc_sda_out, tdc_sda_oen : std_logic;
signal direct_timestamp : std_logic_vector(127 downto 0);
signal direct_timestamp_wr : std_logic;
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
mezz_scl_b <= tdc_scl_out when (tdc_scl_oen = '0') else 'Z';
mezz_sda_b <= tdc_sda_out when (tdc_sda_oen = '0') else 'Z';
cmp_tdc_clks_rsts_mgment : clks_rsts_manager
generic map
(nb_of_reg => 68)
port map
(clk_sys_i => clk_sys_i,
acam_refclk_p_i => acam_refclk_p_i,
acam_refclk_n_i => acam_refclk_n_i,
tdc_125m_clk_p_i => tdc_clk_125m_p_i,
tdc_125m_clk_n_i => tdc_clk_125m_n_i,
rst_n_i => rst_n_a_i,
pll_sdo_i => pll_sdo_i,
pll_status_i => pll_status_i,
send_dac_word_p_i => send_dac_word_p,
dac_word_i => dac_word,
acam_refclk_r_edge_p_o => acam_refclk_r_edge_p,
wrabbit_dac_value_i => tm_dac_value_i,
wrabbit_dac_wr_p_i => tm_dac_wr_i,
internal_rst_o => rst_125m_mezz,
pll_cs_n_o => pll_cs_o,
pll_dac_sync_n_o => pll_dac_sync,
pll_sdi_o => pll_sdi,
pll_sclk_o => pll_sclk,
tdc_125m_clk_o => clk_125m_mezz,
pll_status_o => open);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
rst_125m_mezz_n <= not rst_125m_mezz;
pll_dac_sync_o <= pll_dac_sync;
pll_sdi_o <= pll_sdi;
pll_sclk_o <= pll_sclk;
---------------------------------------------------------------------------------------------------
-- TDC BOARD --
---------------------------------------------------------------------------------------------------
cmp_tdc_mezz : fmc_tdc_mezzanine
generic map
(g_span => 32,
g_width => 32,
values_for_simul => g_simulation)
port map
-- 62M5 clk and reset
(clk_sys_i => clk_sys_i,
rst_sys_n_i => rst_sys_n_i,
-- 125M clk and reset
clk_ref_0_i => clk_125m_mezz,
rst_ref_0_i => rst_125m_mezz,
-- Configuration of the DAC on the TDC mezzanine, non White Rabbit
acam_refclk_r_edge_p_i => acam_refclk_r_edge_p,
send_dac_word_p_o => send_dac_word_p,
dac_word_o => dac_word,
-- ACAM interface
start_from_fpga_o => start_from_fpga_o,
err_flag_i => err_flag_i,
int_flag_i => int_flag_i,
start_dis_o => start_dis_o,
stop_dis_o => stop_dis_o,
data_bus_io => data_bus_io,
address_o => address_o,
cs_n_o => cs_n_o,
oe_n_o => oe_n_o,
rd_n_o => rd_n_o,
wr_n_o => wr_n_o,
ef1_i => ef1_i,
ef2_i => ef2_i,
-- Input channels enable
enable_inputs_o => enable_inputs_o,
term_en_1_o => term_en_1_o,
term_en_2_o => term_en_2_o,
term_en_3_o => term_en_3_o,
term_en_4_o => term_en_4_o,
term_en_5_o => term_en_5_o,
-- LEDs on TDC mezzanine
tdc_led_status_o => tdc_led_status_o,
tdc_led_trig1_o => tdc_led_trig1_o,
tdc_led_trig2_o => tdc_led_trig2_o,
tdc_led_trig3_o => tdc_led_trig3_o,
tdc_led_trig4_o => tdc_led_trig4_o,
tdc_led_trig5_o => tdc_led_trig5_o,
-- Input channels to FPGA (not used)
tdc_in_fpga_1_i => tdc_in_fpga_1_i,
tdc_in_fpga_2_i => tdc_in_fpga_2_i,
tdc_in_fpga_3_i => tdc_in_fpga_3_i,
tdc_in_fpga_4_i => tdc_in_fpga_4_i,
tdc_in_fpga_5_i => tdc_in_fpga_5_i,
-- WISHBONE interface with the GN4124 core
wb_tdc_csr_adr_i => tdc_slave_in.adr,
wb_tdc_csr_dat_i => tdc_slave_in.dat,
wb_tdc_csr_stb_i => tdc_slave_in.stb,
wb_tdc_csr_we_i => tdc_slave_in.we,
wb_tdc_csr_cyc_i => tdc_slave_in.cyc,
wb_tdc_csr_sel_i => tdc_slave_in.sel,
wb_tdc_csr_dat_o => tdc_slave_out.dat,
wb_tdc_csr_ack_o => tdc_slave_out.ack,
wb_tdc_csr_stall_o => tdc_slave_out.stall,
-- White Rabbit
wrabbit_link_up_i => tm_link_up_i,
wrabbit_time_valid_i => tm_time_valid_i,
wrabbit_cycles_i => tm_cycles_i,
wrabbit_utc_i => tm_tai_i(31 downto 0),
wrabbit_utc_p_o => open, -- for debug
wrabbit_clk_aux_lock_en_o => tm_clk_aux_lock_en_o,
wrabbit_clk_aux_locked_i => tm_clk_aux_locked_i,
wrabbit_clk_dmtd_locked_i => '1', -- FIXME: fan out real signal from the WRCore
wrabbit_dac_value_i => tm_dac_value_i,
wrabbit_dac_wr_p_i => tm_dac_wr_i,
-- Interrupt line from EIC
wb_irq_o => fmc_eic_irq,
-- EEPROM I2C on TDC mezzanine
i2c_scl_oen_o => tdc_scl_oen,
i2c_scl_i => mezz_scl_b,
i2c_sda_oen_o => tdc_sda_oen,
i2c_sda_i => mezz_sda_b,
i2c_scl_o => tdc_scl_out,
i2c_sda_o => tdc_sda_out,
-- 1-Wire on TDC mezzanine
one_wire_b => mezz_one_wire_b,
direct_timestamp_o => direct_timestamp,
direct_timestamp_stb_o => direct_timestamp_wr);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Domains crossing: clk_125m_mezz <-> clk_62m5_sys
cmp_tdc_clk_crossing : xwb_clock_crossing
port map
(slave_clk_i => clk_sys_i,
slave_rst_n_i => rst_sys_n_i,
slave_i => slave_i,
slave_o => slave_o,
master_clk_i => clk_125m_mezz, -- Master reader port: TDC core at 125 MHz
master_rst_n_i => rst_125m_mezz_n,
master_i => tdc_slave_out,
master_o => tdc_slave_in);
tdc_slave_out.err <= '0';
tdc_slave_out.rty <= '0';
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Domains crossing: synchronization of the wb_ird_o from 125MHz to 62.5MHz
irq_pulse_synchronizer : process (clk_sys_i)
begin
if rising_edge (clk_sys_i) then
if rst_sys_n_i = '0' then
fmc_eic_irq_synch <= (others => '0');
else
fmc_eic_irq_synch <= fmc_eic_irq_synch(0) & fmc_eic_irq;
end if;
end if;
irq_o <= fmc_eic_irq_synch(1);
end process;
U_DirectRD: fmc_tdc_direct_readout
port map (
clk_tdc_i => clk_125m_mezz,
rst_tdc_n_i => rst_125m_mezz_n,
clk_sys_i => clk_sys_i,
rst_sys_n_i => rst_sys_n_i,
direct_timestamp_i => direct_timestamp,
direct_timestamp_wr_i => direct_timestamp_wr,
direct_slave_i => direct_slave_i,
direct_slave_o => direct_slave_o);
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- sdb_meta_pkg |
-- |
---------------------------------------------------------------------------------------------------
-- File sdb_meta_pkg.vhd |
-- |
-- Description Sdb meta-information for the FMC TDC design for SPEC. |
-- |
-- Authors Matthieu Cattin (matthieu.cattin@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 04/2013 |
-- Version v1 |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
package sdb_meta_pkg is
------------------------------------------------------------------------------
-- Meta-information sdb records
------------------------------------------------------------------------------
-- Top module repository url
constant c_SDB_REPO_URL : t_sdb_repo_url := (
-- url (string, 63 char)
repo_url => "http://svn.ohwr.org/fmc-tdc/hdl/spec/ ");
-- Synthesis informations
constant c_SDB_SYNTHESIS : t_sdb_synthesis := (
-- Top module name (string, 16 char)
syn_module_name => "spec_top_fmc_tdc",
-- Commit ID (hex string, 128-bit = 32 char)
-- git log -1 --format="%H" | cut -c1-320
syn_commit_id => x"00000000",
-- Synthesis tool name (string, 8 char)
syn_tool_name => "ISE ",
-- Synthesis tool version (bcd encoded, 32-bit)
syn_tool_version => x"00000134",
-- Synthesis date (bcd encoded, 32-bit)
syn_date => x"20140121",
-- Synthesised by (string, 15 char)
syn_username => "egousiou ");
-- Integration record
constant c_SDB_INTEGRATION : t_sdb_integration := (
product => (
vendor_id => x"000000000000CE42", -- CERN
device_id => x"593b56e5", -- echo "spec_fmc-tdc-1ns5cha" | md5sum | cut -c1-8
version => x"00050000", -- bcd encoded, [31:16] = major, [15:0] = minor
date => x"20140121", -- yyyymmdd
name => "spec_top_fmc_tdc "));
end sdb_meta_pkg;
package body sdb_meta_pkg is
end sdb_meta_pkg;
\ No newline at end of file
library ieee;
use ieee.STD_LOGIC_1164.all;
use ieee.NUMERIC_STD.all;
use work.gencores_pkg.all;
entity spec_reset_gen is
port (
clk_sys_i : in std_logic;
rst_pcie_n_a_i : in std_logic;
rst_button_n_a_i : in std_logic;
rst_n_o : out std_logic
);
end spec_reset_gen;
architecture behavioral of spec_reset_gen is
signal powerup_cnt : unsigned(7 downto 0) := x"00";
signal button_synced_n : std_logic;
signal pcie_synced_n : std_logic;
signal powerup_n : std_logic := '0';
begin -- behavioral
U_EdgeDet_PCIe : gc_sync_ffs port map (
clk_i => clk_sys_i,
rst_n_i => '1',
data_i => rst_pcie_n_a_i,
ppulse_o => pcie_synced_n);
U_Sync_Button : gc_sync_ffs port map (
clk_i => clk_sys_i,
rst_n_i => '1',
data_i => rst_button_n_a_i,
synced_o => button_synced_n);
p_powerup_reset : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if(powerup_cnt /= x"ff") then
powerup_cnt <= powerup_cnt + 1;
powerup_n <= '0';
else
powerup_n <= '1';
end if;
end if;
end process;
rst_n_o <= powerup_n and button_synced_n and (not pcie_synced_n);
end behavioral;
#----------------------------------------
# Clocks
#----------------------------------------
NET "clk_20m_vcxo_i" LOC = H12;
NET "clk_20m_vcxo_i" IOSTANDARD = "LVCMOS25";
NET "clk_20m_vcxo_i" TNM_NET = "clk_20m_vcxo_i";
TIMESPEC TS_clk_20m_vcxo_i = PERIOD "clk_20m_vcxo_i" 50 ns HIGH 50%;
NET "clk_125m_pllref_n_i" LOC = F10;
NET "clk_125m_pllref_n_i" IOSTANDARD = "LVDS_25";
NET "clk_125m_pllref_p_i" LOC = G9;
NET "clk_125m_pllref_p_i" IOSTANDARD = "LVDS_25";
NET "clk_125m_pllref_p_i" TNM_NET = clk_125m_pllref_p_i;
TIMESPEC TS_clk_125m_pllref_p_i = PERIOD "clk_125m_pllref_p_i" 8 ns HIGH 50%;
NET "clk_125m_pllref_n_i" TNM_NET = clk_125m_pllref_n_i;
TIMESPEC TS_clk_125m_pllref_n_i = PERIOD "clk_125m_pllref_n_i" 8 ns HIGH 50%;
NET "clk_125m_gtp_n_i" LOC = D11;
NET "clk_125m_gtp_p_i" LOC = C11;
NET "clk_125m_gtp_n_i" TNM_NET = clk_125m_gtp_n_i;
TIMESPEC TS_clk_125m_gtp_n_i = PERIOD "clk_125m_gtp_n_i" 8 ns HIGH 50%;
NET "clk_125m_gtp_p_i" TNM_NET = clk_125m_gtp_p_i;
TIMESPEC TS_clk_125m_gtp_p_i = PERIOD "clk_125m_gtp_p_i" 8 ns HIGH 50%;
NET "tdc_clk_125m_p_i" LOC = "L20";
NET "tdc_clk_125m_p_i" IOSTANDARD = "LVDS_25";
NET "tdc_clk_125m_p_i" TNM_NET = "tdc_clk_125m_p_i";
TIMESPEC TStdc_clk_125m_p_i = PERIOD "tdc_clk_125m_p_i" 8 ns HIGH 50%;
NET "tdc_clk_125m_n_i" LOC = "L22";
NET "tdc_clk_125m_n_i" IOSTANDARD = "LVDS_25";
NET "tdc_clk_125m_n_i" TNM_NET = "tdc_clk_125m_n_i";
TIMESPEC TS_tdc_clk_125m_n_i = PERIOD "tdc_clk_125m_n_i" 8 ns HIGH 50%;
NET "p2l_clk_n_i" LOC = M19;
NET "p2l_clk_n_i" IOSTANDARD = "DIFF_SSTL18_I";
NET "p2l_clk_p_i" LOC = M20;
NET "p2l_clk_p_i" IOSTANDARD = "DIFF_SSTL18_I";
NET "p2l_clk_p_i" TNM_NET = "p2l_clk_p_i";
TIMESPEC TS_p2l_clk_p_i = PERIOD "p2l_clk_p_i" 5 ns HIGH 50%;
NET "p2l_clk_n_i" TNM_NET = "p2l_clk_n_i";
TIMESPEC TS_p2l_clk_n_i = PERIOD "p2l_clk_n_i" 5 ns HIGH 50%;
#----------------------------------------
# FMC slot
#----------------------------------------
# <ucfgen_start>
# This section has bee generated automatically by ucfgen.py. Do not hand-modify if not really necessary.
# ucfgen pin assignments for mezzanine fmc-tdc-v3 slot 0
NET "acam_refclk_p_i" LOC = "E16";
NET "acam_refclk_p_i" IOSTANDARD = "LVDS_25";
NET "acam_refclk_n_i" LOC = "F16";
NET "acam_refclk_n_i" IOSTANDARD = "LVDS_25";
NET "tdc_led_trig1_o" LOC = "W18";
NET "tdc_led_trig1_o" IOSTANDARD = "LVCMOS25";
NET "tdc_led_trig2_o" LOC = "B20";
NET "tdc_led_trig2_o" IOSTANDARD = "LVCMOS25";
NET "tdc_led_trig3_o" LOC = "A20";
NET "tdc_led_trig3_o" IOSTANDARD = "LVCMOS25";
NET "term_en_1_o" LOC = "Y11";
NET "term_en_1_o" IOSTANDARD = "LVCMOS25";
NET "term_en_2_o" LOC = "AB11";
NET "term_en_2_o" IOSTANDARD = "LVCMOS25";
NET "ef1_i" LOC = "W12";
NET "ef1_i" IOSTANDARD = "LVCMOS25";
NET "ef2_i" LOC = "Y12";
NET "ef2_i" IOSTANDARD = "LVCMOS25";
NET "term_en_3_o" LOC = "R11";
NET "term_en_3_o" IOSTANDARD = "LVCMOS25";
NET "term_en_4_o" LOC = "T11";
NET "term_en_4_o" IOSTANDARD = "LVCMOS25";
NET "term_en_5_o" LOC = "R13";
NET "term_en_5_o" IOSTANDARD = "LVCMOS25";
NET "tdc_led_status_o" LOC = "T14";
NET "tdc_led_status_o" IOSTANDARD = "LVCMOS25";
NET "tdc_led_trig4_o" LOC = "D17";
NET "tdc_led_trig4_o" IOSTANDARD = "LVCMOS25";
NET "tdc_led_trig5_o" LOC = "C18";
NET "tdc_led_trig5_o" IOSTANDARD = "LVCMOS25";
NET "pll_sclk_o" LOC = "AA16";
NET "pll_sclk_o" IOSTANDARD = "LVCMOS25";
NET "pll_dac_sync_o" LOC = "AB16";
NET "pll_dac_sync_o" IOSTANDARD = "LVCMOS25";
NET "pll_cs_o" LOC = "Y17";
NET "pll_cs_o" IOSTANDARD = "LVCMOS25";
NET "cs_n_o" LOC = "AB17";
NET "cs_n_o" IOSTANDARD = "LVCMOS25";
NET "err_flag_i" LOC = "V11";
NET "err_flag_i" IOSTANDARD = "LVCMOS25";
NET "int_flag_i" LOC = "W11";
NET "int_flag_i" IOSTANDARD = "LVCMOS25";
NET "start_dis_o" LOC = "T15";
NET "start_dis_o" IOSTANDARD = "LVCMOS25";
NET "stop_dis_o" LOC = "U15";
NET "stop_dis_o" IOSTANDARD = "LVCMOS25";
NET "pll_sdo_i" LOC = "AB18";
NET "pll_sdo_i" IOSTANDARD = "LVCMOS25";
NET "pll_status_i" LOC = "Y18";
NET "pll_status_i" IOSTANDARD = "LVCMOS25";
NET "pll_sdi_o" LOC = "AA18";
NET "pll_sdi_o" IOSTANDARD = "LVCMOS25";
NET "start_from_fpga_o" LOC = "W17";
NET "start_from_fpga_o" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[27]" LOC = "AB4";
NET "data_bus_io[27]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[26]" LOC = "AA4";
NET "data_bus_io[26]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[25]" LOC = "AB9";
NET "data_bus_io[25]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[24]" LOC = "Y9";
NET "data_bus_io[24]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[23]" LOC = "Y10";
NET "data_bus_io[23]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[22]" LOC = "W10";
NET "data_bus_io[22]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[21]" LOC = "U10";
NET "data_bus_io[21]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[20]" LOC = "T10";
NET "data_bus_io[20]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[19]" LOC = "AB8";
NET "data_bus_io[19]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[18]" LOC = "AA8";
NET "data_bus_io[18]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[17]" LOC = "AB7";
NET "data_bus_io[17]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[16]" LOC = "Y7";
NET "data_bus_io[16]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[15]" LOC = "V9";
NET "data_bus_io[15]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[14]" LOC = "U9";
NET "data_bus_io[14]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[13]" LOC = "AB6";
NET "data_bus_io[13]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[12]" LOC = "AA6";
NET "data_bus_io[12]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[11]" LOC = "R8";
NET "data_bus_io[11]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[10]" LOC = "R9";
NET "data_bus_io[10]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[9]" LOC = "AB5";
NET "data_bus_io[9]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[8]" LOC = "Y5";
NET "data_bus_io[8]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[7]" LOC = "AB12";
NET "data_bus_io[7]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[6]" LOC = "U8";
NET "data_bus_io[6]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[5]" LOC = "AA12";
NET "data_bus_io[5]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[4]" LOC = "T8";
NET "data_bus_io[4]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[3]" LOC = "W8";
NET "data_bus_io[3]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[2]" LOC = "V7";
NET "data_bus_io[2]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[1]" LOC = "Y6";
NET "data_bus_io[1]" IOSTANDARD = "LVCMOS25";
NET "data_bus_io[0]" LOC = "W6";
NET "data_bus_io[0]" IOSTANDARD = "LVCMOS25";
NET "address_o[3]" LOC = "AB15";
NET "address_o[3]" IOSTANDARD = "LVCMOS25";
NET "address_o[2]" LOC = "Y15";
NET "address_o[2]" IOSTANDARD = "LVCMOS25";
NET "address_o[1]" LOC = "U12";
NET "address_o[1]" IOSTANDARD = "LVCMOS25";
NET "address_o[0]" LOC = "T12";
NET "address_o[0]" IOSTANDARD = "LVCMOS25";
NET "oe_n_o" LOC = "V13";
NET "oe_n_o" IOSTANDARD = "LVCMOS25";
NET "rd_n_o" LOC = "AB13";
NET "rd_n_o" IOSTANDARD = "LVCMOS25";
NET "wr_n_o" LOC = "Y13";
NET "wr_n_o" IOSTANDARD = "LVCMOS25";
NET "enable_inputs_o" LOC = "C19";
NET "enable_inputs_o" IOSTANDARD = "LVCMOS25";
NET "mezz_one_wire_b" LOC = "A19";
NET "mezz_one_wire_b" IOSTANDARD = "LVCMOS25";
# <ucfgen_end>
NET "mezz_sys_scl_b" LOC = "F7";
NET "mezz_sys_scl_b" IOSTANDARD = "LVCMOS25";
NET "mezz_sys_sda_b" LOC = "F8";
NET "mezz_sys_sda_b" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# 1-wire thermometer w/ ID
#----------------------------------------
NET "carrier_onewire_b" LOC = D4;
NET "carrier_onewire_b" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# GN4124 interface
#----------------------------------------
NET "rst_n_a_i" LOC = N20;
NET "rst_n_a_i" IOSTANDARD = "LVCMOS18";
NET "l2p_clk_n_o" LOC = K22;
NET "l2p_clk_n_o" IOSTANDARD = "DIFF_SSTL18_I";
NET "l2p_clk_p_o" LOC = K21;
NET "l2p_clk_p_o" IOSTANDARD = "DIFF_SSTL18_I";
NET "l2p_dframe_o" LOC = U22;
NET "l2p_dframe_o" IOSTANDARD = "SSTL18_I";
NET "l2p_edb_o" LOC = U20;
NET "l2p_edb_o" IOSTANDARD = "SSTL18_I";
NET "l2p_rdy_i" LOC = U19;
NET "l2p_rdy_i" IOSTANDARD = "SSTL18_I";
NET "l2p_valid_o" LOC = T18;
NET "l2p_valid_o" IOSTANDARD = "SSTL18_I";
NET "l_wr_rdy_i[0]" LOC = R20;
NET "l_wr_rdy_i[0]" IOSTANDARD = "SSTL18_I";
NET "l_wr_rdy_i[1]" LOC = T22;
NET "l_wr_rdy_i[1]" IOSTANDARD = "SSTL18_I";
#NET "L_CLKN" LOC = N19;
#NET "L_CLKN" IOSTANDARD = "DIFF_SSTL18_I";
#NET "L_CLKP" LOC = P20;
#NET "L_CLKP" IOSTANDARD = "DIFF_SSTL18_I";
NET "p2l_dframe_i" LOC = J22;
NET "p2l_dframe_i" IOSTANDARD = "SSTL18_I";
NET "p2l_rdy_o" LOC = J16;
NET "p2l_rdy_o" IOSTANDARD = "SSTL18_I";
NET "p2l_valid_i" LOC = L19;
NET "p2l_valid_i" IOSTANDARD = "SSTL18_I";
NET "p_rd_d_rdy_i[0]" LOC = N16;
NET "p_rd_d_rdy_i[0]" IOSTANDARD = "SSTL18_I";
NET "p_rd_d_rdy_i[1]" LOC = P19;
NET "p_rd_d_rdy_i[1]" IOSTANDARD = "SSTL18_I";
NET "p_wr_rdy_o[0]" LOC = L15;
NET "p_wr_rdy_o[0]" IOSTANDARD = "SSTL18_I";
NET "p_wr_rdy_o[1]" LOC = K16;
NET "p_wr_rdy_o[1]" IOSTANDARD = "SSTL18_I";
NET "p_wr_req_i[0]" LOC = M22;
NET "p_wr_req_i[0]" IOSTANDARD = "SSTL18_I";
NET "p_wr_req_i[1]" LOC = M21;
NET "p_wr_req_i[1]" IOSTANDARD = "SSTL18_I";
NET "rx_error_o" LOC = J17;
NET "rx_error_o" IOSTANDARD = "SSTL18_I";
NET "tx_error_i" LOC = M17;
NET "tx_error_i" IOSTANDARD = "SSTL18_I";
NET "vc_rdy_i[0]" LOC = B21;
NET "vc_rdy_i[0]" IOSTANDARD = "SSTL18_I";
NET "vc_rdy_i[1]" LOC = B22;
NET "vc_rdy_i[1]" IOSTANDARD = "SSTL18_I";
NET "l2p_data_o[0]" LOC = P16;
NET "l2p_data_o[0]" IOSTANDARD = "SSTL18_I";
NET "l2p_data_o[1]" LOC = P21;
NET "l2p_data_o[1]" IOSTANDARD = "SSTL18_I";
NET "l2p_data_o[2]" LOC = P18;
NET "l2p_data_o[2]" IOSTANDARD = "SSTL18_I";
NET "l2p_data_o[3]" LOC = T20;
NET "l2p_data_o[3]" IOSTANDARD = "SSTL18_I";
NET "l2p_data_o[4]" LOC = V21;
NET "l2p_data_o[4]" IOSTANDARD = "SSTL18_I";
NET "l2p_data_o[5]" LOC = V19;
NET "l2p_data_o[5]" IOSTANDARD = "SSTL18_I";
NET "l2p_data_o[6]" LOC = W22;
NET "l2p_data_o[6]" IOSTANDARD = "SSTL18_I";
NET "l2p_data_o[7]" LOC = Y22;
NET "l2p_data_o[7]" IOSTANDARD = "SSTL18_I";
NET "l2p_data_o[8]" LOC = P22;
NET "l2p_data_o[8]" IOSTANDARD = "SSTL18_I";
NET "l2p_data_o[9]" LOC = R22;
NET "l2p_data_o[9]" IOSTANDARD = "SSTL18_I";
NET "l2p_data_o[10]" LOC = T21;
NET "l2p_data_o[10]" IOSTANDARD = "SSTL18_I";
NET "l2p_data_o[11]" LOC = T19;
NET "l2p_data_o[11]" IOSTANDARD = "SSTL18_I";
NET "l2p_data_o[12]" LOC = V22;
NET "l2p_data_o[12]" IOSTANDARD = "SSTL18_I";
NET "l2p_data_o[13]" LOC = V20;
NET "l2p_data_o[13]" IOSTANDARD = "SSTL18_I";
NET "l2p_data_o[14]" LOC = W20;
NET "l2p_data_o[14]" IOSTANDARD = "SSTL18_I";
NET "l2p_data_o[15]" LOC = Y21;
NET "l2p_data_o[15]" IOSTANDARD = "SSTL18_I";
NET "p2l_data_i[0]" LOC = K20;
NET "p2l_data_i[0]" IOSTANDARD = "SSTL18_I";
NET "p2l_data_i[1]" LOC = H22;
NET "p2l_data_i[1]" IOSTANDARD = "SSTL18_I";
NET "p2l_data_i[2]" LOC = H21;
NET "p2l_data_i[2]" IOSTANDARD = "SSTL18_I";
NET "p2l_data_i[3]" LOC = L17;
NET "p2l_data_i[3]" IOSTANDARD = "SSTL18_I";
NET "p2l_data_i[4]" LOC = K17;
NET "p2l_data_i[4]" IOSTANDARD = "SSTL18_I";
NET "p2l_data_i[5]" LOC = G22;
NET "p2l_data_i[5]" IOSTANDARD = "SSTL18_I";
NET "p2l_data_i[6]" LOC = G20;
NET "p2l_data_i[6]" IOSTANDARD = "SSTL18_I";
NET "p2l_data_i[7]" LOC = K18;
NET "p2l_data_i[7]" IOSTANDARD = "SSTL18_I";
NET "p2l_data_i[8]" LOC = K19;
NET "p2l_data_i[8]" IOSTANDARD = "SSTL18_I";
NET "p2l_data_i[9]" LOC = H20;
NET "p2l_data_i[9]" IOSTANDARD = "SSTL18_I";
NET "p2l_data_i[10]" LOC = J19;
NET "p2l_data_i[10]" IOSTANDARD = "SSTL18_I";
NET "p2l_data_i[11]" LOC = E22;
NET "p2l_data_i[11]" IOSTANDARD = "SSTL18_I";
NET "p2l_data_i[12]" LOC = E20;
NET "p2l_data_i[12]" IOSTANDARD = "SSTL18_I";
NET "p2l_data_i[13]" LOC = F22;
NET "p2l_data_i[13]" IOSTANDARD = "SSTL18_I";
NET "p2l_data_i[14]" LOC = F21;
NET "p2l_data_i[14]" IOSTANDARD = "SSTL18_I";
NET "p2l_data_i[15]" LOC = H19;
NET "p2l_data_i[15]" IOSTANDARD = "SSTL18_I";
NET "irq_p_o" LOC = U16;
NET "irq_p_o" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# PCB version number (coded with resistors)
#----------------------------------------
NET "pcb_ver_i[0]" LOC = P5;
NET "pcb_ver_i[0]" IOSTANDARD = "LVCMOS15";
NET "pcb_ver_i[1]" LOC = P4;
NET "pcb_ver_i[1]" IOSTANDARD = "LVCMOS15";
NET "pcb_ver_i[2]" LOC = AA2;
NET "pcb_ver_i[2]" IOSTANDARD = "LVCMOS15";
NET "pcb_ver_i[3]" LOC = AA1;
NET "pcb_ver_i[3]" IOSTANDARD = "LVCMOS15";
#----------------------------------------
# FMC Presence
#----------------------------------------
NET "prsnt_m2c_n_i" LOC = AB14;
NET "prsnt_m2c_n_i" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# TDC IN FPGA (not used)
#----------------------------------------
NET "tdc_in_fpga_1_i" LOC = V17;
NET "tdc_in_fpga_1_i" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# Carrier Generic Stuff
#----------------------------------------
NET "led_red" LOC = D5;
NET "led_red" IOSTANDARD = "LVCMOS25";
NET "led_green" LOC = E5;
NET "led_green" IOSTANDARD = "LVCMOS25";
NET "dac_cs1_n_o" LOC = A3;
NET "dac_cs1_n_o" IOSTANDARD = "LVCMOS25";
NET "dac_cs2_n_o" LOC = B3;
NET "dac_cs2_n_o" IOSTANDARD = "LVCMOS25";
#NET "dac_clr_n_o" LOC = F7;
#NET "dac_clr_n_o" IOSTANDARD = "LVCMOS25";
NET "dac_din_o" LOC = C4;
NET "dac_din_o" IOSTANDARD = "LVCMOS25";
NET "dac_sclk_o" LOC = A4;
NET "dac_sclk_o" IOSTANDARD = "LVCMOS25";
NET "button1_i" LOC = C22;
NET "button1_i" IOSTANDARD = "LVCMOS18";
NET "button2_i" LOC = D21;
NET "button2_i" IOSTANDARD = "LVCMOS18";
#----------------------------------------
# SFP
#----------------------------------------
NET "sfp_rxp_i" LOC= D15;
NET "sfp_rxn_i" LOC= C15;
NET "sfp_txp_o" LOC= B16;
NET "sfp_txn_o" LOC= A16;
NET "sfp_mod_def1_b" LOC = C17;
NET "sfp_mod_def1_b" IOSTANDARD = "LVCMOS25";
NET "sfp_mod_def0_b" LOC = G15;
NET "sfp_mod_def0_b" IOSTANDARD = "LVCMOS25";
NET "sfp_mod_def2_b" LOC = G16;
NET "sfp_mod_def2_b" IOSTANDARD = "LVCMOS25";
NET "sfp_rate_select_b" LOC = H14;
NET "sfp_rate_select_b" IOSTANDARD = "LVCMOS25";
NET "sfp_tx_fault_i" LOC = A17;
NET "sfp_tx_fault_i" IOSTANDARD = "LVCMOS25";
NET "sfp_tx_disable_o" LOC = F17;
NET "sfp_tx_disable_o" IOSTANDARD = "LVCMOS25";
NET "sfp_los_i" LOC = D18;
NET "sfp_los_i" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# UART
#----------------------------------------
NET "uart_rxd_i" LOC= A2;
NET "uart_rxd_i" IOSTANDARD=LVCMOS25;
NET "uart_txd_o" LOC= B2;
NET "uart_txd_o" IOSTANDARD=LVCMOS25;
#----------------------------------------
# False Path
#----------------------------------------
# GN4124
NET "rst_n_a_i" TIG;
NET "cmp_gn4124_core/rst_*" TIG;
NET "cmp_gn4124_core/cmp_clk_in/P_clk" TNM_NET = cmp_gn4124_core/cmp_clk_in/P_clk;
TIMESPEC TS_cmp_gn4124_core_cmp_clk_in_P_clk = PERIOD "cmp_gn4124_core/cmp_clk_in/P_clk" 5 ns HIGH 50%;
PIN "cmp_clk_dmtd_buf.O" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clk_62m5_sys" TNM_NET = clk_62m5_sys;
TIMESPEC ts_ignore_crossclock = FROM "clk_62m5_sys" TO "tdc_clk_125m_p_i" 10ns DATAPATHONLY;
TIMESPEC ts_ignore_crossclock2 = FROM "tdc_clk_125m_p_i" TO "clk_62m5_sys" 10ns DATAPATHONLY;
TIMESPEC ts_ignore_xclock1 = FROM "clk_62m5_sys" TO "clk_125m_pllref_n_i" 10ns DATAPATHONLY;
TIMESPEC ts_ignore_xclock2 = FROM "clk_125m_pllref_p_i" TO "clk_62m5_sys" 10ns DATAPATHONLY;
TIMESPEC ts_x3 = FROM "clk_62m5_sys" TO "U_GTP_ch1_rx_divclk" 10ns DATAPATHONLY;
TIMESPEC TS_x4 = FROM "U_GTP_ch1_rx_divclk" TO "clk_62m5_sys" 10ns DATAPATHONLY;
PIN "clk_125m_pllref_BUFG.O" CLOCK_DEDICATED_ROUTE = FALSE;
NET "U_GTP/ch1_gtp_clkout_int<1>" TNM_NET = U_GTP/ch1_gtp_clkout_int<1>;
TIMESPEC TS_U_GTP_ch1_gtp_clkout_int_1_ = PERIOD "U_GTP/ch1_gtp_clkout_int<1>" 125 MHz HIGH 50%;
##Created by Constraints Editor (xc6slx45t-fgg484-3) - 2012/08/07
INST "*/U_SOFTPLL/U_Wrapped_Softpll/gen_feedback_dmtds*/clk_in" TNM = skew_limit;
INST "*/U_SOFTPLL/U_Wrapped_Softpll/gen_ref_dmtds*/clk_in" TNM = skew_limit;
TIMESPEC TS_ = FROM "skew_limit" TO "FFS" 2 ns DATAPATHONLY;
#Created by Constraints Editor (xc6slx45t-fgg484-3) - 2012/08/08
INST "U_WR_CORE/WRPC/U_Endpoint/U_Wrapped_Endpoint/U_PCS_1000BASEX/gen_8bit.U_RX_PCS/timestamp_trigger_p_a_o" TNM = rx_ts_trig;
TIMESPEC TS_RXTS = FROM "rx_ts_trig" TO "FFS" 2 ns DATAPATHONLY;
--_________________________________________________________________________________________________
-- |
-- |SPEC TDC| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- spec_top_fmc_tdc |
-- |
---------------------------------------------------------------------------------------------------
-- File spec_top_fmc_tdc.vhd |
-- |
-- Description TDC top level for a SPEC carrier. Figure 1 shows the architecture of the unit. |
-- |
-- For the communication with the PCIe, the ohwr.org GN4124 core is instantiated. |
-- |
-- The TDC mezzanine core is instantiated for the communication with the TDC board. |
-- The VIC core is forwarding the interrupts coming from the TDC mezzanine core to |
-- the GN4124 core. |
-- The carrier_info module provides general information on the SPEC PCB version, PLLs |
-- locking state etc. |
-- The 1-Wire core provides communication with the SPEC Thermometer&UniqueID chip. |
-- All the cores communicate with the GN4124 core through the SDB crossbar. The SDB |
-- crossbar is responsible for managing the acess to the GN4124 core. |
-- |
-- The speed of all the cores (TDC mezzanine, VIC, carrier csr, 1-Wire as well as |
-- the GN4124 core) is 125MHz. |
-- |
-- The 125MHz clock comes from the PLL located on the TDC mezzanine board. |
-- The clks_rsts_manager unit is responsible for automatically configuring the PLL |
-- upon the FPGA startup or after a PCIe reset, using the 20MHz VCXO on the SPEC |
-- carrier board. The clks_rsts_manager is keeping all the rest of the logic under |
-- reset until the PLL gets locked. |
-- |
-- __________________________________________________________________ |
-- ________ | ___ _____ | |
-- | | | ___________________ | | | | | |
-- | PLL |<->| | clks rsts manager | | | | | | |
-- | DAC | | |___________________| | | | | | |
-- | | | ____________________________ | | | | | |
-- | | | | | \ | | | | | |
-- | ACAM |<->| | TDC mezzanine | \ | | | | | |
-- |________| | |--|____________________________| \ | | | G | | |
-- TDC mezz | | \ | | | | | |
-- | | ____________________________ | S | | N | | |
-- | |->| | | | | | | |
-- | | Vector Interrupt Controller| ---- | D | <--> | 4 | | |
-- | |____________________________| | | | | | |
-- | | B | | 1 | | |
-- | ____________________________ | | | | | |
-- | | | | | | 2 | | |
-- SPEC 1Wire <->| | 1-Wire | ---- | | | | | |
-- | |____________________________| | | | 4 | | |
-- | / | | | | | |
-- | ____________________________ / | | | | | |
-- | | | / | | | | | |
-- | | carrier_info | / | | | | | |
-- | |____________________________| | | | | | |
-- | |___| |_____| | |
-- | | |
-- | ______________________________________________ | |
-- SPEC LEDs <->| |___________________LEDs_______________________| | |
-- | | |
-- |__________________________________________________________________| |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 01/2014 |
-- Version v5 (see sdb_meta_pkg) |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 05/2011 v1 GP First version |
-- 06/2012 v2 EG Revamping; Comments added, signals renamed |
-- removed LEDs from top level |
-- new GN4124 core integrated |
-- carrier 1 wire master added |
-- mezzanine I2C master added |
-- mezzanine 1 wire master added |
-- interrupts generator added |
-- changed generation of rst_125m_mezz |
-- DAC reconfiguration+needed regs added |
-- 06/2012 v3 EG Changes for v2 of TDC mezzanine |
-- Several pinout changes, |
-- acam_ref_clk LVDS instead of CMOS, |
-- no PLL_LD only PLL_STATUS |
-- 04/2013 v4 EG added SDB; fixed bugs in data_formatting; added carrier CSR information |
-- 01/2014 v5 EG added VIC and EIC in the TDC mezzanine |
-- |
----------------------------------------------/!\-------------------------------------------------|
-- Note for eva: Remember the design is synthesised with Synplify Premier with DP (tdc_syn.prj) |
-- For PAR use the tdc_par_script.tcl commands in Xilinx ISE! |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.tdc_core_pkg.all;
use work.gn4124_core_pkg.all;
use work.gencores_pkg.all;
use work.wishbone_pkg.all;
--use work.sdb_meta_pkg.all;
use work.wrcore_pkg.all;
use work.wr_fabric_pkg.all;
use work.wr_xilinx_pkg.all;
use work.synthesis_descriptor.all;
library UNISIM;
use UNISIM.vcomponents.all;
--=================================================================================================
-- Entity declaration for spec_top_fmc_tdc
--=================================================================================================
entity spec_top_fmc_tdc is
generic
(g_span : integer := 32; -- address span in bus interfaces
g_width : integer := 32; -- data width in bus interfaces
values_for_simul : boolean := FALSE); -- this generic is set to TRUE
-- when instantiated in a test-bench
port
(-- SPEC carrier
clk_125m_pllref_p_i: in std_logic; -- 125 MHz PLL reference
clk_125m_pllref_n_i: in std_logic;
clk_125m_gtp_n_i : in std_logic; -- 125 MHz GTP reference
clk_125m_gtp_p_i : in std_logic;
clk_20m_vcxo_i : in std_logic; -- 20 MHz VCXO
dac_sclk_o : out std_logic; -- PLL VCXO DAC Drive
dac_din_o : out std_logic;
dac_cs1_n_o : out std_logic;
dac_cs2_n_o : out std_logic;
sfp_txp_o : out std_logic; -- SFP
sfp_txn_o : out std_logic;
sfp_rxp_i : in std_logic := '0';
sfp_rxn_i : in std_logic := '1';
sfp_mod_def0_b : in std_logic; -- SFP detect pin
sfp_mod_def1_b : inout std_logic; -- SFP scl
sfp_mod_def2_b : inout std_logic; -- SFP sda
sfp_rate_select_b : inout std_logic := '0';
sfp_tx_fault_i : in std_logic := '0';
sfp_tx_disable_o : out std_logic;
sfp_los_i : in std_logic := '0';
uart_rxd_i : in std_logic := '1'; -- UART
uart_txd_o : out std_logic;
carrier_scl_b : inout std_logic; -- SPEC EEPROM
carrier_sda_b : inout std_logic;
carrier_onewire_b : inout std_logic; -- SPEC 1-wire
button1_i : in std_logic := '1';
button2_i : in std_logic := '1';
-- Interface with GN4124
rst_n_a_i : in std_logic;
-- P2L Direction
p2l_clk_p_i : in std_logic; -- Receiver Source Synchronous Clock+
p2l_clk_n_i : in std_logic; -- Receiver Source Synchronous Clock-
p2l_data_i : in std_logic_vector(15 downto 0);-- Parallel receive data
p2l_dframe_i : in std_logic; -- Receive Frame
p2l_valid_i : in std_logic; -- Receive Data Valid
p2l_rdy_o : out std_logic; -- Rx Buffer Full Flag
p_wr_req_i : in std_logic_vector(1 downto 0); -- PCIe Write Request
p_wr_rdy_o : out std_logic_vector(1 downto 0); -- PCIe Write Ready
rx_error_o : out std_logic; -- Receive Error
vc_rdy_i : in std_logic_vector(1 downto 0); -- Virtual channel ready
-- L2P Direction
l2p_clk_p_o : out std_logic; -- Transmitter Source Synchronous Clock+ (freq set in GN4124 config registers)
l2p_clk_n_o : out std_logic; -- Transmitter Source Synchronous Clock- (freq set in GN4124 config registers)
l2p_data_o : out std_logic_vector(15 downto 0);-- Parallel transmit data
l2p_dframe_o : out std_logic; -- Transmit Data Frame
l2p_valid_o : out std_logic; -- Transmit Data Valid
l2p_edb_o : out std_logic; -- Packet termination and discard
l2p_rdy_i : in std_logic; -- Tx Buffer Full Flag
l_wr_rdy_i : in std_logic_vector(1 downto 0); -- Local-to-PCIe Write
p_rd_d_rdy_i : in std_logic_vector(1 downto 0); -- PCIe-to-Local Read Response Data Ready
tx_error_i : in std_logic; -- Transmit Error
irq_p_o : out std_logic; -- Interrupt request pulse to GN4124 GPIO 8
irq_aux_p_o : out std_logic; -- Interrupt request pulse to GN4124 GPIO 9, aux signal
-- Interface with the PLL AD9516 and DAC AD5662 on TDC mezzanine
pll_sclk_o : out std_logic; -- SPI clock
pll_sdi_o : out std_logic; -- data line for PLL and DAC
pll_cs_o : out std_logic; -- PLL chip select
pll_dac_sync_o : out std_logic; -- DAC chip select
pll_sdo_i : in std_logic; -- not used for the moment
pll_status_i : in std_logic; -- PLL Digital Lock Detect, active high
tdc_clk_125m_p_i : in std_logic; -- 125 MHz differential clock: system clock
tdc_clk_125m_n_i : in std_logic; -- 125 MHz differential clock: system clock
acam_refclk_p_i : in std_logic; -- 31.25 MHz differential clock: ACAM ref clock
acam_refclk_n_i : in std_logic; -- 31.25 MHz differential clock: ACAM ref clock
-- Timing interface with the ACAM on TDC mezzanine
start_from_fpga_o : out std_logic; -- start signal
err_flag_i : in std_logic; -- error flag
int_flag_i : in std_logic; -- interrupt flag
start_dis_o : out std_logic; -- start disable, not used
stop_dis_o : out std_logic; -- stop disable, not used
-- Data interface with the ACAM on TDC mezzanine
data_bus_io : inout std_logic_vector(27 downto 0);
address_o : out std_logic_vector(3 downto 0);
cs_n_o : out std_logic; -- chip select for ACAM
oe_n_o : out std_logic; -- output enable for ACAM
rd_n_o : out std_logic; -- read signal for ACAM
wr_n_o : out std_logic; -- write signal for ACAM
ef1_i : in std_logic; -- empty flag iFIFO1
ef2_i : in std_logic; -- empty flag iFIFO2
-- Enable of input Logic on TDC mezzanine
enable_inputs_o : out std_logic; -- enables all 5 inputs
term_en_1_o : out std_logic; -- Ch.1 termination enable of 50 Ohm termination
term_en_2_o : out std_logic; -- Ch.2 termination enable of 50 Ohm termination
term_en_3_o : out std_logic; -- Ch.3 termination enable of 50 Ohm termination
term_en_4_o : out std_logic; -- Ch.4 termination enable of 50 Ohm termination
term_en_5_o : out std_logic; -- Ch.5 termination enable of 50 Ohm termination
-- LEDs on TDC mezzanine
tdc_led_status_o : out std_logic; -- amber led on front pannel, division of 125 MHz tdc_clk
tdc_led_trig1_o : out std_logic; -- amber led on front pannel, Ch.1 enable
tdc_led_trig2_o : out std_logic; -- amber led on front pannel, Ch.2 enable
tdc_led_trig3_o : out std_logic; -- amber led on front pannel, Ch.3 enable
tdc_led_trig4_o : out std_logic; -- amber led on front pannel, Ch.4 enable
tdc_led_trig5_o : out std_logic; -- amber led on front pannel, Ch.5 enable
-- Input Logic on TDC mezzanine (not used currently)
tdc_in_fpga_1_i : in std_logic; -- Ch.1 for ACAM, also received by FPGA
tdc_in_fpga_2_i : in std_logic; -- Ch.2 for ACAM, also received by FPGA
tdc_in_fpga_3_i : in std_logic; -- Ch.3 for ACAM, also received by FPGA
tdc_in_fpga_4_i : in std_logic; -- Ch.4 for ACAM, also received by FPGA
tdc_in_fpga_5_i : in std_logic; -- Ch.5 for ACAM, also received by FPGA
-- I2C EEPROM interface on TDC mezzanine
mezz_sys_scl_b : inout std_logic := '1'; -- Mezzanine system EEPROM I2C clock
mezz_sys_sda_b : inout std_logic := '1'; -- Mezzanine system EEPROM I2C data
-- 1-wire interface on TDC mezzanine
mezz_one_wire_b : inout std_logic;
-- font panel leds
led_red : out std_logic;
led_green : out std_logic;
-- Carrier other signals
pcb_ver_i : in std_logic_vector(3 downto 0); -- PCB version
prsnt_m2c_n_i : in std_logic); -- Mezzanine presence (active low)
end spec_top_fmc_tdc;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of spec_top_fmc_tdc is
---------------------------------------------------------------------------------------------------
-- SDB CONSTANTS --
---------------------------------------------------------------------------------------------------
-- Note: All address in sdb and crossbar are BYTE addresses!
-- Master ports on the wishbone crossbar
constant c_NUM_WB_MASTERS : integer := 5;
constant c_WB_SLAVE_SPEC_ONEWIRE: integer := 0; -- Carrier onewire interface
constant c_WB_SLAVE_SPEC_INFO : integer := 1; -- Info on SPEC control and status registers
constant c_WB_SLAVE_VIC : integer := 2; -- Interrupt controller
constant c_WB_SLAVE_TDC : integer := 3; -- TDC core configuration
constant c_SLAVE_WRCORE : integer := 4; -- White Rabbit PTP core
-- SDB header address
constant c_SDB_ADDRESS : t_wishbone_address := x"00000000";
-- Slave port on the wishbone crossbar
constant c_NUM_WB_SLAVES : integer := 1;
constant c_MASTER_GENNUM : integer := 0;
constant c_FMC_TDC_SDB_BRIDGE : t_sdb_bridge := f_xwb_bridge_manual_sdb(x"0001FFFF", x"00000000");
constant c_WRCORE_BRIDGE_SDB : t_sdb_bridge := f_xwb_bridge_manual_sdb(x"0003ffff", x"00000000");
constant c_INTERCONNECT_LAYOUT : t_sdb_record_array(6 downto 0) :=
(0 => f_sdb_embed_device (c_ONEWIRE_SDB_DEVICE, x"00010000"),
1 => f_sdb_embed_device (c_SPEC_INFO_SDB_DEVICE, x"00020000"),
2 => f_sdb_embed_device (c_xwb_vic_sdb, x"00030000"), -- c_xwb_vic_sdb described in the wishbone_pkg
3 => f_sdb_embed_bridge (c_FMC_TDC_SDB_BRIDGE, x"00040000"),
4 => f_sdb_embed_bridge (c_WRCORE_BRIDGE_SDB, x"00080000"),
5 => f_sdb_embed_repo_url (c_sdb_repo_url),
6 => f_sdb_embed_synthesis (c_sdb_synthesis_info));
---------------------------------------------------------------------------------------------------
-- VIC CONSTANT --
---------------------------------------------------------------------------------------------------
constant c_VIC_VECTOR_TABLE : t_wishbone_address_array(0 to 0) :=
(0 => x"00052000");
---------------------------------------------------------------------------------------------------
-- Signals --
---------------------------------------------------------------------------------------------------
-- WRabbit clocks
signal pllout_clk_sys, pllout_clk_dmtd : std_logic;
signal pllout_clk_fb_pllref, pllout_clk_fb_dmtd : std_logic;
signal clk_125m_pllref, clk_125m_gtp : std_logic;
signal clk_dmtd : std_logic;
attribute buffer_type : string; --" {bufgdll | ibufg | bufgp | ibuf | bufr | none}";
attribute buffer_type of clk_125m_pllref : signal is "BUFG";
-- TDC core clocks and resets
signal clk_20m_vcxo, clk_20m_vcxo_buf : std_logic;
signal clk_62m5_sys, clk_125m_mezz : std_logic;
signal rst_125m_mezz_n, rst_125m_mezz : std_logic;
signal acam_refclk_r_edge_p : std_logic;
signal rst_sys, rst_sys_n : std_logic;
-- DAC configuration through PCIe/VME
signal send_dac_word_p : std_logic;
signal dac_word : std_logic_vector(23 downto 0);
-- WISHBONE from crossbar master port
signal cnx_master_out : t_wishbone_master_out_array(c_NUM_WB_MASTERS-1 downto 0);
signal cnx_master_in : t_wishbone_master_in_array(c_NUM_WB_MASTERS-1 downto 0);
-- WISHBONE to crossbar slave port
signal cnx_slave_out : t_wishbone_slave_out_array(c_NUM_WB_SLAVES-1 downto 0);
signal cnx_slave_in : t_wishbone_slave_in_array(c_NUM_WB_SLAVES-1 downto 0);
signal tdc_slave_in : t_wishbone_slave_in;
signal tdc_slave_out : t_wishbone_slave_out;
signal gn_wb_adr : std_logic_vector(31 downto 0);
-- Carrier CSR info
signal gn4124_status : std_logic_vector(31 downto 0);
-- Carrier 1-wire
signal carrier_owr_en, carrier_owr_i : std_logic_vector(c_FMC_ONE_WIRE_NB - 1 downto 0);
-- VIC
signal fmc_eic_irq, irq_to_gn4124 : std_logic;
signal fmc_eic_irq_synch : std_logic_vector (1 downto 0);
-- WRabbit time
signal tm_link_up, tm_time_valid, tm_dac_wr_p : std_logic;
signal tm_utc : std_logic_vector(39 downto 0);
signal tm_cycles : std_logic_vector(27 downto 0);
signal tm_dac_value, tm_dac_value_reg : std_logic_vector(23 downto 0);
signal tm_clk_aux_lock_en, tm_clk_aux_locked : std_logic;
-- WRabbit PHY
signal phy_tx_data, phy_rx_data : std_logic_vector(7 downto 0);
signal phy_tx_k, phy_tx_disparity, phy_rx_k : std_logic;
signal phy_tx_enc_err, phy_rx_rbclk : std_logic;
signal phy_rx_enc_err, phy_rst, phy_loopen : std_logic;
signal phy_rx_bitslide : std_logic_vector(3 downto 0);
-- DAC configuration through WRabbit
signal dac_hpll_load_p1, dac_dpll_load_p1 : std_logic;
signal dac_hpll_data, dac_dpll_data : std_logic_vector(15 downto 0);
-- EEPROM on mezzanine
signal wrc_scl_out, wrc_scl_in, wrc_sda_out, wrc_sda_in: std_logic;
signal tdc_scl_out, tdc_scl_in, tdc_sda_out, tdc_sda_in: std_logic;
signal tdc_scl_oen, tdc_sda_oen : std_logic;
-- SFP EEPROM on mezzanine
signal sfp_scl_out, sfp_scl_in, sfp_sda_out, sfp_sda_in: std_logic;
-- Carrier 1-Wire
signal wrc_owr_en, wrc_owr_in : std_logic_vector(1 downto 0);
-- aux
signal pll_sclk, pll_sdi, pll_dac_sync : std_logic;
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
---------------------------------------------------------------------------------------------------
-- 62.5 MHz system clock --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
cmp_clk_vcxo_ibuf : IBUFG
port map
(O => clk_20m_vcxo_buf,
I => clk_20m_vcxo_i);
cmp_clk_vcxo_gbuf : BUFG
port map
(O => clk_20m_vcxo,
I => clk_20m_vcxo_buf);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
cmp_sys_clk_pll : PLL_BASE
generic map
(BANDWIDTH => "OPTIMIZED",
CLK_FEEDBACK => "CLKFBOUT",
COMPENSATION => "INTERNAL",
DIVCLK_DIVIDE => 1,
CLKFBOUT_MULT => 50,
CLKFBOUT_PHASE => 0.000,
CLKOUT0_DIVIDE => 16, -- 62.5 MHz
CLKOUT0_PHASE => 0.000,
CLKOUT0_DUTY_CYCLE => 0.500,
CLKOUT1_DIVIDE => 16, -- not used
CLKOUT1_PHASE => 0.000,
CLKOUT1_DUTY_CYCLE => 0.500,
CLKOUT2_DIVIDE => 16,
CLKOUT2_PHASE => 0.000,
CLKOUT2_DUTY_CYCLE => 0.500,
CLKIN_PERIOD => 50.0,
REF_JITTER => 0.016)
port map
(CLKFBOUT => pllout_clk_fb_pllref,
CLKOUT0 => pllout_clk_sys,
CLKOUT1 => open,
CLKOUT2 => open,
CLKOUT3 => open,
CLKOUT4 => open,
CLKOUT5 => open,
LOCKED => open,
RST => '0',
CLKFBIN => pllout_clk_fb_pllref,
CLKIN => clk_20m_vcxo);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
cmp_clk_sys_buf : BUFG
port map
(O => clk_62m5_sys,
I => pllout_clk_sys);
---------------------------------------------------------------------------------------------------
-- Reset for 62M5 clk domain --
---------------------------------------------------------------------------------------------------
U_Reset_Generator : spec_reset_gen
port map
(clk_sys_i => clk_62m5_sys,
rst_pcie_n_a_i => rst_n_a_i,
rst_button_n_a_i => button1_i,
rst_n_o => rst_sys_n);
-- -- -- -- -- -- -- -- -- --
rst_sys <= not rst_sys_n;
---------------------------------------------------------------------------------------------------
-- 125 MHz clk and Reset for TDC core --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
cmp_tdc_clks_rsts_mgment : clks_rsts_manager
generic map
(nb_of_reg => 68)
port map
(clk_sys_i => clk_62m5_sys,
acam_refclk_p_i => acam_refclk_p_i,
acam_refclk_n_i => acam_refclk_n_i,
tdc_125m_clk_p_i => tdc_clk_125m_p_i,
tdc_125m_clk_n_i => tdc_clk_125m_n_i,
rst_n_i => rst_n_a_i,
pll_sdo_i => pll_sdo_i,
pll_status_i => pll_status_i,
send_dac_word_p_i => send_dac_word_p,
dac_word_i => dac_word,
acam_refclk_r_edge_p_o => acam_refclk_r_edge_p,
wrabbit_dac_value_i => tm_dac_value,
wrabbit_dac_wr_p_i => tm_dac_wr_p,
internal_rst_o => rst_125m_mezz,
pll_cs_n_o => pll_cs_o,
pll_dac_sync_n_o => pll_dac_sync,
pll_sdi_o => pll_sdi,
pll_sclk_o => pll_sclk,
tdc_125m_clk_o => clk_125m_mezz,
pll_status_o => open);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
rst_125m_mezz_n <= not rst_125m_mezz;
pll_dac_sync_o <= pll_dac_sync;
pll_sdi_o <= pll_sdi;
pll_sclk_o <= pll_sclk;
---------------------------------------------------------------------------------------------------
-- 62.5 MHz DMTD clock --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
cmp_dmtd_clk_pll : PLL_BASE
generic map
(BANDWIDTH => "OPTIMIZED",
CLK_FEEDBACK => "CLKFBOUT",
COMPENSATION => "INTERNAL",
DIVCLK_DIVIDE => 1,
CLKFBOUT_MULT => 50,
CLKFBOUT_PHASE => 0.000,
CLKOUT0_DIVIDE => 16, -- 62.5 MHz
CLKOUT0_PHASE => 0.000,
CLKOUT0_DUTY_CYCLE => 0.500,
CLKOUT1_DIVIDE => 16, -- not used
CLKOUT1_PHASE => 0.000,
CLKOUT1_DUTY_CYCLE => 0.500,
CLKOUT2_DIVIDE => 8,
CLKOUT2_PHASE => 0.000,
CLKOUT2_DUTY_CYCLE => 0.500,
CLKIN_PERIOD => 50.0,
REF_JITTER => 0.016)
port map
(CLKFBOUT => pllout_clk_fb_dmtd,
CLKOUT0 => pllout_clk_dmtd,
CLKOUT1 => open,
CLKOUT2 => open,
CLKOUT3 => open,
CLKOUT4 => open,
CLKOUT5 => open,
LOCKED => open,
RST => '0',
CLKFBIN => pllout_clk_fb_dmtd,
CLKIN => clk_20m_vcxo_buf);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
cmp_clk_dmtd_buf : BUFG
port map
(O => clk_dmtd,
I => pllout_clk_dmtd);
---------------------------------------------------------------------------------------------------
-- 125 MHz clk for White Rabbit core --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
U_Buf_CLK_PLL : IBUFGDS
generic map
(DIFF_TERM => true,
IBUF_LOW_PWR => true) -- Low power (TRUE) vs. performance (FALSE) setting for referenced
port map
(O => clk_125m_pllref, -- Buffer output
I => clk_125m_pllref_p_i, -- Diff_p buffer input (connect directly to top-level port)
IB => clk_125m_pllref_n_i); -- Diff_n buffer input (connect directly to top-level port)
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
U_Buf_CLK_GTP : IBUFDS
generic map
(DIFF_TERM => true,
IBUF_LOW_PWR => false)
port map
(O => clk_125m_gtp,
I => clk_125m_gtp_p_i,
IB => clk_125m_gtp_n_i);
---------------------------------------------------------------------------------------------------
-- White Rabbit Core + PHY --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
U_WR_CORE : xwr_core
generic map
(g_simulation => 0,
g_phys_uart => true,
g_virtual_uart => true,
g_with_external_clock_input => false,
g_aux_clks => 1,
g_ep_rxbuf_size => 1024,
g_dpram_initf => "wrc.ram",
g_dpram_size => 90112/4,
g_interface_mode => PIPELINED,
g_address_granularity => BYTE,
g_softpll_enable_debugger => false)
port map
(clk_sys_i => clk_62m5_sys,
clk_dmtd_i => clk_dmtd,
clk_ref_i => clk_125m_pllref,
clk_aux_i(0) => clk_125m_mezz,
rst_n_i => rst_sys_n,
-- DAC
dac_hpll_load_p1_o => dac_hpll_load_p1,
dac_hpll_data_o => dac_hpll_data,
dac_dpll_load_p1_o => dac_dpll_load_p1,
dac_dpll_data_o => dac_dpll_data,
-- PHY
phy_ref_clk_i => clk_125m_pllref,
phy_tx_data_o => phy_tx_data,
phy_tx_k_o => phy_tx_k,
phy_tx_disparity_i => phy_tx_disparity,
phy_tx_enc_err_i => phy_tx_enc_err,
phy_rx_data_i => phy_rx_data,
phy_rx_rbclk_i => phy_rx_rbclk,
phy_rx_k_i => phy_rx_k,
phy_rx_enc_err_i => phy_rx_enc_err,
phy_rx_bitslide_i => phy_rx_bitslide,
phy_rst_o => phy_rst,
phy_loopen_o => phy_loopen,
-- SPEC LEDs
led_act_o => LED_RED,
led_link_o => LED_GREEN,
-- SFP
scl_o => wrc_scl_out,
scl_i => wrc_scl_in,
sda_o => wrc_sda_out,
sda_i => wrc_sda_in,
sfp_scl_o => sfp_scl_out,
sfp_scl_i => sfp_scl_in,
sfp_sda_o => sfp_sda_out,
sfp_sda_i => sfp_sda_in,
sfp_det_i => sfp_mod_def0_b,
uart_rxd_i => uart_rxd_i,
uart_txd_o => uart_txd_o,
-- 1-wire
owr_en_o => wrc_owr_en,
owr_i => wrc_owr_in,
-- WISHBONE
slave_i => cnx_master_out(c_SLAVE_WRCORE),
slave_o => cnx_master_in(c_SLAVE_WRCORE),
-- Timimg info for TDC core
tm_link_up_o => tm_link_up,
tm_dac_value_o => tm_dac_value,
tm_dac_wr_o(0) => tm_dac_wr_p,
tm_clk_aux_lock_en_i(0) => tm_clk_aux_lock_en,
tm_clk_aux_locked_o(0) => tm_clk_aux_locked,
tm_time_valid_o => tm_time_valid,
tm_tai_o => tm_utc,
tm_cycles_o => tm_cycles,
-- not used
btn1_i => '1',
btn2_i => '1',
pps_p_o => open,
-- aux reset
rst_aux_n_o => open);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
U_GTP : wr_gtp_phy_spartan6
generic map
(g_simulation => 0,
g_enable_ch0 => 0,
g_enable_ch1 => 1)
port map
(gtp_clk_i => clk_125m_gtp,
ch0_ref_clk_i => clk_125m_pllref,
ch0_tx_data_i => x"00",
ch0_tx_k_i => '0',
ch0_tx_disparity_o => open,
ch0_tx_enc_err_o => open,
ch0_rx_rbclk_o => open,
ch0_rx_data_o => open,
ch0_rx_k_o => open,
ch0_rx_enc_err_o => open,
ch0_rx_bitslide_o => open,
ch0_rst_i => '1',
ch0_loopen_i => '0',
ch1_ref_clk_i => clk_125m_pllref,
ch1_tx_data_i => phy_tx_data,
ch1_tx_k_i => phy_tx_k,
ch1_tx_disparity_o => phy_tx_disparity,
ch1_tx_enc_err_o => phy_tx_enc_err,
ch1_rx_data_o => phy_rx_data,
ch1_rx_rbclk_o => phy_rx_rbclk,
ch1_rx_k_o => phy_rx_k,
ch1_rx_enc_err_o => phy_rx_enc_err,
ch1_rx_bitslide_o => phy_rx_bitslide,
ch1_rst_i => phy_rst,
ch1_loopen_i => '0', -- phy_loopen,
pad_txn0_o => open,
pad_txp0_o => open,
pad_rxn0_i => '0',
pad_rxp0_i => '0',
pad_txn1_o => sfp_txn_o,
pad_txp1_o => sfp_txp_o,
pad_rxn1_i => sfp_rxn_i,
pad_rxp1_i => sfp_rxp_i);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
U_DAC_ARB : spec_serial_dac_arb
generic map
(g_invert_sclk => false,
g_num_extra_bits => 8)
port map
(clk_i => clk_62m5_sys,
rst_n_i => rst_sys_n,
val1_i => dac_dpll_data,
load1_i => dac_dpll_load_p1,
val2_i => dac_hpll_data,
load2_i => dac_hpll_load_p1,
dac_cs_n_o(0) => dac_cs1_n_o,
dac_cs_n_o(1) => dac_cs2_n_o,
-- dac_clr_n_o => open,
dac_sclk_o => dac_sclk_o,
dac_din_o => dac_din_o);
-- -- -- -- -- --
sfp_tx_disable_o <= '0';
-- dac_clr_n_o <= '1';
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Tristates for Carrier EEPROM
mezz_sys_scl_b <= '0' when (wrc_scl_out = '0') else 'Z';--tdc_scl_out when (tdc_scl_oen = '0') else '0' when (wrc_scl_out = '0') else 'Z';
mezz_sys_sda_b <= '0' when (wrc_sda_out = '0') else 'Z';--tdc_sda_out when (tdc_sda_oen = '0') else '0' when (wrc_sda_out = '0') else 'Z';
wrc_scl_in <= mezz_sys_scl_b;
wrc_sda_in <= mezz_sys_sda_b;
tdc_scl_in <= mezz_sys_scl_b;
tdc_sda_in <= mezz_sys_sda_b;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Tristates for SFP EEPROM
sfp_mod_def1_b <= '0' when sfp_scl_out = '0' else 'Z';
sfp_mod_def2_b <= '0' when sfp_sda_out = '0' else 'Z';
sfp_scl_in <= sfp_mod_def1_b;
sfp_sda_in <= sfp_mod_def2_b;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
carrier_onewire_b <= '0' when wrc_owr_en(0) = '1' else 'Z';
wrc_owr_in(0) <= carrier_onewire_b;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
---------------------------------------------------------------------------------------------------
-- CSR WISHBONE CROSSBAR --
---------------------------------------------------------------------------------------------------
-- 0x00000 -> SDB
-- 0x10000 -> Carrier 1-wire master
-- 0x20000 -> Carrier CSR information
-- 0x30000 -> Vector Interrupt Controller
-- 0x40000 -> TDC mezzanine SDB
-- 0x10000 -> TDC core configuration (including ACAM regs)
-- 0x11000 -> TDC Mezzanine 1-wire master
-- 0x12000 -> TDC Mezzanine Embedded Interrupt Controller
-- 0x13000 -> TDC Mezzanine I2C master
-- 0x14000 -> TDC core timestamps retrieval from memory
cmp_sdb_crossbar : xwb_sdb_crossbar
generic map
(g_num_masters => c_NUM_WB_SLAVES,
g_num_slaves => c_NUM_WB_MASTERS,
g_registered => true,
g_wraparound => true,
g_layout => c_INTERCONNECT_LAYOUT,
g_sdb_addr => c_SDB_ADDRESS)
port map
(clk_sys_i => clk_62m5_sys,
rst_n_i => rst_sys_n,
slave_i => cnx_slave_in,
slave_o => cnx_slave_out,
master_i => cnx_master_in,
master_o => cnx_master_out);
---------------------------------------------------------------------------------------------------
-- GN4124 CORE --
---------------------------------------------------------------------------------------------------
cmp_gn4124_core: gn4124_core
port map
(rst_n_a_i => rst_n_a_i,
status_o => gn4124_status,
-- P2L Direction Source Sync DDR related signals
p2l_clk_p_i => p2l_clk_p_i,
p2l_clk_n_i => p2l_clk_n_i,
p2l_data_i => p2l_data_i,
p2l_dframe_i => p2l_dframe_i,
p2l_valid_i => p2l_valid_i,
-- P2L Control
p2l_rdy_o => p2l_rdy_o,
p_wr_req_i => p_wr_req_i,
p_wr_rdy_o => p_wr_rdy_o,
rx_error_o => rx_error_o,
-- L2P Direction Source Sync DDR related signals
l2p_clk_p_o => l2p_clk_p_o,
l2p_clk_n_o => l2p_clk_n_o,
l2p_data_o => l2p_data_o ,
l2p_dframe_o => l2p_dframe_o,
l2p_valid_o => l2p_valid_o,
l2p_edb_o => l2p_edb_o,
-- L2P Control
l2p_rdy_i => l2p_rdy_i,
l_wr_rdy_i => l_wr_rdy_i,
p_rd_d_rdy_i => p_rd_d_rdy_i,
tx_error_i => tx_error_i,
vc_rdy_i => vc_rdy_i,
-- Interrupt interface
dma_irq_o => open,
irq_p_i => irq_to_gn4124,
irq_p_o => irq_p_o,
-- CSR WISHBONE interface (master pipelined)
csr_clk_i => clk_62m5_sys,
csr_adr_o => gn_wb_adr,
csr_dat_o => cnx_slave_in(c_MASTER_GENNUM).dat,
csr_sel_o => cnx_slave_in(c_MASTER_GENNUM).sel,
csr_stb_o => cnx_slave_in(c_MASTER_GENNUM).stb,
csr_we_o => cnx_slave_in(c_MASTER_GENNUM).we,
csr_cyc_o => cnx_slave_in(c_MASTER_GENNUM).cyc,
csr_dat_i => cnx_slave_out(c_MASTER_GENNUM).dat,
csr_ack_i => cnx_slave_out(c_MASTER_GENNUM).ack,
csr_stall_i => cnx_slave_out(c_MASTER_GENNUM).stall,
-- DMA: not used
dma_clk_i => clk_62m5_sys,
dma_adr_o => open,
dma_cyc_o => open,
dma_dat_o => open,
dma_sel_o => open,
dma_stb_o => open,
dma_we_o => open,
dma_ack_i => '1',
dma_dat_i => (others => '0'),
dma_stall_i => '0',
dma_reg_clk_i => clk_62m5_sys,
dma_reg_adr_i => (others => '0'),
dma_reg_dat_i => (others => '0'),
dma_reg_sel_i => (others => '0'),
dma_reg_stb_i => '0',
dma_reg_we_i => '0',
dma_reg_cyc_i => '0',
dma_reg_dat_o => open,
dma_reg_ack_o => open,
dma_reg_stall_o => open);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Convert 32-bit word address into byte address for crossbar
cnx_slave_in(c_MASTER_GENNUM).adr <= gn_wb_adr(29 downto 0) & "00";
---------------------------------------------------------------------------------------------------
-- TDC BOARD --
---------------------------------------------------------------------------------------------------
cmp_tdc_mezz : fmc_tdc_mezzanine
generic map
(g_span => g_span,
g_width => g_width,
values_for_simul => FALSE)
port map
-- 62M5 clk and reset
(clk_sys_i => clk_62m5_sys,
rst_sys_n_i => rst_sys_n,
-- 125M clk and reset
clk_ref_0_i => clk_125m_mezz,
rst_ref_0_i => rst_125m_mezz,
-- Configuration of the DAC on the TDC mezzanine, non White Rabbit
acam_refclk_r_edge_p_i => acam_refclk_r_edge_p,
send_dac_word_p_o => send_dac_word_p,
dac_word_o => dac_word,
-- ACAM interface
start_from_fpga_o => start_from_fpga_o,
err_flag_i => err_flag_i,
int_flag_i => int_flag_i,
start_dis_o => start_dis_o,
stop_dis_o => stop_dis_o,
data_bus_io => data_bus_io,
address_o => address_o,
cs_n_o => cs_n_o,
oe_n_o => oe_n_o,
rd_n_o => rd_n_o,
wr_n_o => wr_n_o,
ef1_i => ef1_i,
ef2_i => ef2_i,
-- Input channels enable
enable_inputs_o => enable_inputs_o,
term_en_1_o => term_en_1_o,
term_en_2_o => term_en_2_o,
term_en_3_o => term_en_3_o,
term_en_4_o => term_en_4_o,
term_en_5_o => term_en_5_o,
-- LEDs on TDC mezzanine
tdc_led_status_o => tdc_led_status_o,
tdc_led_trig1_o => tdc_led_trig1_o,
tdc_led_trig2_o => tdc_led_trig2_o,
tdc_led_trig3_o => tdc_led_trig3_o,
tdc_led_trig4_o => tdc_led_trig4_o,
tdc_led_trig5_o => tdc_led_trig5_o,
-- Input channels to FPGA (not used)
tdc_in_fpga_1_i => tdc_in_fpga_1_i,
tdc_in_fpga_2_i => tdc_in_fpga_2_i,
tdc_in_fpga_3_i => tdc_in_fpga_3_i,
tdc_in_fpga_4_i => tdc_in_fpga_4_i,
tdc_in_fpga_5_i => tdc_in_fpga_5_i,
-- WISHBONE interface with the GN4124 core
wb_tdc_csr_adr_i => tdc_slave_in.adr,
wb_tdc_csr_dat_i => tdc_slave_in.dat,
wb_tdc_csr_stb_i => tdc_slave_in.stb,
wb_tdc_csr_we_i => tdc_slave_in.we,
wb_tdc_csr_cyc_i => tdc_slave_in.cyc,
wb_tdc_csr_sel_i => tdc_slave_in.sel,
wb_tdc_csr_dat_o => tdc_slave_out.dat,
wb_tdc_csr_ack_o => tdc_slave_out.ack,
wb_tdc_csr_stall_o => tdc_slave_out.stall,
-- White Rabbit
wrabbit_link_up_i => tm_link_up,
wrabbit_time_valid_i => tm_time_valid,
wrabbit_cycles_i => tm_cycles,
wrabbit_utc_i => tm_utc(31 downto 0),
wrabbit_utc_p_o => open, -- for debug
wrabbit_clk_aux_lock_en_o => tm_clk_aux_lock_en,
wrabbit_clk_aux_locked_i => tm_clk_aux_locked,
wrabbit_clk_dmtd_locked_i => '1', -- FIXME: fan out real signal from the WRCore
wrabbit_dac_value_i => tm_dac_value_reg,
wrabbit_dac_wr_p_i => tm_dac_wr_p,
-- Interrupt line from EIC
wb_irq_o => fmc_eic_irq,
-- EEPROM I2C on TDC mezzanine
i2c_scl_oen_o => tdc_scl_oen,
i2c_scl_i => tdc_scl_in,
i2c_sda_oen_o => tdc_sda_oen,
i2c_sda_i => tdc_sda_in,
i2c_scl_o => tdc_scl_out,
i2c_sda_o => tdc_sda_out,
-- 1-Wire on TDC mezzanine
one_wire_b => mezz_one_wire_b);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Domains crossing: clk_125m_mezz <-> clk_62m5_sys
cmp_tdc_clk_crossing : xwb_clock_crossing
port map
(slave_clk_i => clk_62m5_sys, -- Slave control port: GNUM interface at 62.5 MHz
slave_rst_n_i => rst_sys_n,
slave_i => cnx_master_out(c_WB_SLAVE_TDC),
slave_o => cnx_master_in(c_WB_SLAVE_TDC),
master_clk_i => clk_125m_mezz, -- Master reader port: TDC core at 125 MHz
master_rst_n_i => rst_125m_mezz_n,
master_i => tdc_slave_out,
master_o => tdc_slave_in);
---------------------------------------------------------------------------------------------------
-- VIC --
---------------------------------------------------------------------------------------------------
cmp_vic : xwb_vic
generic map
(g_interface_mode => PIPELINED,
g_address_granularity => BYTE,
g_num_interrupts => 1,
g_init_vectors => c_VIC_VECTOR_TABLE)
port map
(clk_sys_i => clk_62m5_sys,
rst_n_i => rst_sys_n,
slave_i => cnx_master_out(c_WB_SLAVE_VIC),
slave_o => cnx_master_in(c_WB_SLAVE_VIC),
irqs_i(0) => fmc_eic_irq_synch(1),
irq_master_o => irq_to_gn4124);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Domains crossing: synchronization of the wb_ird_o from 125MHz to 62.5MHz
irq_pulse_synchronizer: process (clk_62m5_sys)
begin
if rising_edge (clk_62m5_sys) then
if rst_sys_n = '0' then
fmc_eic_irq_synch <= (others => '0');
else
fmc_eic_irq_synch <= fmc_eic_irq_synch(0) & fmc_eic_irq;
end if;
end if;
end process;
---------------------------------------------------------------------------------------------------
-- Carrier 1-wire MASTER DS18B20 (thermometer + unique ID) --
---------------------------------------------------------------------------------------------------
-- cmp_carrier_onewire : xwb_onewire_master
-- generic map
-- (g_interface_mode => CLASSIC,
-- g_address_granularity => BYTE,
-- g_num_ports => 1,
-- g_ow_btp_normal => "5.0",
-- g_ow_btp_overdrive => "1.0")
-- port map
-- (clk_sys_i => clk_62m5_sys,
-- rst_n_i => rst_sys_n,
-- slave_i => cnx_master_out(c_WB_SLAVE_SPEC_ONEWIRE),
-- slave_o => cnx_master_in(c_WB_SLAVE_SPEC_ONEWIRE),
-- desc_o => open,
-- owr_pwren_o => open,
-- owr_en_o => carrier_owr_en,
-- owr_i => carrier_owr_i);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- carrier_onewire_b <= '0' when carrier_owr_en(0) = '1' else 'Z';
-- carrier_owr_i(0) <= carrier_onewire_b;
---------------------------------------------------------------------------------------------------
-- Carrier CSR information --
---------------------------------------------------------------------------------------------------
-- Information on carrier type, mezzanine presence, pcb version
cmp_carrier_info : carrier_info
port map
(rst_n_i => rst_sys_n,
clk_sys_i => clk_62m5_sys,
wb_adr_i => cnx_master_out(c_WB_SLAVE_SPEC_INFO).adr(3 downto 2),
wb_dat_i => cnx_master_out(c_WB_SLAVE_SPEC_INFO).dat,
wb_dat_o => cnx_master_in(c_WB_SLAVE_SPEC_INFO).dat,
wb_cyc_i => cnx_master_out(c_WB_SLAVE_SPEC_INFO).cyc,
wb_sel_i => cnx_master_out(c_WB_SLAVE_SPEC_INFO).sel,
wb_stb_i => cnx_master_out(c_WB_SLAVE_SPEC_INFO).stb,
wb_we_i => cnx_master_out(c_WB_SLAVE_SPEC_INFO).we,
wb_ack_o => cnx_master_in(c_WB_SLAVE_SPEC_INFO).ack,
wb_stall_o => cnx_master_in(c_WB_SLAVE_SPEC_INFO).stall,
carrier_info_carrier_pcb_rev_i => pcb_ver_i,
carrier_info_carrier_reserved_i => (others => '0'),
carrier_info_carrier_type_i => c_CARRIER_TYPE,
carrier_info_stat_fmc_pres_i => prsnt_m2c_n_i,
carrier_info_stat_p2l_pll_lck_i => gn4124_status(0),
carrier_info_stat_sys_pll_lck_i => '0',
carrier_info_stat_ddr3_cal_done_i => '0',
carrier_info_stat_reserved_i => (others => '0'),
carrier_info_ctrl_led_green_o => open,
carrier_info_ctrl_led_red_o => open,
carrier_info_ctrl_dac_clr_n_o => open,
carrier_info_ctrl_reserved_o => open,
carrier_info_rst_fmc0_n_o => open,
carrier_info_rst_fmc0_n_i => '1',
carrier_info_rst_fmc0_n_load_o => open,
carrier_info_rst_reserved_o => open);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Unused wishbone signals
cnx_master_in(c_WB_SLAVE_SPEC_INFO).err <= '0';
cnx_master_in(c_WB_SLAVE_SPEC_INFO).rty <= '0';
cnx_master_in(c_WB_SLAVE_SPEC_INFO).int <= '0';
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
\ No newline at end of file
-------------------------------------------------------------------------------
-- Title : Fine Delay FMC SPEC (Simple PCIe FMC Carrier) SDB descriptor
-- Project : Fine Delay FMC (fmc-delay-1ns-4cha)
-------------------------------------------------------------------------------
-- File : synthesis_descriptor.vhd
-- Author : Evangelia Gousiou
-- Company : CERN
-- Created : 2013-04-16
-- Last update: 2013-04-16
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: SDB descriptor for the top level of the FD on a SPEC carrier.
-- Contains synthesis & source repository information.
-- Warning: this file is modified whenever a synthesis is executed.
-------------------------------------------------------------------------------
--
-- Copyright (c) 2013 CERN / BE-CO-HT
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
library ieee;
use ieee.STD_LOGIC_1164.all;
use work.wishbone_pkg.all;
package synthesis_descriptor is
constant c_sdb_synthesis_info : t_sdb_synthesis :=
(
syn_module_name => "tdc-spec ",
syn_commit_id => "00000000000000000000000000000000",
syn_tool_name => "ISE ",
syn_tool_version => x"00000134",
syn_date => x"00000000",
syn_username => "egousiou ");
constant c_sdb_repo_url : t_sdb_repo_url :=
(
repo_url => "http://svn.ohwr.org/fmc-tdc "
);
end package synthesis_descriptor;
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- tdc_core_pkg |
-- |
---------------------------------------------------------------------------------------------------
-- File tdc_core_pkg.vhd |
-- |
-- Description Package containing core wide constants and components |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 04/2012 |
-- Version v0.2 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 07/2011 v0.1 GP First version |
-- 04/2012 v0.2 EG Revamping; Gathering of all the constants, declarations of all the |
-- units; Comments added, signals renamed |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
use work.wishbone_pkg.all;
use work.genram_pkg.all;
--use work.sdb_meta_pkg.all;
--=================================================================================================
-- Package declaration for tdc_core_pkg
--=================================================================================================
package tdc_core_pkg is
---------------------------------------------------------------------------------------------------
-- Constant regarding the Mezzanine DAC configuration --
---------------------------------------------------------------------------------------------------
-- Vout = Vref (DAC_WORD/ 65536); for Vout = 1.65V, with Vref = 2.5V the DAC_WORD = xA8F5
constant c_DEFAULT_DAC_WORD : std_logic_vector(23 downto 0) := x"00A8F5";
---------------------------------------------------------------------------------------------------
-- Constants regarding the SDB Devices Definitions --
---------------------------------------------------------------------------------------------------
-- Note: All address in sdb and crossbar are BYTE addresses!
-- Devices sdb description
constant c_ONEWIRE_SDB_DEVICE : t_sdb_device :=
(abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"01",
wbd_endian => c_sdb_endian_big,
wbd_width => x"4", -- 32-bit port granularity
sdb_component =>
(addr_first => x"0000000000000000",
addr_last => x"0000000000000007",
product =>
(vendor_id => x"000000000000CE42", -- CERN
device_id => x"00000602", -- "WB-Onewire.Control " | md5sum | cut -c1-8
version => x"00000001",
date => x"20121116",
name => "WB-Onewire.Control ")));
constant c_SPEC_INFO_SDB_DEVICE : t_sdb_device :=
(abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"01",
wbd_endian => c_sdb_endian_big,
wbd_width => x"4", -- 32-bit port granularity
sdb_component =>
(addr_first => x"0000000000000000",
addr_last => x"000000000000001F",
product =>
(vendor_id => x"000000000000CE42", -- CERN
device_id => x"00000603", -- "WB-SPEC.CSR " | md5sum | cut -c1-8
version => x"00000001",
date => x"20121116",
name => "WB-SPEC.CSR ")));
constant c_TDC_EIC_DEVICE : t_sdb_device :=
(abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"01",
wbd_endian => c_sdb_endian_big,
wbd_width => x"4", -- 32-bit port granularity
sdb_component =>
(addr_first => x"0000000000000000",
addr_last => x"000000000000000F",
product =>
(vendor_id => x"000000000000CE42", -- CERN
device_id => x"00000605", -- "WB-FMC-ADC.EIC " | md5sum | cut -c1-8
version => x"00000001",
date => x"20121116",
name => "WB-FMC-TDC.EIC ")));
constant c_I2C_SDB_DEVICE : t_sdb_device :=
(abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"01",
wbd_endian => c_sdb_endian_big,
wbd_width => x"4", -- 32-bit port granularity
sdb_component =>
(addr_first => x"0000000000000000",
addr_last => x"000000000000001F",
product =>
(vendor_id => x"000000000000CE42", -- CERN
device_id => x"00000606", -- "WB-I2C.Control " | md5sum | cut -c1-8
version => x"00000001",
date => x"20121116",
name => "WB-I2C.Control ")));
constant c_TDC_EIC_SDB : t_sdb_device := (
abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"01",
wbd_endian => c_sdb_endian_big,
wbd_width => x"4", -- 32-bit port granularity
sdb_component => (
addr_first => x"0000000000000000",
addr_last => x"000000000000000F",
product => (
vendor_id => x"000000000000CE42", -- CERN
device_id => x"26ec6086", -- "WB-FMC-TDC.EIC " | md5sum | cut -c1-8
version => x"00000001",
date => x"20131204",
name => "WB-FMC-TDC.EIC ")));
constant c_TDC_CONFIG_SDB_DEVICE : t_sdb_device :=
(abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"01",
wbd_endian => c_sdb_endian_big,
wbd_width => x"4", -- 32-bit port granularity
sdb_component =>
(addr_first => x"0000000000000000",
addr_last => x"00000000000000FF",
product =>
(vendor_id => x"000000000000CE42", -- CERN
device_id => x"00000604", -- "WB-TDC-Core-Config " | md5sum | cut -c1-8
version => x"00000001",
date => x"20130429",
name => "WB-TDC-Core-Config ")));
constant c_TDC_MEM_SDB_DEVICE : t_sdb_device :=
(abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"01",
wbd_endian => c_sdb_endian_big,
wbd_width => x"4", -- 32-bit port granularity
sdb_component =>
(addr_first => x"0000000000000000",
addr_last => x"0000000000000FFF",
product =>
(vendor_id => x"000000000000CE42", -- CERN
device_id => x"00000601", -- "WB-TDC-Mem " | md5sum | cut -c1-8
version => x"00000001",
date => x"20121116",
name => "WB-TDC-Mem ")));
---------------------------------------------------------------------------------------------------
-- Constants regarding 1 Hz pulse generation --
---------------------------------------------------------------------------------------------------
-- for synthesis: 1 sec = x"07735940" clk_i cycles (1 clk_i cycle = 8ns)
constant c_SYN_CLK_PERIOD : std_logic_vector(31 downto 0) := x"07735940";
-- for simulation: 1 msec = x"0001E848" clk_i cycles (1 clk_i cycle = 8ns)
constant c_SIM_CLK_PERIOD : std_logic_vector(31 downto 0) := x"0001E848";
---------------------------------------------------------------------------------------------------
-- Vector with the 11 ACAM Configuration Registers --
---------------------------------------------------------------------------------------------------
subtype config_register is std_logic_vector(31 downto 0);
type config_vector is array (10 downto 0) of config_register;
---------------------------------------------------------------------------------------------------
-- Constants regarding addressing of the ACAM registers --
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- Addresses of ACAM configuration registers to be written by the PCIe host
-- corresponds to:
constant c_ACAM_REG0_ADR : std_logic_vector(7 downto 0) := x"00"; -- address 0x51000 of GN4124 BAR 0
constant c_ACAM_REG1_ADR : std_logic_vector(7 downto 0) := x"01"; -- address 0x51004 of GN4124 BAR 0
constant c_ACAM_REG2_ADR : std_logic_vector(7 downto 0) := x"02"; -- address 0x51008 of GN4124 BAR 0
constant c_ACAM_REG3_ADR : std_logic_vector(7 downto 0) := x"03"; -- address 0x5100C of GN4124 BAR 0
constant c_ACAM_REG4_ADR : std_logic_vector(7 downto 0) := x"04"; -- address 0x51010 of GN4124 BAR 0
constant c_ACAM_REG5_ADR : std_logic_vector(7 downto 0) := x"05"; -- address 0x51014 of GN4124 BAR 0
constant c_ACAM_REG6_ADR : std_logic_vector(7 downto 0) := x"06"; -- address 0x51018 of GN4124 BAR 0
constant c_ACAM_REG7_ADR : std_logic_vector(7 downto 0) := x"07"; -- address 0x5101C of GN4124 BAR 0
constant c_ACAM_REG11_ADR : std_logic_vector(7 downto 0) := x"0B"; -- address 0x5102C of GN4124 BAR 0
constant c_ACAM_REG12_ADR : std_logic_vector(7 downto 0) := x"0C"; -- address 0x51030 of GN4124 BAR 0
constant c_ACAM_REG14_ADR : std_logic_vector(7 downto 0) := x"0E"; -- address 0x51038 of GN4124 BAR 0
---------------------------------------------------------------------------------------------------
-- Addresses of ACAM read-only registers, to be written by the ACAM and used within the core to access ACAM timestamps
constant c_ACAM_REG8_ADR : std_logic_vector(7 downto 0) := x"08"; -- not accessible for writing from PCI-e
constant c_ACAM_REG9_ADR : std_logic_vector(7 downto 0) := x"09"; -- not accessible for writing from PCI-e
constant c_ACAM_REG10_ADR : std_logic_vector(7 downto 0) := x"0A"; -- not accessible for writing from PCI-e
---------------------------------------------------------------------------------------------------
-- Addresses of ACAM configuration readback registers, to be written by the ACAM
-- corresponds to:
constant c_ACAM_REG0_RDBK_ADR : std_logic_vector(7 downto 0) := x"10"; -- address 0x51040 of the GN4124 BAR 0
constant c_ACAM_REG1_RDBK_ADR : std_logic_vector(7 downto 0) := x"11"; -- address 0x51044 of the GN4124 BAR 0
constant c_ACAM_REG2_RDBK_ADR : std_logic_vector(7 downto 0) := x"12"; -- address 0x51048 of the GN4124 BAR 0
constant c_ACAM_REG3_RDBK_ADR : std_logic_vector(7 downto 0) := x"13"; -- address 0x5104C of the GN4124 BAR 0
constant c_ACAM_REG4_RDBK_ADR : std_logic_vector(7 downto 0) := x"14"; -- address 0x51050 of the GN4124 BAR 0
constant c_ACAM_REG5_RDBK_ADR : std_logic_vector(7 downto 0) := x"15"; -- address 0x51054 of the GN4124 BAR 0
constant c_ACAM_REG6_RDBK_ADR : std_logic_vector(7 downto 0) := x"16"; -- address 0x51058 of the GN4124 BAR 0
constant c_ACAM_REG7_RDBK_ADR : std_logic_vector(7 downto 0) := x"17"; -- address 0x5105C of the GN4124 BAR 0
constant c_ACAM_REG8_RDBK_ADR : std_logic_vector(7 downto 0) := x"18"; -- address 0x51060 of the GN4124 BAR 0
constant c_ACAM_REG9_RDBK_ADR : std_logic_vector(7 downto 0) := x"19"; -- address 0x51064 of the GN4124 BAR 0
constant c_ACAM_REG10_RDBK_ADR : std_logic_vector(7 downto 0) := x"1A"; -- address 0x51068 of the GN4124 BAR 0
constant c_ACAM_REG11_RDBK_ADR : std_logic_vector(7 downto 0) := x"1B"; -- address 0x5106C of the GN4124 BAR 0
constant c_ACAM_REG12_RDBK_ADR : std_logic_vector(7 downto 0) := x"1C"; -- address 0x51070 of the GN4124 BAR 0
constant c_ACAM_REG14_RDBK_ADR : std_logic_vector(7 downto 0) := x"1E"; -- address 0x51078 of the GN4124 BAR 0
---------------------------------------------------------------------------------------------------
-- Constants regarding addressing of the TDC core registers --
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- Addresses of TDC core Configuration registers to be written by the PCIe host
-- corresponds to:
constant c_STARTING_UTC_ADR : std_logic_vector(7 downto 0) := x"20"; -- address 0x51080 of GN4124 BAR 0
constant c_ACAM_INPUTS_EN_ADR : std_logic_vector(7 downto 0) := x"21"; -- address 0x51084 of GN4124 BAR 0
constant c_START_PHASE_ADR : std_logic_vector(7 downto 0) := x"22"; -- address 0x51088 of GN4124 BAR 0
constant c_ONE_HZ_PHASE_ADR : std_logic_vector(7 downto 0) := x"23"; -- address 0x5108C of GN4124 BAR 0
constant c_IRQ_TSTAMP_THRESH_ADR : std_logic_vector(7 downto 0) := x"24"; -- address 0x51090 of GN4124 BAR 0
constant c_IRQ_TIME_THRESH_ADR : std_logic_vector(7 downto 0) := x"25"; -- address 0x51094 of GN4124 BAR 0
constant c_DAC_WORD_ADR : std_logic_vector(7 downto 0) := x"26"; -- address 0x51098 of GN4124 BAR 0
constant c_DEACT_CHAN_ADR : std_logic_vector(7 downto 0) := x"27"; -- address 0x5109C of GN4124 BAR 0
---------------------------------------------------------------------------------------------------
-- Addresses of TDC core Status registers to be written by the different core units
-- corresponds to:
constant c_LOCAL_UTC_ADR : std_logic_vector(7 downto 0) := x"28"; -- address 0x510A0 of GN4124 BAR 0
constant c_IRQ_CODE_ADR : std_logic_vector(7 downto 0) := x"29"; -- address 0x510A4 of GN4124 BAR 0
constant c_WR_INDEX_ADR : std_logic_vector(7 downto 0) := x"2A"; -- address 0x510A8 of GN4124 BAR 0
constant c_CORE_STATUS_ADR : std_logic_vector(7 downto 0) := x"2B"; -- address 0x510AC of GN4124 BAR 0
constant c_WRABBIT_STATUS_ADR : std_logic_vector(7 downto 0) := x"2C"; -- address 0x510B0 of GN4124 BAR 0
constant c_WRABBIT_CTRL_ADR : std_logic_vector(7 downto 0) := x"2D"; -- address 0x510B4 of GN4124 BAR 0
---------------------------------------------------------------------------------------------------
-- Address of TDC core Control register
-- corresponds to:
constant c_CTRL_REG_ADR : std_logic_vector(7 downto 0) := x"3F"; -- address 0x510FC of GN4124 BAR 0
---------------------------------------------------------------------------------------------------
-- Constants regarding ACAM retriggers --
---------------------------------------------------------------------------------------------------
-- Number of clk_i cycles corresponding to the Acam retrigger period;
-- through Acam Reg 4 StartTimer the chip is programmed to retrigger every:
-- (15+1) * acam_ref_clk = (15+1) * 32 ns
-- x"00000040" * clk_i = 64 * 8 ns
-- 512 ns
constant c_ACAM_RETRIG_PERIOD : std_logic_vector(31 downto 0) := x"00000040";
-- Used to multiply by 64, which is the retrigger period in clk_i cycles
constant c_ACAM_RETRIG_PERIOD_SHIFT : integer := 6;
---------------------------------------------------------------------------------------------------
-- Constants regarding TDC & SPEC LEDs --
---------------------------------------------------------------------------------------------------
constant c_SPEC_LED_PERIOD_SIM : std_logic_vector(31 downto 0) := x"00004E20"; -- 1 ms at 20 MHz
constant c_SPEC_LED_PERIOD_SYN : std_logic_vector(31 downto 0) := x"01312D00"; -- 1 s at 20 MHz
constant c_BLINK_LGTH_SYN : std_logic_vector(31 downto 0) := x"00BEBC20"; -- 100 ms at 125 MHz
constant c_BLINK_LGTH_SIM : std_logic_vector(31 downto 0) := x"000004E2"; -- 10 us at 125 MHz
--c_RESET_WORD
---------------------------------------------------------------------------------------------------
-- Constants regarding the Circular Buffer --
---------------------------------------------------------------------------------------------------
constant c_CIRCULAR_BUFF_SIZE : unsigned(31 downto 0) := x"00000100";
---------------------------------------------------------------------------------------------------
-- Constants regarding the One-Wire interface --
---------------------------------------------------------------------------------------------------
constant c_FMC_ONE_WIRE_NB : integer := 1;
---------------------------------------------------------------------------------------------------
-- Constants regarding the Carrier CSR info --
---------------------------------------------------------------------------------------------------
constant c_CARRIER_TYPE : std_logic_vector(15 downto 0) := X"0001";
---------------------------------------------------------------------------------------------------
-- Components Declarations: --
---------------------------------------------------------------------------------------------------
component fmc_tdc_mezzanine is
generic
(g_span : integer := 32;
g_width : integer := 32;
values_for_simul : boolean := false);
port
(clk_sys_i : in std_logic;
rst_sys_n_i : in std_logic;
-- Signals from the clks_rsts_manager unit
clk_ref_0_i : in std_logic;
rst_ref_0_i : in std_logic;
-- TDC core
acam_refclk_r_edge_p_i : in std_logic;
send_dac_word_p_o : out std_logic;
dac_word_o : out std_logic_vector(23 downto 0);
start_from_fpga_o : out std_logic;
err_flag_i : in std_logic;
int_flag_i : in std_logic;
start_dis_o : out std_logic;
stop_dis_o : out std_logic;
data_bus_io : inout std_logic_vector(27 downto 0);
address_o : out std_logic_vector(3 downto 0);
cs_n_o : out std_logic;
oe_n_o : out std_logic;
rd_n_o : out std_logic;
wr_n_o : out std_logic;
ef1_i : in std_logic;
ef2_i : in std_logic;
tdc_in_fpga_1_i : in std_logic;
tdc_in_fpga_2_i : in std_logic;
tdc_in_fpga_3_i : in std_logic;
tdc_in_fpga_4_i : in std_logic;
tdc_in_fpga_5_i : in std_logic;
enable_inputs_o : out std_logic;
term_en_1_o : out std_logic;
term_en_2_o : out std_logic;
term_en_3_o : out std_logic;
term_en_4_o : out std_logic;
term_en_5_o : out std_logic;
tdc_led_status_o : out std_logic;
tdc_led_trig1_o : out std_logic;
tdc_led_trig2_o : out std_logic;
tdc_led_trig3_o : out std_logic;
tdc_led_trig4_o : out std_logic;
tdc_led_trig5_o : out std_logic;
-- White Rabbit core
wrabbit_link_up_i : in std_logic;
wrabbit_time_valid_i : in std_logic;
wrabbit_cycles_i : in std_logic_vector(27 downto 0);
wrabbit_utc_i : in std_logic_vector(31 downto 0);
wrabbit_utc_p_o : out std_logic;
wrabbit_clk_aux_lock_en_o : out std_logic;
wrabbit_clk_aux_locked_i : in std_logic;
wrabbit_clk_dmtd_locked_i : in std_logic;
wrabbit_dac_value_i : in std_logic_vector(23 downto 0);
wrabbit_dac_wr_p_i : in std_logic;
-- WISHBONE interface with the GN4124/VME_core
-- for the core configuration | core interrupts | 1Wire | I2C
wb_tdc_csr_adr_i : in std_logic_vector(31 downto 0);
wb_tdc_csr_dat_i : in std_logic_vector(31 downto 0);
wb_tdc_csr_cyc_i : in std_logic;
wb_tdc_csr_sel_i : in std_logic_vector(3 downto 0);
wb_tdc_csr_stb_i : in std_logic;
wb_tdc_csr_we_i : in std_logic;
wb_tdc_csr_dat_o : out std_logic_vector(31 downto 0);
wb_tdc_csr_ack_o : out std_logic;
wb_tdc_csr_stall_o : out std_logic;
wb_irq_o : out std_logic;
-- Interrupt pulses, for debug
irq_tstamp_p_o : out std_logic;
irq_time_p_o : out std_logic;
irq_acam_err_p_o : out std_logic;
-- I2C EEPROM interface
i2c_scl_o : out std_logic;
i2c_scl_oen_o : out std_logic;
i2c_scl_i : in std_logic;
i2c_sda_o : out std_logic;
i2c_sda_oen_o : out std_logic;
i2c_sda_i : in std_logic;
-- 1-wire UniqueID&Thermometer interface
one_wire_b : inout std_logic;
direct_timestamp_o : out std_logic_vector(127 downto 0);
direct_timestamp_stb_o : out std_logic
);
end component;
---------------------------------------------------------------------------------------------------
component fmc_tdc_core
generic
(g_span : integer := 32;
g_width : integer := 32;
values_for_simul : boolean := false);
port
(clk_125m_i : in std_logic;
rst_i : in std_logic;
acam_refclk_r_edge_p_i : in std_logic;
send_dac_word_p_o : out std_logic;
dac_word_o : out std_logic_vector(23 downto 0);
start_from_fpga_o : out std_logic;
err_flag_i : in std_logic;
int_flag_i : in std_logic;
start_dis_o : out std_logic;
stop_dis_o : out std_logic;
data_bus_io : inout std_logic_vector(27 downto 0);
address_o : out std_logic_vector(3 downto 0);
cs_n_o : out std_logic;
oe_n_o : out std_logic;
rd_n_o : out std_logic;
wr_n_o : out std_logic;
ef1_i : in std_logic;
ef2_i : in std_logic;
tdc_in_fpga_1_i : in std_logic;
tdc_in_fpga_2_i : in std_logic;
tdc_in_fpga_3_i : in std_logic;
tdc_in_fpga_4_i : in std_logic;
tdc_in_fpga_5_i : in std_logic;
enable_inputs_o : out std_logic;
term_en_1_o : out std_logic;
term_en_2_o : out std_logic;
term_en_3_o : out std_logic;
term_en_4_o : out std_logic;
term_en_5_o : out std_logic;
tdc_led_status_o : out std_logic;
tdc_led_trig1_o : out std_logic;
tdc_led_trig2_o : out std_logic;
tdc_led_trig3_o : out std_logic;
tdc_led_trig4_o : out std_logic;
tdc_led_trig5_o : out std_logic;
wrabbit_status_reg_i : in std_logic_vector(g_width-1 downto 0);
wrabbit_ctrl_reg_o : out std_logic_vector(g_width-1 downto 0);
wrabbit_synched_i : in std_logic;
wrabbit_tai_p_i : in std_logic;
wrabbit_tai_i : in std_logic_vector(31 downto 0);
irq_tstamp_p_o : out std_logic;
irq_time_p_o : out std_logic;
irq_acam_err_p_o : out std_logic;
tdc_config_wb_adr_i : in std_logic_vector(g_span-1 downto 0);
tdc_config_wb_dat_i : in std_logic_vector(g_width-1 downto 0);
tdc_config_wb_stb_i : in std_logic;
tdc_config_wb_we_i : in std_logic;
tdc_config_wb_cyc_i : in std_logic;
tdc_config_wb_dat_o : out std_logic_vector(g_width-1 downto 0);
tdc_config_wb_ack_o : out std_logic;
tdc_mem_wb_adr_i : in std_logic_vector(31 downto 0);
tdc_mem_wb_dat_i : in std_logic_vector(31 downto 0);
tdc_mem_wb_stb_i : in std_logic;
tdc_mem_wb_we_i : in std_logic;
tdc_mem_wb_cyc_i : in std_logic;
tdc_mem_wb_ack_o : out std_logic;
tdc_mem_wb_dat_o : out std_logic_vector(31 downto 0);
tdc_mem_wb_stall_o : out std_logic;
direct_timestamp_o : out std_logic_vector(127 downto 0);
direct_timestamp_stb_o : out std_logic
);
end component;
---------------------------------------------------------------------------------------------------
component wrabbit_sync is
generic
(g_simulation : boolean;
g_with_wrabbit_core : boolean);
port
(clk_sys_i : in std_logic;
rst_n_sys_i : in std_logic;
clk_ref_i : in std_logic;
rst_n_ref_i : in std_logic;
wrabbit_dac_value_i : in std_logic_vector(23 downto 0);
wrabbit_dac_wr_p_i : in std_logic;
wrabbit_link_up_i : in std_logic;
wrabbit_time_valid_i : in std_logic; -- this is i te clk_ref_0 domain, no??
wrabbit_clk_aux_lock_en_o : out std_logic;
wrabbit_clk_aux_locked_i : in std_logic;
wrabbit_clk_dmtd_locked_i : in std_logic;
wrabbit_synched_o : out std_logic;
wrabbit_reg_i : in std_logic_vector(31 downto 0);
wrabbit_reg_o : out std_logic_vector(31 downto 0));
end component;
---------------------------------------------------------------------------------------------------
component spec_reset_gen is
port
(clk_sys_i : in std_logic;
rst_pcie_n_a_i : in std_logic;
rst_button_n_a_i : in std_logic;
rst_n_o : out std_logic);
end component;
---------------------------------------------------------------------------------------------------
component decr_counter
generic
(width : integer := 32);
port
(clk_i : in std_logic;
rst_i : in std_logic;
counter_load_i : in std_logic;
counter_top_i : in std_logic_vector(width-1 downto 0);
-------------------------------------------------------------
counter_is_zero_o : out std_logic;
counter_o : out std_logic_vector(width-1 downto 0));
-------------------------------------------------------------
end component;
---------------------------------------------------------------------------------------------------
component free_counter is
generic
(width : integer := 32);
port
(clk_i : in std_logic;
counter_en_i : in std_logic;
rst_i : in std_logic;
counter_top_i : in std_logic_vector(width-1 downto 0);
-------------------------------------------------------------
counter_is_zero_o : out std_logic;
counter_o : out std_logic_vector(width-1 downto 0));
-------------------------------------------------------------
end component;
---------------------------------------------------------------------------------------------------
component incr_counter
generic
(width : integer := 32);
port
(clk_i : in std_logic;
counter_top_i : in std_logic_vector(width-1 downto 0);
counter_incr_en_i : in std_logic;
rst_i : in std_logic;
-------------------------------------------------------------
counter_is_full_o : out std_logic;
counter_o : out std_logic_vector(width-1 downto 0));
-------------------------------------------------------------
end component;
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
component start_retrig_ctrl
generic
(g_width : integer := 32);
port
(clk_i : in std_logic;
rst_i : in std_logic;
acam_intflag_f_edge_p_i : in std_logic;
utc_p_i : in std_logic;
----------------------------------------------------------------------
current_retrig_nb_o : out std_logic_vector(g_width-1 downto 0);
roll_over_incr_recent_o : out std_logic;
clk_i_cycles_offset_o : out std_logic_vector(g_width-1 downto 0);
roll_over_nb_o : out std_logic_vector(g_width-1 downto 0);
retrig_nb_offset_o : out std_logic_vector(g_width-1 downto 0));
----------------------------------------------------------------------
end component;
---------------------------------------------------------------------------------------------------
component local_pps_gen
generic
(g_width : integer := 32);
port
(acam_refclk_r_edge_p_i : in std_logic;
clk_i : in std_logic;
clk_period_i : in std_logic_vector(g_width-1 downto 0);
load_utc_p_i : in std_logic;
pulse_delay_i : in std_logic_vector(g_width-1 downto 0);
rst_i : in std_logic;
starting_utc_i : in std_logic_vector(g_width-1 downto 0);
----------------------------------------------------------------------
local_utc_o : out std_logic_vector(g_width-1 downto 0);
local_utc_p_o : out std_logic);
----------------------------------------------------------------------
end component;
---------------------------------------------------------------------------------------------------
component data_engine
port
(acam_ack_i : in std_logic;
acam_dat_i : in std_logic_vector(31 downto 0);
clk_i : in std_logic;
rst_i : in std_logic;
acam_ef1_i : in std_logic;
acam_ef1_meta_i : in std_logic;
acam_ef2_i : in std_logic;
acam_ef2_meta_i : in std_logic;
activate_acq_p_i : in std_logic;
deactivate_acq_p_i : in std_logic;
acam_wr_config_p_i : in std_logic;
acam_rdbk_config_p_i : in std_logic;
acam_rdbk_status_p_i : in std_logic;
acam_rdbk_ififo1_p_i : in std_logic;
acam_rdbk_ififo2_p_i : in std_logic;
acam_rdbk_start01_p_i : in std_logic;
acam_rst_p_i : in std_logic;
acam_config_i : in config_vector;
start_from_fpga_i : in std_logic;
----------------------------------------------------------------------
state_active_p_o : out std_logic;
acam_adr_o : out std_logic_vector(7 downto 0);
acam_cyc_o : out std_logic;
acam_dat_o : out std_logic_vector(31 downto 0);
acam_stb_o : out std_logic;
acam_we_o : out std_logic;
acam_config_rdbk_o : out config_vector;
acam_ififo1_o : out std_logic_vector(31 downto 0);
acam_ififo2_o : out std_logic_vector(31 downto 0);
acam_start01_o : out std_logic_vector(31 downto 0);
acam_tstamp1_o : out std_logic_vector(31 downto 0);
acam_tstamp1_ok_p_o : out std_logic;
acam_tstamp2_o : out std_logic_vector(31 downto 0);
acam_tstamp2_ok_p_o : out std_logic);
----------------------------------------------------------------------
end component;
---------------------------------------------------------------------------------------------------
component reg_ctrl
generic
(g_span : integer := 32;
g_width : integer := 32);
port
(clk_i : in std_logic;
rst_i : in std_logic;
tdc_config_wb_adr_i : in std_logic_vector(g_span-1 downto 0);
tdc_config_wb_cyc_i : in std_logic;
tdc_config_wb_dat_i : in std_logic_vector(g_width-1 downto 0);
tdc_config_wb_stb_i : in std_logic;
tdc_config_wb_we_i : in std_logic;
acam_config_rdbk_i : in config_vector;
acam_ififo1_i : in std_logic_vector(g_width-1 downto 0);
acam_ififo2_i : in std_logic_vector(g_width-1 downto 0);
acam_start01_i : in std_logic_vector(g_width-1 downto 0);
local_utc_i : in std_logic_vector(g_width-1 downto 0);
irq_code_i : in std_logic_vector(g_width-1 downto 0);
wr_index_i : in std_logic_vector(g_width-1 downto 0);
core_status_i : in std_logic_vector(g_width-1 downto 0);
wrabbit_status_reg_i : in std_logic_vector(g_width-1 downto 0);
----------------------------------------------------------------------
tdc_config_wb_ack_o : out std_logic;
tdc_config_wb_dat_o : out std_logic_vector(g_width-1 downto 0);
activate_acq_p_o : out std_logic;
deactivate_acq_p_o : out std_logic;
deactivate_chan_o : out std_logic_vector(4 downto 0);
acam_wr_config_p_o : out std_logic;
acam_rdbk_config_p_o : out std_logic;
acam_rdbk_status_p_o : out std_logic;
acam_rdbk_ififo1_p_o : out std_logic;
acam_rdbk_ififo2_p_o : out std_logic;
acam_rdbk_start01_p_o : out std_logic;
acam_rst_p_o : out std_logic;
load_utc_p_o : out std_logic;
irq_tstamp_threshold_o : out std_logic_vector(g_width-1 downto 0);
irq_time_threshold_o : out std_logic_vector(g_width-1 downto 0);
send_dac_word_p_o : out std_logic;
dac_word_o : out std_logic_vector(23 downto 0);
dacapo_c_rst_p_o : out std_logic;
acam_config_o : out config_vector;
starting_utc_o : out std_logic_vector(g_width-1 downto 0);
acam_inputs_en_o : out std_logic_vector(g_width-1 downto 0);
start_phase_o : out std_logic_vector(g_width-1 downto 0);
one_hz_phase_o : out std_logic_vector(g_width-1 downto 0);
wrabbit_ctrl_reg_o : out std_logic_vector(g_width-1 downto 0));
----------------------------------------------------------------------
end component;
---------------------------------------------------------------------------------------------------
component acam_timecontrol_interface
port
(err_flag_i : in std_logic;
int_flag_i : in std_logic;
acam_refclk_r_edge_p_i : in std_logic;
utc_p_i : in std_logic;
clk_i : in std_logic;
activate_acq_p_i : in std_logic;
rst_i : in std_logic;
window_delay_i : in std_logic_vector(31 downto 0);
state_active_p_i : in std_logic;
deactivate_acq_p_i : in std_logic;
----------------------------------------------------------------------
start_from_fpga_o : out std_logic;
stop_dis_o : out std_logic;
acam_errflag_r_edge_p_o : out std_logic;
acam_errflag_f_edge_p_o : out std_logic;
acam_intflag_f_edge_p_o : out std_logic);
----------------------------------------------------------------------
end component;
---------------------------------------------------------------------------------------------------
component data_formatting
port
(tstamp_wr_wb_ack_i : in std_logic;
tstamp_wr_dat_i : in std_logic_vector(127 downto 0);
acam_tstamp1_i : in std_logic_vector(31 downto 0);
acam_tstamp1_ok_p_i : in std_logic;
acam_tstamp2_i : in std_logic_vector(31 downto 0);
acam_tstamp2_ok_p_i : in std_logic;
clk_i : in std_logic;
dacapo_c_rst_p_i : in std_logic;
deactivate_chan_i : in std_logic_vector(4 downto 0);
rst_i : in std_logic;
roll_over_incr_recent_i : in std_logic;
clk_i_cycles_offset_i : in std_logic_vector(31 downto 0);
roll_over_nb_i : in std_logic_vector(31 downto 0);
utc_i : in std_logic_vector(31 downto 0);
retrig_nb_offset_i : in std_logic_vector(31 downto 0);
utc_p_i : in std_logic;
----------------------------------------------------------------------
tstamp_wr_wb_adr_o : out std_logic_vector(7 downto 0);
tstamp_wr_wb_cyc_o : out std_logic;
tstamp_wr_dat_o : out std_logic_vector(127 downto 0);
tstamp_wr_wb_stb_o : out std_logic;
tstamp_wr_wb_we_o : out std_logic;
tstamp_wr_p_o : out std_logic;
acam_channel_o : out std_logic_vector(2 downto 0);
wr_index_o : out std_logic_vector(31 downto 0));
----------------------------------------------------------------------
end component;
---------------------------------------------------------------------------------------------------
component irq_generator is
generic
(g_width : integer := 32);
port
(clk_i : in std_logic;
rst_i : in std_logic;
irq_tstamp_threshold_i : in std_logic_vector(g_width-1 downto 0);
irq_time_threshold_i : in std_logic_vector(g_width-1 downto 0);
activate_acq_p_i : in std_logic;
deactivate_acq_p_i : in std_logic;
tstamp_wr_p_i : in std_logic;
acam_errflag_r_edge_p_i : in std_logic;
----------------------------------------------------------------------
irq_tstamp_p_o : out std_logic;
irq_acam_err_p_o : out std_logic;
irq_time_p_o : out std_logic);
----------------------------------------------------------------------
end component;
---------------------------------------------------------------------------------------------------
component tdc_eic
port
(rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(1 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
wb_int_o : out std_logic;
irq_tdc_tstamps_i : in std_logic;
irq_tdc_time_i : in std_logic;
irq_tdc_acam_err_i : in std_logic);
end component tdc_eic;
---------------------------------------------------------------------------------------------------
component dma_eic
port
(rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(1 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
wb_int_o : out std_logic;
irq_dma_done_i : in std_logic;
irq_dma_error_i : in std_logic);
end component dma_eic;
---------------------------------------------------------------------------------------------------
component irq_controller
port
(clk_i : in std_logic;
rst_n_i : in std_logic;
irq_src_p_i : in std_logic_vector(31 downto 0);
wb_adr_i : in std_logic_vector(1 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
----------------------------------------------------------------------
wb_dat_o : out std_logic_vector(31 downto 0);
wb_ack_o : out std_logic;
irq_p_o : out std_logic);
end component irq_controller;
---------------------------------------------------------------------------------------------------
component clks_rsts_manager
generic
(nb_of_reg : integer := 68);
port
(clk_sys_i : in std_logic;
acam_refclk_p_i : in std_logic;
acam_refclk_n_i : in std_logic;
tdc_125m_clk_p_i : in std_logic;
tdc_125m_clk_n_i : in std_logic;
rst_n_i : in std_logic;
pll_status_i : in std_logic;
pll_sdo_i : in std_logic;
send_dac_word_p_i : in std_logic;
dac_word_i : in std_logic_vector(23 downto 0);
wrabbit_dac_wr_p_i : in std_logic;
wrabbit_dac_value_i : in std_logic_vector(23 downto 0);
----------------------------------------------------------------------
tdc_125m_clk_o : out std_logic;
internal_rst_o : out std_logic;
acam_refclk_r_edge_p_o : out std_logic;
pll_cs_n_o : out std_logic;
pll_dac_sync_n_o : out std_logic;
pll_sdi_o : out std_logic;
pll_sclk_o : out std_logic;
pll_status_o : out std_logic);
----------------------------------------------------------------------
end component;
---------------------------------------------------------------------------------------------------
component carrier_info
port
(rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(1 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
carrier_info_carrier_pcb_rev_i : in std_logic_vector(3 downto 0);
carrier_info_carrier_reserved_i : in std_logic_vector(11 downto 0);
carrier_info_carrier_type_i : in std_logic_vector(15 downto 0);
carrier_info_stat_fmc_pres_i : in std_logic;
carrier_info_stat_p2l_pll_lck_i : in std_logic;
carrier_info_stat_sys_pll_lck_i : in std_logic;
carrier_info_stat_ddr3_cal_done_i : in std_logic;
carrier_info_stat_reserved_i : in std_logic_vector(27 downto 0);
carrier_info_ctrl_led_green_o : out std_logic;
carrier_info_ctrl_led_red_o : out std_logic;
carrier_info_ctrl_dac_clr_n_o : out std_logic;
carrier_info_ctrl_reserved_o : out std_logic_vector(28 downto 0);
carrier_info_rst_fmc0_n_o : out std_logic;
carrier_info_rst_fmc0_n_i : in std_logic;
carrier_info_rst_fmc0_n_load_o : out std_logic;
carrier_info_rst_reserved_o : out std_logic_vector(30 downto 0));
end component carrier_info;
---------------------------------------------------------------------------------------------------
component leds_manager is
generic
(g_width : integer := 32;
values_for_simul : boolean := false);
port
(clk_i : in std_logic;
rst_i : in std_logic;
utc_p_i : in std_logic;
acam_inputs_en_i : in std_logic_vector(g_width-1 downto 0);
acam_channel_i : in std_logic_vector(5 downto 0);
tstamp_wr_p_i : in std_logic;
----------------------------------------------------------------------
tdc_led_status_o : out std_logic;
tdc_led_trig1_o : out std_logic;
tdc_led_trig2_o : out std_logic;
tdc_led_trig3_o : out std_logic;
tdc_led_trig4_o : out std_logic;
tdc_led_trig5_o : out std_logic);
----------------------------------------------------------------------
end component;
---------------------------------------------------------------------------------------------------
component acam_databus_interface
port
(ef1_i : in std_logic;
ef2_i : in std_logic;
data_bus_io : inout std_logic_vector(27 downto 0);
clk_i : in std_logic;
rst_i : in std_logic;
adr_i : in std_logic_vector(7 downto 0);
cyc_i : in std_logic;
dat_i : in std_logic_vector(31 downto 0);
stb_i : in std_logic;
we_i : in std_logic;
----------------------------------------------------------------------
adr_o : out std_logic_vector(3 downto 0);
cs_n_o : out std_logic;
oe_n_o : out std_logic;
rd_n_o : out std_logic;
wr_n_o : out std_logic;
ack_o : out std_logic;
ef1_o : out std_logic;
ef1_meta_o : out std_logic;
ef2_o : out std_logic;
ef2_meta_o : out std_logic;
dat_o : out std_logic_vector(31 downto 0));
----------------------------------------------------------------------
end component;
---------------------------------------------------------------------------------------------------
component circular_buffer
port
(clk_i : in std_logic;
tstamp_wr_rst_i : in std_logic;
tstamp_wr_stb_i : in std_logic;
tstamp_wr_cyc_i : in std_logic;
tstamp_wr_we_i : in std_logic;
tstamp_wr_adr_i : in std_logic_vector(7 downto 0);
tstamp_wr_dat_i : in std_logic_vector(127 downto 0);
tdc_mem_wb_rst_i : in std_logic;
tdc_mem_wb_stb_i : in std_logic;
tdc_mem_wb_cyc_i : in std_logic;
tdc_mem_wb_we_i : in std_logic;
tdc_mem_wb_adr_i : in std_logic_vector(31 downto 0);
tdc_mem_wb_dat_i : in std_logic_vector(31 downto 0);
--------------------------------------------------
tstamp_wr_ack_p_o : out std_logic;
tstamp_wr_dat_o : out std_logic_vector(127 downto 0);
tdc_mem_wb_ack_o : out std_logic;
tdc_mem_wb_dat_o : out std_logic_vector(31 downto 0);
tdc_mem_wb_stall_o : out std_logic);
--------------------------------------------------
end component;
---------------------------------------------------------------------------------------------------
component blk_mem_circ_buff_v6_4
port
(clka : in std_logic;
addra : in std_logic_vector(7 downto 0);
dina : in std_logic_vector(127 downto 0);
ena : in std_logic;
wea : in std_logic_vector(0 downto 0);
clkb : in std_logic;
addrb : in std_logic_vector(9 downto 0);
dinb : in std_logic_vector(31 downto 0);
enb : in std_logic;
web : in std_logic_vector(0 downto 0);
--------------------------------------------------
douta : out std_logic_vector(127 downto 0);
doutb : out std_logic_vector(31 downto 0));
--------------------------------------------------
end component;
component fmc_tdc_wrapper is
generic (
g_simulation : boolean);
port (
clk_sys_i : in std_logic;
rst_sys_n_i : in std_logic;
rst_n_a_i : in std_logic;
pll_sclk_o : out std_logic;
pll_sdi_o : out std_logic;
pll_cs_o : out std_logic;
pll_dac_sync_o : out std_logic;
pll_sdo_i : in std_logic;
pll_status_i : in std_logic;
tdc_clk_125m_p_i : in std_logic;
tdc_clk_125m_n_i : in std_logic;
acam_refclk_p_i : in std_logic;
acam_refclk_n_i : in std_logic;
start_from_fpga_o : out std_logic;
err_flag_i : in std_logic;
int_flag_i : in std_logic;
start_dis_o : out std_logic;
stop_dis_o : out std_logic;
data_bus_io : inout std_logic_vector(27 downto 0);
address_o : out std_logic_vector(3 downto 0);
cs_n_o : out std_logic;
oe_n_o : out std_logic;
rd_n_o : out std_logic;
wr_n_o : out std_logic;
ef1_i : in std_logic;
ef2_i : in std_logic;
enable_inputs_o : out std_logic;
term_en_1_o : out std_logic;
term_en_2_o : out std_logic;
term_en_3_o : out std_logic;
term_en_4_o : out std_logic;
term_en_5_o : out std_logic;
tdc_led_status_o : out std_logic;
tdc_led_trig1_o : out std_logic;
tdc_led_trig2_o : out std_logic;
tdc_led_trig3_o : out std_logic;
tdc_led_trig4_o : out std_logic;
tdc_led_trig5_o : out std_logic;
tdc_in_fpga_1_i : in std_logic;
tdc_in_fpga_2_i : in std_logic;
tdc_in_fpga_3_i : in std_logic;
tdc_in_fpga_4_i : in std_logic;
tdc_in_fpga_5_i : in std_logic;
mezz_one_wire_b : inout std_logic;
mezz_scl_b : inout std_logic;
mezz_sda_b : inout std_logic;
tm_link_up_i : in std_logic;
tm_time_valid_i : in std_logic;
tm_cycles_i : in std_logic_vector(27 downto 0);
tm_tai_i : in std_logic_vector(39 downto 0);
tm_clk_aux_lock_en_o : out std_logic;
tm_clk_aux_locked_i : in std_logic;
tm_clk_dmtd_locked_i : in std_logic;
tm_dac_value_i : in std_logic_vector(23 downto 0);
tm_dac_wr_i : in std_logic;
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
direct_slave_i : in t_wishbone_slave_in;
direct_slave_o : out t_wishbone_slave_out;
irq_o : out std_logic);
end component fmc_tdc_wrapper;
component fmc_tdc_direct_readout is
port (
clk_tdc_i : in std_logic;
rst_tdc_n_i : in std_logic;
clk_sys_i : in std_logic;
rst_sys_n_i : in std_logic;
direct_timestamp_i : in std_logic_vector(127 downto 0);
direct_timestamp_wr_i : in std_logic;
direct_slave_i : in t_wishbone_slave_in;
direct_slave_o : out t_wishbone_slave_out);
end component fmc_tdc_direct_readout;
end tdc_core_pkg;
--=================================================================================================
-- package body
--=================================================================================================
package body tdc_core_pkg is
end tdc_core_pkg;
--=================================================================================================
-- package end
--=================================================================================================
---------------------------------------------------------------------------------------------------
-- E N D O F F I L E
---------------------------------------------------------------------------------------------------
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment