Skip to content
Snippets Groups Projects
Commit 877c339e authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Readback current active WG ctrl via mon_ctrl. Verified mon_ctrl in tb_diag_wg_wideband.vhd.

parent ba49caa0
No related branches found
No related tags found
1 merge request!210MM readback the currently active crosslets info, instead of the initial MM...
Pipeline #25794 passed
......@@ -21,7 +21,12 @@
-- Purpose: Sine waveform generator
-- Description:
-- . Based on diag_waveproc from LOFAR.
-- . Based on diag_waveproc from LOFAR1.
-- . Monitor the active WG ctrl:
-- - WG ctrl.mode = off takes effect immediately
-- - WG ctrl.ampl takes effect immediately
-- - Changing WG ctrl.phase and ctrl.freq require a restart to take effect,
-- to have synchronous phase relation between different WG.
-- Remarks:
-- . For WG sine periods that integer fit in the WG buffer size the carrier
-- wWave (CW) frequency is exact. For fractional WG frequencies, for which
......@@ -73,6 +78,7 @@ ENTITY diag_wg IS
buf_rdval : IN STD_LOGIC;
ctrl : IN t_diag_wg;
mon_ctrl : OUT t_diag_wg;
out_ovr : OUT STD_LOGIC;
out_dat : OUT STD_LOGIC_VECTOR(g_buf_dat_w-1 DOWNTO 0);
......@@ -117,8 +123,11 @@ ARCHITECTURE rtl OF diag_wg IS
SIGNAL state : state_enum;
SIGNAL nxt_state : state_enum;
SIGNAL prev_state : state_enum;
SIGNAL idle : STD_LOGIC;
SIGNAL i_mon_ctrl : t_diag_wg;
SIGNAL nxt_mon_ctrl : t_diag_wg;
SIGNAL nof_samples : STD_LOGIC_VECTOR(g_buf_addr_w DOWNTO 0); -- only use effective range of nof_samples+1
SIGNAL nxt_nof_samples : STD_LOGIC_VECTOR(g_buf_addr_w DOWNTO 0);
SIGNAL sample_cnt : NATURAL RANGE 0 TO 2**g_buf_addr_w-1;
......@@ -126,7 +135,7 @@ ARCHITECTURE rtl OF diag_wg IS
SIGNAL sample_step : NATURAL RANGE 0 TO g_rate_factor;
SIGNAL nxt_sample_step : NATURAL;
SIGNAL init_repeat_done : STD_LOGIC;
SIGNAL phase : STD_LOGIC_VECTOR(ctrl.freq'LENGTH-1 DOWNTO 0);
SIGNAL nxt_phase : STD_LOGIC_VECTOR(phase'RANGE);
SIGNAL phase_step : STD_LOGIC_VECTOR(phase'RANGE);
......@@ -159,12 +168,15 @@ ARCHITECTURE rtl OF diag_wg IS
BEGIN
mon_ctrl <= i_mon_ctrl;
registers : PROCESS(clk, rst)
BEGIN
IF rst = '1' THEN
-- Internal registers.
nof_samples <= (OTHERS => '0');
state <= s_off;
prev_state <= s_off;
sample_cnt <= 0;
sample_step <= 0;
phase <= (OTHERS => '0');
......@@ -172,6 +184,7 @@ BEGIN
init_phase_cnt <= 0;
init_sync <= '0';
-- Output registers.
i_mon_ctrl <= c_diag_wg_rst;
buf_addr <= (OTHERS => '0');
buf_rden <= '0';
out_ovr <= '0';
......@@ -182,6 +195,7 @@ BEGIN
-- Internal registers.
nof_samples <= nxt_nof_samples;
state <= nxt_state;
prev_state <= state;
sample_cnt <= nxt_sample_cnt;
sample_step <= nxt_sample_step;
phase <= nxt_phase;
......@@ -189,6 +203,7 @@ BEGIN
init_phase_cnt <= nxt_init_phase_cnt;
init_sync <= nxt_init_sync;
-- Output registers.
i_mon_ctrl <= nxt_mon_ctrl;
buf_addr <= nxt_buf_addr;
buf_rden <= nxt_buf_rden;
out_ovr <= nxt_out_ovr;
......@@ -317,9 +332,23 @@ BEGIN
END IF;
END PROCESS;
ctrl_ampl <= '0' & ctrl.ampl;
p_mon_ctrl : PROCESS(i_mon_ctrl, ctrl, prev_state, state)
BEGIN
nxt_mon_ctrl <= i_mon_ctrl;
IF TO_UINT(ctrl.mode) = c_diag_wg_mode_off THEN
-- WG immediately goes into off state
nxt_mon_ctrl <= ctrl;
ELSIF prev_state = s_init AND prev_state /= state THEN
-- WG holds ctrl, when it goes into active state (s_single, s_repeat, or s_calc)
nxt_mon_ctrl <= ctrl;
END IF;
-- These MM ctrl fields always take effect immediately in all WG states
nxt_mon_ctrl.ampl <= ctrl.ampl;
nxt_mon_ctrl.nof_samples <= ctrl.nof_samples;
END PROCESS;
mult : ENTITY common_mult_lib.common_mult
GENERIC MAP (
g_technology => g_technology,
......
......@@ -66,6 +66,7 @@ ENTITY diag_wg_wideband IS
st_restart : IN STD_LOGIC;
st_ctrl : IN t_diag_wg;
st_mon_ctrl : OUT t_diag_wg;
out_ovr : OUT STD_LOGIC_VECTOR(g_wideband_factor -1 DOWNTO 0); -- big endian, so first output sample in MSBit, MSData
out_dat : OUT STD_LOGIC_VECTOR(g_wideband_factor*g_buf_dat_w-1 DOWNTO 0);
......@@ -88,7 +89,9 @@ ARCHITECTURE str OF diag_wg_wideband IS
TYPE t_buf_dat_arr IS ARRAY (NATURAL RANGE <>) OF STD_LOGIC_VECTOR(g_buf_dat_w-1 DOWNTO 0);
TYPE t_buf_adr_arr IS ARRAY (NATURAL RANGE <>) OF STD_LOGIC_VECTOR(g_buf_addr_w-1 DOWNTO 0);
SIGNAL st_mon_ctrl_arr : t_diag_wg_arr(0 TO g_wideband_factor-1);
-- Use same address and data widths for both MM side and ST side memory ports
SIGNAL buf_rdval : STD_LOGIC_VECTOR(0 TO g_wideband_factor-1);
SIGNAL buf_rddata : t_buf_dat_arr(0 TO g_wideband_factor-1);
......@@ -107,6 +110,8 @@ BEGIN
mm_rdval <= buf_rdval(0);
mm_rddata <= buf_rddata(0);
st_mon_ctrl <= st_mon_ctrl_arr(0); -- same for all g_wideband_factor waveform generators
gen_wg : FOR I IN 0 TO g_wideband_factor-1 GENERATE
-- Waveform buffer
u_buf : ENTITY common_lib.common_ram_crw_crw
......@@ -157,7 +162,8 @@ BEGIN
buf_rden => st_rd(I),
ctrl => st_ctrl,
mon_ctrl => st_mon_ctrl_arr(I),
out_ovr => out_ovr( g_wideband_factor-I-1),
out_dat => out_dat((g_wideband_factor-I)*g_buf_dat_w-1 DOWNTO (g_wideband_factor-I-1)*g_buf_dat_w),
out_val => out_val( g_wideband_factor-I-1),
......
......@@ -62,7 +62,8 @@ ENTITY diag_wg_wideband_reg IS
sla_out : OUT t_mem_miso; -- actual ranges defined by c_mm_reg
-- MM registers in st_clk domain
st_wg_ctrl : OUT t_diag_wg -- WG control port
st_wg_ctrl : OUT t_diag_wg; -- WG control write port
st_mon_ctrl : IN t_diag_wg -- WG control read port, for currently active control
);
END diag_wg_wideband_reg;
......@@ -80,6 +81,8 @@ ARCHITECTURE rtl OF diag_wg_wideband_reg IS
SIGNAL mm_wg_ctrl : t_diag_wg;
SIGNAL mm_wg_ctrl_mode_wr : STD_LOGIC;
SIGNAL mm_mon_ctrl : t_diag_wg;
-- Registers in st_clk domain
BEGIN
......@@ -129,14 +132,14 @@ BEGIN
sla_out.rdval <= '1'; -- c_mm_reg.latency = 1
CASE TO_UINT(sla_in.address(c_mm_reg.adr_w-1 DOWNTO 0)) IS
WHEN 0 =>
sla_out.rddata( 7 DOWNTO 0) <= mm_wg_ctrl.mode; -- = 8 = c_diag_wg_mode_w
sla_out.rddata(31 DOWNTO 16) <= mm_wg_ctrl.nof_samples; -- = 16 = c_diag_wg_nof_samples_w
sla_out.rddata( 7 DOWNTO 0) <= mm_mon_ctrl.mode; -- = 8 = c_diag_wg_mode_w
sla_out.rddata(31 DOWNTO 16) <= mm_mon_ctrl.nof_samples; -- = 16 = c_diag_wg_nof_samples_w
WHEN 1 =>
sla_out.rddata(15 DOWNTO 0) <= mm_wg_ctrl.phase; -- = 16 = c_diag_wg_phase_w
sla_out.rddata(15 DOWNTO 0) <= mm_mon_ctrl.phase; -- = 16 = c_diag_wg_phase_w
WHEN 2 =>
sla_out.rddata(30 DOWNTO 0) <= mm_wg_ctrl.freq; -- = 31 = c_diag_wg_freq_w
sla_out.rddata(30 DOWNTO 0) <= mm_mon_ctrl.freq; -- = 31 = c_diag_wg_freq_w
WHEN 3 =>
sla_out.rddata(16 DOWNTO 0) <= mm_wg_ctrl.ampl; -- = 17 = c_diag_wg_ampl_w
sla_out.rddata(16 DOWNTO 0) <= mm_mon_ctrl.ampl; -- = 17 = c_diag_wg_ampl_w
WHEN OTHERS => NULL; -- not used MM addresses
END CASE;
END IF;
......@@ -161,6 +164,7 @@ BEGIN
------------------------------------------------------------------------------
no_cross : IF g_cross_clock_domain = FALSE GENERATE -- so mm_clk = st_clk
-- Write: MM to ST clock domain
p_st_clk : PROCESS(st_rst, st_clk)
BEGIN
IF st_rst='1' THEN
......@@ -171,9 +175,13 @@ BEGIN
END IF;
END IF;
END PROCESS;
END GENERATE; -- no_cross
gen_cross : IF g_cross_clock_domain = TRUE GENERATE
-- Read: ST to MM clock domain
mm_mon_ctrl <= st_mon_ctrl;
END GENERATE;
-- Write: MM to ST clock domain
gen_cross_wr : IF g_cross_clock_domain = TRUE GENERATE
-- Assume diag WG mode gets written last, so when diag WG mode is transfered properly to the st_clk domain, then
-- the other diag WG control fields are stable as well
u_mode : ENTITY common_lib.common_reg_cross_domain
......@@ -188,7 +196,7 @@ BEGIN
out_dat => st_wg_ctrl.mode,
out_new => OPEN -- when '1' then the out_dat was updated with in_dat due to in_new
);
END GENERATE; -- gen_cross
END GENERATE;
-- The other wg_ctrl only take effect in diag_wg after the mode has been set
st_wg_ctrl.nof_samples <= mm_wg_ctrl.nof_samples;
......@@ -196,4 +204,57 @@ BEGIN
st_wg_ctrl.phase <= mm_wg_ctrl.phase;
st_wg_ctrl.ampl <= mm_wg_ctrl.ampl;
-- Read: ST to MM clock domain
gen_cross_rd : IF g_cross_clock_domain = TRUE GENERATE
u_mode : ENTITY common_lib.common_reg_cross_domain
PORT MAP (
in_rst => st_rst,
in_clk => st_clk,
in_dat => st_mon_ctrl.mode,
out_rst => mm_rst,
out_clk => mm_clk,
out_dat => mm_mon_ctrl.mode
);
u_nof_samples : ENTITY common_lib.common_reg_cross_domain
PORT MAP (
in_rst => st_rst,
in_clk => st_clk,
in_dat => st_mon_ctrl.nof_samples,
out_rst => mm_rst,
out_clk => mm_clk,
out_dat => mm_mon_ctrl.nof_samples
);
u_freq : ENTITY common_lib.common_reg_cross_domain
PORT MAP (
in_rst => st_rst,
in_clk => st_clk,
in_dat => st_mon_ctrl.freq,
out_rst => mm_rst,
out_clk => mm_clk,
out_dat => mm_mon_ctrl.freq
);
u_phase : ENTITY common_lib.common_reg_cross_domain
PORT MAP (
in_rst => st_rst,
in_clk => st_clk,
in_dat => st_mon_ctrl.phase,
out_rst => mm_rst,
out_clk => mm_clk,
out_dat => mm_mon_ctrl.phase
);
u_ampl : ENTITY common_lib.common_reg_cross_domain
PORT MAP (
in_rst => st_rst,
in_clk => st_clk,
in_dat => st_mon_ctrl.ampl,
out_rst => mm_rst,
out_clk => mm_clk,
out_dat => mm_mon_ctrl.ampl
);
END GENERATE;
END rtl;
......@@ -80,7 +80,8 @@ END mms_diag_wg_wideband;
ARCHITECTURE str OF mms_diag_wg_wideband IS
SIGNAL st_wg_ctrl : t_diag_wg;
SIGNAL st_wg_ctrl : t_diag_wg; -- write
SIGNAL st_mon_ctrl : t_diag_wg; -- read
BEGIN
......@@ -100,7 +101,8 @@ BEGIN
sla_out => reg_miso,
-- MM registers in st_clk domain
st_wg_ctrl => st_wg_ctrl
st_wg_ctrl => st_wg_ctrl,
st_mon_ctrl => st_mon_ctrl
);
u_wg_wideband : ENTITY work.diag_wg_wideband
......@@ -137,6 +139,7 @@ BEGIN
st_restart => st_restart,
st_ctrl => st_wg_ctrl,
st_mon_ctrl => st_mon_ctrl,
out_ovr => out_ovr,
out_dat => out_dat,
......
......@@ -19,6 +19,14 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
--------------------------------------------------------------------------------
-- Purpose: Tb for WG
-- Description: Verifies all WG modes.
-- Usage:
-- > as 10
-- > run -all
-- . Use select rigth mouse in Wave window on wg_dat and choose radix -->
-- decimal and format --> analogue (automatic)
-- . Observe state in diag_wg(0).
LIBRARY IEEE, common_lib;
USE IEEE.STD_LOGIC_1164.ALL;
......@@ -27,15 +35,6 @@ USE IEEE.MATH_REAL.ALL;
USE common_lib.common_pkg.ALL;
USE work.diag_pkg.ALL;
-- Usage:
-- > do wave_diag_wg_wideband.do
-- > run -all
--
-- . Use select rigth mouse in wave window on wg_dat and choose 'format --> analogue (automatic)'
-- . run 10 us to see CALC mode waveform output at proper automatic scale
-- . run 100 us to see SINGLE and REPEAT mode waveform output at proper automatic scale
ENTITY tb_diag_wg_wideband IS
GENERIC (
-- Wideband parameters
......@@ -82,6 +81,8 @@ ARCHITECTURE tb OF tb_diag_wg_wideband IS
SIGNAL restart : STD_LOGIC;
SIGNAL wg_ctrl : t_diag_wg;
SIGNAL cur_ctrl : t_diag_wg;
SIGNAL mon_ctrl : t_diag_wg;
SIGNAL wg_mode : NATURAL;
SIGNAL wg_freq : NATURAL;
......@@ -156,6 +157,7 @@ BEGIN
-- wg_ampl <= INTEGER(3.0/REAL(c_wg_full_scale) * c_ampl_unit); -- yields amplitude of 3
WAIT UNTIL rising_edge(clk); -- align to rising edge
cur_ctrl <= wg_ctrl;
WAIT FOR c_clk_period*200;
---------------------------------------------------------------------------
......@@ -163,51 +165,97 @@ BEGIN
-- CALC mode
wg_mode <= c_diag_wg_mode_calc;
WAIT FOR c_clk_period*10;
ASSERT mon_ctrl = cur_ctrl REPORT "Wrong mon_ctrl (expected hold OFF)" SEVERITY ERROR;
restart <= '1';
WAIT FOR c_clk_period*1;
restart <= '0';
cur_ctrl <= wg_ctrl;
WAIT FOR c_clk_period*10;
ASSERT mon_ctrl = cur_ctrl REPORT "Wrong mon_ctrl (expected new CALC)" SEVERITY ERROR;
WAIT FOR c_clk_period*3000;
wg_ampl <= INTEGER(0.5 * c_ampl_unit); -- change ampl immediately
WAIT FOR c_clk_period*1;
cur_ctrl <= wg_ctrl;
WAIT FOR c_clk_period*10;
ASSERT mon_ctrl = cur_ctrl REPORT "Wrong mon_ctrl (expected new CALC ampl)" SEVERITY ERROR;
WAIT FOR c_clk_period*3000;
wg_phase <= INTEGER(90.0 * c_phase_unit); -- no change phase without restart
wg_freq <= INTEGER(0.5/512.0 * c_freq_unit); -- no change freq without restart
WAIT FOR c_clk_period*10;
ASSERT mon_ctrl = cur_ctrl REPORT "Wrong mon_ctrl (expected hold CALC phase and freq)" SEVERITY ERROR;
WAIT FOR c_clk_period*3000;
restart <= '1';
WAIT FOR c_clk_period*1;
restart <= '0';
cur_ctrl <= wg_ctrl;
WAIT FOR c_clk_period*10;
ASSERT mon_ctrl = cur_ctrl REPORT "Wrong mon_ctrl (expected new CALC phase and freq)" SEVERITY ERROR;
WAIT FOR c_clk_period*3000;
--WAIT FOR 1 sec;
-- OFF mode
wg_mode <= c_diag_wg_mode_off;
WAIT FOR c_clk_period*1;
cur_ctrl <= wg_ctrl; -- OFF mode takes effect immediately
WAIT FOR c_clk_period*10;
ASSERT mon_ctrl = cur_ctrl REPORT "Wrong mon_ctrl (expected immediately OFF)" SEVERITY ERROR;
restart <= '1';
WAIT FOR c_clk_period*1;
restart <= '0';
WAIT FOR c_clk_period*10;
ASSERT mon_ctrl = cur_ctrl REPORT "Wrong mon_ctrl (expected still OFF)" SEVERITY ERROR;
WAIT FOR c_clk_period*200;
-- SINGLE mode
wg_mode <= c_diag_wg_mode_single;
FOR I IN 0 TO 1 LOOP
WAIT FOR c_clk_period*10;
ASSERT mon_ctrl = cur_ctrl REPORT "Wrong mon_ctrl (expected hold OFF)" SEVERITY ERROR;
FOR I IN 0 TO 3 LOOP
restart <= '1';
WAIT FOR c_clk_period*1;
restart <= '0';
cur_ctrl <= wg_ctrl;
WAIT FOR c_clk_period*10;
ASSERT mon_ctrl = cur_ctrl REPORT "Wrong mon_ctrl (expected new SINGLE)" SEVERITY ERROR;
WAIT FOR c_clk_period*c_buf_nof_dat;
WAIT FOR c_clk_period*300;
END LOOP;
-- REPEAT mode
wg_mode <= c_diag_wg_mode_repeat;
restart <= '1';
WAIT FOR c_clk_period*1;
restart <= '0';
WAIT FOR c_clk_period*c_buf_nof_dat*5;
WAIT FOR c_clk_period*200;
restart <= '1';
WAIT FOR c_clk_period*1;
restart <= '0';
WAIT FOR c_clk_period*c_buf_nof_dat*5;
WAIT FOR c_clk_period*200;
WAIT FOR c_clk_period*10;
ASSERT mon_ctrl = cur_ctrl REPORT "Wrong mon_ctrl (expected hold SINGLE)" SEVERITY ERROR;
FOR I IN 0 TO 1 LOOP
restart <= '1';
WAIT FOR c_clk_period*1;
restart <= '0';
cur_ctrl <= wg_ctrl;
WAIT FOR c_clk_period*10;
ASSERT mon_ctrl = cur_ctrl REPORT "Wrong mon_ctrl (expected new REPEAT)" SEVERITY ERROR;
WAIT FOR c_clk_period*c_buf_nof_dat*5;
WAIT FOR c_clk_period*200;
END LOOP;
-- OFF mode
wg_mode <= c_diag_wg_mode_off;
WAIT FOR c_clk_period*1;
cur_ctrl <= wg_ctrl; -- OFF mode takes effect immediately, no need for restart
WAIT FOR c_clk_period*10;
ASSERT mon_ctrl = cur_ctrl REPORT "Wrong mon_ctrl (expected immediately OFF)" SEVERITY ERROR;
restart <= '1';
WAIT FOR c_clk_period*1;
restart <= '0';
WAIT FOR c_clk_period*10;
ASSERT mon_ctrl = cur_ctrl REPORT "Wrong mon_ctrl (expected still OFF)" SEVERITY ERROR;
WAIT FOR c_clk_period*200;
WAIT FOR c_clk_period*100;
......@@ -245,6 +293,7 @@ BEGIN
st_restart => restart,
st_ctrl => wg_ctrl,
st_mon_ctrl => mon_ctrl,
out_ovr => out_ovr,
out_dat => out_dat,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment