From 4da3811ead0ddbd71272908629138e7c7e6ec8a8 Mon Sep 17 00:00:00 2001 From: Daniel van der Schuur <schuur@astron.nl> Date: Tue, 28 Feb 2017 14:14:26 +0000 Subject: [PATCH] -Instantiated mms_common_pulse_delay in ctrl_unb1_board; -Finished self-checking tb_common_pulse_delay. --- .../unb1_board/src/vhdl/ctrl_unb1_board.vhd | 46 +++++-- .../common/src/vhdl/common_pulse_delay.vhd | 10 +- .../src/vhdl/mms_common_pulse_delay.vhd | 3 +- .../common/tb/vhdl/tb_common_pulse_delay.vhd | 112 ++++++++++++++---- 4 files changed, 134 insertions(+), 37 deletions(-) diff --git a/boards/uniboard1/libraries/unb1_board/src/vhdl/ctrl_unb1_board.vhd b/boards/uniboard1/libraries/unb1_board/src/vhdl/ctrl_unb1_board.vhd index ebaf63731a..db5d686f54 100644 --- a/boards/uniboard1/libraries/unb1_board/src/vhdl/ctrl_unb1_board.vhd +++ b/boards/uniboard1/libraries/unb1_board/src/vhdl/ctrl_unb1_board.vhd @@ -103,9 +103,7 @@ ENTITY ctrl_unb1_board IS ---------------------------------------------------------------------------- -- PPS delay -- . Maximum number of dp_clk cycles that pps can be delayed. Actual number - -- is determined dynamically by MM register. - -- . 0 : Don't instantiate delay component. Does not add extra MM register. - -- . >0 : Instantiate delay component. Adds an extra MM register. + -- is determined dynamically by MM register reg_common_pulse_delay. ---------------------------------------------------------------------------- g_pps_delay_max : NATURAL := 0; @@ -217,6 +215,10 @@ ENTITY ctrl_unb1_board IS -- PPSH reg_ppsh_mosi : IN t_mem_mosi := c_mem_mosi_rst; reg_ppsh_miso : OUT t_mem_miso; + + -- Pulse (PPS) delay + reg_common_pulse_delay_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_common_pulse_delay_miso : OUT t_mem_miso := c_mem_miso_rst; -- eth1g control&monitoring eth1g_tse_clk_out : OUT STD_LOGIC; @@ -299,7 +301,8 @@ ARCHITECTURE str OF ctrl_unb1_board IS SIGNAL ext_clk : STD_LOGIC; SIGNAL ext_pps : STD_LOGIC; SIGNAL dp_dis : STD_LOGIC; - + SIGNAL mms_ppsh_pps_sys : STD_LOGIC; + SIGNAL node_ctrl_dp_clk_in : STD_LOGIC := '0'; SIGNAL node_ctrl_dp_rst_out : STD_LOGIC; @@ -595,11 +598,9 @@ BEGIN ------------------------------------------------------------------------------ -- PPS input ------------------------------------------------------------------------------ - u_mms_ppsh : ENTITY ppsh_lib.mms_ppsh GENERIC MAP ( - g_st_clk_freq => g_dp_clk_freq, - g_pps_delay_max => g_pps_delay_max + g_st_clk_freq => g_dp_clk_freq ) PORT MAP ( -- Clocks and reset @@ -614,10 +615,35 @@ BEGIN reg_miso => reg_ppsh_miso, -- Streaming clock domain - pps_sys => dp_pps + pps_sys => mms_ppsh_pps_sys ); - - + + ------------------------------------------------------------------------------ + -- PPS delay + ------------------------------------------------------------------------------ + gen_mms_common_pulse_delay : IF g_pps_delay_max>0 GENERATE + u_mms_common_pulse_delay : ENTITY common_lib.mms_common_pulse_delay + GENERIC MAP ( + g_pulse_delay_max => g_pps_delay_max, + g_register_out => TRUE + ) + PORT MAP ( + pulse_clk => dp_clk_in, + pulse_rst => dp_rst_in, + pulse_in => mms_ppsh_pps_sys, + pulse_out => dp_pps, + + mm_clk => mm_clk, + mm_rst => i_mm_rst, + reg_mosi => reg_common_pulse_delay_mosi, + reg_miso => reg_common_pulse_delay_miso + ); + END GENERATE; + + no_mms_common_pulse_delay : IF g_pps_delay_max=0 GENERATE + dp_pps <= mms_ppsh_pps_sys; + END GENERATE; + ------------------------------------------------------------------------------ -- I2C control for UniBoard sensors ------------------------------------------------------------------------------ diff --git a/libraries/base/common/src/vhdl/common_pulse_delay.vhd b/libraries/base/common/src/vhdl/common_pulse_delay.vhd index 0fdc2489f5..19653c95fd 100644 --- a/libraries/base/common/src/vhdl/common_pulse_delay.vhd +++ b/libraries/base/common/src/vhdl/common_pulse_delay.vhd @@ -31,24 +31,24 @@ USE work.common_pkg.ALL; ENTITY common_pulse_delay IS GENERIC ( - g_pulse_delay_max : NATURAL; -- Maximum delay value supported; determines internal counter width. + g_pulse_delay_max : NATURAL; -- Maximum delay value desired by user; determines internal counter width. g_register_out : BOOLEAN -- TRUE adds output register, adding 1 cycle of delay to the pulse_delay setting. ); PORT ( clk : IN STD_LOGIC; rst : IN STD_LOGIC; pulse_in : IN STD_LOGIC; - pulse_delay : IN STD_LOGIC_VECTOR(ceil_log2(g_pulse_delay_max)-1 DOWNTO 0); + pulse_delay : IN STD_LOGIC_VECTOR(ceil_log2(g_pulse_delay_max+1)-1 DOWNTO 0); pulse_out : OUT STD_LOGIC ); END ENTITY common_pulse_delay; ARCHITECTURE str OF common_pulse_delay IS - CONSTANT c_pulse_delay_max_width : NATURAL := ceil_log2(g_pulse_delay_max); + CONSTANT c_pulse_delay_max_width : NATURAL := ceil_log2(g_pulse_delay_max+1); - SIGNAL pulse_delay_reg : STD_LOGIC_VECTOR(ceil_log2(g_pulse_delay_max)-1 DOWNTO 0); - SIGNAL nxt_pulse_delay_reg : STD_LOGIC_VECTOR(ceil_log2(g_pulse_delay_max)-1 DOWNTO 0); + SIGNAL pulse_delay_reg : STD_LOGIC_VECTOR(c_pulse_delay_max_width-1 DOWNTO 0); + SIGNAL nxt_pulse_delay_reg : STD_LOGIC_VECTOR(c_pulse_delay_max_width-1 DOWNTO 0); SIGNAL common_counter_cnt_en : STD_LOGIC; SIGNAL common_counter_count : STD_LOGIC_VECTOR(c_pulse_delay_max_width-1 DOWNTO 0); diff --git a/libraries/base/common/src/vhdl/mms_common_pulse_delay.vhd b/libraries/base/common/src/vhdl/mms_common_pulse_delay.vhd index 831ca0fed0..e8b7c951e5 100644 --- a/libraries/base/common/src/vhdl/mms_common_pulse_delay.vhd +++ b/libraries/base/common/src/vhdl/mms_common_pulse_delay.vhd @@ -33,7 +33,8 @@ USE technology_lib.technology_select_pkg.ALL; ENTITY mms_common_pulse_delay IS GENERIC ( - g_pulse_delay_max : NATURAL := 0 -- Maximum number of clk cycles that pulse can be delayed + g_pulse_delay_max : NATURAL := 0; -- Maximum number of clk cycles that pulse can be delayed + g_register_out : BOOLEAN ); PORT ( pulse_clk : IN STD_LOGIC; diff --git a/libraries/base/common/tb/vhdl/tb_common_pulse_delay.vhd b/libraries/base/common/tb/vhdl/tb_common_pulse_delay.vhd index 57451d455a..aecf97add5 100644 --- a/libraries/base/common/tb/vhdl/tb_common_pulse_delay.vhd +++ b/libraries/base/common/tb/vhdl/tb_common_pulse_delay.vhd @@ -24,6 +24,10 @@ -- Purpose: -- . Feed different pulse_delay control settings to common_pulse_delay, -- verify correct pulse_out +-- Usage: +-- . as 8 +-- . run -a +-- . if no failure messages are printed, TB ran OK. LIBRARY IEEE, common_lib; USE IEEE.STD_LOGIC_1164.ALL; @@ -35,18 +39,50 @@ END tb_common_pulse_delay; ARCHITECTURE tb OF tb_common_pulse_delay IS - CONSTANT c_clk_period : TIME := 5 ns; - CONSTANT c_pulse_delay_max : NATURAL := 10; - CONSTANT c_pulse_delay_max_w : NATURAL := ceil_log2(c_pulse_delay_max); - - SIGNAL tb_end : STD_LOGIC := '0'; - SIGNAL clk : STD_LOGIC := '1'; - SIGNAL rst : STD_LOGIC := '1'; - SIGNAL pulse_in : STD_LOGIC; - SIGNAL nxt_pulse_in : STD_LOGIC; - SIGNAL pulse_delay : STD_LOGIC_VECTOR(c_pulse_delay_max_w-1 DOWNTO 0); - SIGNAL nxt_pulse_delay : STD_LOGIC_VECTOR(c_pulse_delay_max_w-1 DOWNTO 0); - SIGNAL pulse_out : STD_LOGIC; + ----------------------------------------------------------------------------- + -- common_pulse_delay parameters + ----------------------------------------------------------------------------- + CONSTANT c_pulse_delay_max : NATURAL := 100; + CONSTANT c_pulse_delay_max_w : NATURAL := ceil_log2(c_pulse_delay_max+1); + + ----------------------------------------------------------------------------- + -- Clock & reset + ----------------------------------------------------------------------------- + CONSTANT c_clk_period : TIME := 5 ns; + + SIGNAL clk : STD_LOGIC := '1'; + SIGNAL rst : STD_LOGIC := '1'; + + ----------------------------------------------------------------------------- + -- Stimuli + ----------------------------------------------------------------------------- + SIGNAL pulse_in : STD_LOGIC; + SIGNAL first_pulse : STD_LOGIC; + SIGNAL pulse_delay : STD_LOGIC_VECTOR(c_pulse_delay_max_w-1 DOWNTO 0); + + ----------------------------------------------------------------------------- + -- Verification + ---------------------------------------------------------------------------- + CONSTANT c_nof_pulses : NATURAL := pow2(ceil_log2(c_pulse_delay_max))-1; + CONSTANT c_init_cycles : NATURAL := 12; -- Number of clock cycles for init (startup after reset) + CONSTANT c_total_delay_cycles : NATURAL := (c_nof_pulses*(c_nof_pulses+1))/2; --sum of functional delays 1..c_nof_pulses + CONSTANT c_total_reg_delay_cycles : NATURAL := c_nof_pulses; -- 1 extra delay cycles is introduced for every pulse due to register + CONSTANT c_total_cycles : NATURAL := c_init_cycles+c_total_delay_cycles+c_total_reg_delay_cycles; + + SIGNAL tb_end : STD_LOGIC := '0'; + SIGNAL pulse_delay_reg : STD_LOGIC_VECTOR(c_pulse_delay_max_w-1 DOWNTO 0); + SIGNAL pulse_out : STD_LOGIC; + SIGNAL pulse_count : NATURAL; + SIGNAL pulse_delay_count : NATURAL; + + ----------------------------------------------------------------------------- + -- Registers + ----------------------------------------------------------------------------- + SIGNAL nxt_pulse_in : STD_LOGIC; + SIGNAL nxt_pulse_delay : STD_LOGIC_VECTOR(c_pulse_delay_max_w-1 DOWNTO 0); + SIGNAL nxt_pulse_delay_reg : STD_LOGIC_VECTOR(c_pulse_delay_max_w-1 DOWNTO 0); + SIGNAL nxt_pulse_count : NATURAL; + SIGNAL nxt_pulse_delay_count : NATURAL; BEGIN @@ -60,8 +96,9 @@ BEGIN -- Stimuli ----------------------------------------------------------------------------- -- Create the first pulse here, then feed pulse_out to pulse - nxt_pulse_in <= '1'; --FIXME - + first_pulse <= '0', '1' AFTER 10*c_clk_period, '0' AFTER 11*c_clk_period; + nxt_pulse_in <= first_pulse or pulse_out; + -- Make next pulse delay 1 cycle longer nxt_pulse_delay <= INCR_UVEC(pulse_delay, 1) WHEN pulse_in='1' ELSE pulse_delay; ----------------------------------------------------------------------------- @@ -70,7 +107,7 @@ BEGIN u_common_pulse_delay : ENTITY work.common_pulse_delay GENERIC MAP ( g_pulse_delay_max => c_pulse_delay_max, - g_register_out => FALSE + g_register_out => TRUE ) PORT MAP ( clk => clk, @@ -81,17 +118,50 @@ BEGIN pulse_out => pulse_out ); - ------------------------------------------------------------------------------- + ----------------------------------------------------------------------------- + -- Verification + -- . Check total number of output pulses + -- . Check input->output pulse delay + ----------------------------------------------------------------------------- + tb_end <= '0', '1' AFTER c_total_cycles*c_clk_period; + + -- Keep counts + nxt_pulse_count <= pulse_count+1 WHEN pulse_out='1' ELSE pulse_count; + nxt_pulse_delay_count <= 0 WHEN pulse_in='1' ELSE pulse_delay_count+1; + + -- Store the delay setting for comparison to actual pulse delay + nxt_pulse_delay_reg <= pulse_delay WHEN pulse_in='1' ELSE pulse_delay_reg; + + -- Perform checks + p_verify: PROCESS(pulse_out, tb_end) + BEGIN + -- input/output pulse delay should match setting + IF pulse_out='1' AND pulse_delay_count/=TO_UINT(pulse_delay_reg) THEN + REPORT "I/O pulse delay does not match delay setting!" SEVERITY FAILURE; + END IF; + -- Total number of pulses should be the maximum allowed by common_pulse_delay's interal counter width + IF tb_end='1' AND pulse_count/=c_nof_pulses THEN + REPORT "Incorrect total number of pulses!" SEVERITY FAILURE; + END IF; + END PROCESS; + + ----------------------------------------------------------------------------- -- Registers - ------------------------------------------------------------------------------- + ----------------------------------------------------------------------------- p_clk : PROCESS (rst, clk) BEGIN IF rst = '1' THEN - pulse_delay <= (OTHERS=>'0'); - pulse_in <= '0'; + pulse_delay <= (OTHERS=>'0'); + pulse_delay_reg <= (OTHERS=>'0'); + pulse_in <= '0'; + pulse_count <= 0; + pulse_delay_count <= 0; ELSIF rising_edge(clk) THEN - pulse_delay <= nxt_pulse_delay; - pulse_in <= nxt_pulse_in; + pulse_delay <= nxt_pulse_delay; + pulse_delay_reg <= nxt_pulse_delay_reg; + pulse_in <= nxt_pulse_in; + pulse_count <= nxt_pulse_count; + pulse_delay_count <= nxt_pulse_delay_count; END IF; END PROCESS; -- GitLab