2
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ always @ (*) begin if (in) number = cur_state; what happens when in is low? \$\endgroup\$ – Tom Carpenter Dec 13 '16 at 7:42
  • \$\begingroup\$ The previous value stored in number is retained. \$\endgroup\$ – HelperKing Dec 13 '16 at 7:48
  • \$\begingroup\$ And what does that infer in a combinational circuit? \$\endgroup\$ – Tom Carpenter Dec 13 '16 at 7:49
3
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ A clocked process should use a nonblocking asignment: if (in) number <= cur_state; \$\endgroup\$ – toolic Dec 13 '16 at 13:18
  • 1
    \$\begingroup\$ @toolic makes no difference in the code above. There's nothing to say that non-blocking must be used for clocked processes. Mixing the two should be avoided. \$\endgroup\$ – Tom Carpenter Dec 13 '16 at 13:38
1
\$\begingroup\$

The Combination of @Tom Carpenter and @toolic answers are almost correct. You need the non-blocking assignments if you would like to avoid simulation issues of combinational events happening after sequential events. Non-blocking assignment makes sure of that.

Another thing that is important to add is that the in input, is an asynchronous signal, and therefore if sampled, has to be sampled through a minimum of a double-Flop synchronizer.

\$\endgroup\$
1
\$\begingroup\$

I have re-written your code with a single register for holding the state of your FSM.

module counter (input wire in, input wire clock, input wire reset, output reg  number);
reg  cur_state;
reg  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 + 1'b1;
end

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

This is how your code is synthesized using Yosys

enter image description here

This makes sense, since we are describing a FSM with a single register [Single 1 flip flop] to store the state and at every clock positive edge the input into this flip flop is some combinational circuit output [Which adds 1 to the current state].

This is described with these two functional blocks

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 + 1'b1;
end

The main issue now is in the final DLatch that is holding your output

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

This is because the above code block is describing a DLatch. Whenever IN == 1 let the output = the current state, and Whenever IN ==0 dont change the output.

This is translated into a Dlatch at which the gate of the latch [The EN] is connected to the input IN and the input of this DLatch is connected to the current state.

As mentioned above you can fix this misinterpretation using an else statement in the last always block

always @ (*) begin
    if (in) number = cur_state;
    else number=0;
end 

Now your this is how the code is synthesized. You can see that the output is now driven by an AND gate not a latch.

enter image description here

I am pretty sure the above answers already mentioned this but i think looking into how your circuit is synthesized makes a huge difference.

\$\endgroup\$
  • \$\begingroup\$ (FPGAs noob here) If I don't care about the value of number when in is low, can I assign it 4'bx as constant value, to make it explicit I don't care about it? If so, although I don't care about it, what could be the "real" output value? There would be any difference if I use 4'bz to set it to high impedance, or is not recommended here? \$\endgroup\$ – Piranna Oct 23 at 9:09
  • \$\begingroup\$ EDIT: according to stackoverflow.com/q/29451175/586382, seems its support depend of the synthetizer, and in general it's better to optimice the Karnaugh maps by hand to have full control of the output instead of have undefined behaviour. \$\endgroup\$ – Piranna Oct 23 at 9:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.