VHDL Codes for Useful Components |
Throughout the duration of courses like ee480 and ee 552, we have come across several useful basic components that will contribute to ensuring the success of a bigger implemtation of components. Listed below are the complete VHDL codes for several of the unit components that we think may prove useful to future students to be used either as template or as a reference.
There are VHDL codes provided for the following implementations:
(i) Full Adder
(ii) N-bit Ripple Carry Adder
(iii) N bit Register (D flip-flop)
(iv) N -bit Multiplexer
(v) Zero detector
(vi) Shift Register
A Full Adder |
A full adder consists of 3 inputs and 2 outputs. Adders are used to perform the addition of bits in the computer. See Figure 1 for a complete schematic diagram of a full adder is illustrated below.
Figure 1: Schemaric of a Full Adder
An example of the VHDL code for a full adder is shown below:
library ieee;
use ieee.std_logic_1164.all;
entity Full_Adder is
port ( X, Y, Cin: in BIT;
Cout, Sum: out BIT);
end Full_Adder;
architecture structural of Full_Adder is
begin
Sum <= X xor Y xor Cin ;
Cout <= (X and Y) or (X and Cin) or (Y and Cin);
end structural;
A Ripple Carry Adder |
The ripple carry adder decomposes addition into bit-wise operations.
See Figure 2 for more details.
Advantages : Simple, interative unidirectional structure
Disadvantages : Delay grows in proportion with the number of bits
Figure 2: Schmatic of a Ripple Carry Adder
The code below is a simple implementation of the ripple carry adder using a cascade of simple full adders. Note that the component full adder is included in the coding below i.e the code for the full adder must be in the same directory as the ripple carry adder VHDL code.
library ieee;
use ieee.std_logic_1164.all;
entity Adder is
generic ( num_bits : positive := n )
port ( A, B: in BIT_VECTOR(num_bits-1 downto 0);
Cin: in BIT; Cout: out BIT;
Sum: out BIT_VECTOR(num_bits-1 downto 0));
end Adder;
architecture Structure of Adder is
component Full_Adder
port ( X, Y, Cin: in BIT;
Cout, Sum: out BIT);
end component;
signal C: BIT_VECTOR(num_bits-1 downto 0);
begin
Stages: for index in num_bits-1 downto 0 generate
LowBit : if index = 0 generate
FA:Full_Adder port map (A(0),B(0),Cin,C(0),Sum(0));
end generate;
OtherBits : if index /= 0 generate
FA:Full_Adder port map (A(i),B(i),C(i-1),C(i),Sum(i));
end generate;
end generate;
Cout <= C(num_bits-1);
end;
A Register |
D flip-flops are often used as components to build registers.
Registers can either have synchonous / asynchronous resets.
Note
1. Synchronous resets are resets that are dependent on the clock. That meanse they are held synchronized with the clock. Assuming that the system is triggered at the rising edge of the clock, the reset will only take place when there is a chage in the clock from '0' to '1'.2. Asynchronous reset are are independent of the clock edges. The reset will take place whether or not the clock is at a '1' or '0'.
Figure 3 shows a schematic that clearly depicts
the inputs and outputs of the flip flop.
Figure 3: D Flip-flop
An example of the VHDL code for a positive edge triggered D flip-flop with asynchronous reset shown below:
library ieee;
use ieee.std_logic_1164.all;
entity DFFClr is
port (CLR, CLK, D : in BIT; Q, QB : out BIT);
end;
architecture Behave of DFFClr is
signal Qi : BIT;
begin QB <= not Qi; Q <= Qi;
process (CLR, CLK) begin
if CLR = '1' then
Qi <= '0' ;
elsif CLK'EVENT and CLK = '1'
then Qi <= D;
end if;
end process;
end;
With the use of the D flip-flop as a component, we can create a register. The register schematic is depicted below (Figure 4).
Figure 4: Register using a D-Dlip Flop
The VHDL code for an N bit 1-input 1-output register is built below:
library ieee;
use ieee.std_logic_1164.all;
entity Register is
generic (num_bit : positive := N )
port ( D : in BIT_VECTOR(num_bit-1 downto 0);
Clk, Clr: in BIT ;
Q : out BIT_VECTOR(num_bit-1 downto 0));
end Register;
architecture structural of Register is
component DFFClr
port (Clr, Clk, D : in BIT; Q, QB : out BIT);
end component;
begin
STAGES : for index in num_bit-1 downto 0 generate
FF: DFFClr port map (Clr, Clk, D(i), Q(i), open);
end generate;
end structural;
An N-bit multiplexer |
A multiplexer uses a select key(s) to choose the output(s) desired. In this exanple, we will build multiplexer where n= 2. Therefore, the select only contains either a '0' or a '1'. Modifications can be performed on the program to expand the number of bits. Figure 5 shows the 2-bit multiplexer below.
Figure 5: A 2-bit Multiplexer
The VHDL code for an N-bit multiplexer
library ieee;
use ieee.std_logic_1164.all;
entity NMux is
generic (Mux_width : positive := N)
port (A, B : in BIT_VECTOR (Mux_width-1 downto 0);
Sel : in BIT := '0';
Y : out BIT_VECTOR (Mux_width-1 downto 0));
end;
architecture Behave of NMux is
begin
Y <= A when Sel = '1' else B ;
end;
Zero Detector |
A zero detector accepts a bus of any width and will produce a single-bit output of '1' if all input bits are zero. A schematic of the zero detector is shown in Figure 6:
Figure 6: A Zero Detector
The VHDL code for a zero detector is as shown :
library ieee;
use ieee.std_logic_1164.all;
entity AllZero is
port ( X : BIT_VECTOR;
F : out BIT );
end;
architecture behavioral of AllZero is
begin
process (X)
begin
F <= '1' ;
for index in X'RANGE loop
if X(j) = '1' then
F <= '0';
end if;
end loop;
end process;
end behavioral;
A Shift Register |
A variable-width shift register that shifts (left or right under input control, DIR ) on the positive edge of the clock, CLK , gated by a shift enable, SH . The parallel load, LD , is synchronous and aligns the input LSB to the LSB of the output, filling unused MSBs with zero. Bits vacated during shifts are zero filled. The clear, CLR is asynchronous. A complete diagram of the shift register as shown in Figure 7.
The VHDL code for the shift register is as illustrated.
library ieee;
use ieee.std_logic_1164.all;
entity ShiftN is
port( CLK, CLR, LD, SH, DIR: in BIT;
D: in BIT_VECTOR;
Q: out BIT_VECTOR );
begin assert (D'LENGTH <= Q'LENGTH)
report "D wider than output Q" severity Failure;
end ShiftN;
architecture behavioral of ShiftN is
begin
Shift: process (CLR, CLK)
subtype InB is NATURAL range D'LENGTH-1 downto 0;
subtype OutB is NATURAL range Q'LENGTH-1 downto 0;
variable St: BIT_VECTOR(OutB);
begin
if CLR = '1' then
St := (others => '0'); Q <= St ;
elsif CLK'EVENT and CLK='1' then
if LD = '1' then
St := (others => '0');
St(InB) := D;
Q <= St;
elsif SH = '1' then
case DIR is
when '0' => St := '0' & St(St'LEFT downto 1);
when '1' => St := St(St'LEFT-1 downto 0) & '0';
end case;
Q <= St ;
end if;
end if;
end process;
end behavioral;
References |
Texts:
1. EE 480 Lecture NotesWebsites:1. http://www.giscafe.com
2. http://techweb.com
Last updated: October 19, 1999