Commit 547a3cff authored by gilsoriano's avatar gilsoriano

Basic trigger: core for the basic repetition functionality improved to allow low-jitter operation.

parent 9c48eb1b
......@@ -334,22 +334,22 @@ NET "manual_rst_n_o" LOC = T22;
NET "fpga_o_en" IOSTANDARD = "LVCMOS33";
NET "fpga_o_en" DRIVE = "4";
NET "fpga_o_en" SLEW = "QUIETIO";
NET "fpga_o_en" PULLDOWN;
## NET "fpga_o_en" PULLDOWN;
NET "fpga_o_blo_en" LOC = N3;
NET "fpga_o_blo_en" IOSTANDARD = "LVCMOS33";
NET "fpga_o_blo_en" DRIVE = "4";
NET "fpga_o_blo_en" SLEW = "QUIETIO";
NET "fpga_o_blo_en" PULLDOWN;
## NET "fpga_o_blo_en" PULLDOWN;
NET "fpga_o_ttl_en" LOC = M3;
NET "fpga_o_ttl_en" IOSTANDARD = "LVCMOS33";
NET "fpga_o_ttl_en" DRIVE = "4";
NET "fpga_o_ttl_en" SLEW = "QUIETIO";
NET "fpga_o_ttl_en" PULLDOWN;
## NET "fpga_o_ttl_en" PULLDOWN;
NET "fpga_o_inv_en" LOC = P3;
NET "fpga_o_inv_en" IOSTANDARD = "LVCMOS33";
NET "fpga_o_inv_en" DRIVE = "4";
NET "fpga_o_inv_en" SLEW = "QUIETIO";
NET "fpga_o_inv_en" PULLDOWN;
## NET "fpga_o_inv_en" PULLDOWN;
##-------------------
##-- Motherboard and piggyback IDs
##--
......
......@@ -25,16 +25,16 @@ use work.ctdah_pkg.ALL;
entity basic_trigger_core is
port (
wb_rst_i : in STD_LOGIC;
wb_clk_i : in STD_LOGIC;
wb_rst_i : in STD_LOGIC;
wb_clk_i : in STD_LOGIC;
pulse_i : in STD_LOGIC;
pulse_o : out STD_LOGIC;
pulse_n_o : out STD_LOGIC;
pulse_i : in STD_LOGIC;
pulse_o : out STD_LOGIC;
pulse_n_o : out STD_LOGIC;
led_o : out STD_LOGIC;
crop_o : out STD_LOGIC;
level_i : in STD_LOGIC --! 0 here means ttl
led_o : out STD_LOGIC
);
end basic_trigger_core;
......@@ -45,11 +45,12 @@ architecture Behavioral of basic_trigger_core is
signal s_deglitched_pulse : STD_LOGIC;
signal s_deglitched_pulse_d0 : STD_LOGIC;
signal s_pulse_parity : STD_LOGIC;
signal s_monostable : STD_LOGIC;
begin
s_pulse <= pulse_i;
s_pulse <= pulse_i;
inst_debo: gc_debouncer
generic map( g_LENGTH => 2)
......@@ -60,7 +61,8 @@ begin
glitch_mask => "11");
pulse_monostable : gc_simple_monostable
generic map (g_PULSE_LENGTH => 20)
generic map (g_PULSE_LENGTH => 16) --! We remove the stages of deglitching
--! to produce 1us sharp at the output
port map (rst => wb_rst_i,
clk => wb_clk_i,
input => s_deglitched_pulse,
......@@ -68,7 +70,7 @@ begin
output_n => pulse_n_o);
led_monostable : gc_simple_monostable
generic map (g_PULSE_LENGTH => 100000000) --! 500ms
generic map (g_PULSE_LENGTH => 2000000) --! 500ms
port map (
rst => wb_rst_i,
clk => wb_clk_i,
......@@ -76,4 +78,5 @@ begin
output => led_o);
--output_n not connected
end Behavioral;
......@@ -65,33 +65,40 @@ end basic_trigger_top;
architecture Behavioral of basic_trigger_top is
signal s_pulse_i : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_pulse_i_rear : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_pulse_i_front : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_pulse_o : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_pulse_n_o : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_led : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_pulse_i : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_pulse_i_rear : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_pulse_i_front : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_pulse_o_front : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_pulse_o : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_pulse_o_d0 : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_pulse_n_o : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_led : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
signal s_level : STD_LOGIC;
signal s_crop : STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1) := (others => '0');
signal s_fpga_o_en : STD_LOGIC;
signal s_fpga_o_ttl_en : STD_LOGIC;
signal s_fpga_o_inv_en : STD_LOGIC;
signal s_fpga_o_blo_en : STD_LOGIC;
signal s_level : STD_LOGIC;
signal s_rst : STD_LOGIC_VECTOR(7 downto 0) := (others => '1');
signal s_fpga_o_en : STD_LOGIC;
signal s_fpga_o_ttl_en : STD_LOGIC;
signal s_fpga_o_inv_en : STD_LOGIC;
signal s_fpga_o_blo_en : STD_LOGIC;
component basic_trigger_core is
port (wb_rst_i : in STD_LOGIC;
wb_clk_i : in STD_LOGIC;
signal s_rst : STD_LOGIC_VECTOR(7 downto 0) := (others => '1');
type delay_array is array (g_NUMBER_OF_CHANNELS downto 1)
of STD_LOGIC_VECTOR(3 downto 0);
pulse_i : in STD_LOGIC;
pulse_o : out STD_LOGIC;
pulse_n_o : out STD_LOGIC;
signal s_pulse_i_reg : delay_array;
led_o : out STD_LOGIC;
component basic_trigger_core is
port (wb_rst_i : in STD_LOGIC;
wb_clk_i : in STD_LOGIC;
level_i : in STD_LOGIC);
pulse_i : in STD_LOGIC;
pulse_o : out STD_LOGIC;
pulse_n_o : out STD_LOGIC;
led_o : out STD_LOGIC);
end component;
begin
......@@ -100,15 +107,16 @@ begin
led_pw_o <= '0';
led_err_o <= '1';
led_ttl_o <= s_level;
led_ttl_o <= not(s_level);
led_link_up_o <= '1';
led_pps_o <= '1';
led_wr_ok_o <= '1';
s_pulse_i_front <= pulse_i_front when s_level = '0' else not(pulse_i_front);
s_pulse_i <= s_pulse_i_front or pulse_i_rear;
--! s_level '1' means TTL input, as we have one inverter in the board we
--! invert here.
s_pulse_i_front <= not(pulse_i_front) when s_level = '1' else pulse_i_front;
s_pulse_i <= s_pulse_i_front or not(pulse_i_rear);
fpga_o_en <= s_fpga_o_en when switch_i = '1' else '0';
......@@ -119,12 +127,11 @@ begin
led_o_front <= not(s_led);--! No need of accurate sync, hence we place
led_o_rear <= not(s_led);--! some combinatorial here.
inv_o <= inv_i;--! As we have one Schmitt inverter in the input,
inv_o(4 downto 3) <= inv_i(4 downto 3);--! As we have one Schmitt inverter in the input,
--! and a buffer in the output, there's no need
--! of invert here.
i_repetitors: for i in 1 to g_NUMBER_OF_CHANNELS generate
begin
trigger: basic_trigger_core
......@@ -136,11 +143,23 @@ begin
pulse_o => s_pulse_o(i),
pulse_n_o => s_pulse_n_o(i),
led_o => s_led(i),
level_i => '0');
-- pulse_parity_o => s_pulse_parity(i),
led_o => s_led(i));
end generate i_repetitors;
gen_delays : for j in 1 to g_NUMBER_OF_CHANNELS generate
p_delays : process(clk_i) is
begin
if rising_edge(clk_i) then
s_pulse_o_d0 <= s_pulse_o;
-- s_pulse_parity_d0 <= s_pulse_parity;
s_pulse_i_reg(j)(0) <= s_pulse_i(j);
for i in 1 to 3 loop
s_pulse_i_reg(j)(i) <= s_pulse_i_reg(j)(i-1); --!Another one to improve meta
end loop;
end if;
end process;
end generate;
p_reset_chain : process(clk_i) is
begin
......@@ -170,28 +189,63 @@ begin
end if;
end process p_reset_chain;
pulse_o_front <= s_pulse_o_front when level = '1'
else not(s_pulse_o_front);
--! We register the outputs for better synchronization of the outputs
p_reg_output : process(clk_i) is
inv_o(2) <= s_crop(2);
inv_o(1) <= s_crop(1);
gen_crop : for i in 1 to g_NUMBER_OF_CHANNELS generate
begin
if rising_edge(clk_i) then
if s_rst(7) = '1' then
pulse_o_rear <= (others => '0');
if s_level = '0' then
pulse_o_front <= (others => '0');
else
pulse_o_front <= (others => '1');
p_reg_crop : process (clk_i) is
begin
if rising_edge(clk_i) then
if s_pulse_o(i) = '0' then
s_crop(i) <= '1';
if s_pulse_i_reg(i)(3) = '0' then --! This should be working one clock
--! below s_pulse_o
s_crop(i) <= '0'; --! See gen_output to see the match
end if;
if s_pulse_i(i) = '0' then --! Sharp crop. Metastability
s_crop(i) <= '0'; --! problems?
end if;
end if;
else
pulse_o_rear <= s_pulse_o;
case s_level is
when '0' =>
pulse_o_front <= s_pulse_o;
when others =>
pulse_o_front <= s_pulse_n_o;
end case;
end if;
end if;
end process;
end process;
end generate;
--! We register the outputs for better synchronization of the outputs
gen_output : for i in 1 to g_NUMBER_OF_CHANNELS generate
begin
p_comb_output : process(s_pulse_i(i),
s_pulse_o(i)) is
begin
pulse_o_rear(i) <= '0';
s_pulse_o_front(i) <= '0';
case s_pulse_o(i) is
when '0' =>
--! We just have just finished the pulse and must be cropped.
--! In this case, we assume that the both input sources have an
--! RC filter, so we can improve jitter performance of the
--! first edge by bypassing the signal (no clocking).
if s_pulse_i(i) = '1' then
-- pulse_o_rear(i) <= '1';
if s_crop(i) = '0' then
--! However, glitches of n[DEGLITCHING]*clk length can happen.
s_pulse_o_front(i) <= '1';
else
s_pulse_o_front(i) <= '0';
end if;
else
end if;
when others =>
--! In this other case, we should keep on outputing the pulse
-- pulse_o_rear(i) <= '1';
s_pulse_o_front(i) <= '1';
end case;
end process;
end generate;
end Behavioral;
......@@ -58,27 +58,27 @@ ARCHITECTURE behavior OF trigger_top_tb IS
fpga_o_blo_en : out STD_LOGIC;
level_i : in STD_LOGIC;
level : in STD_LOGIC;
switch_i : in STD_LOGIC; --! General enable
manual_rst_n_o : out STD_LOGIC; --! It allows power sequencing of the
--! 24V rail after a security given
--! delay
pulse_i_front : in STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS - 1 downto 0);
pulse_o_front : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS - 1 downto 0);
pulse_i_front : in STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
pulse_o_front : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
pulse_i_rear : in STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS - 1 downto 0);
pulse_o_rear : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS - 1 downto 0);
pulse_i_rear : in STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
pulse_o_rear : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
led_o_front : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS - 1 downto 0);
led_o_rear : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS - 1 downto 0);
led_o_front : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
led_o_rear : out STD_LOGIC_VECTOR(g_NUMBER_OF_CHANNELS downto 1);
--! WR LEDs not to let them ON
led_link_up_o : out STD_LOGIC;
led_pps_o : out STD_LOGIC;
led_wr_ok_o : out STD_LOGIC;
inv_i : in STD_LOGIC_VECTOR(3 downto 0);
inv_o : out STD_LOGIC_VECTOR(3 downto 0));
inv_i : in STD_LOGIC_VECTOR(4 downto 1);
inv_o : out STD_LOGIC_VECTOR(4 downto 1));
end component;
......@@ -88,6 +88,7 @@ ARCHITECTURE behavior OF trigger_top_tb IS
begin
uut: basic_trigger_top
generic map(g_NUMBER_OF_CHANNELS => 6)
port map(
clk_i => s_clk,
-- rst_i => s_rst,
......@@ -101,7 +102,7 @@ begin
fpga_o_inv_en => fpga_o_inv_en,
fpga_o_blo_en => fpga_o_blo_en,
level_i => level_i,
level => level_i,
switch_i => switch_i,
manual_rst_n_o => manual_rst_n_o ,
......@@ -137,11 +138,11 @@ begin
procedure initial_cond(level : STD_LOGIC) is
begin
-- s_rst <= '1';
switch_i <= '0';
level_i <= level;
switch_i <= '1';
inv_i <= (others => '0');
pulse_i_front <= (others => level);
pulse_i_front <= (others => not(level));
pulse_i_rear <= (others => '0');
level_i <= level;
wait for CLK_PERIOD*50;
-- s_rst <= '0';
wait for CLK_PERIOD*2;
......@@ -155,23 +156,22 @@ begin
level : STD_LOGIC) is
variable v_pulse : STD_LOGIC := level;
begin
pulse(channel) <= level;
wait until rising_edge(s_clk);
pulse(channel) <= not(level);
wait for length;
wait until rising_edge(s_clk);
pulse(channel) <= level;
wait for length;
pulse(channel) <= not(level);
wait until rising_edge(s_clk);
end;
procedure input_front_pulse (length : time; channel : NATURAL;
level : STD_LOGIC) is
procedure input_front_pulse (length : time; channel : NATURAL) is
begin
input_pulse (pulse_i_front, channel, length, level);
input_pulse (pulse_i_front, channel, length, level_i);
end;
procedure input_rear_pulse (length : time; channel : NATURAL) is
begin
input_pulse (pulse_i_rear, channel, length, '0');
input_pulse (pulse_i_rear, channel, length, '1');
end;
procedure input_two_pulses (channel : NATURAL; level : STD_LOGIC;
......@@ -202,18 +202,18 @@ begin
--! First we put one pulse from the Blocking part, then we wait one-clock
--! and lastly we put another clock from the TTL input
initial_cond('0');
initial_cond('1');
input_rear_pulse (1200 ns, 0);
wait until rising_edge(s_clk);
input_front_pulse (1200 ns, 0, level_i);
input_front_pulse (1200 ns, 0);
wait for 40*CLK_PERIOD;
--! We reboot the machine and change the switch to indicate level_i is
--! TTL_N
initial_cond('1');
initial_cond('0');
input_rear_pulse (1200 ns, 0);
wait until rising_edge(s_clk);
input_front_pulse (1200 ns, 0, level_i);
input_front_pulse (1200 ns, 0);
input_two_pulses(0, '1',
1000 ns,
......
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