forked from SJTU-YONGFU-RESEARCH-GRP/core
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfigurable_comparator.v
More file actions
executable file
·135 lines (128 loc) · 5.5 KB
/
configurable_comparator.v
File metadata and controls
executable file
·135 lines (128 loc) · 5.5 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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/**
* Configurable Comparator
*
* This module implements a configurable comparator that can perform various
* comparison operations on two operands. It supports both signed and unsigned
* comparison modes, making it suitable for arithmetic and logical operations.
*
* Key Features:
* - Multiple operations: 6 different comparison operations
* - Signed/unsigned mode: Runtime selectable comparison mode
* - Configurable width: Any bit width via WIDTH parameter
* - Single-bit output: Boolean result of comparison
*
* Comparison Operations:
* - EQUAL (000): a == b
* - NOT_EQUAL (001): a != b
* - LESS_THAN (010): a < b
* - LESS_EQUAL (011): a <= b
* - GREATER_THAN (100): a > b
* - GREATER_EQUAL (101): a >= b
*
* Signed vs Unsigned:
* - Unsigned (signed_mode=0): Standard unsigned comparison
* - Signed (signed_mode=1): Two's complement signed comparison
* - Signed mode properly handles negative numbers
*
* Use Cases:
* - ALU comparison operations
* - Branch condition evaluation
* - Sorting algorithms
* - Range checking
* - Control flow decisions
*
* @param WIDTH Bit width of input operands (default: 16 bits)
*
* @input a[WIDTH-1:0] First operand
* @input b[WIDTH-1:0] Second operand
* @input op_sel[2:0] Operation selector (see operation codes above)
* @input signed_mode 0=unsigned comparison, 1=signed comparison
* @output result Single-bit comparison result (1=true, 0=false)
*/
module configurable_comparator #(
parameter WIDTH = 16 // Bit width of inputs
)(
input wire [WIDTH-1:0] a,
input wire [WIDTH-1:0] b,
input wire [2:0] op_sel, // Operation selector
input wire signed_mode, // 0 for unsigned, 1 for signed comparison
output reg result // Single bit result
);
// Operation codes
localparam EQUAL = 3'b000; // Equal
localparam NOT_EQUAL = 3'b001; // Not equal
localparam LESS_THAN = 3'b010; // Less than
localparam LESS_EQUAL = 3'b011; // Less than or equal
localparam GREATER_THAN = 3'b100; // Greater than
localparam GREATER_EQUAL = 3'b101;// Greater than or equal
// Internal signals for signed comparison
wire signed [WIDTH-1:0] a_signed;
wire signed [WIDTH-1:0] b_signed;
// Convert inputs to signed when in signed mode
assign a_signed = $signed(a);
assign b_signed = $signed(b);
// ============================================================================
// Comparison Results (Mode-Dependent)
// ============================================================================
// Less-than comparison: uses signed or unsigned based on mode
wire lt_result = signed_mode ? (a_signed < b_signed) : (a < b);
// Greater-than comparison: uses signed or unsigned based on mode
wire gt_result = signed_mode ? (a_signed > b_signed) : (a > b);
// ============================================================================
// Operation Selection Logic
// ============================================================================
// Selects comparison operation based on op_sel
always @(*) begin
case (op_sel)
EQUAL: begin
// ================================================================
// Equality Check
// ================================================================
// Result is 1 if operands are equal (same for signed/unsigned)
result = (a == b);
end
NOT_EQUAL: begin
// ================================================================
// Inequality Check
// ================================================================
// Result is 1 if operands are not equal
result = (a != b);
end
LESS_THAN: begin
// ================================================================
// Less Than
// ================================================================
// Uses mode-dependent comparison (signed or unsigned)
result = lt_result;
end
LESS_EQUAL: begin
// ================================================================
// Less Than or Equal
// ================================================================
// Less than OR equal
result = lt_result || (a == b);
end
GREATER_THAN: begin
// ================================================================
// Greater Than
// ================================================================
// Uses mode-dependent comparison (signed or unsigned)
result = gt_result;
end
GREATER_EQUAL: begin
// ================================================================
// Greater Than or Equal
// ================================================================
// Greater than OR equal
result = gt_result || (a == b);
end
default: begin
// ================================================================
// Invalid Operation
// ================================================================
// Default to false for invalid op_sel
result = 1'b0;
end
endcase
end
endmodule