1
\$\begingroup\$

I've done a bit of experimenting with Verilog recently, and I ran into a problem where it doesn't behave as I'd expect. In one of my modules, I have code like the following that is designed to simply track odd/even cycles, because I'm performing operations that take 2 cycles each:

reg even_cycle = 0;

always@(posedge clk)
begin
    even_cycle <= ~even_cycle;
    if(even_cycle)
        //do something
end

The expected behaviour: On the first clock cycle, even_cycle is flipped, which, due to it being a register should see it continue to show zero until the next cycle, where its new value of 1 will be clocked.

What really happens: On the positive edge of the first clock cycle, even_cycle is already set to 1

I'm sure I'm missing something obvious, but could anyone please explain this behaviour? It seems to go against my understanding of registers. How can a reg's value appear to be updated on the same cycle it's assigned?

As a bonus question, if I have a clock signal that I want to pass to a module conditionally, is the following a bad way of doing it? If so, is there a recommended way?

input clk_in; //always running

wire cond_clk;

assign cond_clk = some_condition ? clk_in : 0

When run in the simulator and I stop the clock (i.e the condition becomes false), cond_clk shows as a vertical line in the simulator, as if it's high for a tiny period at the beginning of the cycle.

\$\endgroup\$
3
  • \$\begingroup\$ Which line is doing something you didn't expect? The even_cycle <= ~even_cycle or the if(even_cycle) ? \$\endgroup\$
    – Ben Voigt
    May 9, 2023 at 21:37
  • \$\begingroup\$ For your bonus question, FPGA logic blocks are designed with "clock enable" signals, e.g. if (some_condition && posedge clk). Clock gating risks glitching, unless you use the clock gating features associated with global clock trees. Which is not a bad tradeoff -- the advantage of clock gating over clock enable is power-saving, and for that to be worthwhile, it has to affect a large amount of circuitry (hence global clock tree) \$\endgroup\$
    – Ben Voigt
    May 9, 2023 at 21:42
  • \$\begingroup\$ @BenVoigt Thank you, I will do some reading on that subject \$\endgroup\$
    – Triforcer
    May 9, 2023 at 22:15

1 Answer 1

1
\$\begingroup\$

The simulation behaves as it should. At the positive edge of clk, the nonblocking assignment is executed, updating the even_cycle signal with its new value, which is always the inverse of its previous value.

At time 0, you set even_cycle to 0 in the reg declaration line. It stays at 0 until the 1st positive edge of clk. At that time, even_cycle becomes 1.

Consider this simple code:

module tb;

reg clk = 0;
always #5 clk++;

reg even_cycle = 0;

always @(posedge clk)
begin
    even_cycle <= ~even_cycle;
end

initial #500 $finish;

endmodule

enter image description here

Assuming clk is 0 at time 0 and goes to 1 at time 5, even_cycle goes high at time 5 as well. It then remains at 1 until the 2nd positive edge of clk at time 15. This code models a positive-edge triggered flip flop.

\$\endgroup\$
3
  • \$\begingroup\$ Thanks, I think that confused me because it almost seems like the register behaves differently on the first cycle than on subsequent ones. Considering this normal behaviour, how might I ensure that even_cycle remains at zero for the first clock cycle as I was incorrectly anticipating it would? Do I have to use some additional logic to handle it? \$\endgroup\$
    – Triforcer
    May 9, 2023 at 22:07
  • \$\begingroup\$ @Triforcer toggle on falling edge of the clock \$\endgroup\$
    – jsotola
    May 10, 2023 at 0:51
  • \$\begingroup\$ Also: any process that is synchronous to a clock will see the old value of any signal that changes with the same rising edge. So if you output even_cycle to the console, the first value you should see in the log is 0, and any other logic that is synchronous to clk would also register even_cycle as 0 with the first rising edge. \$\endgroup\$ May 11, 2023 at 6:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.