I'm trying to implement this debouncer circuit in Verilog. This is the code I got, and I believe it should work, but it doesn't. The problem is that the button_debounce
signal is always 0.
module divider(clk, reset, divded_clock_out);
input clk;
input reset;
output reg divded_clock_out;
reg [19:0]counter;
always @(posedge clk or negedge reset)
begin
if(!reset)
counter <= 0;
else
begin
if (counter == 999999)
counter <= 0;
else
counter <= counter + 1;
if (counter < 499999)
divded_clock_out <= 0;
else
divded_clock_out <= 1;
end
end
endmodule
module dff(clk, D, Q, reset);
input clk;
input reset;
input D;
output reg Q;
always @ (posedge clk or posedge reset)
begin
if(reset)
Q <= 1'b0;
else
Q <= D;
end
endmodule
module debounce(clk, button, button_debounce, reset);
input clk;
input reset;
input button;
output button_debounce;
wire [2:0]reg_wire;
dff reg1(clk, button, reg_wire[0], reset);
dff reg2(clk, reg_wire[0], reg_wire[1], reset);
dff reg3(clk, reg_wire[1], reg_wire[2], reset);
assign button_debounce = reg_wire[0] & reg_wire[1] & reg_wire[2];
endmodule
module debouncer_tb();
reg clk;
reg reset;
reg button;
wire divded_clock_out;
wire button_debounce;
initial begin
clk = 0;
reset = 0;
button = 0;
#10;
reset = 1;
button = 1;
end
always #10 clk=~clk;
divider uut(clk, reset, divded_clock_out);
debounce uut2(divded_clock_out, button, button_debounce);
endmodule
The divider works as expected, and I believe it's only a problem with the debouncer
module. For the simulation testbench, the output of the divider is correct and the output of the debouncer is always 0, and it should be 1 when the button input changes to 1.
When I run a simulation, I get the following compile warning:
debounce uut2(divded_clock_out, button, button_debounce);
|
xmelab: *W,CUVWSI : 1 input port was not connected:
xmelab: reset
The debounce
module has 4 ports, but you only connected 3 of them. Check your log files to see if you have a similar message.
Also, when I run the simulation, I see button_debounce
as X (unknown), not 0.
When I change:
debounce uut2(divded_clock_out, button, button_debounce);
to:
debounce uut2(divded_clock_out, button, button_debounce, ~reset);
I see button_debounce
go to 1, as desired. I added reset
to the connection list. Note that I inverted the reset signal because your dff
modules use an active-high reset, whereas the divider uses an active-low reset.
However, using connection-by-order, as shown above, is error prone. It is better to use connection-by-name:
debounce uut2 (
.clk (divded_clock_out),
.button (button),
.button_debounce (button_debounce),
.reset (~reset)
);