VHDL - Problem with std_logic_vector - vhdl

i'm coding a 4-bit binary adder with accumulator:
library ieee;
use ieee.std_logic_1164.all;
entity binadder is
port(n,clk,sh:in bit;
x,y:inout std_logic_vector(3 downto 0);
co:inout bit;
done:out bit);
end binadder;
architecture binadder of binadder is
signal state: integer range 0 to 3;
signal sum,cin:bit;
begin
sum<= (x(0) xor y(0)) xor cin;
co<= (x(0) and y(0)) or (y(0) and cin) or (x(0) and cin);
process
begin
wait until clk='0';
case state is
when 0=>
if(n='1') then
state<=1;
end if;
when 1|2|3=>
if(sh='1') then
x<= sum & x(3 downto 1);
y<= y(0) & y(3 downto 1);
cin<=co;
end if;
if(state=3) then
state<=0;
end if;
end case;
end process;
done<='1' when state=3 else '0';
end binadder;
The output :
-- Compiling architecture binadder of binadder
** Error: C:/Modeltech_pe_edu_6.5a/examples/binadder.vhdl(15):
No feasible entries for infix operator
"xor".
** Error: C:/Modeltech_pe_edu_6.5a/examples/binadder.vhdl(15):
Type error resolving infix expression
"xor" as type std.standard.bit.
** Error: C:/Modeltech_pe_edu_6.5a/examples/binadder.vhdl(16):
No feasible entries for infix operator
"and".
** Error: C:/Modeltech_pe_edu_6.5a/examples/binadder.vhdl(16):
Bad expression in right operand of
infix expression "or".
** Error: C:/Modeltech_pe_edu_6.5a/examples/binadder.vhdl(16):
No feasible entries for infix operator
"and".
** Error: C:/Modeltech_pe_edu_6.5a/examples/binadder.vhdl(16):
Bad expression in left operand of
infix expression "or".
** Error: C:/Modeltech_pe_edu_6.5a/examples/binadder.vhdl(16):
Bad expression in right operand of
infix expression "or".
** Error: C:/Modeltech_pe_edu_6.5a/examples/binadder.vhdl(16):
Type error resolving infix expression
"or" as type std.standard.bit.
** Error: C:/Modeltech_pe_edu_6.5a/examples/binadder.vhdl(28):
No feasible entries for infix operator
"&".
** Error: C:/Modeltech_pe_edu_6.5a/examples/binadder.vhdl(28):
Type error resolving infix expression
"&" as type
ieee.std_logic_1164.std_logic_vector.
** Error: C:/Modeltech_pe_edu_6.5a/examples/binadder.vhdl(39):
VHDL Compiler exiting
I believe i'm not handling std_logic_vector's correctly. Please tell me how? :(

One of the features of VHDL is that very little functionality is provided in the base language itself. Most of it is provided by using packages. The second line of your code is an example of this (use ieee.std_logic_1164.all). This means that you are using all of the std_logic_1164 package. See here for what this package defines.
When you write code, you generally want to store your signals in either std_logic or std_logic_vector. There are two reasons for this. The first is that a std_logic can also represent values other than '0' or '1'. It can also represent 'Z' or 'X' for example. The second is that the simulators (such as modelsim that you are using) are optimised to run faster with std_logic.
As a general convention, it is good practice to always make the inputs and outputs from your entity a std_logic or std_logic_vector.
The specific problem you are having is that you are using the type bit (which is one of the very few types defined in the VHDL standard) with xor.
The simplest solution is to change the co output in your entity to be of type std_logic and to change the declaration for sum and cin to be of type std_logic.
entity binadder is
port(n,clk,sh:in bit;
x,y:inout std_logic_vector(3 downto 0);
co:inout std_logic;
done:out bit);
end binadder;
signal sum,cin:std_logic;
A further comment is that it is generally bad practice to make your ports inout unless you have a very good reason to do so as this removes some of the strict type checking that is built into the language. The best solution is to create a signal within the entity itself and assign the signal directly to the output.
entity binadder is
port(n,clk,sh:in bit;
x,y:inout std_logic_vector(3 downto 0);
co:out std_logic;
done:out bit);
end binadder;
signal co_int:std_logic;
begin
co_int<= (x(0) and y(0)) or (y(0) and cin) or (x(0) and cin);
co <= co_int;
One final comment is that once the value of state is 1, how will it ever become 2 or 3?

Take a look into your logical-physical library mappings.
Check that the physical library actually has the packages dumped.
Make sure you are not using a different version of pre-compiled header with a different version of the simulator.
If nothing works, just make a local copy of ieee, compile the std_logic_1164 packages into it, move to work library and then compile your design. This has to work.

Related

Can't compile with VHDL 2008 Quartus Prime

I'm using Quartus Prime Lite Edition and I want to use unary operator nand on std_logic_vector like this
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity example1 is
port(
BIN : in std_logic_vector (7 downto 0);
result : out std_logic
);
end;
architecture Beh of example1 is
begin
result <= nand BIN;
end Beh;
I tried to follow this instructions, changed VHDL version under VHDL Input in Compiler Settings. Still no effect and getting:
Error (10500): VHDL syntax error at lab2.vhd(16) near text "nand"; expecting "(", or an identifier ("nand" is a reserved keyword), or unary operator
Quartus Prime Lite does not support VHDL 2008.
https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/po/ss-quartus-comparison.pdf
This error is coming as "nand" requires two inputs.
From your question, it appears to me that you want to perform the bitwise nand operation on the input.
If yes, you can replace architecture as follows. I am assuming that you are familiar with the "generate for" syntax!
architecture Beh of example1 is
--Signals for Storing Intermediate Bitwise Values
signal temp1:std_logic_vector(3 downto 0);
signal temp2:std_logic_vector(1 downto 0);
begin
-- First level of NAND Operations
label_1: for i in 0 to 3 generate
temp1(i)<=BIN(2*i) nand BIN(2*i+1);
end generate label_1;
-- Second level of NAND Operations
label_2: for j in 0 to 1 generate
temp2(j)<= temp1(2*j) nand temp1(2*j+1);
end generate label_2;
-- Getting the Final Output
result<= temp2(1) nand temp2(0);
end Beh;
Thanks,
Dr. Ray

Overloading function in subprogram, but I it has "already been defined"

I'm trying to compile my subprogram pack and I get this error:
** Error: C:/Users/kmgrytte/Downloads/subprog_pck.vhd(16): (vcom-1295) Function "parity" has already been defined in this region.
** =====> Prior declaration of "parity" is at C:/Users/kmgrytte/Downloads/subprog_pck.vhd(12).
** Error: C:/Users/kmgrytte/Downloads/subprog_pck.vhd(20): VHDL Compiler exiting
Oveloading like this worked in my main program and I can't find any good examples of overloading in subprograms online.
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
package subprog_pck is
procedure parity;
procedure parity(
in1 : in std_logic_vector(15 downto 0);
in2 : in std_logic_vector(15 downto 0);
par : out std_logic);
function parity return std_logic;
function parity(
indata : in std_logic_vector(15 downto 0)) return std_logic;
impure function parity return std_logic;
impure function parity(
indata : in unsigned(15 downto 0)) return std_logic;
end package subprog_pck;
package body subprog_pck is
procedure parity(
in1 : in std_logic_vector(15 downto 0);
in2 : in std_logic_vector(15 downto 0);
par : out std_logic) is
begin
variable parity1, parity2 : std_logic:=0;
if (rst_n = '0') then
parity1 := '0';
parity2 := '0';
par <= '0';
elsif rising_edge(mclk) then
parity1 := '0';
for i in in1'range loop
if in1(i) = '1' then
parity1 := not parity1;
end if;
end loop;
parity2 := '0';
for j in in2'range loop
parity2 := parity2 xor in2(j);
end loop;
par <= parity1 xor parity2;
end if;
end parity;
function parity(indata : in std_logic_vector(15 downto 0)) return std_logic is
variable parity_var : std_logic := '0';
begin
for i in indata'range loop
if (indata(i) = '1') then
parity_var := not parity_var;
end if;
end loop;
return parity_var;
end function parity;
function parity(indata : in unsigned(15 downto 0))
return std_logic is
variable parity_var : std_logic := '0';
begin
for j in indata'range loop
parity_var := parity_var xor indata(j);
end loop;
return parity_var;
end function parity;
end package body subprog_pck;
Function overloading only occurs when you have the same function name with a different parameter list. Using impure does not overload another function. So you have two version of parity that takes no inputs and outputs a std_logic. Hence the compile error.
You also didn't provide a this version of parity in the package body.
There are additional errors in your package which is missing a library clause (library ieee;) in the context clause. The procedure parity has a variable declaration after begin, your initial values for parity1 and parity2 are 0 (a numeric literal), there's no declaration for rst_n or mclk, par in par <= ... is not a signal, there's no body for procedure parity or function parity with no parameters.
IEEE Std 1076-2008
12.3 Visibility
Two declarations that occur immediately within the same declarative region, other than the declarative region of a block implied by a component instantiation or the declarative region of a generic-mapped package or subprogram equivalent to a package instance or a subprogram instance, shall not be homographs, unless exactly one of them is the implicit declaration of a predefined operation or is an implicit alias of such an implicit declaration.
(There's no implicit declaration here and no predefined operation, emphasis added.)
Also in 12.3
... Each of two declarations is said to be a homograph of the other if and only if both declarations have the same designator, and they denote different named entities, and either overloading is allowed for at most one of the two, or overloading is allowed for both declarations and they have the same parameter and result type profile (see 4.5.1).
4.5 Subprogram overloading
4.5.1
Two formal parameter lists are said to have the same parameter type profile if and only if they have the same number of parameters, and if at each parameter position the corresponding parameters have the same base type. Two subprograms are said to have the same parameter and result type profile if and only if both have the same parameter type profile, and if either both are functions with the same result base type or neither of the two is a function.
You have more than one of these errors. vcom quit after the first one. The order in which errors are found are left to vagaries of the VHDL tool implementation applying semantic rules (other tools might find other errors first, explaining how the errors in the first paragraph above were found).
Modelsim has a verror tool providing more explanation:
vcom Message # 1295:
Two declarations that occur immediately within the same declarative
region must not be homographs, unless exactly one of them is the
declaration of a predefined operation.
Each of two declarations is said to be a homograph of the other if both
declarations have the same identifier, operator symbol, or character
literal, and if overloading is allowed for at most one of the two.
If overloading is allowed for both declarations, then each of the two is
a homograph of the other if they have the same identifier, operator
symbol, or character literal, as well as the same parameter and result
type profile (see 3.1.1). Overloading is defined only for subprograms
(including those those whose designator is an operator symbol) and
enumeration literals (including character literals).
[DOC: IEEE Std 1076-1993 VHDL LRM - 10.3 Visibility]
(These references are from the -1993 revision of the standard.)

VHDL Parametric case

I've some problem with my synthesis tool. I'm writing a module and I'm tryng to make it parametric and scalable. In my design I've a FSM and some counters. The counters have a parametric width ( they are function of the width of the datapath ). The problem is that I'm using that counter to drive a case statements. The synthesizer gives me back this error :
2049990 ERROR - (VHDL-1544) array type case expression must be of a locally static subtype
I've also tried to use subtype, but it doesnt work. The declaration is :
constant LENGTH_COUNTER_WORD : integer := integer(ceil(log2(real(WIDTH_DATA/WIDTH_WORD))));
subtype type_counter_word is std_logic_vector( LENGTH_COUNTER_WORD - 1 downto 0);
signal counter_word : std_logic_vector( LENGTH_COUNTER_WORD - 1 downto 0);
The case :
case type_counter_word'(counter_word) is
when (others => '1') =>
do_stuff();
when others =>
do_other_stuff();
end case;
I cannot switch to VHDL-2008. I've read I can use variable, but I'd like to find a different solution, if it exists. I cannot imagine there isn't any way to give parameters to synthesizer before the synthesis.
This is fixed in VHDL-2008. You can only work around it in earlier standards by using cascaded if statements (with the attendant priority logic). Variables don't make a difference when determining if choices are locally static.
I'm not sure how complicated your do_stuff() and do_other_stuff() operations are, but if you are just doing simple signal assignments, you could look into the and_reduce() function in the ieee.std_logic_misc library.
As an example:
output <= '1' when and_reduce(type_counter_word'(counter_word)) = '1' else '0';
Otherwise, as Kevin's answer suggests, a process block using if statements might be your best option.
About the time of Kevin's good enough answer, I had written this to demonstrate:
library ieee;
use ieee.std_logic_1164.all;
use ieee.math_real.all;
entity counterword is
generic (
WIDTH_DATA: positive := 16;
WIDTH_WORD: positive := 8
);
end entity;
architecture foo of counterword is
constant LENGTH_COUNTER_WORD : integer :=
integer(ceil(log2(real(WIDTH_DATA/WIDTH_WORD))));
subtype type_counter_word is
std_logic_vector( LENGTH_COUNTER_WORD - 1 downto 0);
signal counter_word : std_logic_vector( LENGTH_COUNTER_WORD - 1 downto 0);
procedure do_stuff is
begin
end;
procedure do_other_stuff is
begin
end;
begin
UNLABELLED:
process (counter_word)
begin
-- case type_counter_word'(counter_word) is
-- when (others => '1') =>
-- do_stuff;
-- when others =>
-- do_other_stuff;
-- end case;
if counter_word = type_counter_word'(others => '1') then
do_stuff;
else
do_other_stuff;
end if;
end process;
end architecture;
Note because type_counter_word is a subtype you can provide the subtype constraints in a qualified expression for the aggregate:
if counter_word = type_counter_word'(others => '1') then
From IEEE Std 1076-2008:
9.3.5 Qualified expressions
A qualified expression is a basic operation (see 5.1) that is used to explicitly state the type, and possibly the subtype, of an operand that is an expression or an aggregate.
This example analyzes, elaborates and simulates while doing nothing in particular. It'll call the sequential procedure statement do_other_stuff, which does nothing.
(For do_stuff and do_other stuff, empty interface lists aren't allowed).

VHDL When statement with multiple conditions

I am new to VHDL. I am trying to set a signals value based on the state of multiple conditions. It is outside of a process block. Is what I am trying to do even possible? If so, what am I doing wrong?
This is what I have so far:
signal1<= my_data
WHEN ( bit_cond_true
AND (my_array /= X"00000")
AND (my_array = another_array))
ELSE
other_data;
This is what happens when I try to compile it in ModelSim:
** Error: file.VHD(62): No feasible entries for infix operator "and".
** Error: file.VHD(62): Bad expression in left operand of infix expression "and".
** Error: file.VHD(62): Type error resolving infix expression "and" as type std.standard.boolean.
** Error: file.VHD(67): No feasible entries for infix operator "and".
** Error: file.VHD(66): Bad expression in left operand of infix expression "and".
** Error: file.VHD(67): Type error resolving infix expression "and" as type std.standard.boolean.
** Error: file.VHD(100): VHDL Compiler exiting
First, what you are trying to do is indeed possible, and is called a "conditional signal assignment statement" in VHDL terms.
You have not provided the declarations for the signals used in the expression, but I will assume that they are all std_logic or std_logic_vector, thus:
signal signal1 : std_logic; -- Result
signal my_data : std_logic; -- Value if TRUE condition
signal other_data : std_logic; -- Value if FALSE condition
signal bit_cond_true : std_logic; -- Condition part
signal my_array : std_logic_vector(19 downto 0); -- --||--
signal another_array : std_logic_vector(19 downto 0); -- --||--
So, VHDL is a strong typed language, and the condition you have given for when can't resolve because bit_cond_true is a std_logic, and (my_array /= X"00000") resolves to a boolean. Therefore you get the ModelSim error No feasible entries for infix operator "and". since ModelSim tries to resolve an expression with {std_logic} and {boolean}, but it has no definition of the and operator with the combinations of arguments.
There are different possibilities for converting bit_cond_true to a boolean, and this goes with both VHDL-2002 and VHDL-2008:
signal1 <= my_data when ((bit_cond_true = '1') and
(my_array /= X"00000") and
(my_array = another_array)) else
other_data;
In VHDL-2008 only, you can also use the ?? operator to convert a std_logic value of '1' or 'H' to TRUE, and other values to FALSE. The code then looks:
signal1 <= my_data when ((?? bit_cond_true) and
(my_array /= X"00000") and
(my_array = another_array)) else
other_data;
To get more into the VHDL language, I would recommend that you dive into one of the books listen under "Further reading" in Wikipedia VHDL

VHDL operator argument type mismatch

I have a very simple operator problem in VHDL. I try to compare some inputs with logical operators but get an error message...
entity test is
port (
paddr : in std_logic_vector(15 downto 0);
psel : in std_logic;
penable : in std_logic;
pwrite : in std_logic
);
end entity test;
signal wrfifo_full : std_logic;
process (paddr, psel, penable, pwrite, wrfifo_full) is
begin
if (((paddr(8 downto 2) = "1000000")) and (psel and penable) and (pwrite and not(wrfifo_full))) then
dt_fifo_wr_i <= '1';
else
dt_fifo_wr_i <= '0';
end if;
end process;
Unfortuantely, I get then the following error message:
if (((paddr(8 downto 2) = "1000000")) and (psel and penable) and
(pwrite and not(wrfifo_full))) then
| ncvhdl_p: *E,OPTYMM (hdl/vhdl/test.vhd,523|43): operator argument type mismatch
87[4.3.3.2] 93[4.3.2.2] [7.2]
Anyway sees the problem?
Cheers
psel, penable, pwrite and wrfifo_full are all std_logic.
In vhdl, to write the test they way you have, they would need to be boolean.
Instead write the code so that you are comparing their values to 1 or zero.
(paddr(8 downto 2) = "1000000" and
psel = '1' and penable ='1' and
pwrite = '1' and wrfifo_full = '0')
As George said, you have to currently convert all your std logics to booleans.
In VHDL-2008 however, there is a new conditional operator (??) which is applied implicitly to statements such as yours, which means they will work as you hoped. You'll have to enable VHDL-2008 support on you compiler (or whinge at your supplier to get with the times :)
This book is a good read on all the new bits that VHDL2008 gives us:
VHDL-2008 Just the new stuff
Section 4.4 covers the conditional operator

Resources