Commit d69bd493 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski Committed by Tristan Gingold

wb_fine_pulse_gen: use double clock rate on Kintex7 Ultrascale, allowing for 1ns resolution

parent 9bd003e5
......@@ -16,9 +16,9 @@ entity fine_pulse_gen_kintexultrascale is
);
port
(
clk_ref_i : in std_logic;
clk_par_i : in std_logic;
clk_serdes_i : in std_logic;
rst_serdes_i : in std_logic;
rst_sys_n_i : in std_logic;
......@@ -62,9 +62,9 @@ architecture rtl of fine_pulse_gen_kintexultrascale is
T : in std_ulogic);
end component OSERDESE3;
signal par_data : std_logic_vector(7 downto 0);
signal par_data_rev : std_logic_vector(7 downto 0);
signal par_data : std_logic_vector(15 downto 0);
signal par_data_125 : std_logic_vector(7 downto 0);
signal par_data_rev : std_logic_vector(15 downto 0);
signal dout_predelay, dout_prebuf, dout_nodelay : std_logic;
signal odelay_load : std_logic;
......@@ -72,6 +72,7 @@ architecture rtl of fine_pulse_gen_kintexultrascale is
signal odelay_ntaps : std_logic_vector(4 downto 0);
signal trig_d : std_logic;
-- function f_gen_bitmask (coarse : std_logic_vector; pol : std_logic; cont : std_logic) return std_logic_vector is
......@@ -80,19 +81,25 @@ architecture rtl of fine_pulse_gen_kintexultrascale is
-- end f_gen_bitmask;
signal mask : std_logic_vector(15 downto 0);
signal mask : std_logic_vector(31 downto 0);
signal flip : std_logic;
signal dly_load_d : std_logic;
signal clk_ref_div2 : std_logic := '0';
signal clk_ref_div2_d0, clk_ref_div2_d1, gb_sync_p : std_logic;
begin
rst <= not rst_sys_n_i;
process(clk_par_i)
variable rv : std_logic_vector(15 downto 0);
process(clk_ref_i)
variable rv : std_logic_vector(31 downto 0);
begin
if rising_edge(clk_par_i) then
if rising_edge(clk_ref_i) then
dly_load_d <= dly_load_i;
if dly_load_i = '1' then
......@@ -102,21 +109,37 @@ begin
case coarse_i is
when x"00" =>
rv := "1111000011110000";
rv := "11111111000000001111111100000000";
when x"01" =>
rv := "0111100001111000";
rv := "01111111100000000111111110000000";
when x"02" =>
rv := "0011110000111100";
rv := "00111111110000000011111111000000";
when x"03" =>
rv := "0001111000011110";
rv := "00011111111000000001111111100000";
when x"04" =>
rv := "0000111100001111";
rv := "00001111111100000000111111110000";
when x"05" =>
rv := "1000011110000111";
rv := "00000111111110000000011111111000";
when x"06" =>
rv := "1100001111000011";
rv := "00000011111111000000001111111100";
when x"07" =>
rv := "1110000111100001";
rv := "00000001111111100000000111111110";
when x"08" =>
rv := "00000000111111110000000011111111";
when x"09" =>
rv := "00000000011111111000000001111111";
when x"0a" =>
rv := "00000000001111111100000000111111";
when x"0b" =>
rv := "00000000000111111110000000011111";
when x"0c" =>
rv := "00000000000011111111000000001111";
when x"0d" =>
rv := "00000000000001111111100000000111";
when x"0e" =>
rv := "00000000000000111111110000000011";
when x"0f" =>
rv := "00000000000000011111111000000001";
when others =>
rv := (others => '0');
end case;
......@@ -125,21 +148,37 @@ begin
else
case coarse_i is
when x"00" =>
rv := "1111000000000000";
rv := "11111111000000000000000000000000";
when x"01" =>
rv := "0111100000000000";
rv := "01111111100000000000000000000000";
when x"02" =>
rv := "0011110000000000";
rv := "00111111110000000000000000000000";
when x"03" =>
rv := "0001111000000000";
rv := "00011111111000000000000000000000";
when x"04" =>
rv := "0000111100000000";
rv := "00001111111100000000000000000000";
when x"05" =>
rv := "0000011110000000";
rv := "00000111111110000000000000000000";
when x"06" =>
rv := "0000001111000000";
rv := "00000011111111000000000000000000";
when x"07" =>
rv := "0000000111100000";
rv := "00000001111111100000000000000000";
when x"08" =>
rv := "00000000111111110000000000000000";
when x"09" =>
rv := "00000000011111111000000000000000";
when x"0a" =>
rv := "00000000001111111100000000000000";
when x"0b" =>
rv := "00000000000111111110000000000000";
when x"0c" =>
rv := "00000000000011111111000000000000";
when x"0d" =>
rv := "00000000000001111111100000000000";
when x"0e" =>
rv := "00000000000000111111110000000000";
when x"0f" =>
rv := "00000000000000011111111000000000";
when others =>
rv := (others => '0');
end case;
......@@ -159,17 +198,17 @@ begin
trig_d <= trig_p_i;
if trig_p_i = '1' then
par_data <= mask(15 downto 8);
par_data <= mask(31 downto 16);
flip <= '0';
elsif trig_d = '1' then
par_data <= mask(7 downto 0);
par_data <= mask(15 downto 0);
else
if cont_i = '1' then
if flip = '1' then
par_data <= mask(7 downto 0);
par_data <= mask(15 downto 0);
else
par_data <= mask(15 downto 8);
par_data <= mask(31 downto 16);
end if;
else
if pol_i = '1' then
......@@ -183,6 +222,34 @@ begin
end process;
p_div_clk : process(clk_ref_i, rst_serdes_i )
begin
if rst_serdes_i = '1' then
clk_ref_div2 <= '0';
elsif rising_edge(clk_ref_i) then
clk_ref_div2 <= not clk_ref_div2;
end if;
end process;
p_gearbox : process(clk_par_i)
begin
if rising_edge(clk_par_i) then
clk_ref_div2_d0 <= clk_ref_div2;
clk_ref_div2_d1 <= clk_ref_div2_d0;
gb_sync_p <= clk_ref_div2_d0 xor clk_ref_div2_d1;
if gb_sync_p = '1' then
par_data_125 <= par_data(15 downto 8);
else
par_data_125 <= par_data(7 downto 0);
end if;
end if;
end process;
U_Serdes : OSERDESE3
generic map (
DATA_WIDTH => 8,
......@@ -198,14 +265,14 @@ begin
OQ => pulse_o,
CLK => clk_serdes_i,
CLKDIV => clk_par_i,
D(0) => par_data(7),
D(1) => par_data(6),
D(2) => par_data(5),
D(3) => par_data(4),
D(4) => par_data(3),
D(5) => par_data(2),
D(6) => par_data(1),
D(7) => par_data(0),
D(0) => par_data_125(7),
D(1) => par_data_125(6),
D(2) => par_data_125(5),
D(3) => par_data_125(4),
D(4) => par_data_125(3),
D(5) => par_data_125(2),
D(6) => par_data_125(1),
D(7) => par_data_125(0),
RST => rst_serdes_i,
T => '0'
);
......
......@@ -136,6 +136,7 @@ architecture rtl of fine_pulse_gen_kintexultrascale_shared is
end component BUFG;
signal clk_ser_prebuf, mmcm_clk_fb_prebuf, mmcm_clk_fb : std_logic;
signal clk_par_prebuf : std_logic;
begin
......@@ -165,10 +166,14 @@ begin
CLKFBOUT_PHASE => 0.0, -- Phase offset in degrees of CLKFB (-360.000-360.000)
CLKFBOUT_USE_FINE_PS => "FALSE",
CLKOUT0_DIVIDE_F => 4.0, -- clk_ser: 250 MHz
CLKOUT0_DIVIDE_F => 2.0, -- clk_ser: 500 MHz
CLKOUT0_DUTY_CYCLE => 0.5,
CLKOUT0_PHASE => 0.0,
CLKOUT0_USE_FINE_PS => "FALSE"
CLKOUT1_DIVIDE => 8, -- clk_par: 125 MHz
CLKOUT1_DUTY_CYCLE => 0.5,
CLKOUT1_PHASE => 0.0,
CLKOUT0_USE_FINE_PS => "FALSE",
CLKOUT1_USE_FINE_PS => "FALSE"
)
port map (
-- Clock Inputs inputs: Clock inputs
......@@ -176,6 +181,7 @@ begin
CLKIN2 => '0',
-- Clock Outputs outputs: User configurable clock outputs
CLKOUT0 => clk_ser_prebuf,
CLKOUT1 => clk_par_prebuf,
-- Feedback
CLKFBOUT => mmcm_clk_fb_prebuf,
CLKFBIN => mmcm_clk_fb,
......@@ -208,7 +214,10 @@ begin
I => clk_ser_prebuf,
O => clk_ser_o);
clk_par_o <= clk_ref_i;
u_buf_mmcm_par : BUFG
port map (
I => clk_par_prebuf,
O => clk_par_o);
end generate gen_use_int_serdes_clock;
......
......@@ -427,6 +427,7 @@ begin
g_use_odelay => f_to_bool(g_use_odelay(i)) )
port map (
clk_par_i => clk_par,
clk_ref_i => clk_ref_i,
clk_serdes_i => clk_ser,
rst_serdes_i => regs_out.csr_serdes_rst_o,
rst_sys_n_i => rst_sys_n_i,
......
......@@ -43,8 +43,8 @@ class DDSSyncUnitDriver;
int coarse_par = int'($floor (delta / 16.0));
int coarse_ser = int'($floor (delta / 2.0) - coarse_par * 8);
int fine = int'((delta / 2.0 - $floor(delta / 2.0)) * 2.0 / tap_size);
int coarse_ser = int'($floor (delta / 1.0) - coarse_par * 16);
int fine = int'((delta / 1.0 - $floor(delta / 1.0)) * 1.0 / tap_size);
int mask = coarse_ser;
//(1 << (7-coarse_ser+1)) - 1;
uint32_t ocr;
......@@ -149,7 +149,7 @@ module main;
first_delay = dly;
$display("t_pps %t t_pulse %t delta %d", t_pps, t_pulse, (t_pulse - t_pps) / 1ns );
$display("t_pps %t t_pulse %t delta %.2f", t_pps, t_pulse, real'(t_pulse - t_pps) / real'(1ns) );
/* delta = dly-first_delay;
......@@ -173,14 +173,14 @@ module main;
xwb_fine_pulse_gen
#(
.g_target_platform("KintexUltrascale"),
.g_use_external_serdes_clock(1),
.g_use_external_serdes_clock(0),
.g_num_channels(1)
)
DUT
(
.rst_sys_n_i(rst_n),
.clk_ser_ext_i(clk_250m),
// .clk_ser_ext_i(clk_250m),
.clk_sys_i (clk_62m5),
.clk_ref_i (clk_62m5),
......@@ -222,12 +222,12 @@ module main;
-----/\----- EXCLUDED -----/\----- */
for (t = 1.0; t <= 200.9; t+=1.0)
for (t = 1.0; t <= 200.9; t+=0.1)
begin
// $display("Pulse @ %f", t );
dlys.push_back(t);
drv.pulse(0, 0, 0, t);
drv.pulse(0, 1, 0, t);
end
......
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