How to instanciate a component for generation multiple component parallel? - vhdl

I try to generate a multiple componnt by using the generic map , but i dont know if my code VHDL is correct or no ?
here the programm generate 5 parallel component ( comp) for forming bascule
entity bascule is
Port ( X1,X2,X3,X4,X5: in STD_LOGIC;
Y1,Y2, Y3,Y4,Y5 : in STD_LOGIC;
Z1,Z2,Z3,Z4,Z5 : in STD_LOGIC;
S1,S2,S3,S4,S5 : out STD_LOGIC);
end bascule;
architecture Behavioral of bascule is
component comp
Generic( N: integer :=1);
Port ( X : in STD_LOGIC;
Y : in STD_LOGIC;
Z: in STD_LOGIC;
S : out STD_LOGIC);
end component;
begin
m1 : comp generic map (5)
port map ( X1,Y1,Z1, S1);
m2 : comp generic map (5)
port map ( X2,Y2,Z2, S2);
m3 : comp generic map (5)
port map ( X3,Y3,Z3, S3);
m4 : comp generic map (5)
port map ( X4,Y4,Z4, S4);
m5 : comp generic map (5)
port map ( X5,Y5,Z5, S5);
end Behavioral;
i want to know the way to generate any number of component ?
my best regards

i want to know the way to generate any number of component ?
The key is the word "generate"...
you can use a for..generate loop. In order to do this, you need to express your top entity with the same number of vector inputs as the number of components you expect:
entity bascule is
generic ( number_of_comps : positive)
port ( X,Y,Z: in STD_LOGIC_VECTOR(number_of_comps downto 1);
S : out STD_LOGIC_VECTOR(number_of_comps downto 1));
end bascule;
Then in the architecture you can wire up your components like this:
for i in 1 to number_of_comps generate
inst : entity work.comp
generic map (5)
port map ( X(i),Y(i),Z(i), S(i));
end generate;
I think you may still have a confusion, as you have a generic of 5 on your lower level comp, but it sounds to me like that generic should only be in the top entity, to specify how many comps you want (unless you are then doing the same in the comp entity?)

