Guide to VHDL for embedded software developers: Part 3 - ALU logic & FSMs

Peter Wilson

July 25, 2011

Peter Wilson

Structural n-bit addition
Using the simple 1-bit full adder defined previously, it is a simple matter to create a multiple bit full adder using this model as a building block. As an example, to create a 4 bit adder, with a single carry-in and single bit carry-out, we can define a VHDL model as shown below:

entity four_bit_adder is
   port (sum: out bit_vector (3 downto 0); co : out bit;
        a, b : in bit_vector (3 downto 0); ci : in bit);
end entity four_bit_adder;

architecture simple of four_bit_adder is
   signal carry : bit_vector (3 downto 1);
begin
   fa0 : entity work.full_adder
       port map (sum(0),carry(1),a(0),b(0),ci);
   fa1 : entity work.full_adder
       port map (sum(1),carry(2),a(1),b(1),carry(1));
   fa2 : entity work.full_adder
       port map (sum(2),carry(3),a(2),b(2),carry(2));
   fa3 : entity work.full_adder
       port map (sum(3),co,a(3),b(3),carry(3));
end architecture simple;

This can obviously be extended to multiple bits by repeating the component use in the architecture for as many bits are required.

Configurable n-bit addition
While the structural approach is useful, it is clearly cumbersome and difficult to configure easily. A more sensible approach is to add a generic (parameter) to the model to enable the number of bits to be customised. For example, if we define an entity to add two logic vectors (as opposed to bit vectors used previously), the entity will look something like this:

library IEEE;
use IEEE.std_logic_1164.all;

entity add_beh is
  generic(top : natural := 15);
    port (a :in_std_logic_vector (top downto 0);
          b : in std_logic_vector (top downto 0);
          cin : in std_logic;
          sum : out std_logic_vector (top downto 0);
          cout : out std_logic);
end entity add_beh;

As can be seen from this entity, we have a new parameter, top, which defines the size of the input vectors (a and b) and the output sum (cout). We can then use the same original logic equations that we defined for the initial 1-bit adder and use more behavioural VHDL to create a much more readable model:

architecture behavior of add_beh is
begin
  adder: process(a,b,cin)
           variable carry : std_logic;
           variable tempsum : std_logic_vector(top
           downto 0);
         begin
           carry := cin;
           for i in 0 to top loop
               tempsum(i) := a(i) xor b(i) xor carry;
               carry := (a(i) and b(i))
                        or (a(i) and carry)
                        or (b(i) and carry);
         end loop;
      sum <= tempsum;
      cout <= carry;
   end process adder;
end architecture behavior;

This architecture shows how a single process (with sensitivity list a, b, cin) is used to encapsulate the addition. The process is activated when a, b or cin changes.

A for loop is used to calculated a temporary sum (tempsum) that increments each time around the loop if required and the final value is assigned to the output sum. Also, a stage by stage carry is calculated and used each time around the loop. After the final loop, the value of carry is used to become the final carry-out.

< Previous
Page 3 of 5
Next >

Loading comments...

Most Commented

  • Currently no items

Parts Search Datasheets.com

KNOWLEDGE CENTER