Open Source VHDL Verification Methodology/Пример использования OS-VVM/Пример 2
Материал из Wiki
Проект OS-VVM
Исходные коды
- Пример использования OS-VVM
- Пример 2 (Интеллектуальный ТБ)
Презентации
Coverage
Содержание |
Листинги 1
-- Для покрытия всех пар состояний требуется 1615 циклов -- покрытие A достигается за 103 циклов -- покрытие B достикается за 68 циклов
Листинг файла testbench(tb1)
| Файл: tstb_tb1.vhd |
-- Для покрытия всех пар состояний требуется 1615 циклов -- покрытие A достигается за 103 циклов -- покрытие B достикается за 68 циклов library ieee; use ieee.std_logic_1164.all; use ieee.math_real.all; use ieee.numeric_std.all; use work.RandomPkg.all; use work.CoveragePkg.all; entity testbench is end; architecture tb1 of testbench is component sxema port (a, b : in std_logic_vector (4 downto 1); d : out std_logic_vector (8 downto 1)); end component; signal a, b : std_logic_vector (4 downto 1); signal d : std_logic_vector (8 downto 1); shared variable CovA, CovB : CovPType; shared variable CovD : CovPType; shared variable CovCrossAB : CovPType; begin p0 : sxema port map ( a => a, b => b, d => d); RandomGenProc1 : process variable RndValA, RndValB : real; -- Random value variable RndA, RndB : integer; variable SeedA1 : positive := 7; -- initialize seeds variable SeedA2 : positive := 1; variable SeedB1 : positive := 4; -- initialize seeds variable SeedB2 : positive := 2; variable i : natural := 0; variable CovACovered, CovBCovered : natural := 0; begin -- создание корзин для a, b, d CovA.AddBins(GenBin(0, 15)); CovB.AddBins(GenBin(0, 15)); CovD.AddBins(GenBin(0, 225)); CovCrossAB.AddCross(GenBin(0, 15), GenBin(0, 15)); MainCovLoop : while not (CovCrossAB.IsCovered) loop uniform(SeedA1, SeedA2, RndValA); -- randomize 0.0 to 1.0 uniform(SeedB1, SeedB2, RndValB); -- randomize 0.0 to 1.0 RndA := integer(trunc(RndValA*16.0)); -- scale to 0 to 15 RndB := integer(trunc(RndValB*16.0)); -- scale to 0 to 15 a <= std_logic_vector(to_unsigned(RndA, 4)); b <= std_logic_vector(to_unsigned(RndB, 4)); wait for 10 ns; CovA.ICover(to_integer(unsigned(a))); CovB.ICover(to_integer(unsigned(b))); CovCrossAB.ICover((to_integer(unsigned(a)), to_integer(unsigned(b)))); CovD.ICover(to_integer(unsigned(d))); i := i+1; if (CovA.IsCovered and CovACovered = 0) then CovACovered := i; end if; if (CovB.IsCovered and CovBCovered = 0) then CovBCovered := i; end if; end loop; wait for 10 ns; CovA.WriteBin; CovB.WriteBin; CovD.WriteBin; CovCrossAB.WriteBin; CovA.WriteCovDb ("tb1_CovA.db", OpenKind => write_mode); CovB.WriteCovDb ("tb1_CovB.db", OpenKind => write_mode); CovD.WriteCovDb ("tb1_CovD.db", OpenKind => write_mode); CovCrossAB.WriteCovDb ("tb1_CovCrossAB.db", OpenKind => write_mode); wait; end process; end architecture tb1; |
Листинг файла testbench(tb1a)
-- Для покрытия всех пар состояний требуется 1615 циклов-- покрытие A достигается за 103 циклов-- покрытие B достикается за 68 цикловlibrary ieee;
use ieee.std_logic_1164.all;
use ieee.math_real.all;
use ieee.numeric_std.all;
entity testbench is
end;
architecture tb1a of testbench is
component sxemaport (a, b : in std_logic_vector (4 downto 1);
d : out std_logic_vector (8 downto 1));
end component;
signal a, b : std_logic_vector (4 downto 1);
signal d : std_logic_vector (8 downto 1);
shared variable CovA, CovB : integer_vector (0 to 15) := (others => 0);
shared variable CovCrossAB : integer_vector (0 to 255) := (others => 0);
beginp0 : sxemaport map (a => a, b => b, d => d);
RandomGenProc1 : process
variable RndValA, RndValB : real; -- Random value
variable RndA, RndB, a_i, b_i : integer;
variable SeedA1 : positive := 7; -- initialize seeds
variable SeedA2 : positive := 1;
variable SeedB1 : positive := 4; -- initialize seeds
variable SeedB2 : positive := 2;
variable i : natural := 0;
variable CovACovered, CovBCovered : natural := 0;
variable CovCrossABCovered : natural := 0;
begin-- создание корзин для a, b, dMainCovLoop : while not (CovCrossABCovered = 1) loop
uniform(SeedA1, SeedA2, RndValA); -- randomize 0.0 to 1.0
uniform(SeedB1, SeedB2, RndValB); -- randomize 0.0 to 1.0
RndA := integer(trunc(RndValA*16.0)); -- scale to 0 to 15
RndB := integer(trunc(RndValB*16.0)); -- scale to 0 to 15
a <= std_logic_vector(to_unsigned(RndA, 4));
b <= std_logic_vector(to_unsigned(RndB, 4));
wait for 10 ns;
a_i := to_integer(unsigned(a));
b_i := to_integer(unsigned(b));
CovA(a_i) := CovA(a_i) + 1 ;
CovB(b_i) := CovB(b_i) + 1 ;
CovCrossAB(b_i*16+a_i) := CovCrossAB(b_i*16+a_i) + 1;
i := i+1;
if i = 1000000 then
exit;
end if;
CovACovered := 1;
for j in 0 to 15 loop
if CovA(j)=0 then
CovACovered := 0;
end if;
end loop; -- j
CovBCovered := 1;
for j in 0 to 15 loop
if CovB(j)=0 then
CovBCovered := 0;
end if;
end loop; -- j
CovCrossABCovered := 1;
for j in 0 to 255 loop
if CovCrossAB(j)=0 then
CovCrossABCovered := 0;
end if;
end loop; -- j
end loop;
wait for 10 ns;
wait;
end process;
end architecture tb1a;
Распределение покрытия CovA

