I have the following simplified example of my code, where the DeltasTest entity can be simulated to show the issue. The clock in the real design is inverted or not based on a generic, and feeds several other entities below this one.
The problem is that the simple edge detector does not work (data_out is just a glitch) in behavioral simulation, due to the delta cycle delay introduced on the clock by the inversion stage. Is there a standard or otherwise elegant way to solve this?
So far my best solution is to assign the data_in signal to another signal, to give it the same delta cycle delay as clk. I thought of using a function to invert the clock as necessary based on the generic as a second parameter to the function, but the clock is used in many places and this did not seem very elegant, and I was note sure it would even solve the problem. Clutching at straws, I also tried making the clock inversion assignment a transport assignment, but, as expected, this made no difference.
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;