Commit 74311c60 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

hdl/rtl/fine_delay_core.vhd: direct (non-Wishbone) timestamp/trigger I/O

parent 82d882ec
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- Author : Tomasz Wlostowski -- Author : Tomasz Wlostowski
-- Company : CERN -- Company : CERN
-- Created : 2011-08-24 -- Created : 2011-08-24
-- Last update: 2012-08-09 -- Last update: 2012-11-23
-- Platform : FPGA-generic -- Platform : FPGA-generic
-- Standard : VHDL'93 -- Standard : VHDL'93
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
-- --
-- This source file is free software; you can redistribute it -- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General -- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation; -- Public License as published by the Free Software Fsoundation;
-- either version 2.1 of the License, or (at your option) any -- either version 2.1 of the License, or (at your option) any
-- later version. -- later version.
-- --
...@@ -42,6 +42,7 @@ use ieee.std_logic_1164.all; ...@@ -42,6 +42,7 @@ use ieee.std_logic_1164.all;
use ieee.numeric_std.all; use ieee.numeric_std.all;
use work.gencores_pkg.all; use work.gencores_pkg.all;
use work.genram_pkg.all;
use work.wishbone_pkg.all; use work.wishbone_pkg.all;
use work.fd_main_wbgen2_pkg.all; use work.fd_main_wbgen2_pkg.all;
use work.fine_delay_pkg.all; use work.fine_delay_pkg.all;
...@@ -55,6 +56,11 @@ entity fine_delay_core is ...@@ -55,6 +56,11 @@ entity fine_delay_core is
-- when true, some timeouts are reduced to speed up simulations -- when true, some timeouts are reduced to speed up simulations
g_simulation : boolean := false; g_simulation : boolean := false;
-- when true, the card does not operate as a Delay, but instead
-- provides direct output from the TDC and direct inputs to the channel
-- drivers.
g_with_direct_timestamp_io : boolean := false;
-- Wishbone slave settings -- Wishbone slave settings
g_interface_mode : t_wishbone_interface_mode := PIPELINED; g_interface_mode : t_wishbone_interface_mode := PIPELINED;
g_address_granularity : t_wishbone_address_granularity := WORD g_address_granularity : t_wishbone_address_granularity := WORD
...@@ -213,7 +219,21 @@ entity fine_delay_core is ...@@ -213,7 +219,21 @@ entity fine_delay_core is
wb_we_i : in std_logic; wb_we_i : in std_logic;
wb_ack_o : out std_logic; wb_ack_o : out std_logic;
wb_stall_o : out std_logic; wb_stall_o : out std_logic;
wb_irq_o : out std_logic wb_irq_o : out std_logic;
---------------------------------------------------------------------------
-- Input/Output timestamp I/O
---------------------------------------------------------------------------
tdc_seconds_o : out std_logic_vector(39 downto 0);
tdc_cycles_o : out std_logic_vector(27 downto 0);
tdc_frac_o : out std_logic_vector(11 downto 0);
tdc_valid_o : out std_logic;
outx_seconds_i : in std_logic_vector(40 * 4 - 1 downto 0) := f_gen_dummy_vec('0', 40 * 4);
outx_cycles_i : in std_logic_vector(28 * 4 - 1 downto 0) := f_gen_dummy_vec('0', 28 * 4);
outx_frac_i : in std_logic_vector(12 * 4 - 1 downto 0) := f_gen_dummy_vec('0', 12 * 4);
outx_valid_i : in std_logic_vector(3 downto 0) := x"0"
); );
end fine_delay_core; end fine_delay_core;
...@@ -276,12 +296,20 @@ architecture rtl of fine_delay_core is ...@@ -276,12 +296,20 @@ architecture rtl of fine_delay_core is
signal tsbcr_read_ack, fid_read_ack : std_logic; signal tsbcr_read_ack, fid_read_ack : std_logic;
signal irq_rbuf, irq_spll, irq_sync : std_logic; signal irq_rbuf, irq_spll, irq_sync : std_logic;
type t_delay_channel is record
idle : std_logic;
pulse0, pulse1 : std_logic;
value : std_logic_vector(9 downto 0);
load : std_logic;
load_done : std_logic;
tag : t_fd_timestamp;
end record;
signal chx_delay_idle : std_logic_vector(3 downto 0); type t_delay_channel_array is array (integer range <>) of t_delay_channel;
signal chx_delay_pulse0, chx_delay_pulse1 : std_logic_vector(3 downto 0);
signal chx_delay_value : t_dly_array(0 to 3);
signal chx_delay_load , chx_delay_load_done : std_logic_vector(3 downto 0);
signal channels : t_delay_channel_array(3 downto 0);
signal chx_delay_idle : std_logic_vector(3 downto 0);
signal cnx_out : t_wishbone_master_out_array(0 to 5); signal cnx_out : t_wishbone_master_out_array(0 to 5);
signal cnx_in : t_wishbone_master_in_array(0 to 5); signal cnx_in : t_wishbone_master_in_array(0 to 5);
...@@ -517,6 +545,28 @@ begin -- rtl ...@@ -517,6 +545,28 @@ begin -- rtl
rbuf_mux_valid_masked <= rbuf_mux_valid and regs_fromwb.tsbcr_chan_mask_o; rbuf_mux_valid_masked <= rbuf_mux_valid and regs_fromwb.tsbcr_chan_mask_o;
gen_with_direct_io_tdc : if(g_with_direct_timestamp_io) generate
U_Sync_TDC_Valid_Out : gc_pulse_synchronizer
port map (
clk_in_i => clk_ref_0_i,
clk_out_i => clk_sys_i,
rst_n_i => rst_n_sys,
d_p_i => tag_valid,
q_p_o => tdc_valid_o);
process(clk_ref_0_i)
begin
if rising_edge(clk_ref_0_i) then
if(tag_valid = '1') then
tdc_cycles_o <= tag_coarse;
tdc_seconds_o <= tag_utc;
tdc_frac_o <= tag_frac;
end if;
end if;
end process;
end generate gen_with_direct_io_tdc;
gen_pack_rbuf_mux : for i in 0 to 4 generate gen_pack_rbuf_mux : for i in 0 to 4 generate
rbuf_mux_d(c_TIMESTAMP_TOTAL_BITS * (i+1) -1 downto c_TIMESTAMP_TOTAL_BITS * i) <= to_stdLogicVector(rbuf_mux_ts(i)); rbuf_mux_d(c_TIMESTAMP_TOTAL_BITS * (i+1) -1 downto c_TIMESTAMP_TOTAL_BITS * i) <= to_stdLogicVector(rbuf_mux_ts(i));
end generate gen_pack_rbuf_mux; end generate gen_pack_rbuf_mux;
...@@ -572,6 +622,37 @@ begin -- rtl ...@@ -572,6 +622,37 @@ begin -- rtl
gen_cal_pulse <= cal_pulse_mask and regs_fromwb.calr_psel_o; gen_cal_pulse <= cal_pulse_mask and regs_fromwb.calr_psel_o;
gen_output_channels : for i in 0 to 3 generate gen_output_channels : for i in 0 to 3 generate
gen_with_direct_io : if g_with_direct_timestamp_io generate
U_Sync_Valid_Pulse : gc_pulse_synchronizer
port map (
clk_in_i => clk_sys_i,
clk_out_i => clk_ref_0_i,
rst_n_i => rst_n_ref,
d_p_i => outx_valid_i(i),
q_p_o => channels(i).tag.valid);
process(clk_sys_i)
begin
if rising_edge(Clk_sys_i) then
if(outx_valid_i(i) = '1')then
channels(i).tag.u <= outx_seconds_i(40 * (i+1) - 1 downto 40 * i);
channels(i).tag.c <= outx_cycles_i(28 * (i+1) - 1 downto 28 * i);
channels(i).tag.f <= outx_frac_i(12 * (i+1) -1 downto 12 * i);
end if;
end if;
end process;
end generate gen_with_direct_io;
gen_without_direct_io : if not g_with_direct_timestamp_io generate
channels(i).tag.valid <= tag_valid_masked;
channels(i).tag.u <= tag_utc;
channels(i).tag.c <= tag_coarse;
channels(i).tag.f <= tag_frac;
end generate gen_without_direct_io;
U_Output_ChannelX : fd_delay_channel_driver U_Output_ChannelX : fd_delay_channel_driver
generic map ( generic map (
g_index => i) g_index => i)
...@@ -584,43 +665,53 @@ begin -- rtl ...@@ -584,43 +665,53 @@ begin -- rtl
csync_utc_i => master_csync_utc, csync_utc_i => master_csync_utc,
csync_coarse_i => master_csync_coarse, csync_coarse_i => master_csync_coarse,
gen_cal_i => gen_cal_pulse(i), gen_cal_i => gen_cal_pulse(i),
tag_valid_i => tag_valid_masked, tag_valid_i => channels(i).tag.valid,
tag_utc_i => tag_utc, tag_utc_i => channels(i).tag.u,
tag_coarse_i => tag_coarse, tag_coarse_i => channels(i).tag.c,
tag_frac_i => tag_frac, tag_frac_i => channels(i).tag.f,
pstart_valid_o => rbuf_mux_valid(i+1), pstart_valid_o => rbuf_mux_valid(i+1),
pstart_utc_o => rbuf_mux_ts(i+1).u, pstart_utc_o => rbuf_mux_ts(i+1).u,
pstart_coarse_o => rbuf_mux_ts(i+1).c, pstart_coarse_o => rbuf_mux_ts(i+1).c,
pstart_frac_o => rbuf_mux_ts(i+1).f, pstart_frac_o => rbuf_mux_ts(i+1).f,
delay_pulse0_o => chx_delay_pulse0(i), delay_pulse0_o => channels(i).pulse0,
delay_pulse1_o => chx_delay_pulse1(i), delay_pulse1_o => channels(i).pulse1,
delay_value_o => chx_delay_value(i), delay_value_o => channels(i).value,
delay_load_o => chx_delay_load(i), delay_load_o => channels(i).load,
delay_idle_o => chx_delay_idle(i), delay_idle_o => channels(i).idle,
delay_load_done_i => chx_delay_load_done(i), delay_load_done_i => channels(i).load_done,
wb_i => cnx_out(i+1), wb_i => cnx_out(i+1),
wb_o => cnx_in(i+1)); wb_o => cnx_in(i+1));
chx_delay_idle(i) <= channels(i).idle;
U_DDR_Output : fd_ddr_driver U_DDR_Output : fd_ddr_driver
port map ( port map (
clk0_i => clk_ref_0_i, clk0_i => clk_ref_0_i,
clk1_i => clk_ref_180_i, clk1_i => clk_ref_180_i,
d0_i => chx_delay_pulse0(i), d0_i => channels(i).pulse0,
d1_i => chx_delay_pulse1(i), d1_i => channels(i).pulse1,
q_o => delay_pulse_o(i)); q_o => delay_pulse_o(i));
end generate gen_output_channels; end generate gen_output_channels;
U_Delay_Line_Arbiter : fd_delay_line_arbiter U_Delay_Line_Arbiter : fd_delay_line_arbiter
port map ( port map (
clk_ref_i => clk_ref_0_i, clk_ref_i => clk_ref_0_i,
rst_n_i => rst_n_ref, rst_n_i => rst_n_ref,
load_i => chx_delay_load, load_i(0) => channels(0).load,
done_o => chx_delay_load_done, load_i(1) => channels(1).load,
delay_val0_i => f_reverse_bits(chx_delay_value(0)), load_i(2) => channels(2).load,
delay_val1_i => chx_delay_value(1), load_i(3) => channels(3).load,
delay_val2_i => f_reverse_bits(chx_delay_value(2)),
delay_val3_i => chx_delay_value(3), done_o(0) => channels(0).load_done,
done_o(1) => channels(1).load_done,
done_o(2) => channels(2).load_done,
done_o(3) => channels(3).load_done,
delay_val0_i => f_reverse_bits(channels(0).value),
delay_val1_i => channels(1).value,
delay_val2_i => f_reverse_bits(channels(2).value),
delay_val3_i => channels(3).value,
delay_val_o => delay_val_o, delay_val_o => delay_val_o,
delay_len_o => delay_len_o); delay_len_o => delay_len_o);
...@@ -643,6 +734,8 @@ begin -- rtl ...@@ -643,6 +734,8 @@ begin -- rtl
dbg_tag_out_o => dbg_tag_out dbg_tag_out_o => dbg_tag_out
); );
tag_valid_masked <= tag_valid when unsigned(not chx_delay_idle) = 0 else '0'; tag_valid_masked <= tag_valid when unsigned(not chx_delay_idle) = 0 else '0';
U_LED_Driver : gc_extend_pulse U_LED_Driver : gc_extend_pulse
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- Author : Tomasz Wlostowski -- Author : Tomasz Wlostowski
-- Company : CERN -- Company : CERN
-- Created : 2011-08-24 -- Created : 2011-08-24
-- Last update: 2012-08-09 -- Last update: 2012-11-22
-- Platform : FPGA-generic -- Platform : FPGA-generic
-- Standard : VHDL'93 -- Standard : VHDL'93
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
...@@ -44,7 +44,7 @@ use ieee.numeric_std.all; ...@@ -44,7 +44,7 @@ use ieee.numeric_std.all;
use work.wishbone_pkg.all; use work.wishbone_pkg.all;
use work.fd_main_wbgen2_pkg.all; use work.fd_main_wbgen2_pkg.all;
use work.fd_channel_wbgen2_pkg.all; use work.fd_channel_wbgen2_pkg.all;
use work.genram_pkg.all;
package fine_delay_pkg is package fine_delay_pkg is
...@@ -377,10 +377,11 @@ package fine_delay_pkg is ...@@ -377,10 +377,11 @@ package fine_delay_pkg is
component fine_delay_core component fine_delay_core
generic ( generic (
g_with_wr_core : boolean; g_with_wr_core : boolean := true;
g_simulation : boolean; g_simulation : boolean := false;
g_interface_mode : t_wishbone_interface_mode; g_with_direct_timestamp_io : boolean := false;
g_address_granularity : t_wishbone_address_granularity); g_interface_mode : t_wishbone_interface_mode;
g_address_granularity : t_wishbone_address_granularity);
port ( port (
clk_ref_0_i : in std_logic; clk_ref_0_i : in std_logic;
clk_ref_180_i : in std_logic; clk_ref_180_i : in std_logic;
...@@ -443,7 +444,15 @@ package fine_delay_pkg is ...@@ -443,7 +444,15 @@ package fine_delay_pkg is
wb_we_i : in std_logic; wb_we_i : in std_logic;
wb_ack_o : out std_logic; wb_ack_o : out std_logic;
wb_stall_o : out std_logic; wb_stall_o : out std_logic;
wb_irq_o : out std_logic); wb_irq_o : out std_logic;
tdc_seconds_o : out std_logic_vector(39 downto 0);
tdc_cycles_o : out std_logic_vector(27 downto 0);
tdc_frac_o : out std_logic_vector(11 downto 0);
tdc_valid_o : out std_logic;
outx_seconds_i : in std_logic_vector(40 * 4 - 1 downto 0) := f_gen_dummy_vec('0', 40 * 4);
outx_cycles_i : in std_logic_vector(28 * 4 - 1 downto 0) := f_gen_dummy_vec('0', 28 * 4);
outx_frac_i : in std_logic_vector(12 * 4 - 1 downto 0) := f_gen_dummy_vec('0', 12 * 4);
outx_valid_i : in std_logic_vector(3 downto 0) := x"0");
end component; end component;
function f_to_internal_time ( function f_to_internal_time (
......
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