library ieee;
use ieee.std_logic_1164.all;
-- dummy comp this analyzes and elaborates
entity comp is
Generic( N: integer :=1);
Port (
X: in STD_LOGIC;
Y: in STD_LOGIC;
Z: in STD_LOGIC;
S: out STD_LOGIC
);
end entity;
architecture behave of comp is
begin
S <= X and Y and Z;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity bascule is
Port (
-- X1,X2,X3,X4,X5: in STD_LOGIC;
-- Y1,Y2, Y3,Y4,Y5: in STD_LOGIC;
-- Z1,Z2,Z3,Z4,Z5: in STD_LOGIC;
-- S1,S2,S3,S4,S5: out STD_LOGIC
-- and yes, you could pass the number of elements in these as a generic:
X: in std_logic_vector (1 to 5);
Y: in std_logic_vector (1 to 5);
Z: in std_logic_vector (1 to 5);
S: out std_logic_vector (1 to 5)
);
end bascule;
architecture Behavioral of bascule is
component comp
Generic( N: integer :=1);
Port (
X: in STD_LOGIC;
Y: in STD_LOGIC;
Z: in STD_LOGIC;
S: out STD_LOGIC
);
end component;
begin
M_gen:
-- and use the same generic as above in the generate iteration scheme:
for i in 1 to 5 generate
M:
comp generic map (5)
port map (
X(i), Y(i), Z(i), S(i)
);
end generate;
-- m1 : comp generic map (5)
-- port map ( X1,Y1,Z1, S1);
-- m2 : comp generic map (5)
-- port map ( X2,Y2,Z2, S2);
-- m3 : comp generic map (5)
-- port map ( X3,Y3,Z3, S3);
-- m4 : comp generic map (5)
-- port map ( X4,Y4,Z4, S4);
-- m5 : comp generic map (5)
-- port map ( X5,Y5,Z5, S5);
end Behavioral;
Using a generic to control a generate statement interation instantiating comp
Because you appear confused about how to use generics to control the number of components, I'll demonstrate:
library ieee;
use ieee.std_logic_1164.all;
-- dummy comp
entity comp is
Port (
X: in STD_LOGIC;
Y: in STD_LOGIC;
Z: in STD_LOGIC;
S: out STD_LOGIC
);
end entity;
architecture behave of comp is
begin
S <= X and Y and Z;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity bascule is
generic (MSIZE: natural := 1);
Port (
X: in std_logic_vector (1 to MSIZE);
Y: in std_logic_vector (1 to MSIZE);
Z: in std_logic_vector (1 to MSIZE);
S: out std_logic_vector (1 to MSIZE)
);
end bascule;
architecture Behavioral of bascule is
component comp
Port (
X: in STD_LOGIC;
Y: in STD_LOGIC;
Z: in STD_LOGIC;
S: out STD_LOGIC
);
end component;
begin
Mgen:
for i in 1 to MSIZE generate
M:
comp
port map (
X(i), Y(i), Z(i), S(i)
);
end generate;
end Behavioral;
library ieee;
use ieee.std_logic_1164.all;
entity bascule_tb is
end entity;
architecture foo of bascule_tb is
constant MSIZE: natural :=5;
signal X: std_logic_vector (1 to MSIZE);
signal Y: std_logic_vector (1 to MSIZE);
signal Z: std_logic_vector (1 to MSIZE);
signal S: std_logic_vector (1 to MSIZE);
begin
DUT: entity work.bascule
generic map (MSIZE)
port map (
X => X,
Y => Y,
Z => Z,
S => S
);
end architecture;
We get MSIZE number of comp components based on the generic MSIZE, which is passed the constant MSIZE where bascule is instantiated in the test bench bascule_tb. This analyzes, elaborates and runs (though it doesn't actually do anything).

Related

16 to 1 mux using 2 to 1 mux in vhdl

I'm trying to write a code in vhdl to create a 16 to 1 mux using 2 to 1 mux.
I actually thought that to do this we may need 15 two to one multiplexers and by wiring them together and using structural model I wrote the code below.
First I wrote a 2 to 1 mux:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity MUX_2_1 is
port (
w0 , w1 : IN STD_LOGIC;
SELECT_I: IN std_logic;
DATA_O: out std_logic
);
end MUX_2_1;
architecture MUX_2_1_arch of MUX_2_1 is
--
begin
--
WITH SELECT_I SELECT
DATA_O <= w0 WHEN '0',
w1 WHEN '1',
'X' when others;
--
end MUX_2_1_arch;
and made a package from it, just to use it simple and easy:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
PACKAGE mux2to1_package IS
COMPONENT mux2to1
PORT (w0, w1: IN STD_LOGIC ;
SELECT_I: IN std_logic;
DATA_O: out std_logic ) ;
END COMPONENT ;
END mux2to1_package ;
and then my 16 to 1 mux looks like this:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
USE work.mux2to1_package.all ;
ENTITY mux16to1 IS
PORT (w : IN STD_LOGIC_VECTOR(15 DOWNTO 0) ;
s : IN STD_LOGIC_VECTOR(3 DOWNTO 0) ;
f : OUT STD_LOGIC ) ;
END mux16to1 ;
ARCHITECTURE Structure OF mux16to1 IS
SIGNAL im : STD_LOGIC_VECTOR(7 DOWNTO 0) ;
SIGNAL q : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL p : STD_LOGIC_VECTOR(1 DOWNTO 0);
BEGIN
Mux1: mux2to1 PORT MAP ( w(0), w(1), s(0), im(0)) ;
Mux2: mux2to1 PORT MAP ( w(2), w(3), s(0), im(1)) ;
Mux3: mux2to1 PORT MAP ( w(4), w(5), s(0), im(2)) ;
Mux4: mux2to1 PORT MAP ( w(6), w(7), s(0), im(3)) ;
Mux5: mux2to1 PORT MAP ( w(8), w(9), s(0), im(4)) ;
MUX6: mux2to1 PORT MAP ( w(10), w(11), s(0), im(5));
Mux7: mux2to1 PORT MAP ( w(12), w(13), s(0), im(6)) ;
Mux8: mux2to1 PORT MAP ( w(14), w(15), s(0), im(7)) ;
Mux9: mux2to1 PORT MAP ( im(0), im(1), s(1), q(0)) ;
Mux10: mux2to1 PORT MAP ( im(2), im(3), s(1), q(1)) ;
Mux11: mux2to1 PORT MAP ( im(4), im(5), s(1), q(2)) ;
Mux12: mux2to1 PORT MAP ( im(6), im(7), s(1), q(3)) ;
Mux13: mux2to1 PORT MAP ( q(0), q(1), s(2), p(0)) ;
Mux14: mux2to1 PORT MAP ( q(2), q(3), s(2), p(1)) ;
Mux15: mux2to1 PORT MAP ( p(0), p(1), s(3), f) ;
END Structure ;
and also my testbench is:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
USE work.mux2to1_package.all ;
ENTITY Mux_test IS
END Mux_test;
ARCHITECTURE test OF Mux_test IS
COMPONENT mux16to1 PORT(w : IN STD_LOGIC_VECTOR(15 DOWNTO 0) ;
s : IN STD_LOGIC_VECTOR(3 DOWNTO 0) ;
f : OUT STD_LOGIC ) ;
END COMPONENT;
SIGNAL wi : STD_LOGIC_VECTOR(15 DOWNTO 0) ;
SIGNAL selecting : STD_LOGIC_VECTOR(3 DOWNTO 0) ;
SIGNAL fi : STD_LOGIC ;
BEGIN
a1: mux16to1 PORT MAP(wi , selecting , fi);
wi<= "0101110010001010" , "1001000101010101" after 100 ns;
selecting <= "0011" , "1010" after 20 ns , "1110" after 40 ns, "1100" after 60 ns , "0101" after 80 ns,
"0011" after 100 ns , "1010" after 120 ns , "1110" after 140 ns, "1100" after 160 ns , "0101" after 180 ns;
END ARCHITECTURE;
my simulation:
But when I try to simulate this nothing shows in my output. I'm thinking that maybe that's because I wrote my code in concurrent part and signals im and q and p are not initialized yet so I tried using default values "00000000" for im and "0000" for q and "00" for p when I was declaring the signals, but then I got bunch of errors saying "Instance mux2to1 is unbound" in simulation and nothing actually changed.
Any idea what is the problem??
Also I think there is something wrong with my select input logically.
but I don't understand how i should use the select to be correct for this problem.
I would appreciate if anyone can help me with my problem.
Virtual component binding using component declarations can either be explicit using a configuration specification to supply a binding indication, or rely on a default binding indication.
A default binding indication would rely on finding an entity declared in a reference library whose name matches the component name. That's not the case here, your entity is named MUX_2_1 (case insensitive) while the component name is mux2to1.
It's not illegal to have components unbound in VHDL, it's the equivalent of not loading a component in a particular location in a printed circuit or bread board, it simply produces no output which shows in simulation here as a 'U'.
Here the solutions could be to either change the name of the entity in both the entity declaration and it's architecture from MUX_2_1 to mux2to1, change the component declaration to MUX_2_1 or provide a configuration specification providing an explicit binding indication as a block declarative item in the architecture for mux16to1 of the form
ARCHITECTURE Structure OF mux16to1 IS
SIGNAL im : STD_LOGIC_VECTOR(7 DOWNTO 0) ;
SIGNAL q : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL p : STD_LOGIC_VECTOR(1 DOWNTO 0);
for all: mux2to1 use entity work.MUX_2_1; -- ADDED
When used the latter method provides '1' and '0' outputs on testbench signal fi during simulation.
The testbench can be made more elaborate to demonstrate that the selects are valid. One way would be with marching '0's or '1's in w elements while scanning all the elements and looking for a mismatch:
library ieee;
use ieee.std_logic_1164.all;
entity mux16to1_tb is
end mux16to1_tb;
architecture test of mux16to1_tb is
component mux16to1 is
port (
w: in std_logic_vector(15 downto 0);
s: in std_logic_vector(3 downto 0);
f: out std_logic
);
end component;
signal w: std_logic_vector(15 downto 0);
signal s: std_logic_vector(3 downto 0);
signal f: std_logic;
function to_string (inp: std_logic_vector) return string is
variable image_str: string (1 to inp'length);
alias input_str: std_logic_vector (1 to inp'length) is inp;
begin
for i in input_str'range loop
image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i)));
end loop;
return image_str;
end function;
begin
DUT:
mux16to1
port map (
w => w,
s => s,
f => f
);
STIMULI:
process
use ieee.numeric_std.all;
begin
for i in w'reverse_range loop
w <= (others => '1');
w(i) <= '0';
for j in w'reverse_range loop
s <= std_logic_vector(to_unsigned(j, s'length));
wait for 10 ns;
end loop;
end loop;
wait;
end process;
VALIDATE:
process
begin
for x in w'reverse_range loop
for y in w'reverse_range loop
wait for 10 ns;
assert f = w(y)
report
LF & HT & "f = " & std_ulogic'image(f) & " " &
"expected " & std_ulogic'image(w(y)) &
LF & HT & "w = " & to_string(w) &
LF & HT & "s = " & to_string(s)
severity ERROR;
end loop;
end loop;
wait;
end process;
end architecture;
The output f of mux16to1 is selected for each value of w using a marching '0's pattern. Any mismatch between f and the selected name element value of w is reported with diagnostic information.
Here we see that mux16t01 implements a 16:1 selection properly without the need to modify the original posters design.
Without error injection the testbench waveforms for w, s and f can be viewed in a waveform display to validate correct operation.

Using generic for a type in a port entity in VHDL 93

I have a type declared in a package which I use in the port entity:
Package:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
package ports_type is
constant N: positive := 3;
type t_ports_types is array(0 to N-1) of std_logic_vector (N-1 downto 0);
end package ports_type;
Module:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ports_type.all;
entity ports is
generic (
N : positive := 3
);
port(
inp : in t_ports_types;
outp : out std_logic_vector(N-1 downto 0)
);
end ports;
architecture Behavioral of ports is
begin
process(inp)
variable result : std_logic;
begin
for y in 0 to N-1 loop
result := '0';
for x in 0 to N-1 loop
result := result or inp(x)(y);
end loop;
outp(y) <= result;
end loop;
end process;
end Behavioral;
The problem is that I have to manually change the value of Nin the package, which is a problem if I want to instantiate the ports entity in another module, like:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ports_type.all;
entity ports_top is
generic (
N : positive := 3
);
Port (
A : in std_logic_vector(N-1 downto 0);
B : in std_logic_vector(N-1 downto 0);
C : in std_logic_vector(N-1 downto 0);
Outp : out std_logic_vector(N-1 downto 0)
);
end ports_top;
architecture Behavioral of ports_top is
signal s_ports : t_ports_types;
begin
s_ports(0) <= A;
s_ports(1) <= B;
s_ports(2) <= C;
ports_0: entity work.ports(Behavioral)
generic map (
N => N
)
port map(
inp => s_ports,
outp => Outp
);
end Behavioral;
The goal would be to only change N in the top module and not in the package as well. Is that possible with vhdl'93?
Thanks for the help.

VHDL typecast signed to std_logic_vector

I am looking at this example and below answer which is a nice solution to produce two's complement:
library ieee;
use ieee.numeric_std.all;
entity twoscomplement is
generic
(
Nbits : positive := 8
);
port
(
A : in unsigned (Nbits-1 downto 0);
Y : out signed (Nbits downto 0)
);
end entity twoscomplement;
architecture a1 of twoscomplement is
begin
Y <= -signed(resize(A, Y'length));
end architecture;
I want to use the said example to have two's complement and then make a "16-bit subtractor". The code will look like the following:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity subtractor_16bit is
Port ( a : in STD_LOGIC_VECTOR(15 downto 0);
b : in STD_LOGIC_VECTOR(15 downto 0);
cin : in STD_LOGIC;
sum : out STD_LOGIC_VECTOR(15 downto 0);
cout : out STD_LOGIC;
over : out STD_LOGIC
);
end subtractor_16bit;
architecture Behavioral of subtractor_16bit is
component fulladder_16bit is
Port (
a : in STD_LOGIC_VECTOR(15 downto 0);
b : in STD_LOGIC_VECTOR(15 downto 0);
cin : in STD_LOGIC;
sum : out STD_LOGIC_VECTOR(15 downto 0);
cout : out STD_LOGIC;
over : out STD_LOGIC
);
end component;
component twoscomplement is
Port (
A : in unsigned (15 downto 0);
C : out signed (15 downto 0)
);
end component;
signal n1 : STD_LOGIC_VECTOR(15 downto 0);
begin
twoscomplement_1: twoscomplement port map (a => a ,c => n1); --ERROR
fulladder_16bit_1: fulladder_16bit port map (a => a, b => n1, sum => sum , cin => cin, cout => cout, over => over);
end Behavioral;
However, I am receiving an error saying:
Error: type error near a; current type std_logic_vector; expected type unsigned.
Kindly help me to solve this problem.
As nobody is answering this and nobody is down voting it, I will answer.
Look at the error
Error: type error near a; current type std_logic_vector; expected type unsigned.
Now look at entity subtractor_16bit.
[...]
entity subtractor_16bit is
Port ( a : in STD_LOGIC_VECTOR(15 downto 0);
[...]
component twoscomplement is
Port (
A : in unsigned (15 downto 0);
[...]
twoscomplement_1: twoscomplement port map (a => a ,c => n1);
[...]
What do you see? twoscomplement expects an unsigned, while a is std_logic_vector! Just like the error says.
std_logic_vector and unsigned are two separate types. As VHDL is a strongly typed language, you cannot just put the data from one type to another. You need to use type conversion.
For unrelated types, you should implement a type conversion function. Or functions, if you want bidirectional conversion. E.g.
function (input : type_a) return type_b;
But in this case, std_logic_vector and unsigned have the same underlying type, std_logic. (std_ulogic actually since VHDL-2008 I believe.)
In that case you can convert from one type to another explicitly. E.g.
signal a_u : unsigned(y downto 0);
signal a_slv : std_logic_vector(y downto 0);
begin
a_u <= unsigned(a_slv);
Next, your not instantiating the twoscomplement component properly. The entity has a generic Nbits. By default you set it to 8. But in your architecture Behavioral of subtractor_16bit, you feed it with 16 bits, without changing the generic value. That doesn't work.
Also: twoscomplement has two ports: A and Y. But in subtractor_16bit you start using A and C. That's bad coding practice.
Finally, you can drop the component declarations. Just instantiate the entities from the library. E.g.
twoscomplement_1: entity work.twoscomplement [...]
So, subtractor_16bit should look something like this:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity subtractor_16bit is
Port (
a : in STD_LOGIC_VECTOR(15 downto 0);
b : in STD_LOGIC_VECTOR(15 downto 0);
cin : in STD_LOGIC;
sum : out STD_LOGIC_VECTOR(15 downto 0);
cout : out STD_LOGIC;
over : out STD_LOGIC
);
end entity;
architecture structural of subtractor_16bit is
use IEEE.NUMERIC_STD.ALL;
signal n1 : signed(a'range);
begin
twoscomplement_1: entity work.twoscomplement
generic map(
NBits => a'length
)
port map (
a => unsigned(a),
y => n1
);
fulladder_16bit_1: entity work.fulladder_16bit
port map (
a => a,
b => std_logic_vector(n1),
sum => sum,
cin => cin,
cout => cout,
over => over
);
end architecture;
...
HOWEVER this will still not work.
As you see on your entity twoscomplement, port A has a size of NBits, and port Y has a size of NBits+1. That is because you seem to want to keep 16-bit value precision. So when converting unsigned to signed, you need to add a 17th bit for the sign. As a result, the rest of you code will need to be modified!
.... But this can be fixed a different way. I will learn you something about two's complement: -a = not(a) + 1.
Proof (Take 4 bits signed precision):
0 = b'0000 => -0 is not(b'0000)+1 = b'1111'+1 = b'0000'
7 = b'0111 => -7 is not(b'0111)+1 = b'1000'+1 = b'1001'
-6 = b'1010' => 6 is not(b'1010)+1 = b'0101'+1 = b'0110'
See?
So now I will solve your puzzle for you:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity subtractor_16bit is
Port (
a : in STD_LOGIC_VECTOR(15 downto 0);
b : in STD_LOGIC_VECTOR(15 downto 0);
sum : out STD_LOGIC_VECTOR(15 downto 0);
cout : out STD_LOGIC;
over : out STD_LOGIC
);
end entity;
architecture structural of subtractor_16bit is
begin
fulladder_16bit_1: entity work.fulladder_16bit
port map (
a => a,
b => not(b),
sum => sum,
cin => '1',
cout => cout,
over => over
);
end architecture;
You will still need to change/fix the cout and over behavior...

How to fix error "Can't resolve indexed name"

I Write and decelerate this code in Modelsim but in my component i will get error "Can't resolve indexed name type std_ulogic as type std_logic_vector". how to fix it?
library IEEE;
use ieee.std_logic_1164.all,ieee.numeric_std.all,Work.all;
entity NbitCarrySkipAdder is
generic (n: integer :=8);
Port(A, B: in std_logic_vector (n-1 downto 0);
Cin: in std_logic;
Sum: out std_logic_vector (n-1 downto 0);
Cout: out std_logic);
end NbitCarrySkipAdder;
architecture behavioral of NbitCarrySkipAdder is
component NBitBlockWithSkipAdder is
generic(n:integer:=4);
port( a, b : in std_logic_vector( n-1 downto 0);
Cin_Block : in std_logic;
S : out std_logic_vector( n-1 downto 0);
Cout_Block : out std_logic);
end component NBitBlockWithSkipAdder;
signal Carry: std_logic_vector(0 to n);
begin
g1: for i in 0 to n-1 generate
lt: if i = 0 generate
f0: NBitBlockWithSkipAdder port map (A(i),B(i),Cin,Sum(i),Carry(i+1));
end generate lt;
rt: if i = n-1 generate
fn: NBitBlockWithSkipAdder port map (A(i),B(i),Carry(i),Sum(i),Cout);
end generate rt;
md: if i > 0 and i < n-1 generate
fm: NBitBlockWithSkipAdder port map (A(i),B(i),Carry(i),Sum(i),Carry(i+1));
end generate md;
end generate g1;
end architecture behavioral;
deceleration of my component is same as deceleration in the above code.
thx
Problem is that A(i) is a std_logic in port map for NBitBlockWithSkipAdder, but a port is declared as std_logic_vector.
Either change the port type in NBitBlockWithSkipAdder to std_logic, or use a range of one element in A in order to get a std_logic_vector with a single bit, like A(i downto i), thus making instantiations like:
f0 : NBitBlockWithSkipAdder port map (A(i downto i), B(i downto i), Cin, Sum(i downto i), Carry(i+1));

VHDL gate basics

I'm learning VHDL and I've come to a halt. I'd like to create a simple gate out of smaller gates (a NAND gate here). Here's the code:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity ANDGATE2 is
port(
x,y : in STD_LOGIC;
z : out STD_LOGIC
);
end ANDGATE2;
architecture ANDGATE2 of ANDGATE2 is
begin
z <= x AND y;
end ANDGATE2;
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity NOTGATE1 is
port(
x : in STD_LOGIC;
z : out STD_LOGIC
);
end NOTGATE1;
architecture NOTGATE1 of NOTGATE1 is
begin
z <= NOT x;
end NOTGATE1;
library ieee;
use ieee.std_logic_1164.all;
entity NANDGATE2 is
port(
x : in STD_LOGIC;
y : in STD_LOGIC;
z : out STD_LOGIC
);
end NANDGATE2;
architecture NANDGATE2 of NANDGATE2 is
signal c, d: std_logic;
component NOTGATE1
port(
n_in : in STD_LOGIC;
n_out : out STD_LOGIC
);
end component;
component ANDGATE2
port(
a_in1, a_in2 : in STD_LOGIC;
a_out : out STD_LOGIC
);
end component;
begin
N0: ANDGATE2
port map(x, y, c);
N1: NOTGATE1
port map(c, d);
z <= d;
end NANDGATE2;
Here's the code from some tutorial I've been using as a template; it compiles with no problems.
library ieee;
use ieee.std_logic_1164.all;
-- definition of a full adder
entity FULLADDER is
port
(
a, b, c: in std_logic;
sum, carry: out std_logic
);
end FULLADDER;
architecture fulladder_behav of FULLADDER is
begin
sum <= (a xor b) xor c ;
carry <= (a and b) or (c and (a xor b));
end fulladder_behav;
-- 4-bit adder
library ieee;
use ieee.std_logic_1164.all;
entity FOURBITADD is
port
(
a, b: in std_logic_vector(3 downto 0);
Cin : in std_logic;
sum: out std_logic_vector (3 downto 0);
Cout, V: out std_logic
);
end FOURBITADD;
architecture fouradder_structure of FOURBITADD is
signal c: std_logic_vector (4 downto 0);
component FULLADDER
port
(
a, b, c: in std_logic;
sum, carry: out std_logic
);
end component;
begin
FA0: FULLADDER
port map (a(0), b(0), Cin, sum(0), c(1));
FA1: FULLADDER
port map (a(1), b(1), C(1), sum(1), c(2));
FA2: FULLADDER
port map (a(2), b(2), C(2), sum(2), c(3));
FA3: FULLADDER
port map (a(3), b(3), C(3), sum(3), c(4));
V <= c(3) xor c(4);
Cout <= c(4);
end fouradder_structure;
My code compiles with no errors, but with two warnings:
# Warning: ELAB1_0026: p2.vhd : (85, 0): There is no default binding for component "andgate2".(Port "a_in1" is not on the entity).
# Warning: ELAB1_0026: p2.vhd : (87, 0): There is no default binding for component "notgate1".(Port "n_in" is not on the entity).
What gives?
You need to use the same port names on your component and entity declarations.
Right now, for example in your NOTGATE1 entity declaration, you have input port x and output port z, but in the NANDGATE2 architecture, you declare the NOTGATE1 component to have ports n_in and n_out.
This won't cause problems during compilation, since compilation looks at a single unit at a time, and won't see the actual entities. In the elaboration phase, your tools will try to match up the entities to components, but this will fail since the ports don't match.
Not 100% sure, but I think the pins in your component declarations need to match up to the ones in your entity blocks:
component NOTGATE1
port(
x : in STD_LOGIC;
z : out STD_LOGIC
);
end component;
component ANDGATE2
port(
x,y : in STD_LOGIC;
z : out STD_LOGIC
);
Always use explicit port bindings in your port maps, like
port map(a_in1 => x,
a_in2 => y,
a_out => c);
It will make your code also more clear. In big projects it is the first rule of thumb.

Resources