Commit bdbd4607 authored by Tristan Gingold's avatar Tristan Gingold Committed by Dimitris Lampridis

add trigout block.

Also remove timetag_core component.
parent 89dde8f4
......@@ -6,6 +6,7 @@ files = [
"fmc_adc_100Ms_csr.vhd",
"fmc_adc_100Ms_csr_wbgen2_pkg.vhd",
"fmc_adc_alt_trigin.vhd",
"fmc_adc_alt_trigout.vhd",
"fmc_adc_eic.vhd",
"offset_gain_s.vhd",
]
......
......@@ -62,6 +62,10 @@ entity fmc_adc_100Ms_core is
-- Acquisition configuration status flag
acq_cfg_ok_o : out std_logic;
-- Trigout wishbone interface
wb_trigout_slave_i : in t_wishbone_slave_in;
wb_trigout_slave_o : out t_wishbone_slave_out;
-- Events output pulses
trigger_p_o : out std_logic;
acq_start_p_o : out std_logic;
......@@ -73,6 +77,13 @@ entity fmc_adc_100Ms_core is
time_trig_i : in std_logic;
alt_time_trig_i : in std_logic;
-- WR status (for trigout).
wr_tm_link_up_i : in std_logic;
wr_tm_time_valid_i : in std_logic;
wr_enable_i : in std_logic;
current_time_i : in t_timetag;
-- FMC interface
ext_trigger_p_i : in std_logic; -- External trigger
ext_trigger_n_i : in std_logic;
......@@ -1719,4 +1730,113 @@ begin
wb_ddr_master_o.sel <= X"FF";
-- Trigout
b_trigout : block
subtype t_trigout_channels is std_logic_vector(4 downto 0);
signal trigout_fs_triggers, trigout_triggers : t_trigout_channels;
signal trigout_en : t_trigout_channels;
signal trigout_trig : std_logic;
subtype t_trigout_data_seconds is std_logic_vector(39 downto 0);
subtype t_trigout_data_coarse is std_logic_vector(67 downto 40);
subtype t_trigout_data_channels is std_logic_vector(72 downto 68);
subtype t_trigout_data is std_logic_vector(72 downto 0);
signal trigout_fifo_dout : t_trigout_data;
signal trigout_fifo_din : t_trigout_data;
signal trigout_fifo_empty : std_logic;
signal trigout_fifo_full : std_logic;
signal trigout_fifo_wr : std_logic;
signal trigout_fifo_not_empty : std_logic;
signal trigout_fifo_rd_rq : std_logic;
signal trigout_fifo_rd : std_logic;
begin
cmp_alt_trigout : entity work.alt_trigout
port map (
rst_n_i => sys_rst_n_i,
clk_i => sys_clk_i,
wb_i => wb_trigout_slave_i,
wb_o => wb_trigout_slave_o,
wr_enable_i => wr_enable_i,
wr_link_i => wr_tm_link_up_i,
wr_valid_i => wr_tm_time_valid_i,
ts_present_i => trigout_fifo_not_empty,
ch1_enable_o => trigout_en(0),
ch2_enable_o => trigout_en(1),
ch3_enable_o => trigout_en(2),
ch4_enable_o => trigout_en(3),
ext_enable_o => trigout_en(4),
ts_sec_i => trigout_fifo_dout(t_trigout_data_seconds'range),
ch1_mask_i => trigout_fifo_dout(t_trigout_data_channels'right + 0),
ch2_mask_i => trigout_fifo_dout(t_trigout_data_channels'right + 1),
ch3_mask_i => trigout_fifo_dout(t_trigout_data_channels'right + 2),
ch4_mask_i => trigout_fifo_dout(t_trigout_data_channels'right + 3),
ext_mask_i => trigout_fifo_dout(t_trigout_data_channels'right + 4),
cycles_i => trigout_fifo_dout(t_trigout_data_coarse'range),
ts_cycles_rd_o => trigout_fifo_rd_rq
);
trigout_fifo_rd <= trigout_fifo_rd_rq and not trigout_fifo_empty;
-- Triggers (from fs_clk domain).
trigout_fs_triggers <=
(0 => int_trig_d(1),
1 => int_trig_d(2),
2 => int_trig_d(3),
3 => int_trig_d(4),
4 => ext_trig_fixed_delay(ext_trig_fixed_delay'HIGH));
gen_trigout_sync : for i in trigout_triggers'range generate
cmp_trigout_sync : gc_sync_ffs
port map (
clk_i => fs_clk,
rst_n_i => '1',
data_i => trigout_fs_triggers(i),
synced_o => open,
npulse_o => open,
ppulse_o => trigout_triggers(i));
end generate;
trigout_trig <= f_reduce_or (trigout_triggers and trigout_en);
trigout_fifo_wr <= trigout_trig and not trigout_fifo_full;
cmp_trigout_fifo : generic_sync_fifo
generic map (
g_data_width => t_trigout_data'length,
g_size => 16,
g_show_ahead => FALSE,
g_with_empty => TRUE,
g_with_full => TRUE,
g_with_almost_empty => FALSE,
g_with_almost_full => FALSE,
g_with_count => FALSE,
g_almost_empty_threshold => 0,
g_almost_full_threshold => 0
)
port map(
rst_n_i => sys_rst_n_i,
clk_i => sys_clk_i,
d_i => trigout_fifo_din,
we_i => trigout_fifo_wr,
q_o => trigout_fifo_dout,
rd_i => trigout_fifo_rd,
empty_o => trigout_fifo_empty,
full_o => trigout_fifo_full,
almost_empty_o => open,
almost_full_o => open,
count_o => open
);
trigout_fifo_not_empty <= not trigout_fifo_empty;
trigout_fifo_din(t_trigout_data_seconds'range) <= current_time_i.seconds;
trigout_fifo_din(t_trigout_data_coarse'range) <= current_time_i.coarse;
trigout_fifo_din(t_trigout_data_channels'range) <= trigout_triggers;
end block b_trigout;
end rtl;
......@@ -71,6 +71,10 @@ package fmc_adc_100Ms_core_pkg is
-- Acquisition configuration status flag
acq_cfg_ok_o : out std_logic;
-- Trigout wishbone interface
wb_trigout_slave_i : in t_wishbone_slave_in;
wb_trigout_slave_o : out t_wishbone_slave_out;
-- Events output pulses
trigger_p_o : out std_logic;
acq_start_p_o : out std_logic;
......@@ -82,6 +86,13 @@ package fmc_adc_100Ms_core_pkg is
time_trig_i : in std_logic;
alt_time_trig_i : in std_logic;
-- WR status (for trigout).
wr_tm_link_up_i : in std_logic;
wr_tm_time_valid_i : in std_logic;
wr_enable_i : in std_logic;
current_time_i : in t_timetag;
-- FMC interface
ext_trigger_p_i : in std_logic; -- External trigger
ext_trigger_n_i : in std_logic;
......
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
entity alt_trigout is
port (
rst_n_i : in std_logic;
clk_i : in std_logic;
wb_i : in t_wishbone_slave_in;
wb_o : out t_wishbone_slave_out;
-- Set when WR is enabled
wr_enable_i : in std_logic;
-- WR link status
wr_link_i : in std_logic;
-- Set when WR time is valid
wr_valid_i : in std_logic;
-- Set when the timestamp fifo is not empty
ts_present_i : in std_logic;
-- Enable channel 1 trigger
ch1_enable_o : out std_logic;
-- Enable channel 2 trigger
ch2_enable_o : out std_logic;
-- Enable channel 3 trigger
ch3_enable_o : out std_logic;
-- Enable channel 4 trigger
ch4_enable_o : out std_logic;
-- Enable external trigger
ext_enable_o : out std_logic;
-- Seconds part of the timestamp
ts_sec_i : in std_logic_vector(39 downto 0);
-- Set if channel 1 triggered
ch1_mask_i : in std_logic;
-- Set if channel 2 triggered
ch2_mask_i : in std_logic;
-- Set if channel 3 triggered
ch3_mask_i : in std_logic;
-- Set if channel 4 triggered
ch4_mask_i : in std_logic;
-- Set if external trigger
ext_mask_i : in std_logic;
-- Cycles
cycles_i : in std_logic_vector(27 downto 0);
ts_cycles_rd_o : out std_logic
);
end alt_trigout;
architecture syn of alt_trigout is
signal wb_en : std_logic;
signal rd_int : std_logic;
signal wr_int : std_logic;
signal ack_int : std_logic;
signal rd_ack_int : std_logic;
signal wr_ack_int : std_logic;
signal ch1_enable_reg : std_logic;
signal ch2_enable_reg : std_logic;
signal ch3_enable_reg : std_logic;
signal ch4_enable_reg : std_logic;
signal ext_enable_reg : std_logic;
signal wr_ack_done_int : std_logic;
signal reg_rdat_int : std_logic_vector(31 downto 0);
signal rd_ack1_int : std_logic;
begin
-- WB decode signals
wb_en <= wb_i.cyc and wb_i.stb;
rd_int <= wb_en and not wb_i.we;
wr_int <= wb_en and wb_i.we;
ack_int <= rd_ack_int or wr_ack_int;
wb_o.ack <= ack_int;
wb_o.stall <= not ack_int and wb_en;
wb_o.rty <= '0';
wb_o.err <= '0';
-- Assign outputs
ch1_enable_o <= ch1_enable_reg;
ch2_enable_o <= ch2_enable_reg;
ch3_enable_o <= ch3_enable_reg;
ch4_enable_o <= ch4_enable_reg;
ext_enable_o <= ext_enable_reg;
-- Process for write requests.
process (clk_i, rst_n_i) begin
if rst_n_i = '0' then
wr_ack_int <= '0';
wr_ack_done_int <= '0';
ch1_enable_reg <= '0';
ch2_enable_reg <= '0';
ch3_enable_reg <= '0';
ch4_enable_reg <= '0';
ext_enable_reg <= '0';
elsif rising_edge(clk_i) then
if wr_int = '1' then
-- Write in progress
wr_ack_done_int <= wr_ack_int or wr_ack_done_int;
case wb_i.adr(4 downto 3) is
when "00" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- Register status
wr_ack_int <= not wr_ack_done_int;
when "1" =>
-- Register ctrl
ch1_enable_reg <= wb_i.dat(0);
ch2_enable_reg <= wb_i.dat(1);
ch3_enable_reg <= wb_i.dat(2);
ch4_enable_reg <= wb_i.dat(3);
ext_enable_reg <= wb_i.dat(8);
wr_ack_int <= not wr_ack_done_int;
when others =>
end case;
when "01" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- Register ts_mask_sec
wr_ack_int <= not wr_ack_done_int;
when "1" =>
-- Register ts_mask_sec
wr_ack_int <= not wr_ack_done_int;
when others =>
wr_ack_int <= not wr_ack_done_int;
end case;
when "10" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- Register ts_cycles
wr_ack_int <= not wr_ack_done_int;
when others =>
wr_ack_int <= not wr_ack_done_int;
end case;
when others =>
end case;
else
wr_ack_int <= '0';
wr_ack_done_int <= '0';
end if;
end if;
end process;
-- Process for registers read.
process (clk_i, rst_n_i) begin
if rst_n_i = '0' then
rd_ack1_int <= '0';
reg_rdat_int <= (others => 'X');
ts_cycles_rd_o <= '0';
elsif rising_edge(clk_i) then
ts_cycles_rd_o <= '0';
if rd_int = '1' and rd_ack1_int = '0' then
rd_ack1_int <= '1';
case wb_i.adr(4 downto 3) is
when "00" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- status
reg_rdat_int(0) <= wr_enable_i;
reg_rdat_int(1) <= wr_link_i;
reg_rdat_int(2) <= wr_valid_i;
reg_rdat_int(8) <= ts_present_i;
when "1" =>
-- ctrl
reg_rdat_int(0) <= ch1_enable_reg;
reg_rdat_int(1) <= ch2_enable_reg;
reg_rdat_int(2) <= ch3_enable_reg;
reg_rdat_int(3) <= ch4_enable_reg;
reg_rdat_int(8) <= ext_enable_reg;
when others =>
end case;
when "01" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- ts_mask_sec
reg_rdat_int(7 downto 0) <= ts_sec_i(39 downto 32);
reg_rdat_int(16) <= ch1_mask_i;
reg_rdat_int(17) <= ch2_mask_i;
reg_rdat_int(18) <= ch3_mask_i;
reg_rdat_int(19) <= ch4_mask_i;
reg_rdat_int(24) <= ext_mask_i;
when "1" =>
-- ts_mask_sec
reg_rdat_int <= ts_sec_i(31 downto 0);
when others =>
end case;
when "10" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- ts_cycles
reg_rdat_int(27 downto 0) <= cycles_i;
ts_cycles_rd_o <= '1';
when others =>
end case;
when others =>
end case;
else
rd_ack1_int <= '0';
end if;
end if;
end process;
-- Process for read requests.
process (wb_i.adr, reg_rdat_int, rd_ack1_int, rd_int) begin
-- By default ack read requests
wb_o.dat <= (others => '0');
rd_ack_int <= '1';
case wb_i.adr(4 downto 3) is
when "00" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- status
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "1" =>
-- ctrl
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when others =>
end case;
when "01" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- ts_mask_sec
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "1" =>
-- ts_mask_sec
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when others =>
end case;
when "10" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- ts_cycles
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when others =>
end case;
when others =>
end case;
end process;
end syn;
......@@ -68,6 +68,10 @@ entity fmc_adc_mezzanine is
wb_trigin_slave_i : in t_wishbone_slave_in;
wb_trigin_slave_o : out t_wishbone_slave_out;
-- Trigout wishbone interface
wb_trigout_slave_i : in t_wishbone_slave_in;
wb_trigout_slave_o : out t_wishbone_slave_out;
-- FMC interface
ext_trigger_p_i : in std_logic; -- External trigger
ext_trigger_n_i : in std_logic;
......@@ -257,6 +261,8 @@ architecture rtl of fmc_adc_mezzanine is
signal trigger_tag : t_timetag;
signal time_trigger : std_logic;
signal current_time : t_timetag;
-- Alternative time trigger
signal alt_trigin_enable_in : std_logic;
signal alt_trigin_enable_out : std_logic;
......@@ -455,6 +461,9 @@ begin
acq_cfg_ok_o => acq_cfg_ok_o,
wb_trigout_slave_i => wb_trigout_slave_i,
wb_trigout_slave_o => wb_trigout_slave_o,
trigger_p_o => trigger_p,
acq_start_p_o => acq_start_p,
acq_stop_p_o => acq_stop_p,
......@@ -464,6 +473,12 @@ begin
time_trig_i => time_trigger,
alt_time_trig_i => alt_time_trigger,
wr_tm_link_up_i => wr_tm_link_up_i,
wr_tm_time_valid_i => wr_tm_time_valid_i,
wr_enable_i => wr_enable_i,
current_time_i => current_time,
ext_trigger_p_i => ext_trigger_p_i,
ext_trigger_n_i => ext_trigger_n_i,
......@@ -571,7 +586,7 @@ begin
------------------------------------------------------------------------------
-- Time-tagging core
------------------------------------------------------------------------------
cmp_timetag_core : timetag_core
cmp_timetag_core : entity work.timetag_core
port map(
clk_i => sys_clk_i,
rst_n_i => sys_rst_n_i,
......@@ -596,6 +611,8 @@ begin
alt_trigin_tag_i => alt_trigin_tag,
alt_trigin_o => alt_time_trigger,
current_time_o => current_time,
wb_adr_i => cnx_slave_in(c_WB_SLAVE_TIMETAG).adr(6 downto 2), -- cnx_slave_in.adr is byte address
wb_dat_i => cnx_slave_in(c_WB_SLAVE_TIMETAG).dat,
wb_dat_o => cnx_slave_out(c_WB_SLAVE_TIMETAG).dat,
......
......@@ -70,6 +70,8 @@ entity timetag_core is
alt_trigin_tag_i : in t_timetag;
alt_trigin_o : out std_logic;
current_time_o : out t_timetag;
-- Wishbone interface
wb_adr_i : in std_logic_vector(4 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
......@@ -220,6 +222,8 @@ begin
current_time.coarse <= wr_tm_cycles_i when wr_enabled = '1' else time_counter.coarse;
current_time_o <= current_time;
------------------------------------------------------------------------------
-- Time trigger signal generation (stretched to two 125MHz cycles)
------------------------------------------------------------------------------
......
......@@ -38,10 +38,6 @@ use IEEE.NUMERIC_STD.all;
package timetag_core_pkg is
------------------------------------------------------------------------------
-- Constants declaration
------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- Types declaration
------------------------------------------------------------------------------
......@@ -50,38 +46,6 @@ package timetag_core_pkg is
coarse : std_logic_vector(27 downto 0);
end record t_timetag;
------------------------------------------------------------------------------
-- Components declaration
------------------------------------------------------------------------------
component timetag_core is
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
trigger_p_i : in std_logic;
acq_start_p_i : in std_logic;
acq_stop_p_i : in std_logic;
acq_end_p_i : in std_logic;
wr_enabled_i : in std_logic;
wr_tm_time_valid_i : in std_logic;
wr_tm_tai_i : in std_logic_vector(39 downto 0);
wr_tm_cycles_i : in std_logic_vector(27 downto 0);
trig_tag_o : out t_timetag;
time_trig_o : out std_logic;
alt_trigin_enable_o : out std_logic;
alt_trigin_enable_i : in std_logic;
alt_trigin_enable_wr_i : in std_logic;
alt_trigin_tag_i : in t_timetag;
alt_trigin_o : out std_logic;
wb_adr_i : in std_logic_vector(4 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 component timetag_core;
end timetag_core_pkg;
package body timetag_core_pkg is
......
memory-map:
bus: wb-32-be
name: alt_trigout
x-hdl:
busgroup: True
reg_prefix: False
children:
- reg:
name: status
description: Status register
access: ro
width: 32
children:
- field:
name: wr_enable
description: Set when WR is enabled
range: 0
- field:
name: wr_link
description: WR link status
range: 1
- field:
name: wr_valid
description: Set when WR time is valid
range: 2
- field:
name: ts_present
description: Set when the timestamp fifo is not empty
range: 8
- reg:
name: ctrl
description: Control register
access: rw
width: 32
children:
- field:
name: ch1_enable
description: Enable channel 1 trigger
range: 0
- field:
name: ch2_enable
description: Enable channel 2 trigger
range: 1
- field:
name: ch3_enable
description: Enable channel 3 trigger
range: 2
- field:
name: ch4_enable
description: Enable channel 4 trigger
range: 3
- field:
name: ext_enable
description: Enable external trigger
range: 8
- reg:
name: ts_mask_sec
description: Time (seconds) of the last event
width: 64
access: ro
children:
- field:
name: ts_sec
description: Seconds part of the timestamp
range: 39-0
- field:
name: ch1_mask
description: Set if channel 1 triggered
range: 48
- field:
name: ch2_mask
description: Set if channel 2 triggered
range: 49
- field:
name: ch3_mask
description: Set if channel 3 triggered
range: 50
- field:
name: ch4_mask
description: Set if channel 4 triggered
range: 51
- field:
name: ext_mask
description: Set if external trigger
range: 56
- reg:
name: ts_cycles
description: Cycles part of timestamp fifo.
comment: Reading this register discard the entry
width: 32
access: ro
x-hdl:
read-strobe: True
children:
- field:
name: cycles
description: Cycles
range: 27-0
`define ADDR_ALT_TRIGIN_CTRL 'h0
`define ALT_TRIGIN_CTRL_ENABLE_OFFSET 0
`define ALT_TRIGIN_CTRL_ENABLE 'h1
`define ADDR_ALT_TRIGIN_SECONDS 'h8
`define ADDR_ALT_TRIGIN_CYCLES 'h10
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