Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
21335 Discussions

Simulation problem with simple edge detector

Altera_Forum
Honored Contributor II
1,460 Views

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
0 Kudos
7 Replies
Altera_Forum
Honored Contributor II
645 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
645 Views

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?
0 Kudos
Altera_Forum
Honored Contributor II
645 Views

 

--- 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
0 Kudos
Altera_Forum
Honored Contributor II
645 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
645 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
645 Views

 

--- 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;
0 Kudos
Altera_Forum
Honored Contributor II
645 Views

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

0 Kudos
Reply