forked from SJTU-YONGFU-RESEARCH-GRP/core
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparameterized_gray_counter.v
More file actions
executable file
·89 lines (84 loc) · 4.03 KB
/
parameterized_gray_counter.v
File metadata and controls
executable file
·89 lines (84 loc) · 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/**
* Parameterized Gray Code Counter
*
* This module implements a configurable Gray code counter that can count up or down.
* Gray code ensures only one bit changes between consecutive values, making it ideal
* for clock domain crossing, reducing glitches, and improving reliability.
*
* Key Features:
* - Configurable width: Any bit width via WIDTH parameter
* - Bidirectional: Count up or down based on COUNT_MODE
* - Initial value: Configurable starting value
* - Dual output: Both Gray code and binary representations
*
* Gray Code Benefits:
* - Single bit transitions: Reduces power consumption and glitches
* - CDC safety: Safer for clock domain crossing (reduces metastability)
* - Error detection: Multiple bit changes indicate errors
*
* Conversion:
* - Binary to Gray: gray = binary ^ (binary >> 1)
* - Maintained internally in binary for easy increment/decrement
*
* @param WIDTH Counter width in bits (default: 4)
* @param COUNT_MODE 0 = count up, 1 = count down (default: 0)
* @param INITIAL_VALUE Initial counter value on reset (default: 0)
*
* @input clk Clock signal
* @input rst_n Active-low synchronous reset
* @input enable Counter enable (high to count)
* @output gray_out[WIDTH-1:0] Gray code output (only one bit changes per count)
* @output binary_out[WIDTH-1:0] Binary counter value (for reference/convenience)
*/
module parameterized_gray_counter #(
parameter WIDTH = 4, // Counter width in bits
parameter COUNT_MODE = 0, // 0: Up counter, 1: Down counter
parameter INITIAL_VALUE = 0 // Initial counter value
)(
input wire clk, // Clock input
input wire rst_n, // Active-low synchronous reset
input wire enable, // Counter enable signal
output wire [WIDTH-1:0] gray_out, // Gray code output
output wire [WIDTH-1:0] binary_out // Binary counter value (for reference)
);
// ============================================================================
// Internal State
// ============================================================================
// Binary counter register: maintained internally for easy increment/decrement
// We convert to Gray code for output, but binary is easier to manipulate
reg [WIDTH-1:0] binary_count;
// ============================================================================
// Output Generation
// ============================================================================
// Convert binary count to Gray code using standard formula
// Formula: gray = binary ^ (binary >> 1)
// This ensures only one bit changes between consecutive values
assign gray_out = binary_count ^ (binary_count >> 1);
// Also provide binary output for applications that need it
assign binary_out = binary_count;
// ============================================================================
// Counter Logic
// ============================================================================
// Binary counter with synchronous reset and enable control
always @(posedge clk) begin
if (!rst_n) begin
// ====================================================================
// Reset State
// ====================================================================
// Initialize counter to configured initial value
binary_count <= INITIAL_VALUE;
end else if (enable) begin
// ====================================================================
// Count Operation
// ====================================================================
if (COUNT_MODE == 0) begin
// Up counting: increment binary counter
binary_count <= binary_count + 1'b1;
end else begin
// Down counting: decrement binary counter
binary_count <= binary_count - 1'b1;
end
end
// Note: If enable is low, counter holds current value
end
endmodule