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
can't determine type of object at to_integer
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)
Related
I designed a simple shifter but I got an error, I applied different lots of things to solve, then it hasn't been fixed.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
--use ieee.std_logic_unsigned.all;
entity shifter is
Port ( inp : in STD_LOGIC_VECTOR(7 downto 0);
shift_cntrl : in STD_LOGIC_VECTOR(1 downto 0);
shift_out : out STD_LOGIC_VECTOR(15 downto 0));
end shifter;
architecture Behavioral of shifter is
begin
process(shift_cntrl, inp) begin
with shift_cntrl select
shift_out <= STD_LOGIC_VECTOR(to_unsigned(inp, shift_out'LENGTH) sll 4) when "01",
STD_LOGIC_VECTOR(to_unsigned(inp, shift_out'LENGTH) sll 8) when "10",
inp when others;
end process;
end Behavioral;
VHDL error messages:
[Synth 8-2778] type error near inp ; expected type natural [shifter.vhd:18]
[Synth 8-2778] type error near inp ; expected type natural [shifter.vhd:19]
[Synth 8-2757] this construct is only supported in VHDL 1076-2008 [shifter.vhd:20]
with..select is only supported inside a process when the file mode is set to VHDL 2008. Either set the file mode in Vivado to 2008 or simply remove the process around the with..select statement as it is not needed.
In addition, there is no function to_unsigned for a std_logic_vector. Because it is a similar type, you can do a type conversion:
STD_LOGIC_VECTOR(unsigned(inp) sll 4);
I'm currently programming a system in VHDL, and I'm using an enumerator from another package called vnir, which is defined as such:
package vnir is
type row_type_t is (ROW_NONE, ROW_NIR, ROW_BLUE, ROW_RED);
end package vnir;
I've defined my architecture as such
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.vnir;
entity imaging_buffer is
port(
clock : in std_logic;
reset_n : in std_logic;
vnir_row_ready : in vnir.row_type_t
);
end entity imaging_buffer;
architecture rtl of imaging_buffer is
signal vnir_row_ready_i : vnir.row_type_t;
begin
vnir_pipeline : process (reset_n, clock) is
begin
if (reset_n = '0') then
vnir_row_ready_i <= vnir.ROW_NONE;
elsif rising_edge(clock) then
if (vnir_row_ready /= vnir.ROW_NONE) then
--do stuff
end if;
end if;
end process vnir_pipeline;
end architecture;
The internal signal vnir_row_ready_i can be assigned to no problem, however the relational operator doesn't seem to work as ModelSim throws this error when I try to compile:
# ** Error: C:/Users/nashg/Documents/iris_project/ex2_iris/vhdl/subsystems/sdram/Imaging Buffer/test.vhd(23): (vcom-1581) No feasible entries for infix operator '/='.
# ** Error: C:/Users/nashg/Documents/iris_project/ex2_iris/vhdl/subsystems/sdram/Imaging Buffer/test.vhd(23): Type error resolving infix expression "/=" as type std.STANDARD.BOOLEAN.
# ** Error: C:/Users/nashg/Documents/iris_project/ex2_iris/vhdl/subsystems/sdram/Imaging Buffer/test.vhd(28): VHDL Compiler exiting
My coworker helped me figure out how to make it work! I think that the /= operator is created in the vnir scope, but not ported over to the entity I'm working on. By writing :use work.vnir."/="; at the beginning of the file it compiles, so the full entity looks like so:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.vnir;
use work.vnir."/=";
entity imaging_buffer is
port(
clock : in std_logic;
reset_n : in std_logic;
vnir_row_ready : in vnir.row_type_t
);
end entity imaging_buffer;
architecture rtl of imaging_buffer is
signal vnir_row_ready_i : vnir.row_type_t;
begin
vnir_pipeline : process (reset_n, clock) is
begin
if (reset_n = '0') then
vnir_row_ready_i <= vnir.ROW_NONE;
elsif rising_edge(clock) then
if (vnir_row_ready /= vnir.ROW_NONE) then
--do stuff
end if;
end if;
end process vnir_pipeline;
end architecture;
Alternatively it did work by including use work.vnir.all; and taking out the vnir. before the types, but that wasn't possible with the project I'm working one
this is the code and saved it as IR.vhd, while the name of the project is saved as "8051"
when i try to compile a vhdl program in altera it is showing "Error (12007): Top-level design entity "8051" is undefined
" ... what does it mean ?
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity IR is
port(clk,rst,pb1:in std_logic;
irreg:in std_logic_vector(15 downto 0);
ops:out std_logic_vector(2 downto 0);
modes:out std_logic;
loc1:out std_logic_vector(3 downto 0);
loc2ordata:out std_logic_vector(7 downto 0));
end IR;
architecture rtl of IR is
signal ireg: std_logic_vector(15 downto 0);
begin
process (pb1)
begin
if(pb1='0')then --I am going to set up to feed in one instruction at a time
ireg<=irreg; --the instruction is executed when pb1 is pressed
end if;
end process;
ops<=ireg(15 downto 13);
modes<=ireg(12);
loc1<=ireg(11 downto 8);
loc2ordata<=ireg(7 downto 0);
end rtl;
Something I have noticed is that the top level entity name needs to be the same as the file name and module name. So if you called the top level IR, the file probably needs to be IR.v. Now I never capitalize my file names so I don't actually know if capitalization matching is important.
I have the following declarations:
signal count:STD_LOGIC_VECTOR (3 downto 0);
signal txbuff:STD_LOGIC_VECTOR (7 downto 0);
dout is a std_logic output
I am using IEEE.NUMERIC_STD.ALL;
I want to use the vector count as an index into txbuff. Among the many things I've tried is the following:
count<=std_logic_vector(unsigned(count)-1);
dout<=txbuff(unsigned(count));
but I get the following error:
Line 99. Wrong index type for txbuff.
You need an integer as the index type. (Or with other arrays, you can use any discrete type, such as as enumeration).
Other answers have showed you how to get there using type conversion functions : I'll ask instead, why not make "count" an integer, like natural range 0 to 15 in the first place? It'll synthesise just the same, and make for cleaner simpler code.
We actually want to convert the number to an integer, not an unsigned or signed.
To do this, we can use to_integer as defined in numeric_std. Here's an example:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
entity conv_test is Port (
data_in : in std_logic_vector(7 downto 0);
data_sel : in std_logic_vector(2 downto 0);
data_out : out std_logic
);
end conv_test;
architecture Behavioral of conv_test is
begin
data_out <= data_out(to_integer(unsigned(data_sel)));
end Behavioral;
You need to convert to integer using the to_integer function. Check the parameterised MUX:
architecture RTL of MUX is
begin
-----------------------------------------------------------------------
-- MUX_RTL
-----------------------------------------------------------------------
-- Implements a multiplexer
-----------------------------------------------------------------------
MUX_RTL: process(DATA_IN, ADDR_IN)
variable ADDR_IN_INT : integer range 0 to 2**ADDR_WIDTH-1; -- holds the integer value of the address
begin
ADDR_IN_INT := to_integer(unsigned(ADDR_IN));
DATA_OUT <= DATA_IN(ADDR_IN_INT);
end process MUX_RTL;
end architecture RTL;
I found this code which is a part of Exponentiation implementation, I believe this code is for parallel load register, the code had many mistakes, yet I tried to fix it and simplify it(simplification is to make it work), the original code is:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity REG is --Register entity
Port ( CLK,set,reset,In_LOAD : in std_logic;
Din_p: in std_logic_vector(m-1 to 0);
Din_s: in std_logic;
Dout: out std_logic);
end REG;
architecture behavior of REG is
signal Q_temp: std_logic_vector(m-1 down to 0);
begin
Dout<=”0”;
comb:process(In_LOAD,Din_s)
begin
if(In_LOAD=”1”) then Q_temp<=Din_p;end if;
end process comb;
state: process(CLK,set,reset)
begin
if(reset=”1”) then Q_temp<=(others=>”0”);end if;
if(set=”1”) then Q_temp<= (others=>”1”);
elsif(CLK’event and CLK=”1”) then
Q_temp:=Din_p & Q_temp(m-1 down to 1);
end if;
Dout<= Q_temp(0);
end process state;
end behavior;
while the code I modified is:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity REG2 is --Register entity
generic (m: integer := 4);
Port ( CLK,In_LOAD : in std_logic;
Din_p: in std_logic_vector(m-1 to 0);
Dout: out std_logic);
end REG2;
architecture behavior of REG2 is
signal Q_temp: std_logic_vector(m-1 downto 0);
begin
Dout<='0';
process(In_LOAD, Din_p, CLK)
begin
if (CLK'event and CLK='1') then
Q_temp <=Din_p;
elsif (In_LOAD='1') then
Q_temp <= Din_p & Q_temp(m-1 downto 1);
end if;
end process;
Dout <= Q_temp(0);
end behavior;
so my questions are : 1- why I'm getting this error :(Error (10344): VHDL expression error at REG2.vhd(18): expression has 0 elements, but must have 4 elements)?
2- this is a code for parallel load register, right?
thx
Plenty of things are wrong with your code (and the original code).
use the correct quote character " for bit strings and ' for bits instead of ”
downto is one word, not down to
m is not declared; perhaps this is supposed to be a generic?
Assign to Q_temp using signal assignment <= instead of variable assignment :=
Sensitivity lists for both your processes are incomplete
As #Morten mentions: the direction of Din_p should probably downto instead of to
Bonus (pet peeve): don't use IEEE.STD_LOGIC_ARITH and IEEE.STD_LOGIC_UNSIGNED, because they are not properly standardized. Use ieee.numeric_std instead.