Sie sind auf Seite 1von 14

Author : http://www.teahlab.com/ --- Circuit : Full Adder --- Structure: --As shown in the interactive circuits on Teahlab.

com, -the Full Adder is made up of two Half Adders and a -OR Gate. We are going to build this VHDL Full Adder -based on that same structure. --1] First we will design a Half Adder entity -2] Second we will desgin a OR gate entity. -3] Third we will combine those two entities to form -a Full Adder. --- Note #1: --To build the Half Adder using structural design -techniques, we need a XOR Gate and a AND Gate. So -in the first portion of the design we will define a -XOR Gate and a AND Gate, and then use them to -design the Half Adder. --It is very important to learn structural design -(RTL) strategies because as your assignments become -larger and larger, knowledge of register transfer -level (RTL) design strategies become indispensable. -------------------------------------------------------------- Here we define the AND gate that we need for -- the Half Adder library ieee; use ieee.std_logic_1164.all; entity andGate is port( A, B : in std_logic; F : out std_logic); end andGate; architecture func of andGate is begin F <= A and B; end func; --*============================ -- Here we define the XOR gate that we need for -- the Half Adder library ieee; use ieee.std_logic_1164.all; entity xorGate is port( A, B : in std_logic; F : out std_logic); end xorGate; architecture func of xorGate is

begin F <= A xor B; end func; --*============================ -- At this point we construct the half adder -- using the AND and XOR gates library ieee; use ieee.std_logic_1164.all; entity halfAdder is port( A, B : in std_logic; sum, Cout : out std_logic); end halfAdder; architecture halfAdder of halfAdder is component andGate is -- import AND Gate port( A, B : in std_logic; F : out std_logic); end component; component xorGate is -- import XOR Gate port( A, B : in std_logic; F : out std_logic); end component; begin G1 : xorGate port map(A, B, sum); G2 : andGate port map(A, B, Cout); end halfAdder; --*======================*=================== END HALF ADDER -- Now we define the OR gate that we need for the Full Adder library ieee; use ieee.std_logic_1164.all; entity orGate is port( A, B : in std_logic; F : out std_logic); end orGate; architecture func of orGate is begin F <= A or B; end func; --*==============================* --*==============================* -- We are finally ready to build the Full Adder library ieee; use ieee.std_logic_1164.all; entity fullAdder is port( A, B, Cin : in std_logic; sum, Cout : out std_logic); end fullAdder;

-architecture fullAdder of fullAdder is component halfAdder is --import Half Adder entity port( A, B : in std_logic; sum, Cout : out std_logic); end component; component orGate is --import OR Gate entity port( A, B : in std_logic; F : out std_logic); end component; signal halfTohalf, halfToOr1, halfToOr2: std_logic; begin G1: halfAdder port map(A, B, halfTohalf, halfToOr1); G2: halfAdder port map(halfTohalf, Cin, sum, halfToOr2); G3: orGate port map(halfToOr1, halfToOr2, Cout); end fullAdder; ----------------------------------------------------------END ----------------------------------------------------------END

TEST BENCH
--TEST 1 A <= '0'; B <= '1'; wait for 10 ns; assert(sum = '0') report "sum error 1" severity error; assert(Cout = '1') report "Cout error 1" severity error; if(sum /= '1' or Cout /= '0') then errCnt := errCnt + 1; end if; --TEST 2 A <= '1'; B <= '1'; wait for 10 ns; assert(sum = '1') report "sum error 2" severity error; assert(Cout = '1') report "Cout error 2" severity error; if(sum /= '0' or Cout /= '1') then errCnt := errCnt + 1; end if; --TEST 3 A <= '1'; B <= '0'; wait for 10 ns; assert(sum = '0') report "sum error 3" severity error;

assert(Cout = '1') report "Cout error 3" severity error; if(sum /= '1' or Cout /= '0') then errCnt := errCnt + 1; end if; ---- SUMMARY ---if(errCnt = 0) then assert false report "Success!" severity note; else assert false report "Faillure!" severity note; end if; end process; end tb; ------------------------------------------------------------configuration cfg_tb of fullAdder_tb is for tb end for; end cfg_tb; ----------------------------------------------------------END ----------------------------------------------------------END

VHDL code for Full Adder using structural style


