diff --git a/libraries/io/ppsh/tb/vhdl/tb_mms_ppsh.vhd b/libraries/io/ppsh/tb/vhdl/tb_mms_ppsh.vhd index 39e21de98a90bb33568d11fbeed94e304dc52444..d308e06249db71b1111e2183d43cbd900c416d37 100644 --- a/libraries/io/ppsh/tb/vhdl/tb_mms_ppsh.vhd +++ b/libraries/io/ppsh/tb/vhdl/tb_mms_ppsh.vhd @@ -32,13 +32,18 @@ END tb_mms_ppsh; ARCHITECTURE tb OF tb_mms_ppsh IS - CONSTANT c_clk_freq : NATURAL := 1000; -- clock frequency in Hz - CONSTANT c_clk_period : TIME := 1000000 us / c_clk_freq; - CONSTANT c_pps_period : NATURAL := c_clk_freq; -- 1 s takes c_clk_freq clk cycles + CONSTANT c_st_clk_freq : NATURAL := 1000; -- clock frequency in Hz + CONSTANT c_st_clk_period : TIME := 1000000 us / c_st_clk_freq; + CONSTANT c_mm_clk_period : TIME := c_st_clk_period * 3; -- somewhat slower mm_clk + CONSTANT c_pps_period : NATURAL := c_st_clk_freq; -- 1 s takes c_clk_freq clk cycles + + CONSTANT c_cnt_w : NATURAL := ceil_log2(c_st_clk_freq); SIGNAL tb_end : STD_LOGIC := '0'; - SIGNAL rst : STD_LOGIC := '1'; - SIGNAL clk : STD_LOGIC := '1'; + SIGNAL mm_rst : STD_LOGIC := '1'; + SIGNAL mm_clk : STD_LOGIC := '1'; + SIGNAL st_rst : STD_LOGIC := '1'; + SIGNAL st_clk : STD_LOGIC := '1'; -- DUT SIGNAL pps_ext : STD_LOGIC; @@ -48,7 +53,7 @@ ARCHITECTURE tb OF tb_mms_ppsh IS SIGNAL reg_miso : t_mem_miso; -- Verify - SIGNAL bsn : NATURAL; + SIGNAL bsn : NATURAL; -- block sequence number counts seconds SIGNAL pps_toggle : STD_LOGIC; SIGNAL pps_stable : STD_LOGIC; SIGNAL capture_cnt : NATURAL; @@ -65,8 +70,10 @@ BEGIN ----------------------------------------------------------------------------- -- Stimuli ----------------------------------------------------------------------------- - rst <= '1', '0' AFTER 7*c_clk_period; - clk <= NOT clk OR tb_end AFTER c_clk_period/2; + st_rst <= '1', '0' AFTER 7*c_st_clk_period; + st_clk <= NOT st_clk OR tb_end AFTER c_st_clk_period/2; + mm_rst <= '1', '0' AFTER 7*c_mm_clk_period; + mm_clk <= NOT mm_clk OR tb_end AFTER c_mm_clk_period/2; p_pps_ext : PROCESS VARIABLE v_pps_period : NATURAL := c_pps_period; @@ -81,10 +88,10 @@ BEGIN ELSIF bsn = 69 THEN v_pps_period := c_pps_period+1; END IF; - proc_common_wait_some_cycles(clk, v_pps_period-1); + proc_common_wait_some_cycles(st_clk, v_pps_period-1); pps_ext <= '1'; bsn <= bsn + 1; - proc_common_wait_some_cycles(clk, 1); + proc_common_wait_some_cycles(st_clk, 1); pps_ext <= '0'; END LOOP; @@ -94,88 +101,89 @@ BEGIN p_mm_stimuli : PROCESS VARIABLE v_word : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); BEGIN - proc_common_wait_until_low(clk, rst); -- Wait until reset has finished - proc_common_wait_some_cycles(clk, 10); -- Wait an additional amount of cycles + proc_common_wait_until_low(st_clk, st_rst); -- Wait until reset has finished + proc_common_wait_until_low(mm_clk, mm_rst); -- Wait until reset has finished + proc_common_wait_some_cycles(mm_clk, 10); -- Wait an additional amount of cycles v_word := '0' & TO_UVEC(c_pps_period, 31); -- capture_edge = '0' = at rising edge -- expected_cnt = c_pps_period = 1000 - proc_mem_mm_bus_wr(1, v_word, clk, reg_mosi); + proc_mem_mm_bus_wr(1, v_word, mm_clk, reg_mosi); -- Simulate reading PPS status every 10 PPS periods - proc_common_wait_some_cycles(clk, 10); + proc_common_wait_some_cycles(st_clk, 10); FOR I IN 0 TO 9 LOOP - proc_common_wait_some_cycles(clk, c_pps_period*10); + proc_common_wait_some_cycles(st_clk, c_pps_period*10); - proc_mem_mm_bus_rd(0, clk, reg_mosi); - proc_common_wait_some_cycles(clk, 1); + proc_mem_mm_bus_rd(0, mm_clk, reg_mosi); + proc_common_wait_some_cycles(mm_clk, 1); pps_toggle <= reg_miso.rddata(31); pps_stable <= reg_miso.rddata(30); - capture_cnt <= TO_UINT(reg_miso.rddata(ceil_log2(c_clk_freq)-1 DOWNTO 0)); + capture_cnt <= TO_UINT(reg_miso.rddata(c_cnt_w-1 DOWNTO 0)); END LOOP; - -- Simulate reading PPS offset counter every 0.1 PPS periods - proc_common_wait_some_cycles(clk, 10); - FOR I IN 0 TO 4 LOOP - proc_common_wait_some_cycles(clk, c_pps_period/10); + -- Simulate reading PPS offset counter every 0.25 PPS periods + proc_common_wait_some_cycles(st_clk, 10); + FOR I IN 0 TO 40 LOOP + proc_common_wait_some_cycles(st_clk, c_pps_period/4); last_offset_cnt <= offset_cnt; - proc_mem_mm_bus_rd(2, clk, reg_mosi); - proc_common_wait_some_cycles(clk, 1); - offset_cnt <= TO_UINT(reg_miso.rddata(ceil_log2(c_clk_freq)-1 DOWNTO 0)); + proc_mem_mm_bus_rd(2, mm_clk, reg_mosi); + proc_common_wait_some_cycles(mm_clk, 1); + offset_cnt <= TO_UINT(reg_miso.rddata(c_cnt_w-1 DOWNTO 0)); END LOOP; - proc_common_wait_some_cycles(clk, 100); + proc_common_wait_some_cycles(st_clk, 100); tb_end <= '1'; WAIT; END PROCESS; p_verify : PROCESS BEGIN - proc_common_wait_until_low(clk, rst); -- Wait until reset has finished - proc_common_wait_some_cycles(clk, 10); -- Wait an additional amount of cycles + proc_common_wait_until_low(st_clk, st_rst); -- Wait until reset has finished + proc_common_wait_some_cycles(st_clk, 10); -- Wait an additional amount of cycles - proc_common_wait_some_cycles(clk, c_pps_period/2); -- Verification offset + proc_common_wait_some_cycles(st_clk, c_pps_period/2); -- Verification offset -- 1 - proc_common_wait_some_cycles(clk, c_pps_period*10); + proc_common_wait_some_cycles(st_clk, c_pps_period*10); ASSERT pps_stable='0' REPORT "1) Wrong pps_stable" SEVERITY ERROR; ASSERT capture_cnt=1000 REPORT "1) Wrong capture_cnt" SEVERITY ERROR; -- 2 - proc_common_wait_some_cycles(clk, c_pps_period*10); + proc_common_wait_some_cycles(st_clk, c_pps_period*10); ASSERT pps_stable='1' REPORT "2) Wrong pps_stable" SEVERITY ERROR; ASSERT capture_cnt=1000 REPORT "2) Wrong capture_cnt" SEVERITY ERROR; -- 3 - proc_common_wait_some_cycles(clk, c_pps_period*10); + proc_common_wait_some_cycles(st_clk, c_pps_period*10); ASSERT pps_stable='0' REPORT "3) Wrong pps_stable" SEVERITY ERROR; ASSERT capture_cnt=999 REPORT "3) Wrong capture_cnt" SEVERITY ERROR; -- 4 - proc_common_wait_some_cycles(clk, c_pps_period*10); + proc_common_wait_some_cycles(st_clk, c_pps_period*10); ASSERT pps_stable='0' REPORT "4) Wrong pps_stable" SEVERITY ERROR; ASSERT capture_cnt=1000 REPORT "4) Wrong capture_cnt" SEVERITY ERROR; -- 5 - proc_common_wait_some_cycles(clk, c_pps_period*10); + proc_common_wait_some_cycles(st_clk, c_pps_period*10); ASSERT pps_stable='1' REPORT "5) Wrong pps_stable" SEVERITY ERROR; ASSERT capture_cnt=1000 REPORT "5) Wrong capture_cnt" SEVERITY ERROR; -- 6 - proc_common_wait_some_cycles(clk, c_pps_period*10); + proc_common_wait_some_cycles(st_clk, c_pps_period*10); ASSERT pps_stable='1' REPORT "6) Wrong pps_stable" SEVERITY ERROR; ASSERT capture_cnt=1000 REPORT "6) Wrong capture_cnt" SEVERITY ERROR; -- 7 - proc_common_wait_some_cycles(clk, c_pps_period*10); + proc_common_wait_some_cycles(st_clk, c_pps_period*10); ASSERT pps_stable='0' REPORT "7) Wrong pps_stable" SEVERITY ERROR; ASSERT capture_cnt=1001 REPORT "7) Wrong capture_cnt" SEVERITY ERROR; -- 8 - proc_common_wait_some_cycles(clk, c_pps_period*10); + proc_common_wait_some_cycles(st_clk, c_pps_period*10); ASSERT pps_stable='0' REPORT "8) Wrong pps_stable" SEVERITY ERROR; ASSERT capture_cnt=1000 REPORT "8) Wrong capture_cnt" SEVERITY ERROR; -- 9 - proc_common_wait_some_cycles(clk, c_pps_period*10); + proc_common_wait_some_cycles(st_clk, c_pps_period*10); ASSERT pps_stable='1' REPORT "9) Wrong pps_stable" SEVERITY ERROR; ASSERT capture_cnt=1000 REPORT "9) Wrong capture_cnt" SEVERITY ERROR; -- 10 - proc_common_wait_some_cycles(clk, c_pps_period/10); + proc_common_wait_some_cycles(st_clk, c_pps_period/10); ASSERT offset_cnt=last_offset_cnt REPORT "10) Wrong offset_cnt" SEVERITY ERROR; -- 11 - proc_common_wait_some_cycles(clk, c_pps_period/10); + proc_common_wait_some_cycles(st_clk, c_pps_period/10); ASSERT offset_cnt=last_offset_cnt REPORT "11) Wrong offset_cnt" SEVERITY ERROR; WAIT; END PROCESS; @@ -187,14 +195,14 @@ BEGIN dut : ENTITY work.mms_ppsh GENERIC MAP ( - g_st_clk_freq => c_clk_freq + g_st_clk_freq => c_st_clk_freq ) PORT MAP ( -- Clocks and reset - mm_rst => rst, - mm_clk => clk, - st_rst => rst, - st_clk => clk, + mm_rst => mm_rst, + mm_clk => mm_clk, + st_rst => st_rst, + st_clk => st_clk, pps_ext => pps_ext, -- Memory-mapped clock domain diff --git a/libraries/io/ppsh/tb/vhdl/tb_ppsh.vhd b/libraries/io/ppsh/tb/vhdl/tb_ppsh.vhd index 4887a8489d1df8bb0245cf12ddb2f6c75c31dbca..2c1e4a9e49f9dc1b8120f4fa3cf1eaa0fddb9cba 100644 --- a/libraries/io/ppsh/tb/vhdl/tb_ppsh.vhd +++ b/libraries/io/ppsh/tb/vhdl/tb_ppsh.vhd @@ -33,6 +33,7 @@ ARCHITECTURE tb OF tb_ppsh IS CONSTANT c_clk_period : TIME := 1000000 us / c_clk_freq; CONSTANT c_pps_default_period : NATURAL := c_clk_freq; -- 1 s takes c_clk_freq clk cycles CONSTANT c_pps_skew : TIME := 7*c_clk_period/10; + CONSTANT c_cnt_w : NATURAL := ceil_log2(c_clk_freq); -- The state name tells what kind of test is being done TYPE t_state_enum IS ( @@ -54,11 +55,15 @@ ARCHITECTURE tb OF tb_ppsh IS SIGNAL pps_ext : STD_LOGIC; SIGNAL pps_sys : STD_LOGIC; SIGNAL pps_toggle : STD_LOGIC; + SIGNAL pps_stable : STD_LOGIC; + SIGNAL pps_stable_ack : STD_LOGIC := '0'; SIGNAL capture_edge : STD_LOGIC; - SIGNAL capture_cnt : STD_LOGIC_VECTOR(ceil_log2(c_clk_freq)-1 DOWNTO 0); - SIGNAL offset_cnt : STD_LOGIC_VECTOR(ceil_log2(c_clk_freq)-1 DOWNTO 0); + SIGNAL capture_cnt : STD_LOGIC_VECTOR(c_cnt_w-1 DOWNTO 0); + SIGNAL offset_cnt : STD_LOGIC_VECTOR(c_cnt_w-1 DOWNTO 0); + SIGNAL expected_cnt : STD_LOGIC_VECTOR(c_cnt_w-1 DOWNTO 0); -- Verify + SIGNAL verify_s : REAL := 0.0; -- provides time line marker for p_verify in Wave Window BEGIN @@ -73,13 +78,44 @@ BEGIN -- Verify that using the falling capture edge indeed does change timing by -- using a c_pps_skew that is > 0.5 c_clk_period and < c_clk_period - capture_edge <= '0', '1' AFTER 5000 ms, '0' AFTER 7000 ms; + p_capture_edge : PROCESS + BEGIN + capture_edge <= '0'; + WAIT FOR 5000 ms; + capture_edge <= '1'; -- will be verified by p_verify + WAIT FOR 2000 ms; + capture_edge <= '0'; + WAIT; + END PROCESS; + + p_verify_pps_stable : PROCESS + BEGIN + pps_stable_ack <= '0'; + WAIT FOR 9000 ms; -- wait until p_capture_edge is done + IF pps_stable /= '0' THEN + REPORT "PPSH : Unexpected pps_stable, should be 0." SEVERITY ERROR; + END IF; + -- ack PPS stable monitor + pps_stable_ack <= '1'; + WAIT FOR 1*c_clk_period; + pps_stable_ack <= '0'; + WAIT FOR 10 ms; + IF pps_stable /= '1' THEN + REPORT "PPSH : Unexpected pps_stable, should be 1." SEVERITY ERROR; + END IF; + WAIT FOR 13000 ms; -- wait until first loop in p_pps_default_period is done + IF pps_stable /= '0' THEN + REPORT "PPSH : Unexpected pps_stable, should have become 0." SEVERITY ERROR; + END IF; + WAIT; + END PROCESS; -- Verify the capture_cnt p_pps_default_period : PROCESS BEGIN tb_state <= s_idle; pps <= '0'; + expected_cnt <= TO_UVEC(c_pps_default_period, c_cnt_w); WAIT UNTIL rst='0'; WAIT FOR 10*c_clk_period; WAIT UNTIL rising_edge(clk); -- get synchronous to clk @@ -130,8 +166,6 @@ BEGIN pps <= '0'; WAIT FOR (c_pps_default_period-I)*c_clk_period; END LOOP; - -- Missing PPS pulses - tb_state <= s_missing_pps; -- End tb_state <= s_end; @@ -158,11 +192,14 @@ BEGIN -- PPS pps_ext => pps_ext, pps_sys => pps_sys, - pps_toggle => pps_toggle, -- MM control - capture_edge => capture_edge, - capture_cnt => capture_cnt, - offset_cnt => offset_cnt + pps_toggle => pps_toggle, + pps_stable => pps_stable, + pps_stable_ack => pps_stable_ack, + capture_edge => capture_edge, + capture_cnt => capture_cnt, + offset_cnt => offset_cnt, + expected_cnt => expected_cnt ); ----------------------------------------------------------------------------- @@ -187,18 +224,21 @@ BEGIN IF UNSIGNED(capture_cnt)/=c_clk_freq+1 THEN REPORT "PPSH : Unexpected capture count value at 6 s." SEVERITY ERROR; END IF; + verify_s <= 6.0; END IF; IF (NOW > 7000 ms) AND (NOW <= 7000 ms + c_clk_period) THEN IF UNSIGNED(capture_cnt)/=c_clk_freq THEN REPORT "PPSH : Unexpected capture count value at 7 s." SEVERITY ERROR; END IF; + verify_s <= 7.0; END IF; IF (NOW > 8000 ms) AND (NOW <= 8000 ms + c_clk_period) THEN IF UNSIGNED(capture_cnt)/=c_clk_freq-1 THEN REPORT "PPSH : Unexpected capture count value at 8 s." SEVERITY ERROR; END IF; + verify_s <= 8.0; END IF; -- Verify external PPS period fluctuations at specific stimuli moments @@ -206,57 +246,65 @@ BEGIN IF UNSIGNED(capture_cnt)/=c_clk_freq THEN REPORT "PPSH : Unexpected capture count value at 10 s." SEVERITY ERROR; END IF; + verify_s <= 10.0; END IF; IF (NOW > 22000 ms) AND (NOW <= 22000 ms + c_clk_period) THEN IF UNSIGNED(capture_cnt)/=c_clk_freq-1 THEN REPORT "PPSH : Unexpected capture count value at 22 s." SEVERITY ERROR; END IF; + verify_s <= 22.0; END IF; IF (NOW > 25000 ms) AND (NOW <= 25000 ms + c_clk_period) THEN IF UNSIGNED(capture_cnt)/=c_clk_freq THEN REPORT "PPSH : Unexpected capture count value at 25 s." SEVERITY ERROR; END IF; + verify_s <= 25.0; END IF; IF (NOW > 28000 ms) AND (NOW <= 28000 ms + c_clk_period) THEN IF UNSIGNED(capture_cnt)/=c_clk_freq+1 THEN REPORT "PPSH : Unexpected capture count value at 28 s." SEVERITY ERROR; END IF; + verify_s <= 28.0; END IF; IF (NOW > 30000 ms) AND (NOW <= 30000 ms + c_clk_period) THEN IF UNSIGNED(capture_cnt)/=c_clk_freq THEN REPORT "PPSH : Unexpected capture count value at 30 s." SEVERITY ERROR; END IF; + verify_s <= 30.0; END IF; IF (NOW > 35000 ms) AND (NOW <= 35000 ms + c_clk_period) THEN IF UNSIGNED(capture_cnt)/=2**capture_cnt'LENGTH-1 THEN REPORT "PPSH : Unexpected capture count value at 35 s." SEVERITY ERROR; END IF; + verify_s <= 35.0; END IF; IF (NOW > 49000 ms) AND (NOW <= 49000 ms + c_clk_period) THEN IF UNSIGNED(capture_cnt)/=2**capture_cnt'LENGTH-1 THEN REPORT "PPSH : Unexpected capture count value at 49 s." SEVERITY ERROR; END IF; + verify_s <= 49.0; END IF; -- check if offset_cnt is counting IF (NOW > 7500 ms) AND (NOW <= 7500 ms + c_clk_period) THEN IF UNSIGNED(offset_cnt)/=475 THEN - REPORT "PPSH : Unexpected offset count value at 5.5 s." SEVERITY ERROR; + REPORT "PPSH : Unexpected offset count value at 7.5 s." SEVERITY ERROR; END IF; + verify_s <= 7.5; END IF; IF (NOW > 7700 ms) AND (NOW <= 7700 ms + c_clk_period) THEN IF UNSIGNED(offset_cnt)/=675 THEN - REPORT "PPSH : Unexpected offset count value at 5.5 s." SEVERITY ERROR; + REPORT "PPSH : Unexpected offset count value at 7.7 s." SEVERITY ERROR; END IF; + verify_s <= 7.7; END IF; - END IF; END PROCESS;