I have two clocks, clk0 and clk1. I want a counter to count on posedge of clk0 but reset at posedge of clk1. The important thing to note is that the reset should occur only on the posedge and not when clk1 is high. So the below code is not possible.
always @(posedge clk0 or posedge clk1)
begin
if (clk1)
count <= 0;
else
count <= count + 1;
end
We cannot drive the counter from two always blocks as well. So the below is not possible:
always @ (posedge clk0)
begin
count <= count + 1;
end
always @ (posedge clk1)
begin
count <= 0;
end
So my question: What offers a similar functionality like
always @(posedge clk0 or posedge clk1)
begin
if (posedge clk1)
count <= 0;
else
count <= count + 1;
end
And is synthesizable?
I want a counter which counts on posedge of clk0 and resets on posedge of clk1. clk0 is faster than clk1 by an order of magnitude. The design needs to be synthesizable.
You need to transfer the 'event' from clk1 to clk0. This is a clock domain crossing issue and thus requires synchronization.
reg clk1_meta,clk1_sync,clk1_prev;
always @(posedge clk0 or negedge reset_n) // async low reset as example
begin
if (!reset_n)
begin
clk1_meta <= 1'b0;
clk1_sync <= 1'b0;
clk1_prev <= 1'b0;
counter <= 'b0;
end
else
begin
// transfer clk1 to clk0
clk1_meta <= clk1;
clk1_sync <= clk1_meta;
// Now we have a safe signal: clk1_sync
clk1_prev <= clk1_sync;
// A rising edge is when clk1_sync1 is high but previously it was low
if (clk1_sync==1'b1 && clk1_prev==1'b0)
counter <= 'b0;
else
counter <= counter + 1;
end
end
There is an unavoidable delay of ~2 clk0 clock cycles before the clk1 arrives in the clk0 domain because of the synchronisation.