Commit 45518da1 authored by CI's avatar CI

Simple cleanup and README added

parent 0d8edb53
Pipeline #3600 passed with stage
in 28 minutes and 51 seconds
This is a testbench to verify the gc_multichannel_frequency_meter core. It uses GHDL simulator and OSVVM as verification methodology. All input signals in the testbench are random, with random seed also.
The generics of the core are:
- g_with_internal_timebase : Specifies from where the period is defined
- g_clk_sys_freq : Frequency of system clock
- g_channels : Number of the channels
- g_counter_bits : Bit length of the counter
And the test cases that are created, depending on the values of these generics are:
- Two bigger category, if g_with_internal_timebase is either true or false, where there are the following:
- Different values of system clock frequency (up to 10000Hz)
- Different values of Channels (from 2 to 5)
Counter bits remain to 32 bits.
There are the following assertions, to give to the testbench a more self-checking approach:
- Check for data mismatch between the testbench's output and RTL output
- Check if the number of the channels are bigger than 1
Note: It is better to give lower values to CLK_SYS_FREQ in order for the simulation to not take loong time to finish
......@@ -6,32 +6,43 @@ TB=tb_gc_multichannel_frequency_meter
echo "Running simulation for $TB"
echo "When g_WITH_INTERNAL_TIMEBASE = TRUE"
echo "clk_sys_freq = 500, channels = 2, counter_bits=32"
ghdl -r --std=08 -frelaxed-rules $TB -gg_WITH_INTERNAL_TIMEBASE=TRUE -gg_CLK_SYS_FREQ=500 -gg_CHANNELS=2 -gg_COUNTER_BITS=32
echo "***********************************************************************************"
echo "clk_sys_freq = 1000, channels = 3, counter_bits=32"
ghdl -r --std=08 -frelaxed-rules $TB -gg_WITH_INTERNAL_TIMEBASE=TRUE -gg_CLK_SYS_FREQ=1000 -gg_CHANNELS=3 -gg_COUNTER_BITS=32
echo "***********************************************************************************"
echo "clk_sys_freq = 5000, channels = 4, counter_bits=32"
ghdl -r --std=08 -frelaxed-rules $TB -gg_WITH_INTERNAL_TIMEBASE=TRUE -gg_CLK_SYS_FREQ=5000 -gg_CHANNELS=4 -gg_COUNTER_BITS=32
echo "***********************************************************************************"
echo "clk_sys_freq = 10000, channels = 5, counter_bits=32"
ghdl -r --std=08 -frelaxed-rules $TB -gg_WITH_INTERNAL_TIMEBASE=TRUE -gg_CLK_SYS_FREQ=10000 -gg_CHANNELS=5 -gg_COUNTER_BITS=32
echo "***********************************************************************************"
echo "When g_WITH_INTERNAL_TIMEBASE = FALSE"
echo "clk_sys_freq = 500, channels = 2, counter_bits=32"
ghdl -r --std=08 -frelaxed-rules $TB -gg_WITH_INTERNAL_TIMEBASE=FALSE -gg_CLK_SYS_FREQ=500 -gg_CHANNELS=2 -gg_COUNTER_BITS=32
echo "***********************************************************************************"
echo "clk_sys_freq = 1000, channels = 3, counter_bits=32"
ghdl -r --std=08 -frelaxed-rules $TB -gg_WITH_INTERNAL_TIMEBASE=FALSE -gg_CLK_SYS_FREQ=1000 -gg_CHANNELS=3 -gg_COUNTER_BITS=32
echo "***********************************************************************************"
echo "clk_sys_freq = 5000, channels = 4, counter_bits=32"
ghdl -r --std=08 -frelaxed-rules $TB -gg_WITH_INTERNAL_TIMEBASE=FALSE -gg_CLK_SYS_FREQ=5000 -gg_CHANNELS=4 -gg_COUNTER_BITS=32
echo "***********************************************************************************"
echo "clk_sys_freq = 10000, channels = 5, counter_bits=32"
ghdl -r --std=08 -frelaxed-rules $TB -gg_WITH_INTERNAL_TIMEBASE=FALSE -gg_CLK_SYS_FREQ=10000 -gg_CHANNELS=5 -gg_COUNTER_BITS=32
echo "======================================"
echo "*When g_WITH_INTERNAL_TIMEBASE = TRUE*"
echo "======================================"
echo "clk_sys_freq = 500, sync_out = TRUE, counter_bits=32"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_WITH_INTERNAL_TIMEBASE=TRUE -gg_CLK_SYS_FREQ=500 -gg_CHANNELS=2 -gg_COUNTER_BITS=32
echo "******************************************************************************"
echo "clk_sys_freq = 1000, sync_out = FALSE, counter_bits=32"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_WITH_INTERNAL_TIMEBASE=TRUE -gg_CLK_SYS_FREQ=1000 -gg_CHANNELS=3 -gg_COUNTER_BITS=32
echo "******************************************************************************"
echo "clk_sys_freq = 5000, sync_out = TRUE, counter_bits=64"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_WITH_INTERNAL_TIMEBASE=TRUE -gg_CLK_SYS_FREQ=5000 -gg_CHANNELS=4 -gg_COUNTER_BITS=32
echo "******************************************************************************"
echo "clk_sys_freq = 10000, sync_out = FALSE, counter_bits=8"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_WITH_INTERNAL_TIMEBASE=TRUE -gg_CLK_SYS_FREQ=10000 -gg_CHANNELS=5 -gg_COUNTER_BITS=32
echo "******************************************************************************"
echo "======================================="
echo "*When g_WITH_INTERNAL_TIMEBASE = FALSE*"
echo "======================================="
echo "clk_sys_freq = 500, sync_out = TRUE, counter_bits=32"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_WITH_INTERNAL_TIMEBASE=FALSE -gg_CLK_SYS_FREQ=500 -gg_CHANNELS=2 -gg_COUNTER_BITS=32
echo "******************************************************************************"
echo "clk_sys_freq = 1000, sync_out = FALSE, counter_bits=32"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_WITH_INTERNAL_TIMEBASE=FALSE -gg_CLK_SYS_FREQ=1000 -gg_CHANNELS=3 -gg_COUNTER_BITS=32
echo "******************************************************************************"
echo "clk_sys_freq = 5000, sync_out = TRUE, counter_bits=64"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_WITH_INTERNAL_TIMEBASE=FALSE -gg_CLK_SYS_FREQ=5000 -gg_CHANNELS=4 -gg_COUNTER_BITS=32
echo "******************************************************************************"
echo "clk_sys_freq = 10000, sync_out = FALSE, counter_bits=8"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_WITH_INTERNAL_TIMEBASE=FALSE -gg_CLK_SYS_FREQ=10000 -gg_CHANNELS=5 -gg_COUNTER_BITS=32
echo "******************************************************************************"
......@@ -25,14 +25,9 @@
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
use std.env.finish;
library work;
use work.gencores_pkg.all;
--OSVVM
......@@ -42,6 +37,7 @@ use osvvm.CoveragePkg.all;
entity tb_gc_multichannel_frequency_meter is
generic (
g_seed : natural;
g_WITH_INTERNAL_TIMEBASE : boolean := true;
g_CLK_SYS_FREQ : integer;
g_COUNTER_BITS : integer := 32;
......@@ -50,13 +46,11 @@ end entity;
architecture tb of tb_gc_multichannel_frequency_meter is
--------------------------------------------------------------------------------
-- Constants and signals
--------------------------------------------------------------------------------
-- Constants
constant C_CLK_SYS_PERIOD : time := 8 ns;
constant C_CLK_IN_PERIOD : time := 10 ns;
-- Signals
signal tb_clk_sys_i : std_logic;
signal tb_clk_in_i : std_logic_vector(g_CHANNELS -1 downto 0) := (others=>'0');
signal tb_rst_n_i : std_logic;
......@@ -64,15 +58,14 @@ architecture tb of tb_gc_multichannel_frequency_meter is
signal tb_channel_sel_i : std_logic_vector(f_log2_ceil(g_CHANNELS)-1 downto 0) := (others=>'0');
signal tb_freq_o : std_logic_vector(g_COUNTER_BITS-1 downto 0);
signal tb_freq_valid_o : std_logic;
signal stop : boolean;
signal s_cnt_gate : unsigned(g_COUNTER_BITS-1 downto 0) := (others=>'0');
signal s_gate_pulse : std_logic := '0';
signal s_gate_pulse_synced : std_logic_vector(g_CHANNELS-1 downto 0) := (others=>'0');
signal s_data_o : std_logic_vector(g_COUNTER_BITS-1 downto 0) := (others=>'0');
signal s_freq_valid_o : std_logic:='0';
-- Types
type t_channel is record
cnt : unsigned(g_COUNTER_BITS-1 downto 0);
freq : unsigned(g_COUNTER_BITS-1 downto 0);
......@@ -86,9 +79,7 @@ architecture tb of tb_gc_multichannel_frequency_meter is
begin
--------------------------------------------------------------------------------
-- Unit Under Test
--------------------------------------------------------------------------------
UUT : entity work.gc_multichannel_frequency_meter
generic map (
g_WITH_INTERNAL_TIMEBASE => g_WITH_INTERNAL_TIMEBASE,
......@@ -104,11 +95,7 @@ begin
freq_o => tb_freq_o,
freq_valid_o => tb_freq_valid_o);
--------------------------------------------------------------------------------
-- Stimulus
--------------------------------------------------------------------------------
-- Clock and reset generation
-- Clock generation
clk_sys_proc : process
begin
while STOP = FALSE loop
......@@ -120,40 +107,20 @@ begin
wait;
end process clk_sys_proc;
-- Reset generation
tb_rst_n_i <= '0', '1' after 4*C_CLK_SYS_PERIOD;
-- Stimulus
stim : process
variable ncycles : natural;
variable v : RandomPType;
variable seed1, seed2 : integer := 888;
impure function rand_stdl(len:integer:=1) return std_logic is
variable r : real;
variable stdlog : std_logic;
begin
uniform(seed1,seed2,r);
stdlog:= '1' when r>0.5 else '0';
return stdlog;
end function;
impure function rand_slv(len:integer) return std_logic_vector is
variable r : real;
variable slv : std_logic_vector(len - 1 downto 0);
variable data : RandomPType;
begin
for i in slv'range loop
uniform(seed1, seed2, r);
slv(i) := '1' when r>0.5 else '0';
end loop;
return slv;
end function;
begin
while (NOW < 1 ms) loop
tb_clk_in_i <= rand_slv(g_CHANNELS);
data.InitSeed(g_seed);
report "[STARTING] with seed = " & to_string(g_seed);
while NOW < 2 ms loop
tb_clk_in_i <= data.randSlv(g_CHANNELS);
wait until (rising_edge(tb_clk_sys_i) and tb_rst_n_i = '1');
-- tb_pps_p1_i <= rand_stdl(1);
tb_channel_sel_i <= v.randslv(0,g_CHANNELS-1,f_log2_ceil(g_CHANNELS));
tb_channel_sel_i <= data.randslv(0,g_CHANNELS-1,f_log2_ceil(g_CHANNELS));
ncycles := ncycles + 1;
end loop;
report "Number of simulation cycles = " & to_string(ncycles);
......@@ -165,21 +132,12 @@ begin
-- Stimulus for pps_p1_i when time internal is FALSE
stim_when_false : if (g_WITH_INTERNAL_TIMEBASE = FALSE) generate
stim_false : process
variable seed1, seed2 : integer := 888;
impure function rand_stdl(len:integer:=1) return std_logic is
variable r : real;
variable stdlog : std_logic;
variable data : RandomPType;
begin
uniform(seed1,seed2,r);
stdlog:= '1' when r>0.5 else '0';
return stdlog;
end function;
begin
while (NOW < 1 ms) loop
data.InitSeed(g_seed);
while NOW < 2 ms loop
wait until rising_edge(tb_clk_sys_i) and s_ready_o='1';
tb_pps_p1_i <= rand_stdl(1);
tb_pps_p1_i <= data.randSlv(1)(1);
end loop;
wait;
end process;
......@@ -188,28 +146,19 @@ begin
-- Stimulus for pps_p1_i when time internal is TRUE
stim_when_true : if (g_WITH_INTERNAL_TIMEBASE = TRUE) generate
stim_false : process
variable seed1, seed2 : integer := 888;
impure function rand_stdl(len:integer:=1) return std_logic is
variable r : real;
variable stdlog : std_logic;
variable data : RandomPType;
begin
uniform(seed1,seed2,r);
stdlog:= '1' when r>0.5 else '0';
return stdlog;
end function;
begin
while (NOW < 1 ms) loop
data.InitSeed(g_seed);
while NOW < 2 ms loop
wait until (rising_edge(tb_clk_sys_i) and tb_rst_n_i='1');
tb_pps_p1_i <= rand_stdl(1);
tb_pps_p1_i <= data.randSlv(1)(1);
end loop;
wait;
end process;
end generate;
--------------------------------------------------------------------------------
-- Self-Checking and Assertions
-- Self-Checking and Assertions --
--------------------------------------------------------------------------------
-- Reproduce the behavior of the internal counter
......@@ -217,12 +166,12 @@ begin
internal_counter : process(tb_clk_sys_i)
begin
if (rising_edge(tb_clk_sys_i)) then
if (tb_rst_n_i = '0') then
if rising_edge(tb_clk_sys_i) then
if tb_rst_n_i = '0' then
s_cnt_gate <= (others=>'0');
s_gate_pulse <= '0';
else
if (s_cnt_gate = g_CLK_SYS_FREQ-1) then
if s_cnt_gate = g_CLK_SYS_FREQ-1 then
s_cnt_gate <= (others=>'0');
s_gate_pulse <= '1';
else
......@@ -232,6 +181,7 @@ begin
end if;
end if;
end process;
end generate with_internal_timebase;
-- Reproduce the RTL behavarior to generate self-check
......@@ -240,12 +190,12 @@ begin
internal_timebase : if (g_WITH_INTERNAL_TIMEBASE=TRUE) generate
synced_gate : process
begin
while (stop = FALSE) loop
wait until (falling_edge(s_gate_pulse));
wait until (rising_edge(tb_clk_in_i(i)));
wait until (rising_edge(tb_clk_in_i(i)));
while not stop loop
wait until falling_edge(s_gate_pulse);
wait until rising_edge(tb_clk_in_i(i));
wait until rising_edge(tb_clk_in_i(i));
s_gate_pulse_synced(i) <= tb_clk_in_i(i);
wait until (rising_edge(tb_clk_in_i(i)));
wait until rising_edge(tb_clk_in_i(i));
s_gate_pulse_synced(i) <= '0';
end loop;
end process;
......@@ -258,24 +208,20 @@ begin
clk_in_i => tb_clk_sys_i,
clk_out_i => tb_clk_in_i(i),
rst_n_i => tb_rst_n_i,
d_ready_o => s_ready_o, --open,
d_p_i => tb_pps_p1_i, --s_gate_pulse,
d_ready_o => s_ready_o,
d_p_i => tb_pps_p1_i,
q_p_o => s_gate_pulse_synced(i));
end generate;
freq_cnt : process(tb_clk_in_i(i),tb_rst_n_i)
begin
if (tb_rst_n_i = '0') then
if tb_rst_n_i = '0' then
ch(i).cnt <= (others=>'0');
ch(i).freq <= (others=>'0');
ch(i).freq_valid_o <= '0';
elsif (rising_edge(tb_clk_in_i(i))) then
if (s_gate_pulse_synced(i)) then
elsif rising_edge(tb_clk_in_i(i)) then
if s_gate_pulse_synced(i) then
ch(i).freq_valid_o <= '1';
ch(i).freq <= ch(i).cnt;
ch(i).cnt <= (others=>'0');
......@@ -300,16 +246,14 @@ begin
-- Check for valid number of channels
assert (g_CHANNELS > 1)
report "Invalid number of channels"
severity failure;
report "Invalid number of channels" severity failure;
-- Check if output is the expected, for TRUE it is OK
check_output : process(tb_clk_sys_i)
begin
if (rising_edge(tb_clk_sys_i) and tb_rst_n_i = '1') then
assert (s_data_o = tb_freq_o)
report "Mismatch in output"
severity failure;
report "Mismatch in output" severity failure;
end if;
end process;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment