linking an output from on entity to the input of another entity - vhdl

I am trying to connect the output of an entity to the input of another entity.
Eventually connect a third entity will be connected,but i want to understand the process of connecting two entity's together.
Do I use a port map? If I do, are they added to both architectures of the different entity's to link them?
I know it wont be as simple as below:
link: transmitter port map (output_e1=>input_e2);
I have tried this but an error returns using ModelSim pointing at components declarations!
update:
ENTITY transmitter is
port(
transmission : out STD_LOGIC_VECTOR (31 downto 0)
);
end transmitter;
architecture Behavioral of transmitter is
end Behavioral;
Entity receiver is
PORT(
rxi:in signed (7 downto 0)
end receiver;
architecture Behavioral of receiver is
end Behavioral;
The above code does not include all the instructions and commands. My program works, but i have two entity and wish to link them as they would be in a communications system.

See the following example, a full adder circuit done using two half adders. You can see how the first half adder output is connected as the input of 2nd half adder.
--top module(full adder) entity declaration
entity fulladder is
port (a : in std_logic;
b : in std_logic;
cin : in std_logic;
sum : out std_logic;
carry : out std_logic
);
end fulladder;
--top module architecture declaration.
architecture behavior of fulladder is
--sub-module(half adder) is declared as a component before the keyword "begin".
component halfadder
port(
a : in std_logic;
b : in std_logic;
sum : out std_logic;
carry : out std_logic
);
end component;
--All the signals are declared here,which are not a part of the top module.
--These are temporary signals like 'wire' in Verilog.
signal s1,c1,c2 : std_logic:='0';
begin
--instantiate and do port map for the first half adder.
HA1 : halfadder port map (
a => a,
b => b,
sum => s1,
carry => c1
);
--instantiate and do port map for the second half adder.
HA2 : halfadder port map (
a => s1,
b => cin,
sum => sum,
carry => c2
);
carry <= c1 or c2; --final carry calculation
end;
See this link for explanation.

Related

node instance instantiates undefined entity error

please I need some help with my VHDL code. I am trying to design a Full adder circuit with 2 half adders. I’m using Max Plus II for my design. I have tried compiling but I keep getting errors(node instance instantiates undefined entity). Please I would appreciate any help I can get. Also, I'm very new to VHDL. Kind regards.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity full_adder is
Port ( a : in STD_LOGIC;
b : in STD_LOGIC;
cin : in STD_LOGIC;
sum : out STD_LOGIC;
cout : out STD_LOGIC);
end full_adder;
architecture Behavioral of full_adder is
component half_adder is
Port ( a : in STD_LOGIC;
b : in STD_LOGIC;
sum : out STD_LOGIC;
cout : out STD_LOGIC);
end component;
signal s1, s2 : STD_LOGIC;
signal c1, c2 : STD_LOGIC;
begin
HA1: half_adder port map (a => a, b => b, sum => s1, cout => c1);
HA2: half_adder port map (a => s1, b => cin, sum => s2, cout => c2);
sum <= s2;
cout <= c1 OR c2;
end Behavioral;
I expect to design a full adder using 2 half adders and an OR gate. I would also like to view the Wave simulation.
Though you have a component statement which defines the interface of your half_adder block, you will need an equivalent entity statement (usually found in its own file) to actually define its inner workings.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity half_adder is
Port ( a : in STD_LOGIC;
b : in STD_LOGIC;
sum : out STD_LOGIC;
cout : out STD_LOGIC);
end half_adder;
architecture dataflow of half_adder is
begin
cout <= a and b;
sum <= a xor b;
end dataflow;
The component statement tells your compiler to look for a module that matches a specific description; the entity statement actually defines the workings of the module itself.

How to reuse an entity to work with different components

I'm reasonably new to vhdl and wondering what the best way is to manage the following situation / pattern:
Say I have an entity A whose architecture instantiates a component B. I would then like to reuse A but this time instantiate a component C in the place of B. C has a completely different functionality to B. B and C may have different sized ports, however the functionality of A is such that it can handle the different port sizes, using, say, generics and generate statements. Essentially A is like a container for either component B, C or maybe D, E, F etc. It maybe performs some logic/buffering on the inputs and outputs of B, C etc. in a way that is common for all these components.
I have read about configurations and my understanding is that I can instantiate a component in A (call it Z), and then link it's entity to different architectures using configurations. It seems not many people use this feature of vhdl.
Are configurations the right way to go for this situation?
Ideally, I would like all of the parameters in the design to depend ultimately on the architecture chosen for Z so that the architecture dictates the port sizes of the entity its linked to (Z), and in turn the port sizes of Z dictate the parameters of A and finally these parameters dictate the port sizes of A. Is this possible?
(I am using 'parameterisation' in the general sense to mean a way of configuring a design. Generics, packages, 'range attributes etc would all be examples of parameterisation)
A pseudocode example of what I mean is below. The values in capitals should depend on the architecture chosen for Z.
entity A is
port
(
clk : in std_logic;
reset : in std_logic;
inputs : in std_logic_vector(SOME_WIDTH_A_IN - 1 downto 0);
outputs : out std_logic_vector(SOME_WIDTH_A_OUT - 1 downto 0);
);
end A;
architecture A_arch of A is
component Z
port
(
clock : in std_logic;
inputs : std_logic_vector(SOME_WIDTH_Z_IN - 1 downto 0);
ouputs : std_logic_vector(SOME_WIDTH_Z_OUT - 1 downto 0)
);
end component;
begin
for i in 1 to SOME_VALUE generate
-- whatever logic/buffering we want to perform on the inputs
end generate;
for i in 1 to SOME_VALUE generate
-- whatever logic/buffering we want to perform on the outputs
end generate;
instance: Z
port map(
clock => clk,
inputs => --output of logic/buffering above
outputs => -- input of logic/buffering above
);
end A_arch;
I may be thinking about this the wrong way - Essentially I would like to avoid having to copy/paste the 'container' entity A to work with different components B, C etc. What is the best way to do this?
It seems that you want your components B,C,D, etc... to do exactly the same except for different port sizes. The best approach to do this is with GENERIC. Let's say your other entity (let's call it INNER_ENTITY) is configurable n-bit wide double flip flop (can be used to resolve metastability).
Here is the example code for OUTER_ENTITY and INNER_ENTITY:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity OUTER_ENTITY is
port (
CLK : in std_logic;
RST : in std_logic;
PORT_A : in std_logic_vector(6 downto 0);
PORT_B : in std_logic_vector(13 downto 0);
SUM_A_B : out std_logic_vector(13 downto 0)
);
end entity;
architecture RTL_OUTER_ENTITY of OUTER_ENTITY is
signal PORT_A_INNER : std_logic_vector(6 downto 0);
signal PORT_B_INNER : std_logic_vector(13 downto 0);
component INNER_ENTITY
generic (PORT_SIZE : integer);
port (
CLK : in std_logic;
RST : in std_logic;
PORT_IN : in std_logic_vector(PORT_SIZE - 1 downto 0);
PORT_OUT : out std_logic_vector(PORT_SIZE - 1 downto 0);
);
end component INNER_ENTITY;
begin
SUM_A_B <= PORT_A_INNER + PORT_B_INNER;
INNER_7_BIT : INNER_ENTITY
generic map (PORT_SIZE => 7)
port map (
CLK => CLK,
RST => RST,
PORT_IN => PORT_A,
PORT_OUT => PORT_A_INNER
);
INNER_14_BIT : INNER_ENTITY
generic map (PORT_SIZE => 14)
port map (
CLK => CLK,
RST => RST,
PORT_IN => PORT_B,
PORT_OUT => PORT_B_INNER
);
end RTL_OUTER_ENTITY;
entity INNER_ENTITY
generic (PORT_SIZE : integer);
port (
CLK : in std_logic;
RST : in std_logic;
PORT_IN : in std_logic_vector(PORT_SIZE - 1 downto 0);
PORT_OUT : out std_logic_vector(PORT_SIZE - 1 downto 0);
);
end entity;
architecture RTL_INNER_ENTITY of INNER_ENTITY is
signal PORT_X : std_logic_vector(PORT_SIZE - 1 downto 0);
begin
process(CLK, RST)
begin
if RST = '1' then
PORT_OUT <= (OTHERS => '0');
PORT_X <= (OTHERS => '0');
elsif rising_edge(CLK) then
PORT_OUT <= PORT_X;
PORT_X <= PORT_IN;
end if;
end process;
end RTL_INNER_ENTITY;
Please note that I did not compile this code so it might have some minor syntax errors but it should give you an overview to how GENERICs might be used to do what you want.

how to get a T flip flop simulation waveform using Xilinx ISE design suite

I tried to simulate a TFF using Xilinx ISE web pack and ModelSim using following block diagram and structural Code was written using VHDL. But I am unable to get the correct waveform. Due to the T-flip flop is sequential circuit, first I gave the output value as 1 or 0 for one output (Q) to start to the process.
T flip flop truth table and block diagram
simulation waveform
code for AND gate:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity AND_GATE is
Port ( X : in STD_LOGIC;
Y : in STD_LOGIC;
W : in STD_LOGIC;
Z : out STD_LOGIC);
end AND_GATE;
architecture Behavioral of AND_GATE is
begin
Z <= X AND Y AND W;
end Behavioral;
code for NOR gate:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity NOR_GATE is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
C : out STD_LOGIC);
end NOR_GATE;
architecture Behavioral of NOR_GATE is
begin
c <= A NOR B;
end Behavioral;
code for T-FF:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity TFF_2 is
Port ( T : in STD_LOGIC;
CLK : in STD_LOGIC;
Q : inout STD_LOGIC;
s : inout STD_LOGIC);
end TFF_2;
architecture STRUCTURAL of TFF_2 is
--declare components being used in T -FF
component TFF is
Port ( T : in STD_LOGIC;
CLK : in STD_LOGIC;
RST : in STD_LOGIC;
Q : out STD_LOGIC);
end component;
component NOR_GATE is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
C : out STD_LOGIC);
end component;
component AND_GATE is
Port ( X : in STD_LOGIC;
Y : in STD_LOGIC;
W : in STD_LOGIC;
Z : out STD_LOGIC);
end component;
--declare signals
signal S1, S2 : STD_LOGIC;
begin
C1 : AND_GATE port map (Q, T, CLK, S1);
C2 : AND_GATE port map (S, T, CLK, S2);
C3 : NOR_GATE port map (S1, S, Q);
C4 : NOR_GATE port map (S2, Q, S);
end STRUCTURAL;
These files synthesized without any errors but in the simulation expected output was not given.
There are a few suggestions I have.
There are non initialised variables. Add := '0'; at the end of the declarations. Simulation might show "X" or unknown. The Synthesised design will work OK, being the hardware will go to one or zero, but simulators need to be directed.
Some of your output variables have feedback into inputs. The design is asynchronous, being that you are not using a clock of some description to time the iterations. Consider using a process and something like if rising_edge(clk)

