I need help creating a 3-bit Gray code counter that can count both forwards and backwards. Using flip-flops as memory, I was able to create a counter but only in one direction. The dir signal, despite changing, cannot reverse the counting direction. The flip-flop needs to have the same value as input to change the exit. I noticed that the counter counts only in the direction it is in at the time of the reset. When dir = 0 it should count from 0 to 7 and when dir = 1 from 7 to 0. I do not want to change the flipflop.
This is the simulation:
![gray counter simulation.png gray counter simulation.png](https://forum.allaboutcircuits.com/data/attachments/313/313141-9afbae5595a6c78d1c50601b232b8396.jpg)
This is the verilog code:
This is the simulation:
![gray counter simulation.png gray counter simulation.png](https://forum.allaboutcircuits.com/data/attachments/313/313141-9afbae5595a6c78d1c50601b232b8396.jpg)
This is the verilog code:
Code:
module gray_counter(
input clk,
input reset,
input dir,
output [2:0] out
);
wire [2:0] stato_attuale;
reg [2:0] eccitazione;
always @(posedge clk) begin
if (dir == 0) begin
eccitazione[0] <= ((~stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0]) |
(~stato_attuale[2] & stato_attuale[1] & stato_attuale[0]) |
(stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0]) |
(stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0]));
eccitazione[1] <= ((~stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0]) |
(stato_attuale[2] & stato_attuale[1] & stato_attuale[0]));
eccitazione[2] <= ((~stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0]) |
(stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0]));
end
else if (dir == 1) begin
eccitazione[0] <= ((stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0]) |
(stato_attuale[2] & stato_attuale[1] & stato_attuale[0]) |
(~stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0]) |
(~stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0]));
eccitazione[1] <= ((stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0]) |
(~stato_attuale[2] & stato_attuale[1] & stato_attuale[0]));
eccitazione[2] <= ((~stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0]) |
(stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0]));
end
end
FF ff0 (.X(eccitazione[0]), .C(eccitazione[0]), .R(reset), .Z(stato_attuale[0]));
FF ff1 (.X(eccitazione[1]), .C(eccitazione[1]), .R(reset), .Z(stato_attuale[1]));
FF ff2 (.X(eccitazione[2]), .C(eccitazione[2]), .R(reset), .Z(stato_attuale[2]));
assign out[0] = stato_attuale[0];
assign out[1] = stato_attuale[1];
assign out[2] = stato_attuale[2];
endmodule
module FF(
input X, C, R,
output Z
);
reg y1, y2;
always @(posedge C or posedge R) begin
if (R) begin
y1 <= 1'b0;
y2 <= 1'b0;
end else begin
y1 <= (~y2 & C & X) | (y1 & (~C | ~y2));
y2 <= y1 ^ C;
end
end
assign Z = y1;
endmodule