Commit 6fa0c8c7 authored by Evangelia Gousiou's avatar Evangelia Gousiou

Merge branch 'dlamprid-dev' into feature/convention

parents 04df2ba6 e66d3b45
...@@ -19,3 +19,4 @@ ...@@ -19,3 +19,4 @@
[submodule "hdl/ip_cores/svec"] [submodule "hdl/ip_cores/svec"]
path = hdl/ip_cores/svec path = hdl/ip_cores/svec
url = https://ohwr.org/project/svec.git url = https://ohwr.org/project/svec.git
...@@ -22,6 +22,8 @@ files = [ ...@@ -22,6 +22,8 @@ files = [
"fmc_tdc_direct_readout_slave_pkg.vhd", "fmc_tdc_direct_readout_slave_pkg.vhd",
"fmc_tdc_wrapper.vhd", "fmc_tdc_wrapper.vhd",
"timestamp_fifo.vhd", "timestamp_fifo.vhd",
"channel_regs.vhd",
"channel_regs_wbgen2_pkg.vhd",
"timestamp_fifo_wb.vhd", "timestamp_fifo_wb.vhd",
"timestamp_fifo_wbgen2_pkg.vhd", "timestamp_fifo_wbgen2_pkg.vhd",
"timestamp_convert_filter.vhd", "timestamp_convert_filter.vhd",
......
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Channel registers
---------------------------------------------------------------------------------------
-- File : channel_regs.vhd
-- Author : auto-generated by wbgen2 from wbgen/channel_regs.wb
-- Created : Thu Sep 26 16:43:02 2019
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/channel_regs.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.wishbone_pkg.all;
use work.ch_reg_wbgen2_pkg.all;
entity channel_regs is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
int_o : out std_logic;
regs_i : in t_ch_reg_in_registers;
regs_o : out t_ch_reg_out_registers
);
end channel_regs;
architecture syn of channel_regs is
signal ch_reg_offset1_int : std_logic_vector(31 downto 0);
signal ch_reg_offset2_int : std_logic_vector(31 downto 0);
signal ch_reg_offset3_int : std_logic_vector(31 downto 0);
signal ch_reg_csr_delta_read_dly0 : std_logic ;
signal ch_reg_csr_delta_read_int : std_logic ;
signal ch_reg_csr_rst_seq_dly0 : std_logic ;
signal ch_reg_csr_rst_seq_int : std_logic ;
signal ch_reg_csr_delta_ref_int : std_logic_vector(2 downto 0);
signal ch_reg_csr_raw_mode_int : std_logic ;
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(2 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments
wrdata_reg <= slave_i.dat;
--
-- 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";
ch_reg_offset1_int <= "00000000000000000000000000000000";
ch_reg_offset2_int <= "00000000000000000000000000000000";
ch_reg_offset3_int <= "00000000000000000000000000000000";
ch_reg_csr_delta_read_int <= '0';
ch_reg_csr_rst_seq_int <= '0';
ch_reg_csr_delta_ref_int <= "000";
ch_reg_csr_raw_mode_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
ch_reg_csr_delta_read_int <= '0';
ch_reg_csr_rst_seq_int <= '0';
ack_in_progress <= '0';
else
end if;
else
if ((slave_i.cyc = '1') and (slave_i.stb = '1')) then
case rwaddr_reg(2 downto 0) is
when "000" =>
if (slave_i.we = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.delta1_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "001" =>
if (slave_i.we = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.delta2_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "010" =>
if (slave_i.we = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.delta3_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "011" =>
if (slave_i.we = '1') then
ch_reg_offset1_int <= wrdata_reg(31 downto 0);
end if;
rddata_reg(31 downto 0) <= ch_reg_offset1_int;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "100" =>
if (slave_i.we = '1') then
ch_reg_offset2_int <= wrdata_reg(31 downto 0);
end if;
rddata_reg(31 downto 0) <= ch_reg_offset2_int;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "101" =>
if (slave_i.we = '1') then
ch_reg_offset3_int <= wrdata_reg(31 downto 0);
end if;
rddata_reg(31 downto 0) <= ch_reg_offset3_int;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "110" =>
if (slave_i.we = '1') then
ch_reg_csr_delta_read_int <= wrdata_reg(1);
ch_reg_csr_rst_seq_int <= wrdata_reg(2);
ch_reg_csr_delta_ref_int <= wrdata_reg(5 downto 3);
ch_reg_csr_raw_mode_int <= wrdata_reg(6);
end if;
rddata_reg(0) <= regs_i.csr_delta_ready_i;
rddata_reg(1) <= '0';
rddata_reg(2) <= '0';
rddata_reg(5 downto 3) <= ch_reg_csr_delta_ref_int;
rddata_reg(6) <= ch_reg_csr_raw_mode_int;
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(2) <= '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
slave_o.dat <= rddata_reg;
-- Delta Timestamp Word 1 (TAI cycles, signed)
-- Delta Timestamp Word 2 (8ns ticks, unsigned)
-- Delta Timestamp Word 3 (fractional part, unsigned)
-- Channel Offset Word 1 (TAI cycles, signed)
regs_o.offset1_o <= ch_reg_offset1_int;
-- Channel Offset Word 2 (8ns ticks, unsigned)
regs_o.offset2_o <= ch_reg_offset2_int;
-- Channel Offset Word 3 (fractional part, unsigned)
regs_o.offset3_o <= ch_reg_offset3_int;
-- Delta Timestamp Ready
-- Read Delta Timestamp
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
ch_reg_csr_delta_read_dly0 <= '0';
regs_o.csr_delta_read_o <= '0';
elsif rising_edge(clk_sys_i) then
ch_reg_csr_delta_read_dly0 <= ch_reg_csr_delta_read_int;
regs_o.csr_delta_read_o <= ch_reg_csr_delta_read_int and (not ch_reg_csr_delta_read_dly0);
end if;
end process;
-- Reset Sequence Counter
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
ch_reg_csr_rst_seq_dly0 <= '0';
regs_o.csr_rst_seq_o <= '0';
elsif rising_edge(clk_sys_i) then
ch_reg_csr_rst_seq_dly0 <= ch_reg_csr_rst_seq_int;
regs_o.csr_rst_seq_o <= ch_reg_csr_rst_seq_int and (not ch_reg_csr_rst_seq_dly0);
end if;
end process;
-- Delta Timestamp Reference Channel
regs_o.csr_delta_ref_o <= ch_reg_csr_delta_ref_int;
-- Raw readout mode
regs_o.csr_raw_mode_o <= ch_reg_csr_raw_mode_int;
rwaddr_reg <= slave_i.adr(4 downto 2);
slave_o.stall <= (not ack_sreg(0)) and (slave_i.stb and slave_i.cyc);
slave_o.err <= '0';
slave_o.rty <= '0';
-- ACK signal generation. Just pass the LSB of ACK counter.
slave_o.ack <= ack_sreg(0);
end syn;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Channel registers
---------------------------------------------------------------------------------------
-- File : channel_regs_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from wbgen/channel_regs.wb
-- Created : Thu Sep 26 16:43:02 2019
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/channel_regs.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.wishbone_pkg.all;
package ch_reg_wbgen2_pkg is
-- Input registers (user design -> WB slave)
type t_ch_reg_in_registers is record
delta1_i : std_logic_vector(31 downto 0);
delta2_i : std_logic_vector(31 downto 0);
delta3_i : std_logic_vector(31 downto 0);
csr_delta_ready_i : std_logic;
end record;
constant c_ch_reg_in_registers_init_value: t_ch_reg_in_registers := (
delta1_i => (others => '0'),
delta2_i => (others => '0'),
delta3_i => (others => '0'),
csr_delta_ready_i => '0'
);
-- Output registers (WB slave -> user design)
type t_ch_reg_out_registers is record
offset1_o : std_logic_vector(31 downto 0);
offset2_o : std_logic_vector(31 downto 0);
offset3_o : std_logic_vector(31 downto 0);
csr_delta_read_o : std_logic;
csr_rst_seq_o : std_logic;
csr_delta_ref_o : std_logic_vector(2 downto 0);
csr_raw_mode_o : std_logic;
end record;
constant c_ch_reg_out_registers_init_value: t_ch_reg_out_registers := (
offset1_o => (others => '0'),
offset2_o => (others => '0'),
offset3_o => (others => '0'),
csr_delta_read_o => '0',
csr_rst_seq_o => '0',
csr_delta_ref_o => (others => '0'),
csr_raw_mode_o => '0'
);
function "or" (left, right: t_ch_reg_in_registers) return t_ch_reg_in_registers;
function f_x_to_zero (x:std_logic) return std_logic;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector;
component channel_regs is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
int_o : out std_logic;
regs_i : in t_ch_reg_in_registers;
regs_o : out t_ch_reg_out_registers
);
end component;
end package;
package body ch_reg_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
if x = '1' then
return '1';
else
return '0';
end if;
end function;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
begin
for i in 0 to x'length-1 loop
if(x(i) = '1') then
tmp(i):= '1';
else
tmp(i):= '0';
end if;
end loop;
return tmp;
end function;
function "or" (left, right: t_ch_reg_in_registers) return t_ch_reg_in_registers is
variable tmp: t_ch_reg_in_registers;
begin
tmp.delta1_i := f_x_to_zero(left.delta1_i) or f_x_to_zero(right.delta1_i);
tmp.delta2_i := f_x_to_zero(left.delta2_i) or f_x_to_zero(right.delta2_i);
tmp.delta3_i := f_x_to_zero(left.delta3_i) or f_x_to_zero(right.delta3_i);
tmp.csr_delta_ready_i := f_x_to_zero(left.csr_delta_ready_i) or f_x_to_zero(right.csr_delta_ready_i);
return tmp;
end function;
end package body;
...@@ -424,9 +424,6 @@ begin ...@@ -424,9 +424,6 @@ begin
if acam_ef1_i ='0' then if acam_ef1_i ='0' then
nxt_engine_st <= GET_STAMP1; nxt_engine_st <= GET_STAMP1;
elsif acam_ef2_i ='0' then
nxt_engine_st <= GET_STAMP2;
else else
nxt_engine_st <= ACTIVE; nxt_engine_st <= ACTIVE;
end if; end if;
......
...@@ -150,12 +150,19 @@ use work.genram_pkg.all; ...@@ -150,12 +150,19 @@ use work.genram_pkg.all;
--================================================================================================= --=================================================================================================
entity fmc_tdc_core is entity fmc_tdc_core is
generic generic
(g_span : integer := 32; -- address span in bus interfaces (g_span : integer := 32; -- address span in bus interfaces
g_width : integer := 32; -- data width in bus interfaces g_width : integer := 32; -- data width in bus interfaces
g_simulation : boolean := false; g_simulation : boolean := false;
g_with_dma_readout : boolean := false; -- Enable filtering based on pulse width. This will have the following effects:
g_with_fifo_readout : boolean := false); -- this generic is set to TRUE -- * Suppress theforwarding of negative slope timestamps.
-- when instantiated in a test-bench -- * Delay the forwarding of timestamps until after the falling edge timestamp.
-- Once enabled, all pulses wider than 1 second or narrower than
-- g_pulse_width_filter_min will be dropped.
g_pulse_width_filter : boolean := true;
-- In 8ns ticks.
g_pulse_width_filter_min : natural := 12;
g_with_dma_readout : boolean := false;
g_with_fifo_readout : boolean := false);
port port
( (
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
...@@ -219,10 +226,6 @@ entity fmc_tdc_core is ...@@ -219,10 +226,6 @@ entity fmc_tdc_core is
timestamp_valid_o : out std_logic_vector(4 downto 0); timestamp_valid_o : out std_logic_vector(4 downto 0);
timestamp_ready_i : in std_logic_vector(4 downto 0); timestamp_ready_i : in std_logic_vector(4 downto 0);
-- direct interface, for compatibility with LIST/WRTD
direct_timestamp_o : out std_logic_vector(127 downto 0);
direct_timestamp_valid_o : out std_logic;
channel_enable_o : out std_logic_vector(4 downto 0); channel_enable_o : out std_logic_vector(4 downto 0);
irq_threshold_o : out std_logic_vector(9 downto 0); irq_threshold_o : out std_logic_vector(9 downto 0);
irq_timeout_o : out std_logic_vector(9 downto 0); irq_timeout_o : out std_logic_vector(9 downto 0);
...@@ -539,6 +542,9 @@ begin ...@@ -539,6 +542,9 @@ begin
U_FilterAndConvert : entity work.timestamp_convert_filter U_FilterAndConvert : entity work.timestamp_convert_filter
generic map (
g_pulse_width_filter => g_pulse_width_filter,
g_pulse_width_filter_min => g_pulse_width_filter_min)
port map ( port map (
clk_tdc_i => clk_tdc_i, clk_tdc_i => clk_tdc_i,
rst_tdc_n_i => rst_tdc_n_i, rst_tdc_n_i => rst_tdc_n_i,
...@@ -553,9 +559,7 @@ begin ...@@ -553,9 +559,7 @@ begin
ts_ready_i => final_timestamp_ready, ts_ready_i => final_timestamp_ready,
ts_offset_i => ts_offset_i, ts_offset_i => ts_offset_i,
reset_seq_i => reset_seq_i, reset_seq_i => reset_seq_i,
raw_enable_i => raw_enable_i, raw_enable_i => raw_enable_i
direct_timestamp_o => direct_timestamp_o,
direct_timestamp_valid_o => direct_timestamp_valid_o
); );
......
...@@ -11,14 +11,11 @@ use work.dr_wbgen2_pkg.all; ...@@ -11,14 +11,11 @@ use work.dr_wbgen2_pkg.all;
entity fmc_tdc_direct_readout is entity fmc_tdc_direct_readout is
port port
( (
clk_tdc_i : in std_logic;
rst_tdc_n_i : in std_logic;
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
rst_sys_n_i : in std_logic; rst_sys_n_i : in std_logic;
direct_timestamp_i : in std_logic_vector(127 downto 0); timestamp_i : in t_tdc_timestamp_array(4 downto 0);
direct_timestamp_wr_i : in std_logic; timestamp_valid_i : in std_logic_vector(4 downto 0);
direct_slave_i : in t_wishbone_slave_in; direct_slave_i : in t_wishbone_slave_in;
direct_slave_o : out t_wishbone_slave_out direct_slave_o : out t_wishbone_slave_out
...@@ -29,24 +26,6 @@ end entity; ...@@ -29,24 +26,6 @@ end entity;
architecture rtl of fmc_tdc_direct_readout is architecture rtl of fmc_tdc_direct_readout is
component fmc_tdc_direct_readout_wb_slave is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(2 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
clk_tdc_i : in std_logic;
regs_i : in t_dr_in_registers;
regs_o : out t_dr_out_registers);
end component fmc_tdc_direct_readout_wb_slave;
constant c_num_channels : integer := 5; constant c_num_channels : integer := 5;
type t_channel_state is record type t_channel_state is record
...@@ -65,24 +44,33 @@ architecture rtl of fmc_tdc_direct_readout is ...@@ -65,24 +44,33 @@ architecture rtl of fmc_tdc_direct_readout is
signal regs_out : t_dr_out_registers; signal regs_out : t_dr_out_registers;
signal regs_in : t_dr_in_registers; signal regs_in : t_dr_in_registers;
signal ts_cycles : std_logic_vector(31 downto 0);
signal ts_seconds : std_logic_vector(31 downto 0);
signal ts_bins : std_logic_vector(17 downto 0);
signal ts_edge : std_logic;
signal ts_channel : std_logic_vector(2 downto 0);
signal direct_slave_out: t_wishbone_slave_out; signal direct_slave_out: t_wishbone_slave_out;
begin signal channel_select : integer := 0;
ts_channel <= direct_timestamp_i(98 downto 96); begin
ts_edge <= direct_timestamp_i(100);
ts_seconds <= direct_timestamp_i(95 downto 64);
ts_cycles <= direct_timestamp_i(63 downto 32);
ts_bins <= direct_timestamp_i(17 downto 0);
U_WB_Slave : fmc_tdc_direct_readout_wb_slave p_channel_select: process (timestamp_valid_i) is
begin
case timestamp_valid_i is
when "00001" => channel_select <= 0;
when "00010" => channel_select <= 1;
when "00100" => channel_select <= 2;
when "01000" => channel_select <= 3;
when "10000" => channel_select <= 4;
when others => channel_select <= 0;
end case;
end process p_channel_select;
regs_in.fifo_cycles_i <= timestamp_i(channel_select).coarse;
regs_in.fifo_edge_i <= timestamp_i(channel_select).slope;
regs_in.fifo_seconds_i <= timestamp_i(channel_select).tai;
regs_in.fifo_channel_i <= '0' & timestamp_i(channel_select).channel;
regs_in.fifo_bins_i <= "000000" & timestamp_i(channel_select).frac;
regs_in.fifo_wr_req_i <= f_to_std_logic(fifo_wr(channel_select) = '1' and
regs_out.fifo_wr_full_o = '0');
U_WB_Slave : entity work.fmc_tdc_direct_readout_wb_slave
port map ( port map (
rst_n_i => rst_sys_n_i, rst_n_i => rst_sys_n_i,
clk_sys_i => clk_sys_i, clk_sys_i => clk_sys_i,
...@@ -95,7 +83,6 @@ begin ...@@ -95,7 +83,6 @@ begin
wb_we_i => direct_slave_i.we, wb_we_i => direct_slave_i.we,
wb_ack_o => direct_slave_out.ack, wb_ack_o => direct_slave_out.ack,
wb_stall_o => direct_slave_out.stall, wb_stall_o => direct_slave_out.stall,
clk_tdc_i => clk_tdc_i,
regs_i => regs_in, regs_i => regs_in,
regs_o => regs_out); regs_o => regs_out);
...@@ -104,26 +91,17 @@ begin ...@@ -104,26 +91,17 @@ begin
direct_slave_o <= direct_slave_out; direct_slave_o <= direct_slave_out;
regs_in.fifo_cycles_i <= ts_cycles;
regs_in.fifo_edge_i <= '1';
regs_in.fifo_seconds_i <= ts_seconds;
regs_in.fifo_channel_i <= '0'&ts_channel;
regs_in.fifo_bins_i <= ts_bins;
regs_in.fifo_wr_req_i <= f_to_std_logic(fifo_wr /= (fifo_wr'range => '0')
and regs_out.fifo_wr_full_o = '0');
gen_channels : for i in 0 to c_num_channels-1 generate gen_channels : for i in 0 to c_num_channels-1 generate
c(i).enable <= regs_out.chan_enable_o(i); c(i).enable <= regs_out.chan_enable_o(i);
fifo_wr(i) <= f_to_std_logic(unsigned(ts_channel) = i fifo_wr(i) <= f_to_std_logic(timestamp_valid_i(i) = '1' and
and ts_edge = '1' c(i).ready = '1');
and direct_timestamp_wr_i = '1'
and c(i).ready = '1');
p_dead_time : process (clk_tdc_i) p_dead_time : process (clk_sys_i)
begin begin
if rising_edge(clk_tdc_i) then if rising_edge(clk_sys_i) then
if rst_tdc_n_i = '0' or c(i).enable = '0' then if rst_sys_n_i = '0' or c(i).enable = '0' then
c(i).timeout <= (others => '0'); c(i).timeout <= (others => '0');
c(i).ready <= '0'; c(i).ready <= '0';
else else
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
-- File : fmc_tdc_direct_readout_slave.vhd -- File : fmc_tdc_direct_readout_slave.vhd
-- Author : auto-generated by wbgen2 from fmc_tdc_direct_readout_slave.wb -- Author : auto-generated by wbgen2 from fmc_tdc_direct_readout_slave.wb
-- Created : Thu May 22 14:05:35 2014 -- Created : Thu Sep 26 16:03:31 2019
-- Standard : VHDL'87 -- Standard : VHDL'87
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fmc_tdc_direct_readout_slave.wb -- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fmc_tdc_direct_readout_slave.wb
...@@ -30,8 +30,9 @@ entity fmc_tdc_direct_readout_wb_slave is ...@@ -30,8 +30,9 @@ entity fmc_tdc_direct_readout_wb_slave is
wb_stb_i : in std_logic; wb_stb_i : in std_logic;
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_err_o : out std_logic;
wb_rty_o : out std_logic;
wb_stall_o : out std_logic; wb_stall_o : out std_logic;
clk_tdc_i : in std_logic;
regs_i : in t_dr_in_registers; regs_i : in t_dr_in_registers;
regs_o : out t_dr_out_registers regs_o : out t_dr_out_registers
); );
...@@ -61,13 +62,8 @@ signal allones : std_logic_vector(31 downto 0); ...@@ -61,13 +62,8 @@ signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0); signal allzeros : std_logic_vector(31 downto 0);
begin begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards. -- Some internal signals assignments
wrdata_reg <= wb_dat_i; 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. -- Main register bank access process.
process (clk_sys_i, rst_n_i) process (clk_sys_i, rst_n_i)
...@@ -223,7 +219,7 @@ begin ...@@ -223,7 +219,7 @@ begin
dr_fifo_in_int(82) <= regs_i.fifo_edge_i; dr_fifo_in_int(82) <= regs_i.fifo_edge_i;
dr_fifo_in_int(86 downto 83) <= regs_i.fifo_channel_i; dr_fifo_in_int(86 downto 83) <= regs_i.fifo_channel_i;
dr_fifo_rst_n <= rst_n_i; dr_fifo_rst_n <= rst_n_i;
dr_fifo_INST : wbgen2_fifo_async dr_fifo_INST : wbgen2_fifo_sync
generic map ( generic map (
g_size => 256, g_size => 256,
g_width => 87, g_width => 87,
...@@ -239,8 +235,7 @@ begin ...@@ -239,8 +235,7 @@ begin
rd_usedw_o => dr_fifo_usedw_int, rd_usedw_o => dr_fifo_usedw_int,
rd_req_i => dr_fifo_rdreq_int, rd_req_i => dr_fifo_rdreq_int,
rst_n_i => dr_fifo_rst_n, rst_n_i => dr_fifo_rst_n,
wr_clk_i => clk_tdc_i, clk_i => clk_sys_i,
rd_clk_i => clk_sys_i,
wr_data_i => dr_fifo_in_int, wr_data_i => dr_fifo_in_int,
rd_data_o => dr_fifo_out_int rd_data_o => dr_fifo_out_int
); );
...@@ -264,6 +259,8 @@ begin ...@@ -264,6 +259,8 @@ begin
-- extra code for reg/fifo/mem: FIFO 'Readout FIFO' data output register 2 -- extra code for reg/fifo/mem: FIFO 'Readout FIFO' data output register 2
rwaddr_reg <= wb_adr_i; rwaddr_reg <= wb_adr_i;
wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i); wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i);
wb_err_o <= '0';
wb_rty_o <= '0';
-- ACK signal generation. Just pass the LSB of ACK counter. -- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0); wb_ack_o <= ack_sreg(0);
end syn; end syn;
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
-- Title : Wishbone slave core for TDC Direct Readout WB Slave -- Title : Wishbone slave core for TDC Direct Readout WB Slave
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
-- File : fmc_tdc_direct_readout_slave_pkg.vhd -- File : fmc_tdc_direct_readout_slave_pkg.vhd
-- Author : auto-generated by wbgen2 from fmc_tdc_direct_readout_slave.wb -- Author : auto-generated by wbgen2 from wbgen/fmc_tdc_direct_readout_slave.wb
-- Created : Thu May 22 14:05:35 2014 -- Created : Thu Sep 26 16:03:31 2019
-- Standard : VHDL'87 -- Standard : VHDL'87
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fmc_tdc_direct_readout_slave.wb -- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/fmc_tdc_direct_readout_slave.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY! -- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
...@@ -73,10 +73,10 @@ function f_x_to_zero (x:std_logic_vector) return std_logic_vector is ...@@ -73,10 +73,10 @@ function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0); variable tmp: std_logic_vector(x'length-1 downto 0);
begin begin
for i in 0 to x'length-1 loop for i in 0 to x'length-1 loop
if(x(i) = 'X' or x(i) = 'U') then if(x(i) = '1') then
tmp(i):= '0'; tmp(i):= '1';
else else
tmp(i):=x(i); tmp(i):= '0';
end if; end if;
end loop; end loop;
return tmp; return tmp;
......
...@@ -110,6 +110,14 @@ entity fmc_tdc_mezzanine is ...@@ -110,6 +110,14 @@ entity fmc_tdc_mezzanine is
g_span : integer := 32; g_span : integer := 32;
g_width : integer := 32; g_width : integer := 32;
g_simulation : boolean := false; g_simulation : boolean := false;
-- Enable filtering based on pulse width. This will have the following effects:
-- * Suppress theforwarding of negative slope timestamps.
-- * Delay the forwarding of timestamps until after the falling edge timestamp.
-- Once enabled, all pulses wider than 1 second or narrower than
-- g_pulse_width_filter_min will be dropped.
g_pulse_width_filter : boolean := true;
-- In 8ns ticks.
g_pulse_width_filter_min : natural := 12;
g_use_dma_readout : boolean := true; g_use_dma_readout : boolean := true;
g_use_fifo_readout : boolean := true; g_use_fifo_readout : boolean := true;
g_use_fake_timestamps_for_sim : boolean := false); g_use_fake_timestamps_for_sim : boolean := false);
...@@ -188,8 +196,9 @@ entity fmc_tdc_mezzanine is ...@@ -188,8 +196,9 @@ entity fmc_tdc_mezzanine is
i2c_sda_i : in std_logic; i2c_sda_i : in std_logic;
-- 1-Wire interface -- 1-Wire interface
onewire_b : inout std_logic; onewire_b : inout std_logic;
direct_timestamp_o : out std_logic_vector(127 downto 0);
direct_timestamp_valid_o : out std_logic; timestamp_o : out t_tdc_timestamp_array(4 downto 0);
timestamp_valid_o : out std_logic_vector(4 downto 0);
sim_timestamp_i : in t_tdc_timestamp := c_dummy_timestamp; sim_timestamp_i : in t_tdc_timestamp := c_dummy_timestamp;
sim_timestamp_valid_i : in std_logic := '0'; sim_timestamp_valid_i : in std_logic := '0';
...@@ -204,6 +213,9 @@ end fmc_tdc_mezzanine; ...@@ -204,6 +213,9 @@ end fmc_tdc_mezzanine;
--================================================================================================= --=================================================================================================
architecture rtl of fmc_tdc_mezzanine is architecture rtl of fmc_tdc_mezzanine is
constant c_CLK_PERIOD : std_logic_vector(31 downto 0) :=
work.tdc_core_pkg.f_pick(g_SIMULATION, c_SIM_CLK_PERIOD, c_SYN_CLK_PERIOD);
--------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------
-- SDB CONSTANTS -- -- SDB CONSTANTS --
--------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------
...@@ -214,7 +226,8 @@ architecture rtl of fmc_tdc_mezzanine is ...@@ -214,7 +226,8 @@ architecture rtl of fmc_tdc_mezzanine is
constant c_WB_SLAVE_TDC_CORE_CONFIG : integer := 1; -- TDC core configuration registers constant c_WB_SLAVE_TDC_CORE_CONFIG : integer := 1; -- TDC core configuration registers
constant c_WB_SLAVE_TDC_EIC : integer := 2; -- TDC interrupts constant c_WB_SLAVE_TDC_EIC : integer := 2; -- TDC interrupts
constant c_WB_SLAVE_TDC_I2C : integer := 3; -- TDC mezzanine board system EEPROM I2C constant c_WB_SLAVE_TDC_I2C : integer := 3; -- TDC mezzanine board system EEPROM I2C
constant c_WB_SLAVE_TDC_FIFO0 : integer := 4; -- Access to TDC core FIFO for timestamps retrieval constant c_WB_SLAVE_TDC_CHANNEL0 : integer := 4; -- Access to TDC core channel registers
-- and FIFO for timestamps retrieval
constant c_WB_SLAVE_TDC_DMA : integer := 9; -- Access to TDC core DMA controller constant c_WB_SLAVE_TDC_DMA : integer := 9; -- Access to TDC core DMA controller
-- Slave port on the wishbone crossbar -- Slave port on the wishbone crossbar
...@@ -325,11 +338,13 @@ begin ...@@ -325,11 +338,13 @@ begin
--------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------
cmp_tdc_core : entity work.fmc_tdc_core cmp_tdc_core : entity work.fmc_tdc_core
generic map generic map
(g_span => g_span, (g_span => g_span,
g_width => g_width, g_width => g_width,
g_simulation => g_simulation, g_simulation => g_simulation,
g_with_dma_readout => g_use_dma_readout, g_pulse_width_filter => g_pulse_width_filter,
g_with_fifo_readout => g_use_fifo_readout) g_pulse_width_filter_min => g_pulse_width_filter_min,
g_with_dma_readout => g_use_dma_readout,
g_with_fifo_readout => g_use_fifo_readout)
port map port map
( -- clks, rst ( -- clks, rst
clk_tdc_i => clk_tdc_i, clk_tdc_i => clk_tdc_i,
...@@ -389,9 +404,6 @@ begin ...@@ -389,9 +404,6 @@ begin
ts_offset_i => ts_offset, ts_offset_i => ts_offset,
reset_seq_i => reset_seq, reset_seq_i => reset_seq,
direct_timestamp_valid_o => direct_timestamp_valid_o,
direct_timestamp_o => direct_timestamp_o,
fmc_id_i => fmc_id_i, fmc_id_i => fmc_id_i,
irq_threshold_o => irq_threshold, irq_threshold_o => irq_threshold,
...@@ -426,47 +438,32 @@ begin ...@@ -426,47 +438,32 @@ begin
tdc_timestamp_ready <= timestamp_ready; tdc_timestamp_ready <= timestamp_ready;
end generate gen_use_real_timestamps; end generate gen_use_real_timestamps;
timestamp_o <= timestamp;
timestamp_valid_o <= timestamp_valid;
gen_fifos : for i in 0 to 4 generate
U_TheFifo : entity work.timestamp_fifo
gen_enable_fifo_readout : if g_use_fifo_readout generate generic map (
gen_fifos : for i in 0 to 4 generate g_use_fifo_readout => g_use_fifo_readout)
port map (
U_TheFifo : entity work.timestamp_fifo clk_sys_i => clk_sys_i,
generic map ( rst_sys_n_i => rst_sys_n_i,
g_channel => i) slave_i => cnx_master_out(c_WB_SLAVE_TDC_CHANNEL0 + i),
port map ( slave_o => cnx_master_in(c_WB_SLAVE_TDC_CHANNEL0 + i),
clk_sys_i => clk_sys_i, irq_o => irq_fifo(i),
rst_sys_n_i => rst_sys_n_i, enable_i => channel_enable(i),
slave_i => cnx_master_out(c_WB_SLAVE_TDC_FIFO0 + i), tick_i => tick_1ms,
slave_o => cnx_master_in(c_WB_SLAVE_TDC_FIFO0 + i), irq_threshold_i => irq_threshold,
irq_o => irq_fifo(i), irq_timeout_i => irq_timeout,
enable_i => channel_enable(i), timestamp_i => timestamp(i),
tick_i => tick_1ms, timestamp_valid_i => timestamp_stb(i),
irq_threshold_i => irq_threshold, ts_offset_o => ts_offset(i),
irq_timeout_i => irq_timeout, reset_seq_o => reset_seq(i),
timestamp_i => timestamp, raw_enable_o => raw_enable(i));
timestamp_valid_i => timestamp_stb,
ts_offset_o => ts_offset(i), timestamp_stb(i) <= timestamp_valid(i) and timestamp_ready(i);
reset_seq_o => reset_seq(i), end generate gen_fifos;
raw_enable_o => raw_enable(i));
timestamp_stb(i) <= timestamp_valid(i) and timestamp_ready(i);
end generate gen_fifos;
end generate gen_enable_fifo_readout;
gen_disable_fifo_readout : if not g_use_fifo_readout generate
gen_fifos : for i in 0 to 4 generate
timestamp_ready(i) <= '1';
cnx_master_in(c_WB_SLAVE_TDC_FIFO0 + i).ack <= '1';
cnx_master_in(c_WB_SLAVE_TDC_FIFO0 + i).stall <= '0';
cnx_master_in(c_WB_SLAVE_TDC_FIFO0 + i).err <= '0';
cnx_master_in(c_WB_SLAVE_TDC_FIFO0 + i).rty <= '0';
end generate gen_fifos;
end generate gen_disable_fifo_readout;
gen_with_dma_readout : if g_use_dma_readout generate gen_with_dma_readout : if g_use_dma_readout generate
U_DMA_Engine : entity work.tdc_dma_engine U_DMA_Engine : entity work.tdc_dma_engine
...@@ -547,8 +544,8 @@ begin ...@@ -547,8 +544,8 @@ begin
wrabbit_utc_p <= '0'; wrabbit_utc_p <= '0';
else else
if wrabbit_clk_aux_locked_i = '1' and g_with_wrabbit_core then if wrabbit_clk_aux_locked_i = '1' and g_with_wrabbit_core then
if unsigned(wrabbit_cycles_i) = (unsigned(c_SYN_CLK_PERIOD)-3) then -- so that the end of the pulse -- so that the end of the pulse comes exactly upon the UTC change
-- comes exactly upon the UTC change if unsigned(wrabbit_cycles_i) = (unsigned(c_CLK_PERIOD) - 3) then
wrabbit_utc_p <= '1'; wrabbit_utc_p <= '1';
else else
wrabbit_utc_p <= '0'; wrabbit_utc_p <= '0';
......
...@@ -132,6 +132,14 @@ entity fmc_tdc_wrapper is ...@@ -132,6 +132,14 @@ entity fmc_tdc_wrapper is
g_simulation : boolean := false; g_simulation : boolean := false;
-- implement direct TDC timestamp readout FIFO, used in the WR Node projects -- implement direct TDC timestamp readout FIFO, used in the WR Node projects
g_with_direct_readout : boolean := false; g_with_direct_readout : boolean := false;
-- Enable filtering based on pulse width. This will have the following effects:
-- * Suppress theforwarding of negative slope timestamps.
-- * Delay the forwarding of timestamps until after the falling edge timestamp.
-- Once enabled, all pulses wider than 1 second or narrower than
-- g_pulse_width_filter_min will be dropped.
g_pulse_width_filter : boolean := true;
-- In 8ns ticks.
g_pulse_width_filter_min : natural := 12;
g_use_dma_readout : boolean := false; g_use_dma_readout : boolean := false;
g_use_fifo_readout : boolean := false; g_use_fifo_readout : boolean := false;
g_use_fake_timestamps_for_sim : boolean := false g_use_fake_timestamps_for_sim : boolean := false
...@@ -242,18 +250,6 @@ end fmc_tdc_wrapper; ...@@ -242,18 +250,6 @@ end fmc_tdc_wrapper;
--================================================================================================= --=================================================================================================
architecture rtl of fmc_tdc_wrapper is architecture rtl of fmc_tdc_wrapper is
component fmc_tdc_direct_readout is
port (
clk_tdc_i : in std_logic;
rst_tdc_n_i : in std_logic;
clk_sys_i : in std_logic;
rst_sys_n_i : in std_logic;
direct_timestamp_i : in std_logic_vector(127 downto 0);
direct_timestamp_wr_i : in std_logic;
direct_slave_i : in t_wishbone_slave_in;
direct_slave_o : out t_wishbone_slave_out);
end component fmc_tdc_direct_readout;
-- WRabbit clocks -- WRabbit clocks
signal clk_125m_mezz : std_logic; signal clk_125m_mezz : std_logic;
signal rst_125m_mezz_n, rst_125m_mezz : std_logic; signal rst_125m_mezz_n, rst_125m_mezz : std_logic;
...@@ -270,8 +266,8 @@ architecture rtl of fmc_tdc_wrapper is ...@@ -270,8 +266,8 @@ architecture rtl of fmc_tdc_wrapper is
signal tdc_scl_out, tdc_scl_oen, tdc_sda_out, tdc_sda_oen : std_logic; signal tdc_scl_out, tdc_scl_oen, tdc_sda_out, tdc_sda_oen : std_logic;
signal direct_timestamp : std_logic_vector(127 downto 0); signal timestamp : t_tdc_timestamp_array(4 downto 0);
signal direct_timestamp_wr : std_logic; signal timestamp_valid : std_logic_vector(4 downto 0);
constant c_cnx_slave_ports : integer := 2; constant c_cnx_slave_ports : integer := 2;
constant c_cnx_master_ports : integer := 2; constant c_cnx_master_ports : integer := 2;
...@@ -322,16 +318,14 @@ begin ...@@ -322,16 +318,14 @@ begin
master_i => cnx_master_in, master_i => cnx_master_in,
master_o => cnx_master_out); master_o => cnx_master_out);
cmp_direct_readout : fmc_tdc_direct_readout cmp_direct_readout : entity work.fmc_tdc_direct_readout
port map ( port map (
clk_tdc_i => clk_125m_mezz, clk_sys_i => clk_sys_i,
rst_tdc_n_i => rst_125m_mezz_n, rst_sys_n_i => rst_sys_n_i,
clk_sys_i => clk_sys_i, timestamp_i => timestamp,
rst_sys_n_i => rst_sys_n_i, timestamp_valid_i => timestamp_valid,
direct_timestamp_i => direct_timestamp, direct_slave_i => cnx_master_out(c_slave_direct),
direct_timestamp_wr_i => direct_timestamp_wr, direct_slave_o => cnx_master_in(c_slave_direct));
direct_slave_i => cnx_master_out(c_slave_direct),
direct_slave_o => cnx_master_in(c_slave_direct));
end generate gen_with_direct_readout; end generate gen_with_direct_readout;
...@@ -406,6 +400,8 @@ begin ...@@ -406,6 +400,8 @@ begin
(g_span => 32, (g_span => 32,
g_width => 32, g_width => 32,
g_simulation => g_simulation, g_simulation => g_simulation,
g_pulse_width_filter => g_pulse_width_filter,
g_pulse_width_filter_min => g_pulse_width_filter_min,
g_use_fifo_readout => g_use_fifo_readout, g_use_fifo_readout => g_use_fifo_readout,
g_use_dma_readout => g_use_dma_readout, g_use_dma_readout => g_use_dma_readout,
g_use_fake_timestamps_for_sim => g_use_fake_timestamps_for_sim) g_use_fake_timestamps_for_sim => g_use_fake_timestamps_for_sim)
...@@ -482,8 +478,9 @@ begin ...@@ -482,8 +478,9 @@ begin
i2c_sda_o => tdc_sda_out, i2c_sda_o => tdc_sda_out,
-- 1-Wire on TDC mezzanine -- 1-Wire on TDC mezzanine
onewire_b => mezz_one_wire_b, onewire_b => mezz_one_wire_b,
direct_timestamp_o => direct_timestamp,
direct_timestamp_valid_o => direct_timestamp_wr, timestamp_o => timestamp,
timestamp_valid_o => timestamp_valid,
sim_timestamp_ready_o => sim_timestamp_ready_o, sim_timestamp_ready_o => sim_timestamp_ready_o,
sim_timestamp_valid_i => sim_timestamp_valid_i, sim_timestamp_valid_i => sim_timestamp_valid_i,
......
...@@ -6,17 +6,19 @@ ...@@ -6,17 +6,19 @@
-- Author : Tomasz Wlostowski -- Author : Tomasz Wlostowski
-- Company : CERN -- Company : CERN
-- Created : 2011-08-29 -- Created : 2011-08-29
-- Last update: 2018-09-10 -- Last update: 2019-09-29
-- Platform : FPGA-generic -- Platform : FPGA-generic
-- Standard : VHDL'93 -- Standard : VHDL'93
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- Description: Pipelined timestamp adder with re-normalization of the result. -- Description: Pipelined timestamp adder with re-normalization of the result.
-- Adds a to b, producing normalized timestamp q. A timestmap is normalized when -- Adds a to b, producing normalized timestamp q. A timestmap is normalized when
-- the 0 <= frac < 2**g_frac_bits, 0 <= coarse <= g_coarse_range-1 and utc >= 0. -- the 0 <= frac < g_frac_range, 0 <= coarse <= g_coarse_range-1 and utc >= 0.
-- For correct operation of renormalizer, input timestamps must meet the -- For correct operation of renormalizer, input timestamps must meet the
-- following constraints: -- following constraints:
-- 1. 0 <= (a/b)_frac_i <= 2**g_frac_bits-1 -- 1. 0 <= a_tai + b_tai < 2**32 - 1
-- 2. -g_coarse_range+1 <= (a_coarse_i + b_coarse_i) <= 3*g_coarse_range-1 -- 2. 0 <= a_frac < g_frac_range
-- 3. -g_frac_range / 2 <= b_frac < g_frac_range / 2
-- 4. -g_coarse_range+1 <= (a_coarse + b_coarse) <= 3*g_coarse_range-1
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- --
-- Copyright (c) 2011 CERN / BE-CO-HT -- Copyright (c) 2011 CERN / BE-CO-HT
...@@ -60,7 +62,7 @@ entity tdc_ts_addsub is ...@@ -60,7 +62,7 @@ entity tdc_ts_addsub is
a_i : in t_tdc_timestamp; a_i : in t_tdc_timestamp;
b_i : in t_tdc_timestamp; b_i : in t_tdc_timestamp;
valid_o : out std_logic; valid_o : out std_logic;
q_o : out t_tdc_timestamp q_o : out t_tdc_timestamp
); );
...@@ -71,12 +73,12 @@ architecture rtl of tdc_ts_addsub is ...@@ -71,12 +73,12 @@ architecture rtl of tdc_ts_addsub is
constant c_NUM_PIPELINE_STAGES : integer := 4; constant c_NUM_PIPELINE_STAGES : integer := 4;
type t_internal_sum is record type t_internal_sum is record
tai : signed(32 downto 0); tai : signed(32 downto 0);
coarse : signed(31 downto 0); coarse : signed(31 downto 0);
frac : signed(15 downto 0); frac : signed(15 downto 0);
seq : std_logic_vector(31 downto 0); channel : std_logic_vector(2 downto 0);
meta : std_logic_vector(31 downto 0); meta : std_logic_vector(31 downto 0);
slope : std_logic; slope : std_logic;
end record; end record;
type t_internal_sum_array is array (integer range <>) of t_internal_sum; type t_internal_sum_array is array (integer range <>) of t_internal_sum;
...@@ -88,7 +90,7 @@ architecture rtl of tdc_ts_addsub is ...@@ -88,7 +90,7 @@ architecture rtl of tdc_ts_addsub is
signal unf_frac : std_logic; signal unf_frac : std_logic;
signal ovf_coarse : std_logic_vector(1 downto 0); signal ovf_coarse : std_logic_vector(1 downto 0);
signal unf_coarse : std_logic_vector(1 downto 0); signal unf_coarse : std_logic_vector(1 downto 0);
begin -- rtl begin -- rtl
-- Pipeline stage 0: just subtract the two timestamps field by field -- Pipeline stage 0: just subtract the two timestamps field by field
...@@ -100,15 +102,13 @@ begin -- rtl ...@@ -100,15 +102,13 @@ begin -- rtl
elsif(enable_i = '1') then elsif(enable_i = '1') then
pipe(0) <= valid_i; pipe(0) <= valid_i;
sums(0).tai <= signed( resize(unsigned(a_i.tai) + unsigned(b_i.tai), 33) ); sums(0).channel <= a_i.channel;
sums(0).seq <= a_i.seq; sums(0).slope <= a_i.slope;
sums(0).slope <= a_i.slope; sums(0).meta <= a_i.meta;
sums(0).meta <= a_i.meta;
sums(0).frac <= signed( resize(unsigned(a_i.frac),16) + resize(unsigned(b_i.frac), 16) );
sums(0).coarse <= signed(resize(unsigned(a_i.coarse), sums(0).coarse'length) +
resize(unsigned(b_i.coarse), sums(0).coarse'length));
sums(0).tai <= signed(resize(unsigned(a_i.tai) + unsigned(b_i.tai), 33));
sums(0).coarse <= signed(a_i.coarse) + signed(b_i.coarse);
sums(0).frac <= signed(resize(signed('0' & a_i.frac), 16) + resize(signed(b_i.frac), 16));
else else
pipe(0) <= '0'; pipe(0) <= '0';
end if; end if;
...@@ -123,17 +123,16 @@ begin -- rtl ...@@ -123,17 +123,16 @@ begin -- rtl
p_stage1 : process(clk_i) p_stage1 : process(clk_i)
begin begin
if rising_edge(clk_i) then if rising_edge(clk_i) then
if rst_n_i = '0' then if rst_n_i = '0' then
pipe(1) <= '0'; pipe(1) <= '0';
else else
pipe(1) <= pipe(0); pipe(1) <= pipe(0);
sums(1).seq <= sums(0).seq; sums(1) <= sums(0);
sums(1).meta <= sums(0).meta; sums(1) <= sums(0);
sums(1).slope <= sums(0).slope; sums(1) <= sums(0);
if(ovf_frac = '1') then if(ovf_frac = '1') then
sums(1).frac <= sums(0).frac - g_frac_range; sums(1).frac <= sums(0).frac - g_frac_range;
sums(1).coarse <= sums(0).coarse + 1; sums(1).coarse <= sums(0).coarse + 1;
...@@ -145,7 +144,6 @@ begin -- rtl ...@@ -145,7 +144,6 @@ begin -- rtl
sums(1).coarse <= sums(0).coarse; sums(1).coarse <= sums(0).coarse;
end if; end if;
sums(1).tai <= sums(0).tai;
end if; end if;
end if; end if;
end process; end process;
...@@ -170,14 +168,14 @@ begin -- rtl ...@@ -170,14 +168,14 @@ begin -- rtl
unf_coarse <= "00"; unf_coarse <= "00";
end if; end if;
if ( sums(1).coarse >= g_frac_range ) then if ( sums(1).coarse >= g_coarse_range ) then
ovf_coarse <= "10"; ovf_coarse <= "10";
elsif ( sums(1).coarse >= 2*g_frac_range ) then elsif ( sums(1).coarse >= 2*g_coarse_range ) then
ovf_coarse <= "01"; ovf_coarse <= "01";
else else
ovf_coarse <= "00"; ovf_coarse <= "00";
end if; end if;
end if; end if;
end if; end if;
end process; end process;
...@@ -192,9 +190,7 @@ begin -- rtl ...@@ -192,9 +190,7 @@ begin -- rtl
else else
pipe(3) <= pipe(2); pipe(3) <= pipe(2);
sums(3).seq <= sums(2).seq; sums(3) <= sums(2);
sums(3).slope <= sums(2).slope;
sums(3).meta <= sums(2).meta;
if(unf_coarse = "10") then if(unf_coarse = "10") then
sums(3).coarse <= sums(2).coarse + g_coarse_range; sums(3).coarse <= sums(2).coarse + g_coarse_range;
...@@ -213,18 +209,16 @@ begin -- rtl ...@@ -213,18 +209,16 @@ begin -- rtl
sums(3).tai <= sums(2).tai; sums(3).tai <= sums(2).tai;
end if; end if;
sums(3).frac <= sums(2).frac;
end if; end if;
end if; end if;
end process; end process;
-- clip the extra bits and output the result -- clip the extra bits and output the result
valid_o <= pipe(c_NUM_PIPELINE_STAGES-1); valid_o <= pipe(c_NUM_PIPELINE_STAGES-1);
q_o.tai <= std_logic_vector(sums(c_NUM_PIPELINE_STAGES-1).tai(31 downto 0)); q_o.tai <= std_logic_vector(sums(c_NUM_PIPELINE_STAGES-1).tai(31 downto 0));
q_o.coarse <= std_logic_vector(sums(c_NUM_PIPELINE_STAGES-1).coarse(31 downto 0)); q_o.coarse <= std_logic_vector(sums(c_NUM_PIPELINE_STAGES-1).coarse(31 downto 0));
q_o.frac <= std_logic_vector(sums(c_NUM_PIPELINE_STAGES-1).frac(11 downto 0)); q_o.frac <= std_logic_vector(sums(c_NUM_PIPELINE_STAGES-1).frac(11 downto 0));
q_o.seq <= sums(c_NUM_PIPELINE_STAGES-1).seq; q_o.slope <= sums(c_NUM_PIPELINE_STAGES-1).slope;
q_o.slope <= sums(c_NUM_PIPELINE_STAGES-1).slope; q_o.meta <= sums(c_NUM_PIPELINE_STAGES-1).meta;
q_o.meta <= sums(c_NUM_PIPELINE_STAGES-1).meta; q_o.channel <= sums(c_NUM_PIPELINE_STAGES-1).channel;
end rtl; end rtl;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
-- File : timestamp_fifo_wbgen2_pkg.vhd -- File : timestamp_fifo_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from wbgen/timestamp_fifo_wb.wb -- Author : auto-generated by wbgen2 from wbgen/timestamp_fifo_wb.wb
-- Created : Sun Sep 2 15:37:55 2018 -- Created : Thu Sep 26 16:42:08 2019
-- Standard : VHDL'87 -- Standard : VHDL'87
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/timestamp_fifo_wb.wb -- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/timestamp_fifo_wb.wb
...@@ -27,10 +27,6 @@ package tsf_wbgen2_pkg is ...@@ -27,10 +27,6 @@ package tsf_wbgen2_pkg is
fifo_ts1_i : std_logic_vector(31 downto 0); fifo_ts1_i : std_logic_vector(31 downto 0);
fifo_ts2_i : std_logic_vector(31 downto 0); fifo_ts2_i : std_logic_vector(31 downto 0);
fifo_ts3_i : std_logic_vector(31 downto 0); fifo_ts3_i : std_logic_vector(31 downto 0);
delta1_i : std_logic_vector(31 downto 0);
delta2_i : std_logic_vector(31 downto 0);
delta3_i : std_logic_vector(31 downto 0);
csr_delta_ready_i : std_logic;
end record; end record;
constant c_tsf_in_registers_init_value: t_tsf_in_registers := ( constant c_tsf_in_registers_init_value: t_tsf_in_registers := (
...@@ -38,11 +34,7 @@ package tsf_wbgen2_pkg is ...@@ -38,11 +34,7 @@ package tsf_wbgen2_pkg is
fifo_ts0_i => (others => '0'), fifo_ts0_i => (others => '0'),
fifo_ts1_i => (others => '0'), fifo_ts1_i => (others => '0'),
fifo_ts2_i => (others => '0'), fifo_ts2_i => (others => '0'),
fifo_ts3_i => (others => '0'), fifo_ts3_i => (others => '0')
delta1_i => (others => '0'),
delta2_i => (others => '0'),
delta3_i => (others => '0'),
csr_delta_ready_i => '0'
); );
-- Output registers (WB slave -> user design) -- Output registers (WB slave -> user design)
...@@ -51,82 +43,64 @@ package tsf_wbgen2_pkg is ...@@ -51,82 +43,64 @@ package tsf_wbgen2_pkg is
fifo_wr_full_o : std_logic; fifo_wr_full_o : std_logic;
fifo_wr_empty_o : std_logic; fifo_wr_empty_o : std_logic;
fifo_wr_usedw_o : std_logic_vector(5 downto 0); fifo_wr_usedw_o : std_logic_vector(5 downto 0);
offset1_o : std_logic_vector(31 downto 0);
offset2_o : std_logic_vector(31 downto 0);
offset3_o : std_logic_vector(31 downto 0);
csr_delta_read_o : std_logic;
csr_rst_seq_o : std_logic;
csr_delta_ref_o : std_logic_vector(2 downto 0);
csr_raw_mode_o : std_logic;
end record; end record;
constant c_tsf_out_registers_init_value: t_tsf_out_registers := ( constant c_tsf_out_registers_init_value: t_tsf_out_registers := (
fifo_wr_full_o => '0', fifo_wr_full_o => '0',
fifo_wr_empty_o => '0', fifo_wr_empty_o => '0',
fifo_wr_usedw_o => (others => '0'), fifo_wr_usedw_o => (others => '0')
offset1_o => (others => '0'),
offset2_o => (others => '0'),
offset3_o => (others => '0'),
csr_delta_read_o => '0',
csr_rst_seq_o => '0',
csr_delta_ref_o => (others => '0'),
csr_raw_mode_o => '0'
); );
function "or" (left, right: t_tsf_in_registers) return t_tsf_in_registers; function "or" (left, right: t_tsf_in_registers) return t_tsf_in_registers;
function f_x_to_zero (x:std_logic) return std_logic; function f_x_to_zero (x:std_logic) return std_logic;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector; function f_x_to_zero (x:std_logic_vector) return std_logic_vector;
component timestamp_fifo_wb is component timestamp_fifo_wb is
port ( port (
rst_n_i : in std_logic; rst_n_i : in std_logic;
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
slave_i : in t_wishbone_slave_in; slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out; slave_o : out t_wishbone_slave_out;
int_o : out std_logic; int_o : out std_logic;
regs_i : in t_tsf_in_registers; regs_i : in t_tsf_in_registers;
regs_o : out t_tsf_out_registers regs_o : out t_tsf_out_registers
); );
end component; end component;
end package; end package;
package body tsf_wbgen2_pkg is package body tsf_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is function f_x_to_zero (x:std_logic) return std_logic is
begin begin
if x = '1' then if x = '1' then
return '1'; return '1';
else
return '0';
end if;
end function;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
begin
for i in 0 to x'length-1 loop
if(x(i) = 'X' or x(i) = 'U') then
tmp(i):= '0';
else else
tmp(i):=x(i); return '0';
end if; end if;
end loop; end function;
return tmp;
end function; function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
function "or" (left, right: t_tsf_in_registers) return t_tsf_in_registers is begin
variable tmp: t_tsf_in_registers; for i in 0 to x'length-1 loop
begin if(x(i) = '1') then
tmp.fifo_wr_req_i := f_x_to_zero(left.fifo_wr_req_i) or f_x_to_zero(right.fifo_wr_req_i); tmp(i):= '1';
tmp.fifo_ts0_i := f_x_to_zero(left.fifo_ts0_i) or f_x_to_zero(right.fifo_ts0_i); else
tmp.fifo_ts1_i := f_x_to_zero(left.fifo_ts1_i) or f_x_to_zero(right.fifo_ts1_i); tmp(i):= '0';
tmp.fifo_ts2_i := f_x_to_zero(left.fifo_ts2_i) or f_x_to_zero(right.fifo_ts2_i); end if;
tmp.fifo_ts3_i := f_x_to_zero(left.fifo_ts3_i) or f_x_to_zero(right.fifo_ts3_i); end loop;
tmp.delta1_i := f_x_to_zero(left.delta1_i) or f_x_to_zero(right.delta1_i); return tmp;
tmp.delta2_i := f_x_to_zero(left.delta2_i) or f_x_to_zero(right.delta2_i); end function;
tmp.delta3_i := f_x_to_zero(left.delta3_i) or f_x_to_zero(right.delta3_i);
tmp.csr_delta_ready_i := f_x_to_zero(left.csr_delta_ready_i) or f_x_to_zero(right.csr_delta_ready_i); function "or" (left, right: t_tsf_in_registers) return t_tsf_in_registers is
return tmp; variable tmp: t_tsf_in_registers;
end function; begin
tmp.fifo_wr_req_i := f_x_to_zero(left.fifo_wr_req_i) or f_x_to_zero(right.fifo_wr_req_i);
tmp.fifo_ts0_i := f_x_to_zero(left.fifo_ts0_i) or f_x_to_zero(right.fifo_ts0_i);
tmp.fifo_ts1_i := f_x_to_zero(left.fifo_ts1_i) or f_x_to_zero(right.fifo_ts1_i);
tmp.fifo_ts2_i := f_x_to_zero(left.fifo_ts2_i) or f_x_to_zero(right.fifo_ts2_i);
tmp.fifo_ts3_i := f_x_to_zero(left.fifo_ts3_i) or f_x_to_zero(right.fifo_ts3_i);
return tmp;
end function;
end package body; end package body;
-- -*- Mode: LUA; tab-width: 2 -*-
peripheral {
name = "Channel registers";
prefix="ch_reg";
hdl_entity="channel_regs";
reg {
name = "Delta Timestamp Word 1";
prefix = "DELTA1";
field {
name = "Delta Timestamp Word 1 (TAI cycles, signed)";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Delta Timestamp Word 2";
prefix = "DELTA2";
field {
name = "Delta Timestamp Word 2 (8ns ticks, unsigned)";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Delta Timestamp Word 3";
prefix = "DELTA3";
field {
name = "Delta Timestamp Word 3 (fractional part, unsigned)";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Channel Offset Word 1";
prefix = "OFFSET1";
field {
name = "Channel Offset Word 1 (TAI cycles, signed)";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Channel Offset Word 2";
prefix = "OFFSET2";
field {
name = "Channel Offset Word 2 (8ns ticks, unsigned)";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Channel Offset Word 3";
prefix = "OFFSET3";
field {
name = "Channel Offset Word 3 (fractional part, unsigned)";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Control/Status";
prefix = "CSR";
field {
name = "Delta Timestamp Ready";
prefix = "DELTA_READY";
type = BIT;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field {
name = "Read Delta Timestamp";
prefix = "DELTA_READ";
type = MONOSTABLE;
};
field {
name = "Reset Sequence Counter";
prefix = "RST_SEQ";
type = MONOSTABLE;
};
field {
name = "Delta Timestamp Reference Channel";
description = "Channel (0-4) to take as the reference for the delta timestamps";
prefix = "DELTA_REF";
type = SLV;
size = 3;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Raw readout mode";
description = "1: enables readout of raw timestamps";
prefix = "RAW_MODE";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
};
...@@ -13,8 +13,6 @@ peripheral ...@@ -13,8 +13,6 @@ peripheral
flags_bus = {FIFO_EMPTY, FIFO_FULL, FIFO_COUNT, FIFO_RESET}; flags_bus = {FIFO_EMPTY, FIFO_FULL, FIFO_COUNT, FIFO_RESET};
flags_dev = {FIFO_EMPTY, FIFO_FULL, FIFO_COUNT, FIFO_RESET}; flags_dev = {FIFO_EMPTY, FIFO_FULL, FIFO_COUNT, FIFO_RESET};
clock = "clk_tdc_i";
field { field {
name = "Seconds"; name = "Seconds";
prefix = "SECONDS"; prefix = "SECONDS";
...@@ -53,7 +51,6 @@ peripheral ...@@ -53,7 +51,6 @@ peripheral
reg { reg {
name = "Channel Enable Register"; name = "Channel Enable Register";
prefix = "CHAN_ENABLE"; prefix = "CHAN_ENABLE";
clock = "clk_tdc_i";
field { field {
name = "Channel enable"; name = "Channel enable";
size = 5; size = 5;
...@@ -66,8 +63,6 @@ peripheral ...@@ -66,8 +63,6 @@ peripheral
reg { reg {
name = "Dead Time Register"; name = "Dead Time Register";
prefix = "DEAD_TIME"; prefix = "DEAD_TIME";
clock = "clk_tdc_i";
field { field {
name = "Dead time (8ns ticks)"; name = "Dead time (8ns ticks)";
size = 24; size = 24;
...@@ -76,4 +71,4 @@ peripheral ...@@ -76,4 +71,4 @@ peripheral
access_dev = READ_ONLY; access_dev = READ_ONLY;
}; };
}; };
}; };
\ No newline at end of file
...@@ -45,134 +45,4 @@ peripheral { ...@@ -45,134 +45,4 @@ peripheral {
size = 32; size = 32;
}; };
}; };
reg {
name = "Delta Timestamp Word 1";
prefix = "DELTA1";
field {
name = "Delta Timestamp Word 1 (TAI cycles, signed)";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Delta Timestamp Word 2";
prefix = "DELTA2";
field {
name = "Delta Timestamp Word 2 (8ns ticks, unsigned)";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Delta Timestamp Word 3";
prefix = "DELTA3";
field {
name = "Delta Timestamp Word 3 (fractional part, unsigned)";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Channel Offset Word 1";
prefix = "OFFSET1";
field {
name = "Channel Offset Word 1 (TAI cycles, signed)";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Channel Offset Word 2";
prefix = "OFFSET2";
field {
name = "Channel Offset Word 2 (8ns ticks, unsigned)";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Channel Offset Word 3";
prefix = "OFFSET3";
field {
name = "Channel Offset Word 3 (fractional part, unsigned)";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Control/Status";
prefix = "CSR";
field {
name = "Delta Timestamp Ready";
prefix = "DELTA_READY";
type = BIT;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field {
name = "Read Delta Timestamp";
prefix = "DELTA_READ";
type = MONOSTABLE;
};
field {
name = "Reset Sequence Counter";
prefix = "RST_SEQ";
type = MONOSTABLE;
};
field {
name = "Delta Timestamp Reference Channel";
description = "Channel (0-4) to take as the reference for the delta timestamps";
prefix = "DELTA_REF";
type = SLV;
size = 3;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Raw readout mode";
description = "1: enables readout of raw timestamps";
prefix = "RAW_MODE";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
}; };
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