Created
August 14, 2014 15:43
-
-
Save tmeissner/1ca16372e247098d9462 to your computer and use it in GitHub Desktop.
Simple example of functional coverage using CoveragePkg of OSVVM
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library ieee; | |
use ieee.std_logic_1164.all; | |
use ieee.numeric_std.all; | |
use std.env.all; | |
library OSVVM; | |
use OSVVM.RandomPkg.all; | |
use OSVVM.CoveragePkg.all; | |
entity OSVVM_tb is | |
end entity OSVVM_tb; | |
architecture sim of OSVVM_tb is | |
constant C_ADDER_WIDTH : positive := 16; | |
constant C_CLK_PERIOD : time := 20 ns; | |
constant C_MAX_BINS : natural := 64; | |
shared variable sv_coverage : CovPType; | |
signal s_adder1_in : unsigned(C_ADDER_WIDTH - 1 downto 0); | |
signal s_adder2_in : unsigned(C_ADDER_WIDTH - 1 downto 0); | |
signal s_adder0_out : unsigned(C_ADDER_WIDTH downto 0) := (others => '0'); | |
signal s_adder1_out : unsigned(C_ADDER_WIDTH downto 0) := (others => '0'); | |
signal s_clk : std_logic := '0'; | |
begin | |
s_clk <= not(s_clk) after C_CLK_PERIOD / 2; | |
-- behaviour model of adder | |
Adder0P : process is | |
begin | |
wait until rising_edge(s_clk); | |
s_adder0_out <= ('0' & s_adder1_in) + ('0' & s_adder2_in); | |
end process Adder0P; | |
-- "rtl" model of adder | |
Adder1P : process is | |
variable v_carry : std_logic; | |
begin | |
wait until rising_edge(s_clk); | |
v_carry := '0'; | |
for index in 0 to C_ADDER_WIDTH - 1 loop | |
if(index = 0) then | |
s_adder1_out(index) <= s_adder1_in(index) xor s_adder2_in(index); | |
else | |
s_adder1_out(index) <= s_adder1_in(index) xor s_adder2_in(index) xor v_carry; | |
end if; | |
v_carry := (s_adder1_in(index) and s_adder2_in(index)) or (s_adder1_in(index) and v_carry) or (s_adder2_in(index) and v_carry); | |
end loop; | |
s_adder1_out(C_ADDER_WIDTH) <= v_carry; | |
end process Adder1P; | |
-- stimulus & coverage of adder inputs | |
StimCoverageP : process is | |
variable v_adder_in : integer_vector(0 to 1); | |
begin | |
s_adder1_in <= (others => '0'); | |
s_adder2_in <= (others => '0'); | |
-- cross bins for all possible combinations (very slow on large vector widths): | |
--sv_coverage.AddCross(GenBin(0, 2 ** C_ADDER_WIDTH - 1), GenBin(0, 2 ** C_ADDER_WIDTH - 1)); | |
-- cross bins for maximum of 64 slices with same width: | |
sv_coverage.AddCross(GenBin(0, 2 ** C_ADDER_WIDTH - 1, C_MAX_BINS), GenBin(0, 2 ** C_ADDER_WIDTH - 1, C_MAX_BINS)); | |
-- cross bins for corner cases: | |
sv_coverage.AddCross(GenBin(0), GenBin(2 ** C_ADDER_WIDTH - 1)); | |
sv_coverage.AddCross(GenBin(2 ** C_ADDER_WIDTH - 1), GenBin(0)); | |
wait for 1 ns; | |
-- loop until reach coverage goal | |
while not sv_coverage.IsCovered loop | |
wait until rising_edge(s_clk); | |
v_adder_in := sv_coverage.RandCovPoint; | |
s_adder1_in <= to_unsigned(v_adder_in(0), C_ADDER_WIDTH); | |
s_adder2_in <= to_unsigned(v_adder_in(1), C_ADDER_WIDTH); | |
sv_coverage.ICover(v_adder_in); | |
end loop; | |
wait for 2 * C_CLK_PERIOD; | |
report("CovBin Coverage details"); | |
sv_coverage.WriteBin; | |
stop; | |
end process StimCoverageP; | |
-- check if outputs of both adders are equal | |
CheckerP : process is | |
begin | |
wait until rising_edge(s_clk); | |
assert s_adder0_out = s_adder1_out | |
report "FAILURE: s_adder0_out (0x" & to_hstring(s_adder0_out) & ") & s_adder1_out (0x" & to_hstring(s_adder1_out) & ") are not equal!" | |
severity failure; | |
end process CheckerP; | |
end architecture sim; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment