问题描述:

I'm using Quartus prime edition v15.1 for writing a register file and I need to use the numeric_std_unsigned package. On compiling, there's an error saying

Error (10481): VHDL Use Clause error : design library "IEEE" does not contain primary unit "NUMERIC_STD_unsigned". Verify that the primary unit exists in the library and has been successfully compiled.

How doesn't the IEEE library have the numeric_std_unsigned package? I've searched a lot and found that IEEE actually supports it. And if so, how can I firstly download the package and install it to the compiler or add it to my project?

EDIT

Here's my code:

library IEEE;

use IEEE.STD_LOGIC_1164.all;

use IEEE.std_logic_arith.all;

use IEEE.numeric_std_unsigned.all;

entity regfile is

port( clk: in STD_LOGIC;

regwrite: in STD_LOGIC;

rs, rt, rd: in STD_LOGIC_VECTOR(1 downto 0);

data_in: in STD_LOGIC_VECTOR(15 downto 0);

rd1, rd2: out STD_LOGIC_VECTOR(15 downto 0));

end;

architecture behave of regfile is

type registerFile is array (3 downto 0) of STD_LOGIC_VECTOR(15 downto 0);

signal registers: registerFile;

begin

process(clk) begin

if rising_edge(clk) then

if regwrite='1' then

registers(to_integer(unsigned(rd))) <= data_in;

end if;

end if;

end process;

process(all)

begin

if (to_integer(rs)=0)

then rd1 <= X"0000";

else rd1 <= registers(to_integer(unsigned(rs)));

end if;

if (to_integer(rt)=0)

then rd2 <= X"0000";

else rd2 <= registers(to_integer(unsigned(rt)));

end if;

end process;

end;

When I use IEEE.numeric_std_unsigned.all the compiler reports the error I posted above.

And when I use IEEE_numeric_std.all the compiler reports

  1. can't determine type of object at to_integer
  2. more than one Use Clause imports a declaration of simple name unsigned -- none of the declarations are directly visible

网友答案:

Once you edited your question to provide a Minimal, Complete, and Verifiable example the error is clearly visible.

Remove the use clause with std_logic_arith, it's incompatible with the unsigned declaration package numeric_std_unsigned uses (referenced from a use clause invoking ieee.numeric_std.all). In it's place use

use ieee.numeric_std.all; 

Some of the to_integer function calls found in your regfile architecture have a signature of [STD_ULOGIC_VECTOR return NATURAL].

(STD_ULOGIC_VECTOR is the base type for resolved subtype STD_LOGIC_VECTOR in package std_logic_1164 in VHDL -2008).

Some to_integer conversion function calls (e.g. to_integer(rs)) require package numeric_std_unsigned.

