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;