0

我试图让 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;
4

0 回答 0