VHDL Design for a Dividor (8-bit / 4-bit)

Algorithm for the Dividor Design


Hardware Connections


Example to divide 0000 0111 by 0010


Please note: The above three pictures are from "Computer Organization and Design" by John L. Hennessy and David A. Patterson, Morgan Kaufmann Publishers, Inc.

RTL Block Diagram for the Dividor Design


The VHDL Code for the Divider Design


----------------------------------------------------------------------------------
-- Company: 		 CS
-- Engineer: 		 Guili Liu
-- 
-- Create Date:    19:42:00 03/18/2009 
-- Design Name: 
-- Module Name:    divisor - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity divisor is
    Port ( Dividend : in  STD_LOGIC_VECTOR (7 downto 0);
           Divis : in  STD_LOGIC_VECTOR (3 downto 0);
           clk : in  STD_LOGIC;
           Start : in  STD_LOGIC;
           Remainder : out  STD_LOGIC_VECTOR (3 downto 0);
	   Quotient : out  STD_LOGIC_VECTOR (3 downto 0);
           Done : out  STD_LOGIC);
end divisor;

architecture Behavioral of divisor is

signal DivBuf: STD_LOGIC_VECTOR (3 downto 0);
-- signal DivNeg: STD_LOGIC_VECTOR (3 downto 0);

signal ACC: STD_LOGIC_VECTOR (7 downto 0);
signal sum: STD_LOGIC_VECTOR (3 downto 0);
signal Remaind :  STD_LOGIC_VECTOR (3 downto 0);

type state is (S0, S1, S2, S3, S4);
signal FSM_cur_state, FSM_nx_state: state;
Signal Counter: STD_LOGIC_VECTOR (2 downto 0);
signal INC_CNT: STD_LOGIC;
signal LD_high: STD_LOGIC;
signal AccShift_left0: STD_LOGIC;
signal AccShift_left1: STD_LOGIC;
--signal addd: STD_LOGIC;
--signal subb: STD_LOGIC;
signal FSM_Done: STD_LOGIC;
--signal sum: STD_LOGIC_VECTOR(3 downto 0);

begin

DivisorReg: process (clk, start)
begin
   if clk'event and clk = '1' then 
	  if start = '1' then
	  DivBuf <= Divis;
	  end if;
	 end if;
end process;

ComboSum: process(DivBuf, ACC)
begin
    	 sum <= ACC(7 downto 4) + (not(DivBuf) + 1);
end process;

ACCReg: process (clk, start, Dividend, sum,
  AccShift_left0, AccShift_left1, LD_high)
begin
   if clk'event and clk = '1' then
	  if start = '1' then
	  ACC <= Dividend(6 downto 0)&'0';	
	  
	  elsif  LD_high = '1' then 
	     ACC(7 downto 4) <= sum;
	  elsif AccShift_left0 = '1' then
			ACC <= ACC(6 downto 0) & '0';
	     elsif AccShift_left1 = '1' then
	     ACC <= ACC(6 downto 0) & '1';
	 end if;
	 end if;	
end process;

-- output the results
Result: process(ACC)
begin  
	 Quotient  <= ACC(3 downto 0);	 
	 Remainder <= '0'&ACC(7 downto 5);	 
end process;

-- Combo Control Output
ComboFSMoutput: process(FSM_cur_State, start, sum, FSM_done)
begin
   INC_CNT <= '0';
   LD_high <= '0';
   AccShift_left0 <= '0';
   AccShift_left1 <= '0';
	case FSM_cur_State is 
	when S0 =>
	          if start = '1' then 
				 FSM_nx_State <= S0;
				 elsif sum(3) = '0' then 
				 FSM_nx_State <= S1;		 
				 else 
				 FSM_nx_State <= S2;
				 end if;
				 
	when S1 =>
				 LD_high <= '1';
				 FSM_nx_State <= S3;
	          	
	when S2 =>
	         AccShift_left0 <= '1';
				INC_CNT <= '1';
	         FSM_nx_State <= S4;
				
	when S3 => 
	         AccShift_left1 <= '1';
				INC_CNT <= '1';
				FSM_nx_State <= S4;
				
	when S4 =>
	         if FSM_done = '1' then 
				FSM_nx_State <= S4;
				else
				FSM_nx_State <= S0;
				end if;
	end case;	
end process;

-- FSM next state register	  
RegFSM_State: process (clk, FSM_nx_State, start)
begin
    if (clk'event and clk = '1') then 
	     if start ='1' then 
		  FSM_Cur_State <= S0;
		  else
		  FSM_Cur_State <= FSM_nx_State;
		  end if;
	 end if;
end process;

-- Counter to control the iteration
RegCounter: process(clk, start)
begin
    if clk'event and clk = '1' then 
	    if start = '1' then
		 Counter <= (others => '0');
		 elsif INC_CNT = '1' then
		 Counter <= Counter + 1;
		 end if;
	 end if;
end process;

-- update FSM_done
ComboFSMdone: process(Counter)
begin
   FSM_done <= counter(2) and (not(counter(1)))  and (not(counter(0)));
end process;

process(FSM_done)
begin 
		done <= FSM_done;
end process;

end Behavioral;