Распределение покрытия CovB

Распределение покрытия CovD

Распределение покрытия CovCrossAB (3D)
|
|
|---|
Листинги 2
-- Для покрытия всех пар состояний требуется 1615 циклов -- покрытие A достигается за 103 циклов -- покрытие B достикается за 68 циклов
Листинг файла testbench(tb2)
| Файл: tstb_tb2.vhd |
-- Для покрытия всех пар состояний требуется 1615 циклов -- покрытие A достигается за 103 циклов -- покрытие B достикается за 68 циклов library ieee; use ieee.std_logic_1164.all; use ieee.math_real.all; use ieee.numeric_std.all; use work.RandomPkg.all; use work.CoveragePkg.all; entity testbench is end; architecture tb2 of testbench is component sxema port (a, b : in std_logic_vector (4 downto 1); d : out std_logic_vector (8 downto 1)); end component; signal a, b : std_logic_vector (4 downto 1); signal d : std_logic_vector (8 downto 1); shared variable RndA, RndB : RandomPType; shared variable CovA, CovB : CovPType; shared variable CovD : CovPType; shared variable CovCrossAB : CovPType; begin p0 : sxema port map ( a => a, b => b, d => d); RandomGenProc1 : process variable SeedA1 : positive := 7; -- initialize seeds variable SeedA2 : positive := 1; variable SeedB1 : positive := 4; -- initialize seeds variable SeedB2 : positive := 2; variable i : natural := 0; variable CovACovered, CovBCovered : natural := 0; begin -- инициализация генератора псевдослучайных чисел RndA.InitSeed(IV => (SeedA1, SeedA2)); RndB.InitSeed(IV => (SeedB1, SeedB2)); -- создание корзин для a, b, d CovA.AddBins(GenBin(0, 15)); CovB.AddBins(GenBin(0, 15)); CovD.AddBins(GenBin(0, 225)); CovCrossAB.AddCross(GenBin(0, 15), GenBin(0, 15)); MainCovLoop : while not (CovCrossAB.IsCovered) loop a <= RndA.RandSlv(0, 15, 4); b <= RndB.RandSlv(0, 15, 4); wait for 10 ns; CovA.ICover(to_integer(unsigned(a))); CovB.ICover(to_integer(unsigned(b))); CovCrossAB.ICover((to_integer(unsigned(a)), to_integer(unsigned(b)))); CovD.ICover(to_integer(unsigned(d))); i := i+1; if (CovA.IsCovered and CovACovered = 0) then CovACovered := i; end if; if (CovB.IsCovered and CovBCovered = 0) then CovBCovered := i; end if; end loop; wait for 10 ns; CovA.WriteBin; CovB.WriteBin; CovD.WriteBin; CovCrossAB.WriteBin; CovA.WriteCovDb ("tb2_CovA.db", OpenKind => write_mode); CovB.WriteCovDb ("tb2_CovB.db", OpenKind => write_mode); CovD.WriteCovDb ("tb2_CovD.db", OpenKind => write_mode); CovCrossAB.WriteCovDb ("tb2_CovCrossAB.db", OpenKind => write_mode); wait; end process; end architecture tb2; |
Листинги 3
Листинг файла testbench(tb3)
| Файл: tstb_tb3.vhd |
-- Случайным образом генерит входные A и B с помощью пакета покрытия, используя перекрёстное покрытие -- т.е. интеллектуальный тестбенч для перебора всех пар -- Для покрытия всех пар состояний требуется 256 циклов -- покрытие A достигается за 49 циклов -- покрытие B достикается за 44 циклов library ieee; use ieee.std_logic_1164.all; use ieee.math_real.all; use ieee.numeric_std.all; use work.RandomPkg.all; use work.CoveragePkg.all; entity testbench is end; architecture tb3 of testbench is component sxema port (a, b : in std_logic_vector (4 downto 1); d : out std_logic_vector (8 downto 1)); end component; signal a, b : std_logic_vector (4 downto 1); signal d : std_logic_vector (8 downto 1); -- shared variable RndA, RndB : RandomPType; shared variable CovA, CovB, CovD : CovPType; shared variable CovCrossAB : CovPType; begin p0 : sxema port map ( a => a, b => b, d => d); RandomGenProc1 : process variable RndA, RndB : integer; variable SeedA1 : positive := 7; -- initialize seeds variable SeedA2 : positive := 1; variable SeedB1 : positive := 4; -- initialize seeds variable SeedB2 : positive := 2; variable i : natural := 0; variable CovACovered, CovBCovered : natural := 0; begin -- инициализация генератора псевдослучайных чисел CovCrossAB.InitSeed(CovCrossAB'instance_name); -- создание корзин для a, b, d CovA.AddBins(GenBin(0, 15)); CovB.AddBins(GenBin(0, 15)); CovD.AddBins(GenBin(0, 225)); CovCrossAB.AddCross(GenBin(0, 15), GenBin(0, 15)); MainCovLoop : while not (CovCrossAB.IsCovered) loop (RndA, RndB) := CovCrossAB.RandCovPoint; a <= std_logic_vector(to_unsigned(RndA, 4)); b <= std_logic_vector(to_unsigned(RndB, 4)); wait for 10 ns; CovA.ICover(to_integer(unsigned(a))); CovB.ICover(to_integer(unsigned(b))); CovCrossAB.ICover((to_integer(unsigned(a)), to_integer(unsigned(b)))); CovD.ICover(to_integer(unsigned(d))); i := i+1; if (CovA.IsCovered and CovACovered = 0) then CovACovered := i; end if; if (CovB.IsCovered and CovBCovered = 0) then CovBCovered := i; end if; end loop; wait for 10 ns; CovA.WriteBin; CovB.WriteBin; CovD.WriteBin; CovCrossAB.WriteBin; CovA.WriteCovDb ("tb3_CovA.db", OpenKind => write_mode); CovB.WriteCovDb ("tb3_CovB.db", OpenKind => write_mode); CovD.WriteCovDb ("tb3_CovD.db", OpenKind => write_mode); CovCrossAB.WriteCovDb ("tb3_CovCrossAB.db", OpenKind => write_mode); wait; end process; end architecture tb3; |
Листинг 0
library ieee;
use ieee.std_logic_1164.all;
use ieee.math_real.all;
use ieee.numeric_std.all;
entity tstb is
end;
architecture beh of tstb is
component sxemaport (a, b : in std_logic_vector (4 downto 1);
d : out std_logic_vector (8 downto 1));
end component;
signal a, b : std_logic_vector (4 downto 1);
signal d : std_logic_vector (8 downto 1);
beginp0 : sxemaport map (a => a, b => b, d => d);
RandomGenProc1 : process
variable RndValA, RndValB : real; -- Random value
variable RndA, RndB : integer;
variable SeedA1 : positive := 7; -- initialize seeds
variable SeedA2 : positive := 1;
variable SeedB1 : positive := 4; -- initialize seeds
variable SeedB2 : positive := 2;
beginfor i in 1 to 100 loop
uniform(SeedA1, SeedA2, RndValA); -- randomize 0.0 to 1.0
uniform(SeedB1, SeedB2, RndValB); -- randomize 0.0 to 1.0
RndA := integer(trunc(RndValA*16.0)); -- scale to 0 to 15
RndB := integer(trunc(RndValB*16.0)); -- scale to 0 to 15
a <= std_logic_vector(to_unsigned(RndA, 4));
b <= std_logic_vector(to_unsigned(RndB, 4));
wait for 10 ns;
end loop;
wait ;
end process;
end;
- Листинг деклараций пакета ieee.math_real (тело пакета)
procedure UNIFORM(variable SEED1,SEED2:inout POSITIVE; variable X:out REAL);
-- Purpose:
-- Returns, in X, a pseudo-random number with uniform
-- distribution in the open interval (0.0, 1.0).
-- Special values:
-- None
-- Domain:
-- 1 <= SEED1 <= 2147483562; 1 <= SEED2 <= 2147483398
-- Error conditions:
-- Error if SEED1 or SEED2 outside of valid domain
-- Range:
-- 0.0 < X < 1.0
-- Notes:
-- a) The semantics for this function are described by the
-- algorithm published by Pierre L'Ecuyer in "Communications
-- of the ACM," vol. 31, no. 6, June 1988, pp. 742-774.
-- The algorithm is based on the combination of two
-- multiplicative linear congruential generators for 32-bit
-- platforms.
--
-- b) Before the first call to UNIFORM, the seed values
-- (SEED1, SEED2) have to be initialized to values in the range
-- [1, 2147483562] and [1, 2147483398] respectively. The
-- seed values are modified after each call to UNIFORM.
--
-- c) This random number generator is portable for 32-bit
-- computers, and it has a period of ~2.30584*(10**18) for each
-- set of seed values.
--
-- d) For information on spectral tests for the algorithm, refer
-- to the L'Ecuyer article.
function TRUNC (X : in REAL ) return REAL;
-- Purpose:
-- Truncates X towards 0.0 and returns truncated value
-- Special values:
-- TRUNC(0.0) = 0.0
-- Domain:
-- X in REAL
-- Error conditions:
-- None
-- Range:
-- TRUNC(X) is mathematically unbounded
-- Notes:
-- a) Implementations have to support at least the domain
-- ABS(X) < REAL(INTEGER'HIGH)

