- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hey Everyone,
I am a little confused on how Quartus decides if something is an actual latch or an inferred latch. For example in the following code, latch_counter and control_word_register are treated as inferred latches, but counter seems to be treated as a register.module prog_counter (reset, ceb, write, data_in, clk, load, data_out,trigger);
input trigger;
input reset;
input ceb, write, load;
input data_in;
input clk;
output data_out;
//declare the control word
reg control_word_register;
reg disable_CWR; //Used to disable the CWR
//declare the counter with 8 bits
reg counter;
reg latch_counter;
//flag for first clk pulse after loading in value of counter
reg flag_counter;
//flag for half count cycle
reg flag_half_counter;
//to write control word into counter
//for control_word, bit 2 reprsents enable,
//bits 1 and 0 represent counter mode
//this also latches in the counter value.
always @(ceb or write or reset or load or data_in or disable_CWR)
begin
//Load control word
//Pin Config: ceb:low, write:high, load:low, reset:low
if (~ceb & write & ~load & ~reset)
control_word_register = data_in ;
//Load Counter Value
//Pin Config: ceb:low, write:low, load:high: reset:low
else if (~ceb & ~write & load & ~reset)
latch_counter = data_in;
//Timer Enable - Prepare timer for loading control word and latch
//Pin Config: ceb:high, reset:low
else if (ceb & ~reset)
begin
//reset the control word counter
control_word_register = 3'd0;
//reset the latch
latch_counter = 8'd0;
end
else if (disable_CWR)
control_word_register = 1'd0;
end
//to counter for counter
always @(posedge clk or posedge reset)
begin
if(reset)
begin
disable_CWR <= 0;
flag_counter <= 0;
counter <= 0;
flag_half_counter<=0;
end
else
begin
if(control_word_register) //counter is enabled
begin
if(control_word_register == 2'b00) //this if for one shot mode
begin
if(~flag_counter)
begin
counter <= latch_counter;
flag_counter <=1;
end
else
begin
if(counter == 8'hff)
begin
//to stop counter for one shot mode
disable_CWR <= 1;
flag_counter <=0;
end
else
counter <= counter + 1;
end
end
else if (control_word_register == 2'b01) //waveform generator mode
begin
if(~flag_counter)
begin
counter <= latch_counter;
flag_counter <= 1;
end
else
begin
if(counter == 8'hff)
flag_counter <= 0;
counter <= counter + 1;
end
end
else if(control_word_register == 2'b10) //this if for the 50% duty cycle waveform generator
begin
if(~flag_counter)
begin
counter <= latch_counter;
flag_counter <= 1;
end
else
begin
if (counter == {1'b0,latch_counter})
begin
flag_half_counter <= ~flag_half_counter;
counter <= counter - 1;
end
else
if (counter == 0)
flag_counter <= 0;
else
counter <= counter - 1;
end
end
else if(control_word_register == 2'b11)//this is for triggered pulse generator mode
begin
if(~flag_counter)
begin
//If we aren't currently sending out a pulse, then keep the counter loaded and ready
//this also resets the counter after a successful pulse is generated so that we will be ready for the next trigger
counter <= latch_counter;
if(trigger)
flag_counter <= 1;
else
flag_counter <= 0;
end
else
if(counter == 8'hff)
begin //stop counter for triggered pulse mode
flag_counter <= 0;
end
else
counter <= counter + 1;
end
end
end
end
assign data_out = (
((counter == 8'hff) & (control_word_register == 2'b00) & flag_counter) |
((counter == 8'hff) & (control_word_register == 2'b01)) |
(flag_half_counter & (control_word_register == 2'b10))|
((counter != 8'hff) & (control_word_register == 2'b11) & flag_counter)
);
endmodule
I get warnings about the former two being inferred, and then get warnings like: Warning: Latch prog_counter:inst|control_word_register has unsafe behavior
Warning: Ports D and ENA on the latch are fed by the same signal rst
Warning: Latch prog_counter:inst|control_word_register has unsafe behavior
Warning: Ports D and ENA on the latch are fed by the same signal rst
Warning: Latch prog_counter:inst|latch_counter has unsafe behavior
Warning: Ports D and ENA on the latch are fed by the same signal rst
Warning: Latch prog_counter:inst|latch_counter has unsafe behavior
Warning: Ports D and ENA on the latch are fed by the same signal rst
Warning: Latch prog_counter:inst|latch_counter has unsafe behavior
Warning: Ports D and ENA on the latch are fed by the same signal rst
Warning: Latch prog_counter:inst|latch_counter has unsafe behavior
Warning: Ports D and ENA on the latch are fed by the same signal rst
Warning: Latch prog_counter:inst|latch_counter has unsafe behavior
Warning: Ports D and ENA on the latch are fed by the same signal rst
Warning: Latch prog_counter:inst|latch_counter has unsafe behavior
Warning: Ports D and ENA on the latch are fed by the same signal rst
Warning: Latch prog_counter:inst|latch_counter has unsafe behavior
Warning: Ports D and ENA on the latch are fed by the same signal rst
Warning: Latch prog_counter:inst|control_word_register has unsafe behavior
Warning: Ports D and ENA on the latch are fed by the same signal rst
Warning: Latch prog_counter:inst|latch_counter has unsafe behavior
Warning: Ports D and ENA on the latch are fed by the same signal rst
the thing is I want to treat latch_counter and control_word_register as storage anyway, so why are they being inferred? is there way a way to force quartus to treat them as registers? If I run a simulation of the circuit, after the latch_counter is loaded correctly and the load pin is pulled low, the latch resets to 0, but I haven't a clue why. Any input is greatly appreciated. Thanks
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Look at what is in your process sensitivity list. If you write a function that responds to reset and posedge clk then it will most likely be a register. If it responds to other stuff and has incomplete in/then statements it may fold it into a latch.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Look at what is in your process sensitivity list. --- Quote End --- In synthesized code, it's almost meaningless what's in the sensitívity list of a combinational process, although the compiler issues warnings about missing signals to keep compatibilty with simulation results. It's the pure logic equations that actually matter. control_word_register and latch_counter are assigned in a combinational (or "level sensitive") process, so latches are created. The behaviour is unsafe, because logical combinations of the same signals are generating different latch states. Unavoidable glitches in the generated logic make the latch state possibly unpredictable. flag_counter and counter are in contrast assigned in a synchronous (edge-sensitive) process and thus synthesized as clockes DFFs.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you both for the replies, I can see now why the latches are created.
FvM: --- Quote Start --- It's the pure logic equations that actually matter. control_word_register and latch_counter are assigned in a combinational (or "level sensitive") process, so latches are created. The behaviour is unsafe, because logical combinations of the same signals are generating different latch states. Unavoidable glitches in the generated logic make the latch state possibly unpredictable. --- Quote End --- is there a way fix the unsafe behavior in the above code?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- is there a way fix the unsafe behavior in the above code? --- Quote End --- You should find an alternative way to achieve the intended behaviour. Actually I don't undertstand the meaning of the present code, e.g. three different cases of reset. Finding a synchronous solution would be preferable, of course.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As always, I should probably just wait for FvM to answer questions. You are correct, but I do find that sensitivity lists do shed light into what the original coder was trying to accomplish. If they have just edges of reset and clocks in the list is shows they intended to write a ff, if they have other stuff in there it shows they are trying to write combinational logic. Although now I am just writing stuff to cover up my incorrect first post...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I didn't suggest to ignore sensitivity lists, I'm mostly filling them up as required by the VHDL standard. I just wanted to prevent jumping into conclusion about the present problem.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello.
I forgot to assign all the cases in a case control in a always @(*), so latches are inferred. OK, I understand that, no problem. But, with the inferred latches present I get both LE count and fmax 10% better than with the inferred latches eliminated. Is the TimeQuest timing analyzer to believe in this case?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes and no. Timequest is only able to analyse registers, not latches. So latches could present all sorts of problems.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page