Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Very strange simulation behavior

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,

My VHDL testbench has a simulated clock mux described as follows:
Code:
entity simulated_clock_mux is 

port 
(
    IN_CLOCK_0  :   in  std_logic ;  
    IN_CLOCK_1  :   in  std_logic ;
    IN_CLOCK_2  :   in  std_logic ;
    IN_CLOCK_3  :   in  std_logic ;
    IN_SELECT    :   in  std_logic_vector ( 1 downto 0 ) ;
    
    OUT_CLOCK   :   out  std_logic   
) ;  

end entity simulated_altclkctrl_video ;

architecture simulated_clock_mux of clock_mux is 

signal clock_vector : std_logic_vector ( 3 downto 0 ) ;

begin

    clock_vector <= IN_CLOCK_3 & IN_CLOCK_2 & IN_CLOCK_1 & IN_CLOCK_0 ;
    OUT_CLOCK <= clock_vector ( to_integer ( unsigned ( IN_SELECT ) ) ) ;

end architecture simulated_clock_mux ;

The above component is instantiated in my design and "clock_mux_out" is used to drive a synchronous process :
Code:
simulated_clock_mux_inst : simulated_clock_mux

port map
(
 IN_CLOCK_0 => simulated_clock_0 ,
 IN_CLOCK_1 => simulated_clock_1 ,
 IN_CLOCK_2 => simulated_clock_2 ,
 IN_CLOCK_3 => simulated_clock_3 ,
 IN_SELECT  => clock_selector ,
       
 OUT_CLOCK => clock_mux_out   
) ;

process ( clock_mux_out , reset ) is 
begin
 if reset = '1' then	
    some_registered_signal <= '0' ;
 elsif rising_edge ( clock_mux_out ) then
    some_registered_signal <= some_signal ;
 end if ;
end process ;

When I observe the waveform - it's twilight zone:

"some_registered_signal" isn't delayed by a clock cycle as I expected it to be - it's a direct copy of "some_signal" !

I go back to my code, omit the simulated clock mux - and drive the "clock_mux_out" signal directly by one of the input clocks:
Code:
--simulated_clock_mux_inst : simulated_clock_mux

--port map
--(
-- IN_CLOCK_0 => simulated_clock_0 ,
-- IN_CLOCK_1 => simulated_clock_1 ,
-- IN_CLOCK_2 => simulated_clock_2 ,
-- IN_CLOCK_3 => simulated_clock_3 ,
-- IN_SELECT  => clock_selector ,
       
-- OUT_CLOCK => clock_mux_out   
--) ;
   
clock_mux_out <= simulated_clock_0  ;

The problem goes away.

What's going on ?
 

I've seen issues like this due to delta cycle delays and scheduling problems between blocks when a clock is run through some logic and/or even through hierarchical blocks. I've never sat down and figured out exactly the instances where it fails to work and how they relate to the spec, as I've only run across the problem a couple of times. Once after modifying some code I inherited and once recently when a colleague brought this problem up in IP code where they had modified the clocking scheme.

As you haven't shown the some_signal generation I can only surmise it is on one of the simulated_clock_# domains and is not clocked by the clock_mux_out output. Which is why you would see such a problem the clock mux assignment is causing a scheduling event that moves the clock past the delta cycle that the data scheduling event takes place. If you add an after to the some_signal assignment you'll see it start working (This might be the only way you can fix this, though I'm no VHDL expert).
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
"some_registered_signal" isn't delayed by a clock cycle as I expected it to be - it's a direct copy of "some_signal" !
Your have described a Dff with "clock_mux_out" as clock. Why would you expect a delayed by a clock cycle signal ? It will behave as an output signal from a Dff. If it changes in the falling edge, then it will not notice it.
 

I assume that some_signal is generated on one of the source clocks? if so you have a delta problem.
Remember that each signal assignment counts as a delta cycle. So clock_mux_out is delayed by 3 deltas WRT simulated_clock_X

so anything that is clocked on simulated_clock_X will have already changed by the time the clock_mux_out rising edge, propogating the signal to make your DFF look like a wire. The best part is - this is a simulation/synthesis missmatch as the hardware will work as expected (apart from the clock muxing issues - not really a good idea in FPGA).

Solution - synchronise some_signal in the clock_mux_out domain by passing it through the same number of signals as the clocks go through:

Code:
a <= ip;
b <= a;
some_signal <= b;  -- 3 delta delay

or just dont mess around re-routing clock signals in your testbench. It can be a mess!
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Your have described a Dff with "clock_mux_out" as clock. Why would you expect a delayed by a clock cycle signal ? It will behave as an output signal from a Dff. If it changes in the falling edge, then it will not notice it.
mmm, because this is how registered signals behave...
Don't know why you mention the falling edge edge in this context - so I'll just pretend I didn't see it.

ads-ee,
As you haven't shown the some_signal generation I can only surmise it is on one of the simulated_clock_# domains and is not clocked by the clock_mux_out output.
Actually,
it is...

TrickyDicky,
I assume that some_signal is generated on one of the source clocks?
Correct.
The rest of your explanation clears things up. Thanks!

I wonder if such behavior is also prevalent with Verilog.
If so - it may prove disastrous to ASIC verification.
 

shaiko said:
I wonder if such behavior is also prevalent with Verilog.
If so - it may prove disastrous to ASIC verification.
Verilog doesn't have the same delta cycle stuff under the hood like VHDL for behavioral code, though you can run into similar issues with routing clocks around your design like this. I usually only see this in the case of testbench signal generation, which I either use an clocked always block to generate the stimulus into the DUT or I just delay the signals that go to the DUT with #1 before applying the signals (when I'm generating stimulus in a task). I normally don't use the opposite edge of the clock as that requires that I "think" about the relationship between the DUT inputs and the rest of the logic as they are phase shifted by 180 degrees.

e.g.

Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// the code in the task will result in a DUT seeing the leading edge of the input_signal.
reg clk = 0;
initial begin
  forever #5 clk = ~clk;
end
 
reg input_signal;
 
task gen_input;
begin
  @(posedge clk);
  input_signal = 1;
end
endtask;
 
dut  dut (
  .clk          (clk),
  .input_signal (input_signal)
);
 
initial begin
#100;
gen_input;
#100;
$stop



In the case of ASIC verification your clock signal are a bunch of ASIC clock buffer primitives that aren't coded like the behavioral description that exhibits the problem you are seeing, the entire tree is implemented and all the delays are annotated.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
the old 'delay by 1' trick solves any issue in verilog. for verification, it can be an issue if you are doing functional verification. for physical and gate level simulation, it is typically fine.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top