From 101aff2a9880e1a67259f442fcf75c198d307d34 Mon Sep 17 00:00:00 2001 From: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> Date: Fri, 17 Jul 2020 13:22:35 +0200 Subject: [PATCH] wb_fine_pulse_gen: simplify clock crossings Conflicts: modules/wishbone/wb_fine_pulse_gen/xwb_fine_pulse_gen.vhd --- .../fine_pulse_gen_kintexultrascale.vhd | 56 +++- ...fine_pulse_gen_kintexultrascale_shared.vhd | 14 +- .../wb_fine_pulse_gen/fine_pulse_gen_wb.vhd | 304 ++---------------- .../wb_fine_pulse_gen/fine_pulse_gen_wb.wb | 21 -- .../fine_pulse_gen_wbgen2_pkg.vhd | 7 +- .../wb_fine_pulse_gen/xwb_fine_pulse_gen.vhd | 111 ++++--- .../include/wb_fine_pulse_gen_regs.vh | 14 +- testbench/wishbone/wb_fine_pulse_gen/main.sv | 2 +- 8 files changed, 157 insertions(+), 372 deletions(-) diff --git a/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_kintexultrascale.vhd b/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_kintexultrascale.vhd index c6706071..fd7ebd20 100644 --- a/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_kintexultrascale.vhd +++ b/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_kintexultrascale.vhd @@ -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 @@ -311,7 +320,7 @@ begin end process; - + U_Serdes : OSERDESE3 generic map ( @@ -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; diff --git a/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_kintexultrascale_shared.vhd b/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_kintexultrascale_shared.vhd index 4a86c988..7d9f38e1 100644 --- a/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_kintexultrascale_shared.vhd +++ b/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_kintexultrascale_shared.vhd @@ -1,6 +1,7 @@ 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" @@ -198,7 +208,7 @@ begin CLKOUT2_DIVIDE => 4, -- clk_odelay: 250 MHz CLKOUT2_DUTY_CYCLE => 0.5, CLKOUT2_PHASE => 0.0, - + CLKOUT0_USE_FINE_PS => "FALSE", CLKOUT1_USE_FINE_PS => "FALSE" ) diff --git a/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_wb.vhd b/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_wb.vhd index 42644b31..f6441120 100644 --- a/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_wb.vhd +++ b/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_wb.vhd @@ -3,7 +3,7 @@ --------------------------------------------------------------------------------------- -- File : fine_pulse_gen_wb.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 @@ -22,9 +22,6 @@ entity 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; @@ -63,13 +60,6 @@ signal fpg_csr_force4_dly0 : std_logic ; signal fpg_csr_force4_int : std_logic ; signal fpg_csr_force5_dly0 : std_logic ; signal fpg_csr_force5_int : std_logic ; -signal fpg_csr_ready_int : std_logic_vector(5 downto 0); -signal fpg_csr_ready_lwb : std_logic ; -signal fpg_csr_ready_lwb_delay : std_logic ; -signal fpg_csr_ready_lwb_in_progress : std_logic ; -signal fpg_csr_ready_lwb_s0 : std_logic ; -signal fpg_csr_ready_lwb_s1 : std_logic ; -signal fpg_csr_ready_lwb_s2 : std_logic ; signal fpg_csr_pll_rst_int : std_logic ; signal fpg_csr_serdes_rst_int : std_logic ; signal fpg_ocr0_pps_offs_int : std_logic_vector(3 downto 0); @@ -121,48 +111,14 @@ signal fpg_ocr7_mask_int : std_logic_vector(7 downto 0); signal fpg_ocr7_cont_int : std_logic ; signal fpg_ocr7_trig_sel_int : std_logic ; signal fpg_odelay_calib_rst_idelayctrl_int : std_logic ; -signal fpg_odelay_calib_rst_idelayctrl_sync0 : std_logic ; -signal fpg_odelay_calib_rst_idelayctrl_sync1 : std_logic ; signal fpg_odelay_calib_rst_odelay_int : std_logic ; -signal fpg_odelay_calib_rst_odelay_sync0 : std_logic ; -signal fpg_odelay_calib_rst_odelay_sync1 : std_logic ; signal fpg_odelay_calib_rst_oserdes_int : std_logic ; -signal fpg_odelay_calib_rst_oserdes_sync0 : std_logic ; -signal fpg_odelay_calib_rst_oserdes_sync1 : std_logic ; -signal fpg_odelay_calib_rdy_sync0 : std_logic ; -signal fpg_odelay_calib_rdy_sync1 : std_logic ; signal fpg_odelay_calib_value_int : std_logic_vector(8 downto 0); -signal fpg_odelay_calib_value_swb : std_logic ; -signal fpg_odelay_calib_value_swb_delay : std_logic ; -signal fpg_odelay_calib_value_swb_s0 : std_logic ; -signal fpg_odelay_calib_value_swb_s1 : std_logic ; -signal fpg_odelay_calib_value_swb_s2 : std_logic ; +signal fpg_odelay_calib_value_update_dly0 : std_logic ; signal fpg_odelay_calib_value_update_int : std_logic ; -signal fpg_odelay_calib_value_update_int_delay : std_logic ; -signal fpg_odelay_calib_value_update_sync0 : std_logic ; -signal fpg_odelay_calib_value_update_sync1 : std_logic ; -signal fpg_odelay_calib_value_update_sync2 : std_logic ; -signal fpg_odelay_calib_bitslip_int : std_logic_vector(1 downto 0); -signal fpg_odelay_calib_bitslip_swb : std_logic ; -signal fpg_odelay_calib_bitslip_swb_delay : std_logic ; -signal fpg_odelay_calib_bitslip_swb_s0 : std_logic ; -signal fpg_odelay_calib_bitslip_swb_s1 : std_logic ; -signal fpg_odelay_calib_bitslip_swb_s2 : std_logic ; signal fpg_odelay_calib_en_vtc_int : std_logic ; -signal fpg_odelay_calib_en_vtc_sync0 : std_logic ; -signal fpg_odelay_calib_en_vtc_sync1 : std_logic ; +signal fpg_odelay_calib_cal_latch_dly0 : std_logic ; signal fpg_odelay_calib_cal_latch_int : std_logic ; -signal fpg_odelay_calib_cal_latch_int_delay : std_logic ; -signal fpg_odelay_calib_cal_latch_sync0 : std_logic ; -signal fpg_odelay_calib_cal_latch_sync1 : std_logic ; -signal fpg_odelay_calib_cal_latch_sync2 : std_logic ; -signal fpg_odelay_calib_taps_int : std_logic_vector(8 downto 0); -signal fpg_odelay_calib_taps_lwb : std_logic ; -signal fpg_odelay_calib_taps_lwb_delay : std_logic ; -signal fpg_odelay_calib_taps_lwb_in_progress : std_logic ; -signal fpg_odelay_calib_taps_lwb_s0 : std_logic ; -signal fpg_odelay_calib_taps_lwb_s1 : std_logic ; -signal fpg_odelay_calib_taps_lwb_s2 : std_logic ; signal ack_sreg : std_logic_vector(9 downto 0); signal rddata_reg : std_logic_vector(31 downto 0); signal wrdata_reg : std_logic_vector(31 downto 0); @@ -199,9 +155,6 @@ begin fpg_csr_force3_int <= '0'; fpg_csr_force4_int <= '0'; fpg_csr_force5_int <= '0'; - fpg_csr_ready_lwb <= '0'; - fpg_csr_ready_lwb_delay <= '0'; - fpg_csr_ready_lwb_in_progress <= '0'; fpg_csr_pll_rst_int <= '0'; fpg_csr_serdes_rst_int <= '0'; fpg_ocr0_pps_offs_int <= "0000"; @@ -256,19 +209,9 @@ begin fpg_odelay_calib_rst_odelay_int <= '0'; fpg_odelay_calib_rst_oserdes_int <= '0'; fpg_odelay_calib_value_int <= "000000000"; - fpg_odelay_calib_value_swb <= '0'; - fpg_odelay_calib_value_swb_delay <= '0'; fpg_odelay_calib_value_update_int <= '0'; - fpg_odelay_calib_value_update_int_delay <= '0'; - fpg_odelay_calib_bitslip_int <= "00"; - fpg_odelay_calib_bitslip_swb <= '0'; - fpg_odelay_calib_bitslip_swb_delay <= '0'; fpg_odelay_calib_en_vtc_int <= '0'; fpg_odelay_calib_cal_latch_int <= '0'; - fpg_odelay_calib_cal_latch_int_delay <= '0'; - fpg_odelay_calib_taps_lwb <= '0'; - fpg_odelay_calib_taps_lwb_delay <= '0'; - fpg_odelay_calib_taps_lwb_in_progress <= '0'; elsif rising_edge(clk_sys_i) then -- advance the ACK generator shift register ack_sreg(8 downto 0) <= ack_sreg(9 downto 1); @@ -289,28 +232,10 @@ begin fpg_csr_force3_int <= '0'; fpg_csr_force4_int <= '0'; fpg_csr_force5_int <= '0'; + fpg_odelay_calib_value_update_int <= '0'; + fpg_odelay_calib_cal_latch_int <= '0'; ack_in_progress <= '0'; else - fpg_csr_ready_lwb <= fpg_csr_ready_lwb_delay; - fpg_csr_ready_lwb_delay <= '0'; - if ((ack_sreg(1) = '1') and (fpg_csr_ready_lwb_in_progress = '1')) then - rddata_reg(19 downto 14) <= fpg_csr_ready_int; - fpg_csr_ready_lwb_in_progress <= '0'; - end if; - fpg_odelay_calib_value_swb <= fpg_odelay_calib_value_swb_delay; - fpg_odelay_calib_value_swb_delay <= '0'; - fpg_odelay_calib_value_update_int <= fpg_odelay_calib_value_update_int_delay; - fpg_odelay_calib_value_update_int_delay <= '0'; - fpg_odelay_calib_bitslip_swb <= fpg_odelay_calib_bitslip_swb_delay; - fpg_odelay_calib_bitslip_swb_delay <= '0'; - fpg_odelay_calib_cal_latch_int <= fpg_odelay_calib_cal_latch_int_delay; - fpg_odelay_calib_cal_latch_int_delay <= '0'; - fpg_odelay_calib_taps_lwb <= fpg_odelay_calib_taps_lwb_delay; - fpg_odelay_calib_taps_lwb_delay <= '0'; - if ((ack_sreg(1) = '1') and (fpg_odelay_calib_taps_lwb_in_progress = '1')) then - rddata_reg(26 downto 18) <= fpg_odelay_calib_taps_int; - fpg_odelay_calib_taps_lwb_in_progress <= '0'; - end if; end if; else if ((slave_i.cyc = '1') and (slave_i.stb = '1')) then @@ -348,11 +273,7 @@ begin rddata_reg(11) <= '0'; rddata_reg(12) <= '0'; rddata_reg(13) <= '0'; - if (slave_i.we = '0') then - fpg_csr_ready_lwb <= '1'; - fpg_csr_ready_lwb_delay <= '1'; - fpg_csr_ready_lwb_in_progress <= '1'; - end if; + rddata_reg(19 downto 14) <= regs_i.csr_ready_i; rddata_reg(20) <= fpg_csr_pll_rst_int; rddata_reg(21) <= fpg_csr_serdes_rst_int; rddata_reg(22) <= regs_i.csr_pll_locked_i; @@ -365,7 +286,7 @@ begin rddata_reg(29) <= 'X'; rddata_reg(30) <= 'X'; rddata_reg(31) <= 'X'; - ack_sreg(5) <= '1'; + ack_sreg(2) <= '1'; ack_in_progress <= '1'; when "0001" => if (slave_i.we = '1') then @@ -573,37 +494,27 @@ begin fpg_odelay_calib_rst_odelay_int <= wrdata_reg(1); fpg_odelay_calib_rst_oserdes_int <= wrdata_reg(2); fpg_odelay_calib_value_int <= wrdata_reg(12 downto 4); - fpg_odelay_calib_value_swb <= '1'; - fpg_odelay_calib_value_swb_delay <= '1'; fpg_odelay_calib_value_update_int <= wrdata_reg(13); - fpg_odelay_calib_value_update_int_delay <= wrdata_reg(13); - fpg_odelay_calib_bitslip_int <= wrdata_reg(15 downto 14); - fpg_odelay_calib_bitslip_swb <= '1'; - fpg_odelay_calib_bitslip_swb_delay <= '1'; - fpg_odelay_calib_en_vtc_int <= wrdata_reg(16); - fpg_odelay_calib_cal_latch_int <= wrdata_reg(17); - fpg_odelay_calib_cal_latch_int_delay <= wrdata_reg(17); + fpg_odelay_calib_en_vtc_int <= wrdata_reg(14); + fpg_odelay_calib_cal_latch_int <= wrdata_reg(15); end if; rddata_reg(0) <= fpg_odelay_calib_rst_idelayctrl_int; rddata_reg(1) <= fpg_odelay_calib_rst_odelay_int; rddata_reg(2) <= fpg_odelay_calib_rst_oserdes_int; - rddata_reg(3) <= fpg_odelay_calib_rdy_sync1; + rddata_reg(3) <= regs_i.odelay_calib_rdy_i; rddata_reg(12 downto 4) <= fpg_odelay_calib_value_int; rddata_reg(13) <= '0'; - rddata_reg(15 downto 14) <= fpg_odelay_calib_bitslip_int; - rddata_reg(16) <= fpg_odelay_calib_en_vtc_int; - rddata_reg(17) <= '0'; - if (slave_i.we = '0') then - fpg_odelay_calib_taps_lwb <= '1'; - fpg_odelay_calib_taps_lwb_delay <= '1'; - fpg_odelay_calib_taps_lwb_in_progress <= '1'; - end if; + rddata_reg(14) <= fpg_odelay_calib_en_vtc_int; + rddata_reg(15) <= '0'; + rddata_reg(24 downto 16) <= regs_i.odelay_calib_taps_i; + rddata_reg(25) <= 'X'; + rddata_reg(26) <= 'X'; rddata_reg(27) <= 'X'; rddata_reg(28) <= 'X'; rddata_reg(29) <= 'X'; rddata_reg(30) <= 'X'; rddata_reg(31) <= 'X'; - ack_sreg(5) <= '1'; + ack_sreg(2) <= '1'; ack_in_progress <= '1'; when others => -- prevent the slave from hanging the bus on invalid address @@ -801,25 +712,6 @@ end process; -- Sync Pulse Ready --- asynchronous std_logic_vector register : Sync Pulse Ready (type RO/WO, clk_ref_i <-> clk_sys_i) -process (clk_ref_i, rst_n_i) -begin - if (rst_n_i = '0') then - fpg_csr_ready_lwb_s0 <= '0'; - fpg_csr_ready_lwb_s1 <= '0'; - fpg_csr_ready_lwb_s2 <= '0'; - fpg_csr_ready_int <= "000000"; - elsif rising_edge(clk_ref_i) then - fpg_csr_ready_lwb_s0 <= fpg_csr_ready_lwb; - fpg_csr_ready_lwb_s1 <= fpg_csr_ready_lwb_s0; - fpg_csr_ready_lwb_s2 <= fpg_csr_ready_lwb_s1; - if ((fpg_csr_ready_lwb_s1 = '1') and (fpg_csr_ready_lwb_s2 = '0')) then - fpg_csr_ready_int <= regs_i.csr_ready_i; - end if; - end if; -end process; - - -- PLL Reset regs_o.csr_pll_rst_o <= fpg_csr_pll_rst_int; -- Serdes Reset @@ -922,177 +814,43 @@ regs_o.ocr7_cont_o <= fpg_ocr7_cont_int; -- Trigger select regs_o.ocr7_trig_sel_o <= fpg_ocr7_trig_sel_int; -- Reset Output IDELAYCTRL --- synchronizer chain for field : Reset Output IDELAYCTRL (type RW/RO, clk_sys_i <-> clk_odelay_i) -process (clk_odelay_i, rst_n_i) -begin - if (rst_n_i = '0') then - regs_o.odelay_calib_rst_idelayctrl_o <= '0'; - fpg_odelay_calib_rst_idelayctrl_sync0 <= '0'; - fpg_odelay_calib_rst_idelayctrl_sync1 <= '0'; - elsif rising_edge(clk_odelay_i) then - fpg_odelay_calib_rst_idelayctrl_sync0 <= fpg_odelay_calib_rst_idelayctrl_int; - fpg_odelay_calib_rst_idelayctrl_sync1 <= fpg_odelay_calib_rst_idelayctrl_sync0; - regs_o.odelay_calib_rst_idelayctrl_o <= fpg_odelay_calib_rst_idelayctrl_sync1; - end if; -end process; - - +regs_o.odelay_calib_rst_idelayctrl_o <= fpg_odelay_calib_rst_idelayctrl_int; -- Reset Output ODELAY --- synchronizer chain for field : Reset Output ODELAY (type RW/RO, clk_sys_i <-> clk_odelay_i) -process (clk_odelay_i, rst_n_i) -begin - if (rst_n_i = '0') then - regs_o.odelay_calib_rst_odelay_o <= '0'; - fpg_odelay_calib_rst_odelay_sync0 <= '0'; - fpg_odelay_calib_rst_odelay_sync1 <= '0'; - elsif rising_edge(clk_odelay_i) then - fpg_odelay_calib_rst_odelay_sync0 <= fpg_odelay_calib_rst_odelay_int; - fpg_odelay_calib_rst_odelay_sync1 <= fpg_odelay_calib_rst_odelay_sync0; - regs_o.odelay_calib_rst_odelay_o <= fpg_odelay_calib_rst_odelay_sync1; - end if; -end process; - - +regs_o.odelay_calib_rst_odelay_o <= fpg_odelay_calib_rst_odelay_int; -- Reset Output OSERDES --- synchronizer chain for field : Reset Output OSERDES (type RW/RO, clk_sys_i <-> clk_oserdes_i) -process (clk_oserdes_i, rst_n_i) -begin - if (rst_n_i = '0') then - regs_o.odelay_calib_rst_oserdes_o <= '0'; - fpg_odelay_calib_rst_oserdes_sync0 <= '0'; - fpg_odelay_calib_rst_oserdes_sync1 <= '0'; - elsif rising_edge(clk_oserdes_i) then - fpg_odelay_calib_rst_oserdes_sync0 <= fpg_odelay_calib_rst_oserdes_int; - fpg_odelay_calib_rst_oserdes_sync1 <= fpg_odelay_calib_rst_oserdes_sync0; - regs_o.odelay_calib_rst_oserdes_o <= fpg_odelay_calib_rst_oserdes_sync1; - end if; -end process; - - +regs_o.odelay_calib_rst_oserdes_o <= fpg_odelay_calib_rst_oserdes_int; -- Output Delay Ready --- synchronizer chain for field : Output Delay Ready (type RO/WO, clk_odelay_i -> clk_sys_i) -process (clk_odelay_i, rst_n_i) -begin - if (rst_n_i = '0') then - fpg_odelay_calib_rdy_sync0 <= '0'; - fpg_odelay_calib_rdy_sync1 <= '0'; - elsif rising_edge(clk_odelay_i) then - fpg_odelay_calib_rdy_sync0 <= regs_i.odelay_calib_rdy_i; - fpg_odelay_calib_rdy_sync1 <= fpg_odelay_calib_rdy_sync0; - end if; -end process; - - -- Output Delay Value --- asynchronous std_logic_vector register : Output Delay Value (type RW/RO, clk_ref_i <-> clk_sys_i) -process (clk_ref_i, rst_n_i) -begin - if (rst_n_i = '0') then - fpg_odelay_calib_value_swb_s0 <= '0'; - fpg_odelay_calib_value_swb_s1 <= '0'; - fpg_odelay_calib_value_swb_s2 <= '0'; - regs_o.odelay_calib_value_o <= "000000000"; - elsif rising_edge(clk_ref_i) then - fpg_odelay_calib_value_swb_s0 <= fpg_odelay_calib_value_swb; - fpg_odelay_calib_value_swb_s1 <= fpg_odelay_calib_value_swb_s0; - fpg_odelay_calib_value_swb_s2 <= fpg_odelay_calib_value_swb_s1; - if ((fpg_odelay_calib_value_swb_s2 = '0') and (fpg_odelay_calib_value_swb_s1 = '1')) then - regs_o.odelay_calib_value_o <= fpg_odelay_calib_value_int; - end if; - end if; -end process; - - +regs_o.odelay_calib_value_o <= fpg_odelay_calib_value_int; -- Delay value update -process (clk_ref_i, rst_n_i) +process (clk_sys_i, rst_n_i) begin if (rst_n_i = '0') then + fpg_odelay_calib_value_update_dly0 <= '0'; regs_o.odelay_calib_value_update_o <= '0'; - fpg_odelay_calib_value_update_sync0 <= '0'; - fpg_odelay_calib_value_update_sync1 <= '0'; - fpg_odelay_calib_value_update_sync2 <= '0'; - elsif rising_edge(clk_ref_i) then - fpg_odelay_calib_value_update_sync0 <= fpg_odelay_calib_value_update_int; - fpg_odelay_calib_value_update_sync1 <= fpg_odelay_calib_value_update_sync0; - fpg_odelay_calib_value_update_sync2 <= fpg_odelay_calib_value_update_sync1; - regs_o.odelay_calib_value_update_o <= fpg_odelay_calib_value_update_sync2 and (not fpg_odelay_calib_value_update_sync1); - end if; -end process; - - --- Serdes Bitslip --- asynchronous std_logic_vector register : Serdes Bitslip (type RW/RO, clk_odelay_i <-> clk_sys_i) -process (clk_odelay_i, rst_n_i) -begin - if (rst_n_i = '0') then - fpg_odelay_calib_bitslip_swb_s0 <= '0'; - fpg_odelay_calib_bitslip_swb_s1 <= '0'; - fpg_odelay_calib_bitslip_swb_s2 <= '0'; - regs_o.odelay_calib_bitslip_o <= "00"; - elsif rising_edge(clk_odelay_i) then - fpg_odelay_calib_bitslip_swb_s0 <= fpg_odelay_calib_bitslip_swb; - fpg_odelay_calib_bitslip_swb_s1 <= fpg_odelay_calib_bitslip_swb_s0; - fpg_odelay_calib_bitslip_swb_s2 <= fpg_odelay_calib_bitslip_swb_s1; - if ((fpg_odelay_calib_bitslip_swb_s2 = '0') and (fpg_odelay_calib_bitslip_swb_s1 = '1')) then - regs_o.odelay_calib_bitslip_o <= fpg_odelay_calib_bitslip_int; - end if; + elsif rising_edge(clk_sys_i) then + fpg_odelay_calib_value_update_dly0 <= fpg_odelay_calib_value_update_int; + regs_o.odelay_calib_value_update_o <= fpg_odelay_calib_value_update_int and (not fpg_odelay_calib_value_update_dly0); end if; end process; -- Enable VT compensation --- synchronizer chain for field : Enable VT compensation (type RW/RO, clk_sys_i <-> clk_odelay_i) -process (clk_odelay_i, rst_n_i) -begin - if (rst_n_i = '0') then - regs_o.odelay_calib_en_vtc_o <= '0'; - fpg_odelay_calib_en_vtc_sync0 <= '0'; - fpg_odelay_calib_en_vtc_sync1 <= '0'; - elsif rising_edge(clk_odelay_i) then - fpg_odelay_calib_en_vtc_sync0 <= fpg_odelay_calib_en_vtc_int; - fpg_odelay_calib_en_vtc_sync1 <= fpg_odelay_calib_en_vtc_sync0; - regs_o.odelay_calib_en_vtc_o <= fpg_odelay_calib_en_vtc_sync1; - end if; -end process; - - +regs_o.odelay_calib_en_vtc_o <= fpg_odelay_calib_en_vtc_int; -- Latch calibration taps -process (clk_odelay_i, rst_n_i) +process (clk_sys_i, rst_n_i) begin if (rst_n_i = '0') then + fpg_odelay_calib_cal_latch_dly0 <= '0'; regs_o.odelay_calib_cal_latch_o <= '0'; - fpg_odelay_calib_cal_latch_sync0 <= '0'; - fpg_odelay_calib_cal_latch_sync1 <= '0'; - fpg_odelay_calib_cal_latch_sync2 <= '0'; - elsif rising_edge(clk_odelay_i) then - fpg_odelay_calib_cal_latch_sync0 <= fpg_odelay_calib_cal_latch_int; - fpg_odelay_calib_cal_latch_sync1 <= fpg_odelay_calib_cal_latch_sync0; - fpg_odelay_calib_cal_latch_sync2 <= fpg_odelay_calib_cal_latch_sync1; - regs_o.odelay_calib_cal_latch_o <= fpg_odelay_calib_cal_latch_sync2 and (not fpg_odelay_calib_cal_latch_sync1); + elsif rising_edge(clk_sys_i) then + fpg_odelay_calib_cal_latch_dly0 <= fpg_odelay_calib_cal_latch_int; + regs_o.odelay_calib_cal_latch_o <= fpg_odelay_calib_cal_latch_int and (not fpg_odelay_calib_cal_latch_dly0); end if; end process; -- n Taps --- asynchronous std_logic_vector register : n Taps (type RO/WO, clk_odelay_i <-> clk_sys_i) -process (clk_odelay_i, rst_n_i) -begin - if (rst_n_i = '0') then - fpg_odelay_calib_taps_lwb_s0 <= '0'; - fpg_odelay_calib_taps_lwb_s1 <= '0'; - fpg_odelay_calib_taps_lwb_s2 <= '0'; - fpg_odelay_calib_taps_int <= "000000000"; - elsif rising_edge(clk_odelay_i) then - fpg_odelay_calib_taps_lwb_s0 <= fpg_odelay_calib_taps_lwb; - fpg_odelay_calib_taps_lwb_s1 <= fpg_odelay_calib_taps_lwb_s0; - fpg_odelay_calib_taps_lwb_s2 <= fpg_odelay_calib_taps_lwb_s1; - if ((fpg_odelay_calib_taps_lwb_s1 = '1') and (fpg_odelay_calib_taps_lwb_s2 = '0')) then - fpg_odelay_calib_taps_int <= regs_i.odelay_calib_taps_i; - end if; - end if; -end process; - - rwaddr_reg <= slave_i.adr(5 downto 2); slave_o.stall <= (not ack_sreg(0)) and (slave_i.stb and slave_i.cyc); slave_o.err <= '0'; diff --git a/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_wb.wb b/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_wb.wb index 651498e7..9219739d 100644 --- a/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_wb.wb +++ b/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_wb.wb @@ -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,27 +635,14 @@ 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 { name = "Enable VT compensation"; description = "Enable VT compensation"; @@ -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"; }; }; }; diff --git a/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_wbgen2_pkg.vhd b/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_wbgen2_pkg.vhd index 6cfb8414..eedaad42 100644 --- a/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_wbgen2_pkg.vhd +++ b/modules/wishbone/wb_fine_pulse_gen/fine_pulse_gen_wbgen2_pkg.vhd @@ -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; diff --git a/modules/wishbone/wb_fine_pulse_gen/xwb_fine_pulse_gen.vhd b/modules/wishbone/wb_fine_pulse_gen/xwb_fine_pulse_gen.vhd index debe9785..718b5385 100644 --- a/modules/wishbone/wb_fine_pulse_gen/xwb_fine_pulse_gen.vhd +++ b/modules/wishbone/wb_fine_pulse_gen/xwb_fine_pulse_gen.vhd @@ -24,7 +24,7 @@ entity xwb_fine_pulse_gen is clk_ser_ext_i : in std_logic := '0'; -- external SERDES clock, used when -- g_use_external_serdes_clock == true - + ext_trigger_p_i : in std_logic := '0'; -- External trigger (i.e. RF receiver) pps_p_i : in std_logic; -- WR PPS @@ -49,7 +49,7 @@ architecture rtl of xwb_fine_pulse_gen is return false; end if; end function; - + component fine_pulse_gen_kintex7_shared is @@ -100,7 +100,7 @@ architecture rtl of xwb_fine_pulse_gen is cont : std_logic; force_tr : std_logic; - + odelay_load : std_logic; odelay_value_out : std_logic_vector(8 downto 0); @@ -109,19 +109,19 @@ architecture rtl of xwb_fine_pulse_gen is type t_channel_array is array(integer range <>) of t_channel; constant c_MAX_NUM_CHANNELS : integer := 6; - + signal ch : t_channel_array(0 to c_MAX_NUM_CHANNELS-1); signal clk_par : std_logic; signal clk_ser : std_logic; signal clk_odelay : std_logic; - + signal regs_out : t_fpg_out_registers; signal regs_in : t_fpg_in_registers; signal rst_n_wr : std_logic; signal pps_p_d : std_logic; - + function f_to_bool(x : bit) return boolean is begin if x= '1' then @@ -130,28 +130,33 @@ architecture rtl of xwb_fine_pulse_gen is return false; end if; end f_to_bool; - + constant c_pps_divider : integer := 6250; signal pps_ext : std_logic; signal pps_cnt : unsigned(15 downto 0); 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 - + p_extend_pps : process(clk_ref_i) begin if rising_edge(clk_ref_i) then 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); pps_ext <= '0'; @@ -165,16 +170,13 @@ begin end if; end if; end process; - + U_Regs : entity work.fine_pulse_gen_wb 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); @@ -274,13 +276,27 @@ begin q_p_o => ch(5).force_tr); - - 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; @@ -323,13 +339,13 @@ begin ch(3).pps_offs <= unsigned(regs_out.ocr3_pps_offs_o); ch(4).pps_offs <= unsigned(regs_out.ocr4_pps_offs_o); ch(5).pps_offs <= unsigned(regs_out.ocr5_pps_offs_o); - + gen_channels : for i in 0 to g_NUM_CHANNELS-1 generate - - - + + + p_fsm : process(clk_ref_i) begin if rising_edge(clk_ref_i) then @@ -337,20 +353,17 @@ 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; - - + + case ch(i).state is when IDLE => ch(i).trig_p <= '0'; @@ -379,8 +392,8 @@ begin if pps_ext = '1' then ch(i).state <= WAIT_TRIGGER; end if; - - + + when WAIT_PPS => ch(i).trig_p <= '0'; ch(i).delay_load <= '0'; @@ -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, @@ -457,7 +471,7 @@ begin ); end generate gen_is_kintex_us_pg; - + end generate; @@ -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; - +end rtl; diff --git a/testbench/wishbone/include/wb_fine_pulse_gen_regs.vh b/testbench/wishbone/include/wb_fine_pulse_gen_regs.vh index 95f3c2ba..953e67b7 100644 --- a/testbench/wishbone/include/wb_fine_pulse_gen_regs.vh +++ b/testbench/wishbone/include/wb_fine_pulse_gen_regs.vh @@ -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 diff --git a/testbench/wishbone/wb_fine_pulse_gen/main.sv b/testbench/wishbone/wb_fine_pulse_gen/main.sv index 7bcbe266..c8a3bf91 100644 --- a/testbench/wishbone/wb_fine_pulse_gen/main.sv +++ b/testbench/wishbone/wb_fine_pulse_gen/main.sv @@ -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); -- GitLab