VHDL Error when converting std_logic_vector into unsigned integer - vhdl

I want to convert a 16-bit std_logic_vector into an integer to use it in a process realising a Moore machine.
entity steuerung is
port (
Clk : in std_logic;
Reset : in std_logic;
AktPos : in std_logic_vector(15 downto 0);
Notaus : in std_logic;
Betrieb : in std_logic;
HPR : in std_logic;
HPL : in std_logic;
ESR : in std_logic;
ESL : in std_logic;
CntClr : out std_logic;
LedR : out std_logic;
LedG : out std_logic;
M_An : out std_logic;
M_Li : out std_logic;
M_Re : out std_logic;
State : out std_logic_vector(5 downto 0)
);
end steuerung;
architecture BEHAVE of steuerung is
begin
process (Reset, Clk, Notaus, Betrieb, AktPos, ESR, ESL) is
type zustand is (steht, links, rechts, neuUnten, neuOben, alarm);
variable zustands_vektor : zustand;
variable ausgabe_vektor : std_logic_vector(5 downto 0);
variable cnt : integer range 0 to 65535 := conv_integer(unsigned(AktPos));
But I'm getting a few errors concerning the last line of code.
The console tells me the following:
"no declaration for "unsigned"
no overloaded function found matching 'conv_integer'"
and also a few errors in the std_logic_arith library (which I definitely included, although not seen in the code)
What have I done wrong?

Your code and your question has many issues ... Here is a list of things to fix:
Use English identifiers for documentation reasons, so others then natives like me can read and understand your question and your code. Moreover you are mixing Germany and English identifiers in the same file.
Add the full code, so we can see the surrounding context. It's needed to investigate and explain your mistakes.
std_logic_arith is a package, not a library. IEEE would be a VHDL library.
Don't use package std_logic_arith. use package numeric_std instead.
When using package numeric_std, an unsigned value is converted to integer with to_integer:
cnt := to_integer(unsigned(AktPos));
The signals: Reset, Notaus, Betrieb, AktPos, ESR, and ESL don't belong to the sensitivity list of a clocked process.
The initial value assignment for your variable is executed only once. Probably, this isn't what you want to achieve, right?
Type zustand is an enumeration type. Thus, the variable zustands_vektor uses wrong naming for an object containing a scalar discrete value. A vector is an array.
In general, using variables in VHDL is nothing for starters. Most likely, you want to use signals. VHDL is a hardware description language not a programming language, where you use variables for daily problem solving.

Related

How to create a subsignal / subvariable from an entity variable in VHDL?

