lili
lili

Reputation: 21

Block of code inside always block is being executed without the input changing in the sensitivity list

Whenever the input to the sensitivity list is a variable (which is an input to the module; a button on the FPGA) the block of code gets executed regardless of the fact whether the value of this variable has changed or not, even though the block of code inside the always block should only be executed when the value of the variable given to it as a parameter in its sensitivity list changes; hence being called sensitivity list.

The block of code is as follows:

always @(in)
  begin
    count = count + 1;
  end

in: input taken from a button on the FPGA

Is our block of code wrong in some way, or should the sensitivity list only take posedge or negedge?

Upvotes: 1

Views: 717

Answers (1)

user7301963
user7301963

Reputation:

I'm not familiar with the rules/practices of writing asynchronous logic, but here's my 2 cents on dealing with button presses:

Try writing a debounce module to detect when the button is pressed, then use the result of the debounce module as the enable signal for your counter. The sensitivity list of the counter in this case would be based on posedge clk.

Here's an explanation for why you need the debounce module.

The debounce module works as follows: let's say to register a button press the button is held down for 3ms and released for another 3ms. (Feel free to play with the time.) Therefore, we need two counters: pressed and released. The pressed counter counts to 3ms then sets the condition to allow the release counter to start counting. Once the release counter has reached 3ms, then the button has been registered as pressed.

module debounce(
  clk,
  button_input,
  button_pressed
    );

  // Input and output ports
  input clk, button_input;
  output button_pressed;

  reg button_pressed;

  // Signals for pressed and released counters
  reg [15:0] pressed_out, pressed_next_out, released_out, released_next_out;
  reg pressed_enable, pressed_reset, released_enable, released_reset;
  reg pressed_ok, released_ok;

  // Counter for when button is pressed down
  // Increment counter
  always @ (*) begin
    if (button_input) begin
      pressed_next_out = pressed_out + 1'b1;
     end else begin
       pressed_next_out = 16'h00000;
    end     
  end

  // Flop incremented value
  always @ (posedge clk) 
     pressed_out <= pressed_next_out;

  // Check if button was pressed (3ms) 
  always @ (posedge clk) begin
     if (&pressed_out) begin
        pressed_ok <= 1;
     end else if (released_ok) begin
        pressed_ok <= 0;
     end
  end

    // Counter for when button is released
    // Increment counter 
   always @ (*) begin
     if (~button_input && pressed_ok) begin
       released_next_out = released_out + 1'b1;
      end else begin
        released_next_out = 16'b0;
     end        
   end

    // Flop incremented value
    always @ (posedge clk)
       released_out <= released_next_out;

    // Check if button was released (3ms)
    always @ (posedge clk) begin
        if (&released_out) begin
           released_ok <= 1;
        end else begin
           released_ok <= 0;
        end
    end

    // Check if button was pressed and released
    always @ (posedge clk) 
       button_pressed <= pressed_ok && released_ok;

endmodule

Upvotes: 1

Related Questions