how to do an action every xth clock pulse?

Status
Not open for further replies.

srinpraveen

Member level 2
Hi guys I have a very basic doubt. I want to know how to do this in verilog. I want to do a particular action every xth clock pulse. How do i incorporate this in verilog? Some ppl say I need to use a counter but lets say I need to do a particular action for every 4th rising edge of the clock pulse, then lets say I introduce a counter. The counter counts upto 4. And then the action takes place. But this action takes place at the 4th rising edge of the clk pulse alone. I want the action to get repeated at the 8th rising edge, 12th edge, 16th edge etc...I can't be using x number of counters for this right?

I tried using the mod operator as in if(counter%4==1'b0)....... in a manner we use in C, C++. But as a matter of fact, the mod operator may not throw a simulation error but on the other hand, does not get synthesised in design vision. In other words the mod operator is not synthesisable anyway.

Does everbody understand my question?And if anybody knows about this, can they provide a simple solution to this?

lostinxlation

Reset the counter at every xth clock pulse.

srinpraveen

Member level 2
reseting the counter is a good idea...But the problem is capturing the xth rising edge....how do we write a condition for that? I am forced to use the mod operator which is not synthesis-friendly... for instance to capture the xth ege point, i am forced to use syntax like if(counter%x==0)....

is there a workaround for this? Am I understanding your reply correctly? If am not, then kindly pls elaborate your explanation so that it will be help me understand this a bit better..i assume ur saying sth like
always@(posedge clk)
begin
counter<=counter+1;
if(counter==4)
counter<=0;

Is this understanding right? If not, then would you suggest a modification to this understanding?

lostinxlation

how do we write a condition for that? I am forced to use the mod operator which is not synthesis-friendly... for instance to capture the xth ege point, i am forced to use syntax like if(counter%x==0)....
You can do the same thing with a resettable counter and a comparator.

srinpraveen

srinpraveen

Points: 2

srinpraveen

Member level 2
You can do the same thing with a resettable counter and a comparator.

What you told corresponds to this piece of code that i wrote above right? (shown again below for persual)
always@(posedge clk)
begin
counter<=counter+1;
if(counter==1'd4) --->counter compares to see if 4 has been reached)
counter<=0; ----> counter reset

permute

that is every 5th cycle
eg, it counts 0,1,2,3,4,0,1,2,3,4,0,1,2,3,4...

you either need to reset to 1, or reset at 3.

srinpraveen

srinpraveen

Points: 2

srinpraveen

Member level 2
@permute
ya i got it buddy...but reseting to 3 won't solve the problem..resetting to 1 is correct...And ya instead if i change the if condition to if(counter==1'd3) then it will be every 4th clock edge...yeah i got the pt buddy...

@lostinxlation and @permute ---> tks for the assistance

permute

(reset _at_ 3, not reset _to_3)

you can really compare to any value that the counter can reach. it just places the output in a different coset. eg, clocks 0,4,8,12 vs 1,5,9,13 vs 2,6,10,14 vs 3,7,11,14. this can be important if use this method in several modules.

srinpraveen

srinpraveen

Points: 2

Jack// ani

This is what your code should look like:

Code:
module clock(bufclk);
input bufclk;

reg [2:0] clkreg = 3'b000;
reg divclk = 1'b0;

always@(posedge bufclk)
begin
clkreg = clkreg + 1;
if (clkreg == 4)
begin
clkreg = 0;
divclk = ~ divclk;
end
end
endmodule

Last edited:
srinpraveen

srinpraveen

Points: 2

srinpraveen

Member level 2
@all tks guys..that has cleared my doubts...and jack, tks for explaining with a model code...i got the point pretty clearly now..

permute

jack's code generates a divided clock, and divides by a factor of 8. Further, it uses the generally bad practice of using blocking assignment in verilog in synchronous processes.

your original code in post 5 was closer to what should be used, especially for FPGAs.

yanzixuan

Member level 3
Code:
reg [ 3: 0] cnt;

parameter   [ 3: 0] N_CYC   = 4;

always@(posedge clk or negedge rst_n) begin
if (~rst_n) cnt <= 0;
else  begin
if (cnt == (N_CYC - 1))
cnt <= 0;
else
cnt <= cnt + 1;
end
end

wire n_cyc_en    = (cnt == (N_CYC - 1));

Jack// ani

True in general, but not necessarily true if you're using blocking statement for clock division purpose. If you're curious to learn how any why, refer to Gotcha # 29 in Verilog and SystemVerilog Gotchas.

Here is short quote from the book:

Gotcha 29: Sequential logic that requires blocking assignments

Gotcha: I'm following the recommendations for using nonblocking assignments in sequential logic, but I still have race conditions in simulation.
Synopsis: When modeling clock dividers, the RTL synthesis design guidelines don't always apply.

srinpraveen

Member level 2
thanks guys for the valuable inputs

Status
Not open for further replies.