I am currently implementing a MIPS processor in VHDL. The system component (which glues together the ALU, register file, control unit, etc.) has the follow entity description:
entity system is
port (
reset : in std_logic;
sys_clk : in std_logic;
instruction : in std_logic_vector(15 downto 0);
sys_mem_dump : in std_logic := '0'
);
end system;
In the architecture section of this system, I am trying to create "subvariables" of the instruction variable, corresponding to the opcode and registers in use.
architecture Behavioral of system is
instruction_opcode : std_logic_vector(3 downto 0) := instruction(15 downto 12);
instruction_rd : std_logic_vector(3 downto 0) := instruction(11 downto 8); -- destination register
instruction_rs : std_logic_vector(3 downto 0) := instruction(7 downto 4); -- source register
instruction_rt : std_logic_vector(3 downto 0) := instruction(3 downto 0); -- target register
-- a bunch of signals
begin
-- a bunch of port maps
end Behavioral
I've tried signal, variable, shared_variable, and constant, but these result in the register file's addresses not being initialized when I port map one of these variables to it. I've also tried putting these variables in the system entity port, but that also doesn't work. I don't want to split the instruction variable in the system entity port into those four variables either.
agree with paebles: you seem to lack basic VHDL knowledge and should look for this in your book.
You should at least know this method:
architecture Behavioral of system is
signal instruction_opcode : std_logic_vector(3 downto 0);
begin
instruction_opcode <= instruction(15 downto 12);
end architecture;
But you can in fact use aliases:
architecture Behavioral of system is
alias instruction_opcode : std_logic_vector(3 downto 0) is instruction(15 downto 12);
begin
end architecture;
A common thread reflecting your comment
#Paebbels Is it simply not possible to do this in VHDL? I have looked at the synario manual and some other websites, and none of the data object types match this use case.
is that the references you have used are inadequate.
In addition to intermediary signals and object aliases described in JH Bonarius' answer there is a method using index ranges declared as subtypes:
library ieee;
use ieee.std_logic_1164.all;
entity field is
port (
fourbitfield: in std_logic_vector (3 downto 0)
);
end entity;
architecture foo of field is
begin
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity system is
port (
reset: in std_logic;
sys_clk: in std_logic;
instruction: in std_logic_vector(15 downto 0);
sys_mem_dump: in std_logic := '0'
);
end entity system;
architecture foo of system is
subtype opcode is integer range 15 downto 12;
subtype rd is integer range 11 downto 8;
subtype rs is integer range 7 downto 4;
subtype rt is integer range 3 downto 0;
begin
U1:
entity work.field port map (instruction(opcode));
U2:
entity work.field port map (instruction(rd));
U3:
entity work.field port map (instruction(rs));
U4:
entity work.field port map (instruction(rt));
end architecture;
This analyzes, elaborates and simulates (Not actually doing anything while proving a lack of bounds errors).
An entity is an independent design unit and naturally allows abstraction (port names are associated with actual signals in a port map during elaboration of a component instantiation). All other forms of names or using intermediary objects are forms of abstraction intended for readability and are dictated by style.
In the above instruction(opcode) and it's like are slice names (IEEE Std 1076-2008 8.5 Slice names) providing a discrete range in the form of a integer subtype. You could likewise use slice names with discrete ranges (e.g. 15 downto 12) as actuals in association lists directly without declaring subtypes:
U1:
entity work.field port map (fourbitfield => instruction(15 downto 12));
Using named association between formal port and actual signals shown here can preclude the need for further abstraction. Dictating abstraction impinges on style not required by the VHDL standard.
Your idea of sub signals or variables aligns with slice names in VHDL as easily as the use of intermediary signals. Aliases are simply other names for named entities (including object slices).
Which additional abstraction method if any you use might depend on the sophistication level of anticipated readers.
If someone were to search the vhdl tag on Stackoverflow thoroughly you'd find examples of all three of these methods. A wile reader could edit your question to align with VHDL syntax and submit it as a duplicate.

Quartus Prime VHDL component instantiation compile error

