`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    13:49:28 11/22/2006 
// Design Name: 
// Module Name:    debounce 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////

module debouncer( btnin, bstate, btndown, btnup, clk, rst);

input  btnin;
output bstate;

output btndown, btnup;

input clk;
input rst;



reg[19:0] debounce;

reg btnout;

reg bsync0, bsync1;

always @(posedge clk)
	bsync1 <= btnin;
	
always @(posedge clk)
	bsync0 <= bsync1;
	
reg bstate;
reg bstateold;


wire idle = (bstate == bsync0);

wire debmax = &debounce;

assign btndown = bstate & (bstateold ^ bstate);
assign btnup = ~bstate & (bstateold ^ bstate);	

	
always @(posedge clk or posedge rst)
	begin
		if (rst)
			begin
				bstate <= 1'b0;
				bstateold <= 1'b0;
				debounce <= 0;
			end
		else
			begin
				if (idle)
					begin
						debounce <= 0;
						bstateold <= bstate;
					end
				else
					begin
						if (debmax)
							begin
								bstateold <= bstate;
								bstate <= ~bstate; 
							end
						else
							begin
								debounce <= debounce + 1;
							end
					end
			end
	end	

endmodule
