Skip to content
Snippets Groups Projects
Commit 5efbf85b authored by Harvey Leicester's avatar Harvey Leicester
Browse files

spll add channels for holdover clks and add exp board gpio interface

parent 834a9416
Branches wrs-v4-dev
No related merge requests found
This diff is collapsed.
...@@ -30,7 +30,6 @@ peripheral { ...@@ -30,7 +30,6 @@ peripheral {
}; };
field { field {
align = 8;
name = "Number of output channels (max: 8)"; name = "Number of output channels (max: 8)";
prefix = "N_OUT"; prefix = "N_OUT";
type = SLV; type = SLV;
...@@ -39,6 +38,15 @@ peripheral { ...@@ -39,6 +38,15 @@ peripheral {
access_dev = WRITE_ONLY; access_dev = WRITE_ONLY;
}; };
field {
name = "Number of external channels (max: 8)";
prefix = "N_EXT";
type = SLV;
size = 3;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field { field {
name = "Debug queue supported"; name = "Debug queue supported";
prefix = "DBG_SUPPORTED"; prefix = "DBG_SUPPORTED";
...@@ -46,6 +54,14 @@ peripheral { ...@@ -46,6 +54,14 @@ peripheral {
access_bus = READ_ONLY; access_bus = READ_ONLY;
access_dev = WRITE_ONLY; access_dev = WRITE_ONLY;
}; };
field {
name = "Holdover supported";
prefix = "HOVER_SUPPORTED";
type = BIT;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
}; };
--------------------------------------------- ---------------------------------------------
...@@ -299,6 +315,22 @@ peripheral { ...@@ -299,6 +315,22 @@ peripheral {
}; };
}; };
reg {
name = "Holdover Channel Tagging Enable Register";
prefix = "HCER";
field {
name = "Holdover Channel Enable";
description = "write 1: enables tag generation on the holdover channel corresponding to the written bit\
write 0: disables tag generation";
type = SLV;
size = 8;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
load = LOAD_EXT;
};
};
reg { reg {
align = 8; align = 8;
name = "Helper DAC Output"; name = "Helper DAC Output";
...@@ -344,6 +376,47 @@ peripheral { ...@@ -344,6 +376,47 @@ peripheral {
}; };
}; };
reg {
name = "Holdover Control/Status Register";
prefix = "ho_csr";
field {
name = "Expansion Board Time Valid";
prefix = "TIME_VALID";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Holdover Clock Valid (per channel)";
prefix = "HOCLK_VALID";
type = SLV;
size = 8;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field {
name = "Holdover Clock in Use";
prefix = "HOCLK_INUSE";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
align = 8;
name = "Number of holdover channels (max: 8)";
prefix = "N_HOVER";
type = SLV;
size = 3;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg { reg {
name = "Debug FIFO Register - SPLL side"; name = "Debug FIFO Register - SPLL side";
prefix = "DFR_SPLL"; prefix = "DFR_SPLL";
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
-- File : spll_wbgen2_pkg.vhd -- File : spll_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from spll_wb_slave.wb -- Author : auto-generated by wbgen2 from spll_wb_slave.wb
-- Created : Sun Jul 16 23:36:22 2023 -- Created : Wed Feb 19 11:21:45 2025
-- Standard : VHDL'87 -- Standard : VHDL'87
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE spll_wb_slave.wb -- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE spll_wb_slave.wb
...@@ -23,7 +23,9 @@ package spll_wbgen2_pkg is ...@@ -23,7 +23,9 @@ package spll_wbgen2_pkg is
type t_spll_in_registers is record type t_spll_in_registers is record
csr_n_ref_i : std_logic_vector(5 downto 0); csr_n_ref_i : std_logic_vector(5 downto 0);
csr_n_out_i : std_logic_vector(2 downto 0); csr_n_out_i : std_logic_vector(2 downto 0);
csr_n_ext_i : std_logic_vector(2 downto 0);
csr_dbg_supported_i : std_logic; csr_dbg_supported_i : std_logic;
csr_hover_supported_i : std_logic;
eccr_ext_supported_i : std_logic; eccr_ext_supported_i : std_logic;
eccr_ext_ref_locked_i : std_logic; eccr_ext_ref_locked_i : std_logic;
eccr_ext_ref_stopped_i : std_logic; eccr_ext_ref_stopped_i : std_logic;
...@@ -39,6 +41,9 @@ package spll_wbgen2_pkg is ...@@ -39,6 +41,9 @@ package spll_wbgen2_pkg is
occr_out_en_i : std_logic_vector(7 downto 0); occr_out_en_i : std_logic_vector(7 downto 0);
rcer_i : std_logic_vector(31 downto 0); rcer_i : std_logic_vector(31 downto 0);
ocer_i : std_logic_vector(7 downto 0); ocer_i : std_logic_vector(7 downto 0);
hcer_i : std_logic_vector(7 downto 0);
ho_csr_hoclk_valid_i : std_logic_vector(7 downto 0);
ho_csr_n_hover_i : std_logic_vector(2 downto 0);
dfr_host_wr_req_i : std_logic; dfr_host_wr_req_i : std_logic;
dfr_host_value_i : std_logic_vector(31 downto 0); dfr_host_value_i : std_logic_vector(31 downto 0);
dfr_host_seq_id_i : std_logic_vector(15 downto 0); dfr_host_seq_id_i : std_logic_vector(15 downto 0);
...@@ -51,7 +56,9 @@ package spll_wbgen2_pkg is ...@@ -51,7 +56,9 @@ package spll_wbgen2_pkg is
constant c_spll_in_registers_init_value: t_spll_in_registers := ( constant c_spll_in_registers_init_value: t_spll_in_registers := (
csr_n_ref_i => (others => '0'), csr_n_ref_i => (others => '0'),
csr_n_out_i => (others => '0'), csr_n_out_i => (others => '0'),
csr_n_ext_i => (others => '0'),
csr_dbg_supported_i => '0', csr_dbg_supported_i => '0',
csr_hover_supported_i => '0',
eccr_ext_supported_i => '0', eccr_ext_supported_i => '0',
eccr_ext_ref_locked_i => '0', eccr_ext_ref_locked_i => '0',
eccr_ext_ref_stopped_i => '0', eccr_ext_ref_stopped_i => '0',
...@@ -67,6 +74,9 @@ package spll_wbgen2_pkg is ...@@ -67,6 +74,9 @@ package spll_wbgen2_pkg is
occr_out_en_i => (others => '0'), occr_out_en_i => (others => '0'),
rcer_i => (others => '0'), rcer_i => (others => '0'),
ocer_i => (others => '0'), ocer_i => (others => '0'),
hcer_i => (others => '0'),
ho_csr_hoclk_valid_i => (others => '0'),
ho_csr_n_hover_i => (others => '0'),
dfr_host_wr_req_i => '0', dfr_host_wr_req_i => '0',
dfr_host_value_i => (others => '0'), dfr_host_value_i => (others => '0'),
dfr_host_seq_id_i => (others => '0'), dfr_host_seq_id_i => (others => '0'),
...@@ -94,6 +104,8 @@ package spll_wbgen2_pkg is ...@@ -94,6 +104,8 @@ package spll_wbgen2_pkg is
rcer_load_o : std_logic; rcer_load_o : std_logic;
ocer_o : std_logic_vector(7 downto 0); ocer_o : std_logic_vector(7 downto 0);
ocer_load_o : std_logic; ocer_load_o : std_logic;
hcer_o : std_logic_vector(7 downto 0);
hcer_load_o : std_logic;
dac_hpll_o : std_logic_vector(23 downto 0); dac_hpll_o : std_logic_vector(23 downto 0);
dac_hpll_wr_o : std_logic; dac_hpll_wr_o : std_logic;
dac_main_value_o : std_logic_vector(23 downto 0); dac_main_value_o : std_logic_vector(23 downto 0);
...@@ -101,6 +113,8 @@ package spll_wbgen2_pkg is ...@@ -101,6 +113,8 @@ package spll_wbgen2_pkg is
dac_main_dac_sel_o : std_logic_vector(3 downto 0); dac_main_dac_sel_o : std_logic_vector(3 downto 0);
dac_main_dac_sel_wr_o : std_logic; dac_main_dac_sel_wr_o : std_logic;
deglitch_thr_o : std_logic_vector(15 downto 0); deglitch_thr_o : std_logic_vector(15 downto 0);
ho_csr_time_valid_o : std_logic;
ho_csr_hoclk_inuse_o : std_logic;
dfr_spll_value_o : std_logic_vector(30 downto 0); dfr_spll_value_o : std_logic_vector(30 downto 0);
dfr_spll_value_wr_o : std_logic; dfr_spll_value_wr_o : std_logic;
dfr_spll_eos_o : std_logic; dfr_spll_eos_o : std_logic;
...@@ -128,6 +142,8 @@ package spll_wbgen2_pkg is ...@@ -128,6 +142,8 @@ package spll_wbgen2_pkg is
rcer_load_o => '0', rcer_load_o => '0',
ocer_o => (others => '0'), ocer_o => (others => '0'),
ocer_load_o => '0', ocer_load_o => '0',
hcer_o => (others => '0'),
hcer_load_o => '0',
dac_hpll_o => (others => '0'), dac_hpll_o => (others => '0'),
dac_hpll_wr_o => '0', dac_hpll_wr_o => '0',
dac_main_value_o => (others => '0'), dac_main_value_o => (others => '0'),
...@@ -135,6 +151,8 @@ package spll_wbgen2_pkg is ...@@ -135,6 +151,8 @@ package spll_wbgen2_pkg is
dac_main_dac_sel_o => (others => '0'), dac_main_dac_sel_o => (others => '0'),
dac_main_dac_sel_wr_o => '0', dac_main_dac_sel_wr_o => '0',
deglitch_thr_o => (others => '0'), deglitch_thr_o => (others => '0'),
ho_csr_time_valid_o => '0',
ho_csr_hoclk_inuse_o => '0',
dfr_spll_value_o => (others => '0'), dfr_spll_value_o => (others => '0'),
dfr_spll_value_wr_o => '0', dfr_spll_value_wr_o => '0',
dfr_spll_eos_o => '0', dfr_spll_eos_o => '0',
...@@ -145,89 +163,94 @@ package spll_wbgen2_pkg is ...@@ -145,89 +163,94 @@ package spll_wbgen2_pkg is
trr_wr_full_o => '0', trr_wr_full_o => '0',
trr_wr_empty_o => '0' trr_wr_empty_o => '0'
); );
function "or" (left, right: t_spll_in_registers) return t_spll_in_registers; function "or" (left, right: t_spll_in_registers) return t_spll_in_registers;
function f_x_to_zero (x:std_logic) return std_logic; function f_x_to_zero (x:std_logic) return std_logic;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector; function f_x_to_zero (x:std_logic_vector) return std_logic_vector;
component spll_wb_slave is component spll_wb_slave is
generic ( generic (
g_with_debug_fifo : integer := 1 ); g_with_debug_fifo : integer := 1 );
port ( port (
rst_n_i : in std_logic; rst_n_i : in std_logic;
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(5 downto 0); wb_adr_i : in std_logic_vector(5 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0); wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0); wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic; wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0); wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic; wb_stb_i : in std_logic;
wb_we_i : in std_logic; wb_we_i : in std_logic;
wb_ack_o : out std_logic; wb_ack_o : out std_logic;
wb_err_o : out std_logic; wb_err_o : out std_logic;
wb_rty_o : out std_logic; wb_rty_o : out std_logic;
wb_stall_o : out std_logic; wb_stall_o : out std_logic;
wb_int_o : out std_logic; wb_int_o : out std_logic;
irq_tag_i : in std_logic; irq_tag_i : in std_logic;
regs_i : in t_spll_in_registers; regs_i : in t_spll_in_registers;
regs_o : out t_spll_out_registers regs_o : out t_spll_out_registers
); );
end component; end component;
end package; end package;
package body spll_wbgen2_pkg is package body spll_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is function f_x_to_zero (x:std_logic) return std_logic is
begin begin
if x = '1' then if x = '1' then
return '1'; return '1';
else
return '0';
end if;
end function;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
begin
for i in 0 to x'length-1 loop
if(x(i) = 'X' or x(i) = 'U') then
tmp(i):= '0';
else else
tmp(i):=x(i); return '0';
end if; end if;
end loop; end function;
return tmp;
end function; function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
function "or" (left, right: t_spll_in_registers) return t_spll_in_registers is begin
variable tmp: t_spll_in_registers; for i in 0 to x'length-1 loop
begin if(x(i) = '1') then
tmp.csr_n_ref_i := f_x_to_zero(left.csr_n_ref_i) or f_x_to_zero(right.csr_n_ref_i); tmp(i):= '1';
tmp.csr_n_out_i := f_x_to_zero(left.csr_n_out_i) or f_x_to_zero(right.csr_n_out_i); else
tmp.csr_dbg_supported_i := f_x_to_zero(left.csr_dbg_supported_i) or f_x_to_zero(right.csr_dbg_supported_i); tmp(i):= '0';
tmp.eccr_ext_supported_i := f_x_to_zero(left.eccr_ext_supported_i) or f_x_to_zero(right.eccr_ext_supported_i); end if;
tmp.eccr_ext_ref_locked_i := f_x_to_zero(left.eccr_ext_ref_locked_i) or f_x_to_zero(right.eccr_ext_ref_locked_i); end loop;
tmp.eccr_ext_ref_stopped_i := f_x_to_zero(left.eccr_ext_ref_stopped_i) or f_x_to_zero(right.eccr_ext_ref_stopped_i); return tmp;
tmp.al_cr_valid_i := f_x_to_zero(left.al_cr_valid_i) or f_x_to_zero(right.al_cr_valid_i); end function;
tmp.al_cr_required_i := f_x_to_zero(left.al_cr_required_i) or f_x_to_zero(right.al_cr_required_i);
tmp.al_cref_i := f_x_to_zero(left.al_cref_i) or f_x_to_zero(right.al_cref_i); function "or" (left, right: t_spll_in_registers) return t_spll_in_registers is
tmp.al_cin_i := f_x_to_zero(left.al_cin_i) or f_x_to_zero(right.al_cin_i); variable tmp: t_spll_in_registers;
tmp.dmtd_stat_cr_valid_i := f_x_to_zero(left.dmtd_stat_cr_valid_i) or f_x_to_zero(right.dmtd_stat_cr_valid_i); begin
tmp.dmtd_stat_val_high_i := f_x_to_zero(left.dmtd_stat_val_high_i) or f_x_to_zero(right.dmtd_stat_val_high_i); tmp.csr_n_ref_i := f_x_to_zero(left.csr_n_ref_i) or f_x_to_zero(right.csr_n_ref_i);
tmp.dmtd_stat_val_low_i := f_x_to_zero(left.dmtd_stat_val_low_i) or f_x_to_zero(right.dmtd_stat_val_low_i); tmp.csr_n_out_i := f_x_to_zero(left.csr_n_out_i) or f_x_to_zero(right.csr_n_out_i);
tmp.f_ext_freq_i := f_x_to_zero(left.f_ext_freq_i) or f_x_to_zero(right.f_ext_freq_i); tmp.csr_n_ext_i := f_x_to_zero(left.csr_n_ext_i) or f_x_to_zero(right.csr_n_ext_i);
tmp.f_ext_valid_i := f_x_to_zero(left.f_ext_valid_i) or f_x_to_zero(right.f_ext_valid_i); tmp.csr_dbg_supported_i := f_x_to_zero(left.csr_dbg_supported_i) or f_x_to_zero(right.csr_dbg_supported_i);
tmp.occr_out_en_i := f_x_to_zero(left.occr_out_en_i) or f_x_to_zero(right.occr_out_en_i); tmp.csr_hover_supported_i := f_x_to_zero(left.csr_hover_supported_i) or f_x_to_zero(right.csr_hover_supported_i);
tmp.rcer_i := f_x_to_zero(left.rcer_i) or f_x_to_zero(right.rcer_i); tmp.eccr_ext_supported_i := f_x_to_zero(left.eccr_ext_supported_i) or f_x_to_zero(right.eccr_ext_supported_i);
tmp.ocer_i := f_x_to_zero(left.ocer_i) or f_x_to_zero(right.ocer_i); tmp.eccr_ext_ref_locked_i := f_x_to_zero(left.eccr_ext_ref_locked_i) or f_x_to_zero(right.eccr_ext_ref_locked_i);
tmp.dfr_host_wr_req_i := f_x_to_zero(left.dfr_host_wr_req_i) or f_x_to_zero(right.dfr_host_wr_req_i); tmp.eccr_ext_ref_stopped_i := f_x_to_zero(left.eccr_ext_ref_stopped_i) or f_x_to_zero(right.eccr_ext_ref_stopped_i);
tmp.dfr_host_value_i := f_x_to_zero(left.dfr_host_value_i) or f_x_to_zero(right.dfr_host_value_i); tmp.al_cr_valid_i := f_x_to_zero(left.al_cr_valid_i) or f_x_to_zero(right.al_cr_valid_i);
tmp.dfr_host_seq_id_i := f_x_to_zero(left.dfr_host_seq_id_i) or f_x_to_zero(right.dfr_host_seq_id_i); tmp.al_cr_required_i := f_x_to_zero(left.al_cr_required_i) or f_x_to_zero(right.al_cr_required_i);
tmp.trr_wr_req_i := f_x_to_zero(left.trr_wr_req_i) or f_x_to_zero(right.trr_wr_req_i); tmp.al_cref_i := f_x_to_zero(left.al_cref_i) or f_x_to_zero(right.al_cref_i);
tmp.trr_value_i := f_x_to_zero(left.trr_value_i) or f_x_to_zero(right.trr_value_i); tmp.al_cin_i := f_x_to_zero(left.al_cin_i) or f_x_to_zero(right.al_cin_i);
tmp.trr_chan_id_i := f_x_to_zero(left.trr_chan_id_i) or f_x_to_zero(right.trr_chan_id_i); tmp.dmtd_stat_cr_valid_i := f_x_to_zero(left.dmtd_stat_cr_valid_i) or f_x_to_zero(right.dmtd_stat_cr_valid_i);
tmp.trr_disc_i := f_x_to_zero(left.trr_disc_i) or f_x_to_zero(right.trr_disc_i); tmp.dmtd_stat_val_high_i := f_x_to_zero(left.dmtd_stat_val_high_i) or f_x_to_zero(right.dmtd_stat_val_high_i);
return tmp; tmp.dmtd_stat_val_low_i := f_x_to_zero(left.dmtd_stat_val_low_i) or f_x_to_zero(right.dmtd_stat_val_low_i);
end function; tmp.f_ext_freq_i := f_x_to_zero(left.f_ext_freq_i) or f_x_to_zero(right.f_ext_freq_i);
tmp.f_ext_valid_i := f_x_to_zero(left.f_ext_valid_i) or f_x_to_zero(right.f_ext_valid_i);
tmp.occr_out_en_i := f_x_to_zero(left.occr_out_en_i) or f_x_to_zero(right.occr_out_en_i);
tmp.rcer_i := f_x_to_zero(left.rcer_i) or f_x_to_zero(right.rcer_i);
tmp.ocer_i := f_x_to_zero(left.ocer_i) or f_x_to_zero(right.ocer_i);
tmp.hcer_i := f_x_to_zero(left.hcer_i) or f_x_to_zero(right.hcer_i);
tmp.ho_csr_hoclk_valid_i := f_x_to_zero(left.ho_csr_hoclk_valid_i) or f_x_to_zero(right.ho_csr_hoclk_valid_i);
tmp.ho_csr_n_hover_i := f_x_to_zero(left.ho_csr_n_hover_i) or f_x_to_zero(right.ho_csr_n_hover_i);
tmp.dfr_host_wr_req_i := f_x_to_zero(left.dfr_host_wr_req_i) or f_x_to_zero(right.dfr_host_wr_req_i);
tmp.dfr_host_value_i := f_x_to_zero(left.dfr_host_value_i) or f_x_to_zero(right.dfr_host_value_i);
tmp.dfr_host_seq_id_i := f_x_to_zero(left.dfr_host_seq_id_i) or f_x_to_zero(right.dfr_host_seq_id_i);
tmp.trr_wr_req_i := f_x_to_zero(left.trr_wr_req_i) or f_x_to_zero(right.trr_wr_req_i);
tmp.trr_value_i := f_x_to_zero(left.trr_value_i) or f_x_to_zero(right.trr_value_i);
tmp.trr_chan_id_i := f_x_to_zero(left.trr_chan_id_i) or f_x_to_zero(right.trr_chan_id_i);
tmp.trr_disc_i := f_x_to_zero(left.trr_disc_i) or f_x_to_zero(right.trr_disc_i);
return tmp;
end function;
end package body; end package body;
...@@ -64,6 +64,8 @@ entity wr_softpll_ng is ...@@ -64,6 +64,8 @@ entity wr_softpll_ng is
-- ext channel) -- ext channel)
g_num_exts : integer := 1; g_num_exts : integer := 1;
-- Number of holdover/backup channels
g_num_holdover_inputs : integer := 0;
-- When true, an additional FIFO is instantiated, providing a realtime record -- When true, an additional FIFO is instantiated, providing a realtime record
-- of user-selectable SoftPLL parameters (e.g. tag values, phase error, DAC drive). -- of user-selectable SoftPLL parameters (e.g. tag values, phase error, DAC drive).
-- These values can be read by "spll_dbg_proxy" daemon for further analysis. -- These values can be read by "spll_dbg_proxy" daemon for further analysis.
...@@ -161,7 +163,13 @@ entity wr_softpll_ng is ...@@ -161,7 +163,13 @@ entity wr_softpll_ng is
debug_o : out std_logic_vector(5 downto 0); debug_o : out std_logic_vector(5 downto 0);
-- Debug FIFO readout interrupt -- Debug FIFO readout interrupt
dbg_fifo_irq_o : out std_logic dbg_fifo_irq_o : out std_logic;
-- Holdover Expansion board interface, enabled when g_num_holdover_inputs > 0
clk_holdover_i : in std_logic_vector(g_num_holdover_inputs-1 downto 0) := (others => '0');
clk_holdover_valid_i : in std_logic_vector(g_num_holdover_inputs-1 downto 0) := (others => '0');
clk_holdover_inuse_o : out std_logic;
expbrd_time_valid_o : out std_logic
); );
end wr_softpll_ng; end wr_softpll_ng;
...@@ -178,6 +186,15 @@ architecture rtl of wr_softpll_ng is ...@@ -178,6 +186,15 @@ architecture rtl of wr_softpll_ng is
constant c_BB_ERROR_BITS : integer := 16; constant c_BB_ERROR_BITS : integer := 16;
--tag vector indexing
--0:ref-1 = rx channels (from phys)
--ref:ref+out-1 = output channels (i.e clocks we can control via spll)
--ref+out:ref+out+ext-1 = external input channels
--ref+out+ext:ref+out_ext+holdover-1 = holdover/backup input channels
constant c_CH_REF_OFFSET : integer := 0;
constant c_CH_OUT_OFFSET : integer := g_num_ref_inputs;
constant c_CH_EXT_OFFSET : integer := g_num_ref_inputs+g_num_outputs;
constant c_CH_HOVER_OFFSET : integer := g_num_ref_inputs+g_num_outputs+g_num_exts;
component spll_wb_slave component spll_wb_slave
generic ( generic (
...@@ -223,7 +240,7 @@ architecture rtl of wr_softpll_ng is ...@@ -223,7 +240,7 @@ architecture rtl of wr_softpll_ng is
function f_num_total_channels function f_num_total_channels
return integer is return integer is
begin begin
return g_num_ref_inputs + g_num_outputs + g_num_exts; return g_num_ref_inputs + g_num_outputs + g_num_exts + g_num_holdover_inputs;
end f_num_total_channels; end f_num_total_channels;
function f_pick ( function f_pick (
...@@ -277,6 +294,7 @@ architecture rtl of wr_softpll_ng is ...@@ -277,6 +294,7 @@ architecture rtl of wr_softpll_ng is
signal rcer_int : std_logic_vector(g_num_ref_inputs-1 downto 0); signal rcer_int : std_logic_vector(g_num_ref_inputs-1 downto 0);
signal ocer_int : std_logic_vector(g_num_outputs-1 downto 0); signal ocer_int : std_logic_vector(g_num_outputs-1 downto 0);
signal hcer_int : std_logic_vector(g_num_holdover_inputs-1 downto 0);
signal wb_out : t_wishbone_slave_out; signal wb_out : t_wishbone_slave_out;
signal wb_in : t_wishbone_slave_in; signal wb_in : t_wishbone_slave_in;
...@@ -317,12 +335,15 @@ architecture rtl of wr_softpll_ng is ...@@ -317,12 +335,15 @@ architecture rtl of wr_softpll_ng is
type t_stat_array is array(integer range <>) of std_logic_vector(15 downto 0); type t_stat_array is array(integer range <>) of std_logic_vector(15 downto 0);
signal r_stat_high_ref : t_stat_array(0 to g_num_ref_inputs-1); signal r_stat_high_ref : t_stat_array(0 to g_num_ref_inputs-1);
signal r_stat_low_ref : t_stat_array(0 to g_num_ref_inputs-1); signal r_stat_low_ref : t_stat_array(0 to g_num_ref_inputs-1);
signal r_stat_valid_ref : std_logic_vector(g_num_ref_inputs-1 downto 0); signal r_stat_valid_ref : std_logic_vector(g_num_ref_inputs-1 downto 0);
signal r_stat_high_fb : t_stat_array(0 to g_num_outputs-1); signal r_stat_high_fb : t_stat_array(0 to g_num_outputs-1);
signal r_stat_low_fb : t_stat_array(0 to g_num_outputs-1); signal r_stat_low_fb : t_stat_array(0 to g_num_outputs-1);
signal r_stat_valid_fb : std_logic_vector(g_num_outputs-1 downto 0); signal r_stat_valid_fb : std_logic_vector(g_num_outputs-1 downto 0);
signal r_stat_high_hover : t_stat_array(0 to g_num_holdover_inputs-1);
signal r_stat_low_hover : t_stat_array(0 to g_num_holdover_inputs-1);
signal r_stat_valid_hover : std_logic_vector(g_num_holdover_inputs-1 downto 0);
signal trr_wr_full : std_logic; signal trr_wr_full : std_logic;
...@@ -330,8 +351,6 @@ architecture rtl of wr_softpll_ng is ...@@ -330,8 +351,6 @@ architecture rtl of wr_softpll_ng is
attribute mark_debug of tag_muxed : signal is "true"; attribute mark_debug of tag_muxed : signal is "true";
attribute mark_debug of trr_wr_full : signal is "true"; attribute mark_debug of trr_wr_full : signal is "true";
attribute mark_debug of tag_valid : signal is "true"; attribute mark_debug of tag_valid : signal is "true";
begin -- rtl begin -- rtl
...@@ -381,8 +400,8 @@ begin -- rtl ...@@ -381,8 +400,8 @@ begin -- rtl
resync_p_a_i => fb_resync_out(0), resync_p_a_i => fb_resync_out(0),
tag_o => tags(i), tag_o => tags(c_CH_REF_OFFSET + i),
tag_stb_p1_o => tags_p(i), tag_stb_p1_o => tags_p(c_CH_REF_OFFSET + i),
r_deglitch_threshold_i => deglitch_thr_slv, r_deglitch_threshold_i => deglitch_thr_slv,
r_low_o => r_stat_low_ref(i), r_low_o => r_stat_low_ref(i),
r_high_o => r_stat_high_ref(i), r_high_o => r_stat_high_ref(i),
...@@ -421,8 +440,8 @@ begin -- rtl ...@@ -421,8 +440,8 @@ begin -- rtl
resync_p_a_i => resync_p, resync_p_a_i => resync_p,
resync_p_o => fb_resync_out(i), resync_p_o => fb_resync_out(i),
tag_o => tags(i+g_num_ref_inputs), tag_o => tags(c_CH_OUT_OFFSET + i),
tag_stb_p1_o => tags_p(i+g_num_ref_inputs), tag_stb_p1_o => tags_p(c_CH_OUT_OFFSET + i),
r_deglitch_threshold_i => deglitch_thr_slv, r_deglitch_threshold_i => deglitch_thr_slv,
dbg_dmtdout_o => open, dbg_dmtdout_o => open,
...@@ -443,7 +462,7 @@ begin -- rtl ...@@ -443,7 +462,7 @@ begin -- rtl
-- drive unused debug output -- drive unused debug output
-- debug_o(4) <= '0'; -- debug_o(4) <= '0';
gen_ext_dmtds: for I in 0 to g_num_exts-1 generate gen_ext_dmtds: for i in 0 to g_num_exts-1 generate
U_DMTD_EXT_internal : entity work.dmtd_with_deglitcher U_DMTD_EXT_internal : entity work.dmtd_with_deglitcher
generic map ( generic map (
...@@ -458,12 +477,12 @@ begin -- rtl ...@@ -458,12 +477,12 @@ begin -- rtl
clk_dmtd_i => clk_dmtd_i, clk_dmtd_i => clk_dmtd_i,
clk_sys_i => clk_sys_i, clk_sys_i => clk_sys_i,
clk_in_i => clk_ext_mul_i(I), clk_in_i => clk_ext_mul_i(i),
resync_p_a_i => fb_resync_out(0), resync_p_a_i => fb_resync_out(0),
tag_o => tags(g_num_ref_inputs + g_num_outputs + I), tag_o => tags(c_CH_EXT_OFFSET + i),
tag_stb_p1_o => tags_p(g_num_ref_inputs + g_num_outputs + I), tag_stb_p1_o => tags_p(c_CH_EXT_OFFSET + i),
r_deglitch_threshold_i => deglitch_thr_slv); r_deglitch_threshold_i => deglitch_thr_slv);
...@@ -504,6 +523,8 @@ begin -- rtl ...@@ -504,6 +523,8 @@ begin -- rtl
regs_out.eccr_ext_ref_locked_i <= clk_ext_mul_locked_i; regs_out.eccr_ext_ref_locked_i <= clk_ext_mul_locked_i;
regs_out.eccr_ext_ref_stopped_i <= clk_ext_stopped_i; regs_out.eccr_ext_ref_stopped_i <= clk_ext_stopped_i;
clk_ext_rst_o <= regs_in.eccr_ext_ref_pllrst_o; clk_ext_rst_o <= regs_in.eccr_ext_ref_pllrst_o;
regs_out.csr_n_ext_i <= std_logic_vector(to_unsigned(g_num_exts, regs_out.csr_n_ext_i'length));
end generate gen_with_ext_clock_input; end generate gen_with_ext_clock_input;
...@@ -516,6 +537,8 @@ begin -- rtl ...@@ -516,6 +537,8 @@ begin -- rtl
regs_out.eccr_ext_ref_locked_i <= '0'; regs_out.eccr_ext_ref_locked_i <= '0';
regs_out.eccr_ext_ref_stopped_i <= '0'; regs_out.eccr_ext_ref_stopped_i <= '0';
clk_ext_rst_o <= '0'; clk_ext_rst_o <= '0';
regs_out.csr_n_ext_i <= (others => '0');
-- drive unused debug outputs -- drive unused debug outputs
-- debug_o(0) <= '0'; -- debug_o(0) <= '0';
-- debug_o(1) <= '0'; -- debug_o(1) <= '0';
...@@ -525,9 +548,44 @@ begin -- rtl ...@@ -525,9 +548,44 @@ begin -- rtl
end generate gen_without_ext_clock_input; end generate gen_without_ext_clock_input;
p_jitter_stat_regs : process(r_stat_valid_fb, r_stat_valid_ref,
r_stat_high_fb, r_stat_high_ref, gen_holdover_dmtds : for i in 0 to g_num_holdover_inputs-1 generate
r_stat_low_fb, r_stat_low_ref,
DMTD_HOVER : entity work.dmtd_with_deglitcher
generic map (
g_counter_bits => g_tag_bits,
g_divide_input_by_2 => g_divide_input_by_2,
g_reverse => g_reverse_dmtds,
g_with_jitter_stats_regs => g_with_jitter_stats_regs,
g_use_sampled_clock => false)
port map (
rst_n_dmtdclk_i => rst_dmtd_n_i,
rst_n_sysclk_i => rst_n_i,
clk_dmtd_i => clk_dmtd_i,
clk_sys_i => clk_sys_i,
clk_in_i => clk_holdover_i(i),
resync_p_a_i => fb_resync_out(0),
tag_o => tags(c_CH_HOVER_OFFSET + i),
tag_stb_p1_o => tags_p(c_CH_HOVER_OFFSET + i),
r_deglitch_threshold_i => deglitch_thr_slv,
r_low_o => r_stat_low_hover(i),
r_high_o => r_stat_high_hover(i),
r_samples_i => regs_in.dmtd_stat_cr_samples_o,
r_minmax_sel_i => regs_in.dmtd_stat_cr_minmax_sel_o,
r_stat_reset_i => regs_in.dmtd_stat_cr_rst_o,
r_stat_ready_o => r_stat_valid_hover(i)
);
end generate gen_holdover_dmtds;
p_jitter_stat_regs : process(r_stat_valid_hover, r_stat_valid_fb, r_stat_valid_ref,
r_stat_high_hover, r_stat_high_fb, r_stat_high_ref,
r_stat_low_hover, r_stat_low_fb, r_stat_low_ref,
regs_in ) regs_in )
begin begin
regs_out.dmtd_stat_cr_valid_i <= '0'; regs_out.dmtd_stat_cr_valid_i <= '0';
...@@ -549,6 +607,12 @@ begin -- rtl ...@@ -549,6 +607,12 @@ begin -- rtl
regs_out.dmtd_stat_val_low_i <= r_stat_low_fb(1); regs_out.dmtd_stat_val_low_i <= r_stat_low_fb(1);
regs_out.dmtd_stat_cr_valid_i <= r_stat_valid_fb(1); regs_out.dmtd_stat_cr_valid_i <= r_stat_valid_fb(1);
end if; end if;
when "0011" =>
if g_num_holdover_inputs > 0 then
regs_out.dmtd_stat_val_high_i <= r_stat_high_hover(0);
regs_out.dmtd_stat_val_low_i <= r_stat_low_hover(0);
regs_out.dmtd_stat_cr_valid_i <= r_stat_valid_hover(0);
end if;
when others => when others =>
null; null;
end case; end case;
...@@ -604,19 +668,24 @@ begin -- rtl ...@@ -604,19 +668,24 @@ begin -- rtl
wb_out.rty <= '0'; wb_out.rty <= '0';
wb_out.stall <= '0'; wb_out.stall <= '0';
p_ocer_rcer_regs : process(clk_sys_i) p_ocer_rcer_hcer_regs : process(clk_sys_i)
begin begin
if rising_edge(clk_sys_i) then if rising_edge(clk_sys_i) then
if rst_n_i = '0' then if rst_n_i = '0' then
ocer_int <= (others => '0'); ocer_int <= (others => '0');
rcer_int <= (others => '0'); rcer_int <= (others => '0');
hcer_int <= (others => '0');
else else
if(regs_in.ocer_load_o = '1') then if(regs_in.ocer_load_o = '1') then
ocer_int <= regs_in.ocer_o(g_num_outputs -1 downto 0); ocer_int <= regs_in.ocer_o(g_num_outputs-1 downto 0);
end if; end if;
if(regs_in.rcer_load_o = '1') then if(regs_in.rcer_load_o = '1') then
rcer_int <= regs_in.rcer_o(g_num_ref_inputs -1 downto 0); rcer_int <= regs_in.rcer_o(g_num_ref_inputs-1 downto 0);
end if;
if(regs_in.hcer_load_o = '1') then
hcer_int <= regs_in.hcer_o(g_num_holdover_inputs-1 downto 0);
end if; end if;
end if; end if;
end if; end if;
...@@ -628,6 +697,9 @@ begin -- rtl ...@@ -628,6 +697,9 @@ begin -- rtl
regs_out.rcer_i(g_num_ref_inputs-1 downto 0) <= rcer_int; regs_out.rcer_i(g_num_ref_inputs-1 downto 0) <= rcer_int;
regs_out.rcer_i(31 downto g_num_ref_inputs) <= (others => '0'); regs_out.rcer_i(31 downto g_num_ref_inputs) <= (others => '0');
regs_out.hcer_i(g_num_holdover_inputs-1 downto 0) <= hcer_int;
regs_out.hcer_i(7 downto g_num_holdover_inputs) <= (others => '0');
p_latch_tags : process(clk_sys_i) p_latch_tags : process(clk_sys_i)
begin begin
if rising_edge(clk_sys_i) then if rising_edge(clk_sys_i) then
...@@ -639,31 +711,40 @@ begin -- rtl ...@@ -639,31 +711,40 @@ begin -- rtl
-- Tags from input channels -- Tags from input channels
for i in 0 to g_num_ref_inputs-1 loop for i in 0 to g_num_ref_inputs-1 loop
if(tags_p(i) = '1') then if(tags_p(c_CH_REF_OFFSET + i) = '1') then
tags_req(i) <= rcer_int(i); tags_req(c_CH_REF_OFFSET + i) <= rcer_int(i);
elsif(tags_grant(i) = '1') then elsif(tags_grant(c_CH_REF_OFFSET + i) = '1') then
tags_req(i) <= '0'; tags_req(c_CH_REF_OFFSET + i) <= '0';
end if; end if;
end loop; -- i end loop; -- i
-- Tags from output channels -- Tags from output channels
for i in 0 to g_num_outputs-1 loop for i in 0 to g_num_outputs-1 loop
if(tags_p(i + g_num_ref_inputs) = '1') then if(tags_p(c_CH_OUT_OFFSET + i) = '1') then
tags_req(i + g_num_ref_inputs) <= ocer_int(i); tags_req(c_CH_OUT_OFFSET + i) <= ocer_int(i);
elsif(tags_grant(i + g_num_ref_inputs) = '1') then elsif(tags_grant(c_CH_OUT_OFFSET + i) = '1') then
tags_req(i + g_num_ref_inputs) <= '0'; tags_req(c_CH_OUT_OFFSET + i) <= '0';
end if; end if;
end loop; -- i end loop; -- i
-- Tags from external channels -- Tags from external channels
for i in 0 to g_num_exts-1 loop for i in 0 to g_num_exts-1 loop
if (tags_p(i + g_num_ref_inputs + g_num_outputs) = '1') then if (tags_p(c_CH_EXT_OFFSET + i) = '1') then
tags_req(i + g_num_ref_inputs + g_num_outputs) <= regs_in.eccr_ext_en_o; tags_req(c_CH_EXT_OFFSET + i) <= regs_in.eccr_ext_en_o;
elsif (tags_grant(i + g_num_ref_inputs + g_num_outputs) = '1') then elsif (tags_grant(c_CH_EXT_OFFSET + i) = '1') then
tags_req(i + g_num_ref_inputs + g_num_outputs) <= '0'; tags_req(c_CH_EXT_OFFSET + i) <= '0';
end if; end if;
end loop; end loop;
-- Tags from holdover channels
for i in 0 to g_num_holdover_inputs-1 loop
if(tags_p(c_CH_HOVER_OFFSET + i) = '1') then
tags_req(c_CH_HOVER_OFFSET + i) <= hcer_int(i);
elsif(tags_grant(c_CH_HOVER_OFFSET + i) = '1') then
tags_req(c_CH_HOVER_OFFSET + i) <= '0';
end if;
end loop; -- i
end if; end if;
end if; end if;
end process; end process;
...@@ -732,8 +813,6 @@ begin -- rtl ...@@ -732,8 +813,6 @@ begin -- rtl
deglitch_thr_slv <= regs_in.deglitch_thr_o; deglitch_thr_slv <= regs_in.deglitch_thr_o;
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Debugging FIFO -- Debugging FIFO
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
...@@ -818,4 +897,27 @@ begin -- rtl ...@@ -818,4 +897,27 @@ begin -- rtl
regs_out.csr_dbg_supported_i <= '1' when g_with_debug_fifo else '0'; regs_out.csr_dbg_supported_i <= '1' when g_with_debug_fifo else '0';
regs_out.trr_disc_i <= '0'; regs_out.trr_disc_i <= '0';
-----------------------------------------------------------------------------
-- HOLDOVER CSR fields
-----------------------------------------------------------------------------
gen_hover: if g_num_holdover_inputs > 0 generate
begin
regs_out.ho_csr_hoclk_valid_i(g_num_holdover_inputs-1 downto 0) <= clk_holdover_valid_i;
clk_holdover_inuse_o <= regs_in.ho_csr_hoclk_inuse_o;
expbrd_time_valid_o <= regs_in.ho_csr_time_valid_o;
regs_out.csr_hover_supported_i <= '1';
regs_out.ho_csr_n_hover_i <= std_logic_vector(to_unsigned(g_num_holdover_inputs, regs_out.ho_csr_n_hover_i'length));
end generate gen_hover;
gen_no_hover: if g_num_holdover_inputs = 0 generate
begin
regs_out.csr_hover_supported_i <= '0';
regs_out.ho_csr_n_hover_i <= (others => '0');
regs_out.ho_csr_hoclk_valid_i <= (others => '0');
clk_holdover_inuse_o <= '0';
expbrd_time_valid_o <= '0';
end generate gen_no_hover;
end rtl; end rtl;
...@@ -60,6 +60,8 @@ entity xwr_softpll_ng is ...@@ -60,6 +60,8 @@ entity xwr_softpll_ng is
-- ext channel) -- ext channel)
g_num_exts : integer := 1; g_num_exts : integer := 1;
-- Number of holdover/backup channels
g_num_holdover_inputs : integer := 0;
-- When true, an additional FIFO is instantiated, providing a realtime record -- When true, an additional FIFO is instantiated, providing a realtime record
-- of user-selectable SoftPLL parameters (e.g. tag values, phase error, DAC drive). -- of user-selectable SoftPLL parameters (e.g. tag values, phase error, DAC drive).
-- These values can be read by "spll_dbg_proxy" daemon for further analysis. -- These values can be read by "spll_dbg_proxy" daemon for further analysis.
...@@ -138,7 +140,12 @@ entity xwr_softpll_ng is ...@@ -138,7 +140,12 @@ entity xwr_softpll_ng is
int_o: out std_logic; int_o: out std_logic;
debug_o : out std_logic_vector(5 downto 0); debug_o : out std_logic_vector(5 downto 0);
dbg_fifo_irq_o : out std_logic dbg_fifo_irq_o : out std_logic;
clk_holdover_i : in std_logic_vector(g_num_holdover_inputs-1 downto 0) := (others => '0');
clk_holdover_valid_i : in std_logic_vector(g_num_holdover_inputs-1 downto 0) := (others => '0');
clk_holdover_inuse_o : out std_logic;
expbrd_time_valid_o : out std_logic
); );
end xwr_softpll_ng; end xwr_softpll_ng;
...@@ -156,6 +163,7 @@ begin -- behavioral ...@@ -156,6 +163,7 @@ begin -- behavioral
g_num_ref_inputs => g_num_ref_inputs, g_num_ref_inputs => g_num_ref_inputs,
g_num_outputs => g_num_outputs, g_num_outputs => g_num_outputs,
g_num_exts => g_num_exts, g_num_exts => g_num_exts,
g_num_holdover_inputs => g_num_holdover_inputs,
g_with_debug_fifo => g_with_debug_fifo, g_with_debug_fifo => g_with_debug_fifo,
g_reverse_dmtds => g_reverse_dmtds, g_reverse_dmtds => g_reverse_dmtds,
g_divide_input_by_2 => g_divide_input_by_2, g_divide_input_by_2 => g_divide_input_by_2,
...@@ -200,7 +208,11 @@ begin -- behavioral ...@@ -200,7 +208,11 @@ begin -- behavioral
wb_stall_o => slave_o.stall, wb_stall_o => slave_o.stall,
irq_o => int_o, irq_o => int_o,
debug_o => debug_o, debug_o => debug_o,
dbg_fifo_irq_o => dbg_fifo_irq_o); dbg_fifo_irq_o => dbg_fifo_irq_o,
clk_holdover_i => clk_holdover_i,
clk_holdover_valid_i => clk_holdover_valid_i,
clk_holdover_inuse_o => clk_holdover_inuse_o,
expbrd_time_valid_o => expbrd_time_valid_o);
slave_o.err <= '0'; slave_o.err <= '0';
slave_o.rty <= '0'; slave_o.rty <= '0';
......
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