I am having an issue when trying to compile the following code:
----------------
----------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity adder_top is
Port ( a_in : in STD_LOGIC_VECTOR (3 downto 0);
b_in : in STD_LOGIC_VECTOR (3 downto 0);
clk : in STD_LOGIC;
clk_en : in STD_LOGIC;
carry_in : in STD_LOGIC;
carry_out : out STD_LOGIC;
c_out : out STD_LOGIC_VECTOR (3 downto 0));
end adder_top;
architecture Behavioral of adder_top is
COMPONENT c_addsub_0
PORT (
A : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
B : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
CLK : IN STD_LOGIC;
C_IN : IN STD_LOGIC;
CE : IN STD_LOGIC;
C_OUT : OUT STD_LOGIC;
S : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
END COMPONENT c_addsub_0;
begin
inst_1 : COMPONENT c_addsub_0
port map
(
A => a_in,
B => b_in,
CLK => clk,
C_IN => carry_in,
CE => clk_en,
C_OUT => carry_out,
S => c_out
);
end Behavioral;
---------------------------
---------------------------
I receive the following error code when trying to compile:
Error (12006): Node instance "inst_1" instantiates undefined entity
"c_addsub_0". Ensure that required library paths are specified
correctly, define the specified entity, or change the instantiation.
If this entity represents Intel FPGA or third-party IP, generate the
synthesis files for the IP.
I am entirely unsure why I am receiving this error. Any help would be greatly appreciated.
The synthesis tool (Quartus) used to analyze and elaborate (a.k.a. compile) your design is complaining that it has not found an entity to bind the component c_addsub_0 with. You need to point the tool, in a tool defined way, to a library that contains the desired entity.
If you intended c_addsub_0 to be a block that you created then maybe it did not analyze into the work library as expected (unexpected syntax errors), or the library path to the work library is not established correctly (unlikely for a synthesis tool). If you wrote c_addsub_0 then it may be easier to use direct entity instantiation -- it saves the hassle of writing the component declaration and keep it in sync with the instance and the entity in another file. For example:
inst_1 : ENTITY work.c_addsub_0(<arch_name>)
port map
(
A => a_in,
B => b_in,
CLK => clk,
C_IN => carry_in,
CE => clk_en,
C_OUT => carry_out,
S => c_out
);
If the c_addsub_0 block is meant to be unbound through elaboration, as a black box until place-and-route, then you need to tell Quartus by decorating the instance with the appropriate syn_black_box attribute.
architecture Behavioral of adder_top is
COMPONENT c_addsub_0
PORT (
A : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
B : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
CLK : IN STD_LOGIC;
C_IN : IN STD_LOGIC;
CE : IN STD_LOGIC;
C_OUT : OUT STD_LOGIC;
S : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
END COMPONENT c_addsub_0;
attribute syn_black_box : boolean;
attribute syn_black_box of c_addsub_0: component is true;
begin
...
It then knows to synthesize a black box representation in the post synthesis netlist for that component. You then need to insure the Quartus back end can find a netlist for the given component in a netlist library path somewhere.
VHDL provides for a variety of ways to create hierarchy with incredibly precise control over binding, signal connections, naming/renaming of blocks and other features which are rarely used in ordinary designs. Unless your synthesis tool only supports one style of instantiation using component declarations or you need a black box, then I would stick with direct entity instantiation.
P.S.: Your use clause use ieee.std_logic_unsigned; should be use synopsys.std_logic_unsigned; -- The IEEE standards body never approved the std_logic_unsigned package. Though, if analyzing with the 1076-2008 standard, it is allowed now to analyze anything you want into the IEEE library. That permits defacto vendor, but not formally standardized, packages to be used without modification of your source code. Only the STD library is now actually a standard. Just be aware that Mentor Graphics and Synopsys versions of this package are different so your code may not achieve the portability that use of the standards based numeric_std package will achieve.

structural vhdl: creating a "main function"

I would like to create a structural VHDL file that implements a "main" function. The "top-level" file would be design and the program that runs the code would be prog. Assuming that fulladd_pack contains the fulladd component, how do I "link" the two VHDL files?
*I also don't get the arguments in main in order for this to work.
-- design.vhdl
library ieee;
use ieee.std_logic_1164.all;
use work.fulladd_pack.all;
ENTITY design IS
port(Cin : IN STD_LOGIC;
X,Y : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
S : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
Cout, Over : OUT STD_LOGIC);
END design;
ARCHITECTURE struct OF design IS
SIGNAL C,temp : STD_LOGIC_VECTOR(1 TO 15);
BEGIN
main: prog PORT MAP(Cin,X,Y,S,C,Cin);
END struct;
-- prog.vhdl
library ieee;
use ieee.std_logic_1164.all;
use work.fulladd_pack.all;
ENTITY prog IS
port(Cin : IN STD_LOGIC;
X,Y : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
S : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
Cout, Over : OUT STD_LOGIC);
END prog;
ARCHITECTURE struct OF prog IS
SIGNAL C,temp : STD_LOGIC_VECTOR(1 TO 15);
BEGIN
instance0: fulladd PORT MAP(Cin,X,Y,S,C,Cin);
output: fulladd PORT MAP(Cin,X,Y,S,C,Cin);
END struct;
You've missed the point. VHDL, as a "programming language", models concurrency, dataflow, and the passage of time. A model is composed of large numbers of elements ('processes') with data ('signals') flowing between them. A built-in kernel in your simulator handles the concurrency and time flow.
At the "top level", you write a testbench, which instantiates the model, and you apply stimulus (by driving signals which are inputs to the model). The stimulus forces data around the model. This carries on until you stop providing stimulus, at which point everthing else (should) stop.
So, no main. Write a testbench. 'Linking' is an internal concept in the simulator; forget it. Just simulate your source files together.

How can I index into a vhdl std_logic_vector?

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;

Passing Generics to Record Port Types

I did recently start to use records for my port definitions, especially if I want to group signals that belong to a certain interface. However, the problem I'm facing here is that I cannot pass, say the width of a std_logic_vector, to the entity by means of a generic. So what I basically want to do is the following:
library ieee;
use ieee.std_logic_1164.all;
use work.math_pkg.all;
package fifo_pkg is
type fifo_in_type is record
data_in : std_logic_vector(DATA_WIDTH_??- 1 downto 0);
rd : std_logic;
wr : std_logic;
end record;
type fifo_out_type is record
data_out : std_logic_vector(DATA_WIDTH_?? - 1 downto 0);
empty : std_logic;
full : std_logic;
end record;
component fifo is
generic
(
MIN_DEPTH : integer;
DATA_WIDTH : integer
);
port
(
clk : in std_logic;
res_n : in std_logic;
i : in fifo_in_type;
o : out fifo_out_type
);
end component fifo;
end fifo_pkg;
So the ideal solutions would be when i can use the same generic in my record as i did in the entity. (So that DATA_WIDTH is the same as DATA_WIDTH_??). I know that this should work somehow with vhdl 2008, however my quartus II 11sp1 does not support generics in records.
Is there an elegant way to achieve that kind of "generic passing" that is synthesizable? I know that one could just store a constant in the package, but then I cannot use the same fifo package to instantiate several fifo's with different widths.
Thanks a million,
T
Can you use type generics with Quartus?
Then you leave the type completely unspecified, so that you can create a FIFO of integers or any other data type:
package fifo_pkg is
generic (type element_type);
type fifo_in_type is record
data_in : element_type;
rd : std_logic;
wr : std_logic;
end record;
type fifo_out_type is record
data_out : element_type;
empty : std_logic;
full : std_logic;
end record;
component fifo is
generic
(
MIN_DEPTH : integer;
DATA_WIDTH : integer
);
port
(
clk : in std_logic;
res_n : in std_logic;
i : in fifo_in_type;
o : out fifo_out_type
);
end component fifo;
end fifo_pkg;
Then when you want to use it:
package wide_fifo_pkg is new fifo_pkg
generic map (type => std_logic_vector(31 downto 0));
and then you can use fifo_in_type and fifo_out_type:
signal i : fifo_in_type;
If you have more than one FIFO in a design unit you can create several versions of the package and use the package prefix to get the right type:
package narrow_fifo_pkg is new fifo_pkg
generic map (type => std_logic_vector(3 downto 0));
signal i32 : wide_fifo_pkg.fifo_in_type;
signal i4 : narrow_fifo_pkg.fifo_in_type;
Another VHDL 2008 option: you can have an unconstrained record type:
type fifo_in_type is record
data_in : std_logic_vector;
rd : std_logic;
wr : std_logic;
end record;
which you can then create subtypes of for your various uses:
subtype fifo1_data_type is fifo_in_type(data_in(31 downto 0));
subtype fifo2_data_type is fifo_in_type(data_in(15 downto 0));
No idea if Quartus supports either of those options - please let us know!
Generics in packages is supported in Xilinx's Vivado toolset currently. Ref their document UG901, the section titled "Generics in Packages" for details and a code sample. Need to make sure the source code properties are set up for VHDL-2008, as explained elsewhere in the same document.

Resources