Commit 101aff2a authored by Tomasz Wlostowski's avatar Tomasz Wlostowski Committed by Tristan Gingold

wb_fine_pulse_gen: simplify clock crossings

Conflicts:
	modules/wishbone/wb_fine_pulse_gen/xwb_fine_pulse_gen.vhd
parent f3f8dd3d
......@@ -11,15 +11,14 @@ use unisim.VCOMPONENTS.all;
entity fine_pulse_gen_kintexultrascale is
generic (
g_sim_delay_tap_ps : integer := 30;
g_ref_clk_freq : real := 125.0;
g_use_odelay : boolean := false;
g_CLK_ODELAY_FREQ : real := 200.0
g_idelayctrl_ref_clk_freq : real := 250.0;
g_use_odelay : boolean := false
);
port
(
clk_sys_i : in std_logic; -- system clock
clk_ref_i : in std_logic; -- 62.5 MHz (WR)
clk_par_i : in std_logic; -- 125 MHz
clk_odelay_i : in std_logic; -- 200 MHz
clk_serdes_i : in std_logic; -- 500 MHz (DDR)
rst_serdes_i : in std_logic;
......@@ -50,6 +49,8 @@ end fine_pulse_gen_kintexultrascale;
architecture rtl of fine_pulse_gen_kintexultrascale is
constant c_DELAY_VALUE : integer := 1000; -- in ps
component OSERDESE3 is
......@@ -132,7 +133,14 @@ architecture rtl of fine_pulse_gen_kintexultrascale is
signal odelay_value_out, odelay_value_in, odelay_value_in_pulse : std_logic_vector(8 downto 0);
signal odelay_load_clk_ref, odelay_load_pulse : std_logic;
signal odelay_load_clk_odelay : std_logic;
signal odelay_load_clk_par : std_logic;
attribute mark_debug : string;
attribute mark_debug of odelay_en_vtc_i : signal is "true";
attribute mark_debug of odelay_cal_latch_i : signal is "true";
attribute mark_debug of odelay_value_out : signal is "true";
begin
......@@ -274,6 +282,7 @@ begin
elsif rising_edge(clk_ref_i) then
clk_ref_div2 <= not clk_ref_div2;
odelay_load_clk_ref <= odelay_load_pulse or odelay_load_i;
if odelay_load_pulse = '1' then
......@@ -293,7 +302,7 @@ begin
rst_n_i => rst_sys_n_i,
d_ready_o => open,
d_p_i => odelay_load_clk_ref,
q_p_o => odelay_load_clk_odelay);
q_p_o => odelay_load_clk_par);
p_gearbox : process(clk_par_i)
begin
......@@ -345,8 +354,28 @@ begin
b_odelay : block
attribute IODELAY_GROUP: string;
attribute IODELAY_GROUP of U_ODELAYE3_Fine_Pulse_Gen : label is "IODELAY_FPGen";
signal odelay_rst_clk_par : std_logic;
signal odelay_en_vtc_clk_par : std_logic;
begin
U_Sync_Reset : gc_sync_ffs
port map (
clk_i => clk_par_i,
rst_n_i => '1',
data_i => odelay_rst_i,
synced_o => odelay_rst_clk_par
);
U_Sync_VTC : gc_sync_ffs
port map (
clk_i => clk_par_i,
rst_n_i => '1',
data_i => odelay_en_vtc_i,
synced_o => odelay_en_vtc_clk_par
);
-- If a OSERDESE3 block (or its simplified version ODDRE) is instantiated,
-- the ODELAYE3 CLK and OSERDESE3 CLK_DIV (or ODDRE C) port must share the same clock
U_ODELAYE3_Fine_Pulse_Gen : ODELAYE3
......@@ -357,7 +386,7 @@ begin
DELAY_VALUE => c_DELAY_VALUE, -- Output delay tap setting
IS_CLK_INVERTED => '0', -- Optional inversion for CLK
IS_RST_INVERTED => '0', -- Optional inversion for RST
REFCLK_FREQUENCY => g_CLK_ODELAY_FREQ, -- IDELAYCTRL clock input frequency in MHz (200.0-2667.0).
REFCLK_FREQUENCY => g_idelayctrl_ref_clk_freq, -- IDELAYCTRL clock input frequency in MHz (200.0-2667.0).
SIM_DEVICE => "ULTRASCALE", -- Set the device version (ULTRASCALE, ULTRASCALE_PLUS, ULTRASCALE_PLUS_ES1, ULTRASCALE_PLUS_ES2)
UPDATE_MODE => "ASYNC" -- Determines when updates to the delay will take effect (ASYNC, MANUAL, SYNC)
)
......@@ -370,18 +399,19 @@ begin
CE => '0', -- 1-bit input: Active high enable increment/decrement input
CLK => clk_par_i, -- 1-bit input: Clock input
CNTVALUEIN => odelay_value_in, -- 9-bit input: Counter value input
EN_VTC => odelay_en_vtc_i, -- 1-bit input: Keep delay constant over VT
EN_VTC => odelay_en_vtc_clk_par, -- 1-bit input: Keep delay constant over VT
INC => '0', -- 1-bit input: Increment/Decrement tap delay input
LOAD => odelay_load_clk_odelay, -- 1-bit input: Load DELAY_VALUE input
LOAD => odelay_load_clk_par, -- 1-bit input: Load DELAY_VALUE input
ODATAIN => pulse_predelay, -- 1-bit input: Data input
RST => odelay_rst_i -- 1-bit input: Asynchronous Reset to the DELAY_VALUE
RST => odelay_rst_clk_par -- 1-bit input: Asynchronous Reset to the DELAY_VALUE
);
end block;
-- same delay applied to all pins
p_latch_delay : process(clk_odelay_i)
p_latch_delay : process(clk_sys_i)
begin
if rising_edge(clk_odelay_i) then
if rising_edge(clk_sys_i) then
if odelay_cal_latch_i = '1' then
odelay_value_out_o <= odelay_value_out;
end if;
......
library ieee;
use ieee.std_logic_1164.all;
use work.gencores_pkg.all;
library unisim;
......@@ -146,8 +147,17 @@ begin
b_idelayctrl: block
attribute IODELAY_GROUP: string;
attribute IODELAY_GROUP of U_IDELAYCTRL_Fine_Pulse_Gen : label is "IODELAY_FPGen";
signal rst_synced : std_logic;
begin
U_Sync_Reset : gc_sync_ffs
port map (
clk_i => clk_odelay,
rst_n_i => '1',
data_i => odelayctrl_rst_i,
synced_o => rst_synced
);
U_IDELAYCTRL_Fine_Pulse_Gen : IDELAYCTRL
generic map (
SIM_DEVICE => "ULTRASCALE" -- Must be set to "ULTRASCALE"
......
......@@ -103,7 +103,6 @@ peripheral {
size = 6;
type = SLV;
prefix = "READY";
clock = "clk_ref_i";
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
......@@ -606,21 +605,18 @@ peripheral {
name = "Reset Output IDELAYCTRL";
type = BIT;
prefix = "rst_idelayctrl";
clock = "clk_odelay_i";
};
field {
name = "Reset Output ODELAY";
type = BIT;
prefix = "rst_odelay";
clock = "clk_odelay_i";
};
field {
name = "Reset Output OSERDES";
type = BIT;
prefix = "rst_oserdes";
clock = "clk_oserdes_i";
};
field {
......@@ -629,7 +625,6 @@ peripheral {
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
prefix = "rdy";
clock = "clk_odelay_i";
};
field {
......@@ -640,25 +635,12 @@ peripheral {
access_bus = READ_WRITE;
access_dev = READ_ONLY;
prefix = "value";
clock = "clk_ref_i";
};
field {
name = "Delay value update";
prefix = "value_update";
type = MONOSTABLE;
clock = "clk_ref_i";
};
field {
name = "Serdes Bitslip";
description = "Bit slip of the DAC output serdes. Together with the value field, it allows output delay adjustment range of a full DAC clock cycle. Expressed in nanoseconds (0 to 4).";
type = SLV;
size = 2;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
prefix = "bitslip";
clock = "clk_odelay_i";
};
field {
......@@ -668,14 +650,12 @@ peripheral {
access_bus = READ_WRITE;
access_dev = READ_ONLY;
prefix = "en_vtc";
clock = "clk_odelay_i";
};
field {
name = "Latch calibration taps";
type = MONOSTABLE;
prefix = "cal_latch";
clock = "clk_odelay_i";
};
field {
......@@ -686,7 +666,6 @@ peripheral {
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
prefix = "taps";
clock = "clk_odelay_i";
};
};
};
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : fine_pulse_gen_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from fine_pulse_gen_wb.wb
-- Created : Wed Jun 24 13:47:27 2020
-- Created : Tue Jul 7 14:29:21 2020
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fine_pulse_gen_wb.wb
......@@ -106,7 +106,6 @@ package fpg_wbgen2_pkg is
odelay_calib_rst_oserdes_o : std_logic;
odelay_calib_value_o : std_logic_vector(8 downto 0);
odelay_calib_value_update_o : std_logic;
odelay_calib_bitslip_o : std_logic_vector(1 downto 0);
odelay_calib_en_vtc_o : std_logic;
odelay_calib_cal_latch_o : std_logic;
end record;
......@@ -181,7 +180,6 @@ package fpg_wbgen2_pkg is
odelay_calib_rst_oserdes_o => '0',
odelay_calib_value_o => (others => '0'),
odelay_calib_value_update_o => '0',
odelay_calib_bitslip_o => (others => '0'),
odelay_calib_en_vtc_o => '0',
odelay_calib_cal_latch_o => '0'
);
......@@ -194,9 +192,6 @@ component fine_pulse_gen_wb is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
clk_ref_i : in std_logic;
clk_odelay_i : in std_logic;
clk_oserdes_i : in std_logic;
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
int_o : out std_logic;
......
......@@ -137,7 +137,10 @@ architecture rtl of xwb_fine_pulse_gen is
signal pll_locked : std_logic;
signal rst_serdes : std_logic;
signal rst_serdes_in, rst_serdes : std_logic;
signal odelay_calib_rdy : std_logic;
signal pps_p1 : std_logic;
begin
......@@ -148,9 +151,11 @@ begin
if rst_n_wr = '0' then
pps_ext <= '0';
pps_cnt <= (others => '0');
pps_p1 <= '0';
else
pps_p_d <= pps_p_i;
pps_p1 <= not pps_p_d and pps_p_i;
if pps_p_i = '1' and pps_p_d = '0' then
pps_cnt <= to_unsigned(1, pps_cnt'length);
......@@ -170,11 +175,8 @@ begin
port map (
rst_n_i => rst_sys_n_i,
clk_sys_i => clk_sys_i,
clk_ref_i => clk_ref_i,
slave_i => slave_i,
slave_o => slave_o,
clk_odelay_i => clk_odelay,
clk_oserdes_i => clk_par,
regs_i => regs_in,
regs_o => regs_out);
......@@ -275,12 +277,26 @@ begin
regs_in.csr_ready_i(0) <= ch(0).ready;
regs_in.csr_ready_i(1) <= ch(1).ready;
regs_in.csr_ready_i(2) <= ch(2).ready;
regs_in.csr_ready_i(3) <= ch(3).ready;
regs_in.csr_ready_i(4) <= ch(4).ready;
regs_in.csr_ready_i(5) <= ch(5).ready;
gen_ready_flags : for i in 0 to g_num_channels-1 generate
U_Sync : gc_sync_ffs
port map (
clk_i => clk_sys_i,
rst_n_i => rst_sys_n_i,
data_i => ch(i).ready,
synced_o => regs_in.csr_ready_i(i)
);
end generate gen_ready_flags;
rst_serdes_in <= regs_out.odelay_calib_rst_oserdes_o or regs_out.csr_serdes_rst_o;
U_Sync_Serdes_Reset : gc_sync_ffs
port map (
clk_i => clk_ref_i,
rst_n_i => '1',
data_i => rst_serdes_in,
synced_o => rst_serdes
);
ch(0).pol <= regs_out.ocr0_pol_o;
ch(1).pol <= regs_out.ocr1_pol_o;
......@@ -337,15 +353,12 @@ begin
ch(i).state <= IDLE;
ch(i).trig_p <= '0';
ch(i).delay_load <= '0';
ch(i).trig_p <= '0';
ch(i).odelay_load <= '0';
else
if ch(i).trig_sel = '1' then
ch(i).trig_in <= ext_trigger_p_i;
else
ch(i).trig_in <= pps_p_i;
ch(i).trig_in <= pps_p1;
end if;
ch(i).trig_in_d <= ch(i).trig_in;
......@@ -414,6 +427,7 @@ begin
port map (
clk_par_i => clk_par,
clk_serdes_i => clk_ser,
rst_serdes_i => rst_serdes,
rst_sys_n_i => rst_sys_n_i,
trig_p_i => ch(I).trig_p,
cont_i => ch(i).cont,
......@@ -430,14 +444,14 @@ begin
U_Pulse_Gen : entity work.fine_pulse_gen_kintexultrascale
generic map (
g_sim_delay_tap_ps => 50,
g_ref_clk_freq => 200.0,
g_idelayctrl_ref_clk_freq => 250.0,
g_use_odelay => f_to_bool(g_use_odelay(i)) )
port map (
clk_sys_i => clk_sys_i,
clk_par_i => clk_par,
clk_ref_i => clk_ref_i,
clk_serdes_i => clk_ser,
clk_odelay_i => clk_odelay,
rst_serdes_i => regs_out.csr_serdes_rst_o,
rst_serdes_i => rst_serdes,
rst_sys_n_i => rst_sys_n_i,
trig_p_i => ch(I).trig_p,
cont_i => ch(i).cont,
......@@ -476,7 +490,7 @@ begin
clk_par_o => clk_par,
clk_ser_o => clk_ser,
clk_ser_ext_i => clk_ser_ext_i,
clk_odelay_o => clk_odelay,
-- clk_odelay_o => clk_odelay,
pll_locked_o => pll_locked);
end generate gen_is_kintex7;
......@@ -494,23 +508,24 @@ begin
clk_par_o => clk_par,
clk_ser_o => clk_ser,
clk_ser_ext_i => clk_ser_ext_i,
clk_odelay_o => clk_odelay,
-- clk_odelay_o => clk_odelay,
pll_locked_o => pll_locked,
odelayctrl_rdy_o => regs_in.odelay_calib_rdy_i,
odelayctrl_rdy_o => odelay_calib_rdy,
odelayctrl_rst_i => regs_out.odelay_calib_rst_idelayctrl_o
);
U_Sync_Reset : gc_sync_ffs
port map (
clk_i => clk_sys_i,
rst_n_i => rst_sys_n_i,
data_i => odelay_calib_rdy,
synced_o => regs_in.odelay_calib_rdy_i
);
end generate gen_is_kintex_ultrascale;
clk_par_o <= clk_par;
regs_in.csr_pll_locked_i <= pll_locked;
end rtl;
......@@ -152,11 +152,9 @@
`define FPG_ODELAY_CALIB_VALUE 32'h00001ff0
`define FPG_ODELAY_CALIB_VALUE_UPDATE_OFFSET 13
`define FPG_ODELAY_CALIB_VALUE_UPDATE 32'h00002000
`define FPG_ODELAY_CALIB_BITSLIP_OFFSET 14
`define FPG_ODELAY_CALIB_BITSLIP 32'h0000c000
`define FPG_ODELAY_CALIB_EN_VTC_OFFSET 16
`define FPG_ODELAY_CALIB_EN_VTC 32'h00010000
`define FPG_ODELAY_CALIB_CAL_LATCH_OFFSET 17
`define FPG_ODELAY_CALIB_CAL_LATCH 32'h00020000
`define FPG_ODELAY_CALIB_TAPS_OFFSET 18
`define FPG_ODELAY_CALIB_TAPS 32'h07fc0000
`define FPG_ODELAY_CALIB_EN_VTC_OFFSET 14
`define FPG_ODELAY_CALIB_EN_VTC 32'h00004000
`define FPG_ODELAY_CALIB_CAL_LATCH_OFFSET 15
`define FPG_ODELAY_CALIB_CAL_LATCH 32'h00008000
`define FPG_ODELAY_CALIB_TAPS_OFFSET 16
`define FPG_ODELAY_CALIB_TAPS 32'h01ff0000
......@@ -97,7 +97,7 @@ class FinePulseGenDriver extends IBusDevice;
calib_time = real'(1.0);
calib_taps = (rv & `FPG_ODELAY_CALIB_TAPS) >> `FPG_ODELAY_CALIB_TAPS_OFFSET;
$display("FPG ODELAY calibration done, val %.1f/%d\n", calib_time, calib_taps );
$display("FPG ODELAY calibration done, %.1f ns = %d taps\n", calib_time, calib_taps );
m_delay_tap_size = calib_time / real'(calib_taps);
......
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