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;
----------------------------------------------------------------------------------------------------
entity data_formatting is
generic(
g_retrig_period_shift : integer :=8;
g_span : integer :=32;
g_width : integer :=32
);
......@@ -49,8 +50,10 @@ entity data_formatting is
clk_i : in std_logic;
clear_dacapo_flag_i : in std_logic;
reset_i : in std_logic;
start_nb_offset_i : in std_logic_vector(g_width-1 downto 0);
utc_current_time_i : in std_logic_vector(g_width-1 downto 0);
clk_cycles_offset_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)
);
......@@ -61,6 +64,11 @@ end data_formatting;
----------------------------------------------------------------------------------------------------
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_fifo_ef : std_logic;
signal acam_fifo_lf : std_logic;
......@@ -68,14 +76,19 @@ signal acam_fine_timestamp : std_logic_vector(16 downto 0);
signal acam_slope : std_logic;
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 reset : std_logic;
signal start_nb_offset : std_logic_vector(g_width-1 downto 0);
signal utc_current_time : std_logic_vector(g_width-1 downto 0);
signal clk_cycles_offset : 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 metadata : std_logic_vector(g_width-1 downto 0);
......@@ -183,16 +196,55 @@ begin
wait until clk ='1';
end process;
-- coarse_time <= x"000000"
-- & acam_start_nb;
-- the metadata field contains extra information about the timestamp
metadata <= x"0000"
& "000" & acam_fifo_ef
& "000" & acam_fifo_lf
& "000" & acam_slope
& "0" & acam_channel;
local_utc <= utc_current_time;
coarse_time <= x"000000"
& acam_start_nb;
-- 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);
-- 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);
-- the number of roll-overs of the ACAM internal start retrigger counter is converted to a number
-- 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"
& "000"
......@@ -215,8 +267,9 @@ begin
clk <= clk_i;
clear_dacapo_flag <= clear_dacapo_flag_i;
reset <= reset_i;
start_nb_offset <= start_nb_offset_i;
utc_current_time <= utc_current_time_i;
clk_cycles_offset <= clk_cycles_offset_i;
retrig_nb_offset <= retrig_nb_offset_i;
current_roll_over <= current_roll_over_i;
mem_ack <= ack_i;
mem_data_rd <= dat_i;
......
......@@ -34,9 +34,12 @@ entity one_hz_gen is
acam_refclk_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
load_utc_i : in std_logic;
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
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
);
end one_hz_gen;
......@@ -79,12 +82,15 @@ architecture rtl of one_hz_gen is
constant constant_delay : unsigned(3 downto 0):=x"4";
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_post : std_logic;
signal onesec_counter_en : std_logic;
signal refclk_edge : std_logic;
signal reset : std_logic;
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);
......@@ -93,27 +99,6 @@ signal total_delay : std_logic_vector(g_width-1 downto 0);
----------------------------------------------------------------------------------------------------
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
generic map(
width => g_width
......@@ -142,8 +127,27 @@ begin
current_value => open
);
clk <= clk_i;
reset <= reset_i;
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;
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
s_acam_refclk(2) and
......@@ -152,6 +156,25 @@ begin
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;
end rtl;
......
......@@ -65,7 +65,7 @@ entity reg_ctrl is
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_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);
core_status_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);
signal acam_ififo1 : 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 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 core_status : std_logic_vector(g_width-1 downto 0);
signal wr_pointer : std_logic_vector(g_width-1 downto 0);
......@@ -310,7 +310,7 @@ begin
start_phase when x"23",
one_hz_phase when x"24",
retrig_freq when x"25",
current_utc when x"26",
local_utc when x"26",
irq_code when x"27",
core_status when x"28",
wr_pointer when x"29",
......
......@@ -39,9 +39,11 @@ entity start_retrigger_control is
clk_i : in std_logic;
one_hz_p_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);
start_trig_o : out std_logic
clk_cycles_offset_o : out std_logic_vector(g_width-1 downto 0);
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;
......@@ -50,6 +52,21 @@ end start_retrigger_control;
----------------------------------------------------------------------------------------------------
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
generic(
width : integer :=32
......@@ -67,53 +84,101 @@ architecture rtl of start_retrigger_control is
signal acam_fall_intflag_p : std_logic;
signal acam_rise_intflag_p : std_logic;
signal acam_halfcounter_gone : std_logic;
signal add_offset : std_logic;
signal add_roll_over : std_logic;
signal clk : std_logic;
signal counter_reset : std_logic;
signal offset_value : std_logic_vector(g_width-1 downto 0);
signal offset_to_shift : unsigned(g_width-1 downto 0);
signal clk_cycles_offset : std_logic_vector(g_width-1 downto 0);
signal current_cycles : std_logic_vector(g_width-1 downto 0);
signal current_retrig_nb : std_logic_vector(g_width-1 downto 0);
signal one_hz_p : std_logic;
signal reset : std_logic;
signal start_nb_offset : std_logic_vector(g_width-1 downto 0);
signal start_trig : std_logic;
signal retrig_nb_offset : std_logic_vector(g_width-1 downto 0);
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
----------------------------------------------------------------------------------------------------
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(
width => g_width
)
port map(
clk => clk,
end_value => x"FFFFFFFF",
incr => add_offset,
reset => counter_reset,
incr => add_roll_over,
reset => roll_over_reset,
count_done => open,
current_value => offset_value
current_value => 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.
capture_offset: process
begin
if reset ='1' then
clk_cycles_offset <= (others=>'0');
retrig_nb_offset <= (others=>'0');
elsif one_hz_p ='1' then
clk_cycles_offset <= current_cycles;
retrig_nb_offset <= current_retrig_nb;
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;
retrig_period_reset <= acam_fall_intflag_p;
retrig_nb_reset <= acam_fall_intflag_p;
roll_over_reset <= one_hz_p;
add_roll_over <= acam_fall_intflag_p;
-- inputs
acam_fall_intflag_p <= acam_fall_intflag_p_i;
......@@ -121,10 +186,30 @@ begin
clk <= clk_i;
one_hz_p <= one_hz_p_i;
reset <= reset_i;
retrig_period <= retrig_period_i;
-- outputs
start_nb_offset_o <= start_nb_offset;
start_trig_o <= start_trig;
clk_cycles_offset_o <= clk_cycles_offset;
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;
----------------------------------------------------------------------------------------------------
......
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