library IEEE; use IEEE.std_logic_1164.all; entity bejoy_fa is port(In1,In2,c_in : in std_logic; sum, c_out : out std_logic); end bejoy_fa; architecture arc of bejoy_fa is component half_adder port(a,b : in std_logic; sum, carry : out std_logic); end component; component or_2 port(a,b : in std_logic; c : out std_logic); end component; signal s1, s2, s3 : std_logic; begin H1: half_adder port map(a=>In1, b=>In2, sum=>s1, carry=>s3); H2: half_adder port map(a=>s1, b=>c_in, sum=>sum, carry=>s2); O1: or_2 port map(a=> s2, b=>s3, c=>c_out); end arc; entity half_adder is port (a,b : in bit ; sum,carry : out bit); end half_adder; architecture arc of half_adder is begin sum<= a xor b;

carry <= a and b; end arc; entity or_2 is port (a,b : in bit ; c : out bit); end or_2; architecture arc of or_2 is begin c<= a or b; end arc;

VHDL, or VHSIC (Very High Speed Integrated Circuits) Hardware Description Language, was developed by the Department of Defense in 1983 for describing hardware design from a software level. The basic building blocks of VHDL design are the ENTITY declaration and the ARCHITECTURE body. Note that comments in VHDL code can be inserted by adding -- comment here anywhere in the code. The comment will continue until the end of the line. There is no way to terminate a comment except an end-of-line. In the following code examples, we use the convention that UPPER CASE words are reserved words in VHDL, while lower case words are identifiers chosen by the programmer.

ENTITY
The ENTITY declaration describes only the input and output ports of the design. The highest level of any VHDL design is a single ENTITY declaration. For MAX+plus II to compile your project, the VHDL file name must be the same as the entity name. For instance, the following ENTITY declaration must be stored in the file counter_4.vhd. The internal relationship between the inputs and the outputs is not specified. At this stage, the entire design is treated as a "black box", with no knowledge of its internal workings. Signals that enter and leave this box must be declared in the PORT declaration.
ENTITY counter_4 IS PORT( clk, reset, load_counter: IN BIT; data: IN BIT_VECTOR( 3 DOWNTO 0 ); count_zero: OUT BIT; count: BUFFER BIT_VECTOR( 3 DOWNTO 0 ) ); END counter_4;

(Note that the last entry in the PORT declaration is not followed by a semicolon.) Each signal has a signal mode (IN, OUT, BUFFER) and a signal type (BIT, BIT_VECTOR). The signal mode determines how the entity will read and write to each signal. There are four different signal modes:

IN: Data flows in to the entity, and the entity cannot write to these signals. The IN mode is used for clock inputs, control inputs, and unidirectional data inputs. OUT: Data flows out of the entity, and the entity cannot read these signals. The OUT mode is only used when the signal is not used in any way by the entity. BUFFER: Data flows out of the entity, but the entity can read the signal (allowing for internal feedback). However, the signal cannot be driven from outside the entity, so it cannot be used for data input.

INOUT: Data can flow both in and out of the entity, and the signal can be driven from outside the entity. This mode should be used only when necessary (for instance, a bidirectional data bus). Otherwise, error checking of the design is reduced, and the code becomes more difficult to understand. You should not use mode INOUT in your designs for this class.

