OpenCores
URL https://opencores.org/ocsvn/scalable_arbiter/scalable_arbiter/trunk

Subversion Repositories scalable_arbiter

[/] [scalable_arbiter/] [trunk/] [rtl/] [verilog/] [debouncer.v] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 kendallc
/*
2
 * Copyright (c) 2008-2009, Kendall Correll
3
 *
4
 * Permission to use, copy, modify, and distribute this software for any
5
 * purpose with or without fee is hereby granted, provided that the above
6
 * copyright notice and this permission notice appear in all copies.
7
 *
8
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
 */
16
 
17
`timescale 1ns / 1ps
18
 
19
module debouncer #(
20
        parameter count = 1,
21
        parameter high_count = count,
22
        parameter low_count = count,
23
        parameter width = 1,
24
        parameter reset_value = {width{1'b0}}
25
)(
26
        input enable,
27
        input [width-1:0] in,
28
        output [width-1:0] out,
29
        output reg rising_pulse,
30
        output reg falling_pulse,
31
        output reg valid,
32
 
33
        input clock,
34
        input reset
35
);
36
 
37
`include "functions.v"
38
 
39
reg [width-1:0] in_reg;
40
reg [width-1:0] out_reg;
41
 
42
always @(posedge clock)
43
begin
44
        in_reg <= in;
45
end
46
 
47
// edge detector
48
wire rising;
49
wire falling;
50
 
51
assign rising = |(~in_reg & in);
52
assign falling = |(in_reg & ~in);
53
 
54
// counter width is the maximum size of the loaded value
55
parameter counter_width = max(flog2(count - 1) + 1,
56
        max(flog2(high_count - 1) + 1, flog2(low_count - 1) + 1));
57
 
58
reg [counter_width:0] counter;
59
reg [counter_width-1:0] counter_load;
60
wire counter_overflow;
61
 
62
assign counter_overflow = counter[counter_width];
63
 
64
// select counter value for rising or falling edge
65
always @(rising, falling)
66
begin
67
        case({rising, falling})
68
        'b11:
69
                counter_load = -count;
70
        'b10:
71
                counter_load = -high_count;
72
        'b01:
73
                counter_load = -low_count;
74
        default:
75
                counter_load = {counter_width{1'bx}};
76
        endcase
77
end
78
 
79
// the counter is reset on a rising or falling edge
80
// reset has priority over overflow, so the counter
81
// will not overflow until the input has been stable
82
// for a full count
83
always @(posedge clock, posedge reset)
84
begin
85
        if(reset)
86
                counter <= {counter_width{1'b0}};
87
        else
88
        begin
89
                if(rising | falling)
90
                        counter <= { 1'b0, counter_load };
91
                else if(enable & ~counter_overflow)
92
                        counter <= counter + 1;
93
        end
94
end
95
 
96
// output is gated by the counter overflow
97
assign out = out_reg;
98
 
99
always @(posedge clock, posedge reset)
100
begin
101
        if(reset)
102
                out_reg <= reset_value;
103
        else
104
        begin
105
                if(counter_overflow)
106
                        out_reg <= in_reg;
107
        end
108
end
109
 
110
always @(posedge clock, posedge reset)
111
begin
112
        if(reset)
113
        begin
114
                rising_pulse <= 1'b0;
115
                falling_pulse <= 1'b0;
116
        end
117
        else
118
        begin
119
                rising_pulse <= counter_overflow & ~out_reg & in_reg;
120
                falling_pulse <= counter_overflow & out_reg & ~in_reg;
121
        end
122
end
123
 
124
always @(posedge clock, posedge reset)
125
begin
126
        if(reset)
127
                valid <= 1'b0;
128
        else
129
                valid <= counter_overflow;
130
end
131
 
132
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.