Commit 62381a0d authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

hdl: added hardware offset support

parent c3737bf7
......@@ -29,7 +29,7 @@ files = [
"tdc_dma_engine.vhd",
"tdc_buffer_control_regs.vhd",
"tdc_buffer_control_regs_wbgen2_pkg.vhd",
"tdc_ts_sub.vhd",
"tdc_ts_addsub.vhd",
"wbgen2_eic_nomask.vhd",
"dma_eic.vhd"
];
......
#!/bin/bash
wbgen2 -V timestamp_fifo_wb.vhd -H record_full -p timestamp_fifo_wbgen2_pkg.vhd -K timestamp_fifo_regs.vh -s defines -C timestamp_fifo_regs.h -D wbgen/timestamp_fifo_wb.html wbgen/timestamp_fifo_wb.wb
wbgen2 -V tdc_buffer_control_regs.vhd -H record_full -p tdc_buffer_control_regs_wbgen2_pkg.vhd -K tdc_buffer_control_regs.vh -s defines -C tdc_buffer_control_regs.h wbgen/tdc_buffer_control_regs.wb
#wbgen2 -V tdc_buffer_control_regs.vhd -H record_full -p tdc_buffer_control_regs_wbgen2_pkg.vhd -K tdc_buffer_control_regs.vh -s defines -C tdc_buffer_control_regs.h wbgen/tdc_buffer_control_regs.wb
#don't do this, latest wbgen is buggy
wbgen2 -V tdc_eic.vhd -s defines -C tdc_eic.h -D wbgen/tdc_eic.html wbgen/tdc_eic.wb
#wbgen2 -V tdc_eic.vhd -s defines -C tdc_eic.h -D wbgen/tdc_eic.html wbgen/tdc_eic.wb
......@@ -211,6 +211,8 @@ entity fmc_tdc_core is
cfg_slave_i : in t_wishbone_slave_in;
cfg_slave_o : out t_wishbone_slave_out;
ts_offset_i : in t_tdc_timestamp_array(4 downto 0);
reset_seq_i : in std_logic_vector(4 downto 0);
timestamp_o : out t_tdc_timestamp_array(4 downto 0);
timestamp_valid_o : out std_logic_vector(4 downto 0);
timestamp_ready_i : in std_logic_vector(4 downto 0);
......@@ -547,7 +549,9 @@ begin
ts_valid_i => raw_timestamp_valid,
ts_o => final_timestamp,
ts_valid_o => final_timestamp_valid,
ts_ready_i => final_timestamp_ready
ts_ready_i => final_timestamp_ready,
ts_offset_i => ts_offset_i,
reset_seq_i => reset_seq_i
);
......
......@@ -276,6 +276,8 @@ architecture rtl of fmc_tdc_mezzanine is
signal tick_1ms : std_logic;
signal counter_1ms : unsigned(17 downto 0);
signal ts_offset : t_tdc_timestamp_array(4 downto 0);
signal reset_seq : std_logic_vector(4 downto 0);
function f_wb_shift_address_word (w : t_wishbone_master_out) return t_wishbone_master_out is
variable r : t_wishbone_master_out;
......@@ -376,6 +378,9 @@ begin
timestamp_valid_o => tdc_timestamp_valid,
timestamp_ready_i => tdc_timestamp_ready,
ts_offset_i => ts_offset,
reset_seq_i => reset_seq,
irq_threshold_o => irq_threshold,
irq_timeout_o => irq_timeout,
channel_enable_o => channel_enable
......@@ -428,7 +433,9 @@ begin
irq_threshold_i => irq_threshold,
irq_timeout_i => irq_timeout,
timestamp_i => timestamp,
timestamp_valid_i => timestamp_stb);
timestamp_valid_i => timestamp_stb,
ts_offset_o => ts_offset(i),
reset_seq_o => reset_seq(i));
timestamp_stb(i) <= timestamp_valid(i) and timestamp_ready(i);
end generate gen_fifos;
......
-------------------------------------------------------------------------------
-- Title : Pipelined timestamp subtractor
-- Project : FMC TDC Core
-------------------------------------------------------------------------------
-- File : tdc_ts_sub.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 2011-08-29
-- Last update: 2018-08-06
-- 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.
-- 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
-------------------------------------------------------------------------------
--
-- Copyright (c) 2011 CERN / BE-CO-HT
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.tdc_core_pkg.all;
entity tdc_ts_addsub is
generic(
g_frac_range : integer := 4096;
g_coarse_range : integer := 125000000
);
port(
clk_i : in std_logic;
rst_n_i : in std_logic;
valid_i : in std_logic; -- when HI, a_* and b_* contain valid timestamps
enable_i : in std_logic := '1'; -- pipeline enable
a_i : in t_tdc_timestamp;
b_i : in t_tdc_timestamp;
valid_o : out std_logic;
q_o : out t_tdc_timestamp
);
end tdc_ts_addsub;
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);
slope : std_logic;
end record;
type t_internal_sum_array is array (integer range <>) of t_internal_sum;
signal pipe : std_logic_vector(c_NUM_PIPELINE_STAGES-1 downto 0);
signal sums : t_internal_sum_array(0 to c_NUM_PIPELINE_STAGES-1);
signal ovf_frac : std_logic;
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
p_stage0 : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pipe(0) <= '0';
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;
if( b_i.tai(31) = '1' ) then -- TAI negative, we subtract
sums(0).frac <= signed( resize(unsigned(a_i.frac) - unsigned(b_i.frac), 16) );
sums(0).coarse <= resize(signed(a_i.coarse), sums(0).coarse'length) -
resize(signed(b_i.coarse), sums(0).coarse'length);
else
sums(0).frac <= signed( resize(unsigned(a_i.frac) + unsigned(b_i.frac), 16) );
sums(0).coarse <= resize(signed(a_i.coarse), sums(0).coarse'length) +
resize(signed(b_i.coarse), sums(0).coarse'length);
end if;
else
pipe(0) <= '0';
end if;
end if;
end process;
unf_frac <= '1' when sums(0).frac < 0 else '0';
ovf_frac <= '1' when sums(0).frac >= g_frac_range else '0';
-- Pipeline stage 1: check the fractional difference for underflow and eventually adjust
-- the coarse difference
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).slope <= sums(0).slope;
if(ovf_frac = '1') then
sums(1).frac <= sums(0).frac - g_frac_range;
sums(1).coarse <= sums(0).coarse + 1;
elsif (unf_frac = '1') then
sums(1).frac <= sums(0).frac + g_frac_range;
sums(1).coarse <= sums(0).coarse - 1;
else
sums(1).frac <= sums(0).frac;
sums(1).coarse <= sums(0).coarse;
end if;
sums(1).tai <= sums(0).tai;
end if;
end if;
end process;
-- Pipeline stage 2: check the coarse sum for under/overflows
p_stage2 : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pipe(2) <= '0';
else
sums(2) <= sums(1);
pipe(2) <= pipe(1);
if(sums(1).coarse < 0) then
unf_coarse <= "10";
elsif(sums(1).coarse <= -g_coarse_range) then
unf_coarse <= "01";
else
unf_coarse <= "00";
end if;
if ( sums(1).coarse >= g_frac_range ) then
ovf_coarse <= "10";
elsif ( sums(1).coarse >= 2*g_frac_range ) then
ovf_coarse <= "01";
else
ovf_coarse <= "00";
end if;
end if;
end if;
end process;
-- Pipeline stage 3: adjust the coarse & TAI sums according to normalize the
-- previously detected under/overflows
p_stage3 : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pipe(3) <= '0';
else
pipe(3) <= pipe(2);
sums(3).seq <= sums(2).seq;
sums(3).slope <= sums(2).slope;
if(unf_coarse = "10") then
sums(3).coarse <= sums(2).coarse + g_coarse_range;
sums(3).tai <= sums(2).tai - 1;
elsif(unf_coarse = "01") then
sums(3).coarse <= sums(2).coarse + 2*g_coarse_range;
sums(3).tai <= sums(2).tai - 2;
elsif(ovf_coarse = "10" ) then
sums(3).coarse <= sums(2).coarse - g_coarse_range;
sums(3).tai <= sums(2).tai + 1;
elsif(ovf_coarse = "01") then
sums(3).coarse <= sums(2).coarse - 2*g_coarse_range;
sums(3).tai <= sums(2).tai + 2;
else
sums(3).coarse <= sums(2).coarse;
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;
end rtl;
This diff is collapsed.
......@@ -48,7 +48,10 @@ entity timestamp_fifo is
irq_timeout_i : in std_logic_vector(9 downto 0);
timestamp_i : in t_tdc_timestamp_array(4 downto 0);
timestamp_valid_i : in std_logic_vector(4 downto 0)
timestamp_valid_i : in std_logic_vector(4 downto 0);
ts_offset_o : out t_tdc_timestamp;
reset_seq_o : out std_logic
);
end entity;
......@@ -68,30 +71,31 @@ architecture rtl of timestamp_fifo is
signal timestamp_with_seq : std_logic_vector(127 downto 0);
signal ref_valid : std_logic;
signal ref_valid : std_logic;
signal ref_ts : t_tdc_timestamp;
signal ref_channel : integer range 0 to 4;
signal sub_valid : std_logic;
signal sub_in_valid, sub_out_valid : std_logic;
signal sub_result : t_tdc_timestamp;
signal sub_result_latched : t_tdc_timestamp;
signal sub_out_valid_latched : std_logic;
begin
--timestamp_with_seq(31 downto 0) <= std_logic_vector(resize(unsigned(timestamp_i(g_channel).tai), 32));
--timestamp_with_seq(63 downto 32) <= std_logic_vector(resize(unsigned(timestamp_i(g_channel).coarse), 32));
--timestamp_with_seq(95 downto 64) <= std_logic_vector(resize(unsigned(timestamp_i(g_channel).frac), 32));
--timestamp_with_seq(98 downto 96) <= timestamp_i(g_channel).channel;
--timestamp_with_seq(99) <= timestamp_i(g_channel).slope;
--timestamp_with_seq(127 downto 100) <= timestamp_i(g_channel).seq(27 downto 0);
ts_offset_o.tai <= regs_out.offset1_o;
ts_offset_o.coarse <= regs_out.offset2_o;
ts_offset_o.frac <= regs_out.offset3_o(11 downto 0);
reset_seq_o <= regs_out.csr_rst_seq_o;
timestamp_with_seq(31 downto 0) <= std_logic_vector(resize(unsigned(timestamp_i(g_channel).raw.tai), 32));
timestamp_with_seq(63 downto 32) <= std_logic_vector(resize(unsigned(timestamp_i(g_channel).raw.coarse), 32));
timestamp_with_seq(95 downto 64) <= std_logic_vector(resize(unsigned(timestamp_i(g_channel).raw.n_bins), 32));
timestamp_with_seq(98 downto 96) <= timestamp_i(g_channel).raw.channel;
timestamp_with_seq(99) <= timestamp_i(g_channel).raw.slope;
timestamp_with_seq(127 downto 100) <= timestamp_i(g_channel).seq(27 downto 0);
timestamp_with_seq(31 downto 0) <= std_logic_vector(resize(unsigned(timestamp_i(g_channel).tai), 32));
timestamp_with_seq(63 downto 32) <= std_logic_vector(resize(unsigned(timestamp_i(g_channel).coarse), 32));
timestamp_with_seq(95 downto 64) <= std_logic_vector(resize(unsigned(timestamp_i(g_channel).frac), 32));
timestamp_with_seq(98 downto 96) <= timestamp_i(g_channel).channel;
timestamp_with_seq(99) <= timestamp_i(g_channel).slope;
timestamp_with_seq(127 downto 100) <= timestamp_i(g_channel).seq(27 downto 0);
U_WB_Slave : entity work.timestamp_fifo_wb
......@@ -155,7 +159,30 @@ begin
b_i => ref_ts,
valid_o => sub_out_valid,
q_o => sub_result);
p_latch_deltas : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_sys_n_i = '0' or enable_i = '0' then
sub_out_valid_latched <= '0';
else
if regs_out.csr_delta_read_o = '1' then
sub_out_valid_latched <= '0';
regs_in.delta1_i <= sub_result_latched.tai;
regs_in.delta2_i <= sub_result_latched.coarse;
regs_in.delta3_i <= x"00000" & sub_result_latched.frac;
end if;
if(sub_out_valid = '1') then
sub_out_valid_latched <= '1';
sub_result_latched <= sub_result;
end if;
end if;
end if;
end process;
regs_in.csr_delta_ready_i <= sub_out_valid_latched;
p_coalesce_irq : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
......
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : timestamp_fifo_wb.vhd
-- Author : auto-generated by wbgen2 from wbgen/timestamp_fifo_wb.wb
-- Created : Mon Aug 6 23:30:18 2018
-- Created : Thu Aug 30 21:26:01 2018
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/timestamp_fifo_wb.wb
......@@ -38,6 +38,11 @@ signal tsf_fifo_in_int : std_logic_vector(127 downto 0)
signal tsf_fifo_out_int : std_logic_vector(127 downto 0);
signal tsf_fifo_rdreq_int : std_logic ;
signal tsf_fifo_rdreq_int_d0 : std_logic ;
signal tsf_offset1_int : std_logic_vector(31 downto 0);
signal tsf_offset2_int : std_logic_vector(31 downto 0);
signal tsf_offset3_int : std_logic_vector(31 downto 0);
signal tsf_csr_delta_read_dly0 : std_logic ;
signal tsf_csr_delta_read_int : std_logic ;
signal tsf_csr_rst_seq_dly0 : std_logic ;
signal tsf_csr_rst_seq_int : std_logic ;
signal tsf_csr_delta_ref_int : std_logic_vector(2 downto 0);
......@@ -67,7 +72,10 @@ begin
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
regs_o.csr_delta_valid_load_o <= '0';
tsf_offset1_int <= "00000000000000000000000000000000";
tsf_offset2_int <= "00000000000000000000000000000000";
tsf_offset3_int <= "00000000000000000000000000000000";
tsf_csr_delta_read_int <= '0';
tsf_csr_rst_seq_int <= '0';
tsf_csr_delta_ref_int <= "000";
tsf_fifo_clear_bus_int <= '0';
......@@ -78,12 +86,11 @@ begin
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
regs_o.csr_delta_valid_load_o <= '0';
tsf_csr_delta_read_int <= '0';
tsf_csr_rst_seq_int <= '0';
tsf_fifo_clear_bus_int <= '0';
ack_in_progress <= '0';
else
regs_o.csr_delta_valid_load_o <= '0';
end if;
else
if ((slave_i.cyc = '1') and (slave_i.stb = '1')) then
......@@ -91,37 +98,52 @@ begin
when "0000" =>
if (slave_i.we = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.delta0_i;
rddata_reg(31 downto 0) <= regs_i.delta1_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "0001" =>
if (slave_i.we = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.delta1_i;
rddata_reg(31 downto 0) <= regs_i.delta2_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "0010" =>
if (slave_i.we = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.delta2_i;
rddata_reg(31 downto 0) <= regs_i.delta3_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "0011" =>
if (slave_i.we = '1') then
tsf_offset1_int <= wrdata_reg(31 downto 0);
end if;
rddata_reg(31 downto 0) <= regs_i.delta3_i;
rddata_reg(31 downto 0) <= tsf_offset1_int;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "0100" =>
if (slave_i.we = '1') then
regs_o.csr_delta_valid_load_o <= '1';
tsf_csr_rst_seq_int <= wrdata_reg(1);
tsf_csr_delta_ref_int <= wrdata_reg(4 downto 2);
tsf_offset2_int <= wrdata_reg(31 downto 0);
end if;
rddata_reg(31 downto 0) <= tsf_offset2_int;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "0101" =>
if (slave_i.we = '1') then
tsf_offset3_int <= wrdata_reg(31 downto 0);
end if;
rddata_reg(31 downto 0) <= tsf_offset3_int;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "0110" =>
if (slave_i.we = '1') then
tsf_csr_delta_read_int <= wrdata_reg(1);
tsf_csr_rst_seq_int <= wrdata_reg(2);
tsf_csr_delta_ref_int <= wrdata_reg(5 downto 3);
end if;
rddata_reg(0) <= regs_i.csr_delta_valid_i;
rddata_reg(0) <= regs_i.csr_delta_ready_i;
rddata_reg(1) <= '0';
rddata_reg(4 downto 2) <= tsf_csr_delta_ref_int;
rddata_reg(5) <= 'X';
rddata_reg(2) <= '0';
rddata_reg(5 downto 3) <= tsf_csr_delta_ref_int;
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
......@@ -150,7 +172,7 @@ begin
rddata_reg(31) <= 'X';
ack_sreg(2) <= '1';
ack_in_progress <= '1';
when "0101" =>
when "0111" =>
if (slave_i.we = '1') then
end if;
if (tsf_fifo_rdreq_int_d0 = '0') then
......@@ -160,25 +182,25 @@ begin
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end if;
when "0110" =>
when "1000" =>
if (slave_i.we = '1') then
end if;
rddata_reg(31 downto 0) <= tsf_fifo_out_int(63 downto 32);
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "0111" =>
when "1001" =>
if (slave_i.we = '1') then
end if;
rddata_reg(31 downto 0) <= tsf_fifo_out_int(95 downto 64);
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "1000" =>
when "1010" =>
if (slave_i.we = '1') then
end if;
rddata_reg(31 downto 0) <= tsf_fifo_out_int(127 downto 96);
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "1001" =>
when "1011" =>
if (slave_i.we = '1') then
if (wrdata_reg(18) = '1') then
tsf_fifo_clear_bus_int <= '1';
......@@ -253,12 +275,29 @@ tsf_fifo_INST : wbgen2_fifo_sync
rd_data_o => tsf_fifo_out_int
);
-- Delta Timestamp Word 0
-- Delta Timestamp Word 1
-- Delta Timestamp Word 2
-- Delta Timestamp Word 3
-- Delta Timestamp Valid
regs_o.csr_delta_valid_o <= wrdata_reg(0);
-- 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 <= tsf_offset1_int;
-- Channel Offset Word 2 (8ns ticks, unsigned)
regs_o.offset2_o <= tsf_offset2_int;
-- Channel Offset Word 3 (fractional part, unsigned)
regs_o.offset3_o <= tsf_offset3_int;
-- Delta Timestamp Ready
-- Read Delta Timestamp
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
tsf_csr_delta_read_dly0 <= '0';
regs_o.csr_delta_read_o <= '0';
elsif rising_edge(clk_sys_i) then
tsf_csr_delta_read_dly0 <= tsf_csr_delta_read_int;
regs_o.csr_delta_read_o <= tsf_csr_delta_read_int and (not tsf_csr_delta_read_dly0);
end if;
end process;
-- Reset Sequence Counter
process (clk_sys_i, rst_n_i)
begin
......
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : timestamp_fifo_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from wbgen/timestamp_fifo_wb.wb
-- Created : Mon Aug 6 23:30:18 2018
-- Created : Thu Aug 30 21:26:01 2018
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/timestamp_fifo_wb.wb
......@@ -27,11 +27,10 @@ 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);
delta0_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_valid_i : std_logic;
csr_delta_ready_i : std_logic;
end record;
constant c_tsf_in_registers_init_value: t_tsf_in_registers := (
......@@ -40,11 +39,10 @@ package tsf_wbgen2_pkg is
fifo_ts1_i => (others => '0'),
fifo_ts2_i => (others => '0'),
fifo_ts3_i => (others => '0'),
delta0_i => (others => '0'),
delta1_i => (others => '0'),
delta2_i => (others => '0'),
delta3_i => (others => '0'),
csr_delta_valid_i => '0'
csr_delta_ready_i => '0'
);
-- Output registers (WB slave -> user design)
......@@ -53,8 +51,10 @@ 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);
csr_delta_valid_o : std_logic;
csr_delta_valid_load_o : std_logic;
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);
end record;
......@@ -63,8 +63,10 @@ package tsf_wbgen2_pkg is
fifo_wr_full_o => '0',
fifo_wr_empty_o => '0',
fifo_wr_usedw_o => (others => '0'),
csr_delta_valid_o => '0',
csr_delta_valid_load_o => '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')
);
......@@ -118,11 +120,10 @@ begin
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.delta0_i := f_x_to_zero(left.delta0_i) or f_x_to_zero(right.delta0_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_valid_i := f_x_to_zero(left.csr_delta_valid_i) or f_x_to_zero(right.csr_delta_valid_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;
......
......@@ -47,25 +47,12 @@ peripheral {
};
reg {
name = "Delta Timestamp word 0";
prefix = "DELTA0";
field {
name = "Delta Timestamp Word 0";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Delta Timestamp Word 1";
prefix = "DELTA1";
field {
name = "Delta Timestamp Word 1";
name = "Delta Timestamp Word 1 (TAI cycles, signed)";
type = SLV;
size = 32;
access_bus = READ_ONLY;
......@@ -78,7 +65,7 @@ peripheral {
prefix = "DELTA2";
field {
name = "Delta Timestamp Word 2";
name = "Delta Timestamp Word 2 (8ns ticks, unsigned)";
type = SLV;
size = 32;
access_bus = READ_ONLY;
......@@ -92,7 +79,7 @@ peripheral {
prefix = "DELTA3";
field {
name = "Delta Timestamp Word 3";
name = "Delta Timestamp Word 3 (fractional part, unsigned)";
type = SLV;
size = 32;
access_bus = READ_ONLY;
......@@ -100,20 +87,62 @@ peripheral {
};
};
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 Valid";
prefix = "DELTA_VALID";
name = "Delta Timestamp Ready";
prefix = "DELTA_READY";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
load = LOAD_EXT;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field {
name = "Read Delta Timestamp";
prefix = "DELTA_READ";
type = MONOSTABLE;
};
field {
......
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