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 {
};
field {
align = 8;
name = "Number of output channels (max: 8)";
prefix = "N_OUT";
type = SLV;
......@@ -39,6 +38,15 @@ peripheral {
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 {
name = "Debug queue supported";
prefix = "DBG_SUPPORTED";
......@@ -46,6 +54,14 @@ peripheral {
access_bus = READ_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 {
};
};
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 {
align = 8;
name = "Helper DAC Output";
......@@ -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 {
name = "Debug FIFO Register - SPLL side";
prefix = "DFR_SPLL";
......
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : spll_wbgen2_pkg.vhd
-- 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
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE spll_wb_slave.wb
......@@ -23,7 +23,9 @@ package spll_wbgen2_pkg is
type t_spll_in_registers is record
csr_n_ref_i : std_logic_vector(5 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_hover_supported_i : std_logic;
eccr_ext_supported_i : std_logic;
eccr_ext_ref_locked_i : std_logic;
eccr_ext_ref_stopped_i : std_logic;
......@@ -39,6 +41,9 @@ package spll_wbgen2_pkg is
occr_out_en_i : std_logic_vector(7 downto 0);
rcer_i : std_logic_vector(31 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_value_i : std_logic_vector(31 downto 0);
dfr_host_seq_id_i : std_logic_vector(15 downto 0);
......@@ -51,7 +56,9 @@ package spll_wbgen2_pkg is
constant c_spll_in_registers_init_value: t_spll_in_registers := (
csr_n_ref_i => (others => '0'),
csr_n_out_i => (others => '0'),
csr_n_ext_i => (others => '0'),
csr_dbg_supported_i => '0',
csr_hover_supported_i => '0',
eccr_ext_supported_i => '0',
eccr_ext_ref_locked_i => '0',
eccr_ext_ref_stopped_i => '0',
......@@ -67,6 +74,9 @@ package spll_wbgen2_pkg is
occr_out_en_i => (others => '0'),
rcer_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_value_i => (others => '0'),
dfr_host_seq_id_i => (others => '0'),
......@@ -94,6 +104,8 @@ package spll_wbgen2_pkg is
rcer_load_o : std_logic;
ocer_o : std_logic_vector(7 downto 0);
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_wr_o : std_logic;
dac_main_value_o : std_logic_vector(23 downto 0);
......@@ -101,6 +113,8 @@ package spll_wbgen2_pkg is
dac_main_dac_sel_o : std_logic_vector(3 downto 0);
dac_main_dac_sel_wr_o : std_logic;
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_wr_o : std_logic;
dfr_spll_eos_o : std_logic;
......@@ -128,6 +142,8 @@ package spll_wbgen2_pkg is
rcer_load_o => '0',
ocer_o => (others => '0'),
ocer_load_o => '0',
hcer_o => (others => '0'),
hcer_load_o => '0',
dac_hpll_o => (others => '0'),
dac_hpll_wr_o => '0',
dac_main_value_o => (others => '0'),
......@@ -135,6 +151,8 @@ package spll_wbgen2_pkg is
dac_main_dac_sel_o => (others => '0'),
dac_main_dac_sel_wr_o => '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_wr_o => '0',
dfr_spll_eos_o => '0',
......@@ -145,89 +163,94 @@ package spll_wbgen2_pkg is
trr_wr_full_o => '0',
trr_wr_empty_o => '0'
);
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_vector) return std_logic_vector;
component spll_wb_slave is
generic (
g_with_debug_fifo : integer := 1 );
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(5 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_err_o : out std_logic;
wb_rty_o : out std_logic;
wb_stall_o : out std_logic;
wb_int_o : out std_logic;
irq_tag_i : in std_logic;
regs_i : in t_spll_in_registers;
regs_o : out t_spll_out_registers
);
end component;
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_vector) return std_logic_vector;
component spll_wb_slave is
generic (
g_with_debug_fifo : integer := 1 );
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(5 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_err_o : out std_logic;
wb_rty_o : out std_logic;
wb_stall_o : out std_logic;
wb_int_o : out std_logic;
irq_tag_i : in std_logic;
regs_i : in t_spll_in_registers;
regs_o : out t_spll_out_registers
);
end component;
end package;
package body spll_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
if x = '1' then
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';
function f_x_to_zero (x:std_logic) return std_logic is
begin
if x = '1' then
return '1';
else
tmp(i):=x(i);
end if;
end loop;
return tmp;
end function;
function "or" (left, right: t_spll_in_registers) return t_spll_in_registers is
variable tmp: t_spll_in_registers;
begin
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.csr_n_out_i := f_x_to_zero(left.csr_n_out_i) or f_x_to_zero(right.csr_n_out_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.eccr_ext_supported_i := f_x_to_zero(left.eccr_ext_supported_i) or f_x_to_zero(right.eccr_ext_supported_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.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.al_cr_valid_i := f_x_to_zero(left.al_cr_valid_i) or f_x_to_zero(right.al_cr_valid_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.al_cref_i := f_x_to_zero(left.al_cref_i) or f_x_to_zero(right.al_cref_i);
tmp.al_cin_i := f_x_to_zero(left.al_cin_i) or f_x_to_zero(right.al_cin_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.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.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.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.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;
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) = '1') then
tmp(i):= '1';
else
tmp(i):= '0';
end if;
end loop;
return tmp;
end function;
function "or" (left, right: t_spll_in_registers) return t_spll_in_registers is
variable tmp: t_spll_in_registers;
begin
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.csr_n_out_i := f_x_to_zero(left.csr_n_out_i) or f_x_to_zero(right.csr_n_out_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.csr_dbg_supported_i := f_x_to_zero(left.csr_dbg_supported_i) or f_x_to_zero(right.csr_dbg_supported_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.eccr_ext_supported_i := f_x_to_zero(left.eccr_ext_supported_i) or f_x_to_zero(right.eccr_ext_supported_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.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.al_cr_valid_i := f_x_to_zero(left.al_cr_valid_i) or f_x_to_zero(right.al_cr_valid_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.al_cref_i := f_x_to_zero(left.al_cref_i) or f_x_to_zero(right.al_cref_i);
tmp.al_cin_i := f_x_to_zero(left.al_cin_i) or f_x_to_zero(right.al_cin_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.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.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.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;
......@@ -64,6 +64,8 @@ entity wr_softpll_ng is
-- ext channel)
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
-- 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.
......@@ -161,7 +163,13 @@ entity wr_softpll_ng is
debug_o : out std_logic_vector(5 downto 0);
-- 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;
......@@ -178,6 +186,15 @@ architecture rtl of wr_softpll_ng is
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
generic (
......@@ -223,7 +240,7 @@ architecture rtl of wr_softpll_ng is
function f_num_total_channels
return integer is
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;
function f_pick (
......@@ -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 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_in : t_wishbone_slave_in;
......@@ -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);
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_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_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_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_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_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_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;
......@@ -330,8 +351,6 @@ architecture rtl of wr_softpll_ng is
attribute mark_debug of tag_muxed : signal is "true";
attribute mark_debug of trr_wr_full : signal is "true";
attribute mark_debug of tag_valid : signal is "true";
begin -- rtl
......@@ -381,8 +400,8 @@ begin -- rtl
resync_p_a_i => fb_resync_out(0),
tag_o => tags(i),
tag_stb_p1_o => tags_p(i),
tag_o => tags(c_CH_REF_OFFSET + i),
tag_stb_p1_o => tags_p(c_CH_REF_OFFSET + i),
r_deglitch_threshold_i => deglitch_thr_slv,
r_low_o => r_stat_low_ref(i),
r_high_o => r_stat_high_ref(i),
......@@ -421,8 +440,8 @@ begin -- rtl
resync_p_a_i => resync_p,
resync_p_o => fb_resync_out(i),
tag_o => tags(i+g_num_ref_inputs),
tag_stb_p1_o => tags_p(i+g_num_ref_inputs),
tag_o => tags(c_CH_OUT_OFFSET + i),
tag_stb_p1_o => tags_p(c_CH_OUT_OFFSET + i),
r_deglitch_threshold_i => deglitch_thr_slv,
dbg_dmtdout_o => open,
......@@ -443,7 +462,7 @@ begin -- rtl
-- drive unused debug output
-- 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
generic map (
......@@ -458,12 +477,12 @@ begin -- rtl
clk_dmtd_i => clk_dmtd_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),
tag_o => tags(g_num_ref_inputs + g_num_outputs + I),
tag_stb_p1_o => tags_p(g_num_ref_inputs + g_num_outputs + I),
tag_o => tags(c_CH_EXT_OFFSET + i),
tag_stb_p1_o => tags_p(c_CH_EXT_OFFSET + i),
r_deglitch_threshold_i => deglitch_thr_slv);
......@@ -504,6 +523,8 @@ begin -- rtl
regs_out.eccr_ext_ref_locked_i <= clk_ext_mul_locked_i;
regs_out.eccr_ext_ref_stopped_i <= clk_ext_stopped_i;
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;
......@@ -516,6 +537,8 @@ begin -- rtl
regs_out.eccr_ext_ref_locked_i <= '0';
regs_out.eccr_ext_ref_stopped_i <= '0';
clk_ext_rst_o <= '0';
regs_out.csr_n_ext_i <= (others => '0');
-- drive unused debug outputs
-- debug_o(0) <= '0';
-- debug_o(1) <= '0';
......@@ -525,9 +548,44 @@ begin -- rtl
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,
r_stat_low_fb, r_stat_low_ref,
gen_holdover_dmtds : for i in 0 to g_num_holdover_inputs-1 generate
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 )
begin
regs_out.dmtd_stat_cr_valid_i <= '0';
......@@ -549,6 +607,12 @@ begin -- rtl
regs_out.dmtd_stat_val_low_i <= r_stat_low_fb(1);
regs_out.dmtd_stat_cr_valid_i <= r_stat_valid_fb(1);
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 =>
null;
end case;
......@@ -604,19 +668,24 @@ begin -- rtl
wb_out.rty <= '0';
wb_out.stall <= '0';
p_ocer_rcer_regs : process(clk_sys_i)
p_ocer_rcer_hcer_regs : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
ocer_int <= (others => '0');
rcer_int <= (others => '0');
hcer_int <= (others => '0');
else
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;
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;
......@@ -628,6 +697,9 @@ begin -- rtl
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.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)
begin
if rising_edge(clk_sys_i) then
......@@ -639,31 +711,40 @@ begin -- rtl
-- Tags from input channels
for i in 0 to g_num_ref_inputs-1 loop
if(tags_p(i) = '1') then
tags_req(i) <= rcer_int(i);
elsif(tags_grant(i) = '1') then
tags_req(i) <= '0';
if(tags_p(c_CH_REF_OFFSET + i) = '1') then
tags_req(c_CH_REF_OFFSET + i) <= rcer_int(i);
elsif(tags_grant(c_CH_REF_OFFSET + i) = '1') then
tags_req(c_CH_REF_OFFSET + i) <= '0';
end if;
end loop; -- i
-- Tags from output channels
for i in 0 to g_num_outputs-1 loop
if(tags_p(i + g_num_ref_inputs) = '1') then
tags_req(i + g_num_ref_inputs) <= ocer_int(i);
elsif(tags_grant(i + g_num_ref_inputs) = '1') then
tags_req(i + g_num_ref_inputs) <= '0';
if(tags_p(c_CH_OUT_OFFSET + i) = '1') then
tags_req(c_CH_OUT_OFFSET + i) <= ocer_int(i);
elsif(tags_grant(c_CH_OUT_OFFSET + i) = '1') then
tags_req(c_CH_OUT_OFFSET + i) <= '0';
end if;
end loop; -- i
-- Tags from external channels
for i in 0 to g_num_exts-1 loop
if (tags_p(i + g_num_ref_inputs + g_num_outputs) = '1') then
tags_req(i + g_num_ref_inputs + g_num_outputs) <= regs_in.eccr_ext_en_o;
elsif (tags_grant(i + g_num_ref_inputs + g_num_outputs) = '1') then
tags_req(i + g_num_ref_inputs + g_num_outputs) <= '0';
if (tags_p(c_CH_EXT_OFFSET + i) = '1') then
tags_req(c_CH_EXT_OFFSET + i) <= regs_in.eccr_ext_en_o;
elsif (tags_grant(c_CH_EXT_OFFSET + i) = '1') then
tags_req(c_CH_EXT_OFFSET + i) <= '0';
end if;
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 process;
......@@ -732,8 +813,6 @@ begin -- rtl
deglitch_thr_slv <= regs_in.deglitch_thr_o;
-----------------------------------------------------------------------------
-- Debugging FIFO
-----------------------------------------------------------------------------
......@@ -818,4 +897,27 @@ begin -- rtl
regs_out.csr_dbg_supported_i <= '1' when g_with_debug_fifo else '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;
......@@ -60,6 +60,8 @@ entity xwr_softpll_ng is
-- ext channel)
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
-- 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.
......@@ -138,7 +140,12 @@ entity xwr_softpll_ng is
int_o: out std_logic;
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;
......@@ -156,6 +163,7 @@ begin -- behavioral
g_num_ref_inputs => g_num_ref_inputs,
g_num_outputs => g_num_outputs,
g_num_exts => g_num_exts,
g_num_holdover_inputs => g_num_holdover_inputs,
g_with_debug_fifo => g_with_debug_fifo,
g_reverse_dmtds => g_reverse_dmtds,
g_divide_input_by_2 => g_divide_input_by_2,
......@@ -200,7 +208,11 @@ begin -- behavioral
wb_stall_o => slave_o.stall,
irq_o => int_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.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