Commit 9aa10a21 authored by Tristan Gingold's avatar Tristan Gingold

tb_vtu: add a test for lowfreq, check initial delay.

parent 026b0437
......@@ -69,8 +69,9 @@ architecture arch of tb_vtu is
signal observer_state : obs_state_type := IDLE;
signal observer_count : natural;
signal observer_period : time;
signal observer_delay : time; -- Delay between sync and first pulse,
signal wait_sync : boolean;
signal observer_delay : natural; -- Delay between sync and first pulse,
type obs_sync_state_type is (WAIT_SYNC, WAIT_PULSE, DONE);
signal sync_state : obs_sync_state_type := DONE;
begin
-- System clock, 62.5 Mhz
process
......@@ -111,27 +112,52 @@ begin
);
-- VTU observer.
process (trig_p, clk_rf, observer_cmd)
process (clk_rf, observer_cmd'transaction)
variable sync_ts : time;
begin
if observer_cmd'active then
sync_state <= WAIT_SYNC;
elsif rising_edge(clk_rf) then
case sync_state is
when WAIT_SYNC =>
if sync = '1' then
report "observer: sync";
sync_ts := now;
sync_state <= WAIT_PULSE;
observer_delay <= 0;
end if;
when WAIT_PULSE =>
observer_delay <= observer_delay + 1;
if trig_p = '1' then
sync_state <= DONE;
end if;
when DONE =>
null;
end case;
end if;
end process;
process (trig_p, stop, observer_cmd'transaction)
variable last_ts : time;
variable this_period : time;
variable stopped : boolean;
begin
if observer_cmd'event then
if observer_cmd'active then
-- New command
case observer_state is
when IDLE | OBS_DONE | OBS_ERR =>
report "observer: new command";
observer_state <= WORKING;
observer_count <= 1;
last_ts := now;
wait_sync <= True;
stopped := false;
when WORKING =>
report "VTU observer command overrides the previous one" severity error;
end case;
end if;
if rising_edge(clk_rf) and sync = '1' and wait_sync then
last_ts := now;
wait_sync <= false;
report "VTU observer: got sync";
if rising_edge (stop) then
stopped := True;
end if;
if trig_p'event and (observer_cmd.square or trig_p = '1') then
......@@ -143,12 +169,11 @@ begin
this_period := now - last_ts;
if observer_count = 1 then
-- First pulse.
assert not wait_sync report "VTU observer: trigger before sync";
observer_delay <= this_period;
assert sync_state = WAIT_PULSE report "VTU observer: trigger before sync";
elsif observer_count = 2 then
observer_period <= this_period;
elsif observer_count > 2 then
if this_period /= observer_period then
if not stopped and this_period /= observer_period then
report "VTU observer: irregular period" severity error;
end if;
end if;
......@@ -209,7 +234,6 @@ begin
procedure test_window (bval : natural; hval : natural; wval : natural)
is
variable val : std_logic_vector(15 downto 0);
variable dly_clk : natural;
begin
-- Program the vtu
-- Delay between start and the first pulse.
......@@ -292,11 +316,9 @@ begin
wait on observer_state;
-- Check observer status.
assert observer_state = OBS_DONE severity error;
dly_clk := (observer_delay + 4999 ps) / 5 ns;
assert dly_clk = (8 + bval + 8 + 8)
report "window test: bad delay:" & natural'image(dly_clk)
assert observer_delay = (8 + bval + 8 + 8)
report "window test: bad delay:" & natural'image(observer_delay)
severity error;
report time'image(observer_delay);
assert observer_period = hval * 5 ns;
-- Check VTU status.
read_status(val);
......@@ -304,6 +326,74 @@ begin
assert val (TRIGUNIT_REGS_STATUS_RUNNING_OFFSET) = '0' severity error;
end test_window;
procedure test_lowfreq (bval : natural; htval : natural)
is
variable val : std_logic_vector(15 downto 0);
variable cnt : natural;
variable dly_exp : natural;
begin
report "test lowfreq - setup vtu";
-- Program the vtu
wait until rising_edge(clk_sys);
-- Delay between start and the first pulse.
write64be_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_BVALUEOFFLINE,
std_logic_vector(to_unsigned(bval, 64)));
-- Delay between the pulses.
write64be_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_HTVALUEOFFLINE,
std_logic_vector(to_unsigned(htval, 64)));
-- Number of pulses (unused).
write64be_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_WVALUEOFFLINE, x"0000_0000_0000_0014");
-- Lowfreq generation, enable.
write16_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_CONFIGOFFLINE, x"0041");
-- Set expected results.
observer_cmd <= (count => 10, infinite => true, square => true);
report "test lowfreq - start pulse";
start_pulse;
read_status(val);
assert val (TRIGUNIT_REGS_STATUS_MISSVALID_OFFSET) = '0' severity error;
-- Sync pulse.
sync_pulse;
-- Check ...
read_status(val);
assert val (TRIGUNIT_REGS_STATUS_STARTREADY_OFFSET) = '1' severity error;
assert val (TRIGUNIT_REGS_STATUS_RUNNING_OFFSET) = '1' severity error;
-- Wait until end of generation.
wait on observer_state;
-- Check observer status.
assert observer_state = OBS_DONE severity error;
assert observer_period = htval * 5 ns;
report "lowfreq delay:" & natural'image(observer_delay);
dly_exp := (8 + bval + 8 + 8 + 1);
assert observer_delay = dly_exp
report "lowfreq test: bad delay:" & natural'image(observer_delay) & ", expect:" & natural'image (dly_exp)
severity error;
-- Stop counter. Synchronize to
wait until rising_edge(clk_vtu);
stop <= '1';
wait for 40 ns;
stop <= '0';
-- Wait a little bit (2 full periods)
wait for 2 * 2 * observer_period;
cnt := observer_count;
-- Wait for 2 full periods.
wait for 2 * 2 * observer_period;
-- We should have stopped after 20 periods. There are some extra periods because of synchronizers.
assert observer_count = cnt severity error;
report "test lowfreq: done";
end test_lowfreq;
variable val : std_logic_vector(15 downto 0);
begin
sync <= '0';
......@@ -330,49 +420,9 @@ begin
-------------------------------------------------------------------------------------------------
-- Test 3: Program the vtu
-- Delay between start and the first pulse.
write64be_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_BVALUEOFFLINE, x"0000_0000_0000_0010");
-- Delay between the pulses.
write64be_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_HTVALUEOFFLINE, x"0000_0000_0000_0011");
-- Number of pulses (unused).
write64be_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_WVALUEOFFLINE, x"0000_0000_0000_0014");
-- Lowfreq generation, enable.
write16_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_CONFIGOFFLINE, x"0041");
observer_cmd <= (count => 20, infinite => true, square => true);
test_lowfreq (29, 17);
report "test 3 - start - lowFreq";
start_pulse;
read_status(val);
assert val (TRIGUNIT_REGS_STATUS_MISSVALID_OFFSET) = '0' severity error;
-- Sync pulse.
sync_pulse;
-- Check ...
read_status(val);
assert val (TRIGUNIT_REGS_STATUS_STARTREADY_OFFSET) = '1' severity error;
assert val (TRIGUNIT_REGS_STATUS_RUNNING_OFFSET) = '1' severity error;
-- Wait until end of generation.
wait on observer_state;
-- Check observer status.
assert observer_state = OBS_DONE severity error;
assert observer_period = 17 * 5 ns;
-- Stop counter. Synchronize to
wait until rising_edge(clk_vtu);
stop <= '1';
wait for 40 ns;
stop <= '0';
-- Wait a little bit (2 full periods)
wait for 2 * 2 * observer_period;
-- We should have stopped after 20 periods. There are some extra periods because of synchronizers.
assert observer_count = 23 severity error;
test_lowfreq (12, 20);
report "end of tests";
wait;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment