Electronic – Verilog preventing latches

flipfloplatchverilog

I created a simple Verilog module that displays random numbers. This module has a counter that counts up at every clock edge and at the press of a button, whatever the number is in the counter at that time is displayed. Here is my code:

module counter (input wire in, input wire clock, input wire reset, output reg [3:0] number)
reg [3:0] cur_state;
reg [3:0] next_state;

always @ (posedge clock) begin
    if (reset) cur_state <= 4'b0;
    else cur_state <= next_state;
end

// next state function
always @ (*) begin
    next_state = cur_state + 4'b1;
end

// output
always @ (*) begin
    if (in) number = cur_state;
end

number[3:0] is sent to a display module to display the corresponding number. (Inputs are debounced properly.)

Everything works fine on the FPGA, but the program notifies me that I've used a latch in output. Is there any way to prevent this and implement the same behavior using a flip-flop?

Thank you.

Best Answer

Your problem lies in that you are describing an asynchronous circuit which requires its previous state.

// output
always @ (*) begin
    if (in) number = cur_state;
end

When in is high, all is well - number is assigned to the value of cur_state. However, what happens when in is low?

When in is low, number does not have a new value specified (i.e. via else) which means that you are inferring that it must hold its value. Whenever a combinational circuit is asked to hold its value, you get a latch.

The way to prevent latches then is to ensure that in every combinationally inferred logic, you fully define the assigned value to never require itself. You can do this in one of two ways.

 

First, if you don't care about the value when in is low, then you can assign some constant:

  // output
  always @ (*) begin
      if (in) begin
          number = cur_state; //If in is high, output the current state 
      end else begin
          number = 4'b0000; //If in is low, output is don't care so avoid latch by assigning value
      end
  end

 

Second, if you need the output to hold its state, then you need to make it a clocked process:

// output
always @ (posedge clock) begin
    if (in) number = cur_state;
end

Now that it is synchronous, you can have the output hold its state because you are now inferring a flip-flop. The down side to this is you have a 1 cycle latency from when you change the in signal to when the number value updates.