You would need an additional clock input to make a comparison between the value of X1, X2, ... in the current clock cycle and the value in the last clock cycle. If the Xes are asynchronous to the clock you have to synchronize them first.
Input synchronisation
To synchronize the inputs to the clock, you have to sample each input with two D flip-flops in serial. The output of the first flip-flop may be harmed by metastability problems which is described in more detail in these papers:
The connection between both flip-flops (for each input) must be constrained so that the rounting path between them is as short as possible. The implementation below will just show the two flip-flops. A more advanced implementation can be found in the sync_Bits component of the PoC Library where I am one of the authors.
Comparison
Once the input is synchronous to the clock, just delay it another clock cylce. This will make up the last value, so that, you can compare the current values to the last values to detect a signal change. The frequency of the input clock must be much faster than the frequency of change on one of the X inputs:
- to get a fast repsonse of the edge-detection, and
- to catch all signal changes.
Here is a possible implementation:
library ieee;
use ieee.std_logic_1164.all;
entity Selector is
port (
clk : in std_logic;
X1: in std_logic;
X2: in std_logic;
X3: in std_logic;
X4: in std_logic;
X5: in std_logic;
X6: in std_logic;
O: out std_logic_vector(2 downto 0)
);
end Selector;
architecture behave of Selector is
signal X : std_logic_vector(6 downto 1); -- all inputs in one vector
signal X_meta : std_logic_vector(6 downto 1); -- first sampling stage
signal X_curr : std_logic_vector(6 downto 1); -- second sampling stage =
-- current value
signal X_last : std_logic_vector(6 downto 1); -- last value of X_curr
begin
-- Concatenate all inputs to one vector for shorter code below.
X <= X6 & X5 & X4 & X3 & X2 & X1;
-- Synchronize external inputs to clock. If the X* inputs are already
-- synchronous to 'clk' then replace this process with:
-- X_curr <= X;
sync: process(clk)
begin
if rising_edge(clk) then
-- The path betweeen these two flip-flops must be constrained for a
-- short delay, so that, the wire in between is as ahort as
-- possible.
X_meta <= X;
X_curr <= X_meta;
end if;
end process;
-- This statement delays the current value X_curr by one clock cycle.
X_last <= X_curr when rising_edge(clk);
-- Comparison and selector output.
process(X_curr, X_last)
begin
if (X_curr(1) xor X_last(1)) = '1' then
O <= "000";
elsif (X_curr(2) xor X_last(2)) = '1' then
O <= "001";
elsif (X_curr(3) xor X_last(3)) = '1' then
O <= "010";
elsif (X_curr(4) xor X_last(4)) = '1' then
O <= "011";
elsif (X_curr(5) xor X_last(5)) = '1' then
O <= "100";
elsif (X_curr(6) xor X_last(6)) = '1' then
O <= "101";
else
O <= "000";
end if;
end process;
end behave;