Commit e66d3b45 authored by Dimitris Lampridis's avatar Dimitris Lampridis

[hdl] move offset calculation outside of channel generation loop.

This reduces the required resources since we only use one set of adders for all channels (instead of one per).

There is no issue with multiple timestamps arriving simultaneously, since the previous stages serialise the
delivery of timestamps and this stage is fully pipelined, so it can process one timestamp per cycle.
parent d693db67
......@@ -65,7 +65,7 @@ begin
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 <= std_logic_vector(to_unsigned(channel_select, 4));
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');
......
......@@ -75,6 +75,7 @@ architecture rtl of tdc_ts_addsub is
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;
......@@ -100,6 +101,7 @@ begin -- rtl
elsif(enable_i = '1') then
pipe(0) <= valid_i;
sums(0).channel <= a_i.channel;
sums(0).slope <= a_i.slope;
sums(0).meta <= a_i.meta;
......@@ -126,9 +128,9 @@ begin -- rtl
else
pipe(1) <= pipe(0);
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;
......@@ -141,7 +143,6 @@ begin -- rtl
sums(1).coarse <= sums(0).coarse;
end if;
sums(1).tai <= sums(0).tai;
end if;
end if;
end process;
......@@ -188,8 +189,7 @@ begin -- rtl
else
pipe(3) <= pipe(2);
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;
......@@ -208,8 +208,6 @@ begin -- rtl
sums(3).tai <= sums(2).tai;
end if;
sums(3).frac <= sums(2).frac;
end if;
end if;
end process;
......@@ -221,4 +219,5 @@ begin -- rtl
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;
......@@ -69,19 +69,18 @@ architecture rtl of timestamp_convert_filter is
signal s1_channel, s2_channel, s3_channel : std_logic_vector(2 downto 0);
signal s1_edge, s2_edge, s3_edge : std_logic;
signal s3_ts : t_tdc_timestamp;
signal ts_valid_sys : std_logic;
signal fifo_we, fifo_rd, fifo_empty, fifo_full, fifo_rd_d : std_logic;
signal fifo_we, fifo_rd : std_logic;
signal fifo_empty, fifo_rd_d : std_logic;
signal fifo_d, fifo_q : std_logic_vector(127 downto 0);
signal ts_fifo_out : t_acam_timestamp;
signal ts_valid_preoffset, ts_ready_preoffset : std_logic_vector(4 downto 0);
signal ts_valid_postoffset, ts_valid_postoffset_with_seq : std_logic_vector(4 downto 0);
signal ts_preoffset, ts_postoffset : t_tdc_timestamp_array(4 downto 0);
signal ts_postoffset_with_seq : t_tdc_timestamp_array(4 downto 0);
signal ts_valid_postoffset : std_logic;
signal ts_valid_preseq : std_logic_vector(4 downto 0);
signal ts_valid_postseq : std_logic_vector(4 downto 0);
signal ts_preoffset, ts_postoffset : t_tdc_timestamp;
signal ts_offset : t_tdc_timestamp;
signal ts_preseq, ts_postseq : t_tdc_timestamp_array(4 downto 0);
signal s1_meta, s2_meta, s3_meta : std_logic_vector(31 downto 0);
function f_pack_acam_timestamp (ts : t_acam_timestamp) return std_logic_vector is
......@@ -96,7 +95,7 @@ architecture rtl of timestamp_convert_filter is
return rv;
end f_pack_acam_timestamp;
function f_unpack_acam_timestamp ( p : std_logic_vector ) return t_acam_timestamp is
function f_unpack_acam_timestamp (p : std_logic_vector) return t_acam_timestamp is
variable ts : t_acam_timestamp;
begin
ts.tai := p(31 downto 0);
......@@ -108,16 +107,16 @@ architecture rtl of timestamp_convert_filter is
return ts;
end f_unpack_acam_timestamp;
begin
begin
fifo_d <= f_pack_acam_timestamp(ts_i);
fifo_we <= ts_valid_i;
U_Sync_FIFO: generic_async_fifo
U_Sync_FIFO : generic_async_fifo
generic map (
g_data_width => 128,
g_size => 16,
g_show_ahead => false)
g_show_ahead => FALSE)
port map (
rst_n_i => rst_sys_n_i,
clk_wr_i => clk_tdc_i,
......@@ -185,12 +184,25 @@ architecture rtl of timestamp_convert_filter is
end if;
end process;
s3_ts.frac <= std_logic_vector(s3_frac);
s3_ts.coarse <= std_logic_vector(s3_coarse);
s3_ts.tai <= std_logic_vector(s3_tai);
s3_ts.slope <= s3_edge;
s3_ts.channel <= s3_channel;
s3_ts.meta <= s3_meta;
ts_preoffset.frac <= std_logic_vector(s3_frac);
ts_preoffset.coarse <= std_logic_vector(s3_coarse);
ts_preoffset.tai <= std_logic_vector(s3_tai);
ts_preoffset.slope <= s3_edge;
ts_preoffset.channel <= s3_channel;
ts_preoffset.meta <= s3_meta;
ts_offset <= ts_offset_i(to_integer(unsigned(s3_channel)));
U_Offset_Adder : entity work.tdc_ts_addsub
port map (
clk_i => clk_sys_i,
rst_n_i => rst_sys_n_i,
valid_i => s3_valid,
enable_i => '1',
a_i => ts_preoffset,
b_i => ts_offset,
valid_o => ts_valid_postoffset,
q_o => ts_postoffset);
gen_channels : for i in 0 to 4 generate
......@@ -199,17 +211,16 @@ architecture rtl of timestamp_convert_filter is
begin
if rising_edge(clk_sys_i) then
if rst_sys_n_i = '0' or enable_i(i) = '0' then
ts_valid_preoffset(i) <= '0';
ts_valid_preseq(i) <= '0';
channels(i).s1_valid <= '0';
channels(i).s2_valid <= '0';
channels(i).last_valid <= '0';
else
channels(i).s1_valid <= '0';
if s3_valid = '1' and unsigned(s3_channel) = i then
if (s3_ts.slope = '1') then -- rising edge
channels(i).last_ts <= s3_ts;
if ts_valid_postoffset = '1' and unsigned(ts_postoffset.channel) = i then
if (ts_postoffset.slope = '1') then -- rising edge
channels(i).last_ts <= ts_postoffset;
channels(i).last_valid <= '1';
channels(i).s1_valid <= '0';
else
......@@ -217,13 +228,16 @@ architecture rtl of timestamp_convert_filter is
channels(i).s1_valid <= '1';
end if;
channels(i).s1_delta_coarse <= unsigned(s3_ts.coarse) - unsigned(channels(i).last_ts.coarse);
channels(i).s1_delta_tai <= unsigned(s3_ts.tai) - unsigned(channels(i).last_ts.tai);
end if;
channels(i).s1_delta_coarse <=
unsigned(ts_postoffset.coarse) - unsigned(channels(i).last_ts.coarse);
channels(i).s1_delta_tai <=
unsigned(ts_postoffset.tai) - unsigned(channels(i).last_ts.tai);
end if;
if channels(i).s1_delta_coarse(31) = '1' then
channels(i).s2_delta_coarse <= channels(i).s1_delta_coarse + to_unsigned(125000000, 32);
channels(i).s2_delta_coarse <=
channels(i).s1_delta_coarse + to_unsigned(125000000, 32);
channels(i).s2_delta_tai <= channels(i).s1_delta_tai - 1;
else
channels(i).s2_delta_coarse <= channels(i).s1_delta_coarse;
......@@ -235,19 +249,19 @@ architecture rtl of timestamp_convert_filter is
if channels(i).s2_valid = '1' then
if channels(i).s2_delta_tai = 0 and channels(i).s2_delta_coarse >= 12 then
ts_preoffset(i).tai <= channels(i).last_ts.tai;
ts_preoffset(i).coarse <= channels(i).last_ts.coarse;
ts_preoffset(i).frac <= channels(i).last_ts.frac;
ts_preoffset(i).channel <= channels(i).last_ts.channel;
ts_preoffset(i).slope <= channels(i).last_ts.slope;
ts_preoffset(i).meta <= channels(i).last_ts.meta;
ts_preseq(i).tai <= channels(i).last_ts.tai;
ts_preseq(i).coarse <= channels(i).last_ts.coarse;
ts_preseq(i).frac <= channels(i).last_ts.frac;
ts_preseq(i).channel <= channels(i).last_ts.channel;
ts_preseq(i).slope <= channels(i).last_ts.slope;
ts_preseq(i).meta <= channels(i).last_ts.meta;
ts_valid_preoffset(i) <= '1';
ts_valid_preseq(i) <= '1';
else
ts_valid_preoffset(i) <= '0';
ts_valid_preseq(i) <= '0';
end if;
else
ts_valid_preoffset(i) <= '0';
ts_valid_preseq(i) <= '0';
end if;
end if;
......@@ -260,43 +274,32 @@ architecture rtl of timestamp_convert_filter is
begin
if rising_edge(clk_sys_i) then
if rst_sys_n_i = '0' or enable_i(i) = '0' then
ts_valid_preoffset(i) <= '0';
ts_valid_preseq(i) <= '0';
else
if s3_valid = '1' and unsigned(s3_channel) = i then
ts_valid_preoffset(i) <= '1';
ts_preoffset(i) <= s3_ts;
if ts_valid_postoffset = '1' and unsigned(ts_postoffset.channel) = i then
ts_valid_preseq(i) <= '1';
ts_preseq(i) <= ts_postoffset;
else
ts_valid_preoffset(i) <= '0';
ts_valid_preseq(i) <= '0';
end if;
end if;
end if;
end process p_fsm;
end generate gen_without_pwidth_filter;
U_Offset_Adder : entity work.tdc_ts_addsub
port map (
clk_i => clk_sys_i,
rst_n_i => rst_sys_n_i,
valid_i => ts_valid_preoffset(i),
enable_i => enable_i(i),
a_i => ts_preoffset(i),
b_i => ts_offset_i(i),
valid_o => ts_valid_postoffset(i),
q_o => ts_postoffset(i));
p_seq_count : process(clk_sys_i) is
begin
if rising_edge(clk_sys_i) then
if rst_sys_n_i = '0' or enable_i(i) = '0' or reset_seq_i(i) = '1' then
channels(i).seq <= (others => '0');
else
if ts_valid_postoffset(i) = '1' then
if ts_valid_preseq(i) = '1' then
channels(i).seq <= channels(i).seq + 1;
ts_valid_postoffset_with_seq(i) <= '1';
ts_postoffset_with_seq(i) <= ts_postoffset(i);
ts_postoffset_with_seq(i).seq <= std_logic_vector(channels(i).seq);
ts_valid_postseq(i) <= '1';
ts_postseq(i) <= ts_preseq(i);
ts_postseq(i).seq <= std_logic_vector(channels(i).seq);
else
ts_valid_postoffset_with_seq(i) <= '0';
ts_valid_postseq(i) <= '0';
end if;
end if;
end if;
......@@ -314,27 +317,21 @@ architecture rtl of timestamp_convert_filter is
end if;
if raw_enable_i(i) = '1' then
--if ts_valid_sys = '1' and unsigned(ts_latched.channel) = i then
-- ts_valid_o(i) <= '1';
-- ts_o(i).raw <= ts_latched.raw;
--end if;
else
if ts_valid_postoffset_with_seq(i) = '1' then
if ts_valid_postseq(i) = '1' then
ts_valid_o(i) <= '1';
ts_o(i) <= ts_postoffset_with_seq(i);
ts_o(i) <= ts_postseq(i);
end if;
end if;
end if;
end if;
end process;
end generate gen_channels;
end rtl;
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