Reputation: 21
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
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