How to solve this problem with delay delta cycle synchronization

I have the following simplified example of my code where an object DeltasTestcan be modeled to show a problem. Real-time clocks are inverted or not based on a common value and serve several other objects below it.

The problem is that a simple edge detector does not work (it data_outis just a malfunction) in behavioral modeling due to the delta cycle delay introduced on the watch during the inversion stage. Is there a standard or otherwise elegant way to solve this problem?

So far, my best solution has been to assign a signal to data_inanother signal to give it the same delta cycle delay as clk. I thought about using the function to invert the clock as needed based on the general parameter as the second parameter of the function, but the clock is used in many places, and this did not seem very elegant to me, and I noticed that it would even solve the problem. Squeezing the straw, I also tried to assign an inversion of clock pulses transport, but, as expected, it did not matter.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity Deltas is
    Generic (
        CLK_INVERT : boolean := false
    );
    Port (
        clk : in std_logic;
        data_in : in std_logic
    );
end Deltas;

architecture Behavioral of Deltas is

    -- Signals
    signal data_reg : std_logic := '0';
    signal clk_inverted : std_logic := '0';
    signal data_out : std_logic := '0';

begin

    ClkInvert : if (CLK_INVERT) generate
        clk_inverted <= not clk;
    else generate
        clk_inverted <= clk;
    end generate;

    process (clk_inverted)  
    begin
        if (rising_edge(clk_inverted)) then
            data_reg <= data_in;
        end if;
    end process;

    process (data_reg, data_in) 
    begin
        if (data_reg /= data_in) then
            data_out <= '1';
        else
            data_out <= '0';
        end if;
    end process;

    -- Other entities use `clk_inverted`. Commented out so that this example compiles
    --LowerEntity : entity work.Counter
    --port map (
    --  clk => clk_inverted
    --);

end Behavioral;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity DeltasTest is
end DeltasTest;

architecture Behavioral of DeltasTest is

    signal clk : std_logic := '0';
    signal data_in : std_logic := '0';

begin

    clk <= not clk after 10 ns;

    process (clk)
        variable count : integer := 0;
    begin
        if (rising_edge(clk)) then
            count := count + 1;
            if (count = 4) then
                count := 0;
                data_in <= not data_in;
            end if;
        end if;
    end process;

    uut : entity work.Deltas
    Port map (
        clk => clk,
        data_in => data_in
    );

end Behavioral;
+4
source share
3 answers

, "" - data_in, , .

clk_inverted , - ( (*) ) , .

, - , , , .

(*) " ", "" FF, - .

, - IP-, , , . IP- , .

- - FPGA ( FPGA, ) . , - , , .


. -.

! 2- SM, ...

...

, , - , ( ).

, ...

function clock_edge(signal clk : in std_logic) return boolean is
begin
   if CLK_INVERT then
      return falling_edge(clk);
   else 
      return rising_edge(clk);
   end if;
end clock_edge;
...

process (my_clock) is
begin
   if clock_edge(my_clk) then ...

, , . , , ( , )

, , . : , - . , , , .

+3

CLK_INVERT CLK_POLARITY. , , -.

entity Deltas is
    Generic (
        CLK_POLARITY : std_logic := '1'
    );
    Port (
        clk : in std_logic;
        data_in : in std_logic
    );
end Deltas;
architecture Behavioral of Deltas is
    signal data_reg : std_logic;
    signal data_out : std_logic;

begin

    process (clk)  
    begin
        if clk = CLK_POLARITY and clk'event then
            data_reg <= data_in;
        end if;
    end process;

: IP-, , ( ), reset reset ( reset reset). , , . DFF reset, , , DFFR (DFF reset), .

-- In package body asynchronous resets
procedure DFFR (
  signal Clk   : std_logic ; 
  signal Reset : std_logic ; 
  signal DataIn : std_logic ;
  signal DataOut : std_logic ;
  constant ResetValue : std_logic 
) is
begin
  if Reset = RESET_POLARITY then 
    DataOut <= ResetValue ; 
  elsif Clk = CLOCK_POLARITY and Clk'event then 
    DataOut <= DataIn ; 
  end if ;
end procedure DFFR ; 

-- In package body synchronous resets
procedure DFFR (
  signal Clk   : std_logic ; 
  signal Reset : std_logic ; 
  signal DataIn : std_logic ;
  signal DataOut : std_logic ;
  constant ResetValue : std_logic 
) is
begin
  if Clk = CLOCK_POLARITY and Clk'event then 
    if Reset = RESET_POLARITY then 
      DataOut <= ResetValue ; 
    else
      DataOut <= DataIn ; 
    end if ;
  end if ; 
end procedure DFFR ; 

-- In package body power on reset by initialization
procedure DFFR (
  signal Clk   : std_logic ; 
  signal Reset : std_logic ; 
  signal DataIn : std_logic ;
  signal DataOut : std_logic ;
  constant ResetValue : std_logic 
) is
begin
  if Clk = CLOCK_POLARITY and Clk'event then 
    DataOut <= DataIn ; 
  end if ;
end procedure DFFR ; 

, , .

IEEE 1076-2018 IEEE VHDL. , , , , .

+1

I think you have a case of metastability. you enter data, if it comes from the outside world, it may not be synchronized.

Clock data_in through two cascade registers and compare between two registers instead of comparing data_reg with the input signal.

I'm sure I made this mistake before

0
source

All Articles