Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
H
HDL
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Jira
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
RTSD
HDL
Commits
5251bbcb
Commit
5251bbcb
authored
2 years ago
by
Eric Kooistra
Browse files
Options
Downloads
Patches
Plain Diff
Add tb_dp_rsn_source.vhd, it compiles OK but does not verify rs_sosi yet.
parent
2dea6766
No related branches found
Branches containing commit
No related tags found
1 merge request
!317
Resolve L2SDP-7
Pipeline
#46150
passed with warnings
2 years ago
Stage: linting
Stage: simulation
Stage: synthesis
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
libraries/base/dp/hdllib.cfg
+1
-0
1 addition, 0 deletions
libraries/base/dp/hdllib.cfg
libraries/base/dp/tb/vhdl/tb_dp_rsn_source.vhd
+365
-0
365 additions, 0 deletions
libraries/base/dp/tb/vhdl/tb_dp_rsn_source.vhd
with
366 additions
and
0 deletions
libraries/base/dp/hdllib.cfg
+
1
−
0
View file @
5251bbcb
...
@@ -221,6 +221,7 @@ test_bench_files =
...
@@ -221,6 +221,7 @@ test_bench_files =
tb/vhdl/tb_mmp_dp_bsn_align_v2.vhd
tb/vhdl/tb_mmp_dp_bsn_align_v2.vhd
tb/vhdl/tb_dp_bsn_monitor.vhd
tb/vhdl/tb_dp_bsn_monitor.vhd
tb/vhdl/tb_dp_bsn_monitor_v2.vhd
tb/vhdl/tb_dp_bsn_monitor_v2.vhd
tb/vhdl/tb_dp_rsn_source.vhd
tb/vhdl/tb_dp_bsn_source.vhd
tb/vhdl/tb_dp_bsn_source.vhd
tb/vhdl/tb_dp_bsn_source_v2.vhd
tb/vhdl/tb_dp_bsn_source_v2.vhd
tb/vhdl/tb_mms_dp_bsn_source.vhd
tb/vhdl/tb_mms_dp_bsn_source.vhd
...
...
This diff is collapsed.
Click to expand it.
libraries/base/dp/tb/vhdl/tb_dp_rsn_source.vhd
0 → 100644
+
365
−
0
View file @
5251bbcb
-------------------------------------------------------------------------------
--
-- Copyright 2022
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Author: E. Kooistra
-- Purpose: Tb for tb_dp_rsn_source
-- Use dp_bsn_source_v2 to create bs_sosi and extending it with dut =
-- dp_rsn_source to create and verify rs_sosi.
-- Remark:
-- * This tb is made based on tb_dp_bsn_source_v2.
LIBRARY
IEEE
,
common_lib
,
dp_lib
;
USE
IEEE
.
STD_LOGIC_1164
.
ALL
;
USE
IEEE
.
NUMERIC_STD
.
ALL
;
USE
common_lib
.
common_pkg
.
ALL
;
USE
common_lib
.
tb_common_pkg
.
ALL
;
USE
dp_lib
.
dp_stream_pkg
.
ALL
;
USE
dp_lib
.
tb_dp_pkg
.
ALL
;
ENTITY
tb_dp_rsn_source
IS
GENERIC
(
g_pps_interval
:
NATURAL
:
=
16
;
--101;
g_bs_block_size
:
NATURAL
:
=
5
;
--23
g_rs_block_size
:
NATURAL
:
=
5
--23
);
END
tb_dp_rsn_source
;
ARCHITECTURE
tb
OF
tb_dp_rsn_source
IS
-- The nof block per sync interval will be the same after every
-- c_min_nof_pps_interval. The c_gcd is the greatest common divider of
-- g_pps_interval and g_bs_block_size, so g_bs_block_size / c_gcd yields an
-- integer. When g_pps_interval and g_bs_block_size are relative prime,
-- then c_gcd = 1, and then it takes g_bs_block_size nof g_pps_interval
-- for the pattern of c_nof_block_per_sync_lo and c_nof_block_per_sync_hi
-- to repeat. If c_gcd = g_bs_block_size, then c_nof_block_per_sync_lo =
-- c_nof_block_per_sync_hi, so then the nof block per sync interval is
-- the same in every pps interval.
CONSTANT
c_gcd
:
NATURAL
:
=
gcd
(
g_pps_interval
,
g_bs_block_size
);
CONSTANT
c_min_nof_pps_interval
:
NATURAL
:
=
g_bs_block_size
/
c_gcd
;
CONSTANT
c_nof_block_per_sync_lo
:
NATURAL
:
=
g_pps_interval
/
g_bs_block_size
;
CONSTANT
c_nof_block_per_sync_hi
:
NATURAL
:
=
ceil_div
(
g_pps_interval
,
g_bs_block_size
);
-- choose c_nof_pps and c_nof_repeat > c_min_nof_pps_interval, because the
-- fractional sync pattern will repeat every c_min_nof_pps_interval number
-- of g_pps_intervals.
CONSTANT
c_factor
:
NATURAL
:
=
3
;
CONSTANT
c_nof_pps
:
NATURAL
:
=
c_min_nof_pps_interval
*
c_factor
;
CONSTANT
c_nof_repeat
:
NATURAL
:
=
c_min_nof_pps_interval
*
c_factor
;
CONSTANT
c_clk_period
:
TIME
:
=
10
ns
;
CONSTANT
c_bsn_w
:
NATURAL
:
=
31
;
CONSTANT
c_bsn_time_offset_w
:
NATURAL
:
=
ceil_log2
(
g_bs_block_size
);
-- Minimum latency between sync and PPS, due to logic in DUT
CONSTANT
c_dut_latency
:
NATURAL
:
=
3
;
-- The state name tells what kind of test is being done
TYPE
t_state_enum
IS
(
s_disable
,
s_dp_on
,
s_dp_on_pps
);
-- Define the PPS (SSN) and BSN grid that both start at 0 according to Figure 3.1 in [1]:
TYPE
t_time_grid
IS
RECORD
pps
:
STD_LOGIC
;
-- pulse per second, g_pps_interval clk per pps interval
ssn
:
NATURAL
;
-- seconds sequence number
bsn
:
NATURAL
;
-- block sequence number, g_bs_block_size clk per block
sync
:
STD_LOGIC
;
-- active at sop when pps is active or was active
sop
:
STD_LOGIC
;
-- start of block
eop
:
STD_LOGIC
;
-- end of block
END
RECORD
;
CONSTANT
c_time_grid_rst
:
t_time_grid
:
=
(
'0'
,
0
,
0
,
'0'
,
'0'
,
'0'
);
-- Reference grid
SIGNAL
ref_grid
:
t_time_grid
:
=
c_time_grid_rst
;
SIGNAL
ssn_eop
:
STD_LOGIC
:
=
'0'
;
SIGNAL
hold_pps
:
STD_LOGIC
:
=
'0'
;
SIGNAL
nxt_hold_pps
:
STD_LOGIC
:
=
'0'
;
-- Tb
SIGNAL
tb_end
:
STD_LOGIC
:
=
'0'
;
SIGNAL
rst
:
STD_LOGIC
:
=
'1'
;
SIGNAL
clk
:
STD_LOGIC
:
=
'1'
;
SIGNAL
tb_state
:
t_state_enum
:
=
s_disable
;
-- BSN source
SIGNAL
dp_on
:
STD_LOGIC
:
=
'0'
;
SIGNAL
dp_on_pps
:
STD_LOGIC
:
=
'0'
;
SIGNAL
dp_on_status
:
STD_LOGIC
;
SIGNAL
bs_restart
:
STD_LOGIC
;
SIGNAL
bs_new_interval
:
STD_LOGIC
;
SIGNAL
tb_new_interval
:
STD_LOGIC
:
=
'0'
;
SIGNAL
bsn_init
:
STD_LOGIC_VECTOR
(
c_bsn_w
-1
DOWNTO
0
)
:
=
(
OTHERS
=>
'0'
);
SIGNAL
bsn_time_offset
:
STD_LOGIC_VECTOR
(
c_bsn_time_offset_w
-1
DOWNTO
0
)
:
=
(
OTHERS
=>
'0'
);
SIGNAL
bs_sosi
:
t_dp_sosi
;
-- RSN source
SIGNAL
rs_restart
:
STD_LOGIC
;
SIGNAL
rs_new_interval
:
STD_LOGIC
;
SIGNAL
rs_sosi
:
t_dp_sosi
;
-- Verify
SIGNAL
exp_grid
:
t_time_grid
;
SIGNAL
unexpected_bs_sync
:
STD_LOGIC
;
SIGNAL
sl0
:
STD_LOGIC
:
=
'0'
;
SIGNAL
verify_en
:
STD_LOGIC
:
=
'0'
;
SIGNAL
verify_sync
:
STD_LOGIC
:
=
'0'
;
SIGNAL
hold_bs_sop
:
STD_LOGIC
;
SIGNAL
prev_bs_valid
:
STD_LOGIC
;
SIGNAL
bs_starts_cnt
:
NATURAL
:
=
0
;
SIGNAL
dbg_c_nof_pps
:
NATURAL
:
=
c_nof_pps
;
SIGNAL
dbg_c_nof_repeat
:
NATURAL
:
=
c_nof_repeat
;
SIGNAL
dbg_nof_blk
:
NATURAL
;
SIGNAL
dbg_accumulate
:
NATURAL
;
SIGNAL
dbg_expected_bsn
:
NATURAL
;
BEGIN
rst
<=
'1'
,
'0'
AFTER
c_clk_period
*
7
;
clk
<=
(
NOT
clk
)
OR
tb_end
AFTER
c_clk_period
/
2
;
-----------------------------------------------------------------------------
-- Generate reference time grid
-----------------------------------------------------------------------------
proc_common_gen_pulse
(
1
,
g_pps_interval
,
'1'
,
sl0
,
clk
,
ref_grid
.
pps
);
proc_common_gen_pulse
(
1
,
g_bs_block_size
,
'1'
,
sl0
,
clk
,
ref_grid
.
sop
);
ref_grid
.
eop
<=
ref_grid
.
sop
'DELAYED
((
g_bs_block_size
-
1
)
*
c_clk_period
);
ssn_eop
<=
ref_grid
.
pps
'DELAYED
((
g_pps_interval
-
1
)
*
c_clk_period
);
ref_grid
.
ssn
<=
ref_grid
.
ssn
+
1
WHEN
rising_edge
(
clk
)
AND
ssn_eop
=
'1'
;
ref_grid
.
bsn
<=
ref_grid
.
bsn
+
1
WHEN
rising_edge
(
clk
)
AND
ref_grid
.
eop
=
'1'
;
-- Issue sync at start of block
p_ref_grid_sync
:
PROCESS
(
ref_grid
,
hold_pps
)
BEGIN
ref_grid
.
sync
<=
'0'
;
nxt_hold_pps
<=
hold_pps
;
IF
ref_grid
.
pps
=
'1'
THEN
IF
ref_grid
.
sop
=
'1'
THEN
ref_grid
.
sync
<=
'1'
;
-- immediately issue sync
ELSE
nxt_hold_pps
<=
'1'
;
-- wait until next block
END
IF
;
END
IF
;
IF
hold_pps
=
'1'
THEN
IF
ref_grid
.
sop
=
'1'
THEN
ref_grid
.
sync
<=
'1'
;
-- issue pending sync
nxt_hold_pps
<=
'0'
;
END
IF
;
END
IF
;
END
PROCESS
;
hold_pps
<=
nxt_hold_pps
WHEN
rising_edge
(
clk
);
exp_grid
<=
ref_grid
'DELAYED
(
c_dut_latency
*
c_clk_period
);
-----------------------------------------------------------------------------
-- Stimuli
-----------------------------------------------------------------------------
p_mm
:
PROCESS
VARIABLE
v_ssn
:
NATURAL
;
VARIABLE
v_bsn_init
:
NATURAL
;
VARIABLE
v_bsn_time_offset
:
NATURAL
;
BEGIN
-- Get synchronous to clk
proc_common_wait_until_low
(
clk
,
rst
);
proc_common_wait_some_cycles
(
clk
,
10
);
-- Start asynchronously by making dp_on high
verify_en
<=
'0'
;
-- only verify visualy in wave window
tb_state
<=
s_dp_on
;
dp_on_pps
<=
'0'
;
dp_on
<=
'1'
;
proc_common_wait_some_cycles
(
clk
,
c_nof_pps
*
g_pps_interval
);
tb_state
<=
s_disable
;
dp_on
<=
'0'
;
dp_on_pps
<=
'0'
;
proc_common_wait_some_cycles
(
clk
,
10
);
-- Start synchronously by making dp_on and dp_on_pps high
verify_en
<=
'1'
;
-- verify automatically in test bench
FOR
I
IN
0
TO
c_nof_repeat
-1
LOOP
-- Wait some variable time between tests, to enforce testing different
-- bsn_time_offset values
proc_common_wait_some_cycles
(
clk
,
20
);
proc_common_wait_some_cycles
(
clk
,
I
*
g_pps_interval
);
-- Wait until in the beginning of PPS interval
proc_common_wait_until_hi_lo
(
clk
,
ref_grid
.
pps
);
proc_common_wait_some_cycles
(
clk
,
c_dut_latency
);
-- Determine bsn_init and bsn_time_offset for BSN source start
-- . bsn_init = BSN at sync
-- . bsn_time_offset = number of clk that sync occurs after PPS
v_ssn
:
=
ref_grid
.
ssn
+
1
;
-- +1 to prepare start in next PPS interval
v_bsn_init
:
=
ceil_div
(
v_SSN
*
g_pps_interval
,
g_bs_block_size
);
-- Equation 3.6 in [1]
v_bsn_time_offset
:
=
v_bsn_init
*
g_bs_block_size
-
v_SSN
*
g_pps_interval
;
-- Equation 3.7 in [1]
bsn_init
<=
TO_UVEC
(
v_bsn_init
,
c_bsn_w
);
--
bsn_time_offset
<=
TO_UVEC
(
v_bsn_time_offset
,
c_bsn_time_offset_w
);
-- Start synchronously by making dp_on and dp_on_pps high
tb_state
<=
s_dp_on_pps
;
dp_on_pps
<=
'1'
;
dp_on
<=
'1'
;
proc_common_wait_some_cycles
(
clk
,
c_nof_pps
*
g_pps_interval
);
tb_state
<=
s_disable
;
dp_on
<=
'0'
;
dp_on_pps
<=
'0'
;
END
LOOP
;
proc_common_wait_some_cycles
(
clk
,
10
);
ASSERT
bs_starts_cnt
=
1
+
c_nof_repeat
REPORT
"Wrong number of BSN source starts."
SEVERITY
ERROR
;
tb_end
<=
'1'
;
WAIT
;
END
PROCESS
;
-----------------------------------------------------------------------------
-- Verification
-- . Some aspects of bs_sosi are verified multiple times in different ways,
-- this overlap is fine, because the tb and DUT are rather complicated, so
-- using different approaches also helpt to verify the tb itself.
-----------------------------------------------------------------------------
verify_sync
<=
verify_en
AND
bs_sosi
.
valid
;
proc_dp_verify_sop_and_eop
(
clk
,
bs_sosi
.
valid
,
bs_sosi
.
sop
,
bs_sosi
.
eop
,
hold_bs_sop
);
-- Verify that sop and eop come in pairs
--proc_dp_verify_sync(clk, verify_sync, bs_sosi.sync, exp_grid.sop, exp_grid.sync); -- Verify sync at sop and at expected_sync
-- Verify sync at sop and at expected_sync
proc_dp_verify_sync
(
0
,
-- start bsn of PPS grid and BSN grid is 0, see [1]
g_pps_interval
,
g_bs_block_size
,
clk
,
verify_en
,
bs_sosi
.
sync
,
bs_sosi
.
sop
,
bs_sosi
.
bsn
,
dbg_nof_blk
,
dbg_accumulate
,
dbg_expected_bsn
);
-- Verify bs_sosi by comparing with exp_grid, this again verifies bs_sosi.sync, sop and bsn
p_verify_bs_sosi_grid
:
PROCESS
(
clk
)
BEGIN
IF
rising_edge
(
clk
)
THEN
unexpected_bs_sync
<=
'0'
;
IF
verify_en
=
'1'
AND
bs_sosi
.
valid
=
'1'
THEN
ASSERT
TO_UINT
(
bs_sosi
.
bsn
)
=
exp_grid
.
bsn
REPORT
"Wrong bs_sosi.bsn /= exp_grid.bsn"
SEVERITY
ERROR
;
ASSERT
bs_sosi
.
sync
=
exp_grid
.
sync
REPORT
"Wrong bs_sosi.sync /= exp_grid.sync"
SEVERITY
ERROR
;
ASSERT
bs_sosi
.
sop
=
exp_grid
.
sop
REPORT
"Wrong bs_sosi.sop /= exp_grid.sop"
SEVERITY
ERROR
;
ASSERT
bs_sosi
.
eop
=
exp_grid
.
eop
REPORT
"Wrong bs_sosi.eop /= exp_grid.eop"
SEVERITY
ERROR
;
-- Mark error in Wave window
IF
bs_sosi
.
sync
=
'1'
AND
bs_sosi
.
sync
/=
exp_grid
.
sync
THEN
unexpected_bs_sync
<=
'1'
;
END
IF
;
END
IF
;
END
IF
;
END
PROCESS
;
-- Verify that bs_sosi.valid = '1' did happen after dp_on by verifying bs_start
prev_bs_valid
<=
bs_sosi
.
valid
WHEN
rising_edge
(
clk
);
bs_starts_cnt
<=
bs_starts_cnt
+
1
WHEN
rising_edge
(
clk
)
AND
bs_sosi
.
valid
=
'1'
AND
prev_bs_valid
=
'0'
;
p_verify_bs_restart
:
PROCESS
(
clk
)
BEGIN
IF
rising_edge
(
clk
)
THEN
IF
bs_restart
=
'1'
THEN
ASSERT
bs_sosi
.
sync
=
'1'
REPORT
"Unexpected bs_start while bs_sosi.sync /= 1"
SEVERITY
ERROR
;
ASSERT
prev_bs_valid
=
'0'
REPORT
"Unexpected bs_start while prev_bs_valid /= 0"
SEVERITY
ERROR
;
END
IF
;
END
IF
;
END
PROCESS
;
p_verify_bs_new_interval
:
PROCESS
(
clk
)
BEGIN
IF
rising_edge
(
clk
)
THEN
IF
bs_restart
=
'1'
THEN
ASSERT
bs_new_interval
=
'1'
REPORT
"Wrong begin of bs_new_interval"
SEVERITY
ERROR
;
tb_new_interval
<=
'1'
;
ELSIF
bs_sosi
.
sync
=
'1'
THEN
ASSERT
bs_new_interval
=
'0'
REPORT
"Wrong end of bs_new_interval"
SEVERITY
ERROR
;
tb_new_interval
<=
'0'
;
ELSIF
tb_new_interval
=
'1'
THEN
ASSERT
bs_new_interval
=
'1'
REPORT
"Wrong level during bs_new_interval"
SEVERITY
ERROR
;
ELSE
ASSERT
bs_new_interval
=
'0'
REPORT
"Unexpected bs_new_interval"
SEVERITY
ERROR
;
END
IF
;
END
IF
;
END
PROCESS
;
-----------------------------------------------------------------------------
-- DUT: dp_bsn_source_v2
-----------------------------------------------------------------------------
u_bsn
:
ENTITY
work
.
dp_bsn_source_v2
GENERIC
MAP
(
g_block_size
=>
g_bs_block_size
,
g_nof_clk_per_sync
=>
g_pps_interval
,
g_bsn_w
=>
c_bsn_w
,
g_bsn_time_offset_w
=>
c_bsn_time_offset_w
)
PORT
MAP
(
rst
=>
rst
,
clk
=>
clk
,
pps
=>
ref_grid
.
pps
,
-- MM control
dp_on
=>
dp_on
,
dp_on_pps
=>
dp_on_pps
,
dp_on_status
=>
dp_on_status
,
-- = src_out.valid
bs_restart
=>
bs_restart
,
-- = src_out.sync for first sync after dp_on went high
bs_new_interval
=>
bs_new_interval
,
-- active during first src_out.sync interval
bsn_init
=>
bsn_init
,
bsn_time_offset
=>
bsn_time_offset
,
-- Streaming
src_out
=>
bs_sosi
);
u_rsn
:
ENTITY
work
.
dp_rsn_source
GENERIC
MAP
(
g_block_size
=>
g_rs_block_size
,
g_nof_clk_per_sync
=>
g_pps_interval
,
g_bsn_w
=>
c_bsn_w
)
PORT
MAP
(
rst
=>
rst
,
clk
=>
clk
,
-- Input stream sosi control using BSN
bs_sosi
=>
bs_sosi
,
-- input reference stream using BSN
-- Output stream sosi control using RSN
rs_sosi
=>
rs_sosi
,
-- output stream using RSN and g_rs_block_size, g_nof_clk_per_sync
rs_restart
=>
rs_restart
,
-- = rs_sosi.sync for first sync after bs_sosi.valid went high
rs_new_interval
=>
rs_new_interval
-- = active during first rs_sosi.sync interval
);
END
tb
;
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment