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

Evaluation Board Circuit for 8051 Microcontroller


The evaluation board is dedicated for usages strictly related to AT89C51 (40 pin DIP), which is an infamous microcontroller and a very frequently used one in the academic arena as well. Generally, most of the evaluation boards available in the market are beyond the affordability range of an individual. Keeping this constraint in mind the board is designed such that it will not only cope with various feasible utilities of the microcontroller but also it will provide a deeper insight of microcontroller interfacing to the rookies. 

The salient features of this 8051 evaluation board are:
[1] It is a very low cost design.
[2] It is very lucid.
[3] It has got an on-board regulated power supply (with LED).
[4] All 4 ports of the 8051 microcontroller are easily accessible for further measures.
[5] It has an on-board reset switch.
[6] ALE, PSEN are arranged in such a manner that both internal and external memory access can be performed with a minor knob movement.
[7] Port 0 pins can be used as input or output with no addendum (mere switch adjustment). 
[8] The board supports serial mode access through RS232 using MAX232 chip.

Schematic:

[Note: All it takes is just to refer the circuit diagram given above and rebuild the circuit using any PCB fabrication tool readily available over Internet (e.g. PCB wizard) and transfer the design to a silk-screen. Then a PCB can be easily fabricated from that silk-screen and the various components can be populated over it using a soldering iron. Voila... you are ready with your fully functional evaluation board.]

*** Anyway, take the Mediafire link to 'PCB Wizard 3.50 PRO' ("no installation needed")
[the file for the evaluation board with .pcb extension is also available along with it.] 

Mediafire Link: http://www.mediafire.com/?3fbr4rl6sstg5k4

One More to The Count

Here is a much awaited book in VHDL and a pretty handy one as well...

Title: Digital Systems Design Using VHDL
Author: Charles H. Roth, Jr.
Publisher: PWS Publishing Company
Year: 1997


Mediafire Link:
http://www.mediafire.com/?vi44gvedywwo4nu

4-bit Ripple Carry Counter [Verilog]

The following code is designed using Xilinx ISE 7.1.04i [web-pack] and simulated on ModelSim PE [student edition], both are readily available over Internet for free.
This design has the following features:
1] Negative edge-triggered.
2] Asynchronous active-low reset.
3] 4-bit Type.
[Note: Simulation results and Stimulus (test-bench) is added with the design. It is duly tested for error free functionality.]


Schematics:
 


Verilog Code:
Ripple carry counter:
module ripple_carry_counter(q, clk, reset);
output [3:0] q;
input clk, reset;
T_FF tff0(q[0], clk, reset);
T_FF tff1(q[1], q[0], reset);
T_FF tff2(q[2], q[1], reset);
T_FF tff3(q[3], q[2], reset);
endmodule 


T flip-flop:
module T_FF(q, clk, reset);
output q;
input clk, reset;
wire d;
D_FF dff0(q, d, clk, reset);
not n1(d, q); // not is Verilog-provided primitive. Case sensitive.
endmodule 


D flip-flop:
module D_FF(q, d, clk, reset);
output q;
input d, clk, reset;
reg q; 
always @(posedge reset or negedge clk)
if (reset)
q = 1'b0;
else
q = d;
endmodule


Stimulus:
module stimulus_v;
reg clk; // Input
reg reset; // Input
wire [3:0] q; // Output
// Instantiate the Unit Under Test
ripple_carry_counter r1 (.q(q), .clk(clk), .reset(reset));
// Control the clk signal that drives the design block. Cycle time = 10
       initial
              clk = 1'b0; // Set clk to 0
       always
              #5 clk = ~clk; // Toggle clk every 5 time units
// Control the reset signal that drives the design block.
// reset is asserted from 0 to 20 and from 200 to 220 
initial
begin
       reset = 1'b1;
       #20 reset = 1'b0;
       #180 reset = 1'b1;
       #20 reset = 1'b0;
