0
\$\begingroup\$

I've been trying to develop a small multiplication engine using some shift registers on XilinX and some custom made functional blocks.

The numbers to multiply is Z and T. The purpose of the engine is more than what is asked in the question. The algorithm I've used to multiply 2 numbers is described below:

    1. CLEAR REGT & REGZ & REGR
    2. LOAD REGT 
    3. LOAD REGZ
    4. LOAD REGR (Value arrives from REGZ).
    5. while stop_signal = 1:
           if LSB == 1:
               LOAD REG R (ADD) 
               SHIFT RIGHT REGT & SHIFT LEFT REGZ
           else 
               SHIFT RIGHT REGT & SHIFT LEFT REGZ

The image above is the xilinx schematic.

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
LIBRARY UNISIM;
USE UNISIM.Vcomponents.ALL;
ENTITY operationalUnit_operationalUnit_sch_tb IS
END operationalUnit_operationalUnit_sch_tb;
ARCHITECTURE behavioral OF operationalUnit_operationalUnit_sch_tb IS 

   COMPONENT operationalUnit
   PORT( input_bus  :   IN  STD_LOGIC_VECTOR (7 DOWNTO 0); 
          LSB   :   OUT STD_LOGIC; 
          afterExtract  :   OUT STD_LOGIC_VECTOR (15 DOWNTO 0); 
          stop_signal   :   OUT STD_LOGIC; 
          after_adder   :   OUT STD_LOGIC_VECTOR (15 DOWNTO 0); 
          output_bus    :   OUT STD_LOGIC_VECTOR (15 DOWNTO 0); 
          open_z    :   IN  STD_LOGIC; 
          open_xy   :   IN  STD_LOGIC; 
          load_z    :   IN  STD_LOGIC; 
          load_t    :   IN  STD_LOGIC; 
          carry_in  :   IN  STD_LOGIC; 
          load_res  :   IN  STD_LOGIC; 
          clear_2   :   IN  STD_LOGIC; 
          clear_1   :   IN  STD_LOGIC; 
          clear_3   :   IN  STD_LOGIC; 
          CLOCK :   IN  STD_LOGIC; 
          left_1    :   IN  STD_LOGIC; 
          ce_1  :   IN  STD_LOGIC; 
             reg_z  : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
          left_2    :   IN  STD_LOGIC; 
          ce_2  :   IN  STD_LOGIC);
   END COMPONENT;

   SIGNAL input_bus :   STD_LOGIC_VECTOR (7 DOWNTO 0);
   SIGNAL LSB   :   STD_LOGIC;
   SIGNAL afterExtract  :   STD_LOGIC_VECTOR (15 DOWNTO 0);
   SIGNAL stop_signal   :   STD_LOGIC;
   SIGNAL after_adder   :   STD_LOGIC_VECTOR (15 DOWNTO 0);
   SIGNAL output_bus    :   STD_LOGIC_VECTOR (15 DOWNTO 0);
   SIGNAL open_z    :   STD_LOGIC;
   SIGNAL open_xy   :   STD_LOGIC;
   SIGNAL load_z    :   STD_LOGIC;
   SIGNAL load_t    :   STD_LOGIC;
   SIGNAL carry_in  :   STD_LOGIC;
   SIGNAL load_res  :   STD_LOGIC;
   SIGNAL clear_2   :   STD_LOGIC;
   SIGNAL clear_1   :   STD_LOGIC;
   SIGNAL clear_3   :   STD_LOGIC;
   SIGNAL CLOCK :   STD_LOGIC;
   SIGNAL left_1    :   STD_LOGIC;
    SIGNAL reg_z : STD_LOGIC_VECTOR(15 DOWNTO 0);
   SIGNAL ce_1  :   STD_LOGIC;
   SIGNAL left_2    :   STD_LOGIC;
   SIGNAL ce_2  :   STD_LOGIC;

