2
votes

I am trying to detect changes in the input signals of my Selector. When I find the first input that changed (either rising or falling edge), I give an index as output. When I try to synthesize my source code, I get an error "unsupported Clock statement". A also tried to use "rising_edge" and "falling_edge", but I got the same error. Here is my code

library ieee;
use ieee.std_logic_1164.all;

entity Selector is
port (
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
begin
process(X1,X2,X3,X4,X5,X6)
begin
    if (X1'event) then
            O <= "000";
    elsif (X2'event) then
            O <= "001";
    elsif (X3'event) then
            O <= "010";
    elsif (X4'event) then
            O <= "011";
    elsif (X5'event) then
            O <= "100";
    elsif (X6'event) then
            O <= "101";
    else
            O <= "000";
    end if;
end process;
end behave;

Is there an alternative solution for that?

1
The incomplete Xilinx XST error message is telling you that a double data rate register with six clocks isn't a supported synthesis construct (see XST HDL supported constructs). Perhaps you could give a bit more of an idea what you're trying to do here. It looks a bit like a priority encoder other than be time order sensitive. If you have desired simulation results dependent on time ordering you'd need to impose a clock compatible with all the events to insure ordering. - user1155120
I want to monitor those six signals. I want to be able to find the first to change (either from H to L or L to H), respecting the priority they have. When I find that signal, I output a specific vector. - user3551775

1 Answers

1
votes

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;