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

hdl: added hardware offset support

parent c3737bf7
...@@ -29,7 +29,7 @@ files = [ ...@@ -29,7 +29,7 @@ files = [
"tdc_dma_engine.vhd", "tdc_dma_engine.vhd",
"tdc_buffer_control_regs.vhd", "tdc_buffer_control_regs.vhd",
"tdc_buffer_control_regs_wbgen2_pkg.vhd", "tdc_buffer_control_regs_wbgen2_pkg.vhd",
"tdc_ts_sub.vhd", "tdc_ts_addsub.vhd",
"wbgen2_eic_nomask.vhd", "wbgen2_eic_nomask.vhd",
"dma_eic.vhd" "dma_eic.vhd"
]; ];
......
#!/bin/bash #!/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 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 #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 ...@@ -211,6 +211,8 @@ entity fmc_tdc_core is
cfg_slave_i : in t_wishbone_slave_in; cfg_slave_i : in t_wishbone_slave_in;
cfg_slave_o : out t_wishbone_slave_out; 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_o : out t_tdc_timestamp_array(4 downto 0);
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);
...@@ -547,7 +549,9 @@ begin ...@@ -547,7 +549,9 @@ begin
ts_valid_i => raw_timestamp_valid, ts_valid_i => raw_timestamp_valid,
ts_o => final_timestamp, ts_o => final_timestamp,
ts_valid_o => final_timestamp_valid, 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 ...@@ -276,6 +276,8 @@ architecture rtl of fmc_tdc_mezzanine is
signal tick_1ms : std_logic; signal tick_1ms : std_logic;
signal counter_1ms : unsigned(17 downto 0); 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 function f_wb_shift_address_word (w : t_wishbone_master_out) return t_wishbone_master_out is
variable r : t_wishbone_master_out; variable r : t_wishbone_master_out;
...@@ -376,6 +378,9 @@ begin ...@@ -376,6 +378,9 @@ begin
timestamp_valid_o => tdc_timestamp_valid, timestamp_valid_o => tdc_timestamp_valid,
timestamp_ready_i => tdc_timestamp_ready, timestamp_ready_i => tdc_timestamp_ready,
ts_offset_i => ts_offset,
reset_seq_i => reset_seq,
irq_threshold_o => irq_threshold, irq_threshold_o => irq_threshold,
irq_timeout_o => irq_timeout, irq_timeout_o => irq_timeout,
channel_enable_o => channel_enable channel_enable_o => channel_enable
...@@ -428,7 +433,9 @@ begin ...@@ -428,7 +433,9 @@ begin
irq_threshold_i => irq_threshold, irq_threshold_i => irq_threshold,
irq_timeout_i => irq_timeout, irq_timeout_i => irq_timeout,
timestamp_i => timestamp, 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); timestamp_stb(i) <= timestamp_valid(i) and timestamp_ready(i);
end generate gen_fifos; 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 ...@@ -48,7 +48,10 @@ entity timestamp_fifo is
irq_timeout_i : in std_logic_vector(9 downto 0); irq_timeout_i : in std_logic_vector(9 downto 0);
timestamp_i : in t_tdc_timestamp_array(4 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; end entity;
...@@ -68,30 +71,31 @@ architecture rtl of timestamp_fifo is ...@@ -68,30 +71,31 @@ architecture rtl of timestamp_fifo is
signal timestamp_with_seq : std_logic_vector(127 downto 0); 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_ts : t_tdc_timestamp;
signal ref_channel : integer range 0 to 4; signal ref_channel : integer range 0 to 4;
signal sub_valid : std_logic; signal sub_valid : std_logic;
signal sub_in_valid, sub_out_valid : std_logic; signal sub_in_valid, sub_out_valid : std_logic;
signal sub_result : t_tdc_timestamp; signal sub_result : t_tdc_timestamp;
signal sub_result_latched : t_tdc_timestamp;
signal sub_out_valid_latched : std_logic;
begin 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)); ts_offset_o.tai <= regs_out.offset1_o;
--timestamp_with_seq(95 downto 64) <= std_logic_vector(resize(unsigned(timestamp_i(g_channel).frac), 32)); ts_offset_o.coarse <= regs_out.offset2_o;
--timestamp_with_seq(98 downto 96) <= timestamp_i(g_channel).channel; ts_offset_o.frac <= regs_out.offset3_o(11 downto 0);
--timestamp_with_seq(99) <= timestamp_i(g_channel).slope; reset_seq_o <= regs_out.csr_rst_seq_o;
--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).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 U_WB_Slave : entity work.timestamp_fifo_wb
...@@ -155,7 +159,30 @@ begin ...@@ -155,7 +159,30 @@ begin
b_i => ref_ts, b_i => ref_ts,
valid_o => sub_out_valid, valid_o => sub_out_valid,
q_o => sub_result); 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) p_coalesce_irq : process(clk_sys_i)
begin begin
if rising_edge(clk_sys_i) then if rising_edge(clk_sys_i) then
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
-- File : timestamp_fifo_wb.vhd -- File : timestamp_fifo_wb.vhd
-- Author : auto-generated by wbgen2 from wbgen/timestamp_fifo_wb.wb -- 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 -- 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
...@@ -38,6 +38,11 @@ signal tsf_fifo_in_int : std_logic_vector(127 downto 0) ...@@ -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_out_int : std_logic_vector(127 downto 0);
signal tsf_fifo_rdreq_int : std_logic ; signal tsf_fifo_rdreq_int : std_logic ;
signal tsf_fifo_rdreq_int_d0 : 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_dly0 : std_logic ;
signal tsf_csr_rst_seq_int : std_logic ; signal tsf_csr_rst_seq_int : std_logic ;
signal tsf_csr_delta_ref_int : std_logic_vector(2 downto 0); signal tsf_csr_delta_ref_int : std_logic_vector(2 downto 0);
...@@ -67,7 +72,10 @@ begin ...@@ -67,7 +72,10 @@ begin
ack_sreg <= "0000000000"; ack_sreg <= "0000000000";
ack_in_progress <= '0'; ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000"; 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_rst_seq_int <= '0';
tsf_csr_delta_ref_int <= "000"; tsf_csr_delta_ref_int <= "000";
tsf_fifo_clear_bus_int <= '0'; tsf_fifo_clear_bus_int <= '0';
...@@ -78,12 +86,11 @@ begin ...@@ -78,12 +86,11 @@ begin
ack_sreg(9) <= '0'; ack_sreg(9) <= '0';
if (ack_in_progress = '1') then if (ack_in_progress = '1') then
if (ack_sreg(0) = '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_csr_rst_seq_int <= '0';
tsf_fifo_clear_bus_int <= '0'; tsf_fifo_clear_bus_int <= '0';
ack_in_progress <= '0'; ack_in_progress <= '0';
else else
regs_o.csr_delta_valid_load_o <= '0';
end if; end if;
else else
if ((slave_i.cyc = '1') and (slave_i.stb = '1')) then if ((slave_i.cyc = '1') and (slave_i.stb = '1')) then
...@@ -91,37 +98,52 @@ begin ...@@ -91,37 +98,52 @@ begin
when "0000" => when "0000" =>
if (slave_i.we = '1') then if (slave_i.we = '1') then
end if; 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_sreg(0) <= '1';
ack_in_progress <= '1'; ack_in_progress <= '1';
when "0001" => when "0001" =>
if (slave_i.we = '1') then if (slave_i.we = '1') then
end if; 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_sreg(0) <= '1';
ack_in_progress <= '1'; ack_in_progress <= '1';
when "0010" => when "0010" =>
if (slave_i.we = '1') then if (slave_i.we = '1') then
end if; 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_sreg(0) <= '1';
ack_in_progress <= '1'; ack_in_progress <= '1';
when "0011" => when "0011" =>
if (slave_i.we = '1') then if (slave_i.we = '1') then
tsf_offset1_int <= wrdata_reg(31 downto 0);
end if; end if;
rddata_reg(31 downto 0) <= regs_i.delta3_i; rddata_reg(31 downto 0) <= tsf_offset1_int;
ack_sreg(0) <= '1'; ack_sreg(0) <= '1';
ack_in_progress <= '1'; ack_in_progress <= '1';
when "0100" => when "0100" =>
if (slave_i.we = '1') then if (slave_i.we = '1') then
regs_o.csr_delta_valid_load_o <= '1'; tsf_offset2_int <= wrdata_reg(31 downto 0);
tsf_csr_rst_seq_int <= wrdata_reg(1); end if;
tsf_csr_delta_ref_int <= wrdata_reg(4 downto 2); 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; 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(1) <= '0';
rddata_reg(4 downto 2) <= tsf_csr_delta_ref_int; rddata_reg(2) <= '0';
rddata_reg(5) <= 'X'; rddata_reg(5 downto 3) <= tsf_csr_delta_ref_int;
rddata_reg(6) <= 'X'; rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X'; rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X'; rddata_reg(8) <= 'X';
...@@ -150,7 +172,7 @@ begin ...@@ -150,7 +172,7 @@ begin
rddata_reg(31) <= 'X'; rddata_reg(31) <= 'X';
ack_sreg(2) <= '1'; ack_sreg(2) <= '1';
ack_in_progress <= '1'; ack_in_progress <= '1';
when "0101" => when "0111" =>
if (slave_i.we = '1') then if (slave_i.we = '1') then
end if; end if;
if (tsf_fifo_rdreq_int_d0 = '0') then if (tsf_fifo_rdreq_int_d0 = '0') then
...@@ -160,25 +182,25 @@ begin ...@@ -160,25 +182,25 @@ begin
ack_in_progress <= '1'; ack_in_progress <= '1';
ack_sreg(0) <= '1'; ack_sreg(0) <= '1';
end if; end if;
when "0110" => when "1000" =>
if (slave_i.we = '1') then if (slave_i.we = '1') then
end if; end if;
rddata_reg(31 downto 0) <= tsf_fifo_out_int(63 downto 32); rddata_reg(31 downto 0) <= tsf_fifo_out_int(63 downto 32);
ack_sreg(0) <= '1'; ack_sreg(0) <= '1';
ack_in_progress <= '1'; ack_in_progress <= '1';
when "0111" => when "1001" =>
if (slave_i.we = '1') then if (slave_i.we = '1') then
end if; end if;
rddata_reg(31 downto 0) <= tsf_fifo_out_int(95 downto 64); rddata_reg(31 downto 0) <= tsf_fifo_out_int(95 downto 64);
ack_sreg(0) <= '1'; ack_sreg(0) <= '1';
ack_in_progress <= '1'; ack_in_progress <= '1';
when "1000" => when "1010" =>
if (slave_i.we = '1') then if (slave_i.we = '1') then
end if; end if;
rddata_reg(31 downto 0) <= tsf_fifo_out_int(127 downto 96); rddata_reg(31 downto 0) <= tsf_fifo_out_int(127 downto 96);
ack_sreg(0) <= '1'; ack_sreg(0) <= '1';
ack_in_progress <= '1'; ack_in_progress <= '1';
when "1001" => when "1011" =>
if (slave_i.we = '1') then if (slave_i.we = '1') then
if (wrdata_reg(18) = '1') then if (wrdata_reg(18) = '1') then
tsf_fifo_clear_bus_int <= '1'; tsf_fifo_clear_bus_int <= '1';
...@@ -253,12 +275,29 @@ tsf_fifo_INST : wbgen2_fifo_sync ...@@ -253,12 +275,29 @@ tsf_fifo_INST : wbgen2_fifo_sync
rd_data_o => tsf_fifo_out_int rd_data_o => tsf_fifo_out_int
); );
-- Delta Timestamp Word 0 -- Delta Timestamp Word 1 (TAI cycles, signed)
-- Delta Timestamp Word 1 -- Delta Timestamp Word 2 (8ns ticks, unsigned)
-- Delta Timestamp Word 2 -- Delta Timestamp Word 3 (fractional part, unsigned)
-- Delta Timestamp Word 3 -- Channel Offset Word 1 (TAI cycles, signed)
-- Delta Timestamp Valid regs_o.offset1_o <= tsf_offset1_int;
regs_o.csr_delta_valid_o <= wrdata_reg(0); -- 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 -- Reset Sequence Counter
process (clk_sys_i, rst_n_i) process (clk_sys_i, rst_n_i)
begin begin
......
...@@ -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 : Mon Aug 6 23:30:18 2018 -- Created : Thu Aug 30 21:26:01 2018
-- 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,11 +27,10 @@ package tsf_wbgen2_pkg is ...@@ -27,11 +27,10 @@ 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);
delta0_i : std_logic_vector(31 downto 0);
delta1_i : std_logic_vector(31 downto 0); delta1_i : std_logic_vector(31 downto 0);
delta2_i : std_logic_vector(31 downto 0); delta2_i : std_logic_vector(31 downto 0);
delta3_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; end record;
constant c_tsf_in_registers_init_value: t_tsf_in_registers := ( constant c_tsf_in_registers_init_value: t_tsf_in_registers := (
...@@ -40,11 +39,10 @@ package tsf_wbgen2_pkg is ...@@ -40,11 +39,10 @@ package tsf_wbgen2_pkg is
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'),
delta0_i => (others => '0'),
delta1_i => (others => '0'), delta1_i => (others => '0'),
delta2_i => (others => '0'), delta2_i => (others => '0'),
delta3_i => (others => '0'), delta3_i => (others => '0'),
csr_delta_valid_i => '0' csr_delta_ready_i => '0'
); );
-- Output registers (WB slave -> user design) -- Output registers (WB slave -> user design)
...@@ -53,8 +51,10 @@ package tsf_wbgen2_pkg is ...@@ -53,8 +51,10 @@ 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);
csr_delta_valid_o : std_logic; offset1_o : std_logic_vector(31 downto 0);
csr_delta_valid_load_o : std_logic; 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_rst_seq_o : std_logic;
csr_delta_ref_o : std_logic_vector(2 downto 0); csr_delta_ref_o : std_logic_vector(2 downto 0);
end record; end record;
...@@ -63,8 +63,10 @@ package tsf_wbgen2_pkg is ...@@ -63,8 +63,10 @@ package tsf_wbgen2_pkg is
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'),
csr_delta_valid_o => '0', offset1_o => (others => '0'),
csr_delta_valid_load_o => '0', offset2_o => (others => '0'),
offset3_o => (others => '0'),
csr_delta_read_o => '0',
csr_rst_seq_o => '0', csr_rst_seq_o => '0',
csr_delta_ref_o => (others => '0') csr_delta_ref_o => (others => '0')
); );
...@@ -118,11 +120,10 @@ begin ...@@ -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_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_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.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.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.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.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; return tmp;
end function; end function;
......
...@@ -47,25 +47,12 @@ peripheral { ...@@ -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 { reg {
name = "Delta Timestamp Word 1"; name = "Delta Timestamp Word 1";
prefix = "DELTA1"; prefix = "DELTA1";
field { field {
name = "Delta Timestamp Word 1"; name = "Delta Timestamp Word 1 (TAI cycles, signed)";
type = SLV; type = SLV;
size = 32; size = 32;
access_bus = READ_ONLY; access_bus = READ_ONLY;
...@@ -78,7 +65,7 @@ peripheral { ...@@ -78,7 +65,7 @@ peripheral {
prefix = "DELTA2"; prefix = "DELTA2";
field { field {
name = "Delta Timestamp Word 2"; name = "Delta Timestamp Word 2 (8ns ticks, unsigned)";
type = SLV; type = SLV;
size = 32; size = 32;
access_bus = READ_ONLY; access_bus = READ_ONLY;
...@@ -92,7 +79,7 @@ peripheral { ...@@ -92,7 +79,7 @@ peripheral {
prefix = "DELTA3"; prefix = "DELTA3";
field { field {
name = "Delta Timestamp Word 3"; name = "Delta Timestamp Word 3 (fractional part, unsigned)";
type = SLV; type = SLV;
size = 32; size = 32;
access_bus = READ_ONLY; access_bus = READ_ONLY;
...@@ -100,20 +87,62 @@ peripheral { ...@@ -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 { reg {
name = "Control/Status"; name = "Control/Status";
prefix = "CSR"; prefix = "CSR";
field { field {
name = "Delta Timestamp Valid"; name = "Delta Timestamp Ready";
prefix = "DELTA_VALID"; prefix = "DELTA_READY";
type = BIT; type = BIT;
access_bus = READ_WRITE; access_bus = READ_ONLY;
access_dev = READ_WRITE; access_dev = WRITE_ONLY;
load = LOAD_EXT; };
field {
name = "Read Delta Timestamp";
prefix = "DELTA_READ";
type = MONOSTABLE;
}; };
field { 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