Search code examples
vhdlsequentialmultiplicationcircuit

Can't get VHDL Sequential Multiplier to Multiply correctly


I have a School Lab that I must do pertaining to creating a sequential multiplier in VHDL. My issues is happening before making the finite state machine for the sequential multiplier. I can not get the base model to multiply correctly, I think I have a issue in my test bench but am not 100% sure of this. I still have doubt that the issue is in my code.

Top Design (basically calling the D-Flip-Flops, MUX and Adder)

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--use ieee.std_logic_arith.all;
--use ieee.std_logic_unsigned.all;
entity toplvds is

    port( A,B: in std_logic_vector(3 downto 0);
            Zero: in std_logic_vector(3 downto 0);
            clk, clr, load, loadP, sb: in std_logic;
            Po: out std_logic_vector(7 downto 0));

end toplvds;

architecture Behavioral of toplvds is

component dffa
    port( dina: in std_logic_vector(3 downto 0);
            clr, clk, load: in std_logic;
            q: out std_logic_vector(3 downto 0));
end component;

component dffb
    port( dinb: in std_logic_vector(3 downto 0);
            clr, clk, load, sb: in std_logic;
            qb0: out std_logic);
end component;

component mux
    port( d0,d1: in std_logic_vector(3 downto 0);
            s: in std_logic;
            y: out std_logic_vector(3 downto 0));
end component;

component adder
    port( a,b: in std_logic_vector(3 downto 0);
            cry: out std_logic;
            r: out std_logic_vector(3 downto 0));
end component;

component dffP
    port( dinp: in std_logic_vector(3 downto 0);
            carry: in std_logic;
            clr, clk, loadP, sb: in std_logic;
            PHout: out std_logic_vector (3 downto 0);
            P: out std_logic_vector(7 downto 0));
end component;

signal Wire1: std_logic_vector(3 downto 0);
signal Wire2: std_logic_vector(3 downto 0);
signal Wire3: std_logic;
signal Wire4: std_logic_vector(3 downto 0);
signal Wire5: std_logic_vector(3 downto 0);
signal Wire6: std_logic_vector(3 downto 0);
signal Wire7: std_logic;

begin

    Wire1 <= Zero;

    u1: dffa port map (dina=>A,clr=>clr,clk=>clk,load=>load,q=>Wire2);
    u2: dffb port map (dinb=>B,clr=>clr,clk=>clk,load=>load,sb=>sb,qb0=>Wire3);
    u3: mux port map (d0=>Wire2,d1=>Wire1,s=>Wire3,y=>Wire4);
    u4: adder port map (a=>Wire6,b=>Wire4,cry=>Wire7,r=>Wire5);
    u5: dffp port map (dinp=>Wire5,carry=>Wire7,clr=>clr,clk=>clk,loadP=>loadP,sb=>sb,PHout=>Wire6,P=>Po);

end Behavioral;

D-Flip-Flop for Multiplicand

library ieee;
use ieee.std_logic_1164.all;
entity dffa is 
    port( dina: in std_logic_vector(3 downto 0);
            clr, clk, load: in std_logic;
            q: out std_logic_vector(3 downto 0));
end dffa;

architecture beh of dffa is
begin
    process(clk,clr)
    begin 
        if(clr = '1') then
            q <= ( others => '0');
        elsif (rising_edge(clk)) then
            if(load = '1') then
                q <= dina;
            end if;
        end if;
    end process;
end beh;

D-Flip-Flop for Multiplier

library ieee;
use ieee.std_logic_1164.all;
entity dffb is 
    port( dinb: in std_logic_vector(3 downto 0);
            clr, clk, load, sb: in std_logic;
            qb0: out std_logic);
end dffb;
architecture beh of dffb is
signal q: std_logic_vector(3 downto 0);
begin
    qb0 <= q(0);
    process(clk,clr, load, sb)
    begin 
        if(clr = '1') then
            q <= ( others => '0');
        elsif (rising_edge(clk)) then
            if(load = '1') then
                q <= dinb;
            elsif (sb = '1') then
                q <= '0' & q ( 3 downto 1); 
            end if;
        end if;
    end process;        
end beh;

MUX

library ieee;
use ieee.std_logic_1164.all;
entity mux is 
    port( d0,d1: in std_logic_vector(3 downto 0);
            s: in std_logic;
            y: out std_logic_vector(3 downto 0));

end mux;

architecture beh of mux is  

begin

    y <= d0 when s = '1' else d1;

end beh;

Adder

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;

entity adder is 
    port( a,b: in std_logic_vector(3 downto 0);
            cry: out std_logic;
            r: out std_logic_vector(3 downto 0));
