Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16663 Discussions

Clocking Block not working correctly?

TuckerZ
New Contributor I
1,441 Views

Hello,

I am having a problem and want to make sure its not user error before chalking it up to a bug.  

I am designing a testbench and checking the status of a set of signals that are contained in an interface using a class and accessed by a method in that class.  That interface contains a clocking block that is used to access them. 

 

My interface looks like this: 

 

 

interface interface_name (
    input logic clk, 
    input logic in0, in1, in2, in3; 
); 

default clocking cb @(posedge clk); 
    input in0; 
    input in1; 
    input in2;
    input in3; 
endclocking

endinterface

 

 

When I simulate in Questa Intel FPGA Edition, I get the following screenshot. The clock is at the top. Followed by one of the non-clocked interface signals. The very bottom signal is the same signal inside of the clocking block. 

TuckerZ_0-1682615149934.png

 

The cursor shows where the posedge of the clock is and where the error occurs. The input sampling of the clocking block should mean that the value of the signal is sampled in the preponed region of that time slot. That value (1) should be used for any following statements executed in that time slot but the old value (0) is still being used. 

The code that uses the clock blocking signals looks like this: 

@ (posedge clk);
if (interface_name.cb.in0 == '0)    return '0;
else return '1; 

The above code is executing the if branch instead of the else branch. 

Am I not understanding something? 

 

0 Kudos
6 Replies
SyafieqS
Employee
1,412 Views

Assuming I understand correctly what you are doing, in your code snippet, you're using the clocking block signal interface_name.cb.in0 inside the @ (posedge clk) block. However, the clocking block signal is not guaranteed to have its value updated until the end of the clocking block. This means that if you're using the signal inside the @ (posedge clk) block, you may be getting the old value of the signal.


You can move the signal access outside of the clocking block and into a separate always block that triggers on the clock edge. For example:


always @(posedge clk) begin

 if (interface_name.in0 == 1'b0) begin

  // Do something if in0 is low

 end else begin

  // Do something else if in0 is high

 end

end


By doing this, you're ensuring that you're sampling the signal at the correct time (on the clock edge) and not relying on the timing of the clocking block.


0 Kudos
TuckerZ
New Contributor I
1,400 Views

When exactly does the end of the clocking block occur? 

0 Kudos
SyafieqS
Employee
1,338 Views

When exactly does the end of the clocking block occur? 

- clocking block remains active until the end of the block is reached which is 'endclocking' keyword


Note: Clocking block is only used to define the timing of the signals within the block. It does not actually sample or modify the signals themselves. The signal values are still sampled on the edges of the clock signal outside of the clocking block.


0 Kudos
TuckerZ
New Contributor I
1,330 Views

And you suggest to just remove the clocking block entirely from the code to avoid this race condition? 

0 Kudos
SyafieqS
Employee
1,246 Views

No, I'm not suggesting that you remove the clocking block entirely from your code. Clocking blocks are a powerful construct that can help ensure that signals are synchronized to the clock edge and can help prevent race condition

However, in some cases, you may want to use signals outside of the clocking block to avoid issues with signal updates. You can still use the clocking block to define the timing of the signals, but you can read the values of the signals outside of the block to ensure that you are getting the updated values.


0 Kudos
SyafieqS
Employee
1,193 Views

Let me know if there is any update.


0 Kudos
Reply