Modelsim VHDL simulation seems to disobey the hold time principle

Status
Not open for further replies.

shaiko

Advanced Member level 5
Joined
Aug 20, 2011
Messages
2,644
Helped
303
Reputation
608
Reaction score
297
Trophy points
1,363
Activity points
18,302
Hello,
In my design I have this very simple synchronous process:

Code:
    counting_read_burst : process ( IN_CLOCK , IN_RESET_ASYNCHRONOUS ) is
    begin 
        if IN_RESET_ASYNCHRONOUS = '1' then
	   counter_selected_read_burst <= ( others => '0' ) ;
        elsif rising_edge ( IN_CLOCK ) then 
	   if [COLOR="#FF0000"]IN_VALID_INFORMATION = '1'[/COLOR] then
		if counter_selected_read_burst = selected_length_read_burst - 1 then
	         	counter_selected_read_burst <= ( others => '0' ) ;
		else
			counter_selected_read_burst <= counter_selected_read_burst + 1 ;    
		end if ;
           end if ;	
        end if ;        
    end process counting_read_burst ;

IN_VALID_INFORMATION is a signal that's also generated synchronously - so I expect "counter_selected_read_burst" to increment one cycle AFTER it rises to '1'.
Unfortunately, this doesn't happen:
counter_selected_read_burst increments on the same edge as IN_VALID_INFORMATION rises from low to high.

What's going on??
I'm completely baffled.
 

Attachments

  • Capture.PNG
    21.9 KB · Views: 64

Without the whole code, we can only guess
 

So take a guess...
Can you offer any explanation for this not being a bug ?
 

my guess is that it is based on how you generate IN_VALID_INFORMATION, which is not shown.
 

This kind of thing usually happens when you think IN_VALID_INFORMATION is synchronous to IN_CLOCK, but actually isnt. Maybe you created it using a clock that has a delta delay wrt IN_CLOCK, or you just used absolute times values to generate it, meaning it changes a delta before the clock edge.

Or maybe theres another problem.
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Nope.
The clock that drives "OUT_VALID" is absolutely the same one that drives "counter_selected_read_burst".
I moved the process above one hierarchy up ( just to see what happens ) - and it behaves properly!
This is very strange.

Maybe it has something to do with the timing resolution ? or the glbl.v file I'm using ?
 

This is why we need to whole code.
It's clearly a delta problem. Please post the code.
 

This is why we need to whole code.
It's clearly a delta problem. Please post the code.
I'll post it - but it'll take me some time.

For now, I managed to "fix" the code in a way that clearly points out it's a delta issue:

This causes faulty behavior:
Code:
counting_read_burst : process ( IN_CLOCK , IN_RESET_ASYNCHRONOUS ) is
    begin 
        if IN_RESET_ASYNCHRONOUS = '1' then
	   counter_selected_read_burst <= ( others => '0' ) ;
        elsif rising_edge ( IN_CLOCK ) then 
	   if IN_VALID_INFORMATION = '1' then
		if counter_selected_read_burst = selected_length_read_burst - 1 then
	         	counter_selected_read_burst <= ( others => '0' ) ;
		else
			counter_selected_read_burst <= counter_selected_read_burst + 1 ;    
		end if ;
           end if ;	
        end if ;        
    end process counting_read_burst ;

This works flawlessly:
Code:
temp_IN_VALID_INFORMATION  <= IN_VALID_INFORMATION ; -- added an intermediate signal (a pure wire) 

counting_read_burst : process ( IN_CLOCK , IN_RESET_ASYNCHRONOUS ) is
    begin 
        if IN_RESET_ASYNCHRONOUS = '1' then
	   counter_selected_read_burst <= ( others => '0' ) ;
        elsif rising_edge ( IN_CLOCK ) then 
	   if temp_IN_VALID_INFORMATION = '1' then
		if counter_selected_read_burst = selected_length_read_burst - 1 then
	         	counter_selected_read_burst <= ( others => '0' ) ;
		else
			counter_selected_read_burst <= counter_selected_read_burst + 1 ;    
		end if ;
           end if ;	
        end if ;        
    end process counting_read_burst ;
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…