Counters Discussion D8.3
Counters Divide-by-8 Counter Behavioral Counter in Verilog Counter using One-Hot State Machine
Divide-by-8 Counter A state diagram for a divide by 8 counter
Divide-by-8 Counter s0 0 0 0 0 0 1 s1 0 0 1 0 1 0 s2 0 1 0 0 1 1 State Q2 Q1 Q0 D2 D1 D0 Present state Next state A state-transition table
Divide-by-8 Counter s0 0 0 0 0 0 1 s1 0 0 1 0 1 0 s2 0 1 0 0 1 1 State Q2 Q1 Q0 D2 D1 D0 Present state Next state Q0 Q1 Q2 D0 D1 D2
Divide-by-8 Counter s0 0 0 0 0 0 1 s1 0 0 1 0 1 0 s2 0 1 0 0 1 1 Q1 Q0 s0 0 0 0 0 0 1 s1 0 0 1 0 1 0 s2 0 1 0 0 1 1 s3 0 1 1 1 0 0 s4 1 0 0 1 0 1 s5 1 0 1 1 1 0 s6 1 1 0 1 1 1 s7 1 1 1 0 0 0 State Q2 Q1 Q0 D2 D1 D0 Present state Next state 00 01 11 10 Q2 1 1 1 1 1 D2 D2 = ~Q2 & Q1 & Q0 | Q2 & ~Q1 | Q2 & ~Q0
Divide-by-8 Counter s0 0 0 0 0 0 1 s1 0 0 1 0 1 0 s2 0 1 0 0 1 1 State Q2 Q1 Q0 D2 D1 D0 Present state Next state Q1 Q0 00 01 11 10 Q2 1 1 1 1 1 D1 D1 = ~Q1 & Q0 | Q1 & ~Q0
Divide-by-8 Counter s0 0 0 0 0 0 1 s1 0 0 1 0 1 0 s2 0 1 0 0 1 1 State Q2 Q1 Q0 D2 D1 D0 Present state Next state Q1 Q0 00 01 11 10 Q2 1 1 1 1 1 D0 D0 = ~Q0
Divide-by-8 Counter A Divide by 8 counter Circuit using D Flip-flops
module DFF (D, clk, clr, Q); input clk ; wire clk ; input clr ; wire clr ; input D ; wire D ; output Q ; reg Q ; always @(posedge clk or posedge clr) if(clr == 1) Q <= 0; else Q <= D; endmodule
Q0 Q1 Q2 D0 D1 D2 module count3 ( Q ,clr ,clk ); input clr ; wire clr ; input clk ; wire clk ; output [2:0] Q ; wire [2:0] Q ; wire [2:0] D ; assign D[2] = ~Q[2] & Q[1] & Q[0] | Q[2] & ~Q[1] | Q[2] & ~Q[0]; assign D[1] = ~Q[1] & Q[0] | Q[1] & ~Q[0]; assign D[0] = ~Q[0]; DFF U2(.D(D[2]), .clk(clk), .clr(clr), .Q(Q[2])); DFF U1(.D(D[1]), .clk(clk), .clr(clr), .Q(Q[1])); DFF U0(.D(D[0]), .clk(clk), .clr(clr), .Q(Q[0])); endmodule Q0 Q1 Q2 D0 D1 D2
count3 Simulation
Counters Divide-by-8 Counter Behavioral Counter in Verilog Counter using One-Hot State Machine
3-Bit Counter Behavior clr count3 Q(2 downto 0) clk always @(posedge clk or posedge clr) begin if(clr == 1) Q <= 0; else Q <= Q + 1; end
counter3.v module counter3 (clk, clr, Q ); input clr ; wire clr ; input clk ; wire clk ; output [2:0] Q ; reg [2:0] Q ; // 3-bit counter always @(posedge clk or posedge clr) begin if(clr == 1) Q <= 0; else Q <= Q + 1; end endmodule Asynchronous clear Output count increments on rising edge of clk
counter3 Simulation
Recall Divide-by-8 Counter Q0 Q1 Q2 D0 D1 D2 s0 0 0 0 0 0 1 s1 0 0 1 0 1 0 s2 0 1 0 0 1 1 s3 0 1 1 1 0 0 s4 1 0 0 1 0 1 s5 1 0 1 1 1 0 s6 1 1 0 1 1 1 s7 1 1 1 0 0 0 State Q2 Q1 Q0 D2 D1 D0 Present state Next state Use Q2, Q1, Q0 as inputs to a combinational circuit to produce an arbitrary waveform.
Example State Q2 Q1 Q0 D2 D1 D0 y Q2 Q1 Q0 00 01 11 10 1 s0 0 0 0 0 0 1 1 s1 0 0 1 0 1 0 1 s2 0 1 0 0 1 1 0 s3 0 1 1 1 0 0 0 s4 1 0 0 1 0 1 0 s5 1 0 1 1 1 0 1 s6 1 1 0 1 1 1 0 s7 1 1 1 0 0 0 1 y = ~Q2 & ~Q1 | Q2 & Q0 1 1 0 0 0 1 0 1 1 1 0 0 0 1 0 1
Counters Divide-by-8 Counter Behavioral Counter in Verilog Counter using One-Hot State Machine
One-Hot State Machines Q0 Q1 Q2 D0 D1 D2 Instead of using the minimum number of flip-flops (3) to implement the state machine, one-hot encoding uses one flip-flop per state (8) to implement the state machine.
Why use One-Hot State Machines? Using one-hot encoding or one flip-flop per state (8) will normally simplify the combinational logic at the expense of more flip-flops. Let's see how for the 3-bit counter
One-Hot Encoding Think of each state as a flip-flop s0 0 0 0 s1 Present state Next state State Q2 Q1 Q0 D[0:7] Think of each state as a flip-flop s0 0 0 0 s1 s1 0 0 1 s2 s2 0 1 0 s3 s3 0 1 1 s4 s4 1 0 0 s5 s5 1 0 1 s6 s6 1 1 0 s7 s7 1 1 1 s0 D[i] = s[i-1] This is just a ring counter!
3-bit Counter State Q2 Q1 Q0 s0 0 0 0 s1 0 0 1 s2 0 1 0 s3 0 1 1 s4 1 0 0 s5 1 0 1 s6 1 1 0 s7 1 1 1 Q2 = s4 | s5 | s6 | s7 Q1 = s2 | s3 | s6 | s7 Q0 = s1 | s3 | s5 | s7
module cnt3hot1(clk,clr,Q); input clk; input clr; output [2:0] Q; wire [2:0] Q; reg [0:7] s; // 8-bit Ring Counter always @(posedge clk or posedge clr) begin if(clr == 1) s <= 8'b10000000; else s[0] <= s[7]; s[1:7] <= s[0:6]; end // 3-bit counter assign Q[2] = s[4] | s[5] | s[6] | s[7]; assign Q[1] = s[2] | s[3] | s[6] | s[7]; assign Q[0] = s[1] | s[3] | s[5] | s[7]; endmodule