end endmodule


Simulation Data:

Thursday, July 14, 2011

AN EXCELLENT BOOK ON VERILOG

The details of this book are:
Title: Verilog HDL - A Guide to Digital Design and Synthesis
Author: Samir Palnitkar
Publisher: Sun Soft Press 
Year: 1996


Mediafire Link: 
http://www.mediafire.com/?amvhgto1tj7vvhk

Wednesday, July 13, 2011

WiPEM - 2011

It was a matter of privilege and immense pleasure to share hands as a Program Committee Member with the dainty sanctum of Deptartment of Electronics and Communication Engineering, Haldia Institute of Technology in WiPEM - 2011 [Winter School on PCB Fabrication for Embedded Applications during January 10 - 14, 2011, Sponsored by IEEE, HIT Student Chapter]. 


Simple Frequency Limiter [VHDL]


The following code is designed using Xilinx ISE 7.1i04 and simulated on Modelsim PE student edition [Both are readily available over Internet for free]

This design acts as a frequency limiter; modifications can be made to this to make it more application specific for advanced implementations. The following code is supported with the test-bench and simulation waveform too for a better understanding. It works in the fashion stated below: There is a system clock (clock_in) which monitors the incoming pulse train (pulse_in). Whenever the frequency of the incoming pulse train goes above the system clock frequency, the system ceases to work (lock goes low). The system automatically retrieves regular functionality by re-asserting the lock, as soon as the foretold condition is met. 

VHDL code: 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity frequency_limiter is
port(clock_in, pulse_in : in std_logic;
        lock : out std_logic);
end frequency_limiter;

architecture architecture_ frequency_limiter of frequency_limiter is
signal count : integer := 0;
begin
process(clock_in, pulse_in)
begin
if(rising_edge(clock_in)) then
        count <= 0;
end if;
if(rising_edge(pulse_in)) then
        count <= count + 1;
end if;
end process;
process(count)
begin
if ((count < 1) or (count = 1)) then
        lock <= '1';
else
        lock <= '0';
end if;
end process;
end architecture_lock_status; 


Test Bench: 
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;

ENTITY tb_ frequency_limiter IS
END tb_ frequency_limiter;

ARCHITECTURE architecture_ tb_ frequency_limiter OF tb_ frequency_limiter IS
signal lock, clock_in, pulse_in : std_logic := '0';
constant period : time := 20 ps;
BEGIN
uut: entity work.lock_status PORT MAP(clock_in, pulse_in, lock);
clock_in_process :process
                             begin
                             clock_in <= '0';
                             wait for period/2;
                             clock_in <= '1';
                             wait for period/2;
                             end process;
stim_proc: process
                 begin
                 -- case 1:
                 pulse_in <= '1';
                 wait for 5 ps;
                 pulse_in <= '0';
                 wait for 5 ps;
                 -- case 2:
                 pulse_in <= '0';
                 wait for 4 ps;
                 pulse_in <= '1';
                 wait for 4 ps;
                 -- case 3:
                 pulse_in <= '0';
                 wait for 5 ps;
                 pulse_in <= '1';
                 wait for 4 ps;
                 -- case 4:
                 pulse_in <= '0';
                 wait for 4 ps;
                 pulse_in <= '1';
                 wait for 5 ps;
                 -- case 5:
                 pulse_in <= '0';
                 wait for 4 ps;
                 pulse_in <= '1';
                 wait;
                 end process;
END architecture_ tb_ frequency_limiter; 


Simulation Data: 

Thursday, June 16, 2011

Some Invaluable Books

Here are the links to a few invaluable books:


[1] VLSI: CMOS Circuit Design Layout and Simulation - R. Jacob Baker 


[2] Engineering Mathematics: Advanced Engineering Mathematics - Erwin Kreyszig
[3] Microprocessor: Understanding 8085 8086 Microprocessors - S. K. Sen