I am trying to make a dataflow design for a comparator in VHDL. It compiles and simulates fine in Xilinx, but I have to use Cadence/NCLaunch. When I copied the same code to gedit and ran it, it gives an error about a semicolon.
my code is :
library ieee;
use ieee.std_logic_1164.all;
-----------------------------------------------------
entity Comparator is
port( A: in std_logic_vector (3 downto 0);
B: in std_logic_vector (3 downto 0);
AeqB: out std_logic;
AltB: out std_logic;
AgtB: out std_logic);
end Comparator;
architecture dataflow of Comparator is
signal AeB : std_logic;
signal AlB : std_logic;
signal AgB : std_logic;
signal i : std_logic_vector (3 downto 0);
signal j : std_logic_vector (3 downto 0);
begin
B1: BLOCK BEGIN
AeB <= i(3) AND i(2) AND i(1) and i(0);
AgB <= j(3) or j(2) or j(1) or j(0);
AlB <= AeB nor AgB;
END BLOCK B1;
B2: BLOCK BEGIN
i <= a xnor b;
END BLOCK B2;
B3: BLOCK BEGIN
j(3) <= (not b(3)) and a(3);
j(2) <= i(3) and not b(2) and a(2);
j(1) <= i(3) and i(2) and not b(1) and a(1);
j(0) <= i(3) and i(2) and i(1) and not b(0) and a(0);
END BLOCK B3;
B4: BLOCK BEGIN
AeqB <= AeB;
AltB <= AlB;
AgTB <= AgB;
END BLOCK B4;
end dataflow;
...and the error I get is:
i <= a xnor b;
|
ncvhdl_p: *E,EXPSMI (/ugrad/syedhuq/ECE425/Lab2/Comparator.vhd,29|11): expecting a semicolon (';') [9.5.1].
As far as I can tell, I have a semicolon there...also if I replace the statement with four individual statements like
i(n) <= a(n) xnor b(n); //[n = 1, 2, 3, 4],
i get the same error 4 times. Can anyone help me out with this??
Also, it compiles fine in Synopsys (VCSMX) and so does the testbench file, but during the linking process it tells me :
Design unit 'COMPARATOR(BEHAVE)' from library '.' cannot be opened for
reading.
Possible causes:
[1] Incorrect logical to physical mapping in synopsys_sim.setup file.
[2] Intermediate file generation was prematurely terminated during analysis.
Reanalyze the design unit and resolve any errors that occur during analysis.
the relevant line from the testbench code is:
for x1: Comparator use entity work.Comparator(Behave);
I'm not familiar with Cadence/NCLaunch, but knowing your code analyzes correctly in an IEEE 1076-1993 compliant tool, and noting where error is (you indicated character position 11 in line 29, noting it appears to be character position 17), I'd say off hand it either doesn't have "xnor" un-commented in package std_logic_1164 (both the specification and the body), or it's a VHDL87 compliant tool, or there's some missing tool set or command line argument to use use the proper std_logic_1164 package.
In the distributed source for std_logic_1164, available from
http://standards.ieee.org/downloads/1076/1076.2-1996/
-- --------------------------------------------------------------------
-- version | mod. date:|
-- v4.200 | 01/02/92 |
-- --------------------------------------------------------------------
You'll find that xnor is commented out by default, when after VHDL92 (-1993, don't ask) was approved it was supposed to be un-commented.
-- -----------------------------------------------------------------------
-- Note : The declaration and implementation of the "xnor" function is
-- specifically commented until at which time the VHDL language has been
-- officially adopted as containing such a function. At such a point,
-- the following comments may be removed along with this notice without
-- further "official" ballotting of this std_logic_1164 package. It is
-- the intent of this effort to provide such a function once it becomes
-- available in the VHDL standard.
-- -----------------------------------------------------------------------
-- function "xnor" ( l, r : std_logic_vector ) return std_logic_vector;
-- function "xnor" ( l, r : std_ulogic_vector ) return std_ulogic_vector;
9.5.1 refers to Conditional signal assigns in IEEE=1076-1993.
The analyzer is acting like it doesn't recognize xnor as a operator and if you look in -1993 7.2.1 Logical operators:
The logical operators and, or, nand, nor,xor, xnor, and not are
defined for predefined types BIT and BOOLEAN. They are also defined
for any one-dimensional array type whose element type is BIT or
BOOLEAN.
Which tells us in an IEEE 1076-1993 compliant tool the declarations for xnor would come from the std_logic_1164 package.
I had a quick gander through some NCSIM, etc. online user guides and tutorials and didn't see anything relating to the problem. It's likely the std_logic_1164 package hadn't had xnor un-commented in both the declaration and body.
The issue may be the the providence (age) or the particular tool copy you are using and may require sysadmin help to correct. In the mean time you can either write your own xnor function (shown), if running into any difficulties try and use not( a xor b) instead.
architecture dataflow of Comparator is
function "xnor" ( l : std_logic; r : std_logic ) return ux01 is
begin
return not (l xor r);
end "xnor";
signal AeB : std_logic;
signal AlB : std_logic;
signal AgB : std_logic;
signal i : std_logic_vector (3 downto 0);
signal j : std_logic_vector (3 downto 0);
begin
Also see Weird XNOR behaviour in VHDL
Related
library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_bit.ALL;
use ieee.numeric_std.ALL;
entity multiplexer is
port (A,B: in std_logic_vector (7 downto 0);
CI: in std_logic;
CO: out std_logic;
ANS: out std_logic_vector (7 downto 0);
OP: in std_logic_vector(1 downto 0);
EN: in std_logic);
end multiplexer;
architecture archi of multiplexer is
signal tmp: std_logic_vector (8 downto 0);
begin
process (EN) begin
if (EN = '1') Then
case OP is
when "00" =>
tmp <= std_logic_vector((TO_INTEGER(A)+TO_INTEGER(B)+TO_INTEGER (CI)),9);
ANS<= tmp(7 downto 0);
CO <= tmp(8);
when "01" =>
tmp <= std_logic_vector((to_integer(A)-to_integer(B)+to_integer (CI)),9);
ANS<= tmp(7 downto 0);
CO <= tmp(8);
when others => NULL;
end case;
else
NULL;
end if;
end process;
end archi;
The errors are coming in the To_integer part. I donot know what I am doing wring over here? Also previously I had used the numeric_arith and numeric_unsigned.all and then the subprograms were conv_integer the program compiled but there were no output in the ANS and CO areas. They were defined as undefined. I am attaching the wave output for reference. Please help.
Previous wave output
The issue appears to be having use clauses containing references to both package numeric_std and numeric_bit.
See IEEE 1076-2008 12.4 Use clauses, para 8:
In order to determine which declarations are made directly visible at a given place by use clauses, consider the set of declarations identified by all use clauses whose scopes enclose this place. Any declaration in this set is a potentially visible declaration. A potentially visible declaration is actually made directly visible except in the following three cases:
a) A potentially visible declaration is not made directly visible if the place considered is within the immediate scope of a homograph of the declaration.
b) If two potentially visible declarations are homographs and one is explicitly declared and the other is implicitly declared, then the implicit declaration is not made directly visible.
c) Potentially visible declarations that have the same designator and that are not covered by case b) are not made directly visible unless each of them is either an enumeration literal specification or the declaration of a subprogram.
Noting you have two potentially visible declarations, e.g.:
The errors are :** Error: C:/altera/16.0/multiplexer2.vhd(17): (vcom-1078) Identifier "unsigned" is not directly visible.
Potentially visible declarations are: ieee.NUMERIC_STD.UNSIGNED (subtype declaration) ieee.NUMERIC_BIT.UNSIGNED (type declaration)
unsigned, a type declaration is not visible under rule c) above.
As Jim notes you don't use type unsigned based on type bit_vector, all object declarations present are based on std_logic and not bit.
Further, 16.8.5.1 General paras 1
Four VHDL packages for arithmetic using bit and standard logic values are defined by this standard. The NUMERIC_BIT and NUMERIC_BIT_UNSIGNED packages are based on the VHDL type BIT, while the NUMERIC_STD and NUMERIC_STD_UNSIGNED packages are based on the type STD_ULOGIC.
and para 6 (in part):
The four packages are mutually incompatible, and only one shall be used in any given design unit.
You've demonstrated that incompatibility, attempting to use a declaration that is neither an enumeration literal nor subprogram (not subject to overload resolution).
If you're tool had been -2008 aware it should have provided an error (shall is mandatory, see 1.3.1) and use clauses for both made visible in the same declarative region are detectable (although not a convenient error to detect).
In general you should use the minimum number of use clauses necessary, providing resources needed for a design description to avoid these sorts of issues.
Commenting out the use clause referencing numeric_bit is not sufficient. The base type of CI is std_ulogic (it's type is std_logic). You can convert a std_logic to an unsigned excepted by expressing CI as a an array type:
library ieee;
use ieee.std_logic_1164.ALL;
-- use ieee.numeric_bit.ALL;
use ieee.numeric_std.ALL;
entity multiplexer is
port (
A,B: in std_logic_vector (7 downto 0);
CI: in std_logic;
CO: out std_logic;
ANS: out std_logic_vector (7 downto 0);
OP: in std_logic_vector(1 downto 0);
EN: in std_logic);
end multiplexer;
architecture archi of multiplexer is
signal tmp: std_logic_vector (8 downto 0);
begin
tmp <= std_logic_vector(unsigned(A)+unsigned(B)+unsigned'(""& CI)) when EN =
'1' and OP = "00" else
std_logic_vector(unsigned(A)-unsigned(B)+unsigned'(""& CI)) when EN = '0' and
OP = "01" else
(others => '0');
-- tmp <= std_logic_vector(unsigned(A)+unsigned(B)+unsigned(CI)) when EN =
-- '1' and OP = "00" else
-- std_logic_vector(unsigned(A)-unsigned(B)+unsigned(CI)) when EN = '0' and
-- OP = "01" else
-- (others => '0');
ANS<= tmp(7 downto 0);
CO <= tmp(8);
end archi;
unsigned'(""& CI) qualifies the expression "" & CI (a null array concatenated with CI as type unsigned.
See 9.3.5 Qualified expressions, para 1:
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.
For the array type unsigned concatenation operators are predefined for concatenation between a value of a single dimensional array type and it's element type. See 9.2.5 Adding operators. The string literal "" has a length of zero (15.7 String literals, 5.3.2.2 Index constraints and discrete ranges, para 4), and it's type is context defined by the qualified expression (See 9.3.2 Literals para 5).
Making the above changes and your multiplexer analyzes. It's functionality is not tested lacking a Minimal, Complete, and Verifiable example.
1. to_integer
Look for documentation for numeric_std package. You can't put std_logic_vector to to_integer function. You have to first cast it to unsigned:
signal a: std_logic_vector(8 downto 0);
signal b: std_logic_vector(8 downto 0);
signal res: integer;
res <= to_integer(unsigned(a) + unsigned(b));
But actually, in your case you don't have to do it at all. Just cast std_logic_vector to unsigned (or signed), and then you can safely add it:
tmp <= std_logic_vector(unsigned(A)+unsigned(B)+unsigned(CI));
2. UUU thing
First - as I already told you - you must have all inputs in sensitivity list, if you want to do it without clock. But this will not help, because you are using signals. Remember, that when you assign something to signal, it is not done immediately, but it is only sceduled, to be done after the process. So after line:
tmp <= std_logic_vector((TO_INTEGER(A)+TO_INTEGER(B)+TO_INTEGER(CI)),9);
tmp does not yet contain result, but still has UUU. Then in lines:
ANS<= tmp(7 downto 0);
CO <= tmp(8);
you assign U to ANS and CO. What you can do is to use variables in process, or even better - to put lines:
ANS<= tmp(7 downto 0);
CO <= tmp(8);
outside of the process:
library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.ALL;
entity multiplexer is
port (
A,B: in std_logic_vector (7 downto 0);
CI: in std_logic;
CO: out std_logic;
ANS: out std_logic_vector (7 downto 0);
OP: in std_logic_vector(1 downto 0);
EN: in std_logic);
end multiplexer;
architecture archi of multiplexer is
signal tmp: std_logic_vector (8 downto 0);
begin
process (EN) begin
if (EN = '1') Then
case OP is
when "00" =>
tmp <= std_logic_vector(unsigned(A)+unsigned(B)+unsigned(CI));
when "01" =>
tmp <= std_logic_vector(unsigned(A)-unsigned(B)+unsigned(CI));
when others => NULL;
end case;
else
NULL;
end if;
end process;
ANS<= tmp(7 downto 0);
CO <= tmp(8);
end archi;
or even get rid of process at all:
architecture archi of multiplexer is
signal tmp: std_logic_vector (8 downto 0);
begin
tmp <= std_logic_vector(unsigned(A)+unsigned(B)+unsigned(CI)) when EN = '1' and OP = "00" else
std_logic_vector(unsigned(A)-unsigned(B)+unsigned(CI)) when EN = '1' and OP = "01" else
(others => '0');
ANS<= tmp(7 downto 0);
CO <= tmp(8);
end archi;
In my filter design , I am using fixed point arithmetic and using sfixed for signals. The design synthesizes with all timing met but my functional simulation and post synth/P&R simulation do not match after arith logic blocks.. Giving a small ex below, where I see that crf_int_r does not match in Post synth simulation.. Can someone help me understand , whether it is not synthesized properly or some other issue for a mismatch between functional and post synth simulation..Using Xilinx ISE 14.7 and VHDL 200X option in ISE.
signal add_alpha1_r : sfixed(5 downto -13) ;
signal add_alpha2_r : sfixed(6 downto -13) ;
signal crf_r : sfixed(17 downto -13) ;
signal crf_int_r : sfixed(17 downto -7) ;
signal alpha_log : sfixed(4 downto -13) ;
signal imgdel_r_d4 : sfixed(4 downto -13) ;
signal imgsum_d2 : sfixed(4 downto -13) ;
add_alpha1_r <= imgdel_r_d4 - imgsum_d2 ; --19.13
add_alpha2_r <= alpha_log + add_alpha1_r ; -- 20.13
crf_r <= add_alpha2_r * beta ; -- 31.13
crf_int_r <= crf_r(17 downto -7);
You encountered a synthesis bug. Making a Minimal, Complete, and Verifiable example from the code presented in the comments, I have tried to synthesize this with ISE 14.7 and VHDL-200X option on:
library ieee;
use ieee.std_logic_1164.all;
library ieee_proposed;
use ieee_proposed.fixed_pkg.all;
entity sfixed_test is
port (alpha_log : out sfixed(4 downto -13));
end sfixed_test;
architecture rtl of sfixed_test is
constant alpha : sfixed(10 downto 0) := "00001111000"; -- 120
type rom_t is array(0 to 2047) of sfixed(4 downto -13);
constant alpha_rom : rom_t := (120 => "111111111111111111",
others => "000000000000000000");
begin -- rtl
alpha_log <= alpha_rom(to_integer(alpha));
end rtl;
XST reports the following warning:
Warning: "::fixed_pkg:TO_INTEGER (sfixed): metavalue detected, returning 0"
A quick look into the RTL or Technology Map Viewer shows, that all outputs were connected to ground instead of VCC as intended in my example.
The problem is the implementation of to_integer as described bewlow. You can work around this, if you change the reading from the ROM to:
alpha_log <= alpha_rom(to_integer(unsigned(std_logic_vector(alpha))));
and also include the package ieee.numeric_std. Then everything works fine.
Further notes: The warning message refers to line 5085 ff. of ieee_proposed/fixed_pkg_c.vhd shipped with ISE. It reads:
if (Is_X (arg)) then
assert NO_WARNING
report fixed_pkg'instance_name
& "TO_INTEGER (sfixed): metavalue detected, returning 0"
severity warning;
return 0;
end if;
Is_X(arg) checks whether the argument contains a U, X, Z, W, or -. It fails here if arg (which is alpha) is a constant. But, it works when alpha is a signal (input).
I am new to the VHDL language, so please bear with me and please help me out.
I have written code for a addition/subtraction unit which will operate on signed integer but at the "if else" part in the last, the compiler is giving an error.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity adder is
port(A,B : in std_logic_vector(3 downto 0);
SUM : out std_logic_vector(3 downto 0);
mode: in std_logic_vector(0 downto 0));
end adder;
architecture behave of adder is
component xorgate is
port( p,q: in std_logic_vector(3 downto 0);
r: out std_logic_vector(3 downto 0));
end component;
signal a1,b1,sum1,output1,mode1:integer;
signal tmp: std_logic_vector(3 downto 0);
variable output: std_logic_vector(3 downto 0);
begin
u1: xorgate port map (B, mode, output);
output1 <= to_integer(signed (output));
a1 <= to_integer(signed(A));
b1 <= to_integer(signed(B));
mode1 <= to_integer(signed(mode));
process(a1,output1,b1,tmp,mode1)
begin
if ( mode1 <= '1') then
sum1 <= a1 + output1 ;
else
sum1 <= a1 + b1;
end if;
tmp <= std_logic_vector(to_signed(sum1,4));
SUM <= tmp( 3 downto 0);
end process;
end behave;
XST Error Message:
ERROR: HDLCompiler:1731 - "E:\XILINX PROGRAM\FULLADD\FULLADD.vhd" Line 31: found '0' definitions of operator "<=", cannot determine exact overloaded matching definition for "<="
ERROR: HDLCompiler:854 - "E:\XILINX PROGRAM\FULLADD\FULLADD.vhd" Line 11: Unit ignored due to previous errors.
Line 31: if ( mode1 <= '1') then
you meant: if ( mode1 = 1) then
Line 11: This just means that because of the previous error, the compiler 'gave up'.
The <= operator in mode1 <= '1' is less-than-or-equal compare of integer with '1', which have no definition, thus the found '0' definitions of operator "<=". Change '1' to simply the integer literal1`.
Other issues with the code are listed below.
The ´variable output: ...´ must be signal output: when output is used as actual for in port map for xorgate. In typical design you don't have variables in the declaration section, between begin and end, of an architecture.
Length of mode is only 1 std_logic (bit), but actual for mode in xorgate port map, which is q in xorgate, is 4 bits. You probably meant to make mode as 3 downto 0 in the port declaration of adder, since compare like mode1 <= 1 will be trivial true if mode is 1 bit.
The intermediate integer signals named *1 and other signal are actually not required if the process uses signed additions from numeric_std package like:
process(A, B, mode, output) is
begin
if signed(mode) <= 1 then
SUM <= std_logic_vector(signed(A) + signed(output));
else
SUM <= std_logic_vector(signed(A) + signed(B));
end if;
end process;
And this can even be reduced to the below, with only output as intermediate signal:
SUM <= std_logic_vector(signed(A) + signed(output)) when (signed(mode) <= 1)
else std_logic_vector(signed(A) + signed(B));
Finally, if mode is to be treaded like unsigned, then replace with unsigned(mode), since unsigned is also defined in the numeric_std package.
The puzzle is probably why the error message is about failure to find an overloaded operator
'1' has at least two definitions, first as a character literal, then as a bit literal. Neither of these have a <= operator comparing them with type Integer, and that's why the compiler gave up.
If you had used an integer literal 1 instead, the compiler could have found a <= operator easily... so if mode1 <= '1' then would work.
Alternatively, you could write your own <= operator accepting inputs of these two types and returning a boolean :
function "<=" (a : Integer; b : Bit) return Boolean is ...
While it would work, it would also deserve a slap on the wrist!
My input data is 2's compliment and I designed the input is signed number and the all of operation is used signed number,the library i used ieee.numeric_std.all, but when i do ‘+’ an error occurred "found '0' definitions of operator "+", cannot determine exact overloaded matching definition for "+"". So I changed another to another library ieee.std_logic_arith.all ans make the add operation as a component, it works.
when i simulate my code by using testbench, error occurred: Entity port xin does not match with type signed of component port.
I think this error is about my library.
can anyone help me ?
new
i do not use adder as a component and the below code works
adder: process(clk)
begin
if (clk'event and clk = '1')then
if enable1='1' then
add1 <= (x0(7)&x0) + (x15(8)&x15);
add2 <= (x1(7)&x1) + (x14(8)&x14);
add3 <= (x2(7)&x2) + (x13(8)&x13);
add4 <= (x3(7)&x3) + (x12(8)&x12);
add5 <= (x4(7)&x4) + (x11(8)&x11);
add6 <= (x5(7)&x5) + (x10(8)&x10);
add7 <= (x6(7)&x6) + (x9(8)&x9);
add8 <= (x7(7)&x7) + (x8(8)&x8);
end if;
end if;
end process adder;
and the library of my testbench use use ieee.numeric_std.all;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
use std.textio.all;
ENTITY tb_signedinput IS
END tb_signedinput;
ARCHITECTURE behavior OF tb_signedinput IS
-- Component Declaration
COMPONENT signedinput is
port( Clk : in std_logic;
reset : in std_logic;
enable1 : in std_logic;
Xin : in signed(7 downto 0);
Yout : out signed(19 downto 0)
);
END COMPONENT;
--Inputs
signal Clk : std_logic := '0';
signal reset : std_logic := '0';
signal Xin : signed(7 downto 0) := (others => '0');
signal enable1 : std_logic := '0';
--Outputs
signal Yout : signed(19 downto 0);
-- Array
constant MEMSIZE: integer :=99;
type testarray is array (MEMSIZE downto 0) of signed(7 DOWNTO 0);
signal testvectors: testarray;
shared variable vectornum,outnum: integer;
-- Clock period definitions
constant Clk_period : time := 10 ns;
BEGIN
-- Component Instantiation
uut: signedinput PORT MAP( Clk => Clk,
reset => reset,
Xin => Xin,
enable1 =>enable1,
Yout => Yout );
the error still occur:
Entity port xin does not match with type std_logic_vector of component port
Entity port yout does not match with type std_logic_vector of component port
therefore, I changed my adder again to
add1 <= resize(x0,9) + x15;
syntax good but same error in testbench..
Is error about my ISE type or library type?
Thank you!
Your addition expression in adder1 is invalid because you're trying to index element "8" when the range of a1 and a2 is 7 downto 0.
Assuming thet you're trying to sign extend it would look something more like this:
q <=(a1(7)&a1 + a2(7)&a2);
The "+" operator has higher precedence than "&" so you are trying to add a1 + a2(7) which is signed + std_logic. This doesn't have an overload defined in numeric_std in addition to being logically wrong.
This works:
q <=(a1(7)&a1) + (a2(7)&a2);
But it isn't the canonical way to implement sign extension when using numeric_std. You only need the left side term to have the same size as q. The signed "+" operator will take care of sign extending its right hand side automatically.
q <= resize(a1, q'length) + a2; -- Sign extend a1 and add
This gives cleaner code that says what it's doing without relying on the non-standard std_logic_arith.
The actual error about the type mismatch on xin isn't apparent from your code. It is possible that you have an older version of signedinput compiled with a different type on its port and haven't updated the library.
Kevin made it look tough, so I figured I'd show something that makes for a good explanation:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity adder1 is
port (
a1: in signed (7 downto 0);
a2: in signed (7 downto 0);
clk: in std_logic;
enable1: in std_logic;
q: out signed (8 downto 0)
);
end entity;
architecture behavioral of adder1 is
begin
UNLABELLED:
process(clk)
begin
if clk'event and clk ='1' then
if enable1 = '1' then
q <= a1(7) & a1 + a2 ;
end if;
end if;
end process;
end architecture;
The assignment to q looks naked so it's worth explaining.
The "+" in numeric_std for signed will sign extend the shorter operand to match the length of the longer operand.
The rest is priority magic.
"+" and "&" are the same priority, which means they're evaluated in left to right textual order, meaning the sign extension with the concatenation operator is performed first (see IEEE Std 1076-2008, 9.2 Operators).
The "+" operator sees the left operand as longer and matches the right operand to it's length, (see package numeric_std "+" for L,R: signed). It does this by using signed RESIZE on both operands after finding the MAX of the length of both, along with converting metavalues to 'X's.
It works if the right operand is longer too:
q <= a1 + (a2(7) & a2) ;
And here we need parentheses to associate the result of the concatenation operator as the right operand of the adding operator, because the two operators are the same priority and would otherwise be encountered in textual order.
There's no reason to call resize yet again, it's only a one bit sign extension by concatenation, based on knowing the sign is embodied in the left hand element (bit) of a two's compliment number.
The term canonical is not found in the VHDL standard.
As far as Xin, I'd agree with Kevin, something likely needs to be reanalyzed so that both references to signed are found in the same package.
Each declaration used in a design is unique. If say the actual in the port map depends on the type signed declaration in package std_logic_arith and the formal were to depend on the declaration of signed in package numeric_std they would be of different types.
lets say I have an n-bit array. I want to AND all elements in the array. Similar to wiring each element to an n-bit AND gate.
How do I achieve this in VHDL?
Note: I am trying to use re-usable VHDL code so I want to avoid hard coding something like
result <= array(0) and array(1) and array(2)....and array(n);
Thanks
Oshara
Solution 1: With unary operator
VHDL-2008 defines unary operators, like these:
outp <= and "11011";
outp <= xor "11011";
outp <= and inp; --this would be your case
However, they might not be supported yet by your compiler.
Solution 2: With pure combinational (and traditional) code
Because in concurrent code you cannot assign a value to a signal more than once, your can create a temp signal with an "extra" dimension. In your case, the output is one-bit, so the temp signal should be a 1D array, as shown below.
-------------------------------------------
entity unary_AND IS
generic (N: positive := 8); --array size
port (
inp: in bit_vector(N-1 downto 0);
outp: out bit);
end entity;
-------------------------------------------
architecture unary_AND of unary_AND is
signal temp: bit_vector(N-1 downto 0);
begin
temp(0) <= inp(0);
gen: for i in 1 to N-1 generate
temp(i) <= temp(i-1) and inp(i);
end generate;
outp <= temp(N-1);
end architecture;
-------------------------------------------
The inferred circuit is shown in the figure below.
Solution 3: With sequential code
This is simpler than solution 2, though you are now using sequential code to solve a purely combinational problem (but the hardware will be the same). You can either write a code similar to that in solution 2, but with a process and loop (the latter, in place of generate) or using a function. Because in sequential code you are allowed to assign a value to a signal more than once, the temp signal of solution 2 is not needed here.
If you have VHDL-2008 available, then reduction and is build into the
language as David Koontz and Pedroni have explained.
If you only have VHDL-2003 and prior available, then you can use a function
like:
function and_reduct(slv : in std_logic_vector) return std_logic is
variable res_v : std_logic := '1'; -- Null slv vector will also return '1'
begin
for i in slv'range loop
res_v := res_v and slv(i);
end loop;
return res_v;
end function;
You can then use the function both inside and outside functions with:
signal arg : std_logic_vector(7 downto 0);
signal res : std_logic;
...
res <= and_reduct(arg);
My favorite, non-VHDL-2008 solution is:
use ieee.std_logic_unsigned.all ; -- assuming not VHDL-2008
. . .
result <= '1' when not MyArray = 0 else '0' ;
With VHDL-2008, I recommend that you use the "and" reduction built-in (see Pedroni's post) and use the IEEE standard package "ieee.numeric_std_unsigned.all" instead of the shareware package "std_logic_unsigned".