end adder;

architecture beh of adder is
    signal temp : std_logic_vector(4 downto 0); 
begin
    temp <= ('0' & a) + ('0' & b);

   r <= temp(3 downto 0); 
   cry <= temp(4);
end beh;

D-Flip-Flop for Product

library ieee;
use ieee.std_logic_1164.all;

entity dffp is 
    port( dinp: in std_logic_vector(3 downto 0);
            carry: in std_logic;
            clr, clk, loadP, sb: in std_logic;
            PHout: out std_logic_vector (3 downto 0);
            P: out std_logic_vector(7 downto 0));
end dffp;

architecture beh of dffp is
signal q: std_logic_vector(7 downto 0);
begin
    --qp0 <= q(0);
    process(clk,clr, loadP, sb)
    begin 
        if(clr = '1') then
            q <= ( others => '0');
        elsif (rising_edge(clk)) then
            if(loadP = '1') then
                --q <= "00000000";
                q(7 downto 4) <= dinp;
            elsif (sb = '1') then
                q <= carry & q ( 7 downto 1);   
            --else 
                --q(7 downto 4) <= dinp;
            end if;
        end if;
    end process;

    PHout <= q(7 downto 4); 
    P <= q;

end beh;

TEST-BENCH Code

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;

ENTITY toplvds_tb IS
END toplvds_tb;

ARCHITECTURE behavior OF toplvds_tb IS 

    -- Component Declaration for the Unit Under Test (UUT)

    COMPONENT toplvds
    PORT(
         A : IN  std_logic_vector(3 downto 0);
         B : IN  std_logic_vector(3 downto 0);
         Zero : IN  std_logic_vector(3 downto 0);
         clk : IN  std_logic;
         clr : IN  std_logic;
         load : IN  std_logic;
         loadP : IN  std_logic;
         sb : IN  std_logic;
         Po : OUT  std_logic_vector(7 downto 0)
        );
    END COMPONENT;


   --Inputs
   signal A : std_logic_vector(3 downto 0) := (others => '0');
   signal B : std_logic_vector(3 downto 0) := (others => '0');
   signal Zero : std_logic_vector(3 downto 0) := (others => '0');
   signal clk : std_logic := '0';
   signal clr : std_logic := '0';
   signal load : std_logic := '0';
   signal loadP : std_logic := '0';
   signal sb : std_logic := '0';

    --Outputs
   signal Po : std_logic_vector(7 downto 0);

   -- Clock period definitions
   constant clk_period : time := 10 ns;

BEGIN

    -- Instantiate the Unit Under Test (UUT)
   uut: toplvds PORT MAP (
          A => A,
          B => B,
          Zero => Zero,
          clk => clk,
          clr => clr,
          load => load,
          loadP => loadP,
          sb => sb,
          Po => Po
        );

   -- Clock process definitions
   clk_process :process
   begin
        clk <= '0';
        wait for clk_period/2;
        clk <= '1';
        wait for clk_period/2;
   end process;


   -- Stimulus process
   stim_proc: process
   begin

        A <= "1011";
        B <= "1101";
        Zero <="0000";

        load <= '0';
        sb <= '0';
        clr <= '1';
        wait for 12 ns;
        clr <= '0'; load <= '1';

        wait for 12 ns;
        load <= '0'; sb <= '1';
        wait for 12 ns;
        sb <= '0'; loadP <= '1';

        wait for 12 ns;
        loadP <= '0'; sb <= '1';
        wait for 12 ns;
        sb <= '0'; loadP <= '1';

        wait for 12 ns;
        loadP <= '0'; sb <= '1';
        wait for 12 ns;
        sb <= '0'; loadP <= '1';

        wait for 12 ns;
        loadP <= '0'; sb <= '1';
        wait for 12 ns;
        sb <= '0'; loadP <= '1';

        wait for 12 ns;
        loadP <= '0'; sb <= '1';

        wait for 20 ns;
        loadP <= '0'; sb <= '0';


      wait;
   end process;

END;

Sorry that I have not commented the code for better understanding. I know this will be hard to follow but I hope someone will. I will also attach an image of the figure of the sequential multiplier I am following, the circuit design.

4 by 4 binary sequential multiplier circuit

4 by 4 binary sequential multiplier circuit - more


Solution

  • Well it was indeed something in the testbench that was giving issues. I worked it out in the lab with fellow classmates. Thank You for your help anyways it is much appreciated.

    p.s. All I did was changed some timing values in the testbench at the very bottom to when the load and shift bit would happen and I got it to work.