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

Corrected that enable toggle does not cause a pulse. Improved tb coverage by...

Corrected that enable toggle does not cause a pulse. Improved tb coverage by counting expected number of pulses.
parent b97607f7
No related branches found
No related tags found
1 merge request!175Added t_sdp_sim. Add func_sdp_get_stat_*() functions to determine the header...
......@@ -18,13 +18,12 @@
-- --------------------------------------------------------------------------
-- Author:
-- . Pieter Donker
-- . Pieter Donker, Eric Kooistra
-- Purpose:
-- . Delay input pulse by number of given delay cycles
-- . Delay input pulse by delay number of cycles
-- Description:
-- . delay input pulse by delay number of cycles
-- . output pulse is derived from low-high transition of input pulse.
-- . the actual pulse delay will be delay + 1, due to implementation latency of 1 clk cycle
-- . The actual pulse delay will be delay + 1, due to implementation latency
-- of 1 clk cycle
-- --------------------------------------------------------------------------
LIBRARY IEEE, technology_lib;
......@@ -36,41 +35,51 @@ ENTITY common_variable_delay IS
g_max_delay : NATURAL := 200 * 10**6
);
PORT (
rst : IN STD_LOGIC;
clk : IN STD_LOGIC;
rst : IN STD_LOGIC;
clk : IN STD_LOGIC;
delay : IN NATURAL RANGE 0 TO g_max_delay := 0;
enable : IN STD_LOGIC := '0';
in_val : IN STD_LOGIC;
out_val : OUT STD_LOGIC
delay : IN NATURAL RANGE 0 TO g_max_delay := 0;
enable : IN STD_LOGIC := '0';
in_pulse : IN STD_LOGIC;
out_pulse : OUT STD_LOGIC
);
END common_variable_delay;
ARCHITECTURE rtl OF common_variable_delay IS
SIGNAL i_out_val : STD_LOGIC;
SIGNAL nxt_out_val : STD_LOGIC;
SIGNAL delay_cnt : NATURAL;
SIGNAL nxt_delay_cnt : NATURAL;
SIGNAL prev_in_val : STD_LOGIC;
SIGNAL i_out_pulse : STD_LOGIC;
SIGNAL nxt_out_pulse : STD_LOGIC;
SIGNAL cnt_en : STD_LOGIC;
SIGNAL nxt_cnt_en : STD_LOGIC;
SIGNAL delay_cnt : NATURAL;
SIGNAL nxt_delay_cnt : NATURAL;
BEGIN
out_val <= i_out_val;
out_pulse <= i_out_pulse;
p_delay: PROCESS(enable, in_val, prev_in_val, delay, delay_cnt)
p_delay: PROCESS(enable, in_pulse, delay, cnt_en, delay_cnt)
BEGIN
nxt_out_val <= '0';
nxt_delay_cnt <= 0;
nxt_out_pulse <= '0';
nxt_cnt_en <= '0';
nxt_delay_cnt <= 0;
IF enable = '1' THEN
IF in_val = '1' AND prev_in_val = '0' THEN -- detect rising edge of in_val
IF delay = 0 THEN
nxt_out_val <= '1';
-- Use cnt_en to avoid that toggling enable causes an out_pulse
nxt_cnt_en <= cnt_en;
IF cnt_en = '1' THEN
nxt_delay_cnt <= delay_cnt + 1;
IF delay_cnt + 1 = delay THEN
nxt_out_pulse <= '1';
nxt_cnt_en <= '0';
END IF;
ELSE
nxt_delay_cnt <= delay_cnt + 1;
IF delay_cnt+1 = delay THEN
nxt_out_val <= '1';
-- Accept new in_pulse when idle, ignore new in_pulse when busy
IF in_pulse = '1' THEN
IF delay = 0 THEN
nxt_out_pulse <= '1'; -- out_pulse immediately
ELSE
nxt_cnt_en <= '1'; -- apply out_pulse after delay
END IF;
END IF;
END IF;
END IF;
......@@ -79,13 +88,13 @@ BEGIN
p_clk : PROCESS(rst, clk)
BEGIN
IF rst = '1' THEN
i_out_val <= '0';
i_out_pulse <= '0';
cnt_en <= '0';
delay_cnt <= 0;
prev_in_val <= '0';
ELSIF rising_edge(clk) THEN
i_out_val <= nxt_out_val;
i_out_pulse <= nxt_out_pulse;
cnt_en <= nxt_cnt_en;
delay_cnt <= nxt_delay_cnt;
prev_in_val <= in_val;
END IF;
END PROCESS;
......
......@@ -41,8 +41,13 @@ ARCHITECTURE tb OF tb_common_variable_delay IS
CONSTANT c_clk_period : TIME := 10 ns;
CONSTANT c_trigger_interval : NATURAL := 40; -- in clk's
CONSTANT c_trigger_latency : NATURAL := 1; -- in clk's
CONSTANT c_delay_arr : t_natural_arr(0 TO 3) := (0, 1, 3, 12);
-- Use a delay > c_trigger_interval to check wiht exp_triggers_cnt that new
-- triggers are ignored when a delay is already busy
CONSTANT c_delay_arr : t_natural_arr(0 TO 5) := (0, 1, 3, 12, c_trigger_interval * 3, 10);
SIGNAL stimuli_done : STD_LOGIC := '0';
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL rst : STD_LOGIC;
SIGNAL clk : STD_LOGIC := '0';
......@@ -51,13 +56,19 @@ ARCHITECTURE tb OF tb_common_variable_delay IS
SIGNAL enable : STD_LOGIC := '0';
SIGNAL trigger : STD_LOGIC := '0';
SIGNAL trigger_dly : STD_LOGIC := '0';
-- Use triggers_cnt to verify that triggers only occur when enable = '1'
-- and when the delay is not busy
SIGNAL triggers_cnt : NATURAL := 0;
SIGNAL exp_triggers_cnt : NATURAL := c_delay_arr'LENGTH;
BEGIN
clk <= (NOT clk) OR tb_end AFTER c_clk_period/2;
rst <= '1', '0' AFTER c_clk_period*4;
-- generate trigger signal
proc_common_gen_pulse(c_trigger_interval/2, c_trigger_interval, '1', rst, clk, trigger);
-- generate trigger pulse signal
proc_common_gen_pulse(1, c_trigger_interval, '1', rst, clk, trigger);
p_in_stimuli : PROCESS
VARIABLE clk_cnt : NATURAL := 0;
......@@ -66,15 +77,12 @@ BEGIN
enable <= '0';
WAIT UNTIL rst = '0';
WAIT UNTIL rising_edge(clk);
-- If enable = 0, no trigger_dly is expected, see wave-window
proc_common_wait_some_cycles(clk, 50);
-- If enable = 0, no trigger_dly is expected
proc_common_wait_some_cycles(clk, c_trigger_interval * 3);
-- Enable trigger output and count clk's between trigger and trigger_dly
enable <= '1';
-- enable trigger output and count clk's between trigger lo-hi and trigger_dly lo-hi
-- check if counted clk's = c_trigger_latency + delay
FOR i IN c_delay_arr'RANGE LOOP
delay <= c_delay_arr(i);
clk_cnt := 0;
......@@ -83,28 +91,32 @@ BEGIN
clk_cnt := clk_cnt + 1;
proc_common_wait_some_cycles(clk, 1);
END LOOP;
ASSERT clk_cnt = c_trigger_latency + delay REPORT "delay failure, got " & int_to_str(clk_cnt) & ", expect " & int_to_str(c_trigger_latency+delay) SEVERITY ERROR;
-- Verify that expected delay was applied
ASSERT clk_cnt = c_trigger_latency + delay REPORT "delay failure, got " & int_to_str(clk_cnt) & ", expect " & int_to_str(c_trigger_latency+delay) SEVERITY ERROR;
proc_common_wait_some_cycles(clk, 10);
END LOOP;
enable <= '0';
proc_common_wait_some_cycles(clk, 10);
proc_common_wait_some_cycles(clk, c_trigger_interval * 3);
ASSERT triggers_cnt = exp_triggers_cnt REPORT "wrong number of trigger_dly." SEVERITY ERROR;
tb_end <= '1';
proc_common_wait_some_cycles(clk, 10);
tb_end <= '1';
WAIT;
END PROCESS;
triggers_cnt <= triggers_cnt + 1 WHEN rising_edge(clk) AND trigger_dly = '1';
-- device under test
u_dut : ENTITY work.common_variable_delay
PORT MAP (
rst => rst,
clk => clk,
rst => rst,
clk => clk,
delay => delay,
enable => enable,
in_val => trigger,
out_val => trigger_dly
delay => delay,
enable => enable,
in_pulse => trigger,
out_pulse => trigger_dly
);
END tb;
......
......@@ -88,8 +88,8 @@ BEGIN
WAIT;
END PROCESS;
-- generate trigger signal
proc_common_gen_pulse(c_trigger_interval/2, c_trigger_interval, '1', rst, clk, trigger);
-- generate trigger pulse signal
proc_common_gen_pulse(1, c_trigger_interval, '1', rst, clk, trigger);
-- device under test
u_dut : ENTITY work.mms_common_variable_delay
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment