1
votes

I have an always block that involves a switch and a key. When I have only the key in the sensitivity list, it behaves fine (only executes the code once then exits the block). When I add the switch to the sensitivity list, it goes crazy and seems to loop indefinitely while I'm holding the key down, even though I only have it trigger on negedge of the key press.

I'm trying to implement a counter that only increments once on each key press.

Here is the working code with only the key in the sensitivity list (sw[1] is to indicate whether it is counting up or down):

always @ (negedge key[2]) begin
  if (~key[2]) 
      begin
        if (sw[1] == 0) begin
          if (p3ctr == 15) p3ctr = 0;
          else p3ctr = p3ctr + 1;
        end
        else if (sw[1] == 1) begin
          if (p3ctr == 0) p3ctr = 15;
          else p3ctr = p3ctr - 1;
        end
    end
end

Here is the broken code (I'm using sw[7] to reset the counter when it gets switched up. This code loops indefinitely while key[2] is held down)

always @ (negedge key[2] or posedge sw[7]) begin
  if (~key[2]) 
      begin
        if (sw[1] == 0) begin
          if (p3ctr == 15) p3ctr = 0;
          else p3ctr = p3ctr + 1;
        end
        else if (sw[1] == 1) begin
          if (p3ctr == 0) p3ctr = 15;
          else p3ctr = p3ctr - 1;
        end
    end
  else begin
    p3ctr = 0;
  end
end

I thought the code in an always block only gets executed once when a signal in the sensitivity list changes, but apparently that isn't the case.

Any idea how I can get this code to execute only once on each key press so the counter behaves properly?

Thanks!

1
What exactly do you mean by "goes crazy"? Does this happen in simulation as well? You are performing simulations, aren't you? - user1619508

1 Answers

2
votes

I'm assuming the issue is being seen when running on a FPGA; a pure simulation would appear fine. The synthesis tool is assuming the first if is asynchronous logic and the else condition is treated as synchronous logic as that is the proper coding style. In the provided code the first condition is if (~key[2]) which means the synthesis tool will treat negedge key[2] as active low asynchronous logic. Start with the reset condition if (sw[7]) and you should get the desired result.

always @ (negedge key[2] or posedge sw[7]) begin
  if (sw[7]) begin
    p3ctr <= 0;
  end
  else begin
    if (sw[1] == 0) begin
      if (p3ctr == 15) p3ctr <= 0;
      else p3ctr <= p3ctr + 1;
    end
    else if (sw[1] == 1) begin
      if (p3ctr == 0) p3ctr <= 15;
      else p3ctr <= p3ctr - 1;
    end
  end
end

Note: best practice to use non-blocking assignments (<=) with flops. Blocking assignment (=) is for combination logic.