Commit d091832e authored by kblantos's avatar kblantos

Testbench added for genram cores

parent 4bc47c7d
action="simulation"
sim_tool="ghdl"
target="altera"
syn_device = "5agxmb1g4f"
sim_top="tb_gc_shiftreg"
ghdl_opt="--std=08 -frelaxed-rules"
files=["tb_gc_shiftreg.vhd"]
modules={"local" : ["../../../../"]}# ,
# "../../../../modules/common",
# "../../../../modules/genrams"]}
This is a testbench to verufy the gc_shiftreg for Altera version. The core is a simple shift register which used in Altera designs.
All the inputs are random in every clock, with randomized seed. The verification methodology that being used is OSVVM. During the self-checking process, we compare the output of the testbench's logic with the RTL output.
#!/bin/bash -e
#This is a simple script to run simulations in GHDL
TB=tb_gc_shiftreg
echo "Running simulation for $TB"
echo "*******************************************************************************"
echo " Test case 1: Size of the shiftreg = 32 "
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_size=32 --wave=waveform.ghw
--------------------------------------------------------------------------------
-- CERN BE-CEM-EDL
-- General Cores Library
-- https://www.ohwr.org/projects/general-cores
--------------------------------------------------------------------------------
--
-- unit name: tb_gc_shiftreg
--
-- author: Konstantinos Blantos
--
-- description: Testbench for generic shift register (Altera version)
--
--------------------------------------------------------------------------------
-- Copyright CERN 2011-2018
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
-------------------------------------------------------------------------------
--=============================================================================
-- Libraries & Packages
--=============================================================================
library ieee;
use ieee.STD_LOGIC_1164.all;
use ieee.NUMERIC_STD.all;
use work.genram_pkg.all;
--OSVMM library
library osvvm;
use osvvm.RandomPkg.all;
use osvvm.CoveragePkg.all;
--==============================================================================
-- Entity declaration for tb_gc_shiftreg
--==============================================================================
entity tb_gc_shiftreg is
generic (
g_seed : natural;
g_size : natural);
end entity;
--==============================================================================
-- Architecture declaration
--==============================================================================
architecture tb of tb_gc_shiftreg is
-- Constants
constant C_CLK_PERIOD : time := 10 ns;
-- Signals
signal tb_clk_i : std_logic;
signal tb_en_i : std_logic := '0';
signal tb_d_i : std_logic := '0';
signal tb_a_i : std_logic_vector(f_log2_size(g_size)-1 downto 0) := (others=>'0');
signal tb_q_o : std_logic;
signal stop : boolean;
signal s_sr : std_logic_vector(g_size-1 downto 0);
begin
-- Unit Under Test
UUT : entity work.gc_shiftreg
generic map (
g_size => g_size)
port map (
clk_i => tb_clk_i,
en_i => tb_en_i,
d_i => tb_d_i,
a_i => tb_a_i,
q_o => tb_q_o);
-- Clock generation
clk_proc : 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 clk_proc;
-- Stimulus
stim : process
variable data : RandomPType;
variable ncycles : natural;
begin
data.InitSeed(g_seed);
report "[STARTING] with seed = " & integer'image(g_seed);
while NOW < 1 ms loop
wait until rising_edge(tb_clk_i);
tb_en_i <= data.randSlv(1)(1);
tb_d_i <= data.randSlv(1)(1);
tb_a_i <= data.randSlv(f_log2_size(g_size));
ncycles := ncycles + 1;
end loop;
report "Number of simulation cycles = " & to_string(ncycles);
stop <= TRUE;
report "Test PASS!";
wait;
end process;
-----------------------------------------------------------------------------
-- Assertions
-----------------------------------------------------------------------------
-- Shift register testbench's logic
tb_logic : process(tb_clk_i)
begin
if rising_edge(tb_clk_i) then
if tb_en_i then
s_sr <= s_sr(s_sr'left-1 downto 0) & tb_d_i;
end if;
end if;
end process;
check_output : process
begin
while not stop loop
wait until rising_edge(tb_clk_i);
assert (tb_q_o = s_sr(to_integer(unsigned(tb_a_i))))
report "Output data mismatch" severity failure;
end loop;
wait;
end process;
end tb;
action="simulation"
sim_tool="ghdl"
target="xilinx"
syn_device="xc6slx45t"
sim_top="tb_inferred_async_fifo"
ghdl_opt="--std=08 -frelaxed-rules"
files=["tb_inferred_async_fifo.vhd"]
modules={"local" : ["../../../../",
"../../../../modules/common",
"../../../../modules/genrams"]}
This is a testbench to verify the functionality of the inferred_async_fifo. It is a dual clock (single reset) Asynchronous FIFO and can be used in two cases depending on the write and read clock. One case is when write clock is faster than the read clock and the other case is when the write clock is slower than the read clock. In addition, there are 6 different tests that can be simulated, regarding the values of the core's generics. Some of them remain stable throughout all the tests. These are:
- `g_data_width` : Data width set to 32-bits
- `g_size` : Size is set to 32-bits
- `g_with_wr_full` : Full signal for write side is always true
- `g_with_wr_empty` : Empty signals for write sige is always true
- `g_with_rd_empty` : Empty signal for read side is always true
- `g_with_rd_full` : Full signal for read side is always true
- `g_almost_empty_threshold` : Threshold for empty flag set to 2
- `g_almost_full_threshold` : Threshold for full signal set to 31
All the other generic values and the combination of them, create the 6 different test cases which are:
- `g_show_ahead` : true / false
- `g_with_wr_almost_full` : true / false
- `g_with_wr_almost_empty` : true / false
- `g_with_rd_almost_full` : true / false
- `g_with_rd_almost_empty` : true / false
NOTE: the option to have all of them as false would be a wrong option since, at least the full/empty signals are very important in the FIFO implementation and behavior.
OSVVM is used as the verification methodology. The inputs in the stimulus of the testbench are random with random seed for write and read side. In addition, these are the following assertions that exist in the testbench:
- The FIFO is not full after reset
- The FIFO is empty after reset
- We don't write to the FIFO when it is full
- We don't read from the FIFO when it is empty
- The input (valid) data is the same as the output (valid) data
#!/bin/bash -e
#This is a simple script to run simulations
#in GHDL
TB=tb_inferred_async_fifo
echo "Running simulation for $TB"
echo "Data width = 32 and size = 32"
echo "*******************************************************************************"
echo " Test case 1: Show ahead = TRUE "
echo " With almost empty and almost full logic for WR/RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=true -gg_with_rd_almost_full=true -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=true -gg_with_wr_almost_empty=true -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31
echo "*******************************************************************************"
echo " Test case 2: Show ahead = TRUE "
echo " NO almost empty and almost full logic for WR/RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=false -gg_with_rd_almost_full=false -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=false -gg_with_wr_almost_empty=false -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31
echo "*******************************************************************************"
echo " Test case 3: Show ahead = FALSE "
echo " With almost empty and almost full logic for WR/RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=false -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=true -gg_with_rd_almost_full=true -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=true -gg_with_wr_almost_empty=true -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31 --wave=waveform.ghw
echo "*******************************************************************************"
echo " Test case 4: Show ahead = FALSE "
echo " NO almost empty and almost full logic for WR/RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=false -gg_with_rd_almost_full=false -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=false -gg_with_wr_almost_empty=false -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31
echo "*******************************************************************************"
echo " Test case 5: Show ahead = TRUE "
echo " With almost empty and almost full logic for WR"
echo " NO almost empty and almost full logic for RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=false -gg_with_rd_almost_full=false -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=true -gg_with_wr_almost_empty=true -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31
echo "*******************************************************************************"
echo " Test case 6: Show ahead = TRUE "
echo " With almost empty and almost full logic for RD"
echo " NO almost empty and almost full logic for WR"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=true -gg_with_rd_almost_full=true -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=false -gg_with_wr_almost_empty=false -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31
action="simulation"
sim_tool="ghdl"
target="xilinx"
syn_device="xc6slx45t"
sim_top="tb_inferred_async_fifo_dual_rst"
ghdl_opt="--std=08 -frelaxed-rules"
files=["tb_inferred_async_fifo_dual_rst.vhd"]
modules={"local" : ["../../../../",
"../../../../modules/common",
"../../../../modules/genrams"]}
This is a testbench to verify the functionality of the inferred_async_dual_rst_fifo. It is a dual clock, dual reset reset Asynchronous FIFO and can be used in two cases depending on the write and read clock. One case is when write clock is faster than the read clock and the other case is when the write clock is slower than the read clock. In addition, there are 6 different tests that can be simulated, regarding the values of the core's generics. Some of them remain stable throughout all the tests. These are:
- `g_data_width` : Data width set to 32-bits
- `g_size` : Size is set to 32-bits
- `g_with_wr_full` : Full signal for write side is always true
- `g_with_wr_empty` : Empty signals for write sige is always true
- `g_with_rd_empty` : Empty signal for read side is always true
- `g_with_rd_full` : Full signal for read side is always true
- `g_almost_empty_threshold` : Threshold for empty flag set to 2
- `g_almost_full_threshold` : Threshold for full signal set to 31
All the other generic values and the combination of them, create the 6 different test cases which are:
- `g_show_ahead` : true / false
- `g_with_wr_almost_full` : true / false
- `g_with_wr_almost_empty` : true / false
- `g_with_rd_almost_full` : true / false
- `g_with_rd_almost_empty` : true / false
NOTE: the option to have all of them as false would be a wrong option since, at least the full/empty signals are very important in the FIFO implementation and behavior.
OSVVM is used as the verification methodology. The inputs in the stimulus of the testbench are random with random seed for write and read side. In addition, these are the following assertions that exist in the testbench:
- The FIFO is not full after reset
- The FIFO is empty after reset
- We don't write to the FIFO when it is full
- We don't read from the FIFO when it is empty
- The input (valid) data is the same as the output (valid) data
#!/bin/bash -e
#This is a simple script to run simulations in GHDL
TB=tb_inferred_async_fifo_dual_rst
echo "Running simulation for $TB"
echo "Data width = 32 and size = 32"
echo "*******************************************************************************"
echo " Test case 1: Show ahead = TRUE "
echo " With almost empty and almost full logic for WR/RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=true -gg_with_rd_almost_full=true -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=true -gg_with_wr_almost_empty=true -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31
echo "*******************************************************************************"
echo " Test case 2: Show ahead = TRUE "
echo " NO almost empty and almost full logic for WR/RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=false -gg_with_rd_almost_full=false -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=false -gg_with_wr_almost_empty=false -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31
echo "*******************************************************************************"
echo " Test case 3: Show ahead = FALSE "
echo " With almost empty and almost full logic for WR/RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=false -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=true -gg_with_rd_almost_full=true -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=true -gg_with_wr_almost_empty=true -gg_almost_empty_threshold=0 -gg_almost_full_threshold=31 -gg_with_wr_count=true -gg_with_rd_count=true
echo "*******************************************************************************"
echo " Test case 4: Show ahead = FALSE "
echo " NO almost empty and almost full logic for WR/RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=false -gg_with_rd_almost_full=false -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=false -gg_with_wr_almost_empty=false -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31
echo "*******************************************************************************"
echo " Test case 5: Show ahead = TRUE "
echo " With almost empty and almost full logic for WR"
echo " NO almost empty and almost full logic for RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=false -gg_with_rd_almost_full=false -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=true -gg_with_wr_almost_empty=true -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31
echo "*******************************************************************************"
echo " Test case 6: Show ahead = TRUE "
echo " With almost empty and almost full logic for RD"
echo " NO almost empty and almost full logic for WR"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=true -gg_with_rd_almost_full=true -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=false -gg_with_wr_almost_empty=false -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31
action="simulation"
sim_tool="ghdl"
target="xilinx"
syn_device="xc6slx45t"
sim_top="tb_inferred_sync_fifo"
ghdl_opt="--std=08 -frelaxed-rules"
files=["tb_inferred_sync_fifo.vhd"]
modules={"local" : ["../../../../",
"../../../../modules/common",
"../../../../modules/genrams"]}
This is a testbench to verify the functionality of inferred_sync_fifo core. It is a single clock/reset FIFO which is using the generic_dpram (with single clock functionality). Depending on the values of the generics there are 5 test cases that are being tested. The stable generics are:
- `g_data_width` : 32-bits
- `g_size` : 32
- `g_show_ahead` : true
- `g_with_full` : true
- `g_with_empty` : true
- `g_almost_full_threshold` : 0
- `g_almost_empty_threshold`: 0
So, the test cases of the testbench are a combination of the rest of the generics:
- `g_show_ahead_legacy_mode` : true / false
- `g_register_flag_outputs` : true / false
- `g_with_almost_full` : true / false (threshold for almost full flag)
- `g_with_almost_empty` : true / false (threshold for almost empty flag)
- `g_with_count` : true / false (words counter)
OSVVM is used as the verification methodology. The inputs in the stimulus of the testbench are random with random seed. In addition, these are the following assertions that exist in the testbench:
- The FIFO is not full after reset
- The FIFO is empty after reset
- We don't write to the FIFO when it is full
- We don't read from the FIFO when it is empty
- The input (valid) data is the same as the output (valid) data
In addition, some simple coverage analysis is taken into account in every test case:
- Write while FIFO is empty
- Write while FIFO is almost empty
- Write while FIFO is almost full
- Read while FIFO is full
- Read while FIFO is almost empty
- Read while FIFO is almost full
NOTE: In some of the test cases, it is possible that some of them would be 0. This is happening because in some of them for example, the almost empty/full flags are not used.
#!/bin/bash -e
#This is a simple script to run simulations
#in GHDL
TB=tb_inferred_sync_fifo
echo "Running simulation for $TB"
echo "Data width = 32 and size = 32"
echo "*******************************************************************************"
echo " Test case 1: Show ahead = TRUE, Show ahead legacy mode = TRUE"
echo " Register flag outputs = TRUE, "
echo " With no almost empty and almost full logic "
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_show_ahead_legacy_mode=true -gg_register_flag_outputs=true --wave=waveform.ghw
echo "*******************************************************************************"
echo " Test case 2: Show ahead = TRUE, Show ahead legacy mode = FALSE"
echo " Register flag outputs = TRUE, "
echo " With no almost empty and almost full logic "
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_show_ahead_legacy_mode=false -gg_register_flag_outputs=true --wave=waveform.ghw
echo "*******************************************************************************"
echo " Test case 3: Show ahead = TRUE, Show ahead legacy mode = FALSE"
echo " Register flag outputs = TRUE, "
echo " With almost empty and almost full logic "
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_show_ahead_legacy_mode=false -gg_register_flag_outputs=true -gg_with_almost_empty=true -gg_with_almost_full=true --wave=waveform.ghw
echo "*******************************************************************************"
echo " Test case 4: Show ahead = TRUE, Show ahead legacy mode = FALSE"
echo " Register flag outputs = FALSE, "
echo " With no almost empty and almost full logic "
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_show_ahead_legacy_mode=false -gg_register_flag_outputs=false -gg_with_count=true --wave=waveform.ghw
echo "*******************************************************************************"
echo " Test case 5: Show ahead = TRUE, Show ahead legacy mode = FALSE"
echo " Register flag outputs = FALSE, "
echo " With almost empty and almost full logic "
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_show_ahead_legacy_mode=false -gg_register_flag_outputs=false -gg_with_count=true -gg_with_almost_empty=true -gg_with_almost_full=true --wave=waveform.ghw
action="simulation"
sim_tool="ghdl"
target="generic"
sim_top="tb_generic_async_fifo"
ghdl_opt="--std=08 -frelaxed-rules"
files=["tb_generic_async_fifo.vhd"]
modules={"local" : ["../../../../",
"../../../../modules/common",
"../../../../modules/genrams"]}
This test is divided in 6 test cases, depending on the value we assign to the generics. Mostly, the RTL core is being simulated for all possible values that `g_show_ahead` can take and also when almost_full and almost_empty logic signals are being used.
OSVVM methodology is used and random values assigned to the input in every clock cycle. Coverage is provided (the results can be showned in the end of the test, in the terminal). What is covered is:
- Write while write side is empty
- Write while write side is almost empty
- Write while write side is almost full
- Read while read side is full
- Read while read side is almost empty
- Read while read side is almost full
Simple VHDL assertions are used in order to verify that:
- FIFO is not full after system reset
- FIFO is empty after system reset
- We don't write in a full FIFO
- We don't read an empty FIFO
Self - checking part of the testbench includes the logic where we verify that the incoming data, matches with the outcoming data
NOTE: This core has been tested also for both cross clocking domains, when fast -> slow clock domain and vice versa
#!/bin/bash -e
#This is a simple script to run simulations in GHDL
TB=tb_generic_async_fifo
echo "Running simulation for $TB"
echo "Data width = 32 and size = 32"
echo "*******************************************************************************"
echo " Test case 1: Show ahead = TRUE "
echo " With almost empty and almost full logic for WR/RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=true -gg_with_rd_almost_full=true -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=true -gg_with_wr_almost_empty=true -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31 --wave=waveform.ghw
echo "*******************************************************************************"
echo " Test case 2: Show ahead = TRUE "
echo " NO almost empty and almost full logic for WR/RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=false -gg_with_rd_almost_full=false -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=false -gg_with_wr_almost_empty=false -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31 --wave=waveform.ghw
echo "*******************************************************************************"
echo " Test case 3: Show ahead = FALSE "
echo " With almost empty and almost full logic for WR/RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=false -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=true -gg_with_rd_almost_full=true -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=true -gg_with_wr_almost_empty=true -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31 --wave=waveform.ghw
echo "*******************************************************************************"
echo " Test case 4: Show ahead = FALSE "
echo " NO almost empty and almost full logic for WR/RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=false -gg_with_rd_almost_full=false -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=false -gg_with_wr_almost_empty=false -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31 --wave=waveform.ghw
echo "*******************************************************************************"
echo " Test case 5: Show ahead = TRUE "
echo " With almost empty and almost full logic for WR"
echo " NO almost empty and almost full logic for RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=false -gg_with_rd_almost_full=false -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=true -gg_with_wr_almost_empty=true -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31 --wave=waveform.ghw
echo "*******************************************************************************"
echo " Test case 6: Show ahead = TRUE "
echo " With almost empty and almost full logic for RD"
echo " NO almost empty and almost full logic for WR"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=true -gg_with_rd_almost_full=true -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=false -gg_with_wr_almost_empty=false -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31 --wave=waveform.ghw
action="simulation"
sim_tool="ghdl"
target="xilinx"
syn_device="xc6slx45t"
sim_top="tb_generic_async_fifo_dual_rst"
ghdl_opt="--std=08 -frelaxed-rules"
files=["tb_generic_async_fifo_dual_rst.vhd"]
modules={"local" : ["../../../../modules/common",
"../../../../modules/genrams"]}
This is a testbench to verify the functionality of the generic_async_dual_rst_fifo. It is a dual clock, dual reset reset Asynchronous FIFO and can be used in two cases depending on the write and read clock. One case is when write clock is faster than the read clock and the other case is when the write clock is slower than the read clock. In addition, there are 6 different tests that can be simulated, regarding the values of the core's generics. Some of them remain stable throughout all the tests. These are:
- `g_data_width` : Data width set to 32-bits
- `g_size` : Size is set to 32-bits
- `g_with_wr_full` : Full signal for write side is always true
- `g_with_wr_empty` : Empty signals for write sige is always true
- `g_with_rd_empty` : Empty signal for read side is always true
- `g_with_rd_full` : Full signal for read side is always true
- `g_almost_empty_threshold` : Threshold for empty flag set to 2
- `g_almost_full_threshold` : Threshold for full signal set to 31
All the other generic values and the combination of them, create the 6 different test cases which are:
- `g_show_ahead` : true / false
- `g_with_wr_almost_full` : true / false
- `g_with_wr_almost_empty` : true / false
- `g_with_rd_almost_full` : true / false
- `g_with_rd_almost_empty` : true / false
NOTE: the option to have all of them as false would be a wrong option since, at least the full/empty signals are very important in the FIFO implementation and behavior.
OSVVM is used as the verification methodology. The inputs in the stimulus of the testbench are random with random seed for write and read side. In addition, these are the following assertions that exist in the testbench:
- The FIFO is not full after reset
- The FIFO is empty after reset
- We don't write to the FIFO when it is full
- We don't read from the FIFO when it is empty
- The input (valid) data is the same as the output (valid) data
#!/bin/bash -e
#This is a simple script to run simulations in GHDL
TB=tb_generic_async_fifo_dual_rst
echo "Running simulation for $TB"
echo "Data width = 32 and size = 32"
echo "*******************************************************************************"
echo " Test case 1: Show ahead = TRUE "
echo " With almost empty and almost full logic for WR/RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=true -gg_with_rd_almost_full=true -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=true -gg_with_wr_almost_empty=true -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31
echo "*******************************************************************************"
echo " Test case 2: Show ahead = TRUE "
echo " NO almost empty and almost full logic for WR/RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=false -gg_with_rd_almost_full=false -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=false -gg_with_wr_almost_empty=false -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31
echo "*******************************************************************************"
echo " Test case 3: Show ahead = FALSE "
echo " With almost empty and almost full logic for WR/RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=false -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=true -gg_with_rd_almost_full=true -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=true -gg_with_wr_almost_empty=true -gg_almost_empty_threshold=0 -gg_almost_full_threshold=31 -gg_with_wr_count=true -gg_with_rd_count=true
echo "*******************************************************************************"
echo " Test case 4: Show ahead = FALSE "
echo " NO almost empty and almost full logic for WR/RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=false -gg_with_rd_almost_full=false -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=false -gg_with_wr_almost_empty=false -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31
echo "*******************************************************************************"
echo " Test case 5: Show ahead = TRUE "
echo " With almost empty and almost full logic for WR"
echo " NO almost empty and almost full logic for RD"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=false -gg_with_rd_almost_full=false -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=true -gg_with_wr_almost_empty=true -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31
echo "*******************************************************************************"
echo " Test case 6: Show ahead = TRUE "
echo " With almost empty and almost full logic for RD"
echo " NO almost empty and almost full logic for WR"
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_wr=$RANDOM -gg_seed_rd=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_with_rd_empty=true -gg_with_rd_full=true -gg_with_rd_almost_empty=true -gg_with_rd_almost_full=true -gg_with_wr_empty=true -gg_with_wr_full=true -gg_with_wr_almost_full=false -gg_with_wr_almost_empty=false -gg_almost_empty_threshold=2 -gg_almost_full_threshold=31
action="simulation"
sim_tool="ghdl"
target="xilinx"
syn_device="xc6slx45t"
sim_top="tb_generic_sync_fifo"
ghdl_opt="--std=08 -frelaxed-rules"
files=["tb_generic_sync_fifo.vhd"]
modules={"local" : ["../../../../",
"../../../../modules/common",
"../../../../modules/genrams"]}
This test is divided in 5 test cases, depending on the value we assign to the generics. Mostly, the RTL core is being simulated for all possible values that `g_show_ahead` and `g_show_ahead_legacy_mode` can take and also when almost_full and almost_empty logic signals are being used.
OSVVM methodology is used and random values assigned to the input in every clock cycle. Coverage is provided (the results can be showned in the end of the test, in the terminal). What is covered is:
- if we write while write side is empty
- if we write while write side is almost empty
- if we write while write side is almost full
- if we read while read side is full
- if we read while read side is almost empty
- if we read while read side is almost full
Simple VHDL assertions are used in order to verify that:
- FIFO is not full after system reset
- FIFO is empty after system reset
- We don't write in a full FIFO
- We don't read an empty FIFO
Self - checking part of the testbench includes the logic where we verify that the incoming data, matches with the outcoming data
#!/bin/bash -e
#This is a simple script to run simulations in GHDL
TB=tb_generic_sync_fifo
echo "Running simulation for $TB"
echo "Data width = 32 and size = 32"
echo "*******************************************************************************"
echo " Test case 1: Show ahead = TRUE, Show ahead legacy mode = TRUE"
echo " Register flag outputs = TRUE, "
echo " With no almost empty and almost full logic "
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_show_ahead_legacy_mode=true -gg_register_flag_outputs=true
echo "*******************************************************************************"
echo " Test case 2: Show ahead = TRUE, Show ahead legacy mode = FALSE"
echo " Register flag outputs = TRUE, "
echo " With no almost empty and almost full logic "
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_show_ahead_legacy_mode=false -gg_register_flag_outputs=true
echo "*******************************************************************************"
echo " Test case 3: Show ahead = TRUE, Show ahead legacy mode = FALSE"
echo " Register flag outputs = TRUE, "
echo " With almost empty and almost full logic "
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_show_ahead_legacy_mode=false -gg_register_flag_outputs=true -gg_with_almost_empty=true -gg_with_almost_full=true
echo "*******************************************************************************"
echo " Test case 4: Show ahead = TRUE, Show ahead legacy mode = FALSE"
echo " Register flag outputs = FALSE, "
echo " With no almost empty and almost full logic "
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_show_ahead_legacy_mode=false -gg_register_flag_outputs=false -gg_with_count=true
echo "*******************************************************************************"
echo " Test case 5: Show ahead = TRUE, Show ahead legacy mode = FALSE"
echo " Register flag outputs = FALSE, "
echo " With almost empty and almost full logic "
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_data_width=32 -gg_size=32 -gg_show_ahead=true -gg_show_ahead_legacy_mode=false -gg_register_flag_outputs=false -gg_with_count=true -gg_with_almost_empty=true -gg_with_almost_full=true
action="simulation"
sim_tool="ghdl"
target="xilinx"
syn_device="xc6slx45t"
sim_top="tb_gc_shiftreg"
ghdl_opt="--std=08 -frelaxed-rules"
files=["tb_gc_shiftreg.vhd"]
modules={"local" : ["../../../../",
"../../../../modules/common",
"../../../../modules/genrams"]}
Testbench for a generic shift register. The methodology that is using is OSVVM with random input signals in every clock cycle. Different test cases can be produced, if the value of the generic `g_size` changed. Here, two test cases are examined when g_size = 64 and 128 bits.
Test process: In every clock cycle, random values are given to enable, data and address. Then the testbench generates the output. The self-checking process is that there is an assertion used to compare in every clock that the output of the RTL code and the testbench is the same. Another assertion, checks that the value of g_size is bigger than 32 bits and is derivative of 64.
#!/bin/bash -e
#This is a simple script to run simulations
#in GHDL
TB=tb_gc_shiftreg
echo "Running simulation for $TB"
echo "Test case 1: Size = 64 bits"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_size=64
echo "***********************************************************"
echo "Test case 2: Size = 128 bits"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_size=128
echo "***********************************************************"
--------------------------------------------------------------------------------
-- CERN BE-CEM-EDL
-- General Cores Library
-- https://www.ohwr.org/projects/general-cores
--------------------------------------------------------------------------------
--
-- unit name: tb_gc_shiftreg
--
-- author: Konstantinos Blantos
--
-- description: Testbench for a generic shift register
--
--------------------------------------------------------------------------------
-- Copyright CERN 2011-2018
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------
--==============================================================================
-- Libraries & Packages --
--==============================================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.genram_pkg.all;
--OSVMM library
library osvvm;
use osvvm.RandomPkg.all;
use osvvm.CoveragePkg.all;
--=============================================================================
-- Entity declaration for tb_gc_shiftreg --
--=============================================================================
entity tb_gc_shiftreg is
generic (
g_seed : natural;
g_size : integer);
end entity;
--==============================================================================
-- Architecture declaration --
--==============================================================================
architecture tb of tb_gc_shiftreg is
-- constants
constant C_CLK_PERIOD : time := 10 ns;
-- signals
signal tb_clk_i : std_logic;
signal tb_en_i : std_logic;
signal tb_d_i : std_logic;
signal tb_q_o : std_logic;
signal tb_a_i : std_logic_vector(f_log2_size(g_size)-1 downto 0);
signal stop : boolean;
signal s_q_o : std_logic;
signal s_dat_o : std_logic_vector(g_size-1 downto 0);
begin
-- Unit Under Test
UUT : entity work.gc_shiftreg
generic map (
g_size => g_size)
port map (
clk_i => tb_clk_i,
en_i => tb_en_i,
d_i => tb_d_i,
q_o => tb_q_o,
a_i => tb_a_i);
-- Clock process
clk_proc : 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 clk_proc;
--------------------------------------------------------------------------------
-- Stimulus --
--------------------------------------------------------------------------------
stim : process
variable data : RandomPType;
variable ncycles : natural;
begin
data.InitSeed(g_seed);
report "[STARTING] with seed = " & integer'image(g_seed);
while (NOW < 2 ms) loop
wait until rising_edge(tb_clk_i);
tb_en_i <= data.randSlv(1)(1);
tb_d_i <= data.randSlv(1)(1);
tb_a_i <= data.randSlv(f_log2_size(g_size));
ncycles := ncycles + 1;
end loop;
report "Number of simulation cycles = " & to_string(ncycles);
stop <= TRUE;
report "Test PASS!";
wait;
end process stim;
--------------------------------------------------------------------------------
-- Assertions --
--------------------------------------------------------------------------------
-- Geneerate the output data of the testbench
g_size_big : if (g_size > 32) generate
process
begin
while not stop loop
wait until rising_edge(tb_clk_i);
if (tb_en_i = '1') then
s_dat_o <= s_dat_o(s_dat_o'left - 1 downto 0) & tb_d_i;
end if;
end loop;
wait;
end process;
s_q_o <= s_dat_o(to_integer(unsigned(tb_a_i)));
end generate;
--------------------------------------------------------------------------------
-- Assertions --
--------------------------------------------------------------------------------
-- Assure that size is derivative of 64
assert (g_size >32 AND (g_size mod 64) = 0)
report "Wrong size" severity failure;
-- Comparison between RTL and TB output
process(tb_clk_i)
begin
if rising_edge(tb_clk_i) then
assert (s_q_o = tb_q_o)
report "Data mismatch" severity failure;
end if;
end process;
end tb;
action="simulation"
sim_tool="ghdl"
target="xilinx"
syn_device="xc6slx45t"
sim_top="tb_generic_dpram"
ghdl_opt="--std=08 -frelaxed-rules"
files=["tb_generic_dpram.vhd"]
modules={"local" : ["../../../../",
"../../../../modules/common"]}
This is a testbench to test and verify, the behavior of the generic_dpram. Since, it depends on the generic values, how the user can use this core, there are 4 different test cases tested. The generic that remain constant are:
- `g_data_width` : 32 bits
- `g_size` : 32 bits
- `g_addr_conflict_resolution` : "read_first"
- `g_init_file` : ""
- `g_fail_if_file_not_found` : true
So, the only generics that change are:
- `g_with_byte_enable` : true/false
- `g_dual_clock` : true/false
Two diffent stimulus exist for the port A and B of the dpram. OSVVM methodology is being used and randomized seed for the inputs. There are three different ways of using this core, dual clock, single clock and splitram. The testbench receives only random input and later (through assertions) it compare the output of the testbench with the one from RTL, no matter what approach is being tested.
#!/bin/bash -e
#This is a simple script to run simulations in GHDL
TB=tb_generic_dpram
echo "Running simulation for $TB"
echo "Data width = 32 and size = 32"
#gen_dual_clock is going to be generated
echo "*******************************************************************************"
echo " Test case 1: With byte enable = false "
echo " Dual clock = true, "
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_a=$RANDOM -gg_seed_b=$RANDOM -gg_data_width=32 -gg_size=32 -gg_with_byte_enable=false -gg_dual_clock=true
#gen_splitram is going to be generated
echo "*******************************************************************************"
echo " Test case 2: With byte enable = true "
echo " Dual clock = false "
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_a=$RANDOM -gg_seed_b=$RANDOM -gg_data_width=32 -gg_size=32 -gg_with_byte_enable=true -gg_dual_clock=false
#gen_dual_clk is going to be generated
echo "*******************************************************************************"
echo " Test case 3: With byte enable = true "
echo " Dual clock = true "
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_a=$RANDOM -gg_seed_b=$RANDOM -gg_data_width=32 -gg_size=32 -gg_with_byte_enable=true -gg_dual_clock=true
#gen_single_clock is going to be generated
echo "*******************************************************************************"
echo " Test case 4: With byte enable = false "
echo " Dual clock = false "
echo "*******************************************************************************"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_a=$RANDOM -gg_seed_b=$RANDOM -gg_data_width=32 -gg_size=32 -gg_with_byte_enable=false -gg_dual_clock=false
This diff is collapsed.
action="simulation"
sim_tool="ghdl"
target="xilinx"
syn_device="xc6slx45t"
sim_top="tb_generic_dpram_dualclock"
ghdl_opt="--std=08 -frelaxed-rules"
files=["tb_generic_dpram_dualclock.vhd"]
modules={"local" : ["../../../../",
"../../../../modules/common",
"../../../../modules/genrams"]}
This is a testbench to test and verify, the behavior of the generic_dpram_dualclock. Since, it depends on the generic values, how the user can use this core, there are 6 different test cases tested. The generic that remain constant are:
- `g_data_width` : 32 bits
- `g_size` : 32 bits
- `g_addr_conflict_resolution` : "read_first"
- `g_init_file` : ""
- `g_fail_if_file_not_found` : true
So, the only generics that change are:
- `g_with_byte_enable` : true/false
- `g_addr_conflict_resolution` : "read_first" / "write_first" / "don't care"
Two diffent stimulus exist for the port A and B of the dpram. OSVVM methodology is being used and randomized seed for the inputs. The testbench receives only random input and later (through assertions) it compare the output of the testbench with the one from RTL, no matter what approach is being tested. This comparison is done with both RAM A and B.
#!/bin/bash -e
#This is a simple script to run simulations
#in GHDL
TB=tb_generic_dpram_dualclock
echo "Running simulation for $TB"
echo "Data width = 32 and size = 64"
echo "Test case 1: With byte enable and don't care address conflict resolution"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_a=$RANDOM -gg_seed_b=$RANDOM -gg_data_width=32 -gg_size=64 -gg_with_byte_enable=true -gg_addr_conflict_resolution="dont_care"
echo "*******************************************************************************"
echo "Test case 2: With byte enable and read first address conflict resolution"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_a=$RANDOM -gg_seed_b=$RANDOM -gg_data_width=32 -gg_size=64 -gg_with_byte_enable=true -gg_addr_conflict_resolution="read_first"
echo "*******************************************************************************"
echo "Test case 3: No byte enable and read first address conflict resolution"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_a=$RANDOM -gg_seed_b=$RANDOM -gg_data_width=32 -gg_size=64 -gg_with_byte_enable=false -gg_addr_conflict_resolution="read_first"
echo "*******************************************************************************"
echo "Test case 4: No byte enable and don't care address conflict resolution"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_a=$RANDOM -gg_seed_b=$RANDOM -gg_data_width=32 -gg_size=64 -gg_with_byte_enable=false -gg_addr_conflict_resolution="dont_care"
echo "*******************************************************************************"
echo "Test case 5: No byte enable and write first address conflict resolution"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_a=$RANDOM -gg_seed_b=$RANDOM -gg_data_width=32 -gg_size=64 -gg_with_byte_enable=false -gg_addr_conflict_resolution="write_first"
echo "*******************************************************************************"
echo "Test case 6: No byte enable and no change address conflict resolution"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed_a=$RANDOM -gg_seed_b=$RANDOM -gg_data_width=32 -gg_size=64 -gg_with_byte_enable=false -gg_addr_conflict_resolution="no_change"
echo "*******************************************************************************"
action="simulation"
sim_tool="ghdl"
target="xilinx"
syn_device="xc6slx45t"
sim_top="tb_generic_dpram_sameclock"
ghdl_opt="--std=08 -frelaxed-rules"
files=["tb_generic_dpram_sameclock.vhd"]
modules={"local" : ["../../../../",
"../../../../modules/common",
"../../../../modules/genrams"]}
This is a testbench to test and verify, the behavior of the generic_dpram_sameclock. Since, it depends on the generic values, how the user can use this core, there are 7 different test cases tested. The generic that remain constant are:
- `g_data_width` : 32 bits
- `g_size` : 32 bits
- `g_init_file` : ""
- `g_fail_if_file_not_found` : true
So, the only generics that change are:
- `g_with_byte_enable` : true/false
- `g_addr_conflict_resolution` : "read_first" / "write_first" / "don't care" / "no_change"
One stimulus exist since there is only one clock domain. OSVVM methodology is being used and randomized seed for the inputs. The testbench receives only random input and later (through assertions) it compares the output of the testbench with the one from RTL depending on the test case that is being tested. Two assertions exist, one for each RAM port.
#!/bin/bash -e
#This is a simple script to run simulations
#in GHDL
TB=tb_generic_dpram_sameclock
echo "Running simulation for $TB"
echo "Data width = 32 and size = 64"
echo "Test case 1: No byte enable and no change in address conflict resolution"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_data_width=32 -gg_size=64 -gg_with_byte_enable=false -gg_addr_conflict_resolution="no_change"
echo "*******************************************************************************"
echo "Test case 2: With byte enable and write first in address conflict resolution"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_data_width=32 -gg_size=64 -gg_with_byte_enable=true -gg_addr_conflict_resolution="write_first"
echo "*******************************************************************************"
echo "Test case 3: No byte enable and write first in address conflict resolution"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_data_width=32 -gg_size=64 -gg_with_byte_enable=false -gg_addr_conflict_resolution="write_first"
echo "*******************************************************************************"
echo "Test case 4: No byte enable and Read first in address conflict resolution"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_data_width=32 -gg_size=64 -gg_with_byte_enable=false -gg_addr_conflict_resolution="read_first"
echo "*******************************************************************************"
echo "Test case 5: No byte enable and don't care what is the address conflict resolution"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_data_width=32 -gg_size=64 -gg_with_byte_enable=false -gg_addr_conflict_resolution="dont_care"
echo "*******************************************************************************"
echo "Test case 6: With byte enable and don't care what is the address conflict resolution"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_data_width=32 -gg_size=64 -gg_with_byte_enable=true -gg_addr_conflict_resolution="dont_care"
echo "*******************************************************************************"
echo "Test case 7: With byte enable and read first in address conflict resolution"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM -gg_data_width=32 -gg_size=64 -gg_with_byte_enable=true -gg_addr_conflict_resolution="read_first"
echo "*******************************************************************************"
action="simulation"
sim_tool="ghdl"
target="xilinx"
syn_device="xc6slx45t"
sim_top="tb_generic_dpram_split"
ghdl_opt="--std=08 -frelaxed-rules"
files=["tb_generic_dpram_split.vhd"]
modules={"local" : ["../../../../",
"../../../../modules/common",
"../../../../modules/genrams"]}
This is a testbench to test and verify, the behavior of the generic_dpram_split. There is only one testcase being tested since the generic values have chosen to remain stabel (as there can not be generated other test cases from them):
- g_size = 16384
- g_addr_conflict_resolution = "read_first"
- g_init_file = ""
- g_fail_if_file_not_found = true
One stimulus exist since there is only one clock domain. OSVVM methodology is being used and randomized seed for the inputs. The testbench receives only random input and later (through assertions) it compares the output of the testbench with the one from RTL depending on the test case that is being tested. Two assertions exist, one for each RAM port.
#!/bin/bash -e
#This is a simple script to run simulations
#in GHDL
TB=tb_generic_dpram_split
echo "Running simulation for $TB"
ghdl -r --std=08 -frelaxed-rules $TB -gg_seed=$RANDOM
echo "*******************************************************************************"
---------------------------------------------------------------------------------
-- CERN BE-CEM-EDL
-- General Cores Library
-- https://www.ohwr.org/projects/general-cores
--------------------------------------------------------------------------------
--
-- unit name: tb_generic_dpram_split
--
-- authos: Konstantinos Blantos
--
-- description: Testbench for generic dpram split core. Develop a 3-D array in
-- order to simulate the RTL behavior and compare the RTL outputs
-- with the outputs from the Testbench.
--
--------------------------------------------------------------------------------
-- Copyright CERN 2017-2018
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------
--==============================================================================
-- Libraries & Packages --
--==============================================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.genram_pkg.all;
use work.memory_loader_pkg.all;
--OSVMM library
library osvvm;
use osvvm.RandomPkg.all;
use osvvm.CoveragePkg.all;
--=============================================================================
-- Entity declaration for tb_generic_dpram_split --
--=============================================================================
entity tb_generic_dpram_split is
generic (
g_seed : natural;
g_size : natural := 16384;
g_addr_conflict_resolution : string := "read_first";
g_init_file : string := "";
g_fail_if_file_not_found : boolean := true);
end entity;
--==============================================================================
-- Architecture declaration --
--==============================================================================
architecture tb of tb_generic_dpram_split is
constant C_CLK_PERIOD : time := 10 ns;
constant c_data_width : integer := 32;
constant c_num_bytes : integer := (c_data_width+7)/8; --4(?)
signal tb_rst_n_i : std_logic;
signal tb_clk_i : std_logic;
-- Port A
signal tb_bwea_i : std_logic_vector(3 downto 0);
signal tb_wea_i : std_logic;
signal tb_aa_i : std_logic_vector(f_log2_size(g_size)-1 downto 0);
signal tb_da_i : std_logic_vector(31 downto 0);
signal tb_qa_o : std_logic_vector(31 downto 0);
-- Port B
signal tb_bweb_i : std_logic_vector(3 downto 0);
signal tb_web_i : std_logic;
signal tb_ab_i : std_logic_vector(f_log2_size(g_size)-1 downto 0);
signal tb_db_i : std_logic_vector(31 downto 0);
signal tb_qb_o : std_logic_vector(31 downto 0);
-- Signals used in testbench
signal stop : boolean;
signal s_dat_a : std_logic_vector(31 downto 0) := (others=>'0');
signal s_dat_b : std_logic_vector(31 downto 0) := (others=>'0');
signal s_we_a : std_logic_vector(c_num_bytes-1 downto 0) := (others=>'0');
signal s_we_b : std_logic_vector(c_num_bytes-1 downto 0) := (others=>'0');
signal wea_rep : std_logic_vector(c_num_bytes-1 downto 0) := (others=>'0');
signal web_rep : std_logic_vector(c_num_bytes-1 downto 0) := (others=>'0');
signal s_int_a : natural;
signal s_int_b : natural;
-- Type of the RAM
type t_split_ram is array(0 to g_size-1) of std_logic_vector(7 downto 0);
-- Functions
impure function f_file_to_ramtype(idx : integer) return t_split_ram is
variable tmp : t_split_ram;
variable mem8 : t_ram8_type(0 to g_size-1);
begin
-- If no file was given, there is nothing to convert, just return
if (g_init_file = "" or g_init_file = "none") then
tmp := (others=>(others=>'0'));
return tmp;
end if;
mem8 := f_load_mem32_from_file_split(g_init_file, g_size, g_fail_if_file_not_found, idx);
return t_split_ram(mem8);
end f_file_to_ramtype;
impure function f_file_contents return t_meminit_array is
begin
return f_load_mem_from_file(g_init_file, g_size, c_data_width, g_fail_if_file_not_found);
end f_file_contents;
type t_split_ram_array is array(0 to 3) of t_split_ram;
shared variable s_ram : t_split_ram_array := (f_file_to_ramtype(0),
f_file_to_ramtype(1),
f_file_to_ramtype(2),
f_file_to_ramtype(3));
begin
-- Unit Under Test
UUT : entity work.generic_dpram_split
generic map (
g_size => g_size,
g_addr_conflict_resolution => g_addr_conflict_resolution,
g_init_file => g_init_file,
g_fail_if_file_not_found => g_fail_if_file_not_found)
port map (
rst_n_i => tb_rst_n_i,
clk_i => tb_clk_i,
bwea_i => tb_bwea_i,
wea_i => tb_wea_i,
aa_i => tb_aa_i,
da_i => tb_da_i,
qa_o => tb_qa_o,
bweb_i => tb_bweb_i,
web_i => tb_web_i,
ab_i => tb_ab_i,
db_i => tb_db_i,
qb_o => tb_qb_o);
-- Clock and reset
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;
end loop;
wait;
end process clk_proc;
tb_rst_n_i <= '0', '1' after 2 * C_CLK_PERIOD;
-- Stimulus
stim : process
variable data : RandomPType;
variable ncycles : natural;
begin
data.InitSeed(g_seed);
report "[STARTING] with seed = " & integer'image(g_seed);
wait until tb_rst_n_i = '1';
while (NOW < 0.5 ms) loop
wait until rising_edge(tb_clk_i);
tb_bwea_i <= data.randSlv(4);
tb_wea_i <= data.randSlv(1)(1);
tb_aa_i <= data.randSlv(f_log2_size(g_size));
tb_da_i <= data.randSlv(32);
tb_bweb_i <= data.randSlv(4);
tb_web_i <= data.randSlv(1)(1);
tb_ab_i <= data.randSlv(f_log2_size(g_size));
tb_db_i <= data.randSlv(32);
ncycles := ncycles + 1;
wait for C_CLK_PERIOD;
end loop;
report "Number of simulation cycles = " & to_string(ncycles);
stop <= TRUE;
report "Test PASS!";
wait;
end process stim;
--------------------------------------------------------------------------------
-- Testbench behavior --
--------------------------------------------------------------------------------
wea_rep <= (others => tb_wea_i);
s_we_a <= tb_bwea_i and wea_rep;
web_rep <= (others => tb_web_i);
s_we_b <= tb_bweb_i and web_rep;
s_int_a <= f_check_bounds(to_integer(unsigned(tb_aa_i)), 0, g_size-1);
s_int_b <= f_check_bounds(to_integer(unsigned(tb_ab_i)), 0, g_size-1);
-- Processes to create two RAMs to store the data
ram_port_a_and_b : for i in 0 to 3 generate
port_a : process(tb_clk_i)
begin
if (rising_edge(tb_clk_I)) then
s_dat_a((i+1)*8-1 downto i*8) <= s_ram(i)(s_int_a);
if (s_we_a(i) = '1') then
s_ram(i)(s_int_a) := tb_da_i((i+1)*8-1 downto i*8);
end if;
end if;
end process;
end generate;
ram_port_b : for j in 0 to 3 generate
port_b : process(tb_clk_i)
begin
if (rising_edge(tb_clk_i)) then
s_dat_b((j+1)*8-1 downto j*8) <= s_ram(j)(s_int_b);
if (s_we_b(j) = '1') then
s_ram(j)(s_int_b) := tb_db_i((j+1)*8-1 downto j*8);
end if;
end if;
end process;
end generate;
--------------------------------------------------------------------------------
-- Assertions --
--------------------------------------------------------------------------------
-- Compare the testbench's RAM_A with the RTL output for port A
check_port_a : process(tb_clk_i)
begin
if (rising_edge(tb_clk_i)) then
if (tb_rst_n_i = '1') then
assert (tb_qa_o = s_dat_a)
report "Data mismatch in Port_A" severity failure;
end if;
end if;
end process;
-- Compare the testbench's RAM_B with the RTL output for port B
check_port_b : process(tb_clk_i)
begin
if (rising_edge(tb_clk_i)) then
if (tb_rst_n_i = '1') then
assert (tb_qb_o = s_dat_b)
report "Data mismatch in Port B" severity failure;
end if;
end if;
end process;
end tb;
action="simulation"
sim_tool="ghdl"
target="xilinx"
syn_device="xc6slx45t"
sim_top="tb_generic_simple_dpram"
ghdl_opt="--std=08 -frelaxed-rules"
files=["tb_generic_simple_dpram.vhd"]
modules={"local" : ["../../../../"]}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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