Commit 13d729a4 authored by egousiou's avatar egousiou

folders restructuring; one core for both spec and svec

git-svn-id: http://svn.ohwr.org/fmc-tdc@120 85dfdc96-de2c-444c-878d-45b388be74a9
parent a7b11dc6
--_________________________________________________________________________________________________
-- |
-- |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 aquisition 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_____| | |
-- |___________| |____________| |___________| |
-- |
-- |
-- 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 |
-- |
----------------------------------------------/!\-------------------------------------------------|
-- 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. |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- 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
--=================================================================================================
-- 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
-- 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 PCIe/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;
-- 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;
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
---------------------------------------------------------------------------------------------------
-- IntFlag and ERRflag Input Synchronizers --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
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_o <= not(int_flag_synch(1)) and int_flag_synch(0);
---------------------------------------------------------------------------------------------------
-- Input Synchronizers --
---------------------------------------------------------------------------------------------------
-- 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;
inputs_synchronizer: 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
---------------------------------------------------------------------------------------------------
--_________________________________________________________________________________________________
-- |
-- |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 GNUM/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 GNUM core is only reading from it. |
-- |
-- |
-- RAM as seen from the RAM as seen from the |
-- data_formatting unit GNUM/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 GNUM/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 GNUM/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 GNUM/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_20m_vcxo_i to parameterize the TDC mezzanine |
-- PLL and DAC that will be used by all the other blocks. |
-- Includes input clk buffers for Xilinx Spartan6. |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Date 05/2012 |
-- Version v0.3 |
-- 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 |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- 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_20m_vcxo_i : in std_logic; -- 20 MHz OSC on carrier board
-- 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 PCIe/VME interface
rst_n_i : in std_logic; -- GNUM/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 VME request for a DAC reconfiguration
dac_word_i : in std_logic_vector(23 downto 0); -- DAC Vout = Vref (dac_word/65536)
-- 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 synched with 20 MHz clock
end clks_rsts_manager;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of clks_rsts_manager is
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);
-- 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
-- PLL and DAC configuration state machine
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;
signal pll_bit_being_sent, dac_bit_being_sent : std_logic;
signal bit_being_sent, send_dac_word_r_edge_p : std_logic;
signal pll_bit_index : integer range 15 downto 0;
signal dac_bit_index : integer range 23 downto 0;
signal dac_word : std_logic_vector(23 downto 0);
signal pll_byte_index : integer range nb_of_reg-1 downto 0;
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 sclk, tdc_clk, acam_refclk : std_logic;
-- Resets
signal internal_rst, interf_rst, rst, vme_rst : std_logic;
signal rst_cnt, vme_rst_cnt : unsigned(7 downto 0) := "00000000";
--=================================================================================================
-- 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;
---------------------------------------------------------------------------------------------------
-- Global Internal Reset --
---------------------------------------------------------------------------------------------------
-- The following processes generate a global internal reset signal for all the rest of the core.
-- This internal reset is triggered by a GNUM/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 GNUM/VME interface or a PoR, to the clk_20m_vcxo_i, using a set of 2 registers.
-- Note that the removal of the reset signal is synchronised.
PoR_synchronizer: process (clk_20m_vcxo_i, rst_n_i)
begin
if rst_n_i = '0' then
rst_in_synch <= (others => '1');
elsif rising_edge (clk_20m_vcxo_i) then
rst_in_synch <= rst_in_synch(0) & '0';
end if;
end process;
---------------------------------------------------------------------------------------------------
-- Synchronous process pll_status_synchronizer: Synchronization of the pll_status_i input to the
-- clk_20m_vcxo_i, using a set of 2 registers.
pll_status_synchronizer: process (clk_20m_vcxo_i)
begin
if rising_edge (clk_20m_vcxo_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 Global_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 global 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 PCIe/VME reset during operation the PLL will remain locked, therefore no
-- rising would be detected.
Global_rst_generation: process (clk_20m_vcxo_i)
begin
if rising_edge (clk_20m_vcxo_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 global rst signal to the
-- 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_20m_vcxo_i, using a set of 3 registers.
send_dac_word_p_synchronizer: process (clk_20m_vcxo_i)
begin
if rising_edge (clk_20m_vcxo_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 pll_dac_word: 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.
pll_dac_word: process (clk_20m_vcxo_i)
begin
if rising_edge (clk_20m_vcxo_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;
end if;
end if;
end process;
---------------------------------------------------------------------------------------------------
-- FSM for configuration of the DAC and PLL --
---------------------------------------------------------------------------------------------------
-- Configuration of the PLL on the TDC mezzanine board:
-- after the powering-up of the board or after a GNUM/VME reset (rst_n_i), or
-- after a PCIe/VME command for the reconfiguration of the DAC (send_dac_word_p_i)
---------------------------------------------------------------------------------------------------
pll_dac_initialization_seq: process (clk_20m_vcxo_i)
begin
if rising_edge (clk_20m_vcxo_i) then
if rst_in_synch(1) = '1' then
config_st <= config_start;
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)
begin
case config_st is
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when config_start =>
-----------------------------------
pll_cs_n <= '1';
dac_cs_n <= '1';
-----------------------------------
if sclk = '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 = '1' then
nxt_config_st <= sending_pll_instruction;
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 = '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 = '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 = '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_20m_vcxo_i) -- transitions take place on the falling edge of sclk
begin
if rising_edge (clk_20m_vcxo_i) then
if rst_in_synch(1) = '1' then
sclk <= '0';
else
sclk <= not(sclk);
end if;
end if;
end process;
---------------------------------------------------------------------------------------------------
pll_index_control: process (clk_20m_vcxo_i)
begin
if rising_edge (clk_20m_vcxo_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 = '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 = '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_20m_vcxo_i)
begin
if rising_edge (clk_20m_vcxo_i) then
if rst_in_synch(1) = '1' then
dac_bit_index <= 23;
elsif dac_cs_n = '1' then
dac_bit_index <= 23;
elsif sclk = '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;
---------------------------------------------------------------------------------------------------
Output_regs: process (clk_20m_vcxo_i)
begin
if rising_edge (clk_20m_vcxo_i) then
if rst_in_synch(1) = '1' then
pll_cs_n_o <= '1';
pll_dac_sync_n_o <= '1';
pll_sdi_o <= '0';
else
if sclk = '1' then
pll_sdi_o <= bit_being_sent;
pll_dac_sync_n_o <= dac_cs_n;
pll_cs_n_o <= pll_cs_n;
end if;
end if;
end if;
end process;
-- -- -- -- -- -- -- --
pll_sclk_o <= sclk;
---------------------------------------------------------------------------------------------------
-- Assignement of the values to be sent for the configurations of the PLL --
---------------------------------------------------------------------------------------------------
-- According to the datasheet 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 |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- 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 PCIe/VME for registers configuration
activate_acq_p_i : in std_logic; -- activates tstamps aquisition
deactivate_acq_p_i : in std_logic; -- activates 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 PCIe/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
-- OUTPUTS
-- 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 PCIe/VME for registers configuration
acam_config_rdbk_o : out config_vector; -- array keeping values read from ACAM regs 0-7, 11, 12, 14
acam_status_o : out std_logic_vector(31 downto 0);-- keeps value read from ACAM reg 12
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);
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);
--=================================================================================================
-- 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 PCIe/VME interface and this core take place at the
-- the reg_ctrl unit.
when INACTIVE =>
-----------------------------------------------
acam_cyc <= '0';
acam_stb <= '0';
acam_we <= '0';
-----------------------------------------------
if activate_acq_p_i = '1' then -- activation of timestamps aquisition
nxt_engine_st <= ACTIVE;
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 ACTIVE =>
-----------------------------------------------
acam_cyc <= '0';
acam_stb <= '0';
acam_we <= '0';
-----------------------------------------------
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';
-----------------------------------------------
if 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';
-----------------------------------------------
if acam_ack_i ='1' then -- idem.
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';
-----------------------------------------------
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';
-----------------------------------------------
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';
-----------------------------------------------
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';
-----------------------------------------------
if acam_ack_i ='1' then
nxt_engine_st <= INACTIVE;
else
nxt_engine_st <= RD_IFIFO2;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when RD_START01 =>
-----------------------------------------------
acam_cyc <= '1';
acam_stb <= '1';
acam_we <= '0';
-----------------------------------------------
if acam_ack_i ='1' then
nxt_engine_st <= INACTIVE;
else
nxt_engine_st <= RD_START01;
end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when WR_RESET =>
-----------------------------------------------
acam_cyc <= '1';
acam_stb <= '1';
acam_we <= '1';
-----------------------------------------------
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';
-----------------------------------------------
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 PCIe 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;
acam_status_o <= acam_config_rdbk(9);
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 PCIe/VME to clear dacapo flag
-- Signals from the one_hz_gen unit
local_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
one_hz_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
-- 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 PCIe/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 : std_logic_vector(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 : std_logic_vector(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);
--=================================================================================================
-- 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' or acam_tstamp2_ok_p_i ='1' then
tstamp_wr_stb <= '1';
tstamp_wr_cyc <= '1';
tstamp_wr_we <= '1';
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 PCIe 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 PCIe/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 <= acam_tstamp1_i(25 downto 18);
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 <= acam_tstamp2_i(25 downto 18);
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 one_hz_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 <= local_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 difined
-- 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');
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
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 <= local_utc_i;
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-1, 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 substracting timestamps.
coarse_time <= std_logic_vector(un_nb_of_cycles);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- 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 <= acam_start_nb & retrig_nb_offset_i(15 downto 0) & -- for debugging (24 MSbits)
acam_fifo_ef & roll_over_incr_recent_i & "0" & -- for debugging (3 bits)
acam_slope & "0" & 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;
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 |
-- PCIe/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 unit, where the GNUM/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 GNUM/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 | |
-- | | | | | | | | | core | |
-- | | start | | | | | | | | |
-- | | 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 gnum 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;
--=================================================================================================
-- 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 PCIe/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 PCIe/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; -- stop disable, not used
-- 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
-- WISHBONE bus interface with the PCIe/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 PCIe/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
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 pulse_delay, window_delay, clk_period : std_logic_vector(g_width-1 downto 0);
signal starting_utc, acam_status, 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 : std_logic;
-- retrigger control
signal clk_i_cycles_offset, roll_over_nb, retrig_nb_offset: std_logic_vector(g_width-1 downto 0);
signal one_hz_p : std_logic;
-- 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);
--LED
signal led_fordebug : std_logic_vector(5 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,
acam_config_rdbk_i => acam_config_rdbk,
acam_status_i => acam_status,
acam_ififo1_i => acam_ififo1,
acam_ififo2_i => acam_ififo2,
acam_start01_i => acam_start01,
local_utc_i => local_utc,
irq_code_i => x"00000000",
core_status_i => x"00000000",
wr_index_i => wr_index,
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);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- 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;
---------------------------------------------------------------------------------------------------
-- ONE HZ GENERATOR --
---------------------------------------------------------------------------------------------------
one_second_block: one_hz_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,
one_hz_p_o => one_hz_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_o,
acam_refclk_r_edge_p_i => acam_refclk_r_edge_p_i,
clk_i => clk_125m_i,
activate_acq_p_i => activate_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);
---------------------------------------------------------------------------------------------------
-- 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,
one_hz_p_i => one_hz_p,
rst_i => rst_i,
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,
acam_config_rdbk_o => acam_config_rdbk,
acam_status_o => acam_status,
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,
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,
one_hz_p_i => one_hz_p,
local_utc_i => local_utc,
tstamp_wr_p_o => tstamp_wr_p,
wr_index_o => wr_index);
---------------------------------------------------------------------------------------------------
-- 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,
one_hz_p_i => one_hz_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,
one_hz_p_i => one_hz_p,
acam_inputs_en_i => acam_inputs_en,
fordebug_i => led_fordebug,
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);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
led_fordebug <= (others => '0');
---------------------------------------------------------------------------------------------------
-- ACAM start_dis/ stop_dis, not used --
---------------------------------------------------------------------------------------------------
start_dis_o <= '0';
stop_dis_o <= '0';
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
\ No newline at end of file
--_________________________________________________________________________________________________
-- |
-- |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&Thermetec |
-- For the interconnection between the GNUM/VME core and the different cores (TDC, |
-- I2C, 1W) the unit also instantiates an SDB crossbar. |
-- |
-- ______________________________ |
-- | | |
-- | ________________ ___ | |
-- | | | | | | |
-- ACAM chip <--> | | TDC core | | | | <--> |
-- | |________________| | S | | |
-- | ________________ | | | |
-- | | | | | | |
-- EEPROM chip <--> | | I2C core | | D | | <--> GNUM/VME core |
-- | |________________| | | | |
-- | ________________ | | | |
-- | | | | B | | |
-- 1W chip <--> | | 1W core | | | | <--> |
-- | |________________| |___| | |
-- | | |
-- |_______________________________| |
-- FMC TDC mezzanine |
-- _______________________________ |
-- | | |
-- DAC chip <--> | clks_rsts_manager | |
-- |_______________________________| |
-- |
-- Figure 1: FMC TDC mezzanine architecture |
-- |
-- |
-- Note that the SPI communication with the TDC board DAC is implemented in the |
-- clcks_rsts_manager;no access to the DAC is provided through the GNUM/VME interface|
-- |
-- Note that the TDC core uses word addressing, whereas the GNUM/VME cores use byte |
-- addressing |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 07/2013 |
-- Version v1 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 07/2013 v1 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
--=================================================================================================
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
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;
irq_tstamp_p_o : out std_logic;
irq_time_p_o : out std_logic;
irq_acam_err_p_o : out std_logic;
-- WISHBONE interface with the GNUM/VME_core
wb_tdc_mezz_adr_i : in std_logic_vector(31 downto 0);
wb_tdc_mezz_dat_i : in std_logic_vector(31 downto 0);
wb_tdc_mezz_dat_o : out std_logic_vector(31 downto 0);
wb_tdc_mezz_cyc_i : in std_logic;
wb_tdc_mezz_sel_i : in std_logic_vector(3 downto 0);
wb_tdc_mezz_stb_i : in std_logic;
wb_tdc_mezz_we_i : in std_logic;
wb_tdc_mezz_ack_o : out std_logic;
wb_tdc_mezz_stall_o : out std_logic;
-- I2C EEPROM interface
sys_scl_b : inout std_logic;
sys_sda_b : inout std_logic;
-- 1-wire UniqueID&Thermometer interface
mezz_one_wire_b : inout 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_CORE_CONFIG : integer := 0; -- TDC core configuration registers
constant c_WB_SLAVE_TDC_ONEWIRE : integer := 1; -- TDC mezzanine board UnidueID&Thermometer 1-wire
constant c_WB_SLAVE_DUMMY : integer := 2; -- Dummy for debugging
constant c_WB_SLAVE_TDC_SYS_I2C : integer := 3; -- TDC mezzanine board system EEPROM I2C
constant c_WB_SLAVE_TSTAMP_MEM : integer := 4; -- Access to TDC core timestamps memory
-- 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_TDC_CONFIG_SDB_DEVICE, x"00010000"),
1 => f_sdb_embed_device(c_ONEWIRE_SDB_DEVICE, x"00011000"),
2 => f_sdb_embed_device(c_TDC_CONFIG_SDB_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 : 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 addresses
signal tdc_core_wb_adr : std_logic_vector(31 downto 0);
signal tdc_mem_wb_adr : std_logic_vector(31 downto 0);
signal dummy_core_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;
-- dummy
signal dummy_reg_1 : std_logic_vector(31 downto 0) := x"F000000D";
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
general_rst_n <= not(rst_i);
---------------------------------------------------------------------------------------------------
-- CSR WISHBONE CROSSBAR --
---------------------------------------------------------------------------------------------------
-- CSR wishbone address decoder
-- 0x10000 -> TDC memory for timestamps retrieval
-- 0x11000 -> TDC core configuration
-- 0x12000 -> TDC mezzanine board system EEPROM I2C
-- 0x13000 -> TDC mezzanine board UnidueID&Thermometer 1-wire
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_125m_i,
rst_n_i => general_rst_n,
slave_i => cnx_slave_in,
slave_o => cnx_slave_out,
master_i => cnx_master_in,
master_o => cnx_master_out);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Connect crossbar slave port to entity port
cnx_slave_in(c_WB_MASTER).adr <= wb_tdc_mezz_adr_i;
cnx_slave_in(c_WB_MASTER).dat <= wb_tdc_mezz_dat_i;
cnx_slave_in(c_WB_MASTER).sel <= wb_tdc_mezz_sel_i;
cnx_slave_in(c_WB_MASTER).stb <= wb_tdc_mezz_stb_i;
cnx_slave_in(c_WB_MASTER).we <= wb_tdc_mezz_we_i;
cnx_slave_in(c_WB_MASTER).cyc <= wb_tdc_mezz_cyc_i;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Unused wishbone signals
wb_tdc_mezz_dat_o <= cnx_slave_out(c_WB_MASTER).dat;
wb_tdc_mezz_ack_o <= cnx_slave_out(c_WB_MASTER).ack;
wb_tdc_mezz_stall_o <= cnx_slave_out(c_WB_MASTER).stall;
---------------------------------------------------------------------------------------------------
-- TDC CORE --
---------------------------------------------------------------------------------------------------
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_125m_i,
rst_i => rst_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_o,
irq_time_p_o => irq_time_p_o,
irq_acam_err_p_o => irq_acam_err_p_o,
-- 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,
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);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- 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';
---------------------------------------------------------------------------------------------------
-- TDC Mezzanine Board EEPROM I2C --
---------------------------------------------------------------------------------------------------
mezzanine_I2C_master_EEPROM : xwb_i2c_master
generic map
(g_interface_mode => PIPELINED,
g_address_granularity => BYTE)
port map
(clk_sys_i => clk_125m_i,
rst_n_i => general_rst_n,
slave_i => cnx_master_out(c_WB_SLAVE_TDC_SYS_I2C),
slave_o => cnx_master_in(c_WB_SLAVE_TDC_SYS_I2C),
desc_o => open,
scl_pad_i => sys_scl_in,
scl_pad_o => sys_scl_out,
scl_padoen_o => sys_scl_oe_n,
sda_pad_i => sys_sda_in,
sda_pad_o => sys_sda_out,
sda_padoen_o => sys_sda_oe_n);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Tri-state buffer for SDA and SCL
sys_scl_b <= sys_scl_out when sys_scl_oe_n = '0' else 'Z';
sys_scl_in <= sys_scl_b;
sys_sda_b <= sys_sda_out when sys_sda_oe_n = '0' else 'Z';
sys_sda_in <= sys_sda_b;
---------------------------------------------------------------------------------------------------
-- TDC Mezzanine Board UniqueID&Thermometer OneWite --
---------------------------------------------------------------------------------------------------
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_125m_i,
rst_n_i => general_rst_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);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
mezz_one_wire_b <= '0' when mezz_owr_en(0) = '1' else 'Z';
mezz_owr_i(0) <= mezz_one_wire_b;
---------------------------------------------------------------------------------------------------
-- Dummy for debugging only! --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- WISHBONE ack generation
dummy_ack_generator: process (clk_125m_i)
begin
if rising_edge (clk_125m_i) then
if general_rst_n = '0' then
cnx_master_in(c_WB_SLAVE_DUMMY).ack <= '0';
else
cnx_master_in(c_WB_SLAVE_DUMMY).ack <= cnx_master_out(c_WB_SLAVE_DUMMY).stb and
cnx_master_out(c_WB_SLAVE_DUMMY).cyc;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Registers read/write
dummy_regs_exchange: process (clk_125m_i)
begin
if rising_edge (clk_125m_i) then
if general_rst_n = '0' then
dummy_reg_1 <= x"F000000D";
elsif cnx_master_out(c_WB_SLAVE_DUMMY).cyc = '1' and cnx_master_out(c_WB_SLAVE_DUMMY).stb = '1'
and cnx_master_out(c_WB_SLAVE_DUMMY).we = '1' then
if dummy_core_wb_adr(7 downto 0) = x"00" then
dummy_reg_1 <= cnx_master_out(c_WB_SLAVE_DUMMY).dat;
end if;
elsif cnx_master_out(c_WB_SLAVE_DUMMY).cyc = '1' and cnx_master_out(c_WB_SLAVE_DUMMY).stb = '1'
and cnx_master_out(c_WB_SLAVE_DUMMY).we = '0' then
if dummy_core_wb_adr(7 downto 0) = x"00" then
cnx_master_in(c_WB_SLAVE_DUMMY).dat <= dummy_reg_1;
elsif dummy_core_wb_adr(7 downto 0) = x"01" then
cnx_master_in(c_WB_SLAVE_DUMMY).dat <= wb_tdc_mezz_adr_i;
else
cnx_master_in(c_WB_SLAVE_DUMMY).dat <= dummy_core_wb_adr;
end if;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Unused wishbone signals
dummy_core_wb_adr <= cnx_master_out(c_WB_SLAVE_DUMMY).adr;
cnx_master_in(c_WB_SLAVE_DUMMY).err <= '0';
cnx_master_in(c_WB_SLAVE_DUMMY).rty <= '0';
cnx_master_in(c_WB_SLAVE_DUMMY).stall <= '0';
cnx_master_in(c_WB_SLAVE_DUMMY).int <= '0';
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 PCIe/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 PCIe/VME|
-- settable threshold irq_time_threshold |
-- |
-- 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, synched to clk_i
irq_tstamp_threshold_i : in std_logic_vector(g_width-1 downto 0); -- PCIe/VME settable threshold
irq_time_threshold_i : in std_logic_vector(g_width-1 downto 0); -- PCIe/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
-- Signal from the one_hz_gen unit (currently not used)
one_hz_p_i : in std_logic; -- pulse upon new second arrival
-- 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
--=================================================================================================
-- 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
one_hz_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
fordebug_i : in std_logic_vector(5 downto 0); -- for debugging, currently not used
-- 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);
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 => one_hz_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 one_hz_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 --
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
lad_1to5_outputs: process (clk_i)
begin
if rising_edge (clk_i) then
tdc_led_trig5_o <= acam_inputs_en_i(4) and acam_inputs_en_i(7);
tdc_led_trig4_o <= acam_inputs_en_i(3) and acam_inputs_en_i(7);
tdc_led_trig3_o <= acam_inputs_en_i(2) and acam_inputs_en_i(7);
tdc_led_trig2_o <= acam_inputs_en_i(1) and acam_inputs_en_i(7);
tdc_led_trig1_o <= acam_inputs_en_i(0) and acam_inputs_en_i(7);
end if;
end process;
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- one_hz_gen |
-- |
---------------------------------------------------------------------------------------------------
-- File one_hz_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 one_hz_gen
--=================================================================================================
entity one_hz_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 PCIe/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
one_hz_p_o : out std_logic); -- pulse upon new second
end one_hz_gen;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of one_hz_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);
one_hz_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 PCIe/VME core for the configuration of the ACAM chip and of |
-- the TDC core. Data transfers take place between the PCIe/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 GNUM/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: config regs readback from the ACAM
acam_config_rdbk_i : in config_vector; -- array keeping values read back from ACAM regs 0-7, 11, 12, 14
acam_status_i : in std_logic_vector(g_width-1 downto 0); -- keeps value read back from ACAM reg 12
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
-- OUTPUTS
-- Signals to the GNUM/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
-- Signals to the clks_resets_manager ubit
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
-- 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, dat_out_pipe0 : 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 GNUM/VME_core --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- TDCconfig_ack_generator: generation of the WISHBONE acknowledge signal for the
-- interactions with the PCIe/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 PCIe/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 PCIe/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 PCIe/VME interrupts based on the number of timestamps
-- o irq_time_threshold : for the activation of PCIe/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;
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;
---------------------------------------------------------------------------------------------------
-- Reception of TDC core Control Register --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- TDCcore_ctrl_reg_reception: reception from the PCIe/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);
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 PCIe interface of all the readable registers,
-- including those of the ACAM and the TDC core.
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 PCIe/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 PCIe/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,
-- others
x"C0FFEEEE" when others;
end architecture rtl;
--=================================================================================================
-- architecture end
--=================================================================================================
---------------------------------------------------------------------------------------------------
-- E N D O F F I L E
---------------------------------------------------------------------------------------------------
--_________________________________________________________________________________________________
-- |
-- |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
one_hz_p_i : in std_logic;
-- OUTPUTS
-- Signals to the data_formatting unit
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
-- one_hz_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 one_hz_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 one_hz_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 one_hz_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 one_hz_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
-- one_hz_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
-- _______________________________________ _________________________________________ ____________________
-- one_hz_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 => one_hz_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 timestamps arrives, these offset will be subrstracted 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 one_hz_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;
end architecture rtl;
--=================================================================================================
-- architecture end
--=================================================================================================
---------------------------------------------------------------------------------------------------
-- E N D O F F I L E
---------------------------------------------------------------------------------------------------
#
# 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
--_________________________________________________________________________________________________
-- |
-- |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 => "SynpliDP",
-- Synthesis tool version (bcd encoded, 32-bit)
syn_tool_version => x"00201203",
-- Synthesis date (bcd encoded, 32-bit)
syn_date => x"20130410",
-- 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"00010001", -- bcd encoded, [31:16] = major, [15:0] = minor
date => x"20130429", -- yyyymmdd
name => "spec_fmctdc1ns5cha "));
end sdb_meta_pkg;
package body sdb_meta_pkg is
end sdb_meta_pkg;
\ No newline at end of file
--_________________________________________________________________________________________________
-- |
-- |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.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 crossbar --
---------------------------------------------------------------------------------------------------
-- Note: All address in sdb and crossbar are BYTE addresses!
-- Master ports on the wishbone crossbar
constant c_NUM_WB_MASTERS : integer := 7;
constant c_SLAVE_DMA : integer := 0; -- DMA controller in the Gennum core
constant c_SLAVE_SPEC_ONEWIRE: integer := 1; -- Carrier onewire interface
constant c_SLAVE_SPEC_CSR : integer := 2; -- Info on SPEC control and status registers
constant c_SLAVE_TDC_CORE : integer := 3; -- TDC core
constant c_SLAVE_INT : integer := 4; -- Interrupt controller
constant c_SLAVE_FMC_SYS_I2C : integer := 5; -- Mezzanine system I2C interface (EEPROM)
constant c_SLAVE_FMC_ONEWIRE : integer := 6; -- Mezzanine onewire interface
-- Slave port on the wishbone crossbar
constant c_NUM_WB_SLAVES : integer := 1;
constant c_MASTER_GENNUM : integer := 0;
-- SDB header address
constant c_SDB_ADDRESS : t_wishbone_address := x"00000000";
-- Devices sdb description
constant c_DMA_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"000000000000003F",
product =>
(vendor_id => x"000000000000CE42", -- CERN
device_id => x"00000601",
version => x"00000001",
date => x"20121116",
name => "WB-DMA.Control ")));
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",
version => x"00000001",
date => x"20121116",
name => "WB-Onewire.Control ")));
constant c_SPEC_CSR_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",
version => x"00000001",
date => x"20121116",
name => "WB-SPEC-CSR ")));
constant c_TDC_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",
version => x"00000001",
date => x"20130429",
name => "WB-TDC-Core ")));
constant c_INT_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"000000000000000F",
product =>
(vendor_id => x"000000000000CE42", -- CERN
device_id => x"00000605",
version => x"00000001",
date => x"20121116",
name => "WB-Int.Control ")));
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",
version => x"00000001",
date => x"20121116",
name => "WB-I2C.Control ")));
-- Wishbone crossbar layout
constant c_INTERCONNECT_LAYOUT : t_sdb_record_array(9 downto 0) :=
(0 => f_sdb_embed_device(c_DMA_SDB_DEVICE, x"00004000"),
1 => f_sdb_embed_device(c_ONEWIRE_SDB_DEVICE, x"00004800"),
2 => f_sdb_embed_device(c_SPEC_CSR_SDB_DEVICE, x"00004C00"),
3 => f_sdb_embed_device(c_TDC_SDB_DEVICE, x"00005000"),
4 => f_sdb_embed_device(c_INT_SDB_DEVICE, x"00005400"),
5 => f_sdb_embed_device(c_I2C_SDB_DEVICE, x"00005800"),
6 => f_sdb_embed_device(c_ONEWIRE_SDB_DEVICE, x"00005C00"),
7 => f_sdb_embed_repo_url(c_SDB_REPO_URL),
8 => f_sdb_embed_synthesis(c_SDB_SYNTHESIS),
9 => f_sdb_embed_integration(c_SDB_INTEGRATION));
---------------------------------------------------------------------------------------------------
-- 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 5000 of gnum BAR 0
constant c_ACAM_REG1_ADR : std_logic_vector(7 downto 0) := x"01"; -- address 5004 of gnum BAR 0
constant c_ACAM_REG2_ADR : std_logic_vector(7 downto 0) := x"02"; -- address 5008 of gnum BAR 0
constant c_ACAM_REG3_ADR : std_logic_vector(7 downto 0) := x"03"; -- address 500C of gnum BAR 0
constant c_ACAM_REG4_ADR : std_logic_vector(7 downto 0) := x"04"; -- address 5010 of gnum BAR 0
constant c_ACAM_REG5_ADR : std_logic_vector(7 downto 0) := x"05"; -- address 5014 of gnum BAR 0
constant c_ACAM_REG6_ADR : std_logic_vector(7 downto 0) := x"06"; -- address 5018 of gnum BAR 0
constant c_ACAM_REG7_ADR : std_logic_vector(7 downto 0) := x"07"; -- address 501C of gnum BAR 0
constant c_ACAM_REG11_ADR : std_logic_vector(7 downto 0) := x"0B"; -- address 502C of gnum BAR 0
constant c_ACAM_REG12_ADR : std_logic_vector(7 downto 0) := x"0C"; -- address 5030 of gnum BAR 0
constant c_ACAM_REG14_ADR : std_logic_vector(7 downto 0) := x"0E"; -- address 5038 of gnum 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 5040 of the gnum BAR 0
constant c_ACAM_REG1_RDBK_ADR : std_logic_vector(7 downto 0) := x"11"; -- address 5044 of the gnum BAR 0
constant c_ACAM_REG2_RDBK_ADR : std_logic_vector(7 downto 0) := x"12"; -- address 5048 of the gnum BAR 0
constant c_ACAM_REG3_RDBK_ADR : std_logic_vector(7 downto 0) := x"13"; -- address 504C of the gnum BAR 0
constant c_ACAM_REG4_RDBK_ADR : std_logic_vector(7 downto 0) := x"14"; -- address 5050 of the gnum BAR 0
constant c_ACAM_REG5_RDBK_ADR : std_logic_vector(7 downto 0) := x"15"; -- address 5054 of the gnum BAR 0
constant c_ACAM_REG6_RDBK_ADR : std_logic_vector(7 downto 0) := x"16"; -- address 5058 of the gnum BAR 0
constant c_ACAM_REG7_RDBK_ADR : std_logic_vector(7 downto 0) := x"17"; -- address 505C of the gnum BAR 0
constant c_ACAM_REG8_RDBK_ADR : std_logic_vector(7 downto 0) := x"18"; -- address 5060 of the gnum BAR 0
constant c_ACAM_REG9_RDBK_ADR : std_logic_vector(7 downto 0) := x"19"; -- address 5064 of the gnum BAR 0
constant c_ACAM_REG10_RDBK_ADR : std_logic_vector(7 downto 0) := x"1A"; -- address 5068 of the gnum BAR 0
constant c_ACAM_REG11_RDBK_ADR : std_logic_vector(7 downto 0) := x"1B"; -- address 506C of the gnum BAR 0
constant c_ACAM_REG12_RDBK_ADR : std_logic_vector(7 downto 0) := x"1C"; -- address 5070 of the gnum BAR 0
constant c_ACAM_REG14_RDBK_ADR : std_logic_vector(7 downto 0) := x"1E"; -- address 5078 of the gnum 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 5080 of gnum BAR 0
constant c_ACAM_INPUTS_EN_ADR : std_logic_vector(7 downto 0) := x"21"; -- address 5084 of gnum BAR 0
constant c_START_PHASE_ADR : std_logic_vector(7 downto 0) := x"22"; -- address 5088 of gnum BAR 0
constant c_ONE_HZ_PHASE_ADR : std_logic_vector(7 downto 0) := x"23"; -- address 508C of gnum BAR 0
constant c_IRQ_TSTAMP_THRESH_ADR: std_logic_vector(7 downto 0) := x"24"; -- address 5090 of gnum BAR 0
constant c_IRQ_TIME_THRESH_ADR : std_logic_vector(7 downto 0) := x"25"; -- address 5094 of gnum BAR 0
constant c_DAC_WORD_ADR : std_logic_vector(7 downto 0) := x"26"; -- address 5098 of gnum BAR 0
-- constant c_RESERVED1 : std_logic_vector(7 downto 0) := x"27"; -- address 509C of gnum 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 50A0 of gnum BAR 0
constant c_IRQ_CODE_ADR : std_logic_vector(7 downto 0) := x"29"; -- address 50A4 of gnum BAR 0
constant c_WR_INDEX_ADR : std_logic_vector(7 downto 0) := x"2A"; -- address 50A8 of gnum BAR 0
constant c_CORE_STATUS_ADR : std_logic_vector(7 downto 0) := x"2B"; -- address 50AC of gnum BAR 0
---------------------------------------------------------------------------------------------------
-- Address of TDC core Control register
-- corresponds to:
constant c_CTRL_REG_ADR : std_logic_vector(7 downto 0) := x"3F"; -- address 50FC of gnum 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_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;
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);
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;
one_hz_p_i : in std_logic;
----------------------------------------------------------------------
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 one_hz_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);
one_hz_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;
----------------------------------------------------------------------
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_status_o : out std_logic_vector(31 downto 0);
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_status_i : in std_logic_vector(g_width-1 downto 0);
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);
----------------------------------------------------------------------
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;
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));
----------------------------------------------------------------------
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;
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);
----------------------------------------------------------------------
start_from_fpga_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;
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);
local_utc_i : in std_logic_vector(31 downto 0);
retrig_nb_offset_i : in std_logic_vector(31 downto 0);
one_hz_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;
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;
one_hz_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 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_20m_vcxo_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);
----------------------------------------------------------------------
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_csr
port
(rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(1 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_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;
carrier_csr_carrier_pcb_rev_i : in std_logic_vector(3 downto 0);
carrier_csr_carrier_reserved_i : in std_logic_vector(11 downto 0);
carrier_csr_carrier_type_i : in std_logic_vector(15 downto 0);
carrier_csr_stat_fmc_pres_i : in std_logic;
carrier_csr_stat_p2l_pll_lck_i : in std_logic;
carrier_csr_stat_sys_pll_lck_i : in std_logic;
carrier_csr_stat_ddr3_cal_done_i : in std_logic;
carrier_csr_stat_reserved_i : in std_logic_vector(27 downto 0);
carrier_csr_ctrl_led_green_o : out std_logic;
carrier_csr_ctrl_led_red_o : out std_logic;
carrier_csr_ctrl_dac_clr_n_o : out std_logic;
carrier_csr_ctrl_reserved_o : out std_logic_vector(28 downto 0));
end component carrier_csr;
---------------------------------------------------------------------------------------------------
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;
one_hz_p_i : in std_logic;
acam_inputs_en_i : in std_logic_vector(g_width-1 downto 0);
fordebug_i : in std_logic_vector(5 downto 0);
----------------------------------------------------------------------
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;
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
---------------------------------------------------------------------------------------------------
\ No newline at end of file
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- top_tdc |
-- |
---------------------------------------------------------------------------------------------------
-- File top_tdc.vhd |
-- |
-- Description TDC top level |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 06/2012 |
-- Version v3 |
-- 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 gnum core integrated |
-- carrier 1 wire master added |
-- mezzanine I2C master added |
-- mezzanine 1 wire master added |
-- interrupts generator added |
-- changed generation of general_rst |
-- 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 |
-- |
----------------------------------------------/!\-------------------------------------------------|
-- 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;
library UNISIM;
use UNISIM.vcomponents.all;
--=================================================================================================
-- Entity declaration for top_tdc
--=================================================================================================
entity top_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
(-- Signals for the GNUM interface
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
-- Signals for the 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_p_i : in std_logic; -- 125 MHz differential clock: system clock
tdc_clk_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
-- Signals for the 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
-- 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 iFIFO1
ef2_i : in std_logic; -- empty flag iFIFO2
-- Signals for the Input Logic on TDC mezzanine
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
-- 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 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
-- Clock from the SPEC carrier
spec_clk_i : in std_logic ; -- 20 MHz clock from VCXO on SPEC
-- Signal for the 1-wire interface (DS18B20 thermometer + unique ID) on SPEC carrier
carrier_one_wire_b : inout std_logic;
-- Signals for the I2C EEPROM interface on TDC mezzanine
sys_scl_b : inout std_logic; -- Mezzanine system I2C clock (EEPROM)
sys_sda_b : inout std_logic; -- Mezzanine system I2C data (EEPROM)
-- Signal for the 1-wire interface (DS18B20 thermometer + unique ID) on TDC mezzanine
mezz_one_wire_b : inout 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)
spec_led_green_o : out std_logic; -- Green LED on SPEC front pannel, PLL status
spec_led_red_o : out std_logic; -- Red LED on SPEC front pannel
spec_aux0_i : in std_logic; -- Button on SPEC board
spec_aux1_i : in std_logic; -- Button on SPEC board
spec_aux2_o : out std_logic; -- Red LED on spec board
spec_aux3_o : out std_logic; -- Red LED on spec board
spec_aux4_o : out std_logic; -- Red LED on spec board
spec_aux5_o : out std_logic); -- Red LED on spec board
end top_tdc;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of top_tdc is
-- clocks and resets
signal clk, general_rst_n, general_rst, clk_125m : std_logic;
signal clk_20m_vcxo_buf, clk_20m_vcxo, acam_refclk_r_edge_p : std_logic;
-- DAC configuration
signal send_dac_word_p : std_logic;
signal dac_word : std_logic_vector(23 downto 0);
-- WISHBONE GNUM DMA
signal dma_stb, dma_cyc, dma_we, dma_ack, dma_stall : std_logic;
signal dma_sel : std_logic_vector(3 downto 0);
signal dma_adr, dma_dat_rd, dma_dat_wr : std_logic_vector(31 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);
-- WISHBONE addresses
signal dma_ctrl_wb_adr, tdc_core_wb_adr, gn_wb_adr : std_logic_vector(31 downto 0);
-- Interrupts
signal irq_to_gn4124 : std_logic;
signal irq_acam_err_p, irq_tstamp_p, irq_time_p : std_logic;
signal dma_irq : std_logic_vector(1 downto 0);
signal irq_sources : std_logic_vector(g_width-1 downto 0);
-- Carrier CSR info
signal gn4124_status : std_logic_vector(31 downto 0);
signal mezz_pll_status : std_logic_vector(11 downto 0);
-- Mezzanine 1-wire
signal mezz_owr_pwren, mezz_owr_en, mezz_owr_i : std_logic_vector(c_FMC_ONE_WIRE_NB - 1 downto 0);
-- Carrier 1-wire
signal carrier_owr_en, carrier_owr_i : std_logic_vector(c_FMC_ONE_WIRE_NB - 1 downto 0);
-- Mezzanine system I2C for EEPROM
signal sys_scl_in, sys_scl_out, sys_scl_oe_n : std_logic;
signal sys_sda_in, sys_sda_out, sys_sda_oe_n : std_logic;
-- <acam_status_i<31:0>> is never used.
-- <adr_i<7:4>> is never used.
-- <dat_i<31:28>> is never used.
-- <tstamp_wr_dat_i<127:0>> is never used.
-- <acam_tstamp1_i<30:30>> is never used.
-- <acam_tstamp1_i<28:28>> is never used.
-- <acam_tstamp2_i<31:31>> is never used.
-- <acam_tstamp2_i<29:29>> is never used.
-- <gnum_dma_adr_i<31:10>> is never used.
-- <wbm_adr_i<31:18> never used
-- gnum_csr_adr_i<31:8> is never used
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
svec_clk_ibuf : IBUFG
port map
(I => spec_clk_i,
O => clk_20m_vcxo_buf);
---------------------------------------------------------------------------------------------------
-- CSR WISHBONE CROSSBAR --
---------------------------------------------------------------------------------------------------
-- CSR wishbone address decoder
-- 0x04000 -> DMA configuration
-- 0x04800 -> Carrier 1-wire master (Unidue ID & Thermometer)
-- 0x04C00 -> Carrier CSR information
-- 0x05000 -> TDC core & ACAM
-- 0x05400 -> Interrupt controller
-- 0x05800 -> Mezzanine I2C master (EEPROM)
-- 0x05C00 -> Mezzanine 1-wire master (Unidue ID & Thermometer)
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_125m,
rst_n_i => rst_n_a_i,
slave_i => cnx_slave_in,
slave_o => cnx_slave_out,
master_i => cnx_master_in,
master_o => cnx_master_out);
---------------------------------------------------------------------------------------------------
-- GNUM CORE --
---------------------------------------------------------------------------------------------------
gnum_interface_block: 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 => dma_irq,
irq_p_i => irq_to_gn4124,
irq_p_o => irq_p_o,
-- CSR WISHBONE interface (master pipelined)
csr_clk_i => clk_125m,
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 WISHBONE interface (pipelined)
dma_clk_i => clk_125m,
dma_adr_o => dma_adr,
dma_cyc_o => dma_cyc,
dma_dat_o => dma_dat_wr,
dma_sel_o => dma_sel,
dma_stb_o => dma_stb,
dma_we_o => dma_we,
dma_ack_i => dma_ack,
dma_dat_i => dma_dat_rd,
dma_stall_i => dma_stall,
-- DMA registers WISHBONE interface (slave classic)
dma_reg_clk_i => clk_125m,
dma_reg_adr_i => dma_ctrl_wb_adr,
dma_reg_dat_i => cnx_master_out(c_SLAVE_DMA).dat,
dma_reg_sel_i => cnx_master_out(c_SLAVE_DMA).sel,
dma_reg_stb_i => cnx_master_out(c_SLAVE_DMA).stb,
dma_reg_we_i => cnx_master_out(c_SLAVE_DMA).we,
dma_reg_cyc_i => cnx_master_out(c_SLAVE_DMA).cyc,
dma_reg_dat_o => cnx_master_in(c_SLAVE_DMA).dat,
dma_reg_ack_o => cnx_master_in(c_SLAVE_DMA).ack,
dma_reg_stall_o => cnx_master_in(c_SLAVE_DMA).stall);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Convert 32-bit word address into byte address for crossbar
cnx_slave_in(c_MASTER_GENNUM).adr <= gn_wb_adr(29 downto 0) & "00";
-- Convert 32-bit byte address into word address for DMA controller
dma_ctrl_wb_adr <= "00" & cnx_master_out(c_SLAVE_DMA).adr(31 downto 2);
-- Unused wishbone signals
cnx_master_in(c_SLAVE_DMA).err <= '0';
cnx_master_in(c_SLAVE_DMA).rty <= '0';
cnx_master_in(c_SLAVE_DMA).int <= '0';
---------------------------------------------------------------------------------------------------
-- TDC 125MHz clk --
---------------------------------------------------------------------------------------------------
cmp_tdc1_clks_rsts_mgment : clks_rsts_manager
generic map
(nb_of_reg => 68)
port map
(clk_20m_vcxo_i => clk_20m_vcxo_buf,
acam_refclk_p_i => acam_refclk_p_i,
acam_refclk_n_i => acam_refclk_n_i,
tdc_125m_clk_p_i => tdc_clk_p_i,
tdc_125m_clk_n_i => tdc_clk_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,
internal_rst_o => general_rst,
pll_cs_n_o => pll_cs_o,
pll_dac_sync_n_o => pll_dac_sync_o,
pll_sdi_o => pll_sdi_o,
pll_sclk_o => pll_sclk_o,
tdc_125m_clk_o => clk_125m,
pll_status_o => open);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
general_rst_n <= not general_rst;
---------------------------------------------------------------------------------------------------
-- TDC CORE --
---------------------------------------------------------------------------------------------------
tdc_core: fmc_tdc_core
generic map
(g_span => g_span,
g_width => g_width,
values_for_simul => FALSE)
port map
(-- clk, rst
clk_125m_i => clk_125m,
rst_i => general_rst,
acam_refclk_r_edge_p_i => acam_refclk_r_edge_p,
-- DAC configuration
send_dac_word_p_o => send_dac_word_p,
dac_word_o => dac_word,
-- 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)
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,
-- WISHBONE CSR for TDC core and ACAM configuration
tdc_config_wb_adr_i => tdc_core_wb_adr,
tdc_config_wb_dat_i => cnx_master_out(c_SLAVE_TDC_CORE).dat,
tdc_config_wb_stb_i => cnx_master_out(c_SLAVE_TDC_CORE).stb,
tdc_config_wb_we_i => cnx_master_out(c_SLAVE_TDC_CORE).we,
tdc_config_wb_cyc_i => cnx_master_out(c_SLAVE_TDC_CORE).cyc,
tdc_config_wb_dat_o => cnx_master_in(c_SLAVE_TDC_CORE).dat,
tdc_config_wb_ack_o => cnx_master_in(c_SLAVE_TDC_CORE).ack,
-- WISHBONE DMA for timestamps transfer
tdc_mem_wb_adr_i => dma_adr,
tdc_mem_wb_dat_i => dma_dat_wr,
tdc_mem_wb_stb_i => dma_stb,
tdc_mem_wb_we_i => dma_we,
tdc_mem_wb_cyc_i => dma_cyc,
tdc_mem_wb_ack_o => dma_ack,
tdc_mem_wb_dat_o => dma_dat_rd,
tdc_mem_wb_stall_o => dma_stall);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Convert byte address into word address
tdc_core_wb_adr <= "00" & cnx_master_out(c_SLAVE_TDC_CORE).adr(31 downto 2);
-- Unused wishbone signals
cnx_master_in(c_SLAVE_TDC_CORE).err <= '0';
cnx_master_in(c_SLAVE_TDC_CORE).rty <= '0';
cnx_master_in(c_SLAVE_TDC_CORE).stall <= '0';
cnx_master_in(c_SLAVE_TDC_CORE).int <= '0';
---------------------------------------------------------------------------------------------------
-- INTERRUPTS CONTROLLER --
---------------------------------------------------------------------------------------------------
-- IRQ sources
-- 0 -> end of DMA transfer
-- 1 -> DMA transfer error
-- 2 -> number of timestamps reached threshold
-- 3 -> number of seconds passed reached threshold
-- 4 -> ACAM error
-- 5-31 -> unused
cmp_irq_controller : irq_controller
port map
(clk_i => clk_125m,
rst_n_i => general_rst_n,
irq_src_p_i => irq_sources,
irq_p_o => irq_to_gn4124,
wb_adr_i => cnx_master_out(c_SLAVE_INT).adr(3 downto 2),
wb_dat_i => cnx_master_out(c_SLAVE_INT).dat,
wb_dat_o => cnx_master_in(c_SLAVE_INT).dat,
wb_cyc_i => cnx_master_out(c_SLAVE_INT).cyc,
wb_sel_i => cnx_master_out(c_SLAVE_INT).sel,
wb_stb_i => cnx_master_out(c_SLAVE_INT).stb,
wb_we_i => cnx_master_out(c_SLAVE_INT).we,
wb_ack_o => cnx_master_in(c_SLAVE_INT).ack);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
irq_sources(1 downto 0) <= dma_irq;
irq_sources(2) <= irq_tstamp_p;
irq_sources(3) <= irq_time_p;
irq_sources(4) <= irq_acam_err_p;
irq_sources(31 downto 5) <= (others => '0');
irq_aux_p_o <= irq_to_gn4124;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Unused wishbone signals
cnx_master_in(c_SLAVE_INT).err <= '0';
cnx_master_in(c_SLAVE_INT).rty <= '0';
cnx_master_in(c_SLAVE_INT).stall <= '0';
cnx_master_in(c_SLAVE_INT).int <= '0';
---------------------------------------------------------------------------------------------------
-- 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_125m,
rst_n_i => general_rst_n,
slave_i => cnx_master_out(c_SLAVE_SPEC_ONEWIRE),
slave_o => cnx_master_in(c_SLAVE_SPEC_ONEWIRE),
desc_o => open,
owr_pwren_o => open,
owr_en_o => carrier_owr_en,
owr_i => carrier_owr_i);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
carrier_one_wire_b <= '0' when carrier_owr_en(0) = '1' else 'Z';
carrier_owr_i(0) <= carrier_one_wire_b;
---------------------------------------------------------------------------------------------------
-- Mezzanine I2C Master EEPROM --
---------------------------------------------------------------------------------------------------
mezzanine_I2C_master_EEPROM : xwb_i2c_master
generic map
(g_interface_mode => CLASSIC,
g_address_granularity => BYTE)
port map
(clk_sys_i => clk_125m,
rst_n_i => general_rst_n,
slave_i => cnx_master_out(c_SLAVE_FMC_SYS_I2C),
slave_o => cnx_master_in(c_SLAVE_FMC_SYS_I2C),
desc_o => open,
scl_pad_i => sys_scl_in,
scl_pad_o => sys_scl_out,
scl_padoen_o => sys_scl_oe_n,
sda_pad_i => sys_sda_in,
sda_pad_o => sys_sda_out,
sda_padoen_o => sys_sda_oe_n);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Tri-state buffer for SDA and SCL
sys_scl_b <= sys_scl_out when sys_scl_oe_n = '0' else 'Z';
sys_scl_in <= sys_scl_b;
sys_sda_b <= sys_sda_out when sys_sda_oe_n = '0' else 'Z';
sys_sda_in <= sys_sda_b;
---------------------------------------------------------------------------------------------------
-- Mezzanine 1-wire MASTER DS18B20 (thermometer + unique ID) --
---------------------------------------------------------------------------------------------------
cmp_fmc_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_125m,
rst_n_i => general_rst_n,
slave_i => cnx_master_out(c_SLAVE_FMC_ONEWIRE),
slave_o => cnx_master_in(c_SLAVE_FMC_ONEWIRE),
desc_o => open,
owr_pwren_o => mezz_owr_pwren,
owr_en_o => mezz_owr_en,
owr_i => mezz_owr_i);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
mezz_one_wire_b <= '0' when mezz_owr_en(0) = '1' else 'Z';
mezz_owr_i(0) <= mezz_one_wire_b;
---------------------------------------------------------------------------------------------------
-- Carrier CSR information --
---------------------------------------------------------------------------------------------------
-- Information on carrier type, mezzanine presence, pcb version
cmp_carrier_csr : carrier_csr
port map
(rst_n_i => general_rst_n,
wb_clk_i => clk_125m,
wb_addr_i => cnx_master_out(c_SLAVE_SPEC_CSR).adr(3 downto 2),
wb_data_i => cnx_master_out(c_SLAVE_SPEC_CSR).dat,
wb_data_o => cnx_master_in(c_SLAVE_SPEC_CSR).dat,
wb_cyc_i => cnx_master_out(c_SLAVE_SPEC_CSR).cyc,
wb_sel_i => cnx_master_out(c_SLAVE_SPEC_CSR).sel,
wb_stb_i => cnx_master_out(c_SLAVE_SPEC_CSR).stb,
wb_we_i => cnx_master_out(c_SLAVE_SPEC_CSR).we,
wb_ack_o => cnx_master_in(c_SLAVE_SPEC_CSR).ack,
carrier_csr_carrier_pcb_rev_i => pcb_ver_i,
carrier_csr_carrier_reserved_i => mezz_pll_status,
carrier_csr_carrier_type_i => c_CARRIER_TYPE,
carrier_csr_stat_fmc_pres_i => prsnt_m2c_n_i,
carrier_csr_stat_p2l_pll_lck_i => gn4124_status(0),
carrier_csr_stat_sys_pll_lck_i => '0',--open,
carrier_csr_stat_ddr3_cal_done_i => '0',
carrier_csr_stat_reserved_i => (others => '0'),
carrier_csr_ctrl_led_green_o => open,
carrier_csr_ctrl_led_red_o => open,
carrier_csr_ctrl_dac_clr_n_o => open,
carrier_csr_ctrl_reserved_o => open);
mezz_pll_status <= "00000000000" & pll_status_i;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Unused wishbone signals
cnx_master_in(c_SLAVE_SPEC_CSR).err <= '0';
cnx_master_in(c_SLAVE_SPEC_CSR).rty <= '0';
cnx_master_in(c_SLAVE_SPEC_CSR).stall <= '0';
cnx_master_in(c_SLAVE_SPEC_CSR).int <= '0';
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
\ No newline at end of file
--------------------------------------------------------------------------------
-- CERN (BE-CO-HT)
-- IRQ controller
-- http://www.ohwr.org/projects/fmc-adc-100m14b4cha
--------------------------------------------------------------------------------
--
-- unit name: irq_controller (irq_controller.vhd)
--
-- author: Matthieu Cattin (matthieu.cattin@cern.ch)
--
-- date: 18-11-2011
--
-- version: 1.0
--
-- description:
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- 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
--------------------------------------------------------------------------------
-- last changes: see svn log.
--------------------------------------------------------------------------------
-- TODO: -
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
--library UNISIM;
--use UNISIM.vcomponents.all;
entity irq_controller is
port (
-- Clock, reset
clk_i : in std_logic;
rst_n_i : in std_logic;
-- Interrupt sources input, must be 1 clk_i tick long
irq_src_p_i : in std_logic_vector(31 downto 0);
-- IRQ pulse output
irq_p_o : out std_logic;
-- Wishbone interface
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
);
end irq_controller;
architecture rtl of irq_controller is
------------------------------------------------------------------------------
-- Components declaration
------------------------------------------------------------------------------
component irq_controller_regs
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(1 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_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;
irq_ctrl_multi_irq_o : out std_logic_vector(31 downto 0);
irq_ctrl_multi_irq_i : in std_logic_vector(31 downto 0);
irq_ctrl_multi_irq_load_o : out std_logic;
irq_ctrl_src_o : out std_logic_vector(31 downto 0);
irq_ctrl_src_i : in std_logic_vector(31 downto 0);
irq_ctrl_src_load_o : out std_logic;
irq_ctrl_en_mask_o : out std_logic_vector(31 downto 0)
);
end component irq_controller_regs;
------------------------------------------------------------------------------
-- Signals declaration
------------------------------------------------------------------------------
signal irq_en_mask : std_logic_vector(31 downto 0);
signal irq_pending : std_logic_vector(31 downto 0);
signal irq_pending_d : std_logic_vector(31 downto 0);
signal irq_pending_re : std_logic_vector(31 downto 0);
signal irq_src_rst : std_logic_vector(31 downto 0);
signal irq_src_rst_en : std_logic;
signal multi_irq : std_logic_vector(31 downto 0);
signal multi_irq_rst : std_logic_vector(31 downto 0);
signal multi_irq_rst_en : std_logic;
signal irq_p_or : std_logic_vector(32 downto 0);
begin
------------------------------------------------------------------------------
-- Wishbone interface to IRQ controller registers
------------------------------------------------------------------------------
cmp_irq_controller_regs : irq_controller_regs
port map(
rst_n_i => rst_n_i,
wb_clk_i => clk_i,
wb_addr_i => wb_adr_i,
wb_data_i => wb_dat_i,
wb_data_o => wb_dat_o,
wb_cyc_i => wb_cyc_i,
wb_sel_i => wb_sel_i,
wb_stb_i => wb_stb_i,
wb_we_i => wb_we_i,
wb_ack_o => wb_ack_o,
irq_ctrl_multi_irq_o => multi_irq_rst,
irq_ctrl_multi_irq_load_o => multi_irq_rst_en,
irq_ctrl_multi_irq_i => multi_irq,
irq_ctrl_src_o => irq_src_rst,
irq_ctrl_src_i => irq_pending,
irq_ctrl_src_load_o => irq_src_rst_en,
irq_ctrl_en_mask_o => irq_en_mask
);
------------------------------------------------------------------------------
-- Register interrupt sources
-- IRQ is pending until a '1' is written to the corresponding bit
------------------------------------------------------------------------------
p_irq_src : process (clk_i)
begin
if rising_edge(clk_i) then
for I in 0 to irq_pending'length-1 loop
if rst_n_i = '0' then
irq_pending(I) <= '0';
elsif irq_src_p_i(I) = '1' then
irq_pending(I) <= '1';
elsif irq_src_rst_en = '1' and irq_src_rst(I) = '1' then
irq_pending(I) <= '0';
end if;
end loop; -- I
end if;
end process p_irq_src;
------------------------------------------------------------------------------
-- Multiple interrupt detection
-- Rise a flag if an interrupt occurs while an irq is still pending
-- Write '1' to the flag to clear it
------------------------------------------------------------------------------
p_multi_irq_detect : process (clk_i)
begin
if rising_edge(clk_i) then
for I in 0 to multi_irq'length-1 loop
if rst_n_i = '0' then
multi_irq(I) <= '0';
elsif irq_src_p_i(I) = '1' and irq_pending(I) = '1' then
multi_irq(I) <= '1';
elsif multi_irq_rst_en = '1' and multi_irq_rst(I) = '1' then
multi_irq(I) <= '0';
end if;
end loop; -- I
end if;
end process p_multi_irq_detect;
------------------------------------------------------------------------------
-- Generate IRQ output pulse
------------------------------------------------------------------------------
irq_p_or(0) <= '0';
l_irq_out_pulse : for I in 0 to irq_src_p_i'length-1 generate
irq_p_or(I+1) <= irq_p_or(I) or (irq_src_p_i(I) and irq_en_mask(I));
end generate l_irq_out_pulse;
p_irq_out_pulse : process (clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
irq_p_o <= '0';
else
irq_p_o <= irq_p_or(32);
end if;
end if;
end process p_irq_out_pulse;
end rtl;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for IRQ controller registers
---------------------------------------------------------------------------------------
-- File : ../rtl/irq_controller_regs.vhd
-- Author : auto-generated by wbgen2 from irq_controller_regs.wb
-- Created : Wed Jan 18 09:43:55 2012
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE irq_controller_regs.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity irq_controller_regs is
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(1 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_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;
-- Port for std_logic_vector field: 'Multiple interrupt' in reg: 'Multiple interrupt register'
irq_ctrl_multi_irq_o : out std_logic_vector(31 downto 0);
irq_ctrl_multi_irq_i : in std_logic_vector(31 downto 0);
irq_ctrl_multi_irq_load_o : out std_logic;
-- Port for std_logic_vector field: 'Interrupt sources' in reg: 'Interrupt sources register '
irq_ctrl_src_o : out std_logic_vector(31 downto 0);
irq_ctrl_src_i : in std_logic_vector(31 downto 0);
irq_ctrl_src_load_o : out std_logic;
-- Port for std_logic_vector field: 'Interrupt enable mask' in reg: 'Interrupt enable mask register'
irq_ctrl_en_mask_o : out std_logic_vector(31 downto 0)
);
end irq_controller_regs;
architecture syn of irq_controller_regs is
signal irq_ctrl_en_mask_int : std_logic_vector(31 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 bus_clock_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_data_i;
bwsel_reg <= wb_sel_i;
bus_clock_int <= wb_clk_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 (bus_clock_int, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
irq_ctrl_multi_irq_load_o <= '0';
irq_ctrl_src_load_o <= '0';
irq_ctrl_en_mask_int <= "00000000000000000000000000000000";
elsif rising_edge(bus_clock_int) 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
irq_ctrl_multi_irq_load_o <= '0';
irq_ctrl_src_load_o <= '0';
ack_in_progress <= '0';
else
irq_ctrl_multi_irq_load_o <= '0';
irq_ctrl_src_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
irq_ctrl_multi_irq_load_o <= '1';
else
rddata_reg(31 downto 0) <= irq_ctrl_multi_irq_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "01" =>
if (wb_we_i = '1') then
irq_ctrl_src_load_o <= '1';
else
rddata_reg(31 downto 0) <= irq_ctrl_src_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (wb_we_i = '1') then
irq_ctrl_en_mask_int <= wrdata_reg(31 downto 0);
else
rddata_reg(31 downto 0) <= irq_ctrl_en_mask_int;
end if;
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_data_o <= rddata_reg;
-- Multiple interrupt
irq_ctrl_multi_irq_o <= wrdata_reg(31 downto 0);
-- Interrupt sources
irq_ctrl_src_o <= wrdata_reg(31 downto 0);
-- Interrupt enable mask
irq_ctrl_en_mask_o <= irq_ctrl_en_mask_int;
rwaddr_reg <= wb_addr_i;
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Carrier control and status registers
---------------------------------------------------------------------------------------
-- File : ../rtl/carrier_csr.vhd
-- Author : auto-generated by wbgen2 from carrier_csr.wb
-- Created : Mon Mar 11 17:11:09 2013
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE carrier_csr.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_csr is
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(1 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_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;
-- Port for std_logic_vector field: 'PCB revision' in reg: 'Carrier type and PCB version'
carrier_csr_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_csr_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_csr_carrier_type_i : in std_logic_vector(15 downto 0);
-- Port for BIT field: 'FMC presence' in reg: 'Status'
carrier_csr_stat_fmc_pres_i : in std_logic;
-- Port for BIT field: 'GN4142 core P2L PLL status' in reg: 'Status'
carrier_csr_stat_p2l_pll_lck_i : in std_logic;
-- Port for BIT field: 'System clock PLL status' in reg: 'Status'
carrier_csr_stat_sys_pll_lck_i : in std_logic;
-- Port for BIT field: 'DDR3 calibration status' in reg: 'Status'
carrier_csr_stat_ddr3_cal_done_i : in std_logic;
-- Port for std_logic_vector field: 'Reserved' in reg: 'Status'
carrier_csr_stat_reserved_i : in std_logic_vector(27 downto 0);
-- Port for BIT field: 'Green LED' in reg: 'Control'
carrier_csr_ctrl_led_green_o : out std_logic;
-- Port for BIT field: 'Red LED' in reg: 'Control'
carrier_csr_ctrl_led_red_o : out std_logic;
-- Port for BIT field: 'DAC clear' in reg: 'Control'
carrier_csr_ctrl_dac_clr_n_o : out std_logic;
-- Port for std_logic_vector field: 'Reserved' in reg: 'Control'
carrier_csr_ctrl_reserved_o : out std_logic_vector(28 downto 0)
);
end carrier_csr;
architecture syn of carrier_csr is
signal carrier_csr_ctrl_led_green_int : std_logic ;
signal carrier_csr_ctrl_led_red_int : std_logic ;
signal carrier_csr_ctrl_dac_clr_n_int : std_logic ;
signal carrier_csr_ctrl_reserved_int : std_logic_vector(28 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 bus_clock_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_data_i;
bwsel_reg <= wb_sel_i;
bus_clock_int <= wb_clk_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 (bus_clock_int, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
carrier_csr_ctrl_led_green_int <= '0';
carrier_csr_ctrl_led_red_int <= '0';
carrier_csr_ctrl_dac_clr_n_int <= '0';
carrier_csr_ctrl_reserved_int <= "00000000000000000000000000000";
elsif rising_edge(bus_clock_int) 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(1 downto 0) is
when "00" =>
if (wb_we_i = '1') then
else
rddata_reg(3 downto 0) <= carrier_csr_carrier_pcb_rev_i;
rddata_reg(15 downto 4) <= carrier_csr_carrier_reserved_i;
rddata_reg(31 downto 16) <= carrier_csr_carrier_type_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "01" =>
if (wb_we_i = '1') then
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
else
rddata_reg(0) <= carrier_csr_stat_fmc_pres_i;
rddata_reg(1) <= carrier_csr_stat_p2l_pll_lck_i;
rddata_reg(2) <= carrier_csr_stat_sys_pll_lck_i;
rddata_reg(3) <= carrier_csr_stat_ddr3_cal_done_i;
rddata_reg(31 downto 4) <= carrier_csr_stat_reserved_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (wb_we_i = '1') then
rddata_reg(0) <= 'X';
carrier_csr_ctrl_led_green_int <= wrdata_reg(0);
rddata_reg(1) <= 'X';
carrier_csr_ctrl_led_red_int <= wrdata_reg(1);
rddata_reg(2) <= 'X';
carrier_csr_ctrl_dac_clr_n_int <= wrdata_reg(2);
carrier_csr_ctrl_reserved_int <= wrdata_reg(31 downto 3);
else
rddata_reg(0) <= carrier_csr_ctrl_led_green_int;
rddata_reg(1) <= carrier_csr_ctrl_led_red_int;
rddata_reg(2) <= carrier_csr_ctrl_dac_clr_n_int;
rddata_reg(31 downto 3) <= carrier_csr_ctrl_reserved_int;
end if;
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_data_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_csr_ctrl_led_green_o <= carrier_csr_ctrl_led_green_int;
-- Red LED
carrier_csr_ctrl_led_red_o <= carrier_csr_ctrl_led_red_int;
-- DAC clear
carrier_csr_ctrl_dac_clr_n_o <= carrier_csr_ctrl_dac_clr_n_int;
-- Reserved
carrier_csr_ctrl_reserved_o <= carrier_csr_ctrl_reserved_int;
rwaddr_reg <= wb_addr_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 |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- 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 => "svec_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 => "SynpliDP",
-- Synthesis tool version (bcd encoded, 32-bit)
syn_tool_version => x"00201206",
-- Synthesis date (bcd encoded, 32-bit)
syn_date => x"20130629",
-- 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"47c786a2", -- echo "spec_fmc-adc-100m14b4cha" | md5sum | cut -c1-8
version => x"00010001", -- bcd encoded, [31:16] = major, [15:0] = minor
date => x"20130629", -- yyyymmdd
name => "spec_fmctdc1ns5cha "));
end sdb_meta_pkg;
package body sdb_meta_pkg is
end sdb_meta_pkg;
\ No newline at end of file
#
# Clocks
#
NET "clk_62m5_sys" TNM_NET = "clk_62m5_sys";
NET "clk_20m_vcxo_i" TNM_NET = "clk_20m_vcxo_i";
NET "tdc1_clk_125m" TNM_NET = "tdc1_clk_125m";
NET "tdc2_clk_125m" TNM_NET = "tdc2_clk_125m";
TIMESPEC ts_ignore_xclock1 = FROM "clk_62m5_sys" TO "tdc1_clk_125m" 20ns DATAPATHONLY;
TIMESPEC ts_ignore_xclock2 = FROM "tdc1_clk_125m" TO "clk_62m5_sys" 20ns DATAPATHONLY;
TIMESPEC ts_ignore_xclock3 = FROM "clk_62m5_sys" TO "tdc1_clk_125m" 20ns DATAPATHONLY;
TIMESPEC ts_ignore_xclock4 = FROM "tdc1_clk_125m" TO "clk_62m5_sys" 20ns DATAPATHONLY;
TIMESPEC ts_ignore_xclock4 = FROM "clk_20m_vcxo_i" TO "clk_62m5_sys" 200ns DATAPATHONLY;
TIMESPEC ts_ignore_xclock4 = FROM "clk_62m5_sys" TO "clk_20m_vcxo_i" 200ns DATAPATHONLY;
# SVEC clock/reset
NET "clk_20m_vcxo_i" LOC = V26;
NET "por_n_i" LOC = AD28;
NET "clk_20m_vcxo_i" IOSTANDARD="LVCMOS33";
NET "por_n_i" IOSTANDARD="LVCMOS33";
# mezzanine detection / i2c
NET "tdc1_prsntm2c_n_i" LOC = N30;
NET "tdc1_scl_b" LOC = P28;
NET "tdc1_sda_b" LOC = P30;
NET "tdc2_prsntm2c_n_i" LOC = AE29;
NET "tdc2_scl_b" LOC = W29;
NET "tdc2_sda_b" LOC = V30;
NET "tdc2_prsntm2c_n_i" IOSTANDARD = "LVCMOS33";
NET "tdc2_scl_b" IOSTANDARD = "LVCMOS33";
NET "tdc2_sda_b" IOSTANDARD = "LVCMOS33";
NET "tdc1_prsntm2c_n_i" IOSTANDARD = "LVCMOS33";
NET "tdc1_scl_b" IOSTANDARD = "LVCMOS33";
NET "tdc1_sda_b" IOSTANDARD = "LVCMOS33";
NET "carrier_one_wire_b" LOC = AC30;
NET "carrier_one_wire_b" IOSTANDARD = "LVCMOS33";
NET "pcb_ver_i[0]" LOC = AD20;
NET "pcb_ver_i[1]" LOC = AE20;
NET "pcb_ver_i[2]" LOC = AD18;
NET "pcb_ver_i[3]" LOC = AE17;
NET "pcb_ver_i[0]" IOSTANDARD="LVCMOS33";
NET "pcb_ver_i[1]" IOSTANDARD="LVCMOS33";
NET "pcb_ver_i[2]" IOSTANDARD="LVCMOS33";
NET "pcb_ver_i[3]" IOSTANDARD="LVCMOS33";
NET "fp_led_line_oen_o[0]" LOC = AD26;
NET "fp_led_line_oen_o[0]" IOSTANDARD="LVCMOS33";
NET "fp_led_line_oen_o[1]" LOC = AD27;
NET "fp_led_line_oen_o[1]" IOSTANDARD="LVCMOS33";
NET "fp_led_line_o[0]" LOC = AC27;
NET "fp_led_line_o[0]" IOSTANDARD="LVCMOS33";
NET "fp_led_line_o[1]" LOC = AC28;
NET "fp_led_line_o[1]" IOSTANDARD="LVCMOS33";
NET "fp_led_column_o[0]" LOC = AE30;
NET "fp_led_column_o[0]" IOSTANDARD="LVCMOS33";
NET "fp_led_column_o[1]" LOC = AE27;
NET "fp_led_column_o[1]" IOSTANDARD="LVCMOS33";
NET "fp_led_column_o[2]" LOC = AE28;
NET "fp_led_column_o[2]" IOSTANDARD="LVCMOS33";
NET "fp_led_column_o[3]" LOC = AF28;
NET "fp_led_column_o[3]" IOSTANDARD="LVCMOS33";
NET "vme_write_n_i" LOC = R1;
NET "vme_rst_n_i" LOC = P4;
#NET "vme_sysclk_i" LOC = P3;
NET "vme_retry_oe_o" LOC = R4;
NET "vme_retry_n_o" LOC = AB2;
NET "vme_lword_n_b" LOC = M7;
NET "vme_iackout_n_o" LOC = N3;
NET "vme_iackin_n_i" LOC = P7;
NET "vme_iack_n_i" LOC = N1;
NET "vme_ga_i[5]" LOC = M6;
NET "vme_dtack_oe_o" LOC = T1;
NET "vme_dtack_n_o" LOC = R5;
NET "vme_ds_n_i[1]" LOC = Y7;
NET "vme_ds_n_i[0]" LOC = Y6;
NET "vme_data_oe_n_o" LOC = P1;
NET "vme_data_dir_o" LOC = P2;
NET "vme_berr_o" LOC = R3;
NET "vme_as_n_i" LOC = P6;
NET "vme_addr_oe_n_o" LOC = N4;
NET "vme_addr_dir_o" LOC = N5;
NET "vme_irq_n_o[6]" LOC = R7;
NET "vme_irq_n_o[5]" LOC = AH2;
NET "vme_irq_n_o[4]" LOC = AF2;
NET "vme_irq_n_o[3]" LOC = N9;
NET "vme_irq_n_o[2]" LOC = N10;
NET "vme_irq_n_o[1]" LOC = AH4;
NET "vme_irq_n_o[0]" LOC = AG4;
NET "vme_ga_i[4]" LOC = V9;
NET "vme_ga_i[3]" LOC = V10;
NET "vme_ga_i[2]" LOC = AJ1;
NET "vme_ga_i[1]" LOC = AH1;
NET "vme_ga_i[0]" LOC = V7;
NET "vme_data_b[31]" LOC = AK3;
NET "vme_data_b[30]" LOC = AH3;
NET "vme_data_b[29]" LOC = T8;
NET "vme_data_b[28]" LOC = T9;
NET "vme_data_b[27]" LOC = AK4;
NET "vme_data_b[26]" LOC = AJ4;
NET "vme_data_b[25]" LOC = W6;
NET "vme_data_b[24]" LOC = W7;
NET "vme_data_b[23]" LOC = AB6;
NET "vme_data_b[22]" LOC = AB7;
NET "vme_data_b[21]" LOC = W9;
NET "vme_data_b[20]" LOC = W10;
NET "vme_data_b[19]" LOC = AK5;
NET "vme_data_b[18]" LOC = AH5;
NET "vme_data_b[17]" LOC = AD6;
NET "vme_data_b[16]" LOC = AC6;
NET "vme_data_b[15]" LOC = AA6;
NET "vme_data_b[14]" LOC = AA7;
NET "vme_data_b[13]" LOC = T6;
NET "vme_data_b[12]" LOC = T7;
NET "vme_data_b[11]" LOC = AG5;
NET "vme_data_b[10]" LOC = AE5;
NET "vme_data_b[9]" LOC = Y11;
NET "vme_data_b[8]" LOC = W11;
NET "vme_data_b[7]" LOC = AF6;
NET "vme_data_b[6]" LOC = AE6;
NET "vme_data_b[5]" LOC = Y8;
NET "vme_data_b[4]" LOC = Y9;
NET "vme_data_b[3]" LOC = AE7;
NET "vme_data_b[2]" LOC = AD7;
NET "vme_data_b[1]" LOC = AA9;
NET "vme_data_b[0]" LOC = AA10;
NET "vme_am_i[5]" LOC = V8;
NET "vme_am_i[4]" LOC = AG3;
NET "vme_am_i[3]" LOC = AF3;
NET "vme_am_i[2]" LOC = AF4;
NET "vme_am_i[1]" LOC = AE4;
NET "vme_am_i[0]" LOC = AK2;
NET "vme_addr_b[31]" LOC = T2;
NET "vme_addr_b[30]" LOC = T3;
NET "vme_addr_b[29]" LOC = T4;
NET "vme_addr_b[28]" LOC = U1;
NET "vme_addr_b[27]" LOC = U3;
NET "vme_addr_b[26]" LOC = U4;
NET "vme_addr_b[25]" LOC = U5;
NET "vme_addr_b[24]" LOC = V1;
NET "vme_addr_b[23]" LOC = V2;
NET "vme_addr_b[22]" LOC = W1;
NET "vme_addr_b[21]" LOC = W3;
NET "vme_addr_b[20]" LOC = AA4;
NET "vme_addr_b[19]" LOC = AA5;
NET "vme_addr_b[18]" LOC = Y1;
NET "vme_addr_b[17]" LOC = Y2;
NET "vme_addr_b[16]" LOC = Y3;
NET "vme_addr_b[15]" LOC = Y4;
NET "vme_addr_b[14]" LOC = AC1;
NET "vme_addr_b[13]" LOC = AC3;
NET "vme_addr_b[12]" LOC = AD1;
NET "vme_addr_b[11]" LOC = AD2;
NET "vme_addr_b[10]" LOC = AB3;
NET "vme_addr_b[9]" LOC = AB4;
NET "vme_addr_b[8]" LOC = AD3;
NET "vme_addr_b[7]" LOC = AD4;
NET "vme_addr_b[6]" LOC = AC4;
NET "vme_addr_b[5]" LOC = AC5;
NET "vme_addr_b[4]" LOC = N7;
NET "vme_addr_b[3]" LOC = N8;
NET "vme_addr_b[2]" LOC = AE1;
NET "vme_addr_b[1]" LOC = AE3;
NET "vme_write_n_i" IOSTANDARD = "LVCMOS33";
NET "vme_rst_n_i" IOSTANDARD = "LVCMOS33";
#NET "vme_sysclk_i" IOSTANDARD = "LVCMOS33";
NET "vme_retry_oe_o" IOSTANDARD = "LVCMOS33";
NET "vme_retry_n_o" IOSTANDARD = "LVCMOS33";
NET "vme_lword_n_b" IOSTANDARD = "LVCMOS33";
NET "vme_iackout_n_o" IOSTANDARD = "LVCMOS33";
NET "vme_iackin_n_i" IOSTANDARD = "LVCMOS33";
NET "vme_iack_n_i" IOSTANDARD = "LVCMOS33";
NET "vme_ga_i[5]" IOSTANDARD = "LVCMOS33";
NET "vme_dtack_oe_o" IOSTANDARD = "LVCMOS33";
NET "vme_dtack_n_o" IOSTANDARD = "LVCMOS33";
NET "vme_ds_n_i[1]" IOSTANDARD = "LVCMOS33";
NET "vme_ds_n_i[0]" IOSTANDARD = "LVCMOS33";
NET "vme_data_oe_n_o" IOSTANDARD = "LVCMOS33";
NET "vme_data_dir_o" IOSTANDARD = "LVCMOS33";
NET "vme_berr_o" IOSTANDARD = "LVCMOS33";
NET "vme_as_n_i" IOSTANDARD = "LVCMOS33";
NET "vme_addr_oe_n_o" IOSTANDARD = "LVCMOS33";
NET "vme_addr_dir_o" IOSTANDARD = "LVCMOS33";
NET "vme_irq_n_o[6]" IOSTANDARD = "LVCMOS33";
NET "vme_irq_n_o[5]" IOSTANDARD = "LVCMOS33";
NET "vme_irq_n_o[4]" IOSTANDARD = "LVCMOS33";
NET "vme_irq_n_o[3]" IOSTANDARD = "LVCMOS33";
NET "vme_irq_n_o[2]" IOSTANDARD = "LVCMOS33";
NET "vme_irq_n_o[1]" IOSTANDARD = "LVCMOS33";
NET "vme_irq_n_o[0]" IOSTANDARD = "LVCMOS33";
NET "vme_ga_i[4]" IOSTANDARD = "LVCMOS33";
NET "vme_ga_i[3]" IOSTANDARD = "LVCMOS33";
NET "vme_ga_i[2]" IOSTANDARD = "LVCMOS33";
NET "vme_ga_i[1]" IOSTANDARD = "LVCMOS33";
NET "vme_ga_i[0]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[31]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[30]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[29]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[28]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[27]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[26]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[25]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[24]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[23]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[22]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[21]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[20]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[19]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[18]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[17]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[16]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[15]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[14]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[13]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[12]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[11]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[10]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[9]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[8]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[7]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[6]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[5]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[4]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[3]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[2]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[1]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[0]" IOSTANDARD = "LVCMOS33";
NET "vme_am_i[5]" IOSTANDARD = "LVCMOS33";
NET "vme_am_i[4]" IOSTANDARD = "LVCMOS33";
NET "vme_am_i[3]" IOSTANDARD = "LVCMOS33";
NET "vme_am_i[2]" IOSTANDARD = "LVCMOS33";
NET "vme_am_i[1]" IOSTANDARD = "LVCMOS33";
NET "vme_am_i[0]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[31]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[30]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[29]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[28]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[27]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[26]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[25]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[24]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[23]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[22]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[21]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[20]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[19]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[18]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[17]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[16]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[15]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[14]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[13]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[12]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[11]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[10]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[9]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[8]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[7]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[6]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[5]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[4]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[3]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[2]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[1]" IOSTANDARD = "LVCMOS33";
# <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 "tdc1_acam_refclk_p_i" LOC = "H15";
NET "tdc1_acam_refclk_p_i" IOSTANDARD = "LVDS_25";
NET "tdc1_acam_refclk_n_i" LOC = "G15";
NET "tdc1_acam_refclk_n_i" IOSTANDARD = "LVDS_25";
NET "tdc1_125m_clk_p_i" LOC = "E16";
NET "tdc1_125m_clk_p_i" IOSTANDARD = "LVDS_25";
NET "tdc1_125m_clk_n_i" LOC = "D16";
NET "tdc1_125m_clk_n_i" IOSTANDARD = "LVDS_25";
NET "tdc1_led_trig1_o" LOC = "H13";
NET "tdc1_led_trig1_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_led_trig2_o" LOC = "H11";
NET "tdc1_led_trig2_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_led_trig3_o" LOC = "G11";
NET "tdc1_led_trig3_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_term_en_1_o" LOC = "C16";
NET "tdc1_term_en_1_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_term_en_2_o" LOC = "A16";
NET "tdc1_term_en_2_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_ef1_i" LOC = "F19";
NET "tdc1_ef1_i" IOSTANDARD = "LVCMOS25";
NET "tdc1_ef2_i" LOC = "E19";
NET "tdc1_ef2_i" IOSTANDARD = "LVCMOS25";
NET "tdc1_term_en_3_o" LOC = "F15";
NET "tdc1_term_en_3_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_term_en_4_o" LOC = "E15";
NET "tdc1_term_en_4_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_term_en_5_o" LOC = "F13";
NET "tdc1_term_en_5_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_led_status_o" LOC = "E13";
NET "tdc1_led_status_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_led_trig4_o" LOC = "L11";
NET "tdc1_led_trig4_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_led_trig5_o" LOC = "K11";
NET "tdc1_led_trig5_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_pll_sclk_o" LOC = "M15";
NET "tdc1_pll_sclk_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_pll_dac_sync_n_o" LOC = "K15";
NET "tdc1_pll_dac_sync_n_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_pll_cs_n_o" LOC = "L14";
NET "tdc1_pll_cs_n_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_cs_n_o" LOC = "K14";
NET "tdc1_cs_n_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_err_flag_i" LOC = "H16";
NET "tdc1_err_flag_i" IOSTANDARD = "LVCMOS25";
NET "tdc1_int_flag_i" LOC = "G16";
NET "tdc1_int_flag_i" IOSTANDARD = "LVCMOS25";
NET "tdc1_start_dis_o" LOC = "F11";
NET "tdc1_start_dis_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_stop_dis_o" LOC = "E11";
NET "tdc1_stop_dis_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_pll_sdo_i" LOC = "L13";
NET "tdc1_pll_sdo_i" IOSTANDARD = "LVCMOS25";
NET "tdc1_pll_status_i" LOC = "E9";
NET "tdc1_pll_status_i" IOSTANDARD = "LVCMOS25";
NET "tdc1_pll_sdi_o" LOC = "M13";
NET "tdc1_pll_sdi_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_start_from_fpga_o" LOC = "F9";
NET "tdc1_start_from_fpga_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[27]" LOC = "E17";
NET "tdc1_data_bus_io[27]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[26]" LOC = "F17";
NET "tdc1_data_bus_io[26]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[25]" LOC = "F18";
NET "tdc1_data_bus_io[25]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[24]" LOC = "G18";
NET "tdc1_data_bus_io[24]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[23]" LOC = "F20";
NET "tdc1_data_bus_io[23]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[22]" LOC = "G20";
NET "tdc1_data_bus_io[22]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[21]" LOC = "E21";
NET "tdc1_data_bus_io[21]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[20]" LOC = "F21";
NET "tdc1_data_bus_io[20]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[19]" LOC = "K21";
NET "tdc1_data_bus_io[19]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[18]" LOC = "L21";
NET "tdc1_data_bus_io[18]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[17]" LOC = "L20";
NET "tdc1_data_bus_io[17]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[16]" LOC = "M20";
NET "tdc1_data_bus_io[16]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[15]" LOC = "F22";
NET "tdc1_data_bus_io[15]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[14]" LOC = "G22";
NET "tdc1_data_bus_io[14]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[13]" LOC = "L19";
NET "tdc1_data_bus_io[13]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[12]" LOC = "M19";
NET "tdc1_data_bus_io[12]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[11]" LOC = "E23";
NET "tdc1_data_bus_io[11]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[10]" LOC = "F23";
NET "tdc1_data_bus_io[10]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[9]" LOC = "A25";
NET "tdc1_data_bus_io[9]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[8]" LOC = "B25";
NET "tdc1_data_bus_io[8]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[7]" LOC = "G21";
NET "tdc1_data_bus_io[7]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[6]" LOC = "C24";
NET "tdc1_data_bus_io[6]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[5]" LOC = "H21";
NET "tdc1_data_bus_io[5]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[4]" LOC = "D24";
NET "tdc1_data_bus_io[4]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[3]" LOC = "D25";
NET "tdc1_data_bus_io[3]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[2]" LOC = "E25";
NET "tdc1_data_bus_io[2]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[1]" LOC = "H22";
NET "tdc1_data_bus_io[1]" IOSTANDARD = "LVCMOS25";
NET "tdc1_data_bus_io[0]" LOC = "J22";
NET "tdc1_data_bus_io[0]" IOSTANDARD = "LVCMOS25";
NET "tdc1_address_o[3]" LOC = "F14";
NET "tdc1_address_o[3]" IOSTANDARD = "LVCMOS25";
NET "tdc1_address_o[2]" LOC = "G14";
NET "tdc1_address_o[2]" IOSTANDARD = "LVCMOS25";
NET "tdc1_address_o[1]" LOC = "H14";
NET "tdc1_address_o[1]" IOSTANDARD = "LVCMOS25";
NET "tdc1_address_o[0]" LOC = "J14";
NET "tdc1_address_o[0]" IOSTANDARD = "LVCMOS25";
NET "tdc1_oe_n_o" LOC = "G12";
NET "tdc1_oe_n_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_rd_n_o" LOC = "A15";
NET "tdc1_rd_n_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_wr_n_o" LOC = "B15";
NET "tdc1_wr_n_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_enable_inputs_o" LOC = "J12";
NET "tdc1_enable_inputs_o" IOSTANDARD = "LVCMOS25";
NET "tdc1_one_wire_b" LOC = "H12";
NET "tdc1_one_wire_b" IOSTANDARD = "LVCMOS25";
# ucfgen pin assignments for mezzanine fmc-tdc-v3 slot 1
NET "tdc2_acam_refclk_p_i" LOC = "AF16";
NET "tdc2_acam_refclk_p_i" IOSTANDARD = "LVDS_25";
NET "tdc2_acam_refclk_n_i" LOC = "AG16";
NET "tdc2_acam_refclk_n_i" IOSTANDARD = "LVDS_25";
NET "tdc2_125m_clk_p_i" LOC = "AH16";
NET "tdc2_125m_clk_p_i" IOSTANDARD = "LVDS_25";
NET "tdc2_125m_clk_n_i" LOC = "AK16";
NET "tdc2_125m_clk_n_i" IOSTANDARD = "LVDS_25";
NET "tdc2_led_trig1_o" LOC = "Y20";
NET "tdc2_led_trig1_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_led_trig2_o" LOC = "W19";
NET "tdc2_led_trig2_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_led_trig3_o" LOC = "Y19";
NET "tdc2_led_trig3_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_term_en_1_o" LOC = "AJ17";
NET "tdc2_term_en_1_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_term_en_2_o" LOC = "AK17";
NET "tdc2_term_en_2_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_ef1_i" LOC = "AB14";
NET "tdc2_ef1_i" IOSTANDARD = "LVCMOS25";
NET "tdc2_ef2_i" LOC = "AC14";
NET "tdc2_ef2_i" IOSTANDARD = "LVCMOS25";
NET "tdc2_term_en_3_o" LOC = "AE19";
NET "tdc2_term_en_3_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_term_en_4_o" LOC = "AF19";
NET "tdc2_term_en_4_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_term_en_5_o" LOC = "AE24";
NET "tdc2_term_en_5_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_led_status_o" LOC = "AF24";
NET "tdc2_led_status_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_led_trig4_o" LOC = "Y21";
NET "tdc2_led_trig4_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_led_trig5_o" LOC = "AA21";
NET "tdc2_led_trig5_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_pll_sclk_o" LOC = "AF25";
NET "tdc2_pll_sclk_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_pll_dac_sync_n_o" LOC = "AG25";
NET "tdc2_pll_dac_sync_n_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_pll_cs_n_o" LOC = "AC19";
NET "tdc2_pll_cs_n_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_cs_n_o" LOC = "AD19";
NET "tdc2_cs_n_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_err_flag_i" LOC = "Y17";
NET "tdc2_err_flag_i" IOSTANDARD = "LVCMOS25";
NET "tdc2_int_flag_i" LOC = "AA17";
NET "tdc2_int_flag_i" IOSTANDARD = "LVCMOS25";
NET "tdc2_start_dis_o" LOC = "AB17";
NET "tdc2_start_dis_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_stop_dis_o" LOC = "AD17";
NET "tdc2_stop_dis_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_pll_sdo_i" LOC = "AC20";
NET "tdc2_pll_sdo_i" IOSTANDARD = "LVCMOS25";
NET "tdc2_pll_status_i" LOC = "AD24";
NET "tdc2_pll_status_i" IOSTANDARD = "LVCMOS25";
NET "tdc2_pll_sdi_o" LOC = "AB20";
NET "tdc2_pll_sdi_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_start_from_fpga_o" LOC = "AC24";
NET "tdc2_start_from_fpga_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[27]" LOC = "AA15";
NET "tdc2_data_bus_io[27]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[26]" LOC = "Y15";
NET "tdc2_data_bus_io[26]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[25]" LOC = "AD15";
NET "tdc2_data_bus_io[25]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[24]" LOC = "AC15";
NET "tdc2_data_bus_io[24]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[23]" LOC = "AB16";
NET "tdc2_data_bus_io[23]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[22]" LOC = "Y16";
NET "tdc2_data_bus_io[22]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[21]" LOC = "AF15";
NET "tdc2_data_bus_io[21]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[20]" LOC = "AE15";
NET "tdc2_data_bus_io[20]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[19]" LOC = "AA14";
NET "tdc2_data_bus_io[19]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[18]" LOC = "Y14";
NET "tdc2_data_bus_io[18]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[17]" LOC = "Y13";
NET "tdc2_data_bus_io[17]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[16]" LOC = "W14";
NET "tdc2_data_bus_io[16]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[15]" LOC = "AE12";
NET "tdc2_data_bus_io[15]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[14]" LOC = "AD12";
NET "tdc2_data_bus_io[14]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[13]" LOC = "AF11";
NET "tdc2_data_bus_io[13]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[12]" LOC = "AE11";
NET "tdc2_data_bus_io[12]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[11]" LOC = "AC12";
NET "tdc2_data_bus_io[11]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[10]" LOC = "AB12";
NET "tdc2_data_bus_io[10]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[9]" LOC = "AE10";
NET "tdc2_data_bus_io[9]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[8]" LOC = "AD10";
NET "tdc2_data_bus_io[8]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[7]" LOC = "AH8";
NET "tdc2_data_bus_io[7]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[6]" LOC = "AK15";
NET "tdc2_data_bus_io[6]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[5]" LOC = "AG8";
NET "tdc2_data_bus_io[5]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[4]" LOC = "AJ15";
NET "tdc2_data_bus_io[4]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[3]" LOC = "AF13";
NET "tdc2_data_bus_io[3]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[2]" LOC = "AE13";
NET "tdc2_data_bus_io[2]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[1]" LOC = "AD11";
NET "tdc2_data_bus_io[1]" IOSTANDARD = "LVCMOS25";
NET "tdc2_data_bus_io[0]" LOC = "AC11";
NET "tdc2_data_bus_io[0]" IOSTANDARD = "LVCMOS25";
NET "tdc2_address_o[3]" LOC = "AF23";
NET "tdc2_address_o[3]" IOSTANDARD = "LVCMOS25";
NET "tdc2_address_o[2]" LOC = "AE23";
NET "tdc2_address_o[2]" IOSTANDARD = "LVCMOS25";
NET "tdc2_address_o[1]" LOC = "AF21";
NET "tdc2_address_o[1]" IOSTANDARD = "LVCMOS25";
NET "tdc2_address_o[0]" LOC = "AE21";
NET "tdc2_address_o[0]" IOSTANDARD = "LVCMOS25";
NET "tdc2_oe_n_o" LOC = "AD22";
NET "tdc2_oe_n_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_rd_n_o" LOC = "AD16";
NET "tdc2_rd_n_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_wr_n_o" LOC = "AC16";
NET "tdc2_wr_n_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_enable_inputs_o" LOC = "AA19";
NET "tdc2_enable_inputs_o" IOSTANDARD = "LVCMOS25";
NET "tdc2_one_wire_b" LOC = "AB19";
NET "tdc2_one_wire_b" IOSTANDARD = "LVCMOS25";
# <ucfgen_end>
#Created by Constraints Editor (xc6slx150t-fgg900-3) - 2013/07/19
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 "tdc1_125m_clk_n_i" TNM_NET = tdc1_125m_clk_n_i;
TIMESPEC TS_tdc1_tdc_125m_clk_n_i = PERIOD "tdc1_125m_clk_n_i" 8 ns HIGH 50%;
NET "tdc1_125m_clk_p_i" TNM_NET = tdc1_125m_clk_p_i;
TIMESPEC TS_tdc1_125m_clk_p_i = PERIOD "tdc1_125m_clk_p_i" 8 ns HIGH 50%;
NET "tdc2_125m_clk_p_i" TNM_NET = tdc2_125m_clk_p_i;
TIMESPEC TS_tdc2_tdc_125m_clk_p_i = PERIOD "tdc2_125m_clk_p_i" 8 ns HIGH 50%;
NET "tdc2_125m_clk_n_i" TNM_NET = tdc2_125m_clk_n_i;
TIMESPEC TS_tdc2_tdc_125m_clk_n_i = PERIOD "tdc2_125m_clk_n_i" 8 ns HIGH 50%;
--_________________________________________________________________________________________________
-- |
-- |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.sdb_meta_pkg.all;
use work.gencores_pkg.all;
--=================================================================================================
-- Package declaration for tdc_core_pkg
--=================================================================================================
package tdc_core_pkg is
---------------------------------------------------------------------------------------------------
-- Constants regarding the SDB crossbar --
---------------------------------------------------------------------------------------------------
-- Note: All address in sdb and crossbar are BYTE addresses!
-- Devices sdb description
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",
version => x"00000001",
date => x"20121116",
name => "WB-TDC-MEM ")));
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",
version => x"00000001",
date => x"20121116",
name => "WB-Onewire.Control ")));
constant c_SPEC_CSR_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",
version => x"00000001",
date => x"20121116",
name => "WB-SPEC-CSR ")));
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",
version => x"00000001",
date => x"20130429",
name => "WB-TDC-Core-Config ")));
constant c_INT_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"000000000000000F",
product =>
(vendor_id => x"000000000000CE42", -- CERN
device_id => x"00000605",
version => x"00000001",
date => x"20121116",
name => "WB-Int.Control ")));
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",
version => x"00000001",
date => x"20121116",
name => "WB-I2C.Control ")));
---------------------------------------------------------------------------------------------------
-- 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 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/VME host
-- corresponds to:
constant c_ACAM_REG0_ADR : std_logic_vector(7 downto 0) := x"00"; -- PCIe/VME address 5000
constant c_ACAM_REG1_ADR : std_logic_vector(7 downto 0) := x"01"; -- PCIe/VME address 5004
constant c_ACAM_REG2_ADR : std_logic_vector(7 downto 0) := x"02"; -- PCIe/VME address 5008
constant c_ACAM_REG3_ADR : std_logic_vector(7 downto 0) := x"03"; -- PCIe/VME address 500C
constant c_ACAM_REG4_ADR : std_logic_vector(7 downto 0) := x"04"; -- PCIe/VME address 5010
constant c_ACAM_REG5_ADR : std_logic_vector(7 downto 0) := x"05"; -- PCIe/VME address 5014
constant c_ACAM_REG6_ADR : std_logic_vector(7 downto 0) := x"06"; -- PCIe/VME address 5018
constant c_ACAM_REG7_ADR : std_logic_vector(7 downto 0) := x"07"; -- PCIe/VME address 501C
constant c_ACAM_REG11_ADR : std_logic_vector(7 downto 0) := x"0B"; -- PCIe/VME address 502C
constant c_ACAM_REG12_ADR : std_logic_vector(7 downto 0) := x"0C"; -- PCIe/VME address 5030
constant c_ACAM_REG14_ADR : std_logic_vector(7 downto 0) := x"0E"; -- PCIe/VME address 5038
---------------------------------------------------------------------------------------------------
-- 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"; -- PCIe/VME address 5020, read only
constant c_ACAM_REG9_ADR : std_logic_vector(7 downto 0) := x"09"; -- PCIe/VME address 5024, read only
constant c_ACAM_REG10_ADR : std_logic_vector(7 downto 0) := x"0A"; -- PCIe/VME address 5028, read only
---------------------------------------------------------------------------------------------------
-- 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"; -- PCIe/VME address 5040, read only
constant c_ACAM_REG1_RDBK_ADR : std_logic_vector(7 downto 0) := x"11"; -- PCIe/VME address 5044, read only
constant c_ACAM_REG2_RDBK_ADR : std_logic_vector(7 downto 0) := x"12"; -- PCIe/VME address 5048, read only
constant c_ACAM_REG3_RDBK_ADR : std_logic_vector(7 downto 0) := x"13"; -- PCIe/VME address 504C, read only
constant c_ACAM_REG4_RDBK_ADR : std_logic_vector(7 downto 0) := x"14"; -- PCIe/VME address 5050, read only
constant c_ACAM_REG5_RDBK_ADR : std_logic_vector(7 downto 0) := x"15"; -- PCIe/VME address 5054, read only
constant c_ACAM_REG6_RDBK_ADR : std_logic_vector(7 downto 0) := x"16"; -- PCIe/VME address 5058, read only
constant c_ACAM_REG7_RDBK_ADR : std_logic_vector(7 downto 0) := x"17"; -- PCIe/VME address 505C, read only
constant c_ACAM_REG8_RDBK_ADR : std_logic_vector(7 downto 0) := x"18"; -- PCIe/VME address 5060, read only
constant c_ACAM_REG9_RDBK_ADR : std_logic_vector(7 downto 0) := x"19"; -- PCIe/VME address 5064, read only
constant c_ACAM_REG10_RDBK_ADR : std_logic_vector(7 downto 0) := x"1A"; -- PCIe/VME address 5068, read only
constant c_ACAM_REG11_RDBK_ADR : std_logic_vector(7 downto 0) := x"1B"; -- PCIe/VME address 506C, read only
constant c_ACAM_REG12_RDBK_ADR : std_logic_vector(7 downto 0) := x"1C"; -- PCIe/VME address 5070, read only
constant c_ACAM_REG14_RDBK_ADR : std_logic_vector(7 downto 0) := x"1E"; -- PCIe/VME address 5078, read only
---------------------------------------------------------------------------------------------------
-- 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"; -- PCIe/VME address 5080
constant c_ACAM_INPUTS_EN_ADR : std_logic_vector(7 downto 0) := x"21"; -- PCIe/VME address 5084
constant c_START_PHASE_ADR : std_logic_vector(7 downto 0) := x"22"; -- PCIe/VME address 5088
constant c_ONE_HZ_PHASE_ADR : std_logic_vector(7 downto 0) := x"23"; -- PCIe/VME address 508C
constant c_IRQ_TSTAMP_THRESH_ADR: std_logic_vector(7 downto 0) := x"24"; -- PCIe/VME address 5090
constant c_IRQ_TIME_THRESH_ADR : std_logic_vector(7 downto 0) := x"25"; -- PCIe/VME address 5094
constant c_DAC_WORD_ADR : std_logic_vector(7 downto 0) := x"26"; -- PCIe/VME address 5098
-- constant c_RESERVED1 : std_logic_vector(7 downto 0) := x"27"; -- PCIe/VME address 509C
---------------------------------------------------------------------------------------------------
-- 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"; -- PCIe/VME address 50A0
constant c_IRQ_CODE_ADR : std_logic_vector(7 downto 0) := x"29"; -- PCIe/VME address 50A4
constant c_WR_INDEX_ADR : std_logic_vector(7 downto 0) := x"2A"; -- PCIe/VME address 50A8
constant c_CORE_STATUS_ADR : std_logic_vector(7 downto 0) := x"2B"; -- PCIe/VME address 50AC
---------------------------------------------------------------------------------------------------
-- Address of TDC core Control register
-- corresponds to:
constant c_CTRL_REG_ADR : std_logic_vector(7 downto 0) := x"3F"; -- PCIe/VME address 50FC
---------------------------------------------------------------------------------------------------
-- 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;
---------------------------------------------------------------------------------------------------
-- Components Declarations: --
---------------------------------------------------------------------------------------------------
component fmc_tdc_mezzanine is
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;
irq_tstamp_p_o : out std_logic;
irq_time_p_o : out std_logic;
irq_acam_err_p_o : out std_logic;
wb_tdc_mezz_adr_i : in std_logic_vector(31 downto 0);
wb_tdc_mezz_dat_i : in std_logic_vector(31 downto 0);
wb_tdc_mezz_dat_o : out std_logic_vector(31 downto 0);
wb_tdc_mezz_cyc_i : in std_logic;
wb_tdc_mezz_sel_i : in std_logic_vector(3 downto 0);
wb_tdc_mezz_stb_i : in std_logic;
wb_tdc_mezz_we_i : in std_logic;
wb_tdc_mezz_ack_o : out std_logic;
wb_tdc_mezz_stall_o : out std_logic;
sys_scl_b : inout std_logic;
sys_sda_b : inout std_logic;
mezz_one_wire_b : inout 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;
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);
end component;
---------------------------------------------------------------------------------------------------
component xvme64x_core
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
VME_AS_n_i : in std_logic;
VME_RST_n_i : in std_logic;
VME_WRITE_n_i : in std_logic;
VME_AM_i : in std_logic_vector(5 downto 0);
VME_DS_n_i : in std_logic_vector(1 downto 0);
VME_GA_i : in std_logic_vector(5 downto 0);
VME_BERR_o : out std_logic;
VME_DTACK_n_o : out std_logic;
VME_RETRY_n_o : out std_logic;
VME_RETRY_OE_o : out std_logic;
VME_LWORD_n_b_i : in std_logic;
VME_LWORD_n_b_o : out std_logic;
VME_ADDR_b_i : in std_logic_vector(31 downto 1);
VME_ADDR_b_o : out std_logic_vector(31 downto 1);
VME_DATA_b_i : in std_logic_vector(31 downto 0);
VME_DATA_b_o : out std_logic_vector(31 downto 0);
VME_IRQ_n_o : out std_logic_vector(6 downto 0);
VME_IACKIN_n_i : in std_logic;
VME_IACK_n_i : in std_logic;
VME_IACKOUT_n_o : out std_logic;
VME_DTACK_OE_o : out std_logic;
VME_DATA_DIR_o : out std_logic;
VME_DATA_OE_N_o : out std_logic;
VME_ADDR_DIR_o : out std_logic;
VME_ADDR_OE_N_o : out std_logic;
master_o : out t_wishbone_master_out;
master_i : in t_wishbone_master_in;
irq_i : in std_logic;
irq_ack_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;
one_hz_p_i : in std_logic;
----------------------------------------------------------------------
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 one_hz_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);
one_hz_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;
----------------------------------------------------------------------
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_status_o : out std_logic_vector(31 downto 0);
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_status_i : in std_logic_vector(g_width-1 downto 0);
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);
----------------------------------------------------------------------
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;
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));
----------------------------------------------------------------------
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;
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);
----------------------------------------------------------------------
start_from_fpga_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;
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);
local_utc_i : in std_logic_vector(31 downto 0);
retrig_nb_offset_i : in std_logic_vector(31 downto 0);
one_hz_p_i : in std_logic;
----------------------------------------------------------------------
tdc_led_5_o : out 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;
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);
acam_errflag_r_edge_p_i : in std_logic;
activate_acq_p_i : in std_logic;
deactivate_acq_p_i : in std_logic;
tstamp_wr_p_i : in std_logic;
one_hz_p_i : in std_logic;
----------------------------------------------------------------------
irq_tstamp_p_o : out std_logic;
irq_time_p_o : out std_logic;
irq_acam_err_p_o : out std_logic);
----------------------------------------------------------------------
end component;
---------------------------------------------------------------------------------------------------
component irq_controller
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_tdc1_tstamps_i : in std_logic;
irq_tdc1_acam_err_i : in std_logic;
irq_tdc2_tstamps_i : in std_logic;
irq_tdc2_acam_err_i : in std_logic);
end component irq_controller;
---------------------------------------------------------------------------------------------------
component clks_rsts_manager
generic
(nb_of_reg : integer := 68);
port
(clk_20m_vcxo_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);
----------------------------------------------------------------------
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_csr
port
(rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(1 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_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;
carrier_csr_carrier_pcb_rev_i : in std_logic_vector(3 downto 0);
carrier_csr_carrier_reserved_i : in std_logic_vector(11 downto 0);
carrier_csr_carrier_type_i : in std_logic_vector(15 downto 0);
carrier_csr_stat_fmc_pres_i : in std_logic;
carrier_csr_stat_p2l_pll_lck_i : in std_logic;
carrier_csr_stat_sys_pll_lck_i : in std_logic;
carrier_csr_stat_ddr3_cal_done_i : in std_logic;
carrier_csr_stat_reserved_i : in std_logic_vector(27 downto 0);
carrier_csr_ctrl_led_green_o : out std_logic;
carrier_csr_ctrl_led_red_o : out std_logic;
carrier_csr_ctrl_dac_clr_n_o : out std_logic;
carrier_csr_ctrl_reserved_o : out std_logic_vector(28 downto 0));
end component carrier_csr;
---------------------------------------------------------------------------------------------------
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;
one_hz_p_i : in std_logic;
acam_inputs_en_i : in std_logic_vector(g_width-1 downto 0);
fordebug_i : in std_logic_vector(5 downto 0);
----------------------------------------------------------------------
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;
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
---------------------------------------------------------------------------------------------------
\ No newline at end of file
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- |
-- top_tdc |
-- |
---------------------------------------------------------------------------------------------------
-- File top_tdc.vhd |
-- |
-- Description TDC top level for SVEC. Figure 1 shows the architecture of this unit. |
-- o Two TDC mezzanine cores are instanciated, for the boards on FMC1 and FMC2 |
-- o The IRQ controller is managing the interrupts coming from both TDC cores |
-- o The carrier_csr module provides general information on the SVEC PCB version, |
-- PLLs locking state etc |
-- o The 1-Wire core provides communication with the SVEC Thermometer&UniqueID chip|
-- All these cores communicate with the VME core through the SDB crossbar. The SDB |
-- crossbar is responsible for managing the acess to the VME core. |
-- |
-- The speed for the VME core is 62.5MHz. The TDC mezzanine cores however operate at |
-- 125MHz. The crossing from the 62.5MHz world to the 125MHz world takes place |
-- through dedicated clock_crossing cores. |
-- |
-- The 62.5MHz clock comes from an internal Xilinx FPGA PLL, using the 20MHz VCXO of |
-- the SVEC board. |
-- |
-- The 125MHz clock for each TDC mezzanine comes from the PLL located on it. |
-- A clks_rsts_manager unit is responsible for automatically configuring the PLL upon|
-- the FPGA startup, using the 20MHz VCXO on the SVEC board. The clks_rsts_manager is|
-- keeping the TDC mezzanine core under reset until the respective PLL gets locked. |
-- |
-- Upon powering up of the FPGA as well as after a VME reset, the whole logic gets |
-- reset (FMC1 125MHz, FMC2 125MHz and 62.5MHz). This also triggers a reprogramming |
-- of the mezzanines' PLL through the clks_rsts_manager units. |
-- An extra software reset is implemented for the TDC mezzanine cores, using resevred|
-- bits of the carrier_csr core. Such a reset also triggers the reprogramming of the |
-- mezzanines' PLL. |
-- |
-- __________________________________________________________________ |
-- | ____________________________ ___ _____ | |
-- | | ____________ _______ | | | | | | |
-- | | | | | clk | | \ | | | | | |
-- | | | TDC mezz 1 | | cross | | \ | | | | | |
-- FMC1 | | |____________| |_______| | \ | | | | | |
-- | | ___________________ | \ | | | | | |
-- | | |_clks_rsts_manager_| | | | | | | |
-- | |____________________________| | | | | | |
-- | FMC1 125MHz | | | | | |
-- | ____________________________ | | | | | |
-- | | ____________ _______ | | | | | | |
-- | | | | | clk | | | | | | | |
-- | | | TDC mezz 2 | | cross | | | S | | V | | |
-- FMC2 | | |____________| |_______| | ---- | | | | | |
-- | | ___________________ | | | | | | |
-- | | |_clks_rsts_manager_| | | | | | | |
-- | |____________________________| | D | <--> | M | | |
-- | FMC2 125MHz | | | | | |
-- | ____________________________ | | | | | |
-- | | | | | | | | |
-- | | IRQ controller | ---- | B | | E | | |
-- | |____________________________| | | | | | |
-- | 62.5MHz | | | | | |
-- | ____________________________ | | | | | |
-- | | | | | | | | |
-- SVEC 1W chip | | 1-Wire | ---- | | | | | |
-- | |____________________________| | | | | | |
-- | 62.5MHz / | | | | | |
-- | ____________________________ / | | | | | |
-- | | | / | | | | | |
-- | | Carrier_CSR | / | | | | | |
-- | |____________________________| | | | | | |
-- | |___| |_____| | |
-- | 62.5MHZ 62.5MHz | |
-- | ______________________________________________ | |
-- | |___________________LEDs_______________________| | |
-- | | |
-- |__________________________________________________________________| |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 08/2013 |
-- Version v4 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 08/2013 v4 EG design for SVEC; two cores; synchronizer between vme and the cores |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- 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.sdb_meta_pkg.all;
use work.bicolor_led_ctrl_pkg.all;
library UNISIM;
use UNISIM.vcomponents.all;
--=================================================================================================
-- Entity declaration for top_tdc
--=================================================================================================
entity top_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
(-- Carrier PoR
por_n_i : in std_logic;
-- Carrier 20MHz VCXO
clk_20m_vcxo_i : in std_logic;
-- VME interface
VME_AS_n_i : in std_logic;
VME_RST_n_i : in std_logic;
VME_WRITE_n_i : in std_logic;
VME_AM_i : in std_logic_vector(5 downto 0);
VME_DS_n_i : in std_logic_vector(1 downto 0);
VME_GA_i : in std_logic_vector(5 downto 0);
VME_BERR_o : inout std_logic;
VME_DTACK_n_o : inout std_logic;
VME_RETRY_n_o : out std_logic;
VME_RETRY_OE_o : out std_logic;
VME_LWORD_n_b : inout std_logic;
VME_ADDR_b : inout std_logic_vector(31 downto 1);
VME_DATA_b : inout std_logic_vector(31 downto 0);
VME_BBSY_n_i : in std_logic;
VME_IRQ_n_o : out std_logic_vector(6 downto 0);
VME_IACK_n_i : in std_logic;
VME_IACKIN_n_i : in std_logic;
VME_IACKOUT_n_o : out std_logic;
VME_DTACK_OE_o : inout std_logic;
VME_DATA_DIR_o : inout std_logic;
VME_DATA_OE_N_o : inout std_logic;
VME_ADDR_DIR_o : inout std_logic;
VME_ADDR_OE_N_o : inout std_logic;
-- TDC mezzanine board on FMC slot 1
-- TDC1 PLL AD9516 and DAC AD5662 interface
tdc1_pll_sclk_o : out std_logic;
tdc1_pll_sdi_o : out std_logic;
tdc1_pll_cs_n_o : out std_logic;
tdc1_pll_dac_sync_n_o : out std_logic;
tdc1_pll_sdo_i : in std_logic;
tdc1_pll_status_i : in std_logic;
tdc1_125m_clk_p_i : in std_logic;
tdc1_125m_clk_n_i : in std_logic;
tdc1_acam_refclk_p_i : in std_logic;
tdc1_acam_refclk_n_i : in std_logic;
-- TDC1 ACAM timing interface
tdc1_start_from_fpga_o : out std_logic;
tdc1_err_flag_i : in std_logic;
tdc1_int_flag_i : in std_logic;
tdc1_start_dis_o : out std_logic;
tdc1_stop_dis_o : out std_logic;
-- TDC1 ACAM data interface
tdc1_data_bus_io : inout std_logic_vector(27 downto 0);
tdc1_address_o : out std_logic_vector(3 downto 0);
tdc1_cs_n_o : out std_logic;
tdc1_oe_n_o : out std_logic;
tdc1_rd_n_o : out std_logic;
tdc1_wr_n_o : out std_logic;
tdc1_ef1_i : in std_logic;
tdc1_ef2_i : in std_logic;
-- TDC1 Input Logic
tdc1_enable_inputs_o : out std_logic;
tdc1_term_en_1_o : out std_logic;
tdc1_term_en_2_o : out std_logic;
tdc1_term_en_3_o : out std_logic;
tdc1_term_en_4_o : out std_logic;
tdc1_term_en_5_o : out std_logic;
-- TDC1 1-wire UniqueID & Thermometer
tdc1_one_wire_b : inout std_logic;
-- TDC1 EEPROM I2C
tdc1_scl_b : inout std_logic;
tdc1_sda_b : inout std_logic;
-- TDC1 LEDs
tdc1_led_status_o : out std_logic;
tdc1_led_trig1_o : out std_logic;
tdc1_led_trig2_o : out std_logic;
tdc1_led_trig3_o : out std_logic;
tdc1_led_trig4_o : out std_logic;
tdc1_led_trig5_o : out std_logic;
-- TDC1 Input channels, also arriving to the FPGA (not used for the moment)
tdc1_in_fpga_1_i : in std_logic;
tdc1_in_fpga_2_i : in std_logic;
tdc1_in_fpga_3_i : in std_logic;
tdc1_in_fpga_4_i : in std_logic;
tdc1_in_fpga_5_i : in std_logic;
-- TDC mezzanine board on FMC slot 2
-- TDC2 PLL AD9516 and DAC AD5662 interface
tdc2_pll_sclk_o : out std_logic;
tdc2_pll_sdi_o : out std_logic;
tdc2_pll_cs_n_o : out std_logic;
tdc2_pll_dac_sync_n_o : out std_logic;
tdc2_pll_sdo_i : in std_logic;
tdc2_pll_status_i : in std_logic;
tdc2_125m_clk_p_i : in std_logic;
tdc2_125m_clk_n_i : in std_logic;
tdc2_acam_refclk_p_i : in std_logic;
tdc2_acam_refclk_n_i : in std_logic;
-- TDC2 ACAM timing interface
tdc2_start_from_fpga_o : out std_logic;
tdc2_err_flag_i : in std_logic;
tdc2_int_flag_i : in std_logic;
tdc2_start_dis_o : out std_logic;
tdc2_stop_dis_o : out std_logic;
-- TDC2 ACAM data interface
tdc2_data_bus_io : inout std_logic_vector(27 downto 0);
tdc2_address_o : out std_logic_vector(3 downto 0);
tdc2_cs_n_o : out std_logic;
tdc2_oe_n_o : out std_logic;
tdc2_rd_n_o : out std_logic;
tdc2_wr_n_o : out std_logic;
tdc2_ef1_i : in std_logic;
tdc2_ef2_i : in std_logic;
-- TDC2 Input Logic
tdc2_enable_inputs_o : out std_logic;
tdc2_term_en_1_o : out std_logic;
tdc2_term_en_2_o : out std_logic;
tdc2_term_en_3_o : out std_logic;
tdc2_term_en_4_o : out std_logic;
tdc2_term_en_5_o : out std_logic;
-- TDC2 1-wire UniqueID & Thermometer
tdc2_one_wire_b : inout std_logic;
-- TDC2 EEPROM I2C
tdc2_scl_b : inout std_logic;
tdc2_sda_b : inout std_logic;
-- TDC2 LEDs
tdc2_led_status_o : out std_logic;
tdc2_led_trig1_o : out std_logic;
tdc2_led_trig2_o : out std_logic;
tdc2_led_trig3_o : out std_logic;
tdc2_led_trig4_o : out std_logic;
tdc2_led_trig5_o : out std_logic;
-- TDC2 Input channels, also arriving to the FPGA (not used for the moment)
tdc2_in_fpga_1_i : in std_logic;
tdc2_in_fpga_2_i : in std_logic;
tdc2_in_fpga_3_i : in std_logic;
tdc2_in_fpga_4_i : in std_logic;
tdc2_in_fpga_5_i : in std_logic;
-- Carrier other signals
-- SVEC 1-wire UniqueID & Thermometer
carrier_one_wire_b : inout std_logic;
-- SVEC PCB version
pcb_ver_i : in std_logic_vector(3 downto 0);
-- Mezzanines presence
tdc1_prsntm2c_n_i : in std_logic;
tdc2_prsntm2c_n_i : in std_logic;
-- SVEC Front panel LEDs
fp_led_line_oen_o : out std_logic_vector(1 downto 0);
fp_led_line_o : out std_logic_vector(1 downto 0);
fp_led_column_o : out std_logic_vector(3 downto 0));
end top_tdc;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of top_tdc is
---------------------------------------------------------------------------------------------------
-- CONSTANTS --
---------------------------------------------------------------------------------------------------
-- Constant regarding the Carrier type
constant c_CARRIER_TYPE : std_logic_vector(15 downto 0) := x"0002";
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Constants regarding the SDB crossbar
constant c_NUM_WB_SLAVES : integer := 1;
constant c_NUM_WB_MASTERS : integer := 5;
constant c_MASTER_VME : integer := 0;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
constant c_SLAVE_SVEC_1W : integer := 0; -- SVEC 1wire interface
constant c_SLAVE_SVEC_INFO : integer := 1; -- SVEC control and status registers
constant c_SLAVE_IRQ : integer := 2; -- Interrupt controller
constant c_SLAVE_TDC0 : integer := 3; -- TIMETAG core for time-tagging
constant c_SLAVE_TDC1 : integer := 4; -- TIMETAG core for time-tagging
constant c_SDB_ADDRESS : t_wishbone_address := x"00000000";
constant c_FMC_TDC0_SDB_BRIDGE : t_sdb_bridge := f_xwb_bridge_manual_sdb(x"0001FFFF", x"00000000");
constant c_FMC_TDC1_SDB_BRIDGE : t_sdb_bridge := f_xwb_bridge_manual_sdb(x"0001FFFF", x"00000000");
constant c_INTERCONNECT_LAYOUT : t_sdb_record_array(7 downto 0) :=
(0 => f_sdb_embed_device (c_ONEWIRE_SDB_DEVICE, x"00010000"),
1 => f_sdb_embed_device (c_SPEC_CSR_SDB_DEVICE, x"00020000"),
2 => f_sdb_embed_device (c_INT_SDB_DEVICE, x"00030000"),
3 => f_sdb_embed_bridge (c_FMC_TDC0_SDB_BRIDGE, x"00040000"),
4 => f_sdb_embed_bridge (c_FMC_TDC1_SDB_BRIDGE, x"00060000"),
5 => f_sdb_embed_repo_url (c_SDB_REPO_URL),
6 => f_sdb_embed_synthesis (c_SDB_SYNTHESIS),
7 => f_sdb_embed_integration(c_SDB_INTEGRATION));
---------------------------------------------------------------------------------------------------
-- Signals --
---------------------------------------------------------------------------------------------------
-- Clocks
-- CLOCK DOMAIN: 20 MHz VCXO clock on SVEC carrier board: clk_20m_vcxo_i
signal clk_20m_vcxo_buf, clk_20m_vcxo : std_logic;
-- CLOCK DOMAIN: 62.5 MHz system clock derived from clk_20m_vcxo_i by a Xilinx PLL: clk_62m5_sys
signal clk_62m5_sys, pllout_clk_sys : std_logic;
signal pllout_clk_sys_fb, sys_locked : std_logic;
-- CLOCK DOMAIN: 125 MHz clock from PLL on TDC1: tdc1_clk_125m
signal tdc1_clk_125m : std_logic;
signal tdc1_acam_refclk_r_edge_p : std_logic;
signal tdc1_send_dac_word_p : std_logic;
signal tdc1_dac_word : std_logic_vector(23 downto 0);
signal tdc1_slave_in : t_wishbone_slave_in;
signal tdc1_slave_out : t_wishbone_slave_out;
signal tdc1_irq_acam_err_p : std_logic;
signal tdc1_irq_tstamp_p, tdc1_irq_time_p : std_logic;
-- CLOCK DOMAIN: 125 MHz clock from PLL on TDC2: tdc2_clk_125m
signal tdc2_clk_125m : std_logic;
signal tdc2_acam_refclk_r_edge_p : std_logic;
signal tdc2_send_dac_word_p : std_logic;
signal tdc2_dac_word : std_logic_vector(23 downto 0);
signal tdc2_slave_in : t_wishbone_slave_in;
signal tdc2_slave_out : t_wishbone_slave_out;
signal tdc2_irq_acam_err_p : std_logic;
signal tdc2_irq_tstamp_p, tdc2_irq_time_p : std_logic;
---------------------------------------------------------------------------------------------------
-- Resets
-- asynchronous reset from the FPGA inputs VME_RST_n_i and por_n_i
signal por_rst_n_a : std_logic;
signal powerup_rst_cnt : unsigned(7 downto 0) := "00000000";
-- system reset, synched with 62.5 MHz clock,driven by the VME reset and power-up reset pins.
signal rst_n_sys : std_logic;
-- reset input to the clks_rsts_manager units of the two TDC cores;
-- this reset initiates the configuration of the mezzanines PLL
signal tdc1_soft_rst_n : std_logic; -- driven by carrier CSR reserved bit 0
signal tdc2_soft_rst_n : std_logic; -- driven by carrier CSR reserved bit 1
signal carrier_csr_reserved_out : std_logic_vector(28 downto 0);
-- output reset of the clks_rsts_manager units;
-- this reset is released when the 125 MHz from the mezzanines PLL is available
signal tdc1_general_rst, tdc1_general_rst_n : std_logic;
signal tdc2_general_rst, tdc2_general_rst_n : std_logic;
---------------------------------------------------------------------------------------------------
-- VME interface
signal VME_DATA_b_out : std_logic_vector(31 downto 0);
signal VME_ADDR_b_out : std_logic_vector(31 downto 1);
signal VME_LWORD_n_b_out : std_logic;
signal VME_DATA_DIR_int : std_logic;
signal VME_ADDR_DIR_int : std_logic;
---------------------------------------------------------------------------------------------------
-- Crossbar
-- 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);
---------------------------------------------------------------------------------------------------
-- Interrupts
signal irq_to_vmecore : std_logic;
signal irq_sources : std_logic_vector(31 downto 0);
signal tdc1_irq_tstamps, tdc2_irq_tstamps : std_logic;
---------------------------------------------------------------------------------------------------
-- Carrier other signals
signal mezz_pll_status : std_logic_vector(11 downto 0);
signal carrier_owr_en, carrier_owr_i : std_logic_vector(c_FMC_ONE_WIRE_NB - 1 downto 0);
-- LEDs
signal led_state : std_logic_vector(15 downto 0);
signal tdc1_ef, tdc2_ef, led_tdc1_ef : std_logic;
signal led_tdc2_ef, led_tdc2_pll_status : std_logic;
signal led_tdc1_pll_status, led_vme_access : std_logic;
signal led_clk_62m5_divider : unsigned(22 downto 0);
signal led_clk_62m5_aux : std_logic_vector(7 downto 0);
signal led_clk_62m5 : std_logic;
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
---------------------------------------------------------------------------------------------------
-- Power On Reset --
---------------------------------------------------------------------------------------------------
-- SVEC power-up reset in the clk_62m5_sys domain: rst_n_sys is asserted asynchronously upon VME
-- reset or SVEC AFPGA power-on reset. If none of these signals is asserted at startup, the process
-- waits for the system clock PLL to lock + additional 256 clk_62m5_sys cycles before de-asserting
-- the reset.
p_powerup_reset : process(clk_62m5_sys, por_rst_n_a)
begin
if(por_rst_n_a = '0') then
rst_n_sys <= '0';
elsif rising_edge(clk_62m5_sys) then
if sys_locked = '1' then
if(powerup_rst_cnt = "11111111") then
rst_n_sys <= '1';
else
rst_n_sys <= '0';
powerup_rst_cnt <= powerup_rst_cnt + 1;
end if;
else
rst_n_sys <= '0';
powerup_rst_cnt <= "00000000";
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
por_rst_n_a <= VME_RST_n_i and por_n_i;
---------------------------------------------------------------------------------------------------
-- 62.5 MHz system clock --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
svec_clk_ibuf : IBUFG
port map
(I => clk_20m_vcxo_i,
O => 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, -- 20 MHz x 50 = 1 GHz
CLKFBOUT_PHASE => 0.000,
CLKOUT0_DIVIDE => 16, -- 62.5 MHz
CLKOUT0_PHASE => 0.000,
CLKOUT0_DUTY_CYCLE => 0.500,
CLKOUT1_DIVIDE => 16, -- 125 MHz, 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_sys_fb,
CLKOUT0 => pllout_clk_sys,
CLKOUT1 => open,
CLKOUT2 => open,
CLKOUT3 => open,
CLKOUT4 => open,
CLKOUT5 => open,
LOCKED => sys_locked,
RST => '0',
CLKFBIN => pllout_clk_sys_fb,
CLKIN => clk_20m_vcxo_buf);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
cmp_clk_sys_buf : BUFG
port map
(O => clk_62m5_sys,
I => pllout_clk_sys);
---------------------------------------------------------------------------------------------------
-- TDC1 125MHz --
---------------------------------------------------------------------------------------------------
cmp_tdc1_clks_rsts_mgment : clks_rsts_manager
generic map
(nb_of_reg => 68)
port map
(clk_20m_vcxo_i => clk_20m_vcxo_buf,
acam_refclk_p_i => tdc1_acam_refclk_p_i,
acam_refclk_n_i => tdc1_acam_refclk_n_i,
tdc_125m_clk_p_i => tdc1_125m_clk_p_i,
tdc_125m_clk_n_i => tdc1_125m_clk_n_i,
rst_n_i => tdc1_soft_rst_n, -- just use the system-wide reset to boostrap PLLs
pll_sdo_i => tdc1_pll_sdo_i,
pll_status_i => tdc1_pll_status_i,
send_dac_word_p_i => tdc1_send_dac_word_p,
dac_word_i => tdc1_dac_word,
acam_refclk_r_edge_p_o => tdc1_acam_refclk_r_edge_p,
internal_rst_o => tdc1_general_rst,
pll_cs_n_o => tdc1_pll_cs_n_o,
pll_dac_sync_n_o => tdc1_pll_dac_sync_n_o,
pll_sdi_o => tdc1_pll_sdi_o,
pll_sclk_o => tdc1_pll_sclk_o,
tdc_125m_clk_o => tdc1_clk_125m,
pll_status_o => open);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
tdc1_general_rst_n <= not tdc1_general_rst;
tdc1_soft_rst_n <= carrier_csr_reserved_out(0) and rst_n_sys;
---------------------------------------------------------------------------------------------------
-- TDC1 domains crossing: tdc1_clk_125m <-> clk_62m5_sys --
---------------------------------------------------------------------------------------------------
cmp_clks_crossing_ft0 : xwb_clock_crossing
port map
(slave_clk_i => clk_62m5_sys, -- Slave control port: VME interface at 62.5 MHz
slave_rst_n_i => rst_n_sys,
slave_i => cnx_master_out(c_SLAVE_TDC0),
slave_o => cnx_master_in(c_SLAVE_TDC0),
master_clk_i => tdc1_clk_125m, -- Master reader port: TDC core at 125 MHz
master_rst_n_i => tdc1_general_rst_n,
master_i => tdc1_slave_out,
master_o => tdc1_slave_in);
---------------------------------------------------------------------------------------------------
-- TDC2 125MHz --
---------------------------------------------------------------------------------------------------
cmp_tdc2_clks_rsts_mgment : clks_rsts_manager
generic map
(nb_of_reg => 68)
port map
(clk_20m_vcxo_i => clk_20m_vcxo_buf,
acam_refclk_p_i => tdc2_acam_refclk_p_i,
acam_refclk_n_i => tdc2_acam_refclk_n_i,
tdc_125m_clk_p_i => tdc2_125m_clk_p_i,
tdc_125m_clk_n_i => tdc2_125m_clk_n_i,
rst_n_i => tdc2_soft_rst_n,
pll_sdo_i => tdc2_pll_sdo_i,
pll_status_i => tdc2_pll_status_i,
send_dac_word_p_i => tdc2_send_dac_word_p,
dac_word_i => tdc2_dac_word,
acam_refclk_r_edge_p_o => tdc2_acam_refclk_r_edge_p,
internal_rst_o => tdc2_general_rst,
pll_cs_n_o => tdc2_pll_cs_n_o,
pll_dac_sync_n_o => tdc2_pll_dac_sync_n_o,
pll_sdi_o => tdc2_pll_sdi_o,
pll_sclk_o => tdc2_pll_sclk_o,
tdc_125m_clk_o => tdc2_clk_125m,
pll_status_o => open);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
tdc2_general_rst_n <= not tdc2_general_rst;
tdc2_soft_rst_n <= carrier_csr_reserved_out(1) and rst_n_sys;
---------------------------------------------------------------------------------------------------
-- TDC2 domains crossing: tdc2_clk_125m <-> clk_62m5_sys --
---------------------------------------------------------------------------------------------------
cmp_clks_crossing_ft1 : xwb_clock_crossing
port map
(slave_clk_i => clk_62m5_sys, -- Slave control port: VME interface at 62.5 MHz
slave_rst_n_i => rst_n_sys,
slave_i => cnx_master_out(c_SLAVE_TDC1),
slave_o => cnx_master_in(c_SLAVE_TDC1),
master_clk_i => tdc2_clk_125m, -- Master reader port: TDC core at 125 MHz
master_rst_n_i => tdc2_general_rst_n,
master_i => tdc2_slave_out,
master_o => tdc2_slave_in);
---------------------------------------------------------------------------------------------------
-- CSR WISHBONE CROSSBAR --
---------------------------------------------------------------------------------------------------
-- WISHBONE crossbar
-- 0x10000 -> SVEC carrier UnidueID&Thermometer 1-wire
-- 0x20000 -> SVEC CSR information
-- 0x30000 -> Interrupts
-- 0x40000 -> TDC board on FMC1
-- 0x60000 -> TDC board on FMC2
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_n_sys,
slave_i => cnx_slave_in,
slave_o => cnx_slave_out,
master_i => cnx_master_in,
master_o => cnx_master_out);
---------------------------------------------------------------------------------------------------
-- VME CORE --
---------------------------------------------------------------------------------------------------
U_VME_Core : xvme64x_core
port map (
clk_i => clk_62m5_sys,
rst_n_i => rst_n_sys,
VME_AS_n_i => VME_AS_n_i,
VME_RST_n_i => VME_RST_n_i,
VME_WRITE_n_i => VME_WRITE_n_i,
VME_AM_i => VME_AM_i,
VME_DS_n_i => VME_DS_n_i,
VME_GA_i => VME_GA_i,
VME_BERR_o => VME_BERR_o,
VME_DTACK_n_o => VME_DTACK_n_o,
VME_RETRY_n_o => VME_RETRY_n_o,
VME_RETRY_OE_o => VME_RETRY_OE_o,
VME_LWORD_n_b_i => VME_LWORD_n_b,
VME_LWORD_n_b_o => VME_LWORD_n_b_out,
VME_ADDR_b_i => VME_ADDR_b,
VME_DATA_b_o => VME_DATA_b_out,
VME_ADDR_b_o => VME_ADDR_b_out,
VME_DATA_b_i => VME_DATA_b,
VME_IRQ_n_o => VME_IRQ_n_o,
VME_IACK_n_i => VME_IACK_n_i,
VME_IACKIN_n_i => VME_IACKIN_n_i,
VME_IACKOUT_n_o => VME_IACKOUT_n_o,
VME_DTACK_OE_o => VME_DTACK_OE_o,
VME_DATA_DIR_o => VME_DATA_DIR_int,
VME_DATA_OE_N_o => VME_DATA_OE_N_o,
VME_ADDR_DIR_o => VME_ADDR_DIR_int,
VME_ADDR_OE_N_o => VME_ADDR_OE_N_o,
master_o => cnx_slave_in (c_MASTER_VME),
master_i => cnx_slave_out(c_MASTER_VME),
irq_i => irq_to_vmecore);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
VME_DATA_b <= VME_DATA_b_out when VME_DATA_DIR_int = '1' else (others => 'Z');
VME_ADDR_b <= VME_ADDR_b_out when VME_ADDR_DIR_int = '1' else (others => 'Z');
VME_LWORD_n_b <= VME_LWORD_n_b_out when VME_ADDR_DIR_int = '1' else 'Z';
VME_ADDR_DIR_o <= VME_ADDR_DIR_int;
VME_DATA_DIR_o <= VME_DATA_DIR_int;
---------------------------------------------------------------------------------------------------
-- TDC BOARD 1 --
---------------------------------------------------------------------------------------------------
cmp_tdc_board1 : fmc_tdc_mezzanine
generic map
(g_span => g_span,
g_width => g_width,
values_for_simul => values_for_simul)
port map
(-- clocks, resets, dac
clk_125m_i => tdc1_clk_125m,
rst_i => tdc1_general_rst,
acam_refclk_r_edge_p_i => tdc1_acam_refclk_r_edge_p,
send_dac_word_p_o => tdc1_send_dac_word_p,
dac_word_o => tdc1_dac_word,
-- ACAM
start_from_fpga_o => tdc1_start_from_fpga_o,
err_flag_i => tdc1_err_flag_i,
int_flag_i => tdc1_int_flag_i,
start_dis_o => tdc1_start_dis_o,
stop_dis_o => tdc1_stop_dis_o,
data_bus_io => tdc1_data_bus_io,
address_o => tdc1_address_o,
cs_n_o => tdc1_cs_n_o,
oe_n_o => tdc1_oe_n_o,
rd_n_o => tdc1_rd_n_o,
wr_n_o => tdc1_wr_n_o,
ef1_i => tdc1_ef1_i,
ef2_i => tdc1_ef2_i,
-- Input channels enable
enable_inputs_o => tdc1_enable_inputs_o,
term_en_1_o => tdc1_term_en_1_o,
term_en_2_o => tdc1_term_en_2_o,
term_en_3_o => tdc1_term_en_3_o,
term_en_4_o => tdc1_term_en_4_o,
term_en_5_o => tdc1_term_en_5_o,
-- Input channels to FPGA (not used)
tdc_in_fpga_1_i => tdc1_in_fpga_1_i,
tdc_in_fpga_2_i => tdc1_in_fpga_2_i,
tdc_in_fpga_3_i => tdc1_in_fpga_3_i,
tdc_in_fpga_4_i => tdc1_in_fpga_4_i,
tdc_in_fpga_5_i => tdc1_in_fpga_5_i,
-- LEDs and buttons on TDC and SPEC
tdc_led_status_o => tdc1_led_status_o,
tdc_led_trig1_o => tdc1_led_trig1_o,
tdc_led_trig2_o => tdc1_led_trig2_o,
tdc_led_trig3_o => tdc1_led_trig3_o,
tdc_led_trig4_o => tdc1_led_trig4_o,
tdc_led_trig5_o => tdc1_led_trig5_o,
-- Interrupts
irq_tstamp_p_o => tdc1_irq_tstamp_p,
irq_time_p_o => tdc1_irq_time_p,
irq_acam_err_p_o => tdc1_irq_acam_err_p,
-- WISHBONE interface with the GNUM/VME_core
wb_tdc_mezz_adr_i => tdc1_slave_in.adr,
wb_tdc_mezz_dat_i => tdc1_slave_in.dat,
wb_tdc_mezz_dat_o => tdc1_slave_out.dat,
wb_tdc_mezz_cyc_i => tdc1_slave_in.cyc,
wb_tdc_mezz_sel_i => tdc1_slave_in.sel,
wb_tdc_mezz_stb_i => tdc1_slave_in.stb,
wb_tdc_mezz_we_i => tdc1_slave_in.we,
wb_tdc_mezz_ack_o => tdc1_slave_out.ack,
wb_tdc_mezz_stall_o => tdc1_slave_out.stall,
-- TDC board EEPROM I2C EEPROM interface
sys_scl_b => tdc1_scl_b,
sys_sda_b => tdc1_sda_b,
-- 1-wire UniqueID&Thermometer interface
mezz_one_wire_b => tdc1_one_wire_b);
---------------------------------------------------------------------------------------------------
-- TDC BOARD 2 --
---------------------------------------------------------------------------------------------------
cmp_tdc_board2 : fmc_tdc_mezzanine
generic map
(g_span => g_span,
g_width => g_width,
values_for_simul => values_for_simul)
port map
(-- clocks, resets, dac
clk_125m_i => tdc2_clk_125m,
rst_i => tdc2_general_rst,
acam_refclk_r_edge_p_i => tdc2_acam_refclk_r_edge_p,
send_dac_word_p_o => tdc2_send_dac_word_p,
dac_word_o => tdc2_dac_word,
-- ACAM
start_from_fpga_o => tdc2_start_from_fpga_o,
err_flag_i => tdc2_err_flag_i,
int_flag_i => tdc2_int_flag_i,
start_dis_o => tdc2_start_dis_o,
stop_dis_o => tdc2_stop_dis_o,
data_bus_io => tdc2_data_bus_io,
address_o => tdc2_address_o,
cs_n_o => tdc2_cs_n_o,
oe_n_o => tdc2_oe_n_o,
rd_n_o => tdc2_rd_n_o,
wr_n_o => tdc2_wr_n_o,
ef1_i => tdc2_ef1_i,
ef2_i => tdc2_ef2_i,
-- Input channels enable
enable_inputs_o => tdc2_enable_inputs_o,
term_en_1_o => tdc2_term_en_1_o,
term_en_2_o => tdc2_term_en_2_o,
term_en_3_o => tdc2_term_en_3_o,
term_en_4_o => tdc2_term_en_4_o,
term_en_5_o => tdc2_term_en_5_o,
-- Input channels to FPGA (not used)
tdc_in_fpga_1_i => tdc2_in_fpga_1_i,
tdc_in_fpga_2_i => tdc2_in_fpga_2_i,
tdc_in_fpga_3_i => tdc2_in_fpga_3_i,
tdc_in_fpga_4_i => tdc2_in_fpga_4_i,
tdc_in_fpga_5_i => tdc2_in_fpga_5_i,
-- LEDs and buttons on TDC and SPEC
tdc_led_status_o => tdc2_led_status_o,
tdc_led_trig1_o => tdc2_led_trig1_o,
tdc_led_trig2_o => tdc2_led_trig2_o,
tdc_led_trig3_o => tdc2_led_trig3_o,
tdc_led_trig4_o => tdc2_led_trig4_o,
tdc_led_trig5_o => tdc2_led_trig5_o,
-- Interrupts
irq_tstamp_p_o => tdc2_irq_tstamp_p,
irq_time_p_o => tdc2_irq_time_p,
irq_acam_err_p_o => tdc2_irq_acam_err_p,
-- WISHBONE interface with the GNUM/VME_core
wb_tdc_mezz_adr_i => tdc2_slave_in.adr,
wb_tdc_mezz_dat_i => tdc2_slave_in.dat,
wb_tdc_mezz_dat_o => tdc2_slave_out.dat,
wb_tdc_mezz_cyc_i => tdc2_slave_in.cyc,
wb_tdc_mezz_sel_i => tdc2_slave_in.sel,
wb_tdc_mezz_stb_i => tdc2_slave_in.stb,
wb_tdc_mezz_we_i => tdc2_slave_in.we,
wb_tdc_mezz_ack_o => tdc2_slave_out.ack,
wb_tdc_mezz_stall_o => tdc2_slave_out.stall,
-- TDC board EEPROM I2C EEPROM interface
sys_scl_b => tdc2_scl_b,
sys_sda_b => tdc2_sda_b,
-- 1-wire UniqueID&Thermometer interface
mezz_one_wire_b => tdc2_one_wire_b);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Unused WISHBONE signals
tdc1_slave_out.err <= '0';
tdc1_slave_out.rty <= '0';
tdc1_slave_out.int <= '0';
---------------------------------------------------------------------------------------------------
-- INTERRUPTS CONTROLLER --
---------------------------------------------------------------------------------------------------
-- IRQ sources
-- 0 -> number of timestamps reached threshold or number of seconds passed reached threshold (TDC1)
-- 1 -> ACAM error (TDC1)
-- 2 -> number of timestamps reached threshold or number of seconds passed reached threshold (TDC2)
-- 3 -> ACAM error (TDC2)
-- 4-31 -> unused
cmp_irq_controller : irq_controller
port map
(clk_sys_i => clk_62m5_sys,
rst_n_i => rst_n_sys,
wb_adr_i => cnx_master_out(c_SLAVE_IRQ).adr(3 downto 2),
wb_dat_i => cnx_master_out(c_SLAVE_IRQ).dat,
wb_dat_o => cnx_master_in(c_SLAVE_IRQ).dat,
wb_cyc_i => cnx_master_out(c_SLAVE_IRQ).cyc,
wb_sel_i => cnx_master_out(c_SLAVE_IRQ).sel,
wb_stb_i => cnx_master_out(c_SLAVE_IRQ).stb,
wb_we_i => cnx_master_out(c_SLAVE_IRQ).we,
wb_ack_o => cnx_master_in(c_SLAVE_IRQ).ack,
wb_stall_o => cnx_master_in(c_SLAVE_IRQ).stall,
wb_int_o => irq_to_vmecore,
irq_tdc1_tstamps_i => irq_sources(0),
irq_tdc1_acam_err_i => irq_sources(1),
irq_tdc2_tstamps_i => irq_sources(2),
irq_tdc2_acam_err_i => irq_sources(3));
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Unused wishbone signals
cnx_master_in(c_SLAVE_IRQ).err <= '0';
cnx_master_in(c_SLAVE_IRQ).rty <= '0';
cnx_master_in(c_SLAVE_IRQ).int <= '0';
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- since the TDC cores work in their PLL clock domains (tdc1_clk_125m and tdc2_clk_125m)
-- and the rest works with the system clock (clk_62m5_sys) we need to synchronize
-- interrupt pulses.
cmp_sync_irq0 : gc_pulse_synchronizer
port map
(clk_in_i => tdc1_clk_125m,
clk_out_i => clk_62m5_sys,
rst_n_i => rst_n_sys,
d_p_i => tdc1_irq_tstamps,
q_p_o => irq_sources(0));
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
cmp_sync_irq1 : gc_pulse_synchronizer
port map
(clk_in_i => tdc1_clk_125m,
clk_out_i => clk_62m5_sys,
rst_n_i => rst_n_sys,
d_p_i => tdc1_irq_acam_err_p,
q_p_o => irq_sources(1));
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
cmp_sync_irq2 : gc_pulse_synchronizer
port map
(clk_in_i => tdc2_clk_125m,
clk_out_i => clk_62m5_sys,
rst_n_i => rst_n_sys,
d_p_i => tdc2_irq_tstamps,
q_p_o => irq_sources(2));
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
cmp_sync_irq3 : gc_pulse_synchronizer
port map
(clk_in_i => tdc2_clk_125m,
clk_out_i => clk_62m5_sys,
rst_n_i => rst_n_sys,
d_p_i => tdc2_irq_acam_err_p,
q_p_o => irq_sources(3));
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
tdc1_irq_tstamps <= tdc1_irq_tstamp_p or tdc1_irq_time_p;
tdc2_irq_tstamps <= tdc2_irq_tstamp_p or tdc2_irq_time_p;
irq_sources(31 downto 4) <= (others => '0');
---------------------------------------------------------------------------------------------------
-- Carrier 1-wire MASTER DS18B20 (thermometer + unique ID) --
---------------------------------------------------------------------------------------------------
cmp_carrier_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_62m5_sys,
rst_n_i => rst_n_sys,
slave_i => cnx_master_out(c_SLAVE_SVEC_1W),
slave_o => cnx_master_in(c_SLAVE_SVEC_1W),
desc_o => open,
owr_pwren_o => open,
owr_en_o => carrier_owr_en,
owr_i => carrier_owr_i);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
carrier_one_wire_b <= '0' when carrier_owr_en(0) = '1' else 'Z';
carrier_owr_i(0) <= carrier_one_wire_b;
---------------------------------------------------------------------------------------------------
-- Carrier CSR information --
---------------------------------------------------------------------------------------------------
-- Information on carrier type, mezzanine presence, pcb version
cmp_carrier_csr : carrier_csr
port map
(rst_n_i => rst_n_sys,
wb_clk_i => clk_62m5_sys,
wb_addr_i => cnx_master_out(c_SLAVE_SVEC_INFO).adr(3 downto 2),
wb_data_i => cnx_master_out(c_SLAVE_SVEC_INFO).dat,
wb_data_o => cnx_master_in(c_SLAVE_SVEC_INFO).dat,
wb_cyc_i => cnx_master_out(c_SLAVE_SVEC_INFO).cyc,
wb_sel_i => cnx_master_out(c_SLAVE_SVEC_INFO).sel,
wb_stb_i => cnx_master_out(c_SLAVE_SVEC_INFO).stb,
wb_we_i => cnx_master_out(c_SLAVE_SVEC_INFO).we,
wb_ack_o => cnx_master_in(c_SLAVE_SVEC_INFO).ack,
carrier_csr_carrier_pcb_rev_i => pcb_ver_i,
carrier_csr_carrier_reserved_i => mezz_pll_status,
carrier_csr_carrier_type_i => c_CARRIER_TYPE,
carrier_csr_stat_fmc_pres_i => '1', -- don't care, the golden BS
-- will do that for us
carrier_csr_stat_p2l_pll_lck_i => '0',
carrier_csr_stat_sys_pll_lck_i => '0',
carrier_csr_stat_ddr3_cal_done_i => '0',
carrier_csr_stat_reserved_i => x"0C0FFEE", -- for debugging
carrier_csr_ctrl_led_green_o => open,
carrier_csr_ctrl_led_red_o => open,
carrier_csr_ctrl_dac_clr_n_o => open,
carrier_csr_ctrl_reserved_o => carrier_csr_reserved_out); -- TDC mezzanine cores reset
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Unused wishbone signals
cnx_master_in(c_SLAVE_SVEC_INFO).err <= '0';
cnx_master_in(c_SLAVE_SVEC_INFO).rty <= '0';
cnx_master_in(c_SLAVE_SVEC_INFO).stall <= '0';
cnx_master_in(c_SLAVE_SVEC_INFO).int <= '0';
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
mezz_pll_status <= (0 => tdc1_pll_status_i,
1 => tdc2_pll_status_i,
others => '0');
---------------------------------------------------------------------------------------------------
-- LEDs SVEC front panel --
---------------------------------------------------------------------------------------------------
cmp_LED_ctrler : bicolor_led_ctrl
generic map
(g_NB_COLUMN => 4,
g_NB_LINE => 2,
g_CLK_FREQ => 62500000, -- in Hz
g_REFRESH_RATE => 250) -- in Hz
port map
(rst_n_i => rst_n_sys,
clk_i => clk_62m5_sys,
led_intensity_i => "1100100", -- in %
led_state_i => led_state,
column_o => fp_led_column_o,
line_o => fp_led_line_o,
line_oen_o => fp_led_line_oen_o);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- led_state bits : 15 0
-- ---------------------------------
-- fp led number : | 5 | 6 | 7 | 8 | 1 | 2 | 3 | 4 |
-- LED 1: TDC1 PLL status
led_state(7 downto 6) <= c_LED_RED when led_tdc1_pll_status = '1' else c_LED_OFF;
-- LED 2: TDC2 PLL status
led_state(5 downto 4) <= c_LED_RED when led_tdc2_pll_status = '1' else c_LED_OFF;
-- LED 3: TDC1 empty flag
led_state(3 downto 2) <= c_LED_GREEN when led_tdc1_ef = '1' else c_LED_OFF;
-- LED 4: TDC1 empty flag
led_state(1 downto 0) <= c_LED_GREEN when led_tdc2_ef = '1' else c_LED_OFF;
-- LED 5: VME access
led_state(15 downto 14) <= c_LED_GREEN when led_vme_access = '1' else c_LED_OFF;
-- LED 6: blinking using clk_62m5_sys
led_state(13 downto 12) <= c_LED_GREEN when led_clk_62m5 = '1' else c_LED_OFF;
-- LED 7: not used, permanently green
led_state(11 downto 10) <= c_LED_GREEN;
-- LED 8: not used, permanently red
led_state(9 downto 8) <= c_LED_RED;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
cmp_drive_VME_access_LED: gc_extend_pulse
generic map
(g_width => 5000000)
port map
(clk_i => clk_62m5_sys,
rst_n_i => rst_n_sys,
pulse_i => cnx_slave_in(c_MASTER_VME).cyc,
extended_o => led_vme_access);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
cmp_drive_TDC1_EF_LED: gc_extend_pulse
generic map
(g_width => 5000000)
port map
(clk_i => clk_62m5_sys,
rst_n_i => rst_n_sys,
pulse_i => tdc1_ef,
extended_o => led_tdc1_ef);
-- -- -- -- -- -- --
tdc1_ef <= not(tdc1_ef1_i) or not(tdc1_ef2_i);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
cmp_drive_TDC2_EF_LED: gc_extend_pulse
generic map
(g_width => 5000000)
port map
(clk_i => clk_62m5_sys,
rst_n_i => rst_n_sys,
pulse_i => tdc2_ef,
extended_o => led_tdc2_ef);
-- -- -- -- -- -- --
tdc2_ef <= not(tdc2_ef1_i) or not(tdc2_ef2_i);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
cmp_drive_TDC1_PLL_stat_LED: gc_extend_pulse
generic map
(g_width => 5000000)
port map
(clk_i => clk_62m5_sys,
rst_n_i => rst_n_sys,
pulse_i => tdc2_pll_status_i,
extended_o => led_tdc2_pll_status);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
cmp_drive_TDC2_PLL_stat_LED: gc_extend_pulse
generic map
(g_width => 5000000)
port map
(clk_i => clk_62m5_sys,
rst_n_i => rst_n_sys,
pulse_i => tdc1_pll_status_i,
extended_o => led_tdc1_pll_status);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
clk_62m5_sys_drive_led : process (clk_62m5_sys)
begin
if rising_edge(clk_62m5_sys) then
if(rst_n_sys = '0') then
led_clk_62m5_aux <= "01111111";
led_clk_62m5_divider <= (others => '0');
else
led_clk_62m5_divider <= led_clk_62m5_divider+ 1;
if(led_clk_62m5_divider = 0) then
led_clk_62m5_aux <= led_clk_62m5_aux(6 downto 0) & led_clk_62m5_aux(7);
end if;
end if;
end if;
end process;
-- -- -- -- --
led_clk_62m5 <= led_clk_62m5_aux(0);
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Interrupt controller
---------------------------------------------------------------------------------------
-- File : ../rtl/irq_controller.vhd
-- Author : auto-generated by wbgen2 from irq_controller.wb
-- Created : Tue Jul 23 15:22:16 2013
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE irq_controller.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 irq_controller 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_tdc1_tstamps_i : in std_logic;
irq_tdc1_acam_err_i : in std_logic;
irq_tdc2_tstamps_i : in std_logic;
irq_tdc2_acam_err_i : in std_logic);
end irq_controller;
architecture syn of irq_controller is
signal eic_idr_int : std_logic_vector(3 downto 0);
signal eic_idr_write_int : std_logic ;
signal eic_ier_int : std_logic_vector(3 downto 0);
signal eic_ier_write_int : std_logic ;
signal eic_imr_int : std_logic_vector(3 downto 0);
signal eic_isr_clear_int : std_logic_vector(3 downto 0);
signal eic_isr_status_int : std_logic_vector(3 downto 0);
signal eic_irq_ack_int : std_logic_vector(3 downto 0);
signal eic_isr_write_int : std_logic ;
signal irq_inputs_vector_int : std_logic_vector(3 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(3 downto 0) <= eic_imr_int(3 downto 0);
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(3 downto 0) <= eic_isr_status_int(3 downto 0);
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(3 downto 0) <= wrdata_reg(3 downto 0);
-- extra code for reg/fifo/mem: Interrupt enable register
eic_ier_int(3 downto 0) <= wrdata_reg(3 downto 0);
-- extra code for reg/fifo/mem: Interrupt status register
eic_isr_clear_int(3 downto 0) <= wrdata_reg(3 downto 0);
-- extra code for reg/fifo/mem: IRQ_CONTROLLER
eic_irq_controller_inst : wbgen2_eic
generic map (
g_num_interrupts => 4,
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_tdc1_tstamps_i;
irq_inputs_vector_int(1) <= irq_tdc1_acam_err_i;
irq_inputs_vector_int(2) <= irq_tdc2_tstamps_i;
irq_inputs_vector_int(3) <= irq_tdc2_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 : Wishbone slave core for IRQ controller registers
---------------------------------------------------------------------------------------
-- File : ../rtl/svec_irq_controller_regs.vhd
-- Author : auto-generated by wbgen2 from svec_irq_controller_regs.wb
-- Created : Fri Jul 5 10:18:32 2013
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE svec_irq_controller_regs.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity irq_controller_regs 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: 'Multiple interrupt' in reg: 'Multiple interrupt register'
irq_ctrl_multi_irq_o : out std_logic_vector(31 downto 0);
irq_ctrl_multi_irq_i : in std_logic_vector(31 downto 0);
irq_ctrl_multi_irq_load_o : out std_logic;
-- Port for std_logic_vector field: 'Interrupt sources' in reg: 'Interrupt sources register '
irq_ctrl_src_o : out std_logic_vector(31 downto 0);
irq_ctrl_src_i : in std_logic_vector(31 downto 0);
irq_ctrl_src_load_o : out std_logic;
-- Port for std_logic_vector field: 'Interrupt enable mask' in reg: 'Interrupt enable mask register'
irq_ctrl_en_mask_o : out std_logic_vector(31 downto 0)
);
end irq_controller_regs;
architecture syn of irq_controller_regs is
signal irq_ctrl_en_mask_int : std_logic_vector(31 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";
irq_ctrl_multi_irq_load_o <= '0';
irq_ctrl_src_load_o <= '0';
irq_ctrl_en_mask_int <= "00000000000000000000000000000000";
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
irq_ctrl_multi_irq_load_o <= '0';
irq_ctrl_src_load_o <= '0';
ack_in_progress <= '0';
else
irq_ctrl_multi_irq_load_o <= '0';
irq_ctrl_src_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
irq_ctrl_multi_irq_load_o <= '1';
end if;
rddata_reg(31 downto 0) <= irq_ctrl_multi_irq_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "01" =>
if (wb_we_i = '1') then
irq_ctrl_src_load_o <= '1';
end if;
rddata_reg(31 downto 0) <= irq_ctrl_src_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (wb_we_i = '1') then
irq_ctrl_en_mask_int <= wrdata_reg(31 downto 0);
end if;
rddata_reg(31 downto 0) <= irq_ctrl_en_mask_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;
-- Multiple interrupt
irq_ctrl_multi_irq_o <= wrdata_reg(31 downto 0);
-- Interrupt sources
irq_ctrl_src_o <= wrdata_reg(31 downto 0);
-- Interrupt enable mask
irq_ctrl_en_mask_o <= irq_ctrl_en_mask_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;
library ieee;
use ieee.STD_LOGIC_1164.all;
use WORK.wishbone_pkg.all;
use work.vme64x_pack.all;
entity xvme64x_core is
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
VME_AS_n_i : in std_logic;
VME_RST_n_i : in std_logic;
VME_WRITE_n_i : in std_logic;
VME_AM_i : in std_logic_vector(5 downto 0);
VME_DS_n_i : in std_logic_vector(1 downto 0);
VME_GA_i : in std_logic_vector(5 downto 0);
VME_BERR_o : out std_logic;
VME_DTACK_n_o : out std_logic;
VME_RETRY_n_o : out std_logic;
VME_RETRY_OE_o : out std_logic;
VME_LWORD_n_b_i : in std_logic;
VME_LWORD_n_b_o : out std_logic;
VME_ADDR_b_i : in std_logic_vector(31 downto 1);
VME_ADDR_b_o : out std_logic_vector(31 downto 1);
VME_DATA_b_i : in std_logic_vector(31 downto 0);
VME_DATA_b_o : out std_logic_vector(31 downto 0);
VME_IRQ_n_o : out std_logic_vector(6 downto 0);
VME_IACKIN_n_i : in std_logic;
VME_IACK_n_i : in std_logic;
VME_IACKOUT_n_o : out std_logic;
VME_DTACK_OE_o : out std_logic;
VME_DATA_DIR_o : out std_logic;
VME_DATA_OE_N_o : out std_logic;
VME_ADDR_DIR_o : out std_logic;
VME_ADDR_OE_N_o : out std_logic;
master_o : out t_wishbone_master_out;
master_i : in t_wishbone_master_in;
irq_i : in std_logic;
irq_ack_o : out std_logic
);
end xvme64x_core;
architecture wrapper of xvme64x_core is
component VME64xCore_Top
generic (
g_wb_data_width : integer := 32;
g_wb_addr_width : integer := 64;
g_CRAM_SIZE : integer := 1024);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
VME_AS_n_i : in std_logic;
VME_RST_n_i : in std_logic;
VME_WRITE_n_i : in std_logic;
VME_AM_i : in std_logic_vector(5 downto 0);
VME_DS_n_i : in std_logic_vector(1 downto 0);
VME_GA_i : in std_logic_vector(5 downto 0);
VME_BERR_o : out std_logic;
VME_DTACK_n_o : out std_logic;
VME_RETRY_n_o : out std_logic;
VME_LWORD_n_i : in std_logic;
VME_LWORD_n_o : out std_logic;
VME_ADDR_i : in std_logic_vector(31 downto 1);
VME_ADDR_o : out std_logic_vector(31 downto 1);
VME_DATA_i : in std_logic_vector(31 downto 0);
VME_DATA_o : out std_logic_vector(31 downto 0);
VME_IRQ_o : out std_logic_vector(6 downto 0);
VME_IACKIN_n_i : in std_logic;
VME_IACK_n_i : in std_logic;
VME_IACKOUT_n_o : out std_logic;
VME_DTACK_OE_o : out std_logic;
VME_DATA_DIR_o : out std_logic;
VME_DATA_OE_N_o : out std_logic;
VME_ADDR_DIR_o : out std_logic;
VME_ADDR_OE_N_o : out std_logic;
VME_RETRY_OE_o : out std_logic;
DAT_i : in std_logic_vector(g_wb_data_width - 1 downto 0);
DAT_o : out std_logic_vector(g_wb_data_width - 1 downto 0);
ADR_o : out std_logic_vector(g_wb_addr_width - 1 downto 0);
CYC_o : out std_logic;
ERR_i : in std_logic;
RTY_i : in std_logic;
SEL_o : out std_logic_vector(f_div8(g_wb_addr_width) - 1 downto 0);
STB_o : out std_logic;
ACK_i : in std_logic;
WE_o : out std_logic;
STALL_i : in std_logic;
INT_ack_o : out std_logic;
IRQ_i : in std_logic;
debug : out std_logic_vector(7 downto 0));
end component;
signal rst_in, rst_out : std_logic;
signal dat_out, dat_in : std_logic_vector(31 downto 0);
signal adr_out : std_logic_vector(63 downto 0);
begin -- wrapper
U_Wrapped_VME : VME64xCore_Top
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
VME_AS_n_i => VME_AS_n_i,
VME_RST_n_i => VME_RST_n_i,
VME_WRITE_n_i => VME_WRITE_n_i,
VME_AM_i => VME_AM_i,
VME_DS_n_i => VME_DS_n_i,
VME_GA_i => VME_GA_i,
VME_BERR_o => VME_BERR_o,
VME_DTACK_n_o => VME_DTACK_n_o,
VME_RETRY_n_o => VME_RETRY_n_o,
VME_RETRY_OE_o => VME_RETRY_OE_o,
VME_LWORD_n_i => VME_LWORD_n_b_i,
VME_LWORD_n_o => VME_LWORD_n_b_o,
VME_ADDR_i => VME_ADDR_b_i,
VME_ADDR_o => VME_ADDR_b_o,
VME_DATA_i => VME_DATA_b_i,
VME_DATA_o => VME_DATA_b_o,
VME_IRQ_o => VME_IRQ_n_o,
VME_IACKIN_n_i => VME_IACKIN_n_i,
VME_IACK_n_i => VME_IACK_n_i,
VME_IACKOUT_n_o => VME_IACKOUT_n_o,
VME_DTACK_OE_o => VME_DTACK_OE_o,
VME_DATA_DIR_o => VME_DATA_DIR_o,
VME_DATA_OE_N_o => VME_DATA_OE_N_o,
VME_ADDR_DIR_o => VME_ADDR_DIR_o,
VME_ADDR_OE_N_o => VME_ADDR_OE_N_o,
DAT_i => dat_in,
DAT_o => dat_out,
ADR_o => adr_out,
CYC_o => master_o.cyc,
ERR_i => master_i.err,
RTY_i => master_i.rty,
SEL_o => open,
STB_o => master_o.stb,
ACK_i => master_i.ack,
WE_o => master_o.we,
STALL_i => master_i.stall,
IRQ_i => irq_i,
INT_ack_o => irq_ack_o
);
master_o.dat <= dat_out(31 downto 0);
master_o.sel <= (others => '1');
master_o.adr <= adr_out(29 downto 0) & "00"; -- word address to byte address
dat_in <= master_i.dat;
-- VME_IRQ_n_o <= (others => '0');
end wrapper;
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