From beb0444083407adc7db60ce1007ae28edf5ba2d0 Mon Sep 17 00:00:00 2001 From: Eric Kooistra <kooistra@astron.nl> Date: Tue, 21 Sep 2021 17:49:50 +0200 Subject: [PATCH] Improved comments. Use r.enable instead of v.enable to ease timing closure. This required using expected_out_enable2 in tb for g_block_size = 2. --- .../dp/src/vhdl/dp_bsn_sync_scheduler.vhd | 43 +++++++++++++++---- .../dp/tb/vhdl/tb_dp_bsn_sync_scheduler.vhd | 20 +++++++-- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/libraries/base/dp/src/vhdl/dp_bsn_sync_scheduler.vhd b/libraries/base/dp/src/vhdl/dp_bsn_sync_scheduler.vhd index 9c88855862..0d5b21ea61 100644 --- a/libraries/base/dp/src/vhdl/dp_bsn_sync_scheduler.vhd +++ b/libraries/base/dp/src/vhdl/dp_bsn_sync_scheduler.vhd @@ -38,7 +38,7 @@ -- * ctrl_enable: -- The output is enabled at the ctrl_start_bsn when ctrl_enable = '1' and the -- output is disable after an in_sosi.eop when ctrl_enable = '0'. If the --- output is diabled, then the sosai control fields are forced to '0', the +-- output is diabled, then the sosi control fields are forced to '0', the -- other sosi fields of the in_sosi are passed on to the out_sosi. -- * mon_current_input_bsn: -- The user can read mon_current_input_bsn to determine a suitable @@ -195,13 +195,19 @@ BEGIN output_start <= '0'; output_sync <= '0'; + --------------------------------------------------------------------------- -- Detect ctrl_enable rising event + --------------------------------------------------------------------------- IF ctrl_enable = '1' AND ctrl_enable_evt = '1' THEN v.enable_init := '1'; END IF; - -- Initialization: calculate number of blocks per output sync interval - -- . use r.enable_init instead of v.enable_init to easy timing closure and + --------------------------------------------------------------------------- + -- Initialization: + -- calculate number of blocks per output sync interval, start with + -- nof_blk_max in first sync interval + --------------------------------------------------------------------------- + -- . use r.enable_init instead of v.enable_init to ease timing closure and -- because functionally it makes no difference. IF r.enable_init = '1' THEN -- Assume ctrl_start_bsn is scheduled more than nof_blk block clk cycles @@ -239,7 +245,9 @@ BEGIN v.blk_cnt := 0; END IF; - -- Enable / disable control + --------------------------------------------------------------------------- + -- Enable / re-enable / disable control + --------------------------------------------------------------------------- IF ctrl_enable = '0' THEN -- Disable output when ctrl_enable requests disable. v.enable := '0'; @@ -260,6 +268,12 @@ BEGIN END IF; END IF; + --------------------------------------------------------------------------- + -- Output enable / disable + -- . enable at start_bsn and issue output_start pulse for first output + -- sync interval + -- . disable after input block has finished. + --------------------------------------------------------------------------- -- Hold input eop to detect when input has finished a block and to detect -- gaps between in_sosi.eop and in_sosi.sop IF in_sosi.sop = '1' THEN @@ -269,7 +283,9 @@ BEGIN v.hold_eop := '1'; END IF; - IF v.enable = '1' THEN + -- . use r.enable instead of v.enable to ease timing closure and because + -- functionally it makes no difference. + IF r.enable = '1' THEN -- Output enable at in_sosi.sop start_bsn IF in_sosi.sop = '1' THEN IF UNSIGNED(in_sosi.bsn) = UNSIGNED(r.start_bsn) THEN @@ -285,6 +301,9 @@ BEGIN END IF; END IF; + --------------------------------------------------------------------------- + -- Issue output_sync at output_sync_bsn and request next output_sync_bsn + --------------------------------------------------------------------------- -- Generate output sync interval based on input BSN and ctrl_interval_size IF v.output_enable = '1' THEN IF in_sosi.sop = '1' THEN @@ -300,7 +319,9 @@ BEGIN END IF; END IF; - -- Determine BSN for next output sync + --------------------------------------------------------------------------- + -- Determine BSN for next output_sync (= output_sync_bsn) + --------------------------------------------------------------------------- IF r.update_bsn = '1' THEN -- Similar code as in proc_dp_verify_sync(), the difference is that: -- . Here r.extra is number of extra samples in nof_blk_max compared to @@ -321,8 +342,9 @@ BEGIN -- Assume output_sync_bsn is in future v.update_bsn := '0'; - -- else: last r.input_bsn will be used to keep update_bsn active for - -- more clk cycles to catch up for lost input blocks. + -- If output_sync_bsn is still in past, due to lost input blocks, then + -- last r.input_bsn will be used to keep update_bsn active for more clk + -- cycles to catch up for lost input blocks. END IF; -- Hold input bsn @@ -346,7 +368,10 @@ BEGIN nxt_r <= v; END PROCESS; + ----------------------------------------------------------------------------- -- Output in_sosi with programmed sync interval or disable the output + ----------------------------------------------------------------------------- + -- . note this is part of p_comb, but using a separate process is fine too. p_output_sosi : PROCESS(in_sosi, nxt_r, output_sync) BEGIN output_sosi <= in_sosi; @@ -360,7 +385,9 @@ BEGIN END IF; END PROCESS; + ----------------------------------------------------------------------------- -- Pipeline output to avoid timing closure problems due to use of nxt_r.output_enable + ----------------------------------------------------------------------------- u_out_sosi : ENTITY work.dp_pipeline GENERIC MAP ( g_pipeline => g_pipeline diff --git a/libraries/base/dp/tb/vhdl/tb_dp_bsn_sync_scheduler.vhd b/libraries/base/dp/tb/vhdl/tb_dp_bsn_sync_scheduler.vhd index a94570c92e..67939303a1 100644 --- a/libraries/base/dp/tb/vhdl/tb_dp_bsn_sync_scheduler.vhd +++ b/libraries/base/dp/tb/vhdl/tb_dp_bsn_sync_scheduler.vhd @@ -78,8 +78,8 @@ ENTITY tb_dp_bsn_sync_scheduler IS -- Input sync period and sosi ctrl g_nof_input_sync : NATURAL := 10; g_nof_block_per_input_sync : NATURAL := 17; - g_block_size : NATURAL := 10; - g_input_gap_size : NATURAL := 3; + g_block_size : NATURAL := 2; + g_input_gap_size : NATURAL := 0; -- Output sync period g_nof_samples_per_output_sync : NATURAL := 45 -- 45 / g_block_size = 4.5 @@ -161,6 +161,8 @@ ARCHITECTURE tb OF tb_dp_bsn_sync_scheduler IS SIGNAL prev_out_enable : STD_LOGIC := '0'; SIGNAL pending_out_disable : STD_LOGIC := '0'; SIGNAL expected_out_enable : STD_LOGIC := '0'; + SIGNAL expected_out_enable1 : STD_LOGIC := '0'; + SIGNAL expected_out_enable2 : STD_LOGIC := '0'; SIGNAL expecting_out_start : STD_LOGIC := '0'; SIGNAL hold_out_eop : STD_LOGIC := '0'; SIGNAL hold_out_sop : STD_LOGIC := '0'; @@ -388,6 +390,9 @@ BEGIN END IF; END PROCESS; + expected_out_enable1 <= expected_out_enable WHEN rising_edge(clk); + expected_out_enable2 <= expected_out_enable1 WHEN rising_edge(clk); + p_verify_out_enable : PROCESS(clk) BEGIN -- Use registered values to compare, to avoid combinatorial differences @@ -397,7 +402,16 @@ BEGIN IF rising_edge(clk) THEN IF out_enable /= expected_out_enable THEN IF out_enable = '1' THEN - REPORT "Unexpected enabled out_enable" SEVERITY ERROR; + IF g_block_size > 2 THEN + REPORT "Unexpected enabled out_enable" SEVERITY ERROR; + ELSIF out_enable /= expected_out_enable2 THEN + -- For g_block_size = 2 the use of r.enable (instead of v.enable) + -- in dp_bsn_sync_scheduler.vhd causes that the output can stay + -- enabled 2 cycles longer, which is ok. Using v.enable does + -- avoid this need to use expected_out_enable2, but for timing + -- closure it is preferred to use r.enable. + REPORT "Unexpected enabled out_enable2" SEVERITY ERROR; + END IF; ELSE REPORT "Unexpected disabled out_enable" SEVERITY ERROR; END IF; -- GitLab