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 ...@@ -6,32 +6,43 @@ TB=tb_gc_multichannel_frequency_meter
echo "Running simulation for $TB" echo "Running simulation for $TB"
echo "When g_WITH_INTERNAL_TIMEBASE = TRUE" echo "======================================"
echo "*When g_WITH_INTERNAL_TIMEBASE = TRUE*"
echo "clk_sys_freq = 500, channels = 2, counter_bits=32" echo "======================================"
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 = 500, sync_out = TRUE, counter_bits=32"
echo "clk_sys_freq = 1000, channels = 3, 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
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 "***********************************************************************************"
echo "clk_sys_freq = 5000, channels = 4, counter_bits=32" echo "clk_sys_freq = 1000, sync_out = FALSE, 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 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 "******************************************************************************"
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 "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 "******************************************************************************"
echo "When g_WITH_INTERNAL_TIMEBASE = FALSE" 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 "clk_sys_freq = 500, channels = 2, counter_bits=32" echo "******************************************************************************"
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 "======================================="
echo "clk_sys_freq = 1000, channels = 3, counter_bits=32" echo "*When g_WITH_INTERNAL_TIMEBASE = FALSE*"
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 "***********************************************************************************"
echo "clk_sys_freq = 5000, channels = 4, counter_bits=32" echo "clk_sys_freq = 500, sync_out = TRUE, 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 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 "******************************************************************************"
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 "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 @@ ...@@ -25,14 +25,9 @@
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
library ieee; library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.numeric_std.all; use ieee.numeric_std.all;
use ieee.math_real.all;
use std.env.finish;
library work;
use work.gencores_pkg.all; use work.gencores_pkg.all;
--OSVVM --OSVVM
...@@ -42,6 +37,7 @@ use osvvm.CoveragePkg.all; ...@@ -42,6 +37,7 @@ use osvvm.CoveragePkg.all;
entity tb_gc_multichannel_frequency_meter is entity tb_gc_multichannel_frequency_meter is
generic ( generic (
g_seed : natural;
g_WITH_INTERNAL_TIMEBASE : boolean := true; g_WITH_INTERNAL_TIMEBASE : boolean := true;
g_CLK_SYS_FREQ : integer; g_CLK_SYS_FREQ : integer;
g_COUNTER_BITS : integer := 32; g_COUNTER_BITS : integer := 32;
...@@ -50,13 +46,11 @@ end entity; ...@@ -50,13 +46,11 @@ end entity;
architecture tb of tb_gc_multichannel_frequency_meter is architecture tb of tb_gc_multichannel_frequency_meter is
-------------------------------------------------------------------------------- -- Constants
-- Constants and signals
--------------------------------------------------------------------------------
constant C_CLK_SYS_PERIOD : time := 8 ns; constant C_CLK_SYS_PERIOD : time := 8 ns;
constant C_CLK_IN_PERIOD : time := 10 ns; constant C_CLK_IN_PERIOD : time := 10 ns;
-- Signals
signal tb_clk_sys_i : std_logic; signal tb_clk_sys_i : std_logic;
signal tb_clk_in_i : std_logic_vector(g_CHANNELS -1 downto 0) := (others=>'0'); signal tb_clk_in_i : std_logic_vector(g_CHANNELS -1 downto 0) := (others=>'0');
signal tb_rst_n_i : std_logic; signal tb_rst_n_i : std_logic;
...@@ -64,15 +58,14 @@ architecture tb of tb_gc_multichannel_frequency_meter is ...@@ -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_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_o : std_logic_vector(g_COUNTER_BITS-1 downto 0);
signal tb_freq_valid_o : std_logic; signal tb_freq_valid_o : std_logic;
signal stop : boolean; signal stop : boolean;
signal s_cnt_gate : unsigned(g_COUNTER_BITS-1 downto 0) := (others=>'0'); signal s_cnt_gate : unsigned(g_COUNTER_BITS-1 downto 0) := (others=>'0');
signal s_gate_pulse : std_logic := '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_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_data_o : std_logic_vector(g_COUNTER_BITS-1 downto 0) := (others=>'0');
signal s_freq_valid_o : std_logic:='0'; signal s_freq_valid_o : std_logic:='0';
-- Types
type t_channel is record type t_channel is record
cnt : unsigned(g_COUNTER_BITS-1 downto 0); cnt : unsigned(g_COUNTER_BITS-1 downto 0);
freq : 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 ...@@ -86,9 +79,7 @@ architecture tb of tb_gc_multichannel_frequency_meter is
begin begin
--------------------------------------------------------------------------------
-- Unit Under Test -- Unit Under Test
--------------------------------------------------------------------------------
UUT : entity work.gc_multichannel_frequency_meter UUT : entity work.gc_multichannel_frequency_meter
generic map ( generic map (
g_WITH_INTERNAL_TIMEBASE => g_WITH_INTERNAL_TIMEBASE, g_WITH_INTERNAL_TIMEBASE => g_WITH_INTERNAL_TIMEBASE,
...@@ -104,11 +95,7 @@ begin ...@@ -104,11 +95,7 @@ begin
freq_o => tb_freq_o, freq_o => tb_freq_o,
freq_valid_o => tb_freq_valid_o); freq_valid_o => tb_freq_valid_o);
-------------------------------------------------------------------------------- -- Clock generation
-- Stimulus
--------------------------------------------------------------------------------
-- Clock and reset generation
clk_sys_proc : process clk_sys_proc : process
begin begin
while STOP = FALSE loop while STOP = FALSE loop
...@@ -120,40 +107,20 @@ begin ...@@ -120,40 +107,20 @@ begin
wait; wait;
end process clk_sys_proc; end process clk_sys_proc;
-- Reset generation
tb_rst_n_i <= '0', '1' after 4*C_CLK_SYS_PERIOD; tb_rst_n_i <= '0', '1' after 4*C_CLK_SYS_PERIOD;
-- Stimulus -- Stimulus
stim : process stim : process
variable ncycles : natural; variable ncycles : natural;
variable v : RandomPType; variable data : 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);
begin begin
for i in slv'range loop data.InitSeed(g_seed);
uniform(seed1, seed2, r); report "[STARTING] with seed = " & to_string(g_seed);
slv(i) := '1' when r>0.5 else '0'; while NOW < 2 ms loop
end loop; tb_clk_in_i <= data.randSlv(g_CHANNELS);
return slv;
end function;
begin
while (NOW < 1 ms) loop
tb_clk_in_i <= rand_slv(g_CHANNELS);
wait until (rising_edge(tb_clk_sys_i) and tb_rst_n_i = '1'); 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 <= data.randslv(0,g_CHANNELS-1,f_log2_ceil(g_CHANNELS));
tb_channel_sel_i <= v.randslv(0,g_CHANNELS-1,f_log2_ceil(g_CHANNELS));
ncycles := ncycles + 1; ncycles := ncycles + 1;
end loop; end loop;
report "Number of simulation cycles = " & to_string(ncycles); report "Number of simulation cycles = " & to_string(ncycles);
...@@ -165,21 +132,12 @@ begin ...@@ -165,21 +132,12 @@ begin
-- Stimulus for pps_p1_i when time internal is FALSE -- Stimulus for pps_p1_i when time internal is FALSE
stim_when_false : if (g_WITH_INTERNAL_TIMEBASE = FALSE) generate stim_when_false : if (g_WITH_INTERNAL_TIMEBASE = FALSE) generate
stim_false : process stim_false : process
variable seed1, seed2 : integer := 888; variable data : RandomPType;
impure function rand_stdl(len:integer:=1) return std_logic is
variable r : real;
variable stdlog : std_logic;
begin begin
uniform(seed1,seed2,r); data.InitSeed(g_seed);
stdlog:= '1' when r>0.5 else '0'; while NOW < 2 ms loop
return stdlog;
end function;
begin
while (NOW < 1 ms) loop
wait until rising_edge(tb_clk_sys_i) and s_ready_o='1'; 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; end loop;
wait; wait;
end process; end process;
...@@ -188,28 +146,19 @@ begin ...@@ -188,28 +146,19 @@ begin
-- Stimulus for pps_p1_i when time internal is TRUE -- Stimulus for pps_p1_i when time internal is TRUE
stim_when_true : if (g_WITH_INTERNAL_TIMEBASE = TRUE) generate stim_when_true : if (g_WITH_INTERNAL_TIMEBASE = TRUE) generate
stim_false : process stim_false : process
variable seed1, seed2 : integer := 888; variable data : RandomPType;
impure function rand_stdl(len:integer:=1) return std_logic is
variable r : real;
variable stdlog : std_logic;
begin begin
uniform(seed1,seed2,r); data.InitSeed(g_seed);
stdlog:= '1' when r>0.5 else '0'; while NOW < 2 ms loop
return stdlog;
end function;
begin
while (NOW < 1 ms) loop
wait until (rising_edge(tb_clk_sys_i) and tb_rst_n_i='1'); 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; end loop;
wait; wait;
end process; end process;
end generate; end generate;
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Self-Checking and Assertions -- Self-Checking and Assertions --
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Reproduce the behavior of the internal counter -- Reproduce the behavior of the internal counter
...@@ -217,12 +166,12 @@ begin ...@@ -217,12 +166,12 @@ begin
internal_counter : process(tb_clk_sys_i) internal_counter : process(tb_clk_sys_i)
begin begin
if (rising_edge(tb_clk_sys_i)) then if rising_edge(tb_clk_sys_i) then
if (tb_rst_n_i = '0') then if tb_rst_n_i = '0' then
s_cnt_gate <= (others=>'0'); s_cnt_gate <= (others=>'0');
s_gate_pulse <= '0'; s_gate_pulse <= '0';
else 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_cnt_gate <= (others=>'0');
s_gate_pulse <= '1'; s_gate_pulse <= '1';
else else
...@@ -232,6 +181,7 @@ begin ...@@ -232,6 +181,7 @@ begin
end if; end if;
end if; end if;
end process; end process;
end generate with_internal_timebase; end generate with_internal_timebase;
-- Reproduce the RTL behavarior to generate self-check -- Reproduce the RTL behavarior to generate self-check
...@@ -240,12 +190,12 @@ begin ...@@ -240,12 +190,12 @@ begin
internal_timebase : if (g_WITH_INTERNAL_TIMEBASE=TRUE) generate internal_timebase : if (g_WITH_INTERNAL_TIMEBASE=TRUE) generate
synced_gate : process synced_gate : process
begin begin
while (stop = FALSE) loop while not stop loop
wait until (falling_edge(s_gate_pulse)); 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));
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); 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'; s_gate_pulse_synced(i) <= '0';
end loop; end loop;
end process; end process;
...@@ -258,24 +208,20 @@ begin ...@@ -258,24 +208,20 @@ begin
clk_in_i => tb_clk_sys_i, clk_in_i => tb_clk_sys_i,
clk_out_i => tb_clk_in_i(i), clk_out_i => tb_clk_in_i(i),
rst_n_i => tb_rst_n_i, rst_n_i => tb_rst_n_i,
d_ready_o => s_ready_o, --open, d_ready_o => s_ready_o,
d_p_i => tb_pps_p1_i, --s_gate_pulse, d_p_i => tb_pps_p1_i,
q_p_o => s_gate_pulse_synced(i)); q_p_o => s_gate_pulse_synced(i));
end generate; end generate;
freq_cnt : process(tb_clk_in_i(i),tb_rst_n_i) freq_cnt : process(tb_clk_in_i(i),tb_rst_n_i)
begin begin
if (tb_rst_n_i = '0') then if tb_rst_n_i = '0' then
ch(i).cnt <= (others=>'0'); ch(i).cnt <= (others=>'0');
ch(i).freq <= (others=>'0'); ch(i).freq <= (others=>'0');
ch(i).freq_valid_o <= '0'; ch(i).freq_valid_o <= '0';
elsif rising_edge(tb_clk_in_i(i)) then
elsif (rising_edge(tb_clk_in_i(i))) then if s_gate_pulse_synced(i) then
if (s_gate_pulse_synced(i)) then
ch(i).freq_valid_o <= '1'; ch(i).freq_valid_o <= '1';
ch(i).freq <= ch(i).cnt; ch(i).freq <= ch(i).cnt;
ch(i).cnt <= (others=>'0'); ch(i).cnt <= (others=>'0');
...@@ -300,16 +246,14 @@ begin ...@@ -300,16 +246,14 @@ begin
-- Check for valid number of channels -- Check for valid number of channels
assert (g_CHANNELS > 1) assert (g_CHANNELS > 1)
report "Invalid number of channels" report "Invalid number of channels" severity failure;
severity failure;
-- Check if output is the expected, for TRUE it is OK -- Check if output is the expected, for TRUE it is OK
check_output : process(tb_clk_sys_i) check_output : process(tb_clk_sys_i)
begin begin
if (rising_edge(tb_clk_sys_i) and tb_rst_n_i = '1') then if (rising_edge(tb_clk_sys_i) and tb_rst_n_i = '1') then
assert (s_data_o = tb_freq_o) assert (s_data_o = tb_freq_o)
report "Mismatch in output" report "Mismatch in output" severity failure;
severity failure;
end if; end if;
end process; 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