Commit 1a4f47bb authored by CI's avatar CI

Simple cleanup and README added

parent 45518da1
Pipeline #3602 passed with stage
in 27 minutes and 52 seconds
......@@ -51,13 +51,13 @@ begin
assert g_CLOCK_EDGE = "positive" or g_CLOCK_EDGE = "negative" severity FAILURE;
gen_pos_pulse : if g_PULSE_EDGE = "positive" generate
pulse_o <= data_i and not dff;
pulse_o <= data_i and not dff;
end generate gen_pos_pulse;
gen_neg_pulse : if g_PULSE_EDGE = "negative" generate
pulse_o <= not data_i and dff;
end generate gen_neg_pulse;
gen_async_rst : if g_ASYNC_RST = TRUE generate
sync_posedge : if g_CLOCK_EDGE = "positive" generate
......
This is a simple testbench which uses GHDL simulator and OSVVM verification methodology. The goal is to verify the functionality of the gc_negedge (a simple falling edge detector). Through OSVVM, we can achieve randomization of the input data, with randomized seed value. The test cases of the testbench are defined through the different values assigned to the entity's generics.
The generics of this core are the following:
- g_async_rst : Synchronous or asynchronous reset
- g_clock_edge : Clock edge sensitivity of edge detection
Regarding on the values of the above generics, there are the following test cases:
1. TRUE, positive
2. TRUE, negative
3. FALSE, positive
4. FALSE, negative
Assertions are used to provide a self-checking approach. These are:
- The width of the output pulse is always one clock cycle long
- To always detect a negative edge of a falling input data signal
Coverage that is being covered:
- Reset has been asserted
- Input pulse detected
- Output pulse detected
Note: The values of the two last coverage bins are different because the input signal width is not always one clock cycle long
#!/bin/bash
#This is a simple script to run simulations
#in GHDL
#This is a simple script to run simulations in GHDL
TB=tb_gc_negedge
echo "Running simulation for $TB"
echo " TEST CASE 1 "
echo "ASYNC_RST=TRUE, CLOCK_EDGE=positive"
ghdl -r --std=08 -frelaxed-rules $TB -gg_ASYNC_RST=TRUE -gg_CLOCK_EDGE=positive
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_ASYNC_RST=TRUE -gg_CLOCK_EDGE=positive
echo "******************************************************************************************"
echo " TEST CASE 2 "
echo "ASYNC_RST=TRUE, CLOCK_EDGE=negative"
ghdl -r --std=08 -frelaxed-rules $TB -gg_ASYNC_RST=TRUE -gg_CLOCK_EDGE=negative
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_ASYNC_RST=TRUE -gg_CLOCK_EDGE=negative
echo "******************************************************************************************"
echo " TEST CASE 3 "
echo "ASYNC_RST=FALSE, CLOCK_EDGE=positive"
ghdl -r --std=08 -frelaxed-rules $TB -gg_ASYNC_RST=FALSE -gg_CLOCK_EDGE=positive
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_ASYNC_RST=FALSE -gg_CLOCK_EDGE=positive
echo "******************************************************************************************"
echo " TEST CASE 4 "
echo "ASYNC_RST=FALSE, CLOCK_EDGE=negative"
ghdl -r --std=08 -frelaxed-rules $TB -gg_ASYNC_RST=FALSE -gg_CLOCK_EDGE=negative
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_ASYNC_RST=FALSE -gg_CLOCK_EDGE=negative
echo "******************************************************************************************"
......@@ -28,141 +28,130 @@ library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
use std.env.finish;
-- OSVVM library
library osvvm;
use osvvm.RandomPkg.all;
use osvvm.CoveragePkg.all;
entity tb_gc_negedge is
generic (
g_ASYNC_RST : boolean := FALSE;
g_CLOCK_EDGE : string := "positive");
generic (
g_seed : natural;
g_ASYNC_RST : boolean := FALSE;
g_CLOCK_EDGE : string := "positive");
end entity;
architecture tb of tb_gc_negedge is
-- Constants
constant C_CLK_PERIOD : time := 10 ns;
-- Signals
signal tb_clk_i : std_logic;
signal tb_rst_n_i : std_logic;
signal tb_data_i : std_logic := '0';
signal tb_pulse_o : std_logic;
signal stop : boolean;
-- Variables used for coverage
shared variable cp_rst_i : covPType;
shared variable cp_data_i : covPType;
shared variable cp_pulse_o: covPType;
-- Constants
constant C_CLK_PERIOD : time := 10 ns;
-- Signals
signal tb_clk_i : std_logic;
signal tb_rst_n_i : std_logic;
signal tb_data_i : std_logic := '0';
signal tb_pulse_o : std_logic;
signal stop : boolean;
-- Variables used for coverage
shared variable cp_rst_i : covPType;
shared variable cp_data_i : covPType;
shared variable cp_pulse_o: covPType;
begin
-- Unit Under Test
UUT : entity work.gc_negedge
generic map (
g_ASYNC_RST => g_ASYNC_RST,
g_CLOCK_EDGE => g_CLOCK_EDGE)
port map (
clk_i => tb_clk_i,
rst_n_i => tb_rst_n_i,
data_i => tb_data_i,
pulse_o => tb_pulse_o);
-- Clock and reset generation
-- Unit Under Test
UUT : entity work.gc_negedge
generic map (
g_ASYNC_RST => g_ASYNC_RST,
g_CLOCK_EDGE => g_CLOCK_EDGE)
port map (
clk_i => tb_clk_i,
rst_n_i => tb_rst_n_i,
data_i => tb_data_i,
pulse_o => tb_pulse_o);
-- Clock generation
clk_proc : process
begin
while STOP = FALSE loop
tb_clk_i <= '1';
wait for C_CLK_PERIOD/2;
tb_clk_i <= '0';
wait for C_CLK_PERIOD/2;
while STOP = FALSE loop
tb_clk_i <= '1';
wait for C_CLK_PERIOD/2;
tb_clk_i <= '0';
wait for C_CLK_PERIOD/2;
end loop;
wait;
end process clk_proc;
-- Reset generation
tb_rst_n_i <= '0', '1' after 4*C_CLK_PERIOD;
-- Stimulus
-- Stimulus
stim : process
variable ncycles : natural;
variable seed1, seed2 : integer := 1992;
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;
variable ncycles : natural;
variable data : RandomPType;
begin
wait until (tb_rst_n_i='1');
while (NOW < 1 ms) loop
wait until (rising_edge(tb_clk_i));
tb_data_i <= rand_stdl(1);
ncycles := ncycles + 1;
data.InitSeed(g_seed);
report "[STARTING] with seed = " & to_string(g_seed);
wait until tb_rst_n_i='1';
while NOW < 4 ms loop
wait until rising_edge(tb_clk_i);
tb_data_i <= data.randSlv(1)(1);
ncycles := ncycles + 1;
end loop;
report "Number of simulation cycles = " & to_string(ncycles);
stop <= TRUE;
report "Test PASS!";
report "Test PASS!";
wait;
end process;
--------------------------------------------------------------------------------
-- Assertions
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Assertions --
--------------------------------------------------------------------------------
--Assertion to check that the width of the output pulse
--is asserted for only one clock cycle
one_clk_width : process
begin
if (rising_edge(tb_clk_i)) then
if (tb_pulse_o = '1') then
wait for C_CLK_PERIOD;
assert (tb_pulse_o = '0')
report "output pulse remains high for more than one clock"
severity failure;
end if;
end if;
wait;
end process;
-- Check that the output pulse is asserted
-- in the falling edge of the input pulse
check_edge : process
begin
if (rising_edge(tb_clk_i)) then
wait until (falling_edge(tb_data_i));
assert (rising_edge(tb_pulse_o))
report "Negative edge didn't detect"
severity failure;
end if;
wait;
end process;
--------------------------------------------------------------------------------
-- Coverage
--------------------------------------------------------------------------------
--sets up coverpoint bins
-- Assertion to check that the width of the output pulse
-- is asserted for only one clock cycle
one_clk_width : process
begin
while not stop loop
wait until rising_edge(tb_clk_i);
if tb_pulse_o = '1' then
wait for C_CLK_PERIOD;
assert (tb_pulse_o = '0')
report "output pulse remains high for more than one clock"
severity error;
end if;
end loop;
wait;
end process;
-- Check that the output pulse is asserted
-- in the falling edge of the input pulse
check_negedge : process
begin
while not stop loop
wait until falling_edge(tb_data_i);
wait for 0 ns; --wait for delta time
assert (tb_pulse_o='1')
report "Negative edge didn't detect" severity failure;
end loop;
wait;
end process;
--------------------------------------------------------------------------------
-- Coverage --
--------------------------------------------------------------------------------
--sets up coverpoint bins
init_coverage : process
begin
cp_rst_i.AddBins("reset has asserted", ONE_BIN);
cp_data_i.AddBins("Input pulse detected", ONE_BIN);
cp_pulse_o.AddBins("Output pulse detected", ONE_BIN);
cp_data_i.AddBins("Input pulse detected", ONE_BIN);
cp_pulse_o.AddBins("Output pulse detected", ONE_BIN);
wait;
end process init_coverage;
-- Sample the coverpoints
-- sample coverpoints for reset
sample_rst_n_i : process
-- sample coverpoints for reset
sample_rst_n_i : process
begin
loop
wait on tb_rst_n_i;
......@@ -171,42 +160,42 @@ begin
end loop;
end process;
-- sample coverpoints for input data
sample_data_i : process(tb_clk_i)
-- sample coverpoints for input data
sample_data_i : process(tb_clk_i)
begin
if rising_edge(tb_clk_i) then
cp_data_i.ICover(to_integer(tb_data_i='1'));
end if;
end process;
-- sample coverpoints for output pulse
clock_edge_pos : if (g_CLOCK_EDGE="positive") generate
sample_pulse_o : process(tb_clk_i)
begin
if rising_edge(tb_clk_i) then
cp_pulse_o.ICover(to_integer(tb_pulse_o='1'));
end if;
end process;
end generate;
clock_edge_neg : if (g_CLOCK_EDGE="negative") generate
sample_pulse_o : process
begin
if (rising_edge(tb_clk_i)) then
cp_data_i.ICover(to_integer(tb_data_i='1'));
end if;
loop
wait until (falling_edge(tb_clk_i));
cp_pulse_o.ICover(to_integer(tb_pulse_o='1'));
end loop;
wait;
end process;
end generate;
-- sample coverpoints for output pulse
clock_edge_pos : if (g_CLOCK_EDGE="positive") generate
sample_pulse_o : process(tb_clk_i)
begin
if (rising_edge(tb_clk_i)) then
cp_pulse_o.ICover(to_integer(tb_pulse_o='1'));
end if;
end process;
end generate;
clock_edge_neg : if (g_CLOCK_EDGE="negative") generate
sample_pulse_o : process
begin
loop
wait until (falling_edge(tb_clk_i));
cp_pulse_o.ICover(to_integer(tb_pulse_o='1'));
end loop;
wait;
end process;
end generate;
-- Coverage report
cover_report: process
-- Coverage report
cover_report: process
begin
wait until stop;
cp_rst_i.writebin;
cp_data_i.writebin;
cp_pulse_o.writebin;
cp_data_i.writebin;
cp_pulse_o.writebin;
report "PASS";
end process;
......
This is a simple testbench which uses GHDL simulator and OSVVM verification methodology. The goal is to verify the functionality of the gc_posedge (a simple positive edge detector). Through OSVVM, we can achieve randomization of the input data, with randomized seed value. The test cases of the testbench are defined through the different values assigned to the entity's generics.
The generics of this core are the following:
- g_async_rst : Synchronous or asynchronous reset
- g_clock_edge : Clock edge sensitivity of edge detection
Regarding on the values of the above generics, there are the following test cases:
1. TRUE, positive
2. TRUE, negative
3. FALSE, positive
4. FALSE, negative
Assertions are used to provide a self-checking approach. These are:
- The width of the output pulse is always one clock cycle long
- To always detect a positive edge of a rising input data signal
Coverage that is being covered:
- Reset has been asserted
- Input pulse detected
- Output pulse detected
Note: The values of the two last coverage bins are different because the input signal width is not always one clock cycle long
#!/bin/bash
#This is a simple script to run simulations
#in GHDL
#This is a simple script to run simulations in GHDL
TB=tb_gc_posedge
echo "Running simulation for $TB"
echo " TEST CASE 1 "
echo "ASYNC_RST=TRUE, CLOCK_EDGE=positive"
ghdl -r --std=08 -frelaxed-rules $TB -gg_ASYNC_RST=TRUE -gg_CLOCK_EDGE=positive
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_ASYNC_RST=TRUE -gg_CLOCK_EDGE="positive" --wave=waveform1.ghw
echo "******************************************************************************************"
echo " TEST CASE 2 "
echo "ASYNC_RST=TRUE, CLOCK_EDGE=negative"
ghdl -r --std=08 -frelaxed-rules $TB -gg_ASYNC_RST=TRUE -gg_CLOCK_EDGE=negative
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_ASYNC_RST=TRUE -gg_CLOCK_EDGE="negative" --wave=waveform2.ghw
echo "******************************************************************************************"
echo " TEST CASE 3 "
echo "ASYNC_RST=FALSE, CLOCK_EDGE=positive"
ghdl -r --std=08 -frelaxed-rules $TB -gg_ASYNC_RST=FALSE -gg_CLOCK_EDGE=positive
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_ASYNC_RST=FALSE -gg_CLOCK_EDGE="positive" --wave=waveform3.ghw
echo "******************************************************************************************"
echo " TEST CASE 4 "
echo "ASYNC_RST=FALSE, CLOCK_EDGE=negative"
ghdl -r --std=08 -frelaxed-rules $TB -gg_ASYNC_RST=FALSE -gg_CLOCK_EDGE=negative
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_ASYNC_RST=FALSE -gg_CLOCK_EDGE="negative" --wave=waveform4.ghw
echo "******************************************************************************************"
......@@ -28,186 +28,175 @@ library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
use std.env.finish;
-- OSVVM library
library osvvm;
use osvvm.RandomPkg.all;
use osvvm.CoveragePkg.all;
entity tb_gc_posedge is
generic (
g_ASYNC_RST : boolean := FALSE;
g_CLOCK_EDGE : string := "positive");
generic (
g_seed : natural;
g_ASYNC_RST : boolean;
g_CLOCK_EDGE : string);
end entity;
architecture tb of tb_gc_posedge is
-- constants
constant C_CLK_PERIOD : time := 10 ns;
-- Signals
signal tb_clk_i : std_logic;
signal tb_rst_n_i : std_logic;
signal tb_data_i : std_logic := '0';
signal tb_pulse_o : std_logic;
signal stop : boolean;
-- Variables used for coverage
shared variable cp_rst_i : covPType;
shared variable cp_data_i : covPType;
shared variable cp_pulse_o: covPType;
-- Constants
constant C_CLK_PERIOD : time := 10 ns;
-- Signals
signal tb_clk_i : std_logic;
signal tb_rst_n_i : std_logic;
signal tb_data_i : std_logic := '0';
signal tb_pulse_o : std_logic;
signal stop : boolean;
-- Variables used for coverage
shared variable cp_rst_i : covPType;
shared variable cp_data_i : covPType;
shared variable cp_pulse_o: covPType;
begin
-- Unit Under Test
UUT : entity work.gc_negedge
generic map (
g_ASYNC_RST => g_ASYNC_RST,
g_CLOCK_EDGE => g_CLOCK_EDGE)
port map (
clk_i => tb_clk_i,
rst_n_i => tb_rst_n_i,
data_i => tb_data_i,
pulse_o => tb_pulse_o);
-- Clock and reset generation
-- Unit Under Test
UUT : entity work.gc_posedge
generic map (
g_ASYNC_RST => g_ASYNC_RST,
g_CLOCK_EDGE => g_CLOCK_EDGE)
port map (
clk_i => tb_clk_i,
rst_n_i => tb_rst_n_i,
data_i => tb_data_i,
pulse_o => tb_pulse_o);
-- Clock generation
clk_proc : process
begin
while STOP = FALSE loop
tb_clk_i <= '1';
wait for C_CLK_PERIOD/2;
tb_clk_i <= '0';
wait for C_CLK_PERIOD/2;
while STOP = FALSE loop
tb_clk_i <= '1';
wait for C_CLK_PERIOD/2;
tb_clk_i <= '0';
wait for C_CLK_PERIOD/2;
end loop;
wait;
end process clk_proc;
-- Reset generation
tb_rst_n_i <= '0', '1' after 4*C_CLK_PERIOD;
-- Stimulus
stim : process
variable ncycles : natural;
variable seed1, seed2 : integer := 1992;
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;
-- Stimulus
stim : process
variable ncycles : natural;
variable data : RandomPType;
begin
wait until (tb_rst_n_i='1');
while (NOW < 1 ms) loop
wait until (rising_edge(tb_clk_i));
tb_data_i <= rand_stdl(1);
ncycles := ncycles + 1;
data.InitSeed(g_seed);
report "[STARTING] with seed = " & to_string(g_seed);
wait until tb_rst_n_i='1';
while NOW < 2 ms loop
wait until rising_edge(tb_clk_i);
tb_data_i <= data.randSlv(1)(1);
ncycles := ncycles + 1;
end loop;
report "Number of simulation cycles = " & to_string(ncycles);
stop <= TRUE;
report "Test PASS!";
report "Test PASS!";
wait;
end process;
--------------------------------------------------------------------------------
-- Assertions
--------------------------------------------------------------------------------
--Assertion to check that the width of the output pulse
--is asserted for only one clock cycle
one_clk_width : process
begin
if (rising_edge(tb_clk_i)) then
if (tb_pulse_o = '1') then
wait for C_CLK_PERIOD;
assert (tb_pulse_o = '0')
report "output pulse remains high for more than one clock"
severity failure;
end if;
end if;
wait;
end process;
-- Check that the output pulse is asserted
-- in the falling edge of the input pulse
check_edge : process
begin
if (rising_edge(tb_clk_i)) then
wait until (falling_edge(tb_data_i));
assert (rising_edge(tb_pulse_o))
report "Negative edge didn't detect"
severity failure;
end if;
wait;
end process;
--------------------------------------------------------------------------------
-- Coverage
--------------------------------------------------------------------------------
--sets up coverpoint bins
--------------------------------------------------------------------------------
-- Assertions --
--------------------------------------------------------------------------------
--Assertion to check that the width of the output pulse
--is asserted for only one clock cycle
one_clk_width : process
begin
while not stop loop
wait until rising_edge(tb_clk_i);
if tb_pulse_o = '1' then
wait for C_CLK_PERIOD;
assert (tb_pulse_o = '0')
report "output pulse remains high for more than one clock"
severity failure;
end if;
end loop;
wait;
end process;
-- Check that the output pulse is asserted
-- in the rising edge of the input pulse
check_edge : process
begin
while not stop loop
wait until rising_edge(tb_data_i);
wait for 0 ns; --wait for delta time
assert (tb_pulse_o = '1')
report "Positive edge didn't detect"
severity failure;
end loop;
wait;
end process;
--------------------------------------------------------------------------------
-- Coverage --
--------------------------------------------------------------------------------
--sets up coverpoint bins
init_coverage : process
begin
cp_rst_i.AddBins("reset has asserted", ONE_BIN);
cp_data_i.AddBins("Input pulse detected", ONE_BIN);
cp_pulse_o.AddBins("Output pulse detected", ONE_BIN);
cp_data_i.AddBins("Input pulse detected", ONE_BIN);
cp_pulse_o.AddBins("Output pulse detected", ONE_BIN);
wait;
end process init_coverage;
-- Sample the coverpoints
-- sample coverpoints for reset
sample_rst_n_i : process
-- sample coverpoints for reset
sample_rst_n_i : process
begin
loop
wait on tb_rst_n_i;
wait for C_CLK_PERIOD;
cp_rst_i.ICover(to_integer(tb_rst_n_i = '1'));
end loop;
loop
wait on tb_rst_n_i;
wait for C_CLK_PERIOD;
cp_rst_i.ICover(to_integer(tb_rst_n_i = '1'));
end loop;
end process;
-- sample coverpoints for input data
sample_data_i : process(tb_clk_i)
-- sample coverpoints for input data
sample_data_i : process(tb_clk_i)
begin
if rising_edge(tb_clk_i) then
cp_data_i.ICover(to_integer(tb_data_i='1'));
end if;
end process;
-- sample coverpoints for output pulse
clock_edge_pos : if (g_CLOCK_EDGE="positive") generate
sample_pulse_o : process(tb_clk_i)
begin
if (rising_edge(tb_clk_i)) then
cp_pulse_o.ICover(to_integer(tb_pulse_o='1'));
end if;
end process;
end generate;
clock_edge_neg : if (g_CLOCK_EDGE="negative") generate
sample_pulse_o : process
begin
if (rising_edge(tb_clk_i)) then
cp_data_i.ICover(to_integer(tb_data_i='1'));
end if;
loop
wait until (falling_edge(tb_clk_i));
cp_pulse_o.ICover(to_integer(tb_pulse_o='1'));
end loop;
wait;
end process;
end generate;
-- sample coverpoints for output pulse
clock_edge_pos : if (g_CLOCK_EDGE="positive") generate
sample_pulse_o : process(tb_clk_i)
begin
if (rising_edge(tb_clk_i)) then
cp_pulse_o.ICover(to_integer(tb_pulse_o='1'));
end if;
end process;
end generate;
clock_edge_neg : if (g_CLOCK_EDGE="negative") generate
sample_pulse_o : process
begin
loop
wait until (falling_edge(tb_clk_i));
cp_pulse_o.ICover(to_integer(tb_pulse_o='1'));
end loop;
wait;
end process;
end generate;
-- Coverage report
cover_report: process
-- Coverage report
cover_report: process
begin
wait until stop;
cp_rst_i.writebin;
cp_data_i.writebin;
cp_pulse_o.writebin;
report "PASS";
cp_data_i.writebin;
cp_pulse_o.writebin;
end process;
end tb;
Testbench to verify the functionality of the gc_prio_encoder general core. It receives randomized input signals with random seed. It consist of 6 test cases (can be extented to more) regarding the incoming data width. These test cases are:
1. g_width = 1
2. g_width = 3
3. g_width = 7
4. g_width = 16
5. g_width = 31
6. g_width = 128
This testbench is using the simple logic of the priority encoder, like in the RTL code. The result is stored in a vector and then it is being compared with the one which coming from the RTL core.
Assertions are being used for better self-checking purposes. First of all, it checks if there is a mismatch between the output data of the testbench and RTL code. In addition, the other assertion, checks if the generic value is valid (should be 1 or higher).
......@@ -7,26 +7,26 @@ TB=tb_gc_prio_encoder
echo "Running simulation for $TB"
echo "Width = 1"
ghdl -r --std=08 -frelaxed-rules $TB -gg_width=1
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_width=1
echo "********************************************************************************"
echo "Width = 3"
ghdl -r --std=08 -frelaxed-rules $TB -gg_width=3
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_width=3 --wave=waveform.ghw
echo "********************************************************************************"
echo "Width = 7"
ghdl -r --std=08 -frelaxed-rules $TB -gg_width=7
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_width=7
echo "********************************************************************************"
echo "Width = 16"
ghdl -r --std=08 -frelaxed-rules $TB -gg_width=16
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_width=16
echo "********************************************************************************"
echo "Width = 31"
ghdl -r --std=08 -frelaxed-rules $TB -gg_width=31
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_width=31
echo "********************************************************************************"
echo "Width = 128"
ghdl -r --std=08 -frelaxed-rules $TB -gg_width=128
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_width=128
echo "********************************************************************************"
......@@ -30,122 +30,109 @@ library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
use std.env.finish;
-- OSVVM library
--library osvvm;
--use osvvm.RandomPkg.all;
--use osvvm.CoveragePkg.all;
library osvvm;
use osvvm.RandomPkg.all;
use osvvm.CoveragePkg.all;
entity tb_gc_prio_encoder is
generic (
g_width : integer := 32);
generic (
g_seed : natural;
g_width : integer := 32);
end entity;
architecture tb of tb_gc_prio_encoder is
-- functions
function f_count_stages(width : integer) return integer is
begin
if(width <= 2) then
return 2;
elsif(width <= 4) then
return 3;
elsif(width <= 8) then
return 4;
elsif(width <= 16) then
return 5;
elsif(width <= 32) then
return 6;
elsif(width <= 64) then
return 7;
elsif(width <= 128) then
return 8;
else
return 0;
end if;
end f_count_stages;
-- constants
constant C_STAGES : integer := f_count_stages(g_width);
-- signals
signal tb_d_i : std_logic_vector(g_width-1 downto 0) := (others=>'0');
signal tb_therm_o : std_logic_vector(g_width-1 downto 0);
signal stop : boolean;
type t_stages_array is array (0 to C_STAGES) of std_logic_vector(g_width-1 downto 0);
signal s_stage : t_stages_array;
signal s_data_o : std_logic_vector(g_width-1 downto 0);
-- functions
function f_count_stages(width : integer) return integer is
begin
if(width <= 2) then
return 2;
elsif(width <= 4) then
return 3;
elsif(width <= 8) then
return 4;
elsif(width <= 16) then
return 5;
elsif(width <= 32) then
return 6;
elsif(width <= 64) then
return 7;
elsif(width <= 128) then
return 8;
else
return 0;
end if;
end f_count_stages;
-- constants
constant C_STAGES : integer := f_count_stages(g_width);
-- signals
signal tb_d_i : std_logic_vector(g_width-1 downto 0) := (others=>'0');
signal tb_therm_o : std_logic_vector(g_width-1 downto 0);
signal stop : boolean;
type t_stages_array is array (0 to C_STAGES) of std_logic_vector(g_width-1 downto 0);
signal s_stage : t_stages_array;
signal s_data_o : std_logic_vector(g_width-1 downto 0);
begin
-- Unit Under Test
UUT : entity work.gc_prio_encoder
generic map (
g_width => g_width)
port map (
d_i => tb_d_i,
therm_o => tb_therm_o);
-- Unit Under Test
UUT : entity work.gc_prio_encoder
generic map (
g_width => g_width)
port map (
d_i => tb_d_i,
therm_o => tb_therm_o);
-- Stimulus
-- Stimulus
stim : process
variable ncycles : natural;
variable seed1, seed2 : integer := 1992;
impure function rand_slv(len:integer) return std_logic_vector is
variable r : real;
variable slv : std_logic_vector(len - 1 downto 0);
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;
variable data : RandomPType;
begin
while (NOW < 2 ms) loop
wait for 10 ns; --give every 10ns a new input
tb_d_i <= rand_slv(g_width);
data.InitSeed(g_seed);
report "[STARTING] with seed = " & to_string(g_seed);
while NOW < 2 ms loop
wait for 10 ns; --give every 10ns a new input
tb_d_i <= data.randSlv(g_width);
ncycles := ncycles + 1;
end loop;
report "Number of simulation cycles = " & to_string(ncycles);
stop <= TRUE;
report "Test PASS!";
report "Test PASS!";
wait;
end process;
--------------------------------------------------------------------------------
-- Reproduce the RTL behavior in order to compare it with the actual RTL
--------------------------------------------------------------------------------
s_stage(0) <= tb_d_i;
nof_stages : for i in 1 to C_STAGES generate
data_width : for j in 0 to g_width-1 generate
case_1 : if (j mod (2 ** i) >= (2 ** (i-1))) generate
s_stage(i)(j) <= s_stage(i-1)(j) or s_stage(i-1) (j - (j mod (2**i)) + (2**(i-1)) - 1);
end generate;
case_2 : if not (j mod (2 ** i) >= (2 ** (i-1))) generate
s_stage(i)(j) <= s_stage(i-1)(j);
end generate;
end generate;
--------------------------------------------------------------------------------
-- Reproduce the RTL behavior in order to compare it with the actual RTL
--------------------------------------------------------------------------------
s_stage(0) <= tb_d_i;
nof_stages : for i in 1 to C_STAGES generate
data_width : for j in 0 to g_width-1 generate
case_1 : if (j mod (2 ** i) >= (2 ** (i-1))) generate
s_stage(i)(j) <= s_stage(i-1)(j) or s_stage(i-1) (j - (j mod (2**i)) + (2**(i-1)) - 1);
end generate;
case_2 : if not (j mod (2 ** i) >= (2 ** (i-1))) generate
s_stage(i)(j) <= s_stage(i-1)(j);
end generate;
end generate;
end generate;
s_data_o <= s_stage(C_STAGES);
s_data_o <= s_stage(C_STAGES);
--------------------------------------------------------------------------------
-- Assertions
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Assertions --
--------------------------------------------------------------------------------
assert (s_data_o = tb_therm_o)
report "Output data mismatch"
severity failure;
assert (s_data_o = tb_therm_o)
report "Output data mismatch" severity failure;
assert (g_width > 0)
report "Invalid value of data width"
severity failure;
assert (g_width > 0)
report "Invalid value of data width" severity failure;
end tb;
Testbench to verify the functionality of the gc_pulse_synchronizer general core. It uses GHDL simulator and OSVVM verification methodology. Since in this core there are no generics in the entity, there is only one test case.
The testing process is very simple. It receives random input data (with random seeds). One assertion exist in the testbench to bring self-checking capabilities in it. What it does is that, after the de-assertion of ready_o, checks if, in the next rising edge of clock, the output is HIGH.
Simple coverage is being covered also:
- Reset has been asserted
- New HIGH data arrived
- New valid HIGH data produced
......@@ -6,5 +6,5 @@ TB=tb_gc_pulse_synchronizer
echo "Running simulation for $TB"
ghdl -r --std=08 -frelaxed-rules $TB
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM
......@@ -27,129 +27,126 @@ library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.env.finish;
use ieee.math_real.all;
-- OSVVM library
library osvvm;
use osvvm.RandomPkg.all;
use osvvm.CoveragePkg.all;
entity tb_gc_pulse_synchronizer is
generic (
g_seed : natural);
end entity;
architecture tb of tb_gc_pulse_synchronizer is
constant C_CLK_IN_PERIOD : time := 10 ns;
constant C_CLK_OUT_PERIOD : time := 8 ns;
-- Constants
constant C_CLK_IN_PERIOD : time := 10 ns;
constant C_CLK_OUT_PERIOD : time := 8 ns;
--signals
signal tb_clk_in_i : std_logic;
signal tb_rst_n_i : std_logic;
signal tb_clk_out_i : std_logic;
signal tb_d_ready_o : std_logic;
signal tb_d_p_i : std_logic := '0';
signal tb_q_p_o : std_logic;
signal tb_rst_n_i : std_logic;
signal tb_clk_out_i : std_logic;
signal tb_d_ready_o : std_logic;
signal tb_d_p_i : std_logic := '0';
signal tb_q_p_o : std_logic;
-- variables used for coverage
shared variable cp_rst_in_i : covPType;
shared variable cp_data_i : covPType;
shared variable cp_data_o : covPType;
-- Shared variables used for coverage
shared variable cp_rst_in_i : covPType;
shared variable cp_data_i : covPType;
shared variable cp_data_o : covPType;
signal stop : boolean := FALSE;
begin
-- Unit Under Test
UUT : entity work.gc_pulse_synchronizer
-- Unit Under Test
UUT : entity work.gc_pulse_synchronizer
port map (
clk_in_i => tb_clk_in_i,
rst_n_i => tb_rst_n_i,
clk_out_i => tb_clk_out_i,
d_ready_o => tb_d_ready_o,
d_p_i => tb_d_p_i,
q_p_o => tb_q_p_o);
rst_n_i => tb_rst_n_i,
clk_out_i => tb_clk_out_i,
d_ready_o => tb_d_ready_o,
d_p_i => tb_d_p_i,
q_p_o => tb_q_p_o);
--clocks and resets generation
--clocks generation
clk_in_gen : process
begin
while STOP = FALSE loop
tb_clk_in_i <= '1';
wait for C_CLK_IN_PERIOD/2;
tb_clk_in_i <= '0';
wait for C_CLK_IN_PERIOD/2;
end loop;
wait;
while not stop loop
tb_clk_in_i <= '1';
wait for C_CLK_IN_PERIOD/2;
tb_clk_in_i <= '0';
wait for C_CLK_IN_PERIOD/2;
end loop;
wait;
end process;
clk_out_gen : process
begin
while STOP = FALSE loop
tb_clk_out_i <= '1';
wait for C_CLK_OUT_PERIOD/2;
tb_clk_out_i <= '0';
wait for C_CLK_OUT_PERIOD/2;
end loop;
wait;
while not stop loop
tb_clk_out_i <= '1';
wait for C_CLK_OUT_PERIOD/2;
tb_clk_out_i <= '0';
wait for C_CLK_OUT_PERIOD/2;
end loop;
wait;
end process;
tb_rst_n_i <= '0', '1' after 2*C_CLK_IN_PERIOD;
stim : process
variable data_i : RandomPType;
variable seed1, seed2 : integer := 999;
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;
begin
while (NOW < 2 ms) loop
wait until (rising_edge(tb_clk_in_i) and tb_d_ready_o = '1');
tb_d_p_i <= rand_stdl(1);
end loop;
stop <= TRUE;
wait;
end process;
--------------------------------------------------------------------------------
-- Assertions
--------------------------------------------------------------------------------
-- Self-Checking : after the de-assertion of ready_o, in the next rising edge
-- of clock we expect the output to be HIGH
valid_out_data : process
begin
wait until (tb_rst_n_i = '1');
while (stop=FALSE) loop
wait until falling_edge(tb_d_ready_o);
wait until rising_edge(tb_clk_out_i);
wait for 2*C_CLK_OUT_PERIOD;
assert (tb_q_p_o = '1')
report "output is wrong"
severity failure;
end loop;
wait;
end process;
--------------------------------------------------------------------------------
-- Coverage
--------------------------------------------------------------------------------
--sets up coverpoint bins
-- Reset generation
tb_rst_n_i <= '0', '1' after 2*C_CLK_IN_PERIOD;
-- Stimulus
stim : process
variable data : RandomPType;
variable ncycles : natural;
begin
data.InitSeed(g_seed);
report "[STARTING] with seed = " & to_string(g_seed);
while NOW < 2 ms loop
wait until (rising_edge(tb_clk_in_i) and tb_d_ready_o = '1');
tb_d_p_i <= data.randSlv(1)(1);
ncycles := ncycles + 1;
end loop;
report "Number of Simulation cycles = " & to_string(ncycles);
report "Test PASS!";
stop <= TRUE;
wait;
end process;
--------------------------------------------------------------------------------
-- Assertions --
--------------------------------------------------------------------------------
-- Self-Checking : after the de-assertion of ready_o, in the next rising edge
-- of clock we expect the output to be HIGH
valid_out_data : process
begin
while not stop loop
wait until falling_edge(tb_d_ready_o);
wait until rising_edge(tb_clk_out_i);
wait for 2*C_CLK_OUT_PERIOD;
report "here";
assert (tb_q_p_o = '1')
report "output is wrong" severity failure;
end loop;
wait;
end process;
--------------------------------------------------------------------------------
-- Coverage --
--------------------------------------------------------------------------------
--sets up coverpoint bins
init_coverage : process
begin
cp_rst_in_i.AddBins("reset in has been asserted", ONE_BIN);
cp_data_i.AddBins("new HIGH data arrived", ONE_BIN);
cp_data_o.AddBins("output pulse for HIGH input", ONE_BIN);
cp_data_i.AddBins("new HIGH data arrived", ONE_BIN);
cp_data_o.AddBins("output pulse for HIGH input", ONE_BIN);
wait;
end process init_coverage;
-- Sample the coverpoints
-- Sample the coverpoints
sample_rst_i : process
begin
loop
......@@ -159,31 +156,30 @@ begin
end loop;
end process sample_rst_i;
sample_data_i : process
begin
loop
wait until (rising_edge(tb_clk_in_i));
wait until (rising_edge(tb_d_p_i));
cp_data_i.ICover(to_integer(tb_d_p_i = '1'));
end loop;
end process;
sample_data_o : process
begin
loop
wait until (falling_edge(tb_d_ready_o));
wait until (rising_edge(tb_q_p_o));
cp_data_o.ICover(to_integer(tb_q_p_o='1'));
end loop;
end process;
sample_data_i : process
begin
loop
wait until (rising_edge(tb_clk_in_i));
wait until (rising_edge(tb_d_p_i));
cp_data_i.ICover(to_integer(tb_d_p_i = '1'));
end loop;
end process;
sample_data_o : process
begin
loop
wait until (falling_edge(tb_d_ready_o));
wait until (rising_edge(tb_q_p_o));
cp_data_o.ICover(to_integer(tb_q_p_o='1'));
end loop;
end process;
cover_report: process
begin
wait until stop;
cp_rst_in_i.writebin;
cp_data_i.writebin;
cp_data_o.writebin;
report "PASS";
cp_data_i.writebin;
cp_data_o.writebin;
end process;
end tb;
......
Testbench to verify the functionality of the gc_pulse_synchronizer2 general core. This testbench is very similar to the one for gc_pulse_synchronizer. One of the differences is that, this core, has two different reset ports. It uses GHDL simulator and OSVVM verification methodology. Since in this core there are no generics in the entity, there is only one test case.
The testing process is very simple. It receives random input data (with random seeds). One assertion exist in the testbench to bring self-checking capabilities in it. What it does is that, after the de-assertion of ready_o, checks if, in the next rising edge of clock, the output is HIGH.
Simple coverage is being covered also:
- Reset in has been asserted
- Reset out has been asserted
- New HIGH data arrived
- New valid HIGH data produced
......@@ -6,4 +6,4 @@ TB=tb_gc_pulse_synchronizer2
echo "Running simulation for $TB"
ghdl -r --std=08 -frelaxed-rules $TB
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM
......@@ -29,141 +29,135 @@ library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.env.finish;
use ieee.math_real.all;
-- OSVVM library
library osvvm;
use osvvm.RandomPkg.all;
use osvvm.CoveragePkg.all;
entity tb_gc_pulse_synchronizer2 is
generic (
g_seed : natural);
end entity;
architecture tb of tb_gc_pulse_synchronizer2 is
constant C_CLK_IN_PERIOD : time := 10 ns;
constant C_CLK_OUT_PERIOD : time := 8 ns;
-- Constants
constant C_CLK_IN_PERIOD : time := 5 ns;
constant C_CLK_OUT_PERIOD : time := 10 ns;
-- signals
signal tb_clk_in_i : std_logic;
signal tb_rst_in_n_i : std_logic;
signal tb_clk_out_i : std_logic;
signal tb_rst_out_n_i : std_logic;
signal tb_d_ready_o : std_logic;
signal tb_d_ack_p_o : std_logic;
signal tb_d_p_i : std_logic := '0';
signal tb_q_p_o : std_logic;
-- variables used for coverage
shared variable cp_rst_in_i : covPType;
shared variable cp_rst_out_i : covPType;
shared variable cp_data_i : covPType;
shared variable cp_data_o : covPType;
signal tb_rst_in_n_i : std_logic;
signal tb_clk_out_i : std_logic;
signal tb_rst_out_n_i : std_logic;
signal tb_d_ready_o : std_logic;
signal tb_d_ack_p_o : std_logic;
signal tb_d_p_i : std_logic := '0';
signal tb_q_p_o : std_logic;
signal stop : boolean := FALSE;
-- Shared variables used for coverage
shared variable cp_rst_in_i : covPType;
shared variable cp_rst_out_i : covPType;
shared variable cp_data_i : covPType;
shared variable cp_data_o : covPType;
begin
--Unit Under Test
-- Unit Under Test
UUT : entity work.gc_pulse_synchronizer2
port map (
clk_in_i => tb_clk_in_i,
rst_in_n_i => tb_rst_in_n_i,
clk_out_i => tb_clk_out_i,
rst_out_n_i => tb_rst_out_n_i,
d_ready_o => tb_d_ready_o,
d_ack_p_o => tb_d_ack_p_o,
d_p_i => tb_d_p_i,
q_p_o => tb_q_p_o);
--clock and reset generation
rst_in_n_i => tb_rst_in_n_i,
clk_out_i => tb_clk_out_i,
rst_out_n_i => tb_rst_out_n_i,
d_ready_o => tb_d_ready_o,
d_ack_p_o => tb_d_ack_p_o,
d_p_i => tb_d_p_i,
q_p_o => tb_q_p_o);
-- Clocks generation
clk_in_gen : process
begin
while STOP = FALSE loop
tb_clk_in_i <= '1';
wait for C_CLK_IN_PERIOD/2;
tb_clk_in_i <= '0';
wait for C_CLK_IN_PERIOD/2;
end loop;
wait;
while not stop loop
tb_clk_in_i <= '1';
wait for C_CLK_IN_PERIOD/2;
tb_clk_in_i <= '0';
wait for C_CLK_IN_PERIOD/2;
end loop;
wait;
end process;
clk_out_gen : process
begin
while STOP = FALSE loop
tb_clk_out_i <= '1';
wait for C_CLK_OUT_PERIOD/2;
tb_clk_out_i <= '0';
wait for C_CLK_OUT_PERIOD/2;
end loop;
wait;
while not stop loop
tb_clk_out_i <= '1';
wait for C_CLK_OUT_PERIOD/2;
tb_clk_out_i <= '0';
wait for C_CLK_OUT_PERIOD/2;
end loop;
wait;
end process;
-- Resets generation
tb_rst_in_n_i <= '0', '1' after 2*C_CLK_IN_PERIOD;
tb_rst_out_n_i <= '0', '1' after 2*C_CLK_OUT_PERIOD;
-- Stimulus
stim : process
variable ncycles : natural;
variable seed1, seed2 : integer := 999;
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;
begin
while (NOW < 1 ms) loop
wait until (rising_edge(tb_clk_in_i) and tb_d_ready_o = '1');
tb_d_p_i <= rand_stdl(1);
ncycles := ncycles + 1;
end loop;
report "Number of simulation cycles = " & to_string(ncycles);
stop <= TRUE;
wait;
end process;
--------------------------------------------------------------------------------
-- Assertions
--------------------------------------------------------------------------------
-- Self-Checking : after the de-assertion of ready_o, after one clock cycle
-- (due to g_sync module), we want the output to be like the input pulse
-- but last for one clock
valid_out_data : process
begin
wait until (tb_rst_in_n_i = '1' and tb_rst_out_n_i = '1');
while (stop=FALSE) loop
wait until falling_edge(tb_d_ready_o);
wait until rising_edge(tb_clk_out_i);
wait for 2*C_CLK_OUT_PERIOD;
assert (tb_q_p_o = '1')
report "output is wrong"
severity failure;
end loop;
wait;
end process;
--------------------------------------------------------------------------------
-- Coverage
--------------------------------------------------------------------------------
--sets up coverpoint bins
-- Stimulus
stim : process
variable data : RandomPType;
variable ncycles : natural;
begin
data.InitSeed(g_seed);
report "[STARTING] with seed = " & to_string(g_seed);
while NOW < 2 ms loop
wait until (rising_edge(tb_clk_in_i) and tb_d_ready_o = '1');
tb_d_p_i <= data.randSlv(1)(1);
ncycles := ncycles + 1;
end loop;
report "Number of Simulation cycles = " & to_string(ncycles);
report "Test PASS!";
stop <= TRUE;
wait;
end process;
--------------------------------------------------------------------------------
-- Assertions --
--------------------------------------------------------------------------------
-- Self-Checking : after the de-assertion of ready_o, after one clock cycle
-- (due to g_sync module), we want the output to be like the input pulse
-- but last for one clock
valid_out_data : process
begin
wait until (tb_rst_in_n_i = '1' and tb_rst_out_n_i = '1');
while not stop loop
wait until falling_edge(tb_d_ready_o);
wait until rising_edge(tb_clk_out_i);
wait for 2*C_CLK_OUT_PERIOD;
assert (tb_q_p_o = '1')
report "output is wrong" severity failure;
end loop;
wait;
end process;
--------------------------------------------------------------------------------
-- Coverage --
--------------------------------------------------------------------------------
--sets up coverpoint bins
init_coverage : process
begin
cp_rst_in_i.AddBins("reset in has been asserted", ONE_BIN);
cp_rst_out_i.AddBins("reset out has been asserted",ONE_BIN);
cp_data_i.AddBins("new HIGH data arrives",ONE_BIN);
cp_data_o.AddBins("output pulse for HIGH input",ONE_BIN);
cp_rst_out_i.AddBins("reset out has been asserted",ONE_BIN);
cp_data_i.AddBins("new HIGH data arrives",ONE_BIN);
cp_data_o.AddBins("output pulse for HIGH input",ONE_BIN);
wait;
end process init_coverage;
-- Sample the coverpoints
-- Sample the coverpoints
sample_rst_i : process
begin
loop
......@@ -182,33 +176,32 @@ begin
end loop;
end process sample_rst_out;
sample_data_i : process
begin
loop
wait until (rising_edge(tb_clk_in_i));
wait until (rising_edge(tb_d_p_i));
cp_data_i.ICover(to_integer(tb_d_p_i = '1'));
end loop;
end process;
sample_data_o : process
begin
loop
wait until (falling_edge(tb_d_ready_o));
wait until (rising_edge(tb_q_p_o));
cp_data_o.ICover(to_integer(tb_q_p_o='1'));
end loop;
end process;
-- coverage reports
sample_data_i : process
begin
loop
wait until (rising_edge(tb_clk_in_i));
wait until (rising_edge(tb_d_p_i));
cp_data_i.ICover(to_integer(tb_d_p_i = '1'));
end loop;
end process;
sample_data_o : process
begin
loop
wait until (falling_edge(tb_d_ready_o));
wait until (rising_edge(tb_q_p_o));
cp_data_o.ICover(to_integer(tb_q_p_o='1'));
end loop;
end process;
-- coverage reports
cover_report: process
begin
wait until stop;
cp_rst_out_i.writebin;
cp_rst_in_i.writebin;
cp_data_i.writebin;
cp_data_o.writebin;
report "PASS";
cp_data_i.writebin;
cp_data_o.writebin;
end process;
......
Testbench to verify the functionality of the gc_reset general core. It uses GHDL simulator and OSVVM verification methodology. This core is using 3 generics in the entity:
- g_clocks : Number of clocks
- g_logdelay : Delay duration
- g_syncdepth : Synchronization depth
A combination of them, create these test cases (there can be even more than them):
- 1, 1, 1
- 2, 2, 2
- 1, 5, 3
- 4, 3, 4
The testing process is very simple. It receives random input data (with random seeds). It uses a similar logic to the one that RTL uses and generates a testbench output. One assertion exist in the testbench to bring self-checking capabilities in it and compare the output of the testbench with the one in the RTL code.
Simple coverage is being covered also:
- Asynchronous reset has been asserted
- Output reset has been asserted
Note: It is advised, for simulation purposes, to keep the generic values quite low in order to see the behavior of the module. For higher generic values, increase the simulation time.
It is advised, for simulation purposes, to keep the generic
values quite low in order to see the behavior of the module.
For higher generic values, increase the simulation time
more than 40 ms
......@@ -6,18 +6,27 @@
TB=tb_gc_reset
echo "Running simulation for $TB"
echo ""
echo " TEST CASE 1 "
echo "Number of clocks = 1, LogDelay = 1 , SyncDepth = 1"
ghdl -r --std=08 -frelaxed-rules $TB -gg_clocks=1 -gg_logdelay=1 -gg_syncdepth=1
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_clocks=1 -gg_logdelay=1 -gg_syncdepth=1
echo "****************************************************************************"
echo " TEST CASE 2 "
echo "Number of clocks = 2, LogDelay = 2 , SyncDepth = 2"
ghdl -r --std=08 -frelaxed-rules $TB -gg_clocks=2 -gg_logdelay=2 -gg_syncdepth=2
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_clocks=2 -gg_logdelay=2 -gg_syncdepth=2
echo "****************************************************************************"
echo " TEST CASE 3 "
echo "Number of clocks = 1, LogDelay = 5 , SyncDepth = 3"
ghdl -r --std=08 -frelaxed-rules $TB -gg_clocks=1 -gg_logdelay=3 -gg_syncdepth=4
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_clocks=1 -gg_logdelay=3 -gg_syncdepth=4
echo "****************************************************************************"
echo " TEST CASE 4 "
echo "Number of clocks = 4, LogDelay = 3, SyncDepth = 4"
ghdl -r --std=08 -frelaxed-rules $TB -gg_clocks=4 -gg_logdelay=4 -gg_syncdepth=4
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_clocks=4 -gg_logdelay=4 -gg_syncdepth=4
echo "****************************************************************************"
This diff is collapsed.
Testbench to verify the functionality of the gc_reset_multi_aasd general core. It uses GHDL simulator and OSVVM verification methodology. This core is using 2 generics in the entity:
- g_clocks : Number of clocks
- g_rst_len : Number of clock ticks (per domain) that the input reset must remain deasserted and stable before deasserting the reset output(s)
A combination of them, create these test cases (there can be even more than them):
- 1, 2
- 1, 4
- 2, 2
- 2, 4
- 1, 1
The testing process is very simple. It receives random input data (with random seeds). It uses a similar logic to the one that RTL uses and generates a testbench output (in case of more than one clocks). One assertion exist in the testbench to bring self-checking capabilities in it and compare the output of the testbench with the one in the RTL code.
......@@ -5,21 +5,29 @@
TB=tb_gc_reset_multi_aasd
echo "Running simulation for $TB"
echo ""
echo " TEST CASE 1 "
echo "Clock domains = 1, Number of resets = 2"
ghdl -r --std=08 -frelaxed-rules $TB -gg_CLOCKS=1 -gg_RST_LEN=2 --vcd=waveform.vcd
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_CLOCKS=1 -gg_RST_LEN=2
echo "****************************************************************************"
echo " TEST CASE 2 "
echo "Clock domains = 1, Number of resets = 4"
ghdl -r --std=08 -frelaxed-rules $TB -gg_CLOCKS=1 -gg_RST_LEN=4 --vcd=waveform.vcd
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_CLOCKS=1 -gg_RST_LEN=4
echo "****************************************************************************"
#echo "Clock domains = 2, Number of resets = 2"
#ghdl -r --std=08 -frelaxed-rules $TB -gg_CLOCKS=2 -gg_RST_LEN=2 --vcd=waveform.vcd
#echo "Clock domains = 2, Number of resets = 4"
#ghdl -r --std=08 -frelaxed-rules $TB -gg_CLOCKS=2 -gg_RST_LEN=4 --vcd=waveform.vcd
echo " TEST CASE 3 "
echo "Clock domains = 2, Number of resets = 2"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_CLOCKS=2 -gg_RST_LEN=2
echo "****************************************************************************"
echo " TEST CASE 4 "
echo "Clock domains = 2, Number of resets = 4"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_CLOCKS=2 -gg_RST_LEN=4
echo "****************************************************************************"
echo " TEST CASE 5 "
echo "Clock domains = 1, Number of resets = 1"
ghdl -r --std=08 -frelaxed-rules $TB -gg_CLOCKS=1 -gg_RST_LEN=1 --vcd=waveform.vcd
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_CLOCKS=1 -gg_RST_LEN=1
#Printing result
echo "Test PASS"
......@@ -30,18 +30,14 @@ library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--randomization with manually seeds
use ieee.math_real.all;
use std.env.finish;
--OSVVM
--OSVVM library
library osvvm;
use osvvm.RandomPkg.all;
use osvvm.CoveragePkg.all;
-- Empty entity needed for TB
entity tb_gc_reset_multi_aasd is
generic (
g_seed : natural;
-- number of clock domains
g_CLOCKS : natural := 2;
-- Number of clock ticks (per domain) that the input reset must remain
......@@ -51,24 +47,21 @@ end entity;
architecture tb of tb_gc_reset_multi_aasd is
-- Constants
constant C_CLK_PERIOD : time := 10 ns;
-- Signals
-- all async resets OR'ed together, active high
signal tb_arst_i : std_logic := '0';
-- one clock signal per domain
signal tb_clks_i : std_logic_vector(g_CLOCKS-1 downto 0) := (others=>'0');
-- one syncrhonous, active low reset output per domain
signal tb_rst_n_o : std_logic_vector(g_CLOCKS-1 downto 0);
signal stop : boolean;
signal s_cnt_rst : unsigned(g_RST_LEN-1 downto 0) := (others=>'0');
signal s_cnt_clks : unsigned(g_CLOCKS-1 downto 0) := (others=>'0');
signal s_rst : std_logic;
signal s_cnt_rst : unsigned(g_RST_LEN-1 downto 0) := (others=>'0');
signal s_cnt_clks : unsigned(g_CLOCKS-1 downto 0) := (others=>'0');
--Shared variables for coverage use
shared variable cp_rst_i : covPType;
signal stop : boolean := FALSE;
subtype t_rst_chain is std_logic_vector(g_RST_LEN-1 downto 0);
type t_rst_chains is array(natural range <>) of t_rst_chain;
signal s_rst_chains : t_rst_chains(g_CLOCKS-1 downto 0) := (others => (others => '0'));
begin
......@@ -82,87 +75,81 @@ begin
clks_i => tb_clks_i,
rst_n_o => tb_rst_n_o);
--Randomize stimulus
--Stimulus
stim : process
--number of clk cycles
variable ncycles : natural;
--added for having seeds for random numbers
variable seed1, seed2 : integer := 1692013;
impure function rand_slv(len:integer) return std_logic_vector is
variable r : real;
variable slv : std_logic_vector(len - 1 downto 0);
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;
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;
variable data : RandomPType;
begin
while (NOW < 1 ms) loop
wait for C_CLK_PERIOD;
tb_clks_i <= rand_slv(g_CLOCKS);
tb_arst_i <= rand_stdl(1);
ncycles := ncycles + 1;
data.InitSeed(g_seed);
report "[STARTING] with seed = " & to_string(g_seed);
while NOW < 1 ms loop
wait for C_CLK_PERIOD;
tb_clks_i <= data.randSlv(g_CLOCKS);
tb_arst_i <= data.randSlv(1)(1);
ncycles := ncycles + 1;
end loop;
report "Number of simulation cycles = " & to_string(ncycles);
stop <= TRUE;
report "Test PASS!";
wait;
end process;
-- Assertion 1: checking the values of the generics
assert (g_CLOCKS >0 and g_RST_LEN>0)
report "g_CLOCKS and g_RST_LEN should be greater than zero"
severity failure;
--------------------------------------------------------------------------------
-- Assertions --
--------------------------------------------------------------------------------
-- Assertion 1: checking the values of the generics
assert (g_CLOCKS >0 and g_RST_LEN>0)
report "g_CLOCKS and g_RST_LEN should be greater than zero"
severity failure;
-- Assertion 2: for one clock domain
single_clk_domain : if (g_CLOCKS = 1) generate
-- Assertion 2: for one clock domain
single_clk_domain : if (g_CLOCKS = 1) generate
assert_check : for I in g_CLOCKS-1 downto 0 generate
check : process(tb_clks_i, tb_arst_i)
begin
if (tb_arst_i = '0') then
if (tb_clks_i(i)='0') then
s_cnt_rst <= s_cnt_rst + 1;
if (s_cnt_rst = g_RST_LEN) then
s_cnt_rst <= (others=>'0');
assert (tb_rst_n_o(i) = '1')
report "wrong"
severity warning;
end if;
check : process(tb_clks_i, tb_arst_i)
begin
if tb_arst_i = '0' then
if tb_clks_i(i)='0' then
s_cnt_rst <= s_cnt_rst + 1;
if s_cnt_rst = g_RST_LEN then
s_cnt_rst <= (others=>'0');
assert (tb_rst_n_o(i) = '1')
report "wrong" severity failure;
end if;
end if;
else
s_cnt_rst <= (others=>'0');
s_cnt_rst <= (others=>'0');
end if;
end process;
end generate;
end process;
end generate;
-- Assertion 3: for many clock domains
many_clk_domains : if (g_CLOCKS > 1) generate
assert_check : for I in g_CLOCKS-1 downto 0 generate
check : process(tb_clks_i, tb_arst_i)
begin
if (tb_arst_i = '0') then --if NOT reset
if (rising_edge(tb_clks_i(i))) then --and the clock is going from 0 to 1
assert (rising_edge(tb_rst_n_o(i)))
report "WRONG"
severity warning;
end if;
end generate;
s_rst <= tb_arst_i;
-- Assertion 3: for many clock domains
many_clk_domains : if (g_CLOCKS > 1) generate
assert_check : for I in g_CLOCKS-1 downto 0 generate
check : process(tb_clks_i, s_rst)
begin
if s_rst = '1' then --if NOT reset
s_rst_chains(i) <= (others=>'0');
elsif rising_edge(tb_clks_i(i)) then
s_rst_chains(i) <= '1' & s_rst_chains(i)(g_RST_LEN-1 downto 1);
end if;
end process;
end generate;
end generate;
end process;
process(tb_clks_i, s_rst)
begin
if s_rst = '0' then
if rising_edge(tb_clks_i(i)) then
assert (s_rst_chains(i)(0) = tb_rst_n_o(i))
report "Wrong" severity warning;
end if;
end if;
end process;
end generate;
end generate;
end tb;
Testbench to verify the functionality of the gc_rr_arbiter general core. It uses GHDL simulator and OSVVM verification methodology. The test cases of this testbench arise from the g_size generic and they are : 1, 3, 7, 16, 31, 128.
The testing process is the following: It receives random input data (with random seeds). Two assertions are being used to bring self-checking capabilities in the testbench:
1. Output grant_o is the delayed (by 1 clock cycle) version of grant_comb_o
2. The valid values of grant_comb_o are 0, 1.
An example to the second assertion is the following, for g_size = 3:
req_i grant_o
000 000
001 001
010 010
011 010 / 001
100 100
101 100 / 001
110 100 / 010
111 100 / 010 / 001
Note: It is advised, for simulation purposes, to keep the generic values quite low in order to see the behavior of the module. For higher generic values, increase the simulation time.
Purpose of this test is to verify that :
1) grant has valid values like 0, 1, mod 2
for example, in case of g_size=3 valid values
are 0,1,2,4
req_i grant_o
000 000
001 001
010 010
011 010 / 001
100 100
101 100 / 001
110 100 / 010
111 100 / 010 / 001
2) grant_o is the delayed by 1 clock version of grant_comb_o
......@@ -7,26 +7,26 @@ TB=tb_gc_rr_arbiter
echo "Running simulation for $TB"
echo "Width = 1"
ghdl -r --std=08 -frelaxed-rules $TB -gg_size=1
ghdl -r --std=08 -frelaxed-rules $TB -gg_size=1 -gg_seed=$RANDOM
echo "********************************************************************************"
echo "Width = 3"
ghdl -r --std=08 -frelaxed-rules $TB -gg_size=3
ghdl -r --std=08 -frelaxed-rules $TB -gg_size=3 -gg_seed=$RANDOM
echo "********************************************************************************"
echo "Width = 7"
ghdl -r --std=08 -frelaxed-rules $TB -gg_size=7
ghdl -r --std=08 -frelaxed-rules $TB -gg_size=7 -gg_seed=$RANDOM
echo "********************************************************************************"
echo "Width = 16"
ghdl -r --std=08 -frelaxed-rules $TB -gg_size=16
ghdl -r --std=08 -frelaxed-rules $TB -gg_size=16 -gg_seed=$RANDOM
echo "********************************************************************************"
echo "Width = 31"
ghdl -r --std=08 -frelaxed-rules $TB -gg_size=31
ghdl -r --std=08 -frelaxed-rules $TB -gg_size=31 -gg_seed=$RANDOM
echo "********************************************************************************"
echo "Width = 128"
ghdl -r --std=08 -frelaxed-rules $TB -gg_size=128
ghdl -r --std=08 -frelaxed-rules $TB -gg_size=128 -gg_seed=$RANDOM
echo "********************************************************************************"
......@@ -31,117 +31,103 @@ library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
use std.env.finish;
-- OSVVM library
--library osvvm;
--use osvvm.RandomPkg.all;
--use osvvm.CoveragePkg.all;
library osvvm;
use osvvm.RandomPkg.all;
use osvvm.CoveragePkg.all;
entity tb_gc_rr_arbiter is
generic (
g_size : integer := 3);
generic (
g_seed : natural;
g_size : integer := 3);
end entity;
architecture tb of tb_gc_rr_arbiter is
-- constants
constant C_CLK_PERIOD : time := 10 ns;
-- signals
signal tb_clk_i : std_logic;
signal tb_rst_n_i : std_logic;
signal tb_req_i : std_logic_vector(g_size-1 downto 0) := (others=>'0');
signal tb_grant_o : std_logic_vector(g_size-1 downto 0);
signal tb_grant_comb_o: std_logic_vector(g_size-1 downto 0);
-- constants
constant C_CLK_PERIOD : time := 10 ns;
signal stop : boolean;
signal s_grant_del : std_logic_vector(g_size-1 downto 0) := (others=>'0');
signal s_data_o : std_logic_vector(g_size-1 downto 0) := (others=>'0');
signal s_cnt : unsigned(1 downto 0);
-- signals
signal tb_clk_i : std_logic;
signal tb_rst_n_i : std_logic;
signal tb_req_i : std_logic_vector(g_size-1 downto 0) := (others=>'0');
signal tb_grant_o : std_logic_vector(g_size-1 downto 0);
signal tb_grant_comb_o : std_logic_vector(g_size-1 downto 0);
signal stop : boolean;
signal s_grant_del : std_logic_vector(g_size-1 downto 0) := (others=>'0');
signal s_data_o : std_logic_vector(g_size-1 downto 0) := (others=>'0');
signal s_cnt : unsigned(1 downto 0);
begin
-- Unit Under Test
UUT : entity work.gc_rr_arbiter
generic map (
g_size => g_size)
port map (
clk_i => tb_clk_i,
rst_n_i => tb_rst_n_i,
req_i => tb_req_i,
grant_o => tb_grant_o,
grant_comb_o => tb_grant_comb_o);
-- Clock and reset generation
clk_i_process : process
begin
while stop = FALSE loop
tb_clk_i <= '1';
wait for C_CLK_PERIOD/2;
tb_clk_i <= '0';
wait for C_CLK_PERIOD/2;
end loop;
wait;
end process;
tb_rst_n_i <= '0', '1' after 2*C_CLK_PERIOD;
-- Stimulus
stim : process
variable ncycles : natural;
variable seed1,seed2 : integer := 2000;
impure function rand_slv(len:integer) return std_logic_vector is
variable r : real;
variable slv : std_logic_vector(len - 1 downto 0);
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
wait until (rising_edge(tb_clk_i) and tb_rst_n_i = '1');
tb_req_i <= rand_slv(g_size);
wait for g_size*C_CLK_PERIOD;
ncycles := ncycles + 1;
end loop;
report "Number of Simulation cycles = " & to_string(ncycles);
report "Test PASS!";
stop <= TRUE;
wait;
end process;
-- grant_comb_o is the same as gtant_o with 1 clock delay
compare_grants : process(tb_clk_i)
begin
if (rising_edge(tb_clk_i)) then
if (tb_rst_n_i = '1') then
s_grant_del <= tb_grant_comb_o;
assert (tb_grant_o = s_grant_del)
report "grant_o and grant_comb_o not the same after 1 clock"
severity failure;
end if;
end if;
end process;
process
begin
while (stop=FALSE) loop
wait until tb_rst_n_i = '1';
assert ((to_integer(unsigned(tb_grant_comb_o))) mod 2 = 0
-- Unit Under Test
UUT : entity work.gc_rr_arbiter
generic map (
g_size => g_size)
port map (
clk_i => tb_clk_i,
rst_n_i => tb_rst_n_i,
req_i => tb_req_i,
grant_o => tb_grant_o,
grant_comb_o => tb_grant_comb_o);
-- Clock generation
clk_i_process : process
begin
while not stop loop
tb_clk_i <= '1';
wait for C_CLK_PERIOD/2;
tb_clk_i <= '0';
wait for C_CLK_PERIOD/2;
end loop;
wait;
end process;
-- Reset generation
tb_rst_n_i <= '0', '1' after 2*C_CLK_PERIOD;
-- Stimulus
stim : process
variable ncycles : natural;
variable data : RandomPType;
begin
data.InitSeed(g_seed);
report "[STARTING] with seed = " & to_string(g_seed);
while NOW < 2 ms loop
wait until (rising_edge(tb_clk_i) and tb_rst_n_i = '1');
tb_req_i <= data.randSlv(g_size);
wait for g_size*C_CLK_PERIOD;
ncycles := ncycles + 1;
end loop;
report "Number of Simulation cycles = " & to_string(ncycles);
report "Test PASS!";
stop <= TRUE;
wait;
end process;
-- grant_comb_o is the same as gtant_o with 1 clock delay
compare_grants : process(tb_clk_i)
begin
if rising_edge(tb_clk_i) then
if tb_rst_n_i = '1' then
s_grant_del <= tb_grant_comb_o;
assert (tb_grant_o = s_grant_del)
report "grant_o and grant_comb_o not the same after 1 clock"
severity failure;
end if;
end if;
end process;
process
begin
while not stop loop
wait until tb_rst_n_i = '1';
assert ((to_integer(unsigned(tb_grant_comb_o))) mod 2 = 0
or unsigned(tb_grant_comb_o) = 0
or unsigned(tb_grant_comb_o) = 1)
report "wrong grant"
severity warning;
end loop;
wait;
end process;
report "wrong grant" severity failure;
end loop;
wait;
end process;
end tb;
Testbench to verify the functionality of the gc_serial_dac general core. It uses GHDL simulator and OSVVM verification methodology. This core is using 4 generics in the entity:
- g_num_data_bits : Number of DAC data word bits, LSBs
- g_num_extra_bits : Number of padding MSBs sent as zeros
- g_num_cs_select : Number of chip select inputs
- g_sclk_polarity : Serial clock polarity (0 for rising, 1 for falling edge)
A combination of them, create these test cases (there can be even more than them):
1. 2, 0, 1, 0
2. 2, 1, 2, 0
3. 4, 4, 2, 0
4. 16,8, 1, 0
5. 2, 0, 1, 1
6. 4, 2, 1, 1
7. 8, 4, 2, 1
8. 16,8, 2, 1
The testbench, receives random input data (with random seeds). It uses a similar logic to the one that RTL uses and generates a testbench output. One assertion exist in the testbench to bring self-checking capabilities in it and compare the output of the testbench with the one in the RTL code.
Simple coverage is being covered also:
- Reset has been asserted
- DAC is not busy
Note: It is advised, for simulation purposes, to keep the generic values quite low in order to see the behavior of the module. For higher generic values, increase the simulation time.
......@@ -7,34 +7,42 @@ TB=tb_gc_serial_dac
echo "Running simulation for $TB"
echo "TEST CASE 1"
echo "DAC data word bits = 2, Padding MSBs sent as zeros= 0, chip select inputs = 1, Serial clock polarity = 0"
ghdl -r --std=08 -frelaxed-rules $TB -gg_num_data_bits=2 -gg_num_extra_bits=0 -gg_num_cs_select=1 -gg_sclk_polarity=0
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_num_data_bits=2 -gg_num_extra_bits=0 -gg_num_cs_select=1 -gg_sclk_polarity=0
echo "**********************************************************************************************************"
echo "TEST CASE 2"
echo "DAC data word bits = 2, Padding MSBs sent as zeros= 1, chip select inputs = 2, Serial clock polarity = 0"
ghdl -r --std=08 -frelaxed-rules $TB -gg_num_data_bits=2 -gg_num_extra_bits=1 -gg_num_cs_select=2 -gg_sclk_polarity=0
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_num_data_bits=2 -gg_num_extra_bits=1 -gg_num_cs_select=2 -gg_sclk_polarity=0
echo "**********************************************************************************************************"
echo "TEST CASE 3"
echo "DAC data word bits = 4, Padding MSBs sent as zeros= 4, chip select inputs = 2, Serial clock polarity = 0"
ghdl -r --std=08 -frelaxed-rules $TB -gg_num_data_bits=4 -gg_num_extra_bits=4 -gg_num_cs_select=2 -gg_sclk_polarity=0
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_num_data_bits=4 -gg_num_extra_bits=4 -gg_num_cs_select=2 -gg_sclk_polarity=0
echo "**********************************************************************************************************"
echo "TEST CASE 4"
echo "DAC data word bits = 16, Padding MSBs sent as zeros= 8, chip select inputs = 1, Serial clock polarity = 0"
ghdl -r --std=08 -frelaxed-rules $TB -gg_num_data_bits=16 -gg_num_extra_bits=8 -gg_num_cs_select=1 -gg_sclk_polarity=0
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_num_data_bits=16 -gg_num_extra_bits=8 -gg_num_cs_select=1 -gg_sclk_polarity=0
echo "**********************************************************************************************************"
echo "TEST CASE 5"
echo "DAC data word bits = 2, Padding MSBs sent as zeros= 0, chip select inputs = 1, Serial clock polarity = 1"
ghdl -r --std=08 -frelaxed-rules $TB -gg_num_data_bits=2 -gg_num_extra_bits=0 -gg_num_cs_select=1 -gg_sclk_polarity=1
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_num_data_bits=2 -gg_num_extra_bits=0 -gg_num_cs_select=1 -gg_sclk_polarity=1
echo "**********************************************************************************************************"
echo "TEST CASE 6"
echo "DAC data word bits = 4, Padding MSBs sent as zeros= 2, chip select inputs = 1, Serial clock polarity = 1"
ghdl -r --std=08 -frelaxed-rules $TB -gg_num_data_bits=4 -gg_num_extra_bits=2 -gg_num_cs_select=1 -gg_sclk_polarity=1
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_num_data_bits=4 -gg_num_extra_bits=2 -gg_num_cs_select=1 -gg_sclk_polarity=1
echo "**********************************************************************************************************"
echo "TEST CASE 7"
echo "DAC data word bits = 8, Padding MSBs sent as zeros= 4, chip select inputs = 2, Serial clock polarity = 1"
ghdl -r --std=08 -frelaxed-rules $TB -gg_num_data_bits=8 -gg_num_extra_bits=4 -gg_num_cs_select=2 -gg_sclk_polarity=1
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_num_data_bits=8 -gg_num_extra_bits=4 -gg_num_cs_select=2 -gg_sclk_polarity=1
echo "**********************************************************************************************************"
echo "TEST CASE 8"
echo "DAC data word bits = 16, Padding MSBs sent as zeros= 8, chip select inputs = 2, Serial clock polarity = 1"
ghdl -r --std=08 -frelaxed-rules $TB -gg_num_data_bits=16 -gg_num_extra_bits=8 -gg_num_cs_select=2 -gg_sclk_polarity=1
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_num_data_bits=16 -gg_num_extra_bits=8 -gg_num_cs_select=2 -gg_sclk_polarity=1
echo "**********************************************************************************************************"
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