Friday, July 15, 2011

XC9536 CPLD Based ALU [VHDL]

XC9536 is one of the very antediluvian CPLDs developed by Xilinx. It has a capability of 800 programmable gates. Though it is very insufficient for modern day designs but still adequate enough to implement small design blocks and especially for learning purpose. I have seen many, graduate students pondering for a simple Arithmetic & Logic Unit Design using VHDL. Infact, there are many probable solutions to their quarries too. This design is nothing but another novel approach form my behalf which might be contributive to their necessities. Unquestionably, further modifications can be easily made to this device. This design is developed using VHDL programming language and tested on XC9536 CPLD board. It is deliberately made as an asynchronous design for hardware implementation sake and for a hands-on test-ability sake.

Features: 
[1] This is a 4-bit ALU with eight different arithmatic and logic operations.
[2] The output is 5-bit; the extra bit is provided in order to reflect the carry or borrow for add or subtract operation. The 5th bit will remain zero for logical operations.

[Note: This design is not hardware specific, so it can be implemented on any FPGA or CPLD device, provide the code is duly downloaded to the target device.]

Top-level Schematic:


Design Hierarchy:


VHDL Code:
mg_alu.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity mg_alu is
 port(input1, input2 : in std_logic_vector(3 downto 0);
  select_line : in std_logic_vector(2 downto 0);
output : out std_logic_vector(4 downto 0));
end mg_alu;

architecture Structural of mg_alu is
signal temp1 ,temp2, temp3, temp4, temp5, temp6, temp7, temp8 : std_logic_vector(4 downto 0);
component mg_add is
port(a, b : in std_logic_vector(3 downto 0);
  c : out std_logic_vector(4 downto 0));
end component;
component mg_sub is
port(a, b : in std_logic_vector(3 downto 0);
  c : out std_logic_vector(4 downto 0));
end component;
component mg_and is
port(a, b : in std_logic_vector(3 downto 0);
  c : out std_logic_vector(4 downto 0));
end component;
component mg_or is
port(a, b : in std_logic_vector(3 downto 0);
  c : out std_logic_vector(4 downto 0));
end component;
component mg_xor is
port(a, b : in std_logic_vector(3 downto 0);
  c : out std_logic_vector(4 downto 0));
end component;
component mg_nand is
port(a, b : in std_logic_vector(3 downto 0);
  c : out std_logic_vector(4 downto 0));
end component;
component mg_nor is
port(a, b : in std_logic_vector(3 downto 0);
  c : out std_logic_vector(4 downto 0));
end component;
component mg_xnor is
port(a, b : in std_logic_vector(3 downto 0);
  c : out std_logic_vector(4 downto 0));
end component;
begin
u1 : mg_add port map(input1, input2, temp1);
u2 : mg_sub port map(input1, input2, temp2);
u3 : mg_and port map(input1, input2, temp3);
u4 : mg_or port map(input1, input2, temp4);
u5 : mg_xor port map(input1, input2, temp5);
u6 : mg_nand port map(input1, input2, temp6);
u7 : mg_nor port map(input1, input2, temp7);
u8 : mg_xnor port map(input1, input2, temp8);
process(select_line)
begin
case select_line is
when "000" => output <= temp1; -- add
when "001" => output <= temp2; -- sub
when "010" => output <= temp3; -- and
when "011" => output <= temp4; -- or
when "100" => output <= temp5; -- xor
  when "101" => output <= temp6; -- nand
when "110" => output <= temp7; -- nor
when "111" => output <= temp8; -- xnor
when others =>
end case;
end process;
end Structural;

mg_add.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity mg_add is
 port(a, b : in std_logic_vector(3 downto 0);
  c : out std_logic_vector(4 downto 0));
end mg_add;

architecture Behavioral of mg_add is
begin
process(a, b)
begin
c <= ('0' & a) + ('0' & b);
end process;
end Behavioral;

mg_and.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity mg_and is
port(a, b : in std_logic_vector(3 downto 0);
  c : out std_logic_vector(4 downto 0));
end mg_and;

architecture Behavioral of mg_and is
begin
process(a, b)
begin
c <= ('0' & a) and ('0' & b);
end process;
end Behavioral;

mg_nand.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity mg_nand is
port(a, b : in std_logic_vector(3 downto 0);
  c : out std_logic_vector(4 downto 0));
end mg_nand;

architecture Behavioral of mg_nand is
begin
process(a, b)
begin
c <= ('0' & a) nand ('0' & b);
end process;
end Behavioral;

mg_nor.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity mg_nor is
port(a, b : in std_logic_vector(3 downto 0);
  c : out std_logic_vector(4 downto 0));
end mg_nor;

architecture Behavioral of mg_nor is
begin
process(a, b)
begin
c <= ('0' & a) nor ('0' & b);
end process;
end Behavioral;

mg_or.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity mg_or is
port(a, b : in std_logic_vector(3 downto 0);
  c : out std_logic_vector(4 downto 0));
end mg_or;

architecture Behavioral of mg_or is
begin
process(a, b)
begin
c <= ('0' & a) or ('0' & b);
end process;
end Behavioral;

mg_sub.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity mg_sub is
port(a, b : in std_logic_vector(3 downto 0);
  c : out std_logic_vector(4 downto 0));
end mg_sub;

architecture Behavioral of mg_sub is
begin
process(a, b)
begin
c <= ('0' & a) - ('0' & b);
end process;
end Behavioral;

mg_xnor.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity mg_xnor is
port(a, b : in std_logic_vector(3 downto 0);
  c : out std_logic_vector(4 downto 0));
end mg_xnor;

architecture Behavioral of mg_xnor is
begin
process(a, b)
begin
c <= ('0' & a) xnor ('0' & b);
end process;
end Behavioral;

mg_xor.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity mg_xor is
port(a, b : in std_logic_vector(3 downto 0);
  c : out std_logic_vector(4 downto 0));
end mg_xor;

architecture Behavioral of mg_xor is
begin
process(a, b)
begin
c <= ('0' & a) xor ('0' & b);
end process;
end Behavioral;

Simulation Data: 
The design is simulated with the following data:
input1 is: 0101
input2 is: 1010
select_line is varied from 000 to 111 for eight different ALU operations listed below
000 =>  add
001 =>  sub
010 =>  and
011 =>  or
100 =>  xor
 101 =>  nand
110 =>  nor
111 =>  xnor

No comments:

Post a Comment