Those depending on package numeric_std (e.g. registers(to_integer(unsigned(rs))) also depend on a visible declaration for type unsigned being the same as the type declaration of the same name being visible in package numeric_std (referenced in a use clause in package numeric_std_unsigned).

In VHDL each declaration is unique even if they have the same name. Which one you are referencing is governed by visibility rules.

Before changing the use clause only the unsigned type declared in the Synopsys package was visible in your entity and architecture pair.

After switching std_logic_arith to numeric_std your code analyzes with a -2008 compliant VHDL implementation:

library IEEE;
use IEEE.STD_LOGIC_1164.all; 
-- use IEEE.std_logic_arith.all;
use ieee.numeric_std.all;
use IEEE.numeric_std_unsigned.all;

entity regfile is
    port ( 
        clk:        in  STD_LOGIC;
        regwrite:   in  STD_LOGIC; 
        rs, rt, rd: in  STD_LOGIC_VECTOR(1 downto 0); 
        data_in:    in  STD_LOGIC_VECTOR(15 downto 0); 
        rd1, rd2:   out STD_LOGIC_VECTOR(15 downto 0)
    ); 
end entity;

architecture behave of regfile is 
    type registerFile is array (3 downto 0) of STD_LOGIC_VECTOR(15 downto 0);
    signal registers: registerFile;
begin 
    process (clk) 
    begin
        if rising_edge(clk) then 
            if regwrite = '1' then
                registers(to_integer(unsigned(rd))) <= data_in; 
            end if;
        end if;
    end process;

    process (all)
    begin
        if to_integer(rs) = 0 then 
            rd1 <= X"0000"; 
        else 
            rd1 <= registers(to_integer(unsigned(rs))); 
        end if;

        if to_integer(rt) = 0 then 
            rd2 <= X"0000";
        else 
            rd2 <= registers(to_integer(unsigned(rt)));
        end if;
    end process; 
end architecture;

Style changes not withstanding the only change is the use clause.

You could remove the dependency on package numeric_std by changing the to_integer function calls with the signature [UNSIGNED return NATURAL] to [STD_ULOGIC_VECTOR return NATURAL]:

library ieee;
use ieee.std_logic_1164.all; 
-- use IEEE.std_logic_arith.all;
-- use ieee.numeric_std.all;
use IEEE.numeric_std_unsigned.all;

entity regfile is
    port ( 
        clk:        in  std_logic;
        regwrite:   in  std_logic; 
        rs, rt, rd: in  std_logic_vector(1 downto 0); 
        data_in:    in  std_logic_vector(15 downto 0); 
        rd1, rd2:   out STD_LOGIC_VECTOR(15 downto 0)
    ); 
end entity;

architecture behave of regfile is 
    type registerFile is array (3 downto 0) of STD_LOGIC_VECTOR(15 downto 0);
    signal registers: registerFile;
begin 
    process (clk) 
    begin
        if rising_edge(clk) then 
            if regwrite = '1' then
                registers(to_integer(rd)) <= data_in; 
            end if;
        end if;
    end process;

    process (all)
    begin
        if to_integer(rs) = 0 then 
            rd1 <= X"0000"; 
        else 
            rd1 <= registers(to_integer(rs)); 
        end if;

        if to_integer(rt) = 0 then 
            rd2 <= X"0000";
        else 
            rd2 <= registers(to_integer(rt));
        end if;
    end process; 
end architecture;

Note we've gotten rid of the use clause with package numeric_std and dropped some type conversions for generating the indexes for indexed names selecting registers elements for writes to the register file as well as both read ports.

Both these modifications to your code example analyze, elaborate and simulate telling us the indexes work correctly. The second one using only package numeric_std_unsigned enhances readability.

And of course if your VHDL tool is actually missing package numeric_std_unsigned and it isn't cured by re-installation or updating the Quartus tools you could use a -1993 compliant design description:

library ieee;
use ieee.std_logic_1164.all;
-- use IEEE.std_logic_arith.all;
use ieee.numeric_std.all;
-- use IEEE.numeric_std_unsigned.all;

entity regfile is
    port (
        clk:        in  std_logic;
        regwrite:   in  std_logic;
        rs, rt, rd: in  std_logic_vector(1 downto 0);
        data_in:    in  std_logic_vector(15 downto 0);
        rd1, rd2:   out STD_LOGIC_VECTOR(15 downto 0)
    );
end entity;

architecture behave of regfile is 
    type registerFile is array (3 downto 0) of STD_LOGIC_VECTOR(15 downto 0);
    signal registers: registerFile;
begin
    process (clk)
    begin
        if rising_edge(clk) then
            if regwrite = '1' then
                registers(to_integer(unsigned(rd))) <= data_in;
            end if;
        end if;
    end process;

    process (rs, rt) -- (all)
    begin
        if to_integer(unsigned(rs)) = 0 then
            rd1 <= X"0000";
        else
            rd1 <= registers(to_integer(unsigned(rs)));
        end if;

        if to_integer(unsigned(rt)) = 0 then
            rd2 <= X"0000";
        else
            rd2 <= registers(to_integer(unsigned(rt)));
        end if;
    end process;
end architecture;

Where the process sensitivity list is manually specified and all to_integer calls are from package numeric_std, requiring unsigned type conversions for std_logic_vector values.

(And this analyzes, elaborates and simulates).

网友答案:

I assume you mean the unsigned type of the numeric_std package in the ieee library.

library ieee;
use ieee.numeric_std.all;
...
signal foo : unsigned(7 downto 0);

or

library ieee;
use ieee.numric_std;
...
signal bar : numeric_std.unsigned(7 downto 0);
网友答案:

The installation folder of Quartus Prime 15.1 actually contains a file called numeric_std_unsigned_vhdl2008.vhd which defines the package numeric_std_unsigned and its body. But, apparently the synthesizer does not support it.

The Quartus Prime Standard Handbook v15.1.1, Volume 1 gives in Section 16 under "VHDL Synthesis Support" -> "VHDL-2008 Support" a link to this online help page. At the time of writing this answer, the list of supported VHDL'08 features does not reference Section 16.8.5 of the VHDL'08 Standard which defines the package numeric_std_unsigned. There is also no reference to Appendix A.2.4.

The following sub-section in the Quartus manual states further:

The Quartus Prime software includes the standard IEEE libraries and several vendor-specific VHDL libraries.

The IEEE library includes the standard VHDL packages std_logic_1164, numeric_std, numeric_bit, and math_real.

Given that, you must revert back to using the numeric_std package. But, this package defines the type unsigned which is also defined in std_logic_arith. You should not use the non-standard std_logic_arith package from Synopsys anymore.

Thus, you have to use the package numeric_std instead of both numeric_std_unsigned and std_logic_arith.. Then you have to convert all std_logic_vector to unsigned first, before passing them as an argument to the function to_integer, e.g.:

to_integer(unsigned(rs))

instead of

to_integer(rs)
相关阅读:
Top