Forum Discussion
Altera_Forum
Honored Contributor
9 years agoLatches in frequecny divider using fsm implementation
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 https://pastebin.com/mkw686h4
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 ps, ns;
reg out_change;
reg out;
reg 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? thanks19 Replies
- Altera_Forum
Honored Contributor
Hi Tricky, thank you for your reply.
I have seen some code examples where the signals in sensitivity list are written without any edge statements. Such code can be synthesized ? Why quartus doesn't raise any error if such implementation is not compatible with FPGAs? - Altera_Forum
Honored Contributor
--- Quote Start --- Hi Tricky, thank you for your reply. I have seen some code examples where the signals in sensitivity list are written without any edge statements. Such code can be synthesized ? Why quartus doesn't raise any error if such implementation is not compatible with FPGAs? --- Quote End --- Thats because those blocks will describe assignments for the variables in ALL paths through the block (ie. assigned in all ifs and else), so no latches are created. - Altera_Forum
Honored Contributor
OK, but as you said previously
FPGAs doesn't support both falling and rising edges of signal. is that means every verilog module targeted for FPGA can't have sensitivity list without stating the edge of the signal? Thanks - Altera_Forum
Honored Contributor
--- Quote Start --- OK, but as you said previously FPGAs doesn't support both falling and rising edges of signal. is that means every verilog module targeted for FPGA can't have sensitivity list without stating the edge of the signal? Thanks --- Quote End --- Your code is not clocked, it is level sensitive, hence the latches. If you wanted to be sentive to the edges, you would write:
This would create a double edge sensitive flop, which is not possible in FPGA. The following code is just level sensitive to the compiler, but not simulation as quartus will ignore the signals in the sensitivity list, and just use what is in the always block, so will not produce a flop:always @(posedge clk or negedge clk) begin if (clk = '1') //rising edge action else if (clk = '0') // falling edge action endalways @(clk) begin if (clk = '1' ) // stuff to do while clock is '1' else if (clk = '0') // stuff do while clock is '0' end - Altera_Forum
Honored Contributor
Hi Tricky,
Thank you for your reply. If I get it right, always @(clk) begin ... end or always @(*) are supported for compilation only but not for simulation and programming into FPGAs. Am I correct? Thanks - Altera_Forum
Honored Contributor
--- Quote Start --- Hi Tricky, Thank you for your reply. If I get it right, always @(clk) begin ... end or always @(*) are supported for compilation only but not for simulation and programming into FPGAs. Am I correct? Thanks --- Quote End --- Incorrect. They are a legitimate way of coding verilog, for creating logic or latches, which are both suitable for FPGAs. - Altera_Forum
Honored Contributor
Hi Tricky,
writing always@(clk) means it will execute the process for each changing in clk signal, in other words sesitivity for both rising or falling edges. However as you said FPGAs doesn't support dual edge flip flops. What am I missing? Sorry, I really don't get it when dual edge sensing is valid and when it's not. And why I don't get any synthesis errors if the HDL code is not suitable for the target device? - Altera_Forum
Honored Contributor
FPGAs do not support dual edge flip flops. Plus Synthesis tools (but not simulators) ignore the sensitivity list of the always block. Hence, if you write:
always @(clk) The synthesis tool ignores it, and treats it as always @(*) This is because synth tools have to infer logic from your code, and have to follow specific templates to generate specific logic. See https://www.altera.com/en_us/pdfs/literature/hb/qts/qts-qps-handbook.pdf , section 2-12 for recommended HDL coding styles. The problem with writing always @(clk) Is that in simulation it will behave like a dual edge flop, but as synthesis treats it as always @(*), the simulation behaviour and real hardware behaviour will not match. This is why you get warnings about latch generation when you may have a perfectly good simultion. - Altera_Forum
Honored Contributor
Thank you Tricky