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

Merge branch 'dlamprid-dev' into feature/convention

parents 04df2ba6 e66d3b45
......@@ -19,3 +19,4 @@
[submodule "hdl/ip_cores/svec"]
path = hdl/ip_cores/svec
url = https://ohwr.org/project/svec.git
......@@ -22,6 +22,8 @@ files = [
"fmc_tdc_direct_readout_slave_pkg.vhd",
"fmc_tdc_wrapper.vhd",
"timestamp_fifo.vhd",
"channel_regs.vhd",
"channel_regs_wbgen2_pkg.vhd",
"timestamp_fifo_wb.vhd",
"timestamp_fifo_wbgen2_pkg.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
if acam_ef1_i ='0' then
nxt_engine_st <= GET_STAMP1;
elsif acam_ef2_i ='0' then
nxt_engine_st <= GET_STAMP2;
else
nxt_engine_st <= ACTIVE;
end if;
......
......@@ -150,12 +150,19 @@ use work.genram_pkg.all;
--=================================================================================================
entity fmc_tdc_core is
generic
(g_span : integer := 32; -- address span in bus interfaces
g_width : integer := 32; -- data width in bus interfaces
g_simulation : boolean := false;
g_with_dma_readout : boolean := false;
g_with_fifo_readout : boolean := false); -- this generic is set to TRUE
-- when instantiated in a test-bench
(g_span : integer := 32; -- address span in bus interfaces
g_width : integer := 32; -- data width in bus interfaces
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_with_dma_readout : boolean := false;
g_with_fifo_readout : boolean := false);
port
(
clk_sys_i : in std_logic;
......@@ -219,10 +226,6 @@ entity fmc_tdc_core is
timestamp_valid_o : out 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);
irq_threshold_o : out std_logic_vector(9 downto 0);
irq_timeout_o : out std_logic_vector(9 downto 0);
......@@ -539,6 +542,9 @@ begin
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 (
clk_tdc_i => clk_tdc_i,
rst_tdc_n_i => rst_tdc_n_i,
......@@ -553,9 +559,7 @@ begin
ts_ready_i => final_timestamp_ready,
ts_offset_i => ts_offset_i,
reset_seq_i => reset_seq_i,
raw_enable_i => raw_enable_i,
direct_timestamp_o => direct_timestamp_o,
direct_timestamp_valid_o => direct_timestamp_valid_o
raw_enable_i => raw_enable_i
);
......
......@@ -11,14 +11,11 @@ use work.dr_wbgen2_pkg.all;
entity fmc_tdc_direct_readout is
port
(
clk_tdc_i : in std_logic;
rst_tdc_n_i : in std_logic;
clk_sys_i : in std_logic;
rst_sys_n_i : in std_logic;
direct_timestamp_i : in std_logic_vector(127 downto 0);
direct_timestamp_wr_i : in std_logic;
timestamp_i : in t_tdc_timestamp_array(4 downto 0);
timestamp_valid_i : in std_logic_vector(4 downto 0);
direct_slave_i : in t_wishbone_slave_in;
direct_slave_o : out t_wishbone_slave_out
......@@ -29,24 +26,6 @@ end entity;
architecture rtl of fmc_tdc_direct_readout is
component fmc_tdc_direct_readout_wb_slave is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(2 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
clk_tdc_i : in std_logic;
regs_i : in t_dr_in_registers;
regs_o : out t_dr_out_registers);
end component fmc_tdc_direct_readout_wb_slave;
constant c_num_channels : integer := 5;
type t_channel_state is record
......@@ -65,24 +44,33 @@ architecture rtl of fmc_tdc_direct_readout is
signal regs_out : t_dr_out_registers;
signal regs_in : t_dr_in_registers;
signal ts_cycles : std_logic_vector(31 downto 0);
signal ts_seconds : std_logic_vector(31 downto 0);
signal ts_bins : std_logic_vector(17 downto 0);
signal ts_edge : std_logic;
signal ts_channel : std_logic_vector(2 downto 0);
signal direct_slave_out: t_wishbone_slave_out;
begin
signal channel_select : integer := 0;
ts_channel <= direct_timestamp_i(98 downto 96);
ts_edge <= direct_timestamp_i(100);
ts_seconds <= direct_timestamp_i(95 downto 64);
ts_cycles <= direct_timestamp_i(63 downto 32);
ts_bins <= direct_timestamp_i(17 downto 0);
begin
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 (
rst_n_i => rst_sys_n_i,
clk_sys_i => clk_sys_i,
......@@ -95,7 +83,6 @@ begin
wb_we_i => direct_slave_i.we,
wb_ack_o => direct_slave_out.ack,
wb_stall_o => direct_slave_out.stall,
clk_tdc_i => clk_tdc_i,
regs_i => regs_in,
regs_o => regs_out);
......@@ -104,26 +91,17 @@ begin
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
c(i).enable <= regs_out.chan_enable_o(i);
fifo_wr(i) <= f_to_std_logic(unsigned(ts_channel) = i
and ts_edge = '1'
and direct_timestamp_wr_i = '1'
and c(i).ready = '1');
fifo_wr(i) <= f_to_std_logic(timestamp_valid_i(i) = '1' and
c(i).ready = '1');
p_dead_time : process (clk_tdc_i)
p_dead_time : process (clk_sys_i)
begin
if rising_edge(clk_tdc_i) then
if rst_tdc_n_i = '0' or c(i).enable = '0' then
if rising_edge(clk_sys_i) then
if rst_sys_n_i = '0' or c(i).enable = '0' then
c(i).timeout <= (others => '0');
c(i).ready <= '0';
else
......
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : fmc_tdc_direct_readout_slave.vhd
-- 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
---------------------------------------------------------------------------------------
-- 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
wb_stb_i : in std_logic;
wb_we_i : in 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;
clk_tdc_i : in std_logic;
regs_i : in t_dr_in_registers;
regs_o : out t_dr_out_registers
);
......@@ -61,13 +62,8 @@ 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.
-- Some internal signals assignments
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)
......@@ -223,7 +219,7 @@ begin
dr_fifo_in_int(82) <= regs_i.fifo_edge_i;
dr_fifo_in_int(86 downto 83) <= regs_i.fifo_channel_i;
dr_fifo_rst_n <= rst_n_i;
dr_fifo_INST : wbgen2_fifo_async
dr_fifo_INST : wbgen2_fifo_sync
generic map (
g_size => 256,
g_width => 87,
......@@ -239,8 +235,7 @@ begin
rd_usedw_o => dr_fifo_usedw_int,
rd_req_i => dr_fifo_rdreq_int,
rst_n_i => dr_fifo_rst_n,
wr_clk_i => clk_tdc_i,
rd_clk_i => clk_sys_i,
clk_i => clk_sys_i,
wr_data_i => dr_fifo_in_int,
rd_data_o => dr_fifo_out_int
);
......@@ -264,6 +259,8 @@ begin
-- extra code for reg/fifo/mem: FIFO 'Readout FIFO' data output register 2
rwaddr_reg <= wb_adr_i;
wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i);
wb_err_o <= '0';
wb_rty_o <= '0';
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
......@@ -2,11 +2,11 @@
-- Title : Wishbone slave core for TDC Direct Readout WB Slave
---------------------------------------------------------------------------------------
-- File : fmc_tdc_direct_readout_slave_pkg.vhd
-- Author : auto-generated by wbgen2 from fmc_tdc_direct_readout_slave.wb
-- Created : Thu May 22 14:05:35 2014
-- Author : auto-generated by wbgen2 from wbgen/fmc_tdc_direct_readout_slave.wb
-- Created : Thu Sep 26 16:03:31 2019
-- 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!
---------------------------------------------------------------------------------------
......@@ -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);
begin
for i in 0 to x'length-1 loop
if(x(i) = 'X' or x(i) = 'U') then
tmp(i):= '0';
if(x(i) = '1') then
tmp(i):= '1';
else
tmp(i):=x(i);
tmp(i):= '0';
end if;
end loop;
return tmp;
......
......@@ -110,6 +110,14 @@ entity fmc_tdc_mezzanine is
g_span : integer := 32;
g_width : integer := 32;
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_fifo_readout : boolean := true;
g_use_fake_timestamps_for_sim : boolean := false);
......@@ -188,8 +196,9 @@ entity fmc_tdc_mezzanine is
i2c_sda_i : in std_logic;
-- 1-Wire interface
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_valid_i : in std_logic := '0';
......@@ -204,6 +213,9 @@ end fmc_tdc_mezzanine;
--=================================================================================================
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 --
---------------------------------------------------------------------------------------------------
......@@ -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_EIC : integer := 2; -- TDC interrupts
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
-- Slave port on the wishbone crossbar
......@@ -325,11 +338,13 @@ begin
---------------------------------------------------------------------------------------------------
cmp_tdc_core : entity work.fmc_tdc_core
generic map
(g_span => g_span,
g_width => g_width,
g_simulation => g_simulation,
g_with_dma_readout => g_use_dma_readout,
g_with_fifo_readout => g_use_fifo_readout)
(g_span => g_span,
g_width => g_width,
g_simulation => g_simulation,
g_pulse_width_filter => g_pulse_width_filter,
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
( -- clks, rst
clk_tdc_i => clk_tdc_i,
......@@ -389,9 +404,6 @@ begin
ts_offset_i => ts_offset,
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,
irq_threshold_o => irq_threshold,
......@@ -426,47 +438,32 @@ begin
tdc_timestamp_ready <= timestamp_ready;
end generate gen_use_real_timestamps;
timestamp_o <= timestamp;
timestamp_valid_o <= timestamp_valid;
gen_fifos : for i in 0 to 4 generate
gen_enable_fifo_readout : if g_use_fifo_readout generate
gen_fifos : for i in 0 to 4 generate
U_TheFifo : entity work.timestamp_fifo
generic map (
g_channel => i)
port map (
clk_sys_i => clk_sys_i,
rst_sys_n_i => rst_sys_n_i,
slave_i => cnx_master_out(c_WB_SLAVE_TDC_FIFO0 + i),
slave_o => cnx_master_in(c_WB_SLAVE_TDC_FIFO0 + i),
irq_o => irq_fifo(i),
enable_i => channel_enable(i),
tick_i => tick_1ms,
irq_threshold_i => irq_threshold,
irq_timeout_i => irq_timeout,
timestamp_i => timestamp,
timestamp_valid_i => timestamp_stb,
ts_offset_o => ts_offset(i),
reset_seq_o => reset_seq(i),
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;
U_TheFifo : entity work.timestamp_fifo
generic map (
g_use_fifo_readout => g_use_fifo_readout)
port map (
clk_sys_i => clk_sys_i,
rst_sys_n_i => rst_sys_n_i,
slave_i => cnx_master_out(c_WB_SLAVE_TDC_CHANNEL0 + i),
slave_o => cnx_master_in(c_WB_SLAVE_TDC_CHANNEL0 + i),
irq_o => irq_fifo(i),
enable_i => channel_enable(i),
tick_i => tick_1ms,
irq_threshold_i => irq_threshold,
irq_timeout_i => irq_timeout,
timestamp_i => timestamp(i),
timestamp_valid_i => timestamp_stb(i),
ts_offset_o => ts_offset(i),
reset_seq_o => reset_seq(i),
raw_enable_o => raw_enable(i));
timestamp_stb(i) <= timestamp_valid(i) and timestamp_ready(i);
end generate gen_fifos;
gen_with_dma_readout : if g_use_dma_readout generate
U_DMA_Engine : entity work.tdc_dma_engine
......@@ -547,8 +544,8 @@ begin
wrabbit_utc_p <= '0';
else
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
-- comes exactly upon the UTC change
-- so that the end of the pulse comes exactly upon the UTC change
if unsigned(wrabbit_cycles_i) = (unsigned(c_CLK_PERIOD) - 3) then
wrabbit_utc_p <= '1';
else
wrabbit_utc_p <= '0';
......
......@@ -132,6 +132,14 @@ entity fmc_tdc_wrapper is
g_simulation : boolean := false;
-- implement direct TDC timestamp readout FIFO, used in the WR Node projects
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_fifo_readout : boolean := false;
g_use_fake_timestamps_for_sim : boolean := false
......@@ -242,18 +250,6 @@ end fmc_tdc_wrapper;
--=================================================================================================
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
signal clk_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
signal tdc_scl_out, tdc_scl_oen, tdc_sda_out, tdc_sda_oen : std_logic;
signal direct_timestamp : std_logic_vector(127 downto 0);
signal direct_timestamp_wr : std_logic;
signal timestamp : t_tdc_timestamp_array(4 downto 0);
signal timestamp_valid : std_logic_vector(4 downto 0);
constant c_cnx_slave_ports : integer := 2;
constant c_cnx_master_ports : integer := 2;
......@@ -322,16 +318,14 @@ begin
master_i => cnx_master_in,
master_o => cnx_master_out);
cmp_direct_readout : fmc_tdc_direct_readout
cmp_direct_readout : entity work.fmc_tdc_direct_readout
port map (
clk_tdc_i => clk_125m_mezz,
rst_tdc_n_i => rst_125m_mezz_n,
clk_sys_i => clk_sys_i,
rst_sys_n_i => rst_sys_n_i,
direct_timestamp_i => direct_timestamp,
direct_timestamp_wr_i => direct_timestamp_wr,
direct_slave_i => cnx_master_out(c_slave_direct),
direct_slave_o => cnx_master_in(c_slave_direct));
clk_sys_i => clk_sys_i,
rst_sys_n_i => rst_sys_n_i,
timestamp_i => timestamp,
timestamp_valid_i => timestamp_valid,
direct_slave_i => cnx_master_out(c_slave_direct),
direct_slave_o => cnx_master_in(c_slave_direct));
end generate gen_with_direct_readout;
......@@ -406,6 +400,8 @@ begin
(g_span => 32,
g_width => 32,
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_dma_readout => g_use_dma_readout,
g_use_fake_timestamps_for_sim => g_use_fake_timestamps_for_sim)
......@@ -482,8 +478,9 @@ begin
i2c_sda_o => tdc_sda_out,
-- 1-Wire on TDC mezzanine
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_valid_i => sim_timestamp_valid_i,
......
......@@ -6,17 +6,19 @@
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 2011-08-29
-- Last update: 2018-09-10
-- Last update: 2019-09-29
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Pipelined timestamp adder with re-normalization of the result.
-- 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
-- following constraints:
-- 1. 0 <= (a/b)_frac_i <= 2**g_frac_bits-1
-- 2. -g_coarse_range+1 <= (a_coarse_i + b_coarse_i) <= 3*g_coarse_range-1
-- 1. 0 <= a_tai + b_tai < 2**32 - 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
......@@ -60,7 +62,7 @@ entity tdc_ts_addsub is
a_i : in t_tdc_timestamp;
b_i : in t_tdc_timestamp;
valid_o : out std_logic;
q_o : out t_tdc_timestamp
);
......@@ -71,12 +73,12 @@ architecture rtl of tdc_ts_addsub is
constant c_NUM_PIPELINE_STAGES : integer := 4;
type t_internal_sum is record
tai : signed(32 downto 0);
coarse : signed(31 downto 0);
frac : signed(15 downto 0);
seq : std_logic_vector(31 downto 0);
meta : std_logic_vector(31 downto 0);
slope : std_logic;
tai : signed(32 downto 0);
coarse : signed(31 downto 0);
frac : signed(15 downto 0);
channel : std_logic_vector(2 downto 0);
meta : std_logic_vector(31 downto 0);
slope : std_logic;
end record;
type t_internal_sum_array is array (integer range <>) of t_internal_sum;
......@@ -88,7 +90,7 @@ architecture rtl of tdc_ts_addsub is
signal unf_frac : std_logic;
signal ovf_coarse : std_logic_vector(1 downto 0);
signal unf_coarse : std_logic_vector(1 downto 0);
begin -- rtl
-- Pipeline stage 0: just subtract the two timestamps field by field
......@@ -100,15 +102,13 @@ begin -- rtl
elsif(enable_i = '1') then
pipe(0) <= valid_i;
sums(0).tai <= signed( resize(unsigned(a_i.tai) + unsigned(b_i.tai), 33) );
sums(0).seq <= a_i.seq;
sums(0).slope <= a_i.slope;
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).channel <= a_i.channel;
sums(0).slope <= a_i.slope;
sums(0).meta <= a_i.meta;
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
pipe(0) <= '0';
end if;
......@@ -123,17 +123,16 @@ begin -- rtl
p_stage1 : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pipe(1) <= '0';
else
pipe(1) <= pipe(0);
sums(1).seq <= sums(0).seq;
sums(1).meta <= sums(0).meta;
sums(1).slope <= sums(0).slope;
sums(1) <= sums(0);
sums(1) <= sums(0);
sums(1) <= sums(0);
if(ovf_frac = '1') then
sums(1).frac <= sums(0).frac - g_frac_range;
sums(1).coarse <= sums(0).coarse + 1;
......@@ -145,7 +144,6 @@ begin -- rtl
sums(1).coarse <= sums(0).coarse;
end if;
sums(1).tai <= sums(0).tai;
end if;
end if;
end process;
......@@ -170,14 +168,14 @@ begin -- rtl
unf_coarse <= "00";
end if;
if ( sums(1).coarse >= g_frac_range ) then
if ( sums(1).coarse >= g_coarse_range ) then
ovf_coarse <= "10";
elsif ( sums(1).coarse >= 2*g_frac_range ) then
elsif ( sums(1).coarse >= 2*g_coarse_range ) then
ovf_coarse <= "01";
else
ovf_coarse <= "00";
end if;
end if;
end if;
end process;
......@@ -192,9 +190,7 @@ begin -- rtl
else
pipe(3) <= pipe(2);
sums(3).seq <= sums(2).seq;
sums(3).slope <= sums(2).slope;
sums(3).meta <= sums(2).meta;
sums(3) <= sums(2);
if(unf_coarse = "10") then
sums(3).coarse <= sums(2).coarse + g_coarse_range;
......@@ -213,18 +209,16 @@ begin -- rtl
sums(3).tai <= sums(2).tai;
end if;
sums(3).frac <= sums(2).frac;
end if;
end if;
end process;
-- clip the extra bits and output the result
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.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.seq <= sums(c_NUM_PIPELINE_STAGES-1).seq;
q_o.slope <= sums(c_NUM_PIPELINE_STAGES-1).slope;
q_o.meta <= sums(c_NUM_PIPELINE_STAGES-1).meta;
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.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.slope <= sums(c_NUM_PIPELINE_STAGES-1).slope;
q_o.meta <= sums(c_NUM_PIPELINE_STAGES-1).meta;
q_o.channel <= sums(c_NUM_PIPELINE_STAGES-1).channel;
end rtl;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : timestamp_fifo_wbgen2_pkg.vhd
-- 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
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/timestamp_fifo_wb.wb
......@@ -27,10 +27,6 @@ package tsf_wbgen2_pkg is
fifo_ts1_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);
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_tsf_in_registers_init_value: t_tsf_in_registers := (
......@@ -38,11 +34,7 @@ package tsf_wbgen2_pkg is
fifo_ts0_i => (others => '0'),
fifo_ts1_i => (others => '0'),
fifo_ts2_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'
fifo_ts3_i => (others => '0')
);
-- Output registers (WB slave -> user design)
......@@ -51,82 +43,64 @@ package tsf_wbgen2_pkg is
fifo_wr_full_o : std_logic;
fifo_wr_empty_o : std_logic;
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;
constant c_tsf_out_registers_init_value: t_tsf_out_registers := (
fifo_wr_full_o => '0',
fifo_wr_empty_o => '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'
fifo_wr_usedw_o => (others => '0')
);
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_vector) return std_logic_vector;
component timestamp_fifo_wb 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_tsf_in_registers;
regs_o : out t_tsf_out_registers
);
end component;
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_vector) return std_logic_vector;
component timestamp_fifo_wb 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_tsf_in_registers;
regs_o : out t_tsf_out_registers
);
end component;
end package;
package body tsf_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
if x = '1' then
return '1';
else
return '0';
end if;
end function;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
begin
for i in 0 to x'length-1 loop
if(x(i) = 'X' or x(i) = 'U') then
tmp(i):= '0';
function f_x_to_zero (x:std_logic) return std_logic is
begin
if x = '1' then
return '1';
else
tmp(i):=x(i);
end if;
end loop;
return tmp;
end function;
function "or" (left, right: t_tsf_in_registers) return t_tsf_in_registers is
variable tmp: t_tsf_in_registers;
begin
tmp.fifo_wr_req_i := f_x_to_zero(left.fifo_wr_req_i) or f_x_to_zero(right.fifo_wr_req_i);
tmp.fifo_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);
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;
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_tsf_in_registers) return t_tsf_in_registers is
variable tmp: t_tsf_in_registers;
begin
tmp.fifo_wr_req_i := f_x_to_zero(left.fifo_wr_req_i) or f_x_to_zero(right.fifo_wr_req_i);
tmp.fifo_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;
-- -*- 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
flags_bus = {FIFO_EMPTY, FIFO_FULL, FIFO_COUNT, FIFO_RESET};
flags_dev = {FIFO_EMPTY, FIFO_FULL, FIFO_COUNT, FIFO_RESET};
clock = "clk_tdc_i";
field {
name = "Seconds";
prefix = "SECONDS";
......@@ -53,7 +51,6 @@ peripheral
reg {
name = "Channel Enable Register";
prefix = "CHAN_ENABLE";
clock = "clk_tdc_i";
field {
name = "Channel enable";
size = 5;
......@@ -66,8 +63,6 @@ peripheral
reg {
name = "Dead Time Register";
prefix = "DEAD_TIME";
clock = "clk_tdc_i";
field {
name = "Dead time (8ns ticks)";
size = 24;
......@@ -76,4 +71,4 @@ peripheral
access_dev = READ_ONLY;
};
};
};
\ No newline at end of file
};
......@@ -45,134 +45,4 @@ peripheral {
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