I am new to verilog and HDL.
I want to implement a N-frequency divider,
which count clock ticks (pos and neg) and start the counting mechanism from the first rising edge of the input clk.
In addition the clk divider has to support synchronous rst_n.
I am using Altera Quartus and the following code
module clk_divider_fsm
(
in_clk,
rst_n,
out_clk
);
input in_clk, rst_n;
output out_clk;
parameter prescaler = 10;
parameter BIT_DEPTH = `CLOG2(prescaler);
parameter S0 = 2'b00, S1 = 2'b01, S2 = 2'b10;
parameter CNT_RESET = {BIT_DEPTH{1'b0}};
//parameter CNT_FIRST = {BIT_DEPTH-1{1'b0}, 1'b1};
reg [1:0] ps, ns;
reg out_change;
reg out;
reg [BIT_DEPTH:0] cnt;
initial
begin
ps = S0;
ns = S0;
cnt = CNT_RESET;
out_change = 1'b0;
out = 1'b0;
end
always @ (in_clk)
begin
if(!rst_n)
ps = S0;
else
ps = ns;
// begin
// if(ns != ps)
// ps = ns;
// end
end
always @ (in_clk)
begin
case(ps)
S0: begin
if(in_clk === 1'b1)
begin
out_change <= 1'b1;
ns <= S1;
cnt <= CNT_RESET + 1'b1;
end
else
begin
out_change <= 1'b0;
cnt <= CNT_RESET;
ns <= S0;
end
end
S1: begin
if(in_clk === 1'b0)
begin
if(cnt == prescaler)
begin
cnt <= CNT_RESET + 1'b1;
out_change <= 1'b1;
ns <= S2;
end
else
begin
cnt <= cnt + 1'b1;
out_change <= 1'b0;
ns <= S2;
end
end
else
begin
out_change = 1'b0;
ns = S1;
cnt <= cnt;
end
end
S2: begin
if(in_clk == 1'b1)
begin
if(cnt == prescaler)
begin
cnt <= CNT_RESET + 1'b1;
out_change <= 1'b1;
ns <= S1;
end
else
begin
cnt <= cnt + 1'b1;
out_change <= 1'b0;
ns <= S1;
end
end
else
begin
out_change = 1'b0;
ns = S2;
cnt <= cnt;
end
end
default: begin
out_change <= 1'b0;
cnt <= CNT_RESET;
ns <= S0;
end
endcase
if(!rst_n)
begin
ns <= S0;
cnt <= CNT_RESET;
end
end
always @ (posedge out_change or negedge rst_n)
begin
if(!rst_n)
out <= 1'b0;
else
out <= ~out;
end
assign out_clk = (prescaler == 1) ? (in_clk & rst_n) : out;
endmodule
After synthesis I get warnings about latches used for cnt register.
What am I doing wrong?
Can you guide me with good practice tips to avoid such cases in the future or more elegant ways to implement those kind of RTL?
thanks