[笔记].算法 - 计数器.[Verilog]
0赞
发表于 2010/8/23 20:34:39
阅读(2160)
出自Quartus II自带模板。
1. 二进制计数器
01 |
module binary_counter |
02 |
#( parameter WIDTH=64) |
03 |
( |
04 |
input clk, enable, reset, |
05 |
output reg [WIDTH-1:0] count |
06 |
); |
07 |
|
08 |
// Reset if needed, or increment if counting is enabled |
09 |
always @ ( posedge clk or posedge reset) |
10 |
begin |
11 |
if (reset) |
12 |
count <= 0; |
13 |
else if (enable == 1'b1 ) |
14 |
count <= count + 1; |
15 |
end |
16 |
|
17 |
endmodule |
2. 二进制升降计数器
01 |
module binary_up_down_counter |
02 |
#( parameter WIDTH=64) |
03 |
( |
04 |
input clk, enable, count_up, reset, |
05 |
output reg [WIDTH-1:0] count |
06 |
); |
07 |
|
08 |
// Reset if needed, increment or decrement if counting is enabled |
09 |
always @ ( posedge clk or posedge reset) |
10 |
begin |
11 |
if (reset) |
12 |
count <= 0; |
13 |
else if (enable == 1'b1 ) |
14 |
count <= count + (count_up ? 1 : -1); |
15 |
end |
16 |
|
17 |
endmodule |
3. 饱和限制二进制升降计数器
01 |
module binary_up_down_counter_with_saturation |
02 |
#( parameter WIDTH=32) |
03 |
( |
04 |
input clk, enable, count_up, reset, |
05 |
output reg [WIDTH-1:0] count |
06 |
); |
07 |
|
08 |
reg [WIDTH-1:0] direction; |
09 |
reg [WIDTH-1:0] limit; |
10 |
|
11 |
// Reset if needed, increment or decrement if counter is not saturated |
12 |
always @ ( posedge clk or posedge reset) |
13 |
begin |
14 |
if (reset) |
15 |
count <= 0; |
16 |
else if (enable == 1'b1 ) |
17 |
begin |
18 |
if (count_up) |
19 |
begin |
20 |
direction <= 1; |
21 |
limit <= {WIDTH{ 1'b1 }}; // max value is all 1's |
22 |
end |
23 |
else |
24 |
begin |
25 |
direction <= -1; |
26 |
limit <= {WIDTH{ 1'b0 }}; |
27 |
end |
28 |
|
29 |
if (count != limit) |
30 |
count <= count + direction; |
31 |
end |
32 |
end |
33 |
|
34 |
endmodule |
4. 格雷码计数器
01 |
module gray_counter |
02 |
#( parameter WIDTH=8) |
03 |
( |
04 |
input clk, enable, reset, |
05 |
output reg [WIDTH-1:0] gray_count |
06 |
); |
07 |
|
08 |
// Implementation: |
09 |
|
10 |
// There's an imaginary bit in the counter, at q[-1], that resets to 1 |
11 |
// (unlike the rest of the bits of the counter) and flips every clock cycle. |
12 |
// The decision of whether to flip any non-imaginary bit in the counter |
13 |
// depends solely on the bits below it, down to the imaginary bit. It flips |
14 |
// only if all these bits, taken together, match the pattern 10* (a one |
15 |
// followed by any number of zeros). |
16 |
|
17 |
// Almost every non-imaginary bit has a submodule instance that sets the |
18 |
// bit based on the values of the lower-order bits, as described above. |
19 |
// The rules have to differ slightly for the most significant bit or else |
20 |
// the counter would saturate at it's highest value, 1000...0. |
21 |
|
22 |
// q is the counter, plus the imaginary bit |
23 |
reg q [WIDTH-1:-1]; |
24 |
|
25 |
// no_ones_below[x] = 1 iff there are no 1's in q below q[x] |
26 |
reg no_ones_below [WIDTH-1:-1]; |
27 |
|
28 |
// q_msb is a modification to make the msb logic work |
29 |
reg q_msb; |
30 |
|
31 |
integer i, j, k; |
32 |
|
33 |
always @ ( posedge reset or posedge clk) |
34 |
begin |
35 |
if (reset) |
36 |
begin |
37 |
|
38 |
// Resetting involves setting the imaginary bit to 1 |
39 |
q[-1] <= 1; |
40 |
for (i = 0; i <= WIDTH-1; i = i + 1) |
41 |
q[i] <= 0; |
42 |
|
43 |
end |
44 |
else if (enable) |
45 |
begin |
46 |
// Toggle the imaginary bit |
47 |
q[-1] <= ~q[-1]; |
48 |
|
49 |
for (i = 0; i < WIDTH-1; i = i + 1) |
50 |
begin |
51 |
|
52 |
// Flip q[i] if lower bits are a 1 followed by all 0's |
53 |
q[i] <= q[i] ^ (q[i-1] & no_ones_below[i-1]); |
54 |
|
55 |
end |
56 |
|
57 |
q[WIDTH-1] <= q[WIDTH-1] ^ (q_msb & no_ones_below[WIDTH-2]); |
58 |
end |
59 |
end |
60 |
|
61 |
|
62 |
always @(*) |
63 |
begin |
64 |
|
65 |
// There are never any 1's beneath the lowest bit |
66 |
no_ones_below[-1] <= 1; |
67 |
|
68 |
for (j = 0; j < WIDTH-1; j = j + 1) |
69 |
no_ones_below[j] <= no_ones_below[j-1] & ~q[j-1]; |
70 |
|
71 |
q_msb <= q[WIDTH-1] | q[WIDTH-2]; |
72 |
|
73 |
// Copy over everything but the imaginary bit |
74 |
for (k = 0; k < WIDTH; k = k + 1) |
75 |
gray_count[k] <= q[k]; |
76 |
end |
77 |
|
78 |
|
79 |
endmodule |