我试图让 OSSVM 在 EDA Playground 上与 GHDL 一起工作。(说实话,我以为我已经有了,但它不起作用)。我也无法让它在命令行上运行。因此,鉴于此问题底部的代码(来自https://www.osvvm.org,也位于https://www.edaplayground.com/x/49J)另存为osvvm.vhd
,
我愿意
ghdl -i osvvm.vhd
然后
ghdl -m OSVVM_tb -P/playground_lib/OSVVM-master/
我得到
osvvm.vhd:106:9:error: cannot find resource library "osvvm"
即使我认为我已经正确安装了 GHDL 0.35。如果我做
compile-osvvm.sh --all
我明白了
Vendor directory '/playground_lib/OSVVM-master' already exists.
Compiling library 'osvvm'...
Analyzing package '/playground_lib/OSVVM-master/NamePkg.vhd'
Analyzing package '/playground_lib/OSVVM-master/OsvvmGlobalPkg.vhd'
Analyzing package '/playground_lib/OSVVM-master/VendorCovApiPkg.vhd'
Analyzing package '/playground_lib/OSVVM-master/TranscriptPkg.vhd'
Analyzing package '/playground_lib/OSVVM-master/TextUtilPkg.vhd'
Analyzing package '/playground_lib/OSVVM-master/AlertLogPkg.vhd'
Analyzing package '/playground_lib/OSVVM-master/MessagePkg.vhd'
Analyzing package '/playground_lib/OSVVM-master/SortListPkg_int.vhd'
Analyzing package '/playground_lib/OSVVM-master/RandomBasePkg.vhd'
Analyzing package '/playground_lib/OSVVM-master/RandomPkg.vhd'
Analyzing package '/playground_lib/OSVVM-master/CoveragePkg.vhd'
Analyzing package '/playground_lib/OSVVM-master/MemoryPkg.vhd'
Analyzing package '/playground_lib/OSVVM-master/ScoreboardGenericPkg.vhd'
Analyzing package '/playground_lib/OSVVM-master/ScoreboardPkg_slv.vhd'
Analyzing package '/playground_lib/OSVVM-master/ScoreboardPkg_int.vhd'
Analyzing package '/playground_lib/OSVVM-master/ResolutionPkg.vhd'
Analyzing package '/playground_lib/OSVVM-master/TbUtilPkg.vhd'
Analyzing package '/playground_lib/OSVVM-master/OsvvmContext.vhd'
--------------------------------------------------------------------------------
Compiling OSVVM packages [SUCCESSFUL]
然后当我这样做时
ls /playground_lib/OSVVM-master/osvvm/v08/
我明白了
osvvm-obj08.cf
为什么 GHDL 不能“看到”osvvm
库?
# ghdl --version
GHDL 0.35 (v0.35) [Dunoon edition]
Compiled with GNAT Version: 4.6
mcode code generator
Written by Tristan Gingold.
Copyright (C) 2003 - 2015 Tristan Gingold.
GHDL is free software, covered by the GNU General Public License. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# ghdl --disp-config
command_name: ghdl
command line prefix (--PREFIX): (not set)
environment prefix (GHDL_PREFIX): (not set)
exec prefix (from program name): /usr/share/ghdl
library prefix: /usr/share/ghdl/lib/ghdl
library directory: /usr/share/ghdl/lib/ghdl
default library paths:
/usr/share/ghdl/lib/ghdl/v93/std/
/usr/share/ghdl/lib/ghdl/v93/ieee/
root@main8:/#
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
entity adder0 is
generic (
G_ADDER_WIDTH : positive := 4
);
port (
reset_n : in std_logic;
clk : in std_logic;
a : in unsigned(G_ADDER_WIDTH - 1 downto 0);
b : in unsigned(G_ADDER_WIDTH - 1 downto 0);
y : out unsigned(G_ADDER_WIDTH downto 0)
);
end entity adder0;
architecture rtl of adder0 is
begin
-- behaviour model of adder
Adder0P : process (clk, reset_n) is
begin
if(reset_n = '0') then
y <= (others => '0');
elsif(rising_edge(clk)) then
y <= ('0' & a) + ('0' & b);
end if;
end process Adder0P;
end architecture rtl;
-- Code your design here
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
entity adder1 is
generic (
G_ADDER_WIDTH : positive := 4
);
port (
reset_n : in std_logic;
clk : in std_logic;
a : in unsigned(G_ADDER_WIDTH - 1 downto 0);
b : in unsigned(G_ADDER_WIDTH - 1 downto 0);
y : out unsigned(G_ADDER_WIDTH downto 0)
);
end entity adder1;
architecture rtl of adder1 is
begin
-- "rtl" model of adder
Adder1P : process (clk, reset_n) is
variable v_carry : std_logic;
begin
if(reset_n = '0') then
y <= (others => '0');
elsif(rising_edge(clk)) then
v_carry := '0';
for index in 0 to G_ADDER_WIDTH - 1 loop
if(index = 0) then
y(index) <= a(index) xor b(index);
else
y(index) <= a(index) xor b(index) xor v_carry;
end if;
v_carry := (a(index) and b(index)) or
(a(index) and v_carry) or
(b(index) and v_carry);
end loop;
y(G_ADDER_WIDTH) <= v_carry;
end if;
end process Adder1P;
end architecture rtl;
-- Simple example of functional coverage using CoveragePkg of OSVVM
-- for more information see into documentation of OSVVM which you
-- can find in the http://osvvm.org/downloads section
--
-- OSVVM uses protected types, find more information about using them under:
-- https://www.aldec.com/en/support/resources/documentation/articles/1179
-- and also in the http://osvvm.org/downloads section
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
component adder0 is
generic (
G_ADDER_WIDTH : positive := 4
);
port (
reset_n : in std_logic;
clk : in std_logic;
a : in unsigned(G_ADDER_WIDTH - 1 downto 0);
b : in unsigned(G_ADDER_WIDTH - 1 downto 0);
y : out unsigned(G_ADDER_WIDTH downto 0)
);
end component adder0;
component adder1 is
generic (
G_ADDER_WIDTH : positive := 4
);
port (
reset_n : in std_logic;
clk : in std_logic;
a : in unsigned(G_ADDER_WIDTH - 1 downto 0);
b : in unsigned(G_ADDER_WIDTH - 1 downto 0);
y : out unsigned(G_ADDER_WIDTH downto 0)
);
end component adder1;
-- width of adder inputs
constant C_ADDER_WIDTH : positive := 8;
-- clock period
constant C_CLK_PERIOD : time := 20 ns;
-- how many bins should be generated
constant C_MAX_BINS : natural := 16;
-- coverage object of (protected) type CovPType
shared variable sv_coverage : CovPType;
-- testbench signals
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';
signal s_reset_n : std_logic := '0';
begin
-- global signals
s_reset_n <= '1' after 100 ns;
s_clk <= not(s_clk) after C_CLK_PERIOD / 2;
-- dut 1
i_adder0 : adder0
generic map (
G_ADDER_WIDTH => C_ADDER_WIDTH
)
port map (
reset_n => s_reset_n,
clk => s_clk,
a => s_adder1_in,
b => s_adder2_in,
y => s_adder0_out
);
-- dut 2
i_adder1 : adder1
generic map (
G_ADDER_WIDTH => C_ADDER_WIDTH
)
port map (
reset_n => s_reset_n,
clk => s_clk,
a => s_adder1_in,
b => s_adder2_in,
y => s_adder1_out
);
-- stimulus & coverage of adder inputs
StimCoverageP : process is
-- holds the two random values from sv_coverage object
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 C_MAX_BINS 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 (min against max):
sv_coverage.AddCross(GenBin(0), GenBin(2 ** C_ADDER_WIDTH - 1));
sv_coverage.AddCross(GenBin(2 ** C_ADDER_WIDTH - 1), GenBin(0));
-- loop until reaching coverage goal
while not sv_coverage.IsCovered loop
wait until rising_edge(s_clk);
-- generate random values depending on coverage hole
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);
-- save generated random values in coverage object
sv_coverage.ICover(v_adder_in);
end loop;
wait for 2 * C_CLK_PERIOD;
-- print coverage report
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;