Commit 57ec601c authored by penacoba's avatar penacoba

First complete version. Simulation ok. Pending from synthesis.


git-svn-id: http://svn.ohwr.org/fmc-tdc@54 85dfdc96-de2c-444c-878d-45b388be74a9
parent 8250f67c
...@@ -27,6 +27,7 @@ use IEEE.numeric_std.all; ...@@ -27,6 +27,7 @@ use IEEE.numeric_std.all;
---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
entity data_formatting is entity data_formatting is
generic( generic(
g_retrig_period_shift : integer :=8;
g_span : integer :=32; g_span : integer :=32;
g_width : integer :=32 g_width : integer :=32
); );
...@@ -49,8 +50,10 @@ entity data_formatting is ...@@ -49,8 +50,10 @@ entity data_formatting is
clk_i : in std_logic; clk_i : in std_logic;
clear_dacapo_flag_i : in std_logic; clear_dacapo_flag_i : in std_logic;
reset_i : in std_logic; reset_i : in std_logic;
start_nb_offset_i : in std_logic_vector(g_width-1 downto 0); clk_cycles_offset_i : in std_logic_vector(g_width-1 downto 0);
utc_current_time_i : in std_logic_vector(g_width-1 downto 0); current_roll_over_i : in std_logic_vector(g_width-1 downto 0);
local_utc_i : in std_logic_vector(g_width-1 downto 0);
retrig_nb_offset_i : in std_logic_vector(g_width-1 downto 0);
wr_pointer_o : out std_logic_vector(g_width-1 downto 0) wr_pointer_o : out std_logic_vector(g_width-1 downto 0)
); );
...@@ -61,6 +64,11 @@ end data_formatting; ...@@ -61,6 +64,11 @@ end data_formatting;
---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
architecture rtl of data_formatting is architecture rtl of data_formatting is
signal acam_timestamp1 : std_logic_vector(g_width-1 downto 0);
signal acam_timestamp1_valid : std_logic;
signal acam_timestamp2 : std_logic_vector(g_width-1 downto 0);
signal acam_timestamp2_valid : std_logic;
signal acam_channel : std_logic_vector(2 downto 0); signal acam_channel : std_logic_vector(2 downto 0);
signal acam_fifo_ef : std_logic; signal acam_fifo_ef : std_logic;
signal acam_fifo_lf : std_logic; signal acam_fifo_lf : std_logic;
...@@ -68,14 +76,19 @@ signal acam_fine_timestamp : std_logic_vector(16 downto 0); ...@@ -68,14 +76,19 @@ signal acam_fine_timestamp : std_logic_vector(16 downto 0);
signal acam_slope : std_logic; signal acam_slope : std_logic;
signal acam_start_nb : std_logic_vector(7 downto 0); signal acam_start_nb : std_logic_vector(7 downto 0);
signal acam_timestamp1 : std_logic_vector(g_width-1 downto 0);
signal acam_timestamp1_valid : std_logic;
signal acam_timestamp2 : std_logic_vector(g_width-1 downto 0);
signal acam_timestamp2_valid : std_logic;
signal clk : std_logic; signal clk : std_logic;
signal reset : std_logic; signal reset : std_logic;
signal start_nb_offset : std_logic_vector(g_width-1 downto 0); signal clk_cycles_offset : std_logic_vector(g_width-1 downto 0);
signal utc_current_time : std_logic_vector(g_width-1 downto 0); signal current_roll_over : std_logic_vector(g_width-1 downto 0);
signal retrig_nb_offset : std_logic_vector(g_width-1 downto 0);
signal un_acam_start_nb : unsigned(g_width-1 downto 0);
signal un_clk_cycles_offset : unsigned(g_width-1 downto 0);
signal un_nb_of_retrig : unsigned(g_width-1 downto 0);
signal un_nb_of_cycles : unsigned(g_width-1 downto 0);
signal un_retrig_from_roll_over : unsigned(g_width-1 downto 0);
signal un_retrig_nb_offset : unsigned(g_width-1 downto 0);
signal un_roll_over : unsigned(g_width-1 downto 0);
signal full_timestamp : std_logic_vector(4*g_width-1 downto 0); signal full_timestamp : std_logic_vector(4*g_width-1 downto 0);
signal metadata : std_logic_vector(g_width-1 downto 0); signal metadata : std_logic_vector(g_width-1 downto 0);
...@@ -183,16 +196,55 @@ begin ...@@ -183,16 +196,55 @@ begin
wait until clk ='1'; wait until clk ='1';
end process; end process;
-- coarse_time <= x"000000"
-- & acam_start_nb;
-- the metadata field contains extra information about the timestamp
metadata <= x"0000" metadata <= x"0000"
& "000" & acam_fifo_ef & "000" & acam_fifo_ef
& "000" & acam_fifo_lf & "000" & acam_fifo_lf
& "000" & acam_slope & "000" & acam_slope
& "0" & acam_channel; & "0" & acam_channel;
-- the UTC time is updated every second by the one_hz_pulse
local_utc <= local_utc_i;
-- the coarse time is expressed as the number of 125 MHz clock cycles since the last one_hz_pulse.
-- Since the clk and the pulse are derived from the same PLL, any offset between them is constant
-- and will cancel when substracting timestamps.
coarse_time <= std_logic_vector(un_nb_of_cycles);
local_utc <= utc_current_time; -- all the values needed for the calculations have to be converted to unsigned
un_acam_start_nb <= unsigned(x"000000" & acam_start_nb);
un_clk_cycles_offset <= unsigned(clk_cycles_offset);
un_retrig_nb_offset <= unsigned(retrig_nb_offset);
un_roll_over <= unsigned(current_roll_over);
coarse_time <= x"000000" -- the number of roll-overs of the ACAM internal start retrigger counter is converted to a number
& acam_start_nb; -- of internal start retriggers.
un_retrig_from_roll_over <= shift_left(un_roll_over,8); -- shifted left to multiply by 256
-- the actual number of internal start retriggers actually occurred is calculated by subtracting the offset number
-- already present when the one_hz_pulse arrives, and adding the start nb provided by the ACAM.
un_nb_of_retrig <= un_retrig_from_roll_over
- un_retrig_nb_offset
+ un_acam_start_nb;
-- finally, the coarse time is obtained by multiplying by the number of clk cycles in an internal
-- start retrigger period and adding the number of clk cycles still to be discounted when the
-- one_hz_pulse arrives.
un_nb_of_cycles <= shift_left(un_nb_of_retrig - 1,g_retrig_period_shift)
+ un_clk_cycles_offset;
-- the fine time is directly provided by the ACAM as a number of BINs since the last
-- internal retrigger.
fine_time <= x"000" fine_time <= x"000"
& "000" & "000"
...@@ -215,8 +267,9 @@ begin ...@@ -215,8 +267,9 @@ begin
clk <= clk_i; clk <= clk_i;
clear_dacapo_flag <= clear_dacapo_flag_i; clear_dacapo_flag <= clear_dacapo_flag_i;
reset <= reset_i; reset <= reset_i;
start_nb_offset <= start_nb_offset_i; clk_cycles_offset <= clk_cycles_offset_i;
utc_current_time <= utc_current_time_i; retrig_nb_offset <= retrig_nb_offset_i;
current_roll_over <= current_roll_over_i;
mem_ack <= ack_i; mem_ack <= ack_i;
mem_data_rd <= dat_i; mem_data_rd <= dat_i;
......
...@@ -34,9 +34,12 @@ entity one_hz_gen is ...@@ -34,9 +34,12 @@ entity one_hz_gen is
acam_refclk_i : in std_logic; acam_refclk_i : in std_logic;
clk_i : in std_logic; clk_i : in std_logic;
clock_period_i : in std_logic_vector(g_width-1 downto 0); -- nb of clock periods for 1s clock_period_i : in std_logic_vector(g_width-1 downto 0); -- nb of clock periods for 1s
load_utc_i : in std_logic;
pulse_delay_i : in std_logic_vector(g_width-1 downto 0); -- nb of clock periods phase delay pulse_delay_i : in std_logic_vector(g_width-1 downto 0); -- nb of clock periods phase delay
reset_i : in std_logic; -- with respect to reference clock reset_i : in std_logic; -- with respect to reference clock
starting_utc_i : in std_logic_vector(g_width-1 downto 0);
local_utc_o : out std_logic_vector(g_width-1 downto 0);
one_hz_p_o : out std_logic one_hz_p_o : out std_logic
); );
end one_hz_gen; end one_hz_gen;
...@@ -79,12 +82,15 @@ architecture rtl of one_hz_gen is ...@@ -79,12 +82,15 @@ architecture rtl of one_hz_gen is
constant constant_delay : unsigned(3 downto 0):=x"4"; constant constant_delay : unsigned(3 downto 0):=x"4";
signal clk : std_logic; signal clk : std_logic;
signal local_utc : unsigned(g_width-1 downto 0);
signal load_utc : std_logic;
signal one_hz_p_pre : std_logic; signal one_hz_p_pre : std_logic;
signal one_hz_p_post : std_logic; signal one_hz_p_post : std_logic;
signal onesec_counter_en : std_logic; signal onesec_counter_en : std_logic;
signal refclk_edge : std_logic; signal refclk_edge : std_logic;
signal reset : std_logic; signal reset : std_logic;
signal s_acam_refclk : unsigned(3 downto 0); signal s_acam_refclk : unsigned(3 downto 0);
signal starting_utc : std_logic_vector(g_width-1 downto 0);
signal total_delay : std_logic_vector(g_width-1 downto 0); signal total_delay : std_logic_vector(g_width-1 downto 0);
...@@ -93,27 +99,6 @@ signal total_delay : std_logic_vector(g_width-1 downto 0); ...@@ -93,27 +99,6 @@ signal total_delay : std_logic_vector(g_width-1 downto 0);
---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
begin begin
sync_acam_refclk: process
begin
if reset ='1' then
s_acam_refclk <= (others=>'0');
else
s_acam_refclk <= shift_right(s_acam_refclk,1);
s_acam_refclk(3) <= acam_refclk_i;
end if;
wait until clk ='1';
end process;
onesec_trigger: process
begin
if reset ='1' then
onesec_counter_en <= '0';
elsif refclk_edge ='1' then
onesec_counter_en <= '1';
end if;
wait until clk ='1';
end process;
clock_periods_counter: free_counter clock_periods_counter: free_counter
generic map( generic map(
width => g_width width => g_width
...@@ -142,8 +127,27 @@ begin ...@@ -142,8 +127,27 @@ begin
current_value => open current_value => open
); );
clk <= clk_i; onesec_trigger: process
reset <= reset_i; begin
if reset ='1' then
onesec_counter_en <= '0';
elsif refclk_edge ='1' then
onesec_counter_en <= '1';
end if;
wait until clk ='1';
end process;
utc_counter: process
begin
if reset ='1' then
local_utc <= (others=>'0');
elsif load_utc ='1' then
local_utc <= unsigned(starting_utc);
elsif one_hz_p_post ='1' then
local_utc <= local_utc + 1;
end if;
wait until clk ='1';
end process;
refclk_edge <= not(s_acam_refclk(3)) and refclk_edge <= not(s_acam_refclk(3)) and
s_acam_refclk(2) and s_acam_refclk(2) and
...@@ -152,6 +156,25 @@ begin ...@@ -152,6 +156,25 @@ begin
total_delay <= std_logic_vector(unsigned(pulse_delay_i)+constant_delay); total_delay <= std_logic_vector(unsigned(pulse_delay_i)+constant_delay);
-- inputs
sync_acam_refclk: process
begin
if reset ='1' then
s_acam_refclk <= (others=>'0');
else
s_acam_refclk <= shift_right(s_acam_refclk,1);
s_acam_refclk(3) <= acam_refclk_i;
end if;
wait until clk ='1';
end process;
clk <= clk_i;
reset <= reset_i;
load_utc <= load_utc_i;
starting_utc <= starting_utc_i;
-- output
local_utc_o <= std_logic_vector(local_utc);
one_hz_p_o <= one_hz_p_post; one_hz_p_o <= one_hz_p_post;
end rtl; end rtl;
......
...@@ -65,7 +65,7 @@ entity reg_ctrl is ...@@ -65,7 +65,7 @@ entity reg_ctrl is
acam_ififo1_i : in std_logic_vector(g_width-1 downto 0); acam_ififo1_i : in std_logic_vector(g_width-1 downto 0);
acam_ififo2_i : in std_logic_vector(g_width-1 downto 0); acam_ififo2_i : in std_logic_vector(g_width-1 downto 0);
acam_start01_i : in std_logic_vector(g_width-1 downto 0); acam_start01_i : in std_logic_vector(g_width-1 downto 0);
current_utc_i : in std_logic_vector(g_width-1 downto 0); local_utc_i : in std_logic_vector(g_width-1 downto 0);
irq_code_i : in std_logic_vector(g_width-1 downto 0); irq_code_i : in std_logic_vector(g_width-1 downto 0);
core_status_i : in std_logic_vector(g_width-1 downto 0); core_status_i : in std_logic_vector(g_width-1 downto 0);
wr_pointer_i : in std_logic_vector(g_width-1 downto 0); wr_pointer_i : in std_logic_vector(g_width-1 downto 0);
...@@ -119,7 +119,7 @@ signal acam_status : std_logic_vector(g_width-1 downto 0); ...@@ -119,7 +119,7 @@ signal acam_status : std_logic_vector(g_width-1 downto 0);
signal acam_ififo1 : std_logic_vector(g_width-1 downto 0); signal acam_ififo1 : std_logic_vector(g_width-1 downto 0);
signal acam_ififo2 : std_logic_vector(g_width-1 downto 0); signal acam_ififo2 : std_logic_vector(g_width-1 downto 0);
signal acam_start01 : std_logic_vector(g_width-1 downto 0); signal acam_start01 : std_logic_vector(g_width-1 downto 0);
signal current_utc : std_logic_vector(g_width-1 downto 0); signal local_utc : std_logic_vector(g_width-1 downto 0);
signal irq_code : std_logic_vector(g_width-1 downto 0); signal irq_code : std_logic_vector(g_width-1 downto 0);
signal core_status : std_logic_vector(g_width-1 downto 0); signal core_status : std_logic_vector(g_width-1 downto 0);
signal wr_pointer : std_logic_vector(g_width-1 downto 0); signal wr_pointer : std_logic_vector(g_width-1 downto 0);
...@@ -310,7 +310,7 @@ begin ...@@ -310,7 +310,7 @@ begin
start_phase when x"23", start_phase when x"23",
one_hz_phase when x"24", one_hz_phase when x"24",
retrig_freq when x"25", retrig_freq when x"25",
current_utc when x"26", local_utc when x"26",
irq_code when x"27", irq_code when x"27",
core_status when x"28", core_status when x"28",
wr_pointer when x"29", wr_pointer when x"29",
......
...@@ -39,9 +39,11 @@ entity start_retrigger_control is ...@@ -39,9 +39,11 @@ entity start_retrigger_control is
clk_i : in std_logic; clk_i : in std_logic;
one_hz_p_i : in std_logic; one_hz_p_i : in std_logic;
reset_i : in std_logic; reset_i : in std_logic;
retrig_period_i : in std_logic_vector(g_width-1 downto 0);
start_nb_offset_o : out std_logic_vector(g_width-1 downto 0); clk_cycles_offset_o : out std_logic_vector(g_width-1 downto 0);
start_trig_o : out std_logic current_roll_over_o : out std_logic_vector(g_width-1 downto 0);
retrig_nb_offset_o : out std_logic_vector(g_width-1 downto 0)
); );
end start_retrigger_control; end start_retrigger_control;
...@@ -50,6 +52,21 @@ end start_retrigger_control; ...@@ -50,6 +52,21 @@ end start_retrigger_control;
---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
architecture rtl of start_retrigger_control is architecture rtl of start_retrigger_control is
component free_counter is
generic(
width : integer :=32
);
port(
clk : in std_logic;
enable : in std_logic;
reset : in std_logic;
start_value : in std_logic_vector(width-1 downto 0);
count_done : out std_logic;
current_value : out std_logic_vector(width-1 downto 0)
);
end component;
component incr_counter component incr_counter
generic( generic(
width : integer :=32 width : integer :=32
...@@ -67,65 +84,133 @@ architecture rtl of start_retrigger_control is ...@@ -67,65 +84,133 @@ architecture rtl of start_retrigger_control is
signal acam_fall_intflag_p : std_logic; signal acam_fall_intflag_p : std_logic;
signal acam_rise_intflag_p : std_logic; signal acam_rise_intflag_p : std_logic;
signal acam_halfcounter_gone : std_logic; signal add_roll_over : std_logic;
signal add_offset : std_logic;
signal clk : std_logic; signal clk : std_logic;
signal counter_reset : std_logic; signal clk_cycles_offset : std_logic_vector(g_width-1 downto 0);
signal offset_value : std_logic_vector(g_width-1 downto 0); signal current_cycles : std_logic_vector(g_width-1 downto 0);
signal offset_to_shift : unsigned(g_width-1 downto 0); signal current_retrig_nb : std_logic_vector(g_width-1 downto 0);
signal one_hz_p : std_logic; signal one_hz_p : std_logic;
signal reset : std_logic; signal reset : std_logic;
signal start_nb_offset : std_logic_vector(g_width-1 downto 0); signal retrig_nb_offset : std_logic_vector(g_width-1 downto 0);
signal start_trig : std_logic; signal retrig_nb_reset : std_logic;
signal retrig_p : std_logic;
signal retrig_period : std_logic_vector(g_width-1 downto 0);
signal retrig_period_reset : std_logic;
signal roll_over_reset : std_logic;
signal roll_over_value : std_logic_vector(g_width-1 downto 0);
signal acam_halfcounter_gone : std_logic;
---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
-- architecture begins -- architecture begins
---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
begin begin
acam_irflag_counter: incr_counter retrig_period_counter: free_counter
generic map(
width => g_width
)
port map(
clk => clk,
enable => '1',
reset => retrig_period_reset,
start_value => retrig_period,
count_done => retrig_p,
current_value => current_cycles
);
-- retrig_number_counter: free_counter
-- generic map(
-- width => g_width
-- )
-- port map(
-- clk => clk,
-- enable => retrig_p,
-- reset => retrig_nb_reset,
-- start_value => x"00000100",
--
-- count_done => open,
-- current_value => current_retrig_nb
-- );
retrig_nb_counter: incr_counter
generic map(
width => g_width
)
port map(
clk => clk,
end_value => x"00000100",
incr => retrig_p,
reset => retrig_nb_reset,
count_done => open,
current_value => current_retrig_nb
);
roll_over_counter: incr_counter
generic map( generic map(
width => g_width width => g_width
) )
port map( port map(
clk => clk, clk => clk,
end_value => x"FFFFFFFF", end_value => x"FFFFFFFF",
incr => add_offset, incr => add_roll_over,
reset => counter_reset, reset => roll_over_reset,
count_done => open, count_done => open,
current_value => offset_value current_value => roll_over_value
); );
halfcounter_monitor: process -- The halfcounter monitor is needed to make capture_offset: process
begin -- sure that the falling edge pulse received begin
if reset ='1' or one_hz_p ='1' then -- corresponds to a real overflow of the ACAM if reset ='1' then
acam_halfcounter_gone <= '0'; -- counter and not to a different reason, clk_cycles_offset <= (others=>'0');
elsif acam_rise_intflag_p ='1' then -- for example a reset. retrig_nb_offset <= (others=>'0');
acam_halfcounter_gone <= '1'; -- This way the start_nb_offset will really elsif one_hz_p ='1' then
elsif acam_fall_intflag_p ='1' then -- track the number of internal start retriggers clk_cycles_offset <= current_cycles;
acam_halfcounter_gone <= '0'; -- inside the ACAM. retrig_nb_offset <= current_retrig_nb;
end if; end if;
wait until clk ='1'; wait until clk ='1';
end process; end process;
add_offset <= acam_fall_intflag_p and acam_halfcounter_gone; retrig_period_reset <= acam_fall_intflag_p;
counter_reset <= reset or one_hz_p; retrig_nb_reset <= acam_fall_intflag_p;
offset_to_shift <= unsigned(offset_value); roll_over_reset <= one_hz_p;
start_nb_offset <= std_logic_vector(shift_left(offset_to_shift,8)); add_roll_over <= acam_fall_intflag_p;
start_trig <= one_hz_p;
-- inputs -- inputs
acam_fall_intflag_p <= acam_fall_intflag_p_i; acam_fall_intflag_p <= acam_fall_intflag_p_i;
acam_rise_intflag_p <= acam_rise_intflag_p_i; acam_rise_intflag_p <= acam_rise_intflag_p_i;
clk <= clk_i; clk <= clk_i;
one_hz_p <= one_hz_p_i; one_hz_p <= one_hz_p_i;
reset <= reset_i; reset <= reset_i;
retrig_period <= retrig_period_i;
-- outputs -- outputs
start_nb_offset_o <= start_nb_offset; clk_cycles_offset_o <= clk_cycles_offset;
start_trig_o <= start_trig; retrig_nb_offset_o <= retrig_nb_offset;
current_roll_over_o <= roll_over_value;
-- halfcounter_monitor: process -- The halfcounter monitor is needed to make
-- begin -- sure that the falling edge pulse received
-- if reset ='1' or one_hz_p ='1' then -- corresponds to a real overflow of the ACAM
-- acam_halfcounter_gone <= '0'; -- counter and not to a different reason,
-- elsif acam_rise_intflag_p ='1' then -- for example a reset.
-- acam_halfcounter_gone <= '1'; -- This way the start_nb_offset will really
-- elsif acam_fall_intflag_p ='1' then -- track the number of internal start retriggers
-- acam_halfcounter_gone <= '0'; -- inside the ACAM.
-- end if;
-- wait until clk ='1';
-- end process;
--
-- add_offset <= acam_fall_intflag_p and acam_halfcounter_gone;
-- counter_reset <= reset or one_hz_p;
-- offset_to_shift <= unsigned(offset_value);
-- start_nb_offset <= std_logic_vector(shift_left(offset_to_shift,8));
-- start_trig <= one_hz_p;
end rtl; end rtl;
---------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------
-- architecture ends -- architecture ends
......
This diff is collapsed.
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