The signal type must also be declared in the PORT declaration. Signal type describes the possible values the signal can take, and can describe a vector of similar signal types. The simplest signal types are the BIT and BIT_VECTOR types. The only allowed values for the BIT type are '0' and '1'. (Note that single bit values are assigned values by using single quotes:
bit_signal <= '0';

The BIT and BIT_VECTOR types are intrinsic to the VHDL language, and so they require no library declarations (see the description for std_logic below). The BIT_VECTOR type must be declared with a value for the vector range. For this type, it is declared as
bit_vector_signal : BIT_VECTOR( maximum_index DOWNTO 0 );

and makes a vector with maximum_index+1 elements. These elements can be individually referenced in the architecture body as signal_vector_name( index_value ) where index_value must be between 0 and maximum_index. For instance:
bit_vector_signal(0) <= bit_signal;

assigns the value of bit_signal to the first element (index 0) of the bit vector bit_vector_signal . An entire bit vector can be assigned a value by using double quotes:
bit_vector_signal <= "0001"; This statement assigns '1' to bit_vector_signal(0)

, and '0' to the other three bit

values in this vector. The std_logic and std_logic_vector types are part of the ieee library, and can have the values '0', '1', '-' (don't care), 'Z' (high impedance), or 'X' (indeterminate). The additional values allow more detailed simulations to be performed, and allow the layout editor to optimize logic in the case of assignments to the "don't care" value. To use these types, you must add LIBRARY and USE statements before your entity declaration:
LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY counter_4 IS PORT( clock, reset, load_counter: data: reset_alert: count: ); END counter_4; IN std_logic; IN std_logic_vector( 3 DOWNTO 0 ); OUT std_logic; BUFFER std_logic_vector( 3 DOWNTO 0 )

It is important not to mix BIT and std_logic types in your code. The two types must be converted using resolution functions ("To_bit", "To_bitvector", "To_StdULogic", "To_StdULogicvector") before assigning std_logic signals to bits and vice versa. These functions will considerably complicate your code. In your design, use exclusively BIT and BIT_VECTOR types, or exclusively std_logic and std_logic_vector types. The remainder of this discussion will use only BIT and BIT_VECTOR types.

ARCHITECTURE
The functional relationships between the IN signals and the OUT signals (and the BUFFER signals) are specified in the ARCHITECTURE body. While you can write several different architectures for one entity, only one may appear in your finished VHDL code.
ENTITY full_adder IS PORT ( a, b, carry_in : IN BIT; sum, carry_out: OUT BIT ); END full_adder; ARCHITECTURE architecture_name OF full_adder IS -- List of internal signals here -- List of components here BEGIN --- Architecture statements here -END architecture_name;

There are three styles of ARCHITECTURE statements. You can mix several styles in your design, but you should be aware of the different statement types in each style, since some cannot be interchanged between two styles.

Dataflow Descriptions: In this style, all assignments occur simultaneously in the design, and generally describe the flow of data from the inputs to the outputs. Signals are assigned values by using the assignment operator "<=".
ARCHITECTURE dataflow OF full_adder IS SIGNAL x1, x2, x3, x4, y1 : BIT; BEGIN x1 <= a AND b; x2 <= a AND carry_in; x3 <= b AND carry_in; x4 <= x1 OR x2; carry_out <= x3 OR x4; y1 <= a XOR b; sum <= y1 XOR carry_in; END dataflow;

We could easily eliminate the need for additional signals by consolidating the logical equations:
ARCHITECTURE dataflow OF full_adder IS BEGIN carry_out <= ( a AND b ) OR ( a AND carry_in ) OR ( b AND carry_in ); sum <= a XOR b XOR carry_in; END dataflow;

The layout editor will determine what signal wires might be necessary to implement the design. In a dataflow architecture, signal assignments can be written with logical equations (as above) or with two types of conditional expressions:
output_vector <= != c "00" WHEN ( a = b ) ELSE "01" WHEN ( a = c ) -- and a != b ELSE "10" WHEN ( a = d ) -- and a != b and a

ELSE "11"; WITH selecting_vector SELECT output_vector <= "0001" "0010" "0100" "1000"

WHEN WHEN WHEN WHEN

"00", "01", "10", "11";

Structural Descriptions: In this style, all assignments are performed by mapping signals to components defined before the architecture body.
ENTITY full_adder IS PORT ( a, b, carry_in : IN BIT; sum, carry_out : OUT BIT ); END full_adder; ARCHITECTURE structural OF full_adder IS SIGNAL x1, x2, x3, x4, y1 : BIT; COMPONENT and_gate PORT ( a, b : IN BIT; a_and_b : OUT BIT ); END COMPONENT and_gate; COMPONENT or_gate PORT ( a, b : IN BIT; a_or_b : OUT BIT ); END COMPONENT or_gate; COMPONENT xor_gate PORT (

a, b : IN BIT; a_xor_b : OUT BIT ); END COMPONENT xor_gate; BEGIN and0 : and_gate PORT MAP( a, b, x1 ); and1 : and_gate PORT MAP( a, carry_in, x2 ); and2 : and_gate PORT MAP( b, carry_in, x3 ); or0: or_gate PORT MAP( x1, x2, x4 ); or1: or_gate PORT MAP( x3, x4, carry_out ); xor0: xor_gate PORT MAP( a, b, y1 ); xor1: xor_gate PORT MAP( y1, carry_in, sum ); END structural;

This type of description can get very long, and is generally applied when a library of complex components is already available. Note that except for the substitution of components for logical statements, it is identical to the dataflow description, and all assignments occur simultaneously. Note: the COMPONENT syntax used in the textbook is outdated and will not compile! Use the syntax in the example here, or in the ripple carry adder example below.

Behavioral Descriptions: This style is the most complex, but it allows for the conversion of sequential algorithms to VHDL code. The process statement is the essential part of a behavioral description. It is composed of a label (optional), the word PROCESS, and a sensitivity list. This is a list of signals which activate the process every time one of their values change.
process_name: PROCESS( sensitivity_list_signal_1, ... ) BEGIN -- process statements here END PROCESS process_name;

The most common use of behavioral descriptions is in a state machine, where a device has an internal memory that determines the device's output. A clock input determines the times at which the device's internal state changes. This is generally on the rising edge of the clock, during its transition from '0' to '1'. For instance, a simple four-bit counter is a state machine with 16 internal states (the 16 possible values of the count signal). This design is presented in counter_4.vhd and below:
ENTITY counter_4 IS PORT( clock, reset, load_counter: IN BIT;

data: reset_alert: count: ); END counter_4;

IN BIT_VECTOR( 3 DOWNTO 0 ); OUT BIT; BUFFER BIT_VECTOR( 3 DOWNTO 0 )

ARCHITECTURE behavioral OF counter_4 IS BEGIN upcount: PROCESS( clock ) BEGIN IF( clock'event AND clock= '1' ) THEN IF reset = '1' THEN count <= "0000"; ELSIF load_counter = '1' THEN count <= data; ELSE count(0) <= NOT count(0); count(1) <= count(0) XOR count(1); count(2) <= ( count(0) AND count(1) ) XOR count(2); count(3) <= ( count(0) AND count(1) AND count(2) ) XOR count(3); IF count = "0000" THEN reset_alert <= '1'; ELSE reset_alert <= '0'; END IF; -- IF count = "0000" END IF; -- IF load = '1' END IF; -- IF( clock'event AND clock = '1' ) END PROCESS upcount; END behavioral;

The rising clock edge is determined by the presence of clock in the process sensitivity list, then by the statement
IF( clock'event AND clock= '1' )

The clock event test is added to prevent the statements from being performed on any brief error in the clock signal. In addition to IF-THEN-ELSIF-ELSE statements, a behavioral description can include CASE-WHEN statements to simplify writing the code.
CASE selecting_vector IS WHEN "0001" => output_vector WHEN "0010" => output_vector WHEN "0100" => output_vector WHEN "1000" => output_vector WHEN OTHERS => output_vector END CASE; <= <= <= <= <= "000"; "001"; "010"; "011"; "100";

Other Data Objects


To simplify your coding, you can define data objects other than signals.

Constants: A constant holds a value which you may use at several points within the code, and may want to change throughout the code without searching for every instance.
CONSTANT target_value: BIT_VECTOR( 3 DOWNTO 0 ) := "0101";

Aliases: An alias is an alternative identifier for an existing object or part of an existing object. It may be useful if you have a very large vector, but generally reference only certain groups of bits.
SIGNAL address: BIT_VECTOR( 31 ALIAS top_address: BIT_VECTOR( DOWNTO 28 ); ALIAS memory_bank: BIT_VECTOR( DOWNTO 24 ); ALIAS row_address: BIT_VECTOR( DOWNTO 12 ); DOWNTO 0 ); 3 DOWNTO 0 ) IS address( 31 3 DOWNTO 0 ) IS address( 27 11 DOWNTO 0 ) IS address( 23

FULL ADDER AIM: To design, implement and analyze all the three models for full adder. Design: First, VHDL code for half adder was written and block was generated. Half adder block as component and basic gates, code for full adder is written. The truth tables are as follows:
HALF ADDER

--Structural model for Half Adder library IEEE;use IEEE.STD_LOGIC_1164.all;entity HA isport(A,B:in STD_LOGIC; Sum, Carry:out STD_LOGIC);end HA;architecture struct of HA iscomponent myXORport(in1,in2:in STD_LOGIC; out1:out STD_LOGIC);end component;beginX1: myXOR port map(A,B,Sum);Carry<=A and B;end struct; --Structural model for Full Adder library IEEE;use IEEE.STD_LOGIC_1164.all;entity FA isport(x,y,cin:in std_logic; s, cout:out std_logic);end FA;architecture struct of FA issignal s1,c1,c2 :std_logic;component HAport(A,B:in STD_LOGIC; sum, Carry:out STD_LOGIC);end component;beginHA1: HA port map(x,y, s1,c1);HA2: HA port map(s1,cin, s,c2);cout<=c1 or c2;end struct;

Das könnte Ihnen auch gefallen