Commit dfdb1574 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

wb_fine_pulse_gen: support for configurable pulse width. INTERFACE CHANGED.

parent c68481b6
......@@ -20,15 +20,16 @@ entity fine_pulse_gen_kintex7 is
clk_serdes_i : in std_logic;
rst_serdes_i : in std_logic;
rst_sys_n_i : in std_logic;
cont_i : in std_logic;
rst_sys_n_i : in std_logic;
cont_i : in std_logic;
pol_i : in std_logic;
coarse_i : in std_logic_vector(7 downto 0);
coarse_i : in std_logic_vector(3 downto 0);
trig_p_i : in std_logic;
length_i : in std_logic_vector(23 downto 0);
pulse_o : out std_logic;
pulse_o : out std_logic;
dly_load_i : in std_logic;
dly_fine_i : in std_logic_vector(4 downto 0)
......@@ -55,75 +56,142 @@ architecture rtl of fine_pulse_gen_kintex7 is
-- end f_gen_bitmask;
signal mask : std_logic_vector(15 downto 0);
signal flip : std_logic;
signal dly_load_d : std_logic;
signal mask_start : std_logic_vector(15 downto 0);
signal mask_end : std_logic_vector(15 downto 0);
signal dly_load_d : std_logic;
signal length_d : unsigned(23 downto 0);
signal pulse_pending : std_logic;
attribute mark_debug : string;
attribute mark_debug of pol_i : signal is "TRUE";
attribute mark_debug of coarse_i : signal is "TRUE";
attribute mark_debug of trig_p_i : signal is "TRUE";
attribute mark_debug of dly_load_i : signal is "TRUE";
attribute mark_debug of dly_fine_i : signal is "TRUE";
attribute mark_debug of odelay_ntaps : signal is "TRUE";
type t_state is (IDLE, CONT_H, CONT_L, START_PULSE_H, START_PULSE_L, MID_PULSE_H, MID_PULSE_L, END_PULSE_H, END_PULSE_L);
signal state : t_state;
begin
rst <= not rst_sys_n_i;
process(clk_par_i)
variable rv : std_logic_vector(15 downto 0);
process(clk_par_i, rst_sys_n_i)
variable rv, rv2 : std_logic_vector(15 downto 0);
begin
if rising_edge(clk_par_i) then
if rst_sys_n_i = '0' then
pulse_pending <= '0';
elsif rising_edge(clk_par_i) then
dly_load_d <= dly_load_i;
if dly_load_i = '1' then
odelay_ntaps <= dly_fine_i;
length_d <= unsigned(length_i);
if cont_i = '1' then
case coarse_i is
when x"00" =>
when x"0" =>
rv := "1111000011110000";
when x"01" =>
when x"1" =>
rv := "0111100001111000";
when x"02" =>
when x"2" =>
rv := "0011110000111100";
when x"03" =>
when x"3" =>
rv := "0001111000011110";
when x"04" =>
when x"4" =>
rv := "0000111100001111";
when x"05" =>
when x"5" =>
rv := "1000011110000111";
when x"06" =>
when x"6" =>
rv := "1100001111000011";
when x"07" =>
when x"7" =>
rv := "1110000111100001";
when others =>
rv := (others => '0');
end case;
if pol_i = '1' then
mask_start <= not rv;
mask_end <= not rv;
else
mask_start <= rv;
mask_end <= rv;
end if;
else
case coarse_i is
when x"00" =>
rv := "1111000000000000";
when x"01" =>
rv := "0111100000000000";
when x"02" =>
rv := "0011110000000000";
when x"03" =>
rv := "0001111000000000";
when x"04" =>
rv := "0000111100000000";
when x"05" =>
rv := "0000011110000000";
when x"06" =>
rv := "0000001111000000";
when x"07" =>
rv := "0000000111100000";
when others =>
rv := (others => '0');
end case;
end if;
if pol_i = '0' then
mask <= rv;
else
mask <= not rv;
if unsigned(length_i) = 0 then
case coarse_i is
when x"0" =>
rv := "1111000000000000";
when x"1" =>
rv := "0111100000000000";
when x"2" =>
rv := "0011110000000000";
when x"3" =>
rv := "0001111000000000";
when x"4" =>
rv := "0000111100000000";
when x"5" =>
rv := "0000011110000000";
when x"6" =>
rv := "0000001111000000";
when x"7" =>
rv := "0000000111100000";
when others =>
rv := (others => '0');
end case;
if pol_i = '1' then
mask_start <= not rv;
mask_end <= not rv;
else
mask_start <= rv;
mask_end <= rv;
end if;
else
case coarse_i is
when x"0" =>
rv := "1111111111111111";
when x"1" =>
rv := "0111111111111111";
when x"2" =>
rv := "0011111111111111";
when x"3" =>
rv := "0001111111111111";
when x"4" =>
rv := "0000111111111111";
when x"5" =>
rv := "0000011111111111";
when x"6" =>
rv := "0000001111111111";
when x"7" =>
rv := "0000000111111111";
when others =>
rv := (others => '0');
end case;
if pol_i = '1' then
mask_start <= not rv;
mask_end <= rv;
else
mask_start <= rv;
mask_end <= not rv;
end if;
end if;
end if;
end if;
......@@ -131,29 +199,83 @@ begin
odelay_load <= dly_load_i or dly_load_d;
trig_d <= trig_p_i;
case state is
when IDLE =>
if pol_i = '1' then
par_data <= (others => '1');
else
par_data <= (others => '0');
end if;
if trig_p_i = '1' then
if cont_i = '1' then
state <= CONT_H;
elsif length_d = 0 then
state <= END_PULSE_H;
else
state <= START_PULSE_H;
end if;
end if;
if trig_p_i = '1' then
par_data <= mask(15 downto 8);
flip <= '0';
elsif trig_d = '1' then
par_data <= mask(7 downto 0);
else
when CONT_H =>
if cont_i = '0' then
state <= IDLE;
else
state <= CONT_L;
end if;
if cont_i = '1' then
if flip = '1' then
par_data <= mask(7 downto 0);
par_data <= mask_start(15 downto 8);
when CONT_L =>
par_data <= mask_start(7 downto 0);
state <= CONT_H;
when START_PULSE_H =>
par_data <= mask_start(15 downto 8);
state <= START_PULSE_L;
when START_PULSE_L =>
par_data <= mask_start(7 downto 0);
if length_d = 0 then
state <= IDLE;
else
par_data <= mask(15 downto 8);
state <= MID_PULSE_H;
end if;
else
when MID_PULSE_H =>
state <= MID_PULSE_L;
if pol_i = '1' then
par_data <= (others => '0');
else
par_data <= (others => '1');
end if;
when MID_PULSE_L =>
if length_d = 0 then
state <= END_PULSE_H;
else
state <= MID_PULSE_L;
end if;
length_d <= length_d - 1;
if pol_i = '1' then
par_data <= (others => '0');
else
par_data <= (others => '1');
end if;
end if;
end if;
when END_PULSE_H =>
par_data <= mask_end(15 downto 8);
state <= END_PULSE_L;
when END_PULSE_L =>
par_data <= mask_end(7 downto 0);
state <= IDLE;
end case;
end if;
end process;
......@@ -225,7 +347,7 @@ begin
end generate gen_without_odelay;
pulse_o <= dout_prebuf;
-- gen_output_diff : if g_use_diff_output generate
-- U_OBuf : OBUFDS
-- generic map(
......
......@@ -15,6 +15,9 @@ entity fine_pulse_gen_kintex7_shared is
-- PLL async reset
pll_rst_i : in std_logic;
idelayctrl_rst_i : in std_logic;
idelayctrl_rdy_o : out std_logic;
clk_ser_ext_i : in std_logic;
-- 62.5 MHz reference
......@@ -95,9 +98,9 @@ begin
IDELAYCTRL_inst : IDELAYCTRL
port map (
RDY => open, -- 1-bit output: Ready output
RDY => idelayctrl_rdy_o, -- 1-bit output: Ready output
REFCLK => clk_iodelay_bufg, -- 1-bit input: Reference clock input
RST => '0' -- 1-bit input: Active high reset input
RST => idelayctrl_rst_i -- 1-bit input: Active high reset input
);
clk_odelay_o <= clk_iodelay_bufg;
......
......@@ -151,7 +151,7 @@ peripheral {
field {
name = "Fine delay adjust";
prefix = "FINE";
size = 9;
size = 5;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
......@@ -167,8 +167,8 @@ peripheral {
field {
name = "Serdes Bitmask";
prefix = "MASK";
size = 8;
prefix = "COARSE";
size = 4;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
......@@ -191,6 +191,15 @@ peripheral {
description = "1: external trigger; 0: PPS";
};
field {
name = "Pulse Length (in clock cycles, 0 = 1 clock)";
prefix = "LENGTH";
size = 16;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
......@@ -210,7 +219,7 @@ peripheral {
field {
name = "Fine delay adjust";
prefix = "FINE";
size = 9;
size = 5;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
......@@ -225,9 +234,9 @@ peripheral {
};
field {
name = "Serdes Bitmask";
prefix = "MASK";
size = 8;
name = "Coarse";
prefix = "COARSE";
size = 4;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
......@@ -249,6 +258,14 @@ peripheral {
access_dev = READ_ONLY;
description = "1: external trigger; 0: PPS";
};
field {
name = "Pulse Length (in clock cycles, 0 = 1 clock)";
prefix = "LENGTH";
size = 16;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
......@@ -268,7 +285,7 @@ peripheral {
field {
name = "Fine delay adjust";
prefix = "FINE";
size = 9;
size = 5;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
......@@ -283,9 +300,9 @@ peripheral {
};
field {
name = "Serdes Bitmask";
prefix = "MASK";
size = 8;
name = "Coarse";
prefix = "COARSE";
size = 4;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
......@@ -307,6 +324,15 @@ peripheral {
access_dev = READ_ONLY;
description = "1: external trigger; 0: PPS";
};
field {
name = "Pulse Length (in clock cycles, 0 = 1 clock)";
prefix = "LENGTH";
size = 16;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
......@@ -325,7 +351,7 @@ peripheral {
field {
name = "Fine delay adjust";
prefix = "FINE";
size = 9;
size = 5;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
......@@ -340,9 +366,9 @@ peripheral {
};
field {
name = "Serdes Bitmask";
prefix = "MASK";
size = 8;
name = "Coarse";
prefix = "COARSE";
size = 4;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
......@@ -364,6 +390,16 @@ peripheral {
access_dev = READ_ONLY;
description = "1: external trigger; 0: PPS";
};
field {
name = "Pulse Length (in clock cycles, 0 = 1 clock)";
prefix = "LENGTH";
size = 16;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
......@@ -382,7 +418,7 @@ peripheral {
field {
name = "Fine delay adjust";
prefix = "FINE";
size = 9;
size = 5;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
......@@ -397,9 +433,9 @@ peripheral {
};
field {
name = "Serdes Bitmask";
prefix = "MASK";
size = 8;
name = "Coarse";
prefix = "COARSE";
size = 4;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
......@@ -421,6 +457,16 @@ peripheral {
access_dev = READ_ONLY;
description = "1: external trigger; 0: PPS";
};
field {
name = "Pulse Length (in clock cycles, 0 = 1 clock)";
prefix = "LENGTH";
size = 16;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
......@@ -439,7 +485,7 @@ peripheral {
field {
name = "Fine delay adjust";
prefix = "FINE";
size = 9;
size = 5;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
......@@ -454,9 +500,9 @@ peripheral {
};
field {
name = "Serdes Bitmask";
prefix = "MASK";
size = 8;
name = "Coarse";
prefix = "COARSE";
size = 4;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
......@@ -478,6 +524,14 @@ peripheral {
access_dev = READ_ONLY;
description = "1: external trigger; 0: PPS";
};
field {
name = "Pulse Length (in clock cycles, 0 = 1 clock)";
prefix = "LENGTH";
size = 16;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
......@@ -497,7 +551,7 @@ peripheral {
field {
name = "Fine delay adjust";
prefix = "FINE";
size = 9;
size = 5;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
......@@ -512,9 +566,9 @@ peripheral {
};
field {
name = "Serdes Bitmask";
prefix = "MASK";
size = 8;
name = "Coarse";
prefix = "COARSE";
size = 4;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
......@@ -536,6 +590,15 @@ peripheral {
access_dev = READ_ONLY;
description = "1: external trigger; 0: PPS";
};
field {
name = "Pulse Length (in clock cycles, 0 = 1 clock)";
prefix = "LENGTH";
size = 16;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
......@@ -554,7 +617,7 @@ peripheral {
field {
name = "Fine delay adjust";
prefix = "FINE";
size = 9;
size = 5;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
......@@ -569,9 +632,9 @@ peripheral {
};
field {
name = "Serdes Bitmask";
prefix = "MASK";
size = 8;
name = "Coarse";
prefix = "COARSE";
size = 4;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
......@@ -593,6 +656,15 @@ peripheral {
access_dev = READ_ONLY;
description = "1: external trigger; 0: PPS";
};
field {
name = "Pulse Length (in clock cycles * 16, 0 = 1 clock, 1 = 16 clocks, etc)";
prefix = "LENGTH";
size = 16;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
......
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : fine_pulse_gen_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from fine_pulse_gen_wb.wb
-- Created : Tue Jul 7 14:29:21 2020
-- Created : Wed Mar 24 01:13:29 2021
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fine_pulse_gen_wb.wb
......@@ -54,53 +54,61 @@ package fpg_wbgen2_pkg is
csr_pll_rst_o : std_logic;
csr_serdes_rst_o : std_logic;
ocr0_pps_offs_o : std_logic_vector(3 downto 0);
ocr0_fine_o : std_logic_vector(8 downto 0);
ocr0_fine_o : std_logic_vector(4 downto 0);
ocr0_pol_o : std_logic;
ocr0_mask_o : std_logic_vector(7 downto 0);
ocr0_coarse_o : std_logic_vector(3 downto 0);
ocr0_cont_o : std_logic;
ocr0_trig_sel_o : std_logic;
ocr0_length_o : std_logic_vector(15 downto 0);
ocr1_pps_offs_o : std_logic_vector(3 downto 0);
ocr1_fine_o : std_logic_vector(8 downto 0);
ocr1_fine_o : std_logic_vector(4 downto 0);
ocr1_pol_o : std_logic;
ocr1_mask_o : std_logic_vector(7 downto 0);
ocr1_coarse_o : std_logic_vector(3 downto 0);
ocr1_cont_o : std_logic;
ocr1_trig_sel_o : std_logic;
ocr1_length_o : std_logic_vector(15 downto 0);
ocr2_pps_offs_o : std_logic_vector(3 downto 0);
ocr2_fine_o : std_logic_vector(8 downto 0);
ocr2_fine_o : std_logic_vector(4 downto 0);
ocr2_pol_o : std_logic;
ocr2_mask_o : std_logic_vector(7 downto 0);
ocr2_coarse_o : std_logic_vector(3 downto 0);
ocr2_cont_o : std_logic;
ocr2_trig_sel_o : std_logic;
ocr2_length_o : std_logic_vector(15 downto 0);
ocr3_pps_offs_o : std_logic_vector(3 downto 0);
ocr3_fine_o : std_logic_vector(8 downto 0);
ocr3_fine_o : std_logic_vector(4 downto 0);
ocr3_pol_o : std_logic;
ocr3_mask_o : std_logic_vector(7 downto 0);
ocr3_coarse_o : std_logic_vector(3 downto 0);
ocr3_cont_o : std_logic;
ocr3_trig_sel_o : std_logic;
ocr3_length_o : std_logic_vector(15 downto 0);
ocr4_pps_offs_o : std_logic_vector(3 downto 0);
ocr4_fine_o : std_logic_vector(8 downto 0);
ocr4_fine_o : std_logic_vector(4 downto 0);
ocr4_pol_o : std_logic;
ocr4_mask_o : std_logic_vector(7 downto 0);
ocr4_coarse_o : std_logic_vector(3 downto 0);
ocr4_cont_o : std_logic;
ocr4_trig_sel_o : std_logic;
ocr4_length_o : std_logic_vector(15 downto 0);
ocr5_pps_offs_o : std_logic_vector(3 downto 0);
ocr5_fine_o : std_logic_vector(8 downto 0);
ocr5_fine_o : std_logic_vector(4 downto 0);
ocr5_pol_o : std_logic;
ocr5_mask_o : std_logic_vector(7 downto 0);
ocr5_coarse_o : std_logic_vector(3 downto 0);
ocr5_cont_o : std_logic;
ocr5_trig_sel_o : std_logic;
ocr5_length_o : std_logic_vector(15 downto 0);
ocr6_pps_offs_o : std_logic_vector(3 downto 0);
ocr6_fine_o : std_logic_vector(8 downto 0);
ocr6_fine_o : std_logic_vector(4 downto 0);
ocr6_pol_o : std_logic;
ocr6_mask_o : std_logic_vector(7 downto 0);
ocr6_coarse_o : std_logic_vector(3 downto 0);
ocr6_cont_o : std_logic;
ocr6_trig_sel_o : std_logic;
ocr6_length_o : std_logic_vector(15 downto 0);
ocr7_pps_offs_o : std_logic_vector(3 downto 0);
ocr7_fine_o : std_logic_vector(8 downto 0);
ocr7_fine_o : std_logic_vector(4 downto 0);
ocr7_pol_o : std_logic;
ocr7_mask_o : std_logic_vector(7 downto 0);
ocr7_coarse_o : std_logic_vector(3 downto 0);
ocr7_cont_o : std_logic;
ocr7_trig_sel_o : std_logic;
ocr7_length_o : std_logic_vector(15 downto 0);
odelay_calib_rst_idelayctrl_o : std_logic;
odelay_calib_rst_odelay_o : std_logic;
odelay_calib_rst_oserdes_o : std_logic;
......@@ -130,51 +138,59 @@ package fpg_wbgen2_pkg is
ocr0_pps_offs_o => (others => '0'),
ocr0_fine_o => (others => '0'),
ocr0_pol_o => '0',
ocr0_mask_o => (others => '0'),
ocr0_coarse_o => (others => '0'),
ocr0_cont_o => '0',
ocr0_trig_sel_o => '0',
ocr0_length_o => (others => '0'),
ocr1_pps_offs_o => (others => '0'),
ocr1_fine_o => (others => '0'),
ocr1_pol_o => '0',
ocr1_mask_o => (others => '0'),
ocr1_coarse_o => (others => '0'),
ocr1_cont_o => '0',
ocr1_trig_sel_o => '0',
ocr1_length_o => (others => '0'),
ocr2_pps_offs_o => (others => '0'),
ocr2_fine_o => (others => '0'),
ocr2_pol_o => '0',
ocr2_mask_o => (others => '0'),
ocr2_coarse_o => (others => '0'),
ocr2_cont_o => '0',
ocr2_trig_sel_o => '0',
ocr2_length_o => (others => '0'),
ocr3_pps_offs_o => (others => '0'),
ocr3_fine_o => (others => '0'),
ocr3_pol_o => '0',
ocr3_mask_o => (others => '0'),
ocr3_coarse_o => (others => '0'),
ocr3_cont_o => '0',
ocr3_trig_sel_o => '0',
ocr3_length_o => (others => '0'),
ocr4_pps_offs_o => (others => '0'),
ocr4_fine_o => (others => '0'),
ocr4_pol_o => '0',
ocr4_mask_o => (others => '0'),
ocr4_coarse_o => (others => '0'),
ocr4_cont_o => '0',
ocr4_trig_sel_o => '0',
ocr4_length_o => (others => '0'),
ocr5_pps_offs_o => (others => '0'),
ocr5_fine_o => (others => '0'),
ocr5_pol_o => '0',
ocr5_mask_o => (others => '0'),
ocr5_coarse_o => (others => '0'),
ocr5_cont_o => '0',
ocr5_trig_sel_o => '0',
ocr5_length_o => (others => '0'),
ocr6_pps_offs_o => (others => '0'),
ocr6_fine_o => (others => '0'),
ocr6_pol_o => '0',
ocr6_mask_o => (others => '0'),
ocr6_coarse_o => (others => '0'),
ocr6_cont_o => '0',
ocr6_trig_sel_o => '0',
ocr6_length_o => (others => '0'),
ocr7_pps_offs_o => (others => '0'),
ocr7_fine_o => (others => '0'),
ocr7_pol_o => '0',
ocr7_mask_o => (others => '0'),
ocr7_coarse_o => (others => '0'),
ocr7_cont_o => '0',
ocr7_trig_sel_o => '0',
ocr7_length_o => (others => '0'),
odelay_calib_rst_idelayctrl_o => '0',
odelay_calib_rst_odelay_o => '0',
odelay_calib_rst_oserdes_o => '0',
......
......@@ -52,34 +52,6 @@ architecture rtl of xwb_fine_pulse_gen is
component fine_pulse_gen_kintex7_shared is
generic (
g_global_use_odelay : boolean;
g_use_external_serdes_clock : boolean);
port (
pll_rst_i : in std_logic;
clk_ser_ext_i : in std_logic;
clk_ref_i : in std_logic;
clk_par_o : out std_logic;
clk_ser_o : out std_logic;
clk_odelay_o : out std_logic;
pll_locked_o : out std_logic);
end component fine_pulse_gen_kintex7_shared;
component fine_pulse_gen_kintexultrascale_shared is
generic (
g_global_use_odelay : boolean;
g_use_external_serdes_clock : boolean
);
port (
pll_rst_i : in std_logic;
clk_ser_ext_i : in std_logic;
clk_ref_i : in std_logic;
clk_par_o : out std_logic;
clk_ser_o : out std_logic;
clk_odelay_o : out std_logic;
pll_locked_o : out std_logic);
end component fine_pulse_gen_kintexultrascale_shared;
type t_channel_state is (IDLE, WAIT_PPS, WAIT_PPS_FORCED, WAIT_TRIGGER);
......@@ -94,9 +66,10 @@ architecture rtl of xwb_fine_pulse_gen is
pol : std_logic;
cnt : unsigned(3 downto 0);
pps_offs : unsigned(3 downto 0);
mask : std_logic_vector(7 downto 0);
coarse : std_logic_vector(3 downto 0);
delay_load : std_logic;
delay_fine : std_logic_vector(8 downto 0);
delay_fine : std_logic_vector(4 downto 0);
length: std_logic_vector(23 downto 0);
cont : std_logic;
force_tr : std_logic;
......@@ -312,13 +285,20 @@ begin
ch(4).delay_fine <= regs_out.ocr4_fine_o;
ch(5).delay_fine <= regs_out.ocr5_fine_o;
ch(0).mask <= regs_out.ocr0_mask_o;
ch(1).mask <= regs_out.ocr1_mask_o;
ch(2).mask <= regs_out.ocr2_mask_o;
ch(3).mask <= regs_out.ocr3_mask_o;
ch(4).mask <= regs_out.ocr4_mask_o;
ch(5).mask <= regs_out.ocr5_mask_o;
ch(0).coarse <= regs_out.ocr0_coarse_o;
ch(1).coarse <= regs_out.ocr1_coarse_o;
ch(2).coarse <= regs_out.ocr2_coarse_o;
ch(3).coarse <= regs_out.ocr3_coarse_o;
ch(4).coarse <= regs_out.ocr4_coarse_o;
ch(5).coarse <= regs_out.ocr5_coarse_o;
ch(0).length <= "0000" & regs_out.ocr0_length_o & "0000";
ch(1).length <= "0000" & regs_out.ocr1_length_o & "0000";
ch(2).length <= "0000" & regs_out.ocr2_length_o & "0000";
ch(3).length <= "0000" & regs_out.ocr3_length_o & "0000";
ch(4).length <= "0000" & regs_out.ocr4_length_o & "0000";
ch(5).length <= "0000" & regs_out.ocr5_length_o & "0000";
ch(0).cont <= regs_out.ocr0_cont_o;
ch(1).cont <= regs_out.ocr1_cont_o;
ch(2).cont <= regs_out.ocr2_cont_o;
......@@ -431,7 +411,8 @@ begin
rst_sys_n_i => rst_sys_n_i,
trig_p_i => ch(I).trig_p,
cont_i => ch(i).cont,
coarse_i => ch(I).mask,
coarse_i => ch(I).coarse,
length_i => ch(i).length,
pol_i => ch(I).pol,
pulse_o => pulse_o(i),
dly_load_i => ch(i).delay_load,
......@@ -455,11 +436,12 @@ begin
rst_sys_n_i => rst_sys_n_i,
trig_p_i => ch(I).trig_p,
cont_i => ch(i).cont,
coarse_i => ch(I).mask,
coarse_i => ("0000" & ch(I).coarse),
-- length_i => ch(i).length, -- fixme: ultrascale PG doesn't support length
pol_i => ch(I).pol,
pulse_o => pulse_o(i),
dly_load_i => ch(i).delay_load,
dly_fine_i => ch(i).delay_fine,
dly_fine_i => ("0000" & ch(i).delay_fine),
odelay_load_i => ch(i).odelay_load,
odelay_en_vtc_i => regs_out.odelay_calib_en_vtc_o,
......@@ -480,7 +462,7 @@ begin
gen_is_kintex7: if g_target_platform = "Kintex7" generate
U_K7_Shared: fine_pulse_gen_kintex7_shared
U_K7_Shared: entity work.fine_pulse_gen_kintex7_shared
generic map (
g_global_use_odelay => f_global_use_odelay,
g_use_external_serdes_clock => g_use_external_serdes_clock)
......@@ -491,7 +473,18 @@ begin
clk_ser_o => clk_ser,
clk_ser_ext_i => clk_ser_ext_i,
-- clk_odelay_o => clk_odelay,
pll_locked_o => pll_locked);
pll_locked_o => pll_locked,
idelayctrl_rdy_o => odelay_calib_rdy,
idelayctrl_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_kintex7;
......
......@@ -39,106 +39,122 @@
`define FPG_OCR0_PPS_OFFS_OFFSET 0
`define FPG_OCR0_PPS_OFFS 32'h0000000f
`define FPG_OCR0_FINE_OFFSET 4
`define FPG_OCR0_FINE 32'h00001ff0
`define FPG_OCR0_POL_OFFSET 13
`define FPG_OCR0_POL 32'h00002000
`define FPG_OCR0_MASK_OFFSET 14
`define FPG_OCR0_MASK 32'h003fc000
`define FPG_OCR0_CONT_OFFSET 22
`define FPG_OCR0_CONT 32'h00400000
`define FPG_OCR0_TRIG_SEL_OFFSET 23
`define FPG_OCR0_TRIG_SEL 32'h00800000
`define FPG_OCR0_FINE 32'h000001f0
`define FPG_OCR0_POL_OFFSET 9
`define FPG_OCR0_POL 32'h00000200
`define FPG_OCR0_COARSE_OFFSET 10
`define FPG_OCR0_COARSE 32'h00003c00
`define FPG_OCR0_CONT_OFFSET 14
`define FPG_OCR0_CONT 32'h00004000
`define FPG_OCR0_TRIG_SEL_OFFSET 15
`define FPG_OCR0_TRIG_SEL 32'h00008000
`define FPG_OCR0_LENGTH_OFFSET 16
`define FPG_OCR0_LENGTH 32'hffff0000
`define ADDR_FPG_OCR1 6'h8
`define FPG_OCR1_PPS_OFFS_OFFSET 0
`define FPG_OCR1_PPS_OFFS 32'h0000000f
`define FPG_OCR1_FINE_OFFSET 4
`define FPG_OCR1_FINE 32'h00001ff0
`define FPG_OCR1_POL_OFFSET 13
`define FPG_OCR1_POL 32'h00002000
`define FPG_OCR1_MASK_OFFSET 14
`define FPG_OCR1_MASK 32'h003fc000
`define FPG_OCR1_CONT_OFFSET 22
`define FPG_OCR1_CONT 32'h00400000
`define FPG_OCR1_TRIG_SEL_OFFSET 23
`define FPG_OCR1_TRIG_SEL 32'h00800000
`define FPG_OCR1_FINE 32'h000001f0
`define FPG_OCR1_POL_OFFSET 9
`define FPG_OCR1_POL 32'h00000200
`define FPG_OCR1_COARSE_OFFSET 10
`define FPG_OCR1_COARSE 32'h00003c00
`define FPG_OCR1_CONT_OFFSET 14
`define FPG_OCR1_CONT 32'h00004000
`define FPG_OCR1_TRIG_SEL_OFFSET 15
`define FPG_OCR1_TRIG_SEL 32'h00008000
`define FPG_OCR1_LENGTH_OFFSET 16
`define FPG_OCR1_LENGTH 32'hffff0000
`define ADDR_FPG_OCR2 6'hc
`define FPG_OCR2_PPS_OFFS_OFFSET 0
`define FPG_OCR2_PPS_OFFS 32'h0000000f
`define FPG_OCR2_FINE_OFFSET 4
`define FPG_OCR2_FINE 32'h00001ff0
`define FPG_OCR2_POL_OFFSET 13
`define FPG_OCR2_POL 32'h00002000
`define FPG_OCR2_MASK_OFFSET 14
`define FPG_OCR2_MASK 32'h003fc000
`define FPG_OCR2_CONT_OFFSET 22
`define FPG_OCR2_CONT 32'h00400000
`define FPG_OCR2_TRIG_SEL_OFFSET 23
`define FPG_OCR2_TRIG_SEL 32'h00800000
`define FPG_OCR2_FINE 32'h000001f0
`define FPG_OCR2_POL_OFFSET 9
`define FPG_OCR2_POL 32'h00000200
`define FPG_OCR2_COARSE_OFFSET 10
`define FPG_OCR2_COARSE 32'h00003c00
`define FPG_OCR2_CONT_OFFSET 14
`define FPG_OCR2_CONT 32'h00004000
`define FPG_OCR2_TRIG_SEL_OFFSET 15
`define FPG_OCR2_TRIG_SEL 32'h00008000
`define FPG_OCR2_LENGTH_OFFSET 16
`define FPG_OCR2_LENGTH 32'hffff0000
`define ADDR_FPG_OCR3 6'h10
`define FPG_OCR3_PPS_OFFS_OFFSET 0
`define FPG_OCR3_PPS_OFFS 32'h0000000f
`define FPG_OCR3_FINE_OFFSET 4
`define FPG_OCR3_FINE 32'h00001ff0
`define FPG_OCR3_POL_OFFSET 13
`define FPG_OCR3_POL 32'h00002000
`define FPG_OCR3_MASK_OFFSET 14
`define FPG_OCR3_MASK 32'h003fc000
`define FPG_OCR3_CONT_OFFSET 22
`define FPG_OCR3_CONT 32'h00400000
`define FPG_OCR3_TRIG_SEL_OFFSET 23
`define FPG_OCR3_TRIG_SEL 32'h00800000
`define FPG_OCR3_FINE 32'h000001f0
`define FPG_OCR3_POL_OFFSET 9
`define FPG_OCR3_POL 32'h00000200
`define FPG_OCR3_COARSE_OFFSET 10
`define FPG_OCR3_COARSE 32'h00003c00
`define FPG_OCR3_CONT_OFFSET 14
`define FPG_OCR3_CONT 32'h00004000
`define FPG_OCR3_TRIG_SEL_OFFSET 15
`define FPG_OCR3_TRIG_SEL 32'h00008000
`define FPG_OCR3_LENGTH_OFFSET 16
`define FPG_OCR3_LENGTH 32'hffff0000
`define ADDR_FPG_OCR4 6'h14
`define FPG_OCR4_PPS_OFFS_OFFSET 0
`define FPG_OCR4_PPS_OFFS 32'h0000000f
`define FPG_OCR4_FINE_OFFSET 4
`define FPG_OCR4_FINE 32'h00001ff0
`define FPG_OCR4_POL_OFFSET 13
`define FPG_OCR4_POL 32'h00002000
`define FPG_OCR4_MASK_OFFSET 14
`define FPG_OCR4_MASK 32'h003fc000
`define FPG_OCR4_CONT_OFFSET 22
`define FPG_OCR4_CONT 32'h00400000
`define FPG_OCR4_TRIG_SEL_OFFSET 23
`define FPG_OCR4_TRIG_SEL 32'h00800000
`define FPG_OCR4_FINE 32'h000001f0
`define FPG_OCR4_POL_OFFSET 9
`define FPG_OCR4_POL 32'h00000200
`define FPG_OCR4_COARSE_OFFSET 10
`define FPG_OCR4_COARSE 32'h00003c00
`define FPG_OCR4_CONT_OFFSET 14
`define FPG_OCR4_CONT 32'h00004000
`define FPG_OCR4_TRIG_SEL_OFFSET 15
`define FPG_OCR4_TRIG_SEL 32'h00008000
`define FPG_OCR4_LENGTH_OFFSET 16
`define FPG_OCR4_LENGTH 32'hffff0000
`define ADDR_FPG_OCR5 6'h18
`define FPG_OCR5_PPS_OFFS_OFFSET 0
`define FPG_OCR5_PPS_OFFS 32'h0000000f
`define FPG_OCR5_FINE_OFFSET 4
`define FPG_OCR5_FINE 32'h00001ff0
`define FPG_OCR5_POL_OFFSET 13
`define FPG_OCR5_POL 32'h00002000
`define FPG_OCR5_MASK_OFFSET 14
`define FPG_OCR5_MASK 32'h003fc000
`define FPG_OCR5_CONT_OFFSET 22
`define FPG_OCR5_CONT 32'h00400000
`define FPG_OCR5_TRIG_SEL_OFFSET 23
`define FPG_OCR5_TRIG_SEL 32'h00800000
`define FPG_OCR5_FINE 32'h000001f0
`define FPG_OCR5_POL_OFFSET 9
`define FPG_OCR5_POL 32'h00000200
`define FPG_OCR5_COARSE_OFFSET 10
`define FPG_OCR5_COARSE 32'h00003c00
`define FPG_OCR5_CONT_OFFSET 14
`define FPG_OCR5_CONT 32'h00004000
`define FPG_OCR5_TRIG_SEL_OFFSET 15
`define FPG_OCR5_TRIG_SEL 32'h00008000
`define FPG_OCR5_LENGTH_OFFSET 16
`define FPG_OCR5_LENGTH 32'hffff0000
`define ADDR_FPG_OCR6 6'h1c
`define FPG_OCR6_PPS_OFFS_OFFSET 0
`define FPG_OCR6_PPS_OFFS 32'h0000000f
`define FPG_OCR6_FINE_OFFSET 4
`define FPG_OCR6_FINE 32'h00001ff0
`define FPG_OCR6_POL_OFFSET 13
`define FPG_OCR6_POL 32'h00002000
`define FPG_OCR6_MASK_OFFSET 14
`define FPG_OCR6_MASK 32'h003fc000
`define FPG_OCR6_CONT_OFFSET 22
`define FPG_OCR6_CONT 32'h00400000
`define FPG_OCR6_TRIG_SEL_OFFSET 23
`define FPG_OCR6_TRIG_SEL 32'h00800000
`define FPG_OCR6_FINE 32'h000001f0
`define FPG_OCR6_POL_OFFSET 9
`define FPG_OCR6_POL 32'h00000200
`define FPG_OCR6_COARSE_OFFSET 10
`define FPG_OCR6_COARSE 32'h00003c00
`define FPG_OCR6_CONT_OFFSET 14
`define FPG_OCR6_CONT 32'h00004000
`define FPG_OCR6_TRIG_SEL_OFFSET 15
`define FPG_OCR6_TRIG_SEL 32'h00008000
`define FPG_OCR6_LENGTH_OFFSET 16
`define FPG_OCR6_LENGTH 32'hffff0000
`define ADDR_FPG_OCR7 6'h20
`define FPG_OCR7_PPS_OFFS_OFFSET 0
`define FPG_OCR7_PPS_OFFS 32'h0000000f
`define FPG_OCR7_FINE_OFFSET 4
`define FPG_OCR7_FINE 32'h00001ff0
`define FPG_OCR7_POL_OFFSET 13
`define FPG_OCR7_POL 32'h00002000
`define FPG_OCR7_MASK_OFFSET 14
`define FPG_OCR7_MASK 32'h003fc000
`define FPG_OCR7_CONT_OFFSET 22
`define FPG_OCR7_CONT 32'h00400000
`define FPG_OCR7_TRIG_SEL_OFFSET 23
`define FPG_OCR7_TRIG_SEL 32'h00800000
`define FPG_OCR7_FINE 32'h000001f0
`define FPG_OCR7_POL_OFFSET 9
`define FPG_OCR7_POL 32'h00000200
`define FPG_OCR7_COARSE_OFFSET 10
`define FPG_OCR7_COARSE 32'h00003c00
`define FPG_OCR7_CONT_OFFSET 14
`define FPG_OCR7_CONT 32'h00004000
`define FPG_OCR7_TRIG_SEL_OFFSET 15
`define FPG_OCR7_TRIG_SEL 32'h00008000
`define FPG_OCR7_LENGTH_OFFSET 16
`define FPG_OCR7_LENGTH 32'hffff0000
`define ADDR_FPG_ODELAY_CALIB 6'h24
`define FPG_ODELAY_CALIB_RST_IDELAYCTRL_OFFSET 0
`define FPG_ODELAY_CALIB_RST_IDELAYCTRL 32'h00000001
......
......@@ -62,7 +62,7 @@ class FinePulseGenDriver extends IBusDevice;
super.new(acc,base);
endfunction // new
task automatic calibrate();
task automatic calibrate_k7u();
int rv;
real calib_time;
int calib_taps;
......@@ -97,30 +97,60 @@ 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, %.1f ns = %d taps\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);
endtask // calibrate
task automatic calibrate_k7();
int rv;
real calib_time;
int calib_taps;
$error("Calibrate start");
write32( `ADDR_FPG_ODELAY_CALIB, `FPG_ODELAY_CALIB_RST_IDELAYCTRL );
write32( `ADDR_FPG_ODELAY_CALIB, 0 );
write32( `ADDR_FPG_ODELAY_CALIB, `FPG_ODELAY_CALIB_RST_OSERDES );
write32( `ADDR_FPG_ODELAY_CALIB, 0 );
#100ns;
while(1)
begin
read32( `ADDR_FPG_ODELAY_CALIB, rv );
$display("odelay = %x", rv);
if ( rv & `FPG_ODELAY_CALIB_RDY )
break;
end
m_delay_tap_size = 0.078 /*ns*/;
endtask // calibrate
task automatic pulse( int out, int polarity, int cont, real delta, int tr_force = 0 );
task automatic pulse( int out, int polarity, int cont, real delta, int length = 0, int tr_force = 0 );
uint64_t rv;
int coarse_par = int'($floor (delta / 16.0));
int coarse_ser = int'($floor (delta / 1.0) - coarse_par * 16);
int fine = int'((delta / 1.0 - $floor(delta / 1.0)) * 1.0 / m_delay_tap_size);
int mask = coarse_ser;
uint32_t ocr;
$display("Tapsize %.5f Fine %d", m_delay_tap_size, fine);
// $display("Tapsize %.5f Fine %d", m_delay_tap_size, fine);
ocr = (coarse_par << `FPG_OCR0_PPS_OFFS_OFFSET)
| (mask << `FPG_OCR0_MASK_OFFSET)
| (coarse_ser << `FPG_OCR0_COARSE_OFFSET)
| (fine << `FPG_OCR0_FINE_OFFSET)
| (cont ? `FPG_OCR0_CONT : 0)
| (polarity ? `FPG_OCR0_POL : 0 );
| (polarity ? `FPG_OCR0_POL : 0 )
| (length << `FPG_OCR0_LENGTH_OFFSET);
m_acc.write( m_base + `ADDR_FPG_OCR0 + 4 * out, ocr );
......@@ -201,7 +231,7 @@ module main;
if( dlys.size() && t_pps_valid )
begin
automatic real t_req = dlys.pop_front();
automatic real t_req = dlys.pop_front();
automatic time dly = t_pulse - t_pps;
t_pps_valid = 0;
......@@ -233,10 +263,10 @@ module main;
// the Device Under Test
xwb_fine_pulse_gen
#(
.g_target_platform("KintexUltrascale"),
.g_target_platform("Kintex7"),
.g_use_external_serdes_clock(0),
.g_num_channels(1),
.g_use_odelay(6'b1)
.g_use_odelay(6'b111111)
)
DUT
(
......@@ -279,7 +309,7 @@ module main;
drv = new( acc, 0 );
drv.calibrate();
drv.calibrate_k7();
......@@ -292,10 +322,10 @@ module main;
for (t = 1.0; t <= 200.9; t+=0.1)
begin
$display("Pulse @ %f", t );
// $display("Pulse @ %f", t );
dlys.push_back(t);
drv.pulse(0, 1, 0, t);
drv.pulse(0, 0, 0, t, 4);
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