4 Bit Adder using port maps

So I am trying to do a 4 bit adder and have ran into an error I can't seem to figure out.
Error (10430): VHDL Primary Unit Declaration error at adder1.vhd(3): primary unit "Adder1Vhd" already exists in library "work"
I have a project called 4 bit adder and inside that project folder is the .vhd file for Adder1.vhd. Here is the codes I have, if somebody could help me figure this out it would be greatly appreciated.
Adder4.vhd:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY Adder4 IS
GENERIC(CONSTANT N: INTEGER := 4);
PORT(
a, b: IN STD_LOGIC_VECTOR(N-1 DOWNTO 0); -- Input SW[7..4]: a[3..0] inputs,
-- SW[3..0]: b[3..0]
cIn: in std_logic;
sum: OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0); -- Output LEDR[3..0]
cOut: OUT STD_LOGIC -- Output LEDR[4]
);
END Adder4;
ARCHITECTURE imp OF Adder4 IS
COMPONENT Adder1
PORT(
a, b, cIn : in STD_LOGIC;
sum, cOut : out STD_LOGIC);
END COMPONENT;
SIGNAL carry_sig: std_logic_vector(N-1 DOWNTO 0);
BEGIN
A1: Adder1 port map (a(0), b(0), cIn, sum(0), carry_sig(0));
A2: Adder1 port map (a(1), b(1), carry_sig(0), sum(1), carry_sig(1));
A3: Adder1 port map (a(2), b(2), carry_sig(1), sum(2), carry_sig(2));
A4: Adder1 port map (a(3), b(3), carry_sig(2), sum(3), cOut);
END imp;
Adder1.vhd(the file inside the Adder4 project folder):
library ieee;
use ieee.std_logic_1164.all;
entity Adder1Vhd is
port(
a, b, cIn : in std_logic;
sum, cOut : out std_logic);
end Adder1Vhd;
architecture imp of Adder1Vhd is
begin
-- Add two lines (one for sum and the other for cOut) of VHDL code here
sum <= (a xor b) xor cIn;
cOut <= (a and b) or (cIn and (a xor b));
end imp;
There is another file that has an entity named Adder1Vhd in the library work (current work library). You can either delete the file on disk or just remove it from the library work in the file navigator of Quartus II.
By the way, it's a good convention to save a VHDL files using the same name as the entity.
And the name of a component must be the name of it's entity, not the filename. So,
COMPONENT Adder1 -- here 'Adder1' should be 'Adder1Vhd'
PORT(
a, b, cIn : in STD_LOGIC;
sum, cOut : out STD_LOGIC);
END COMPONENT;
Component instantiation statements are the same.

