Question

We have a binary number and we need to generate combination of 2 1's from the given number. If given such a combination of 2 1's we should be able to produce the next combination.

Example:-

Given vector   : 10101111 Given combination : 10100000 output       : 10001000
Given vector   : 10101111 Given combination : 10001000 output       : 10000100
Given vector   : 10101111 Given combination : 10000010 output       : 10000001
Given vector   : 10101111 Given combination : 10000001 output       : 00101000
Given vector   : 10101111 Given combination : 00101000 output       : 00100100

Edit: Once the 2nd 1 reaches the last 1 in the given binary number, the 1st 1 is incremented(set to next '1' in the binary number and the 2nd '1' is made the '1' that comes after the 1st '1'(as in eg 4))

This is to be done in hardware so it should not be computationally complex. How can we design this module in VHDL.

Was it helpful?

Solution

Here is some asynchronous code that will do the job:


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity nex2ones is
    Port ( vector : in   STD_LOGIC_VECTOR (1 to 8);
           combo1 : in   STD_LOGIC_VECTOR (1 to 8);
           combo2 : out  STD_LOGIC_VECTOR (1 to 8);
           error  : out  STD_LOGIC);
end nex2ones;

architecture Behavioral of nex2ones is

type int_array_8 is array (1 to 8) of integer range 0 to 8;

begin

process (vector,combo1)

variable ones_ixs        : int_array_8; 
variable first_combo1_ix : integer range 0 to 8 := 0;
variable second_combo1_ix: integer range 0 to 8 := 0;
variable first_combo1_k  : integer range 0 to 9 := 0;
variable second_combo1_k : integer range 0 to 9 := 0;
variable k               : integer range 1 to 9;

begin

ones_ixs := (others => 0); -- indices of 1s in vector
combo2   <= (others => '0');
k := 1;
first_combo1_ix  := 0;
second_combo1_ix := 0;
first_combo1_k   := 0;  -- corresponding ptr to ones_ixs
second_combo1_k  := 0;
error            <= '0';

for j in 1 to 8 loop

  if combo1(j) = '1' then
      if first_combo1_ix = 0 then
        first_combo1_ix := j;   
        first_combo1_k := k;
      else
        second_combo1_ix := j;
        second_combo1_k := k;
      end if;
  end if;

  if vector(j) = '1' then
    ones_ixs(k) := j; 
    k := k + 1;
  end if;

end loop;  

if k > 1 then k := k - 1; end if; -- point to last nonzero index

if (first_combo1_ix = 0 or second_combo1_ix = 0)
  --or (first_combo1_ix = ones_ixs(k-1) and second_combo1_ix = ones_ixs(k)) 
  or (k < 2) then 
  error <= '1';
else -- no error proceed
  if second_combo1_ix = ones_ixs(k) then              -- can't slide 2nd anymore
    if (second_combo1_k - first_combo1_k) > 1 then    -- is 1st movable
        combo2(ones_ixs(first_combo1_k + 1)) <= '1';    -- move 1st
        if (second_combo1_k - first_combo1_k) > 2 then  -- is 2nd movable
          combo2(ones_ixs(first_combo1_k + 2)) <= '1'; -- move 2nd
        else
          combo2(ones_ixs(second_combo1_k)) <= '1';     -- leave 2nd be
        end if;
      else
        error <= '1'; -- no mas
      end if;
  else
    combo2(ones_ixs(first_combo1_k)) <= '1';      -- leave 1st be
      combo2(ones_ixs(second_combo1_k + 1)) <= '1'; -- next
  end if;
end if;

end process;

end Behavioral;

Testbench output:

   ps       vector   combo1   combo2        
                                   error      
      0     00000000 00000000 00000000 1 
 100000     10101111 10100000 10001000 0 
 200000     10101111 10001000 10000100 0 
 300000     10101111 10000010 10000001 0 
 400000     10101111 10000001 00101000 0 
 500000     10101111 00101000 00100100 0 
 600000     10101111 00100100 00100010 0 
 700000     10101111 00000011 00000000 1 
 800000     11001110 00000110 00000000 1 
 900000     10001110 00001010 00000110 0 
1000000     11001110 00001010 00000110 0 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top