BEGIN

   UUT: operationalUnit PORT MAP(
        input_bus => input_bus, 
        LSB => LSB, 
        afterExtract => afterExtract, 
        stop_signal => stop_signal, 
        after_adder => after_adder, 
        output_bus => output_bus, 
        open_z => open_z, 
        open_xy => open_xy, 
        load_z => load_z, 
        load_t => load_t, 
        carry_in => carry_in, 
        load_res => load_res, 
        clear_2 => clear_2, 
        clear_1 => clear_1, 
        clear_3 => clear_3, 
        CLOCK => CLOCK, 
        left_1 => left_1, 
        reg_Z => reg_z,
        ce_1 => ce_1, 
        left_2 => left_2, 
        ce_2 => ce_2
   );

-- *** Test Bench - User Defined Section ***
   tb : PROCESS
   BEGIN
    input_bus <= "00001010"; --t
    clear_2   <= '0';
    clear_1   <= '0';
    load_t    <= '1';
    clear_3   <= '1';
    open_xy   <= '1';
    carry_in  <= '0';

    wait for 40 ns; 
    clear_3   <= '0';
    load_t    <= '0';

    wait for 40 ns;
    input_bus <= "00000010"; --z
    load_z    <= '1';
    open_z    <= '0';
    wait for 40 ns;
    open_z    <= '1';
    load_z    <= '0';

    wait for 40 ns;
    input_bus <= "00000001"; --y
    open_xy   <= '0';
    wait for 40 ns;
    load_res  <= '1';
    wait for 40 ns;
    load_res  <= '0';
    open_xy   <= '1';


    input_bus <= "00000010"; -- 1 + x
    open_xy   <= '0';
    carry_in  <= '1';

    wait for 40 ns;
    load_res <= '1';

    wait for 40 ns;
    load_res <= '0';
    open_xy <= '1';
    open_z  <= '0';
    carry_in  <= '0';

    wait for 40 ns;
    while stop_signal = '1' loop
        if LSB = '1' 
            then
                load_res <= '1';
                wait for 40 ns;
                load_res <= '0';
                wait for 40 ns;

                    left_1 <= '1';
                    ce_1 <= '1';
                    clear_1 <= '0';
                    load_z <= '0';
                    left_2 <= '0';
                    ce_2 <= '1';
                    clear_2 <= '0';
                    load_t <= '0';

            else
                    left_1 <= '1';
                    ce_1 <= '1';
                    clear_1 <= '0';
                    load_z <= '0';
                    left_2 <= '0';
                    ce_2 <= '1';
                    clear_2 <= '0';
                    load_t <= '0';
                    end if;
                    end loop;

     WAIT; -- will wait forever
   END PROCESS;

     tx : PROCESS
   BEGIN
      for x in 0 to 200 loop
            clock <= '1';
            wait for 20 ns;
            clock <= '0';
            wait for 20 ns;
            end loop;
        WAIT; -- will wait forever
   END PROCESS;
-- *** End Test Bench - User Defined Section ***

END;

The code above solves the equation 1+x+y+z*t. The 1+x+y is solved first and the result on the simulation seems to be ok. But once the multiplication procedure starts things get a little out of hand. The error is right in front of me but I fail to see it.

Naming conventions of functional blocks used:

s_to_8_converter : A block that converts 8 bits to 16 bits. [Tested]

lsb Extractor    : A block that extracts the LSB from the 16 bit output.

zero check       : A block that checks if the bus is empty or not [Tested]. It consists of a 16 input OR gate.

The simulation wave graph.

I've spent days trying to find the error but I just see through it. I am assuming the error is with the while loop where the multiplication starts.

\$\endgroup\$
  • 1
    \$\begingroup\$ Specifically, what is happening and what were you expecting to happen? The essential code is missing. Provide something executable so that someone else can easily see what you're seeing. Just supply the minimum code required to reproduce the problem. These last two are called an MCVE. (stackoverflow.com/help/mcve) \$\endgroup\$ – Oldfart May 22 '18 at 13:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.