安德鲁

[笔记].算法 - 计数器.[Verilog]

0
阅读(2327)

出自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