Open Source VHDL Verification Methodology/Пример использования OS-VVM/Пример 2
Материал из Wiki
				
								
				< Open Source VHDL Verification Methodology | Пример использования OS-VVM
				
				
																
				
				
								
				Версия от 13:31, 1 февраля 2013; ANA  (обсуждение | вклад)
Это снимок страницы. Он включает старые, но не удалённые версии шаблонов и изображений.
Проект 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 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 : integer_vector (0 to 15) := (others => 0); 
- shared variable CovCrossAB : integer_vector (0 to 255) := (others => 0); 
- begin
- p0 : sxema
- port 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, d
- MainCovLoop : 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 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); 
- 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; 
- begin
- for 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)



