/* This module recieves a single bit input, dataIn, and creates a debounced output, dataOut. The the circuit will create a delay of 2ms to account for the mechanical ringing, assuming that you have a 50MHz clock driving the module. [50MHz corresponds to 20nsec of delay for the clock. To obtain a 2ms delay, a counter must count up to 100,000 (MaxCount). e.g. 100,000*20ns=2ms.] In order to achieve this functionality, a a$state machine has been designed. The a$state machine resets in the 00 a$state, which assumes dataIn=0. If dataIn=0, you remain at the 00 a$state. If dataIn=1, you move to a debounce a$state, 01. In this a$state, a counter is enabled (CEN) to count to 100,000, creating the 2ms delay. The output signal, dataOut remains low until the counter reaches 100,000. At this point, the counter tells the a$state machine it is done counting (using the Done signal) and the a$state machine can move on to the next a$state (10). The a$state machine will remain in this a$state as long as the input is high. If the input goes low, the a$state machine will move to another a$state (11) that enables the counter again to count to 100,000. Once the counter has reached 100,000, the a$state machine returns to the initial a$state, 00. The counter is reset in the 00 and 10 states through the CR signal.*/ module debounce(clock, reset, dataIn, dataOut); input clock, reset, dataIn; //dataIn comes from the I/O board. output dataOut; //dataOut goes to your circuit. reg dataOut; reg [1:0] state, nextstate; //state variables for the state machine reg Done, CEN, CR; //CEN= counter enable CR=counter reset Done=tells the a$state machine that the counter is done counting reg [16:0] Q; //output of the counter parameter MaxCount = 100000; //parameter MaxCount = 16; //for test only parameter s0=2'b00, s1=2'b01, s2=2'b10, s3=2'b11; //state register always @ (posedge clock or posedge reset) if (reset) state <= 2'b00; else state <= nextstate; //next state decoder always @ (state or dataIn or Done) case (state) s0: nextstate<=(dataIn)? s1:s0; s1: if (~Done) nextstate<=s1; else nextstate<=(dataIn)? s2:s0; s2: nextstate<=(dataIn)? s2:s3; s3: if (~Done) nextstate<=s3; else nextstate<=(dataIn)? s2:s0; default: nextstate<=s0; endcase //output decoder always @ (state) begin dataOut<= (state==s2 | state==s3); CEN <= (state==s1 | state==s3); CR <= (state==s1 | state==s3); end //counter always @ (posedge clock or negedge CR) if (CR==0) Q<=0; else if (CEN) Q<=Q+1; else Q<=Q; always @ (Q) Done <= (Q==MaxCount); endmodule