Altera_Forum
Honored Contributor
15 years agoUnsafe Latch behavior and inferred latches
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