Commit 1a7c626a authored by Theodor-Adrian Stana's avatar Theodor-Adrian Stana

Implemented pulse synchronizer for CHxLTS*R registers

The pulse synchronizer makes sure the load pulse to the 125 MHz clock
domain registers generates a pulse to load the registers in the 20 MHz
clock domain, which are the registers that are read via I2C.
parent e1bfd7b0
......@@ -243,9 +243,10 @@ architecture arch of conv_common_gw is
type t_ch_pcr is array(c_max_nr_chans-1 downto 0)
of std_logic_vector(31 downto 0);
type t_latest_timestamp_tai is array(c_max_nr_chans-1 downto 0)
-- Latest timestamp
type t_lts_tai is array(c_max_nr_chans-1 downto 0)
of std_logic_vector(39 downto 0);
type t_latest_timestamp_cycles is array(c_max_nr_chans-1 downto 0)
type t_lts_cycles is array(c_max_nr_chans-1 downto 0)
of std_logic_vector(27 downto 0);
--============================================================================
......@@ -347,10 +348,17 @@ architecture arch of conv_common_gw is
signal buf_dat_out : std_logic_vector(c_tagbuff_data_width-1 downto 0);
-- Latest timestamp signals
signal latest_timestamp_ld : std_logic_vector(c_max_nr_chans-1 downto 0);
signal latest_timestamp_tai : t_latest_timestamp_tai;
signal latest_timestamp_cycles : t_latest_timestamp_cycles;
signal latest_timestamp_wrtag : std_logic_vector(c_max_nr_chans-1 downto 0);
signal lts_ld_125 : std_logic_vector(c_max_nr_chans-1 downto 0);
signal lts_tai_125 : t_lts_tai;
signal lts_cycles_125 : t_lts_cycles;
signal lts_wrtag_125 : std_logic_vector(c_max_nr_chans-1 downto 0);
signal lts_ld_toggle : std_logic_vector(c_max_nr_chans-1 downto 0);
signal lts_ld_toggle_d0 : std_logic_vector(c_max_nr_chans-1 downto 0);
signal lts_ld_toggle_d1 : std_logic_vector(c_max_nr_chans-1 downto 0);
signal lts_ld_20 : std_logic_vector(c_max_nr_chans-1 downto 0);
signal lts_tai_20 : t_lts_tai;
signal lts_cycles_20 : t_lts_cycles;
signal lts_wrtag_20 : std_logic_vector(c_max_nr_chans-1 downto 0);
-- One-wire master signals
signal owr_en : std_logic_vector(0 downto 0);
......@@ -976,32 +984,94 @@ end generate;
-- Implement the latest timestamp registers
-- NOTE: Updated in the 125 MHz clock domain
p_latest_timestamp : process (clk_125)
lts_ld_125 <= buf_chan;
p_lts_125 : process (clk_125)
begin
if rising_edge(clk_125) then
for i in 0 to g_nr_chans-1 loop
if (rst_125_n = '0') then
lts_cycles_125(i) <= (others => '0');
lts_tai_125(i) <= (others => '0');
lts_wrtag_125(i) <= '0';
elsif (lts_ld_125(i) = '1') then
lts_cycles_125(i) <= tm_cycles;
lts_tai_125(i) <= tm_tai;
lts_wrtag_125(i) <= buf_wrtag;
end if;
end loop;
end if;
end process p_lts_125;
-- Pulse synchronizer: sync. lts_ld from 125 MHz to 20MHz domain
p_sync_ld_125 : process(clk_125)
begin
if rising_edge(clk_125) then
for i in 0 to g_nr_chans-1 loop
if (rst_125_n = '0') then
latest_timestamp_cycles(i) <= (others => '0');
latest_timestamp_tai(i) <= (others => '0');
latest_timestamp_wrtag(i) <= '0';
elsif (buf_chan(i) = '1') then
latest_timestamp_cycles(i) <= tm_cycles;
latest_timestamp_tai(i) <= tm_tai;
latest_timestamp_wrtag(i) <= buf_wrtag;
lts_ld_toggle(i) <= '0';
elsif (lts_ld_125(i) = '1') then
lts_ld_toggle(i) <= not lts_ld_125(i);
else
lts_ld_toggle(i) <= lts_ld_125(i);
end if;
end loop;
end if;
end process p_latest_timestamp;
end process p_sync_ld_125;
p_sync_ld_20 : process(clk_20_i)
begin
if rising_edge(clk_20_i) then
for i in 0 to g_nr_chans-1 loop
if (rst_20_n = '0') then
lts_ld_20(i) <= '0';
lts_ld_toggle_d0(i) <= '0';
lts_ld_toggle_d1(i) <= '0';
else
lts_ld_toggle_d0(i) <= lts_ld_toggle(i);
lts_ld_toggle_d1(i) <= lts_ld_toggle_d0(i);
lts_ld_20(i) <= lts_ld_toggle_d0(i) xor lts_ld_toggle_d1(i);
end if;
end loop;
end if;
end process p_sync_ld_20;
-- Latest timestamp regs in 20MHz clock domain
p_lts_20 : process (clk_20_i)
begin
if rising_edge(clk_20_i) then
for i in 0 to g_nr_chans-1 loop
if (rst_20_n = '0') then
lts_cycles_20(i) <= (others => '0');
lts_tai_20(i) <= (others => '0');
lts_wrtag_20(i) <= '0';
elsif (lts_ld_20(i) = '1') then
lts_cycles_20(i) <= lts_cycles_125(i);
lts_tai_20(i) <= lts_tai_125(i);
lts_wrtag_20(i) <= lts_wrtag_125(i);
end if;
end loop;
end if;
end process p_lts_20;
--------------------------------------------------------------------------------
-- Connect unused timestamps to all zeroes
gen_latest_timestamp_unused_chans : if (g_nr_chans < c_max_nr_chans) generate
latest_timestamp_cycles(c_max_nr_chans-1 downto g_nr_chans) <= (others => (others => '0'));
latest_timestamp_tai(c_max_nr_chans-1 downto g_nr_chans) <= (others => (others => '0'));
latest_timestamp_tai(c_max_nr_chans-1 downto g_nr_chans) <= (others => (others => '0'));
lts_ld_125(c_max_nr_chans-1 downto g_nr_chans) <= (others => '0');
lts_cycles_125(c_max_nr_chans-1 downto g_nr_chans) <= (others => (others => '0'));
lts_tai_125(c_max_nr_chans-1 downto g_nr_chans) <= (others => (others => '0'));
lts_wrtag_125(c_max_nr_chans-1 downto g_nr_chans) <= (others => '0');
lts_ld_20(c_max_nr_chans-1 downto g_nr_chans) <= (others => '0');
lts_cycles_20(c_max_nr_chans-1 downto g_nr_chans) <= (others => (others => '0'));
lts_tai_20(c_max_nr_chans-1 downto g_nr_chans) <= (others => (others => '0'));
lts_wrtag_20(c_max_nr_chans-1 downto g_nr_chans) <= (others => '0');
end generate gen_latest_timestamp_unused_chans;
--------------------------------------------------------------------------------
-- Then, instantiate the component
cmp_conv_regs : conv_regs
port map (
......@@ -1082,30 +1152,30 @@ end generate gen_latest_timestamp_unused_chans;
reg_tbcsr_full_i => buf_full,
reg_tbcsr_empty_i => buf_empty,
reg_ch1ltscyr_i => latest_timestamp_cycles(0),
reg_ch1ltstlr_i => latest_timestamp_tai(0)(31 downto 0),
reg_ch1ltsthr_tai_i => latest_timestamp_tai(0)(39 downto 32),
reg_ch1ltsthr_wrtag_i => latest_timestamp_wrtag(0),
reg_ch2ltscyr_i => latest_timestamp_cycles(1),
reg_ch2ltstlr_i => latest_timestamp_tai(1)(31 downto 0),
reg_ch2ltsthr_tai_i => latest_timestamp_tai(1)(39 downto 32),
reg_ch2ltsthr_wrtag_i => latest_timestamp_wrtag(1),
reg_ch3ltscyr_i => latest_timestamp_cycles(2),
reg_ch3ltstlr_i => latest_timestamp_tai(2)(31 downto 0),
reg_ch3ltsthr_tai_i => latest_timestamp_tai(2)(39 downto 32),
reg_ch3ltsthr_wrtag_i => latest_timestamp_wrtag(2),
reg_ch4ltscyr_i => latest_timestamp_cycles(3),
reg_ch4ltstlr_i => latest_timestamp_tai(3)(31 downto 0),
reg_ch4ltsthr_tai_i => latest_timestamp_tai(3)(39 downto 32),
reg_ch4ltsthr_wrtag_i => latest_timestamp_wrtag(3),
reg_ch5ltscyr_i => latest_timestamp_cycles(4),
reg_ch5ltstlr_i => latest_timestamp_tai(4)(31 downto 0),
reg_ch5ltsthr_tai_i => latest_timestamp_tai(4)(39 downto 32),
reg_ch5ltsthr_wrtag_i => latest_timestamp_wrtag(4),
reg_ch6ltscyr_i => latest_timestamp_cycles(5),
reg_ch6ltstlr_i => latest_timestamp_tai(5)(31 downto 0),
reg_ch6ltsthr_tai_i => latest_timestamp_tai(5)(39 downto 32),
reg_ch6ltsthr_wrtag_i => latest_timestamp_wrtag(5),
reg_ch1ltscyr_i => lts_cycles_20(0),
reg_ch1ltstlr_i => lts_tai_20(0)(31 downto 0),
reg_ch1ltsthr_tai_i => lts_tai_20(0)(39 downto 32),
reg_ch1ltsthr_wrtag_i => lts_wrtag_20(0),
reg_ch2ltscyr_i => lts_cycles_20(1),
reg_ch2ltstlr_i => lts_tai_20(1)(31 downto 0),
reg_ch2ltsthr_tai_i => lts_tai_20(1)(39 downto 32),
reg_ch2ltsthr_wrtag_i => lts_wrtag_20(1),
reg_ch3ltscyr_i => lts_cycles_20(2),
reg_ch3ltstlr_i => lts_tai_20(2)(31 downto 0),
reg_ch3ltsthr_tai_i => lts_tai_20(2)(39 downto 32),
reg_ch3ltsthr_wrtag_i => lts_wrtag_20(2),
reg_ch4ltscyr_i => lts_cycles_20(3),
reg_ch4ltstlr_i => lts_tai_20(3)(31 downto 0),
reg_ch4ltsthr_tai_i => lts_tai_20(3)(39 downto 32),
reg_ch4ltsthr_wrtag_i => lts_wrtag_20(3),
reg_ch5ltscyr_i => lts_cycles_20(4),
reg_ch5ltstlr_i => lts_tai_20(4)(31 downto 0),
reg_ch5ltsthr_tai_i => lts_tai_20(4)(39 downto 32),
reg_ch5ltsthr_wrtag_i => lts_wrtag_20(4),
reg_ch6ltscyr_i => lts_cycles_20(5),
reg_ch6ltstlr_i => lts_tai_20(5)(31 downto 0),
reg_ch6ltsthr_tai_i => lts_tai_20(5)(39 downto 32),
reg_ch6ltsthr_wrtag_i => lts_wrtag_20(5),
reg_lsr_front_i => line_front,
reg_lsr_frontinv_i => line_inv_i,
......
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