Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

Simulation problem with simple edge detector

I have a very simple edge detector and I'm confused as to why I get this very small blip (pulse) on my output when it detects an edge. I ran into this in a larger design so I simplified it down to a project with only an edge detector. I have a clock, reset and an input that this the rising edge to be detected. The output should be a tick one clock period wide. I'm using the normal method/circuit to detect this, but the simulation gives me this little tiny pulse. Why is this? I've seen a simulation online with the same code that didn't have this problem. I've attached the HDL, testbench (very short files) and a pic of my simulation. Any ideas?

Simulation:

http://www.alteraforum.com/forum/attachment.php?attachmentid=9571&stc=1

My detector:


library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity RisingeEdgeDetector is
    port(        
            CLK                : in std_logic;            
            RESET                : in std_logic;            
            INPUT                : in std_logic;            
            
            OUTPUT            : out std_logic            
        );
    
end entity RisingeEdgeDetector;
architecture arch of RisingeEdgeDetector is
SIGNAL input_latch    : std_logic;    
begin
process(CLK, RESET) 
begin
    if(RESET = '0') then
        input_latch <= '0';
    elsif(rising_edge(CLK)) then
        input_latch <= INPUT;
    end if;
end process;
OUTPUT <= INPUT and (not input_latch);
end architecture arch;

TestBench:


LIBRARY ieee;                                               
USE ieee.std_logic_1164.all;                                
ENTITY RisingeEdgeDetector_vhd_tst IS
END RisingeEdgeDetector_vhd_tst;
ARCHITECTURE RisingeEdgeDetector_arch OF RisingeEdgeDetector_vhd_tst IS
-- constants                                                 
-- signals                                                   
SIGNAL CLK : STD_LOGIC;
SIGNAL INPUT : STD_LOGIC;
SIGNAL OUTPUT : STD_LOGIC;
SIGNAL RESET : STD_LOGIC;
COMPONENT RisingeEdgeDetector
    PORT (
    CLK : IN STD_LOGIC;
    INPUT : IN STD_LOGIC;
    OUTPUT : OUT STD_LOGIC;
    RESET : IN STD_LOGIC
    );
END COMPONENT;
BEGIN
    i1 : RisingeEdgeDetector
    PORT MAP (
-- list connections between master ports and signals
    CLK => CLK,
    INPUT => INPUT,
    OUTPUT => OUTPUT,
    RESET => RESET
    );
init : PROCESS                                               
                                    
BEGIN                                                        
    RESET <= '0';
    wait for 100 ns;
    RESET <= '1';
    
WAIT;                                                       
END PROCESS init; 
                                          
PROCESS                                                                                
BEGIN    
    CLK <= '0';
    wait for 10 ns;
    CLK <= '1';
    wait for 10 ns;
END PROCESS;   
PROCESS                                                                                
BEGIN  
    INPUT <= '0';
    wait for 190 ns;
    INPUT <= '1';
    wait for 20 ns;
    INPUT <= '0';
  
WAIT;
END PROCESS;  
                                       
END RisingeEdgeDetector_arch;

Here is the link of the simulation looks normal:

http://fpgacenter.com/examples/basic/edge_detector.php

7 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    That is due to what is called delta delay.

    Your logic says:

    elsif(rising_edge(CLK)) then

    input_latch <= INPUT;

    end if;

    OUTPUT <= INPUT and (not input_latch);

    thus input_latch acquires input at clock edhe but after delta delay. That very very small delay is seen in the comb logic of:

    OUTPUT <= INPUT and (not input_latch);

    set INPUT to '1' at 191 ns instead of 190 ns and see it disappear
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hey Kaz,

    Thanks for the reply! So the delta delay is because the simulator can't do this truly in parallel so it steps through delta delays to do this? In hardware doesn't this work because at the first clock edge INPUT will go high and then the next clock edge it gets latched and the circuit will see this high signal and at this time the output goes low because it latches a 1 through the dff. Basically there is a 1 clock delay here right?

    I'm trying to make sure I understand whats going on in both cases. If input goes high synchronized to the CLK it will be latched in on the next clock edge right? So, my circuit/simulation for this should work in hardware like it is?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    I'm trying to make sure I understand whats going on in both cases. If input goes high synchronized to the CLK it will be latched in on the next clock edge right? So, my circuit/simulation for this should work in hardware like it is?

    --- Quote End ---

    correct.

    if INPUT is generated by same clock then there will be delay of tCO + path delay or else timing would have failed. So data for sim is best put with some delay from clk edge to match real hardware.

    Generally to avoid delta delay in functional sim try generate data on clock edge rather than specific ns figures
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks! I changed up my test bench it my simulation looks good now. Here is my new stimulus block in my test bench

    
    PROCESS                                                                                
    BEGIN  
        INPUT <= '0';
        wait for 190 ns;
        wait until CLK = '1';
        INPUT <= '1';
        wait until CLK = '0';
        wait until CLK = '1';
        --wait for 20 ns;
        INPUT <= '0';
      
    WAIT;
    END PROCESS; 
    

    Here is a screenshot of the simulation:

    http://www.alteraforum.com/forum/attachment.php?attachmentid=9577&stc=1

    So am I correct in thinking that the simulator now executes the rising edge of input a delta delay after the rising edge of the clock more like a hardware circuit? Instead of the other way around where it took a delta delay/delays to execute the clock while input was technically high for an instant giving me that blip? I think I've got a handle on this now if this is correct.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    other options include:

    1) generate data on clocked process anf forget about specific after figures. Or

    2) register your comb statement on the clk edge

    I normally use option 1
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    other options include:

    1) generate data on clocked process anf forget about specific after figures. Or

    2) register your comb statement on the clk edge

    I normally use option 1

    --- Quote End ---

    This is where you can start building up your testbench_tools_pkg with stuff like this:

    
    procedure wait_for_clks(signal clk : in std_logic; n : natural) is
    begin
      for i in 1 to n loop  --loop 1 to n to allow 0 to  wait for 0 clocks
        wait until rising_edge(clk);
      end loop;
    end procedure wait_for_clks;
        
    ......
    process
    begin
      input <= a;
      wait_for_clks(clk, 10);
      input <= b;
      wait_for_clks(some_other_clk, 100);
      input <= c;
      wait;
    end process;
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Ok. I have never actually done anything like that. I will definitely start though that makes a lot of sense!