Skip to content
Snippets Groups Projects
Commit 08247af4 authored by Reinier van der Walle's avatar Reinier van der Walle
Browse files

Merge branch 'L2SDP-562' into 'master'

MM readback the currently active crosslets info, instead of the initial MM...

Closes L2SDP-562

See merge request desp/hdl!210
parents 6ae57b2a edbdd587
No related branches found
No related tags found
1 merge request!210MM readback the currently active crosslets info, instead of the initial MM...
Pipeline #26094 passed
Showing
with 418 additions and 193 deletions
......@@ -61,7 +61,6 @@ ENTITY sdp_crosslets_subband_select IS
reg_bsn_sync_scheduler_xsub_miso : OUT t_mem_miso := c_mem_miso_rst;
out_crosslets_info : OUT STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0)
);
END sdp_crosslets_subband_select;
......@@ -105,6 +104,7 @@ ARCHITECTURE str OF sdp_crosslets_subband_select IS
SIGNAL crosslets_info_reg : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL crosslets_info_reg_in : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL active_crosslets_info : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL i_out_crosslets_info : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
BEGIN
---------------------------------------------------------------
......@@ -152,9 +152,11 @@ BEGIN
in_reg => crosslets_info_reg_in,
out_reg => crosslets_info_reg
);
p_set_unused_crosslets : PROCESS(crosslets_info_reg)
p_set_unused_crosslets : PROCESS(i_out_crosslets_info)
BEGIN
crosslets_info_reg_in <= crosslets_info_reg; -- Always use crosslets info 6:0 + step(@ index 15)
-- MM readback the currently active crosslets info, instead of the initial MM written crosslets_info_reg
crosslets_info_reg_in <= i_out_crosslets_info; -- Always use crosslets info 6:0 + step(@ index 15)
-- Set crosslets 14:7 to -1
FOR I IN g_N_crosslets TO c_sdp_mm_reg_crosslets_info.nof_dat - 2 LOOP
crosslets_info_reg_in((I+1) * c_sdp_crosslets_index_w - 1 DOWNTO I * c_sdp_crosslets_index_w ) <= TO_SVEC(-1, c_sdp_crosslets_index_w);
......@@ -309,6 +311,7 @@ BEGIN
gen_crosslets_info : FOR I IN 0 TO g_N_crosslets-1 GENERATE
active_crosslets_info((I+1)*c_sdp_crosslets_index_w-1 DOWNTO I*c_sdp_crosslets_index_w) <= TO_UVEC(r.offsets(I), c_sdp_crosslets_index_w);
END GENERATE;
-- pipeline for alignment with sync
u_common_pipeline : ENTITY common_lib.common_pipeline
GENERIC MAP(
......@@ -321,9 +324,11 @@ BEGIN
clk => dp_clk,
in_en => row_sosi.sync,
in_dat => active_crosslets_info,
out_dat => out_crosslets_info
out_dat => i_out_crosslets_info
);
out_crosslets_info <= i_out_crosslets_info;
---------------------------------------------------------------
-- Out sosi pipeline
---------------------------------------------------------------
......
......@@ -55,27 +55,30 @@ ARCHITECTURE tb OF tb_sdp_crosslets_subband_select IS
CONSTANT c_rl : NATURAL := 1;
CONSTANT c_nof_sync : NATURAL := 5;
CONSTANT c_nof_block_per_sync : NATURAL := 4;
CONSTANT c_nof_ch_in : NATURAL := 1024; -- nof input words per block, identical for all input streams.
CONSTANT c_dsp_data_w : NATURAL := c_sdp_W_subband;
CONSTANT c_nof_ch_sel_row : NATURAL := c_sdp_P_pfb;
CONSTANT c_N_crosslets : NATURAL := 2;
CONSTANT c_ch_sel_offsets : t_natural_arr(0 TO c_N_crosslets-1) := (0, 15);
CONSTANT c_nof_ch_sel_col : NATURAL := c_sdp_Q_fft; -- nof of sequential collums to select per row.
CONSTANT c_ch_sel_step : NATURAL := 3; -- offset step size to increase per sync interval
CONSTANT c_crosslet_offsets : t_natural_arr(0 TO c_N_crosslets-1) := (0, 15);
CONSTANT c_crosslet_step : NATURAL := 3; -- offset step size to increase per sync interval
CONSTANT c_nof_ch_in : NATURAL := 1024; -- nof input words per block, identical for all input streams.
CONSTANT c_nof_ch_sel_row : NATURAL := c_sdp_P_pfb;
CONSTANT c_nof_ch_sel_col : NATURAL := c_sdp_Q_fft; -- nof of sequential columns to select per row.
CONSTANT c_nof_ch_sel : NATURAL := c_N_crosslets*c_nof_ch_sel_col*c_nof_ch_sel_row;
CONSTANT c_ctrl_interval_size : NATURAL := c_nof_block_per_sync * c_nof_ch_in;
CONSTANT c_scheduled_bsn : NATURAL := 11;
CONSTANT c_nof_block_dly : NATURAL := c_nof_block_per_sync;
SIGNAL tb_end : STD_LOGIC;
SIGNAL rst : STD_LOGIC;
SIGNAL clk : STD_LOGIC := '1';
SIGNAL mm_clk : STD_LOGIC := '1';
SIGNAL tb_end : STD_LOGIC;
SIGNAL mm_mosi : t_mem_mosi;
SIGNAL mm_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL mm_miso : t_mem_miso;
SIGNAL rd_crosslet_offsets : t_natural_arr(0 TO c_N_crosslets-1) := (0, 15);
SIGNAL rd_crosslet_step : NATURAL;
SIGNAL mm_trigger_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL mm_trigger_miso : t_mem_miso;
......@@ -91,32 +94,74 @@ ARCHITECTURE tb OF tb_sdp_crosslets_subband_select IS
SIGNAL out_sosi : t_dp_sosi;
SIGNAL exp_crosslets_info : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL out_crosslets_info : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL exp_crosslets_info_slv : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL out_crosslets_info_slv : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL exp_crosslets_info_rec : t_sdp_crosslets_info;
SIGNAL out_crosslets_info_rec : t_sdp_crosslets_info;
BEGIN
clk <= (NOT clk) OR tb_end AFTER c_clk_period/2;
mm_clk <= (NOT mm_clk) OR tb_end AFTER c_mm_clk_period/2;
rst <= '1', '0' AFTER c_clk_period*7;
p_select_stimuli : PROCESS
p_mm_stimuli : PROCESS
VARIABLE k : NATURAL;
BEGIN
proc_common_wait_until_low(mm_clk, rst);
proc_common_wait_some_cycles(mm_clk, 50); -- Give dut some time to start
-- BSN Scheduler
-- Set BSN sync scheduler
proc_mem_mm_bus_wr(1, c_ctrl_interval_size, mm_clk, mm_trigger_miso, mm_trigger_mosi);
proc_mem_mm_bus_wr(2, c_scheduled_bsn, mm_clk, mm_trigger_miso, mm_trigger_mosi);
proc_mem_mm_bus_wr(3, 0, mm_clk, mm_trigger_miso, mm_trigger_mosi);
proc_mem_mm_bus_wr(0, 1, mm_clk, mm_trigger_miso, mm_trigger_mosi); --enable
-- Set crosslet info
FOR I IN 0 TO c_N_crosslets-1 LOOP
proc_mem_mm_bus_wr(I, c_crosslet_offsets(I), mm_clk, mm_miso, mm_mosi); --offsets
END LOOP;
proc_mem_mm_bus_wr(15, c_crosslet_step, mm_clk, mm_miso, mm_mosi); --step
proc_common_wait_cross_clock_domain_latency(c_clk_period, c_mm_clk_period);
-- Verify that MM reads the active crosslets_info
-- a) Readback crosslet info after rst release
FOR I IN 0 TO c_N_crosslets-1 LOOP
proc_mem_mm_bus_rd(I, mm_clk, mm_miso, mm_mosi); --offsets
proc_mem_mm_bus_rd_latency(1, mm_clk);
rd_crosslet_offsets(I) <= TO_UINT(mm_miso.rddata(c_word_w-1 DOWNTO 0));
END LOOP;
proc_mem_mm_bus_rd(15, mm_clk, mm_miso, mm_mosi);
proc_mem_mm_bus_rd_latency(1, mm_clk);
rd_crosslet_step <= TO_UINT(mm_miso.rddata(c_word_w-1 DOWNTO 0));
proc_common_wait_some_cycles(mm_clk, 1);
-- Verify that readback crosslet info is active crosslets_info
FOR I IN 0 TO c_N_crosslets-1 LOOP
ASSERT rd_crosslet_offsets(I) = 0 REPORT "Wrong crosslet offset after rst." SEVERITY ERROR;
END LOOP;
ASSERT rd_crosslet_step = 0 REPORT "Wrong crosslet step after rst." SEVERITY ERROR;
-- crosslet info
-- b) Read crosslet_info in every sync interval
WHILE TRUE LOOP
proc_common_wait_until_hi_lo(clk, out_sosi.sync);
proc_common_wait_cross_clock_domain_latency(c_clk_period, c_mm_clk_period);
-- Readback crosslet info
FOR I IN 0 TO c_N_crosslets-1 LOOP
proc_mem_mm_bus_wr(I, c_ch_sel_offsets(I), mm_clk, mm_miso, mm_mosi); --offsets
proc_mem_mm_bus_rd(I, mm_clk, mm_miso, mm_mosi); --offsets
proc_mem_mm_bus_rd_latency(1, mm_clk);
rd_crosslet_offsets(I) <= TO_UINT(mm_miso.rddata(c_word_w-1 DOWNTO 0));
END LOOP;
proc_mem_mm_bus_wr(15, c_ch_sel_step, mm_clk, mm_miso, mm_mosi); --step
proc_mem_mm_bus_rd(15, mm_clk, mm_miso, mm_mosi);
proc_mem_mm_bus_rd_latency(1, mm_clk);
rd_crosslet_step <= TO_UINT(mm_miso.rddata(c_word_w-1 DOWNTO 0));
proc_common_wait_some_cycles(mm_clk, 1);
-- Verify that readback crosslet info is active crosslets_info
FOR I IN 0 TO c_N_crosslets-1 LOOP
ASSERT rd_crosslet_offsets(I) = exp_crosslets_info_rec.offset_arr(I) REPORT "Wrong active crosslet offset in output sync interval." SEVERITY ERROR;
END LOOP;
ASSERT rd_crosslet_step = exp_crosslets_info_rec.step REPORT "Wrong active crosslet step in output sync interval." SEVERITY ERROR;
END LOOP;
WAIT;
END PROCESS;
......@@ -179,16 +224,16 @@ BEGIN
exp_sosi <= c_dp_sosi_rst;
WAIT UNTIL rising_edge(out_sosi.sop);
exp_crosslets_info(c_sdp_crosslets_info_reg_w-1 DOWNTO c_sdp_crosslets_info_reg_w - c_sdp_crosslets_index_w) <= TO_UVEC(c_ch_sel_step, c_sdp_crosslets_index_w);
exp_crosslets_info_slv(c_sdp_crosslets_info_reg_w-1 DOWNTO c_sdp_crosslets_info_reg_w - c_sdp_crosslets_index_w) <= TO_UVEC(c_crosslet_step, c_sdp_crosslets_index_w);
FOR C IN 0 TO c_nof_ch_sel_col-1 LOOP
exp_crosslets_info((C+1)*c_sdp_crosslets_index_w-1 DOWNTO C*c_sdp_crosslets_index_w) <= TO_UVEC(c_ch_sel_offsets(C) + v_sync_ix * c_ch_sel_step, c_sdp_crosslets_index_w);
exp_crosslets_info_slv((C+1)*c_sdp_crosslets_index_w-1 DOWNTO C*c_sdp_crosslets_index_w) <= TO_UVEC(c_crosslet_offsets(C) + v_sync_ix * c_crosslet_step, c_sdp_crosslets_index_w);
END LOOP;
FOR J IN 0 TO c_nof_ch_sel-1 LOOP
v_offset := J / (c_nof_ch_sel_col*c_nof_ch_sel_row);
v_col := J MOD c_nof_ch_sel_col;
v_row := (J/c_nof_ch_sel_col) MOD c_nof_ch_sel_row;
v_k := c_nof_ch_sel_col * v_sync_ix * c_ch_sel_step;
v_k := c_nof_ch_sel_col * v_sync_ix * c_crosslet_step;
exp_sosi <= c_dp_sosi_rst;
exp_sosi.valid <= '1';
......@@ -202,8 +247,8 @@ BEGIN
exp_sosi.eop <= '1';
END IF;
exp_sosi.re <= RESIZE_DP_DSP_DATA(TO_DP_DSP_DATA( (I + c_nof_block_dly) * c_nof_ch_in + v_k + c_nof_ch_sel_col*c_ch_sel_offsets(v_offset) + v_col + v_row*2**5)(c_sdp_W_crosslet-1 DOWNTO 0));
exp_sosi.im <= RESIZE_DP_DSP_DATA(TO_DP_DSP_DATA(1+ (I + c_nof_block_dly) * c_nof_ch_in + v_k + c_nof_ch_sel_col*c_ch_sel_offsets(v_offset) + v_col + v_row*2**5)(c_sdp_W_crosslet-1 DOWNTO 0));
exp_sosi.re <= RESIZE_DP_DSP_DATA(TO_DP_DSP_DATA( (I + c_nof_block_dly) * c_nof_ch_in + v_k + c_nof_ch_sel_col*c_crosslet_offsets(v_offset) + v_col + v_row*2**5)(c_sdp_W_crosslet-1 DOWNTO 0));
exp_sosi.im <= RESIZE_DP_DSP_DATA(TO_DP_DSP_DATA(1+ (I + c_nof_block_dly) * c_nof_ch_in + v_k + c_nof_ch_sel_col*c_crosslet_offsets(v_offset) + v_col + v_row*2**5)(c_sdp_W_crosslet-1 DOWNTO 0));
proc_common_wait_some_cycles(clk, 1);
END LOOP;
......@@ -219,7 +264,7 @@ BEGIN
ASSERT out_sosi.sop = exp_sosi.sop REPORT "Wrong out_sosi.sop" SEVERITY ERROR;
ASSERT out_sosi.eop = exp_sosi.eop REPORT "Wrong out_sosi.eop" SEVERITY ERROR;
ASSERT out_sosi.sync = exp_sosi.sync REPORT "Wrong out_sosi.sync" SEVERITY ERROR;
ASSERT out_crosslets_info = exp_crosslets_info REPORT "Wrong out_crosslets_info" SEVERITY ERROR;
ASSERT out_crosslets_info_slv = exp_crosslets_info_slv REPORT "Wrong out_crosslets_info_slv" SEVERITY ERROR;
IF exp_sosi.valid = '1' THEN
ASSERT out_sosi.re = exp_sosi.re REPORT "Wrong out_sosi.re" SEVERITY ERROR;
ASSERT out_sosi.im = exp_sosi.im REPORT "Wrong out_sosi.im" SEVERITY ERROR;
......@@ -249,7 +294,11 @@ BEGIN
in_sosi_arr => in_sosi_arr,
out_sosi => out_sosi,
out_crosslets_info => out_crosslets_info
out_crosslets_info => out_crosslets_info_slv
);
-- Map crosslets_info slv to record for easier view in Wave window
exp_crosslets_info_rec <= func_sdp_map_crosslets_info(exp_crosslets_info_slv);
out_crosslets_info_rec <= func_sdp_map_crosslets_info(out_crosslets_info_slv);
END tb;
......@@ -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;
......@@ -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);
......@@ -89,6 +90,8 @@ 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,6 +162,7 @@ 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),
......
......@@ -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;
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;
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;
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,
......
......@@ -113,6 +113,7 @@ ENTITY dp_bsn_sync_scheduler IS
GENERIC (
g_bsn_w : NATURAL := c_dp_stream_bsn_w;
g_block_size : NATURAL := 256; -- = number of data valid per BSN block, must be >= 2
g_ctrl_interval_size_min : NATURAL := 1; -- Minimum interval size to use if MM write interval size is set too small.
g_pipeline : NATURAL := 1 -- use '1' on HW, use '0' for easier debugging in Wave window
);
PORT (
......@@ -127,6 +128,7 @@ ENTITY dp_bsn_sync_scheduler IS
mon_current_input_bsn : OUT STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0);
mon_input_bsn_at_sync : OUT STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0);
mon_output_enable : OUT STD_LOGIC;
mon_output_interval_size : OUT NATURAL;
mon_output_sync_bsn : OUT STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0);
-- Streaming
......@@ -158,7 +160,7 @@ ARCHITECTURE rtl OF dp_bsn_sync_scheduler IS
output_sync_bsn : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0);
END RECORD;
CONSTANT c_reg_rst : t_reg := ('0', '0', 0, 0, (OTHERS=>'0'), (OTHERS=>'0'), 0, 0, 0, 0, 0, '1', '0', '0', (OTHERS=>'0'));
CONSTANT c_reg_rst : t_reg := ('0', '0', 0, g_ctrl_interval_size_min, (OTHERS=>'0'), (OTHERS=>'0'), 0, 0, 0, 0, 0, '1', '0', '0', (OTHERS=>'0'));
-- Local registers
SIGNAL r : t_reg;
......@@ -176,6 +178,7 @@ BEGIN
mon_current_input_bsn <= in_sosi.bsn(g_bsn_w-1 DOWNTO 0) WHEN rising_edge(clk) AND in_sosi.sop = '1';
mon_input_bsn_at_sync <= in_sosi.bsn(g_bsn_w-1 DOWNTO 0) WHEN rising_edge(clk) AND in_sosi.sync = '1';
mon_output_enable <= r.output_enable;
mon_output_interval_size <= g_ctrl_interval_size_min WHEN rst='1' ELSE r.interval_size WHEN rising_edge(clk) AND output_start = '1';
mon_output_sync_bsn <= r.output_sync_bsn;
p_clk : PROCESS(rst, clk)
......
......@@ -22,7 +22,8 @@
--
-- wi Bits Access Type Name
-- 0 [0] RW boolean ctrl_enable, '1' is on, '0' is FALSE is off
-- 1 [31:0] RW uint32 ctrl_interval_size
-- 1 [31:0] RW uint32 W: ctrl_interval_size
-- R: mon_output_interval_size
-- 2 [31:0] RW uint64 ctrl_start_bsn[31:0]
-- 3 [31:0] RW ctrl_start_bsn[63:32]
-- 4 [31:0] RO uint64 mon_current_input_bsn[31:0]
......@@ -108,6 +109,7 @@ ARCHITECTURE str OF mmp_dp_bsn_sync_scheduler IS
SIGNAL mon_current_input_bsn : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0);
SIGNAL mon_input_bsn_at_sync : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0);
SIGNAL mon_output_enable : STD_LOGIC;
SIGNAL mon_output_interval_size : NATURAL;
SIGNAL mon_output_sync_bsn : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0);
-- Resize BSN values to 64 bit
......@@ -151,7 +153,7 @@ BEGIN
-- . Read
reg_rd( 0) <= ctrl_enable; -- read back internal ctrl_enable
reg_rd( 2*c_word_w-1 DOWNTO 1*c_word_w) <= TO_UVEC(ctrl_interval_size, c_word_w);
reg_rd( 2*c_word_w-1 DOWNTO 1*c_word_w) <= TO_UVEC(mon_output_interval_size, c_word_w);
reg_rd( 3*c_word_w-1 DOWNTO 2*c_word_w) <= wr_start_bsn_64( c_word_w-1 DOWNTO 0); -- low word
reg_rd( 4*c_word_w-1 DOWNTO 3*c_word_w) <= wr_start_bsn_64( 2*c_word_w-1 DOWNTO c_word_w); -- high word
reg_rd( 5*c_word_w-1 DOWNTO 4*c_word_w) <= rd_current_input_bsn_64( c_word_w-1 DOWNTO 0); -- low word
......@@ -191,6 +193,7 @@ BEGIN
GENERIC MAP (
g_bsn_w => g_bsn_w,
g_block_size => g_block_size,
g_ctrl_interval_size_min => g_ctrl_interval_size_min,
g_pipeline => 1
)
PORT MAP (
......@@ -205,6 +208,7 @@ BEGIN
mon_current_input_bsn => mon_current_input_bsn,
mon_input_bsn_at_sync => mon_input_bsn_at_sync,
mon_output_enable => mon_output_enable,
mon_output_interval_size => mon_output_interval_size,
mon_output_sync_bsn => mon_output_sync_bsn,
-- Streaming
......
......@@ -52,6 +52,7 @@ ARCHITECTURE tb OF tb_mmp_dp_bsn_sync_scheduler IS
CONSTANT c_nof_block_per_input_sync : NATURAL := 17;
CONSTANT c_nof_block_per_output_sync : NATURAL := 5;
CONSTANT c_block_size : NATURAL := 10;
CONSTANT c_ctrl_interval_size_min : NATURAL := 19; -- Minimum interval size to use if MM write interval size is set too small.
CONSTANT c_input_gap_size : NATURAL := 3;
CONSTANT c_sim_nof_blocks : NATURAL := c_nof_block_per_input_sync * c_nof_input_sync;
......@@ -75,6 +76,7 @@ ARCHITECTURE tb OF tb_mmp_dp_bsn_sync_scheduler IS
SIGNAL ctrl_start_bsn_64 : STD_LOGIC_VECTOR(2*c_word_w-1 DOWNTO 0);
SIGNAL mon_output_enable : STD_LOGIC;
SIGNAL mon_output_interval_size : NATURAL;
SIGNAL mon_current_input_bsn_64 : STD_LOGIC_VECTOR(2*c_word_w-1 DOWNTO 0);
SIGNAL mon_input_bsn_at_sync_64 : STD_LOGIC_VECTOR(2*c_word_w-1 DOWNTO 0);
SIGNAL mon_output_sync_bsn_64 : STD_LOGIC_VECTOR(2*c_word_w-1 DOWNTO 0);
......@@ -118,6 +120,13 @@ BEGIN
proc_common_wait_some_cycles(mm_clk, 1);
ASSERT mon_block_size = c_block_size REPORT "Wrong block_size." SEVERITY ERROR;
-- . Read mon_output_interval_size
proc_mem_mm_bus_rd(1, mm_clk, reg_miso, reg_mosi);
proc_mem_mm_bus_rd_latency(1, mm_clk);
mon_output_interval_size <= TO_UINT(reg_miso.rddata(c_word_w-1 DOWNTO 0));
proc_common_wait_some_cycles(mm_clk, 1);
ASSERT mon_output_interval_size = c_ctrl_interval_size_min REPORT "Wrong minimum output interval_size." SEVERITY ERROR;
-- . Read mon_output_enable
proc_mem_mm_bus_rd(8, mm_clk, reg_miso, reg_mosi);
proc_mem_mm_bus_rd_latency(1, mm_clk);
......@@ -214,10 +223,16 @@ BEGIN
proc_mem_mm_bus_rd_latency(1, mm_clk);
mon_output_enable <= reg_miso.rddata(0);
-- . Read mon_output_interval_size
proc_mem_mm_bus_rd(1, mm_clk, reg_miso, reg_mosi);
proc_mem_mm_bus_rd_latency(1, mm_clk);
mon_output_interval_size <= TO_UINT(reg_miso.rddata(c_word_w-1 DOWNTO 0));
-- Verify output is on and running
proc_common_wait_some_cycles(mm_clk, 1);
ASSERT mon_output_enable = '1' REPORT "mon_output_enable is not enabled." SEVERITY ERROR;
ASSERT out_enable = '1' REPORT "output_enable is not enabled." SEVERITY ERROR;
ASSERT mon_output_interval_size = c_ctrl_interval_size REPORT "mon_output_interval_size is not ctrl_interval_size." SEVERITY ERROR;
---------------------------------------------------------------------------
-- Check that monitor BSN are incrementing
......@@ -382,7 +397,8 @@ BEGIN
u_mmp_dp_bsn_sync_scheduler : ENTITY work.mmp_dp_bsn_sync_scheduler
GENERIC MAP (
g_bsn_w => c_bsn_w,
g_block_size => c_block_size
g_block_size => c_block_size,
g_ctrl_interval_size_min => c_ctrl_interval_size_min
)
PORT MAP (
-- Clocks and reset
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment