1. Problem description

            Find the minimum number of an array of 4 numbers and return the position and the number.  This is a subset of the Kashubin sorter/absorber.  Where the sorter employs even and odd states and a comparator, the “Sultan” min function only employs a comparator at each regression. 

 

2. Implementation

2.1 Description

            The min function returns the minimum value of a four 8-bit numbers and the position of the minimum number.  Four numbers were chosen instead of eight because it was the highest number that requires only two levels of comparing.  The algorithm is illustrated below in figure 1.

 

Figure 1.

 

The top level of the min function consists of four 8-bit inputs and one 8-bit output and one 2-bit output with control signal “en”.  The flip flops are clocked with the clk and are positive edge triggered.  Unlike the Kashubin sorter/absorber, there are no registers on the output.  This function is designed to be fast, so only the input goes through a register.  Also, the path to the min value is just N levels of gates, where N is log2 of the number of inputs.  For example, if there are 8 (23) number of inputs, the min function requires 3 levels of compare gates.  Note: If “en” remain on, the min function will find the min value on the positive edge of each clock cycle. The top level diagram is shown below as figure 2.

 

Figure 2.

 

2.2 Tools

            I used the Mentor tools Renoir, ModelSim, and Leonardo.  All were part of the FPGA Advantage evaluation package.  I designed, simulated and synthesized this design with the above tools.

 

2.3 Block Diagram

            Figure 3 is a detail system block diagram of the design.  It is the actual design that Leonardo generated.

 

Figure 3.

 

3. Discussion

3.1 Considerations

            If all of the numbers entered are equal or the minimum number is equal to another number in a different position, the min function will return the first number in the order of the array.  For example, if the sequence 2,2,2,2 were entered into the min function then (2,0) would be returned.  ‘2’ being the lowest number and ‘0’ being it’s position.  The min function does not test for equals.

 

            Similarly, if a don’t care is enter in any position, then it is disregarded and an actual number is returned.

 

3.2 Problems encountered

            Since I have never programmed in VHDL before nor do I have experience in hardware design, it took me about 10 hours to get familiar with the Mentor tools.  This includes going through the tutorial and making test cases.  The design itself is very easy to implement but with no background in VHDL or the tool set it takes much longer.  Total Design time was about 20 hours.

 

I really only encountered two significant problems, the tool set and the process function.  On the last compare state I didn’t include the position bus in the process function, so when new numbers were entered but the min number didn’t change, the output would stay the same even though the position changed.  I fixed this by including the two address buses in the process statement.

 

4. Code

            The code is below.  Notice that I implement a strictly “less than” (<) in all of the compare statements.  This is because unless the number in the higher position (e.g. dat_in1) is strictly less than the number in the lower position (e.g. dat_in0), the number in the lower position is passed on.  Plus I remember from a hardware class that it takes less hardware to do a strictly less than, than a greater than or equal to.

 

            Although the code says “latch”, the implementation is actually a flip-flop.

 

            The first level of compares has the position hard coded in the design block.  Every level after that passes the position of the lowest number.

 

Latch1_latch1.vhd

This implements the flipflop

 

LIBRARY ieee ;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

 

ENTITY latch1 IS

   PORT(

      clk     : IN     std_logic  ;

      dat_in1 : IN     std_logic_vector (7 DOWNTO 0) ;

      en      : IN     std_logic  ;

      dbus6   : OUT    std_logic_vector (7 DOWNTO 0)

   );

 

-- Declarations

 

END latch1 ;

 

-- renoir interface_end

ARCHITECTURE latch1 OF latch1 IS

BEGIN

            process (clk,en)

            BEGIN

                        if (clk='1' AND clk'event) then

                                    if (en='1') then

                                    dbus6 <= dat_in1;

                                    end if;

                        end if;

            end process;

END latch1;

 

 

Compare0_compare0.vhd

This is the first level of compare blocks.

 

LIBRARY ieee ;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

 

ENTITY Compare0 IS

   PORT(

      dbus4  : IN     std_logic_vector (7 DOWNTO 0) ;

      dbus6  : IN     std_logic_vector (7 DOWNTO 0) ;

      dbus12 : OUT    std_logic_vector (7 DOWNTO 0) ;

      dbus13 : OUT    std_logic_vector (1 DOWNTO 0)

   );

 

-- Declarations

 

END Compare0 ;

 

-- renoir interface_end

ARCHITECTURE compare0 OF Compare0 IS

BEGIN

process (dbus6,dbus4)

begin

            IF (dbus6 < dbus4) THEN

                        dbus12 <= dbus6;

                        dbus13 <= "01";

            else

                        dbus12 <= dbus4;

                        dbus13 <= "00";

            end if;

end process;

END compare0;

 

 

Compare3_compare3.vhd

This is the second level of compares.  All compares above this level will be like this.

 

LIBRARY ieee ;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

 

ENTITY Compare3 IS

   PORT(

      dbus12      : IN     std_logic_vector (7 DOWNTO 0) ;

      dbus13      : IN     std_logic_vector (1 DOWNTO 0) ;

      dbus14      : IN     std_logic_vector (7 DOWNTO 0) ;

      dbus15      : IN     std_logic_vector (1 DOWNTO 0) ;

      dat_out     : OUT    std_logic_vector (7 DOWNTO 0) ;

      dat_out_pos : OUT    std_logic_vector (1 DOWNTO 0)

   );

 

-- Declarations

 

END Compare3 ;

 

-- renoir interface_end

ARCHITECTURE Compare3 OF Compare3 IS

BEGIN

process (dbus14,dbus12,dbus15,dbus13)

begin

            if (dbus14 < dbus12) then

                        dat_out <= dbus14;

                        dat_out_pos <= dbus15;

            else

                        dat_out <= dbus12;

                        dat_out_pos <= dbus13;

            end if;

end process;

END Compare3;

 

Four_min_struct.vhd

Top block code

 

LIBRARY ieee ;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

 

ENTITY four_min IS

   PORT(

      clk         : IN     std_logic  ;

      dat_in0     : IN     std_logic_vector (7 DOWNTO 0) ;

      dat_in1     : IN     std_logic_vector (7 DOWNTO 0) ;

      dat_in2     : IN     std_logic_vector (7 DOWNTO 0) ;

      dat_in3     : IN     std_logic_vector (7 DOWNTO 0) ;

      en          : IN     std_logic  ;

      dat_out     : OUT    std_logic_vector (7 DOWNTO 0) ;

      dat_out_pos : OUT    std_logic_vector (1 DOWNTO 0)

   );

 

-- Declarations

 

END four_min ;

 

-- renoir interface_end

--

-- VHDL Architecture Comparer.four_min.struct

--

-- Created:

--          by - sweather.UNKNOWN (SWMOBL)

--          at - 15:16:33 05/09/2001

--

-- Generated by Mentor Graphics' Renoir(TM) 2000.3 (Build 2)

--

LIBRARY ieee ;

USE ieee.std_logic_1164.ALL;

USE ieee.std_logic_arith.ALL;

 

LIBRARY Comparer;

 

ARCHITECTURE struct OF four_min IS

 

   -- Architecture declarations

 

   -- Internal signal declarations

   SIGNAL dbus10 : std_logic_vector(7 DOWNTO 0);

   SIGNAL dbus12 : std_logic_vector(7 DOWNTO 0);

   SIGNAL dbus13 : std_logic_vector(1 DOWNTO 0);

   SIGNAL dbus14 : std_logic_vector(7 DOWNTO 0);

   SIGNAL dbus15 : std_logic_vector(1 DOWNTO 0);

   SIGNAL dbus4  : std_logic_vector(7 DOWNTO 0);

   SIGNAL dbus6  : std_logic_vector(7 DOWNTO 0);

   SIGNAL dbus8  : std_logic_vector(7 DOWNTO 0);

 

   -- Component Declarations

   COMPONENT Compare0

   PORT (

      dbus4  : IN     std_logic_vector (7 DOWNTO 0);

      dbus6  : IN     std_logic_vector (7 DOWNTO 0);

      dbus12 : OUT    std_logic_vector (7 DOWNTO 0);

      dbus13 : OUT    std_logic_vector (1 DOWNTO 0)

   );

   END COMPONENT;

   COMPONENT Compare1

   PORT (

      dbus10 : IN     std_logic_vector (7 DOWNTO 0);

      dbus8  : IN     std_logic_vector (7 DOWNTO 0);

      dbus14 : OUT    std_logic_vector (7 DOWNTO 0);

      dbus15 : OUT    std_logic_vector (1 DOWNTO 0)

   );

   END COMPONENT;

   COMPONENT Compare3

   PORT (

      dbus12      : IN     std_logic_vector (7 DOWNTO 0);

      dbus13      : IN     std_logic_vector (1 DOWNTO 0);

      dbus14      : IN     std_logic_vector (7 DOWNTO 0);

      dbus15      : IN     std_logic_vector (1 DOWNTO 0);

      dat_out     : OUT    std_logic_vector (7 DOWNTO 0);

      dat_out_pos : OUT    std_logic_vector (1 DOWNTO 0)

   );

   END COMPONENT;

   COMPONENT latch0

   PORT (

      clk     : IN     std_logic ;

      dat_in0 : IN     std_logic_vector (7 DOWNTO 0);

      en      : IN     std_logic ;

      dbus4   : OUT    std_logic_vector (7 DOWNTO 0)

   );

   END COMPONENT;

   COMPONENT latch1

   PORT (

      clk     : IN     std_logic ;

      dat_in1 : IN     std_logic_vector (7 DOWNTO 0);

      en      : IN     std_logic ;

      dbus6   : OUT    std_logic_vector (7 DOWNTO 0)

   );

   END COMPONENT;

   COMPONENT latch2

   PORT (

      clk     : IN     std_logic ;

      dat_in2 : IN     std_logic_vector (7 DOWNTO 0);

      en      : IN     std_logic ;

      dbus8   : OUT    std_logic_vector (7 DOWNTO 0)

   );

   END COMPONENT;

   COMPONENT latch3

   PORT (

      clk     : IN     std_logic ;

      dat_in3 : IN     std_logic_vector (7 DOWNTO 0);

      en      : IN     std_logic ;

      dbus10  : OUT    std_logic_vector (7 DOWNTO 0)

   );

   END COMPONENT;

 

   -- Optional embedded configurations

   -- pragma synthesis_off

   FOR ALL : Compare0 USE ENTITY Comparer.Compare0;

   FOR ALL : Compare1 USE ENTITY Comparer.Compare1;

   FOR ALL : Compare3 USE ENTITY Comparer.Compare3;

   FOR ALL : latch0 USE ENTITY Comparer.latch0;

   FOR ALL : latch1 USE ENTITY Comparer.latch1;

   FOR ALL : latch2 USE ENTITY Comparer.latch2;

   FOR ALL : latch3 USE ENTITY Comparer.latch3;

   -- pragma synthesis_on

 

BEGIN

   -- Instance port mappings.

   I4 : Compare0

      PORT MAP (

         dbus4  => dbus4,

         dbus6  => dbus6,

         dbus12 => dbus12,

         dbus13 => dbus13

      );

   I5 : Compare1

      PORT MAP (

         dbus10 => dbus10,

         dbus8  => dbus8,

         dbus14 => dbus14,

         dbus15 => dbus15

      );

   I6 : Compare3

      PORT MAP (

         dbus12      => dbus12,

         dbus13      => dbus13,

         dbus14      => dbus14,

         dbus15      => dbus15,

         dat_out     => dat_out,

         dat_out_pos => dat_out_pos

      );

   I0 : latch0

      PORT MAP (

         clk     => clk,

         dat_in0 => dat_in0,

         en      => en,

         dbus4   => dbus4

      );

   I1 : latch1

      PORT MAP (

         clk     => clk,

         dat_in1 => dat_in1,

         en      => en,

         dbus6   => dbus6

      );

   I2 : latch2

      PORT MAP (

         clk     => clk,

         dat_in2 => dat_in2,

         en      => en,

         dbus8   => dbus8

      );

   I3 : latch3

      PORT MAP (

         clk     => clk,

         dat_in3 => dat_in3,

         en      => en,

         dbus10  => dbus10

      );

 

END struct;