Implementing an Accumulator in VHDL

I am trying to implement a signed accumulator using Core Gen in Xilinx. According to my understanding an accumulator performs the function of a normal register which is just routing the input to the output, but I wanted clarification on that.
I added the Accumulator IPcore (.xco) module to the project and I have a main file which basically contains the component declaration and the port map. I have a single step process too. Everything compiles and I can see the result on the board but don't quite understand what's going on...
When I input 1000 the 8 bit output on the LEDs is 11111000. Another input of 1111 gives me 11110111. I am attaching the code here for the main vhd file called Accm and the .vho file.
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity Accm is
port( b: in std_logic_vector(3 downto 0);
sclr, clk, b1, b2 : in std_logic;
q : out std_logic_vector(7 downto 0)
);
end Accm;
architecture Behavioral of Accm is
-- signal declaration
type tell is (rdy,pulse,not_rdy);
signal d_n_s: tell;
signal en: std_logic;
-- component declaration
COMPONENT my_accm
PORT (
b : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
clk : IN STD_LOGIC;
sclr : IN STD_LOGIC;
q : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
-- port map
begin
A1 : my_accm
PORT MAP (
b => b,
clk => en,
sclr => sclr,
q => q
);
process(clk)
begin
if clk'event and clk='1' then
case d_n_s is
when rdy => en <= '0';
if b1='1' then d_n_s <= pulse; end if;
when pulse => en <= '1';
d_n_s <= not_rdy;
when not_rdy => en <='0';
if b2='1' then d_n_s <= rdy; end if;
end case;
end if;
end process;
-- .VHO CODE
------------- Begin Cut here for COMPONENT Declaration ------ COMP_TAG
COMPONENT my_accm
PORT (
b : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
clk : IN STD_LOGIC;
sclr : IN STD_LOGIC;
q : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
-- COMP_TAG_END ------ End COMPONENT Declaration ------------
-- The following code must appear in the VHDL architecture
-- body. Substitute your own instance name and net names.
------------- Begin Cut here for INSTANTIATION Template ----- INST_TAG
your_instance_name : my_accm
PORT MAP (
b => b,
clk => clk,
sclr => sclr,
q => q
);
end Behavioral;
I am also pasting an image of the accumualtor I generated in CoreGen.
I'D appreciate it if someone could explain me what is going on in this program. Thanks!
"Accumulator" can mean many things. In the hardware Xilinx library, the component you instantiated is an adder in front of a register. The adder is adding the current value of the accumulator register with the input term. The accumulator register is wider than the input so you can accumulate (add together) many input terms without overflowing the output.
When your circuit starts, the accumulator contains zero. You input 1000 (-8) which when added to zero becomes 11111000 (-8 sign extended) on the output. You then add 1111 (-1), and the output becomes 11110111 (-9 sign extended).
Once you are done "accumulating", assert SCLR to clear the accumulator register back to zero (or use SSET or SINIT, as appropriate for your logic).
This should all be covered by the documentation for the Xilinx library (try clicking the "datasheet" button in the corgen dialog).
Actually, I think I get it now. It's just acting like an Adder with signed inputs. I think I am correct on this but would appreciate any clarification!

Resources