Problem with 3 bit gray counter

Thread Starter

pinus

Joined Jun 26, 2024
16
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

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
 

MrChips

Joined Oct 2, 2009
31,199

Thread Starter

pinus

Joined Jun 26, 2024
16
Do you know how to design a FSM (finite state machine) using flip-flops?

https://www.allaboutcircuits.com/textbook/digital/chpt-11/finite-state-machines/

https://www.allaboutcircuits.com/textbook/digital/chpt-8/logic-simplification-karnaugh-maps/

The next state of each flip-flop is determined any the current state of all flip-flops.
As an exercise, design a Gray code counter using one of the three styles of flip-flops.
For the next step, add a DIR input as an additional condition.
I studied how to make a Gray counter using standard flip-flops, but the point of the exercise was to use that custom flip-flop.
 

Thread Starter

pinus

Joined Jun 26, 2024
16
What is the "custom flip-flop"?
I am only aware of four types of flip-flops: D, T, J-K, and R-S flip-flop,
A custom flip-flop refers to a flip-flop circuit that is designed or modified to meet specific requirements or perform a specific function that standard flip-flops cannot.
 

WBahn

Joined Mar 31, 2012
30,343
you could do that... but why bother... just use regular counter and translate BCI to Gray code. with just 3 bits it takes single LUT.
Whether that will work acceptably well depends on the reason for wanting a Gray code counter in the first place. Careful though has to be given to whether asynchronous events can result in glitch states that might impact the captured Gray code value.
 

WBahn

Joined Mar 31, 2012
30,343
A custom flip-flop refers to a flip-flop circuit that is designed or modified to meet specific requirements or perform a specific function that standard flip-flops cannot.
So... what is your "custom flip flop"? What specific function does it perform that none of the standard flip-flops can?
 

Thread Starter

pinus

Joined Jun 26, 2024
16
So... what is your "custom flip flop"? What specific function does it perform that none of the standard flip-flops can?
My professor gave me this flip-flop and asked me to build a Gray counter using that flip-flop as the memory cell. I'm outlining it here for clarity:
module FF(X,C,R,Z);

input X,C,R;
output Z;
wire y1,y2;
assign y1=(~y2&C&X) | (y1&(~C|~y2));
assign y2=y1^C;
assign Z = y1;

endmodule

In my code I also added a reset, but it does not change the point of the flipflop.
After analyzing the flip-flop, I found that when X = 0 and C = 0 at the input, the flip-flop does not change its output. However, when X = 1 and C = 1 at the input, it does change. I designed the counter based on this. Now, the logic is correct, it's just a problem of Verilog syntax. So, the counter simply stops working when the dir signal changes.
 

MrChips

Joined Oct 2, 2009
31,199
My professor gave me this flip-flop and asked me to build a Gray counter using that flip-flop as the memory cell. I'm outlining it here for clarity:
module FF(X,C,R,Z);

input X,C,R;
output Z;
wire y1,y2;
assign y1=(~y2&C&X) | (y1&(~C|~y2));
assign y2=y1^C;
assign Z = y1;

endmodule

In my code I also added a reset, but it does not change the point of the flipflop.
After analyzing the flip-flop, I found that when X = 0 and C = 0 at the input, the flip-flop does not change its output. However, when X = 1 and C = 1 at the input, it does change. I designed the counter based on this. Now, the logic is correct, it's just a problem of Verilog syntax. So, the counter simply stops working when the dir signal changes.
So your prof says to use a T-type flip-flop.
Now go and design a Gray code counter using FSM.
 

MrChips

Joined Oct 2, 2009
31,199
You have three flip-flops with outputs Q0, Q1, Q2.

Q0 on the next clock pulse will change state based on the present state of Q0, Q1, and Q2.
Determine the boolean equation required for the input to the Q0 flip-flop.
 

Thread Starter

pinus

Joined Jun 26, 2024
16
You have three flip-flops with outputs Q0, Q1, Q2.

Q0 on the next clock pulse will change state based on the present state of Q0, Q1, and Q2.
Determine the boolean equation required for the input to the Q0 flip-flop.
My flipflop exit are stato_attuale[], and my inputs for the flipflops based on the output are eccitazione[]
 
Top