Problem with 3 bit gray counter

joeyd999

Joined Jun 6, 2011
6,336
I can't read Italian, so let's just assume your state outputs are A, B, and C (A is the high order bit). The inputs are A, B, C (last state) and D (direction). Assume D is 0 for count up.

Get rid of the IF. Compute the next state as a function of the inputs (D, A, B, C).

A quick Karnaugh Map gives me A = (D)(Abar)+(Dbar)(AC)+(Dbar)(B)(Cbar). [Check my work!]

Do the rest for B and C. Done.

Include a reset input if you desire.
 
Last edited:

Thread Starter

pinus

Joined Jun 26, 2024
16
I can't read Italian, so let's just assume your state outputs are A, B, and C (A is the high order bit). The inputs are A, B, C (last state) and D (direction). Assume D is 0 for count up.

Get rid of the IF. Compute the next state as a function of the inputs (D, A, B, C).

A quick Karnough Map gives me A = (D)(Abar)+(Dbar)(AC)+(Dbar)(B)(Cbar). [Check my work!]

Do the rest for B and C. Done.

Include a reset input if you desire.
eccitazione[0] <= ((~stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0] & ~dir) |
(stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0] & dir) |
(~stato_attuale[2] & stato_attuale[1] & stato_attuale[0] & ~dir) |
(stato_attuale[2] & stato_attuale[1] & stato_attuale[0] & dir) |
(stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0] & ~dir) |
(~stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0] & dir) |
(stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0] & ~dir) |
(~stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0] & dir));

eccitazione[1] <= ((~stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0] & ~dir) |
(stato_attuale[2] & ~stato_attuale[1] & stato_attuale[0] & dir) |
(stato_attuale[2] & stato_attuale[1] & stato_attuale[0] & ~dir) |
(~stato_attuale[2] & stato_attuale[1] & stato_attuale[0] & dir));

eccitazione[2] <= ((~stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0] & ~dir) |
(~stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0] & dir) |
(stato_attuale[2] & ~stato_attuale[1] & ~stato_attuale[0] & ~dir) |
(stato_attuale[2] & stato_attuale[1] & ~stato_attuale[0] & dir));

These are the functions without the if condition.
My flipflop exit are stato_attuale[], and my inputs for the flipflops based on the output are eccitazione[]
 

Thread Starter

pinus

Joined Jun 26, 2024
16
It would be a lot easier to follow and debug if you were to show your work using a truth table and Karnaugh map.
This is the process:
Flipflop table:
1719425765357.png
Then I found this table that says inputs (columns) and what they change about the exit of FF (lines on the left):
1719425926062.png
0 and 1 means exit does not change and remains 0 or 1, 0' means exit from 1 to 0 and 1' exit from 0 to 1

These tables help me find the function for the input of the flipflops because they basically say which bit changes based on Gray code:
1719425998175.png

Then first I separate the input of the 3 flipflops and then to make 0 I need 0 and 0 in input, to make 1' I need in input 1 and 1 etc... (As I mentioned before)

1719426057459.png1719426065452.png1719426074270.png

From this Karnaugh map I found the functions that I put in my code.
 

Attachments

MrChips

Joined Oct 2, 2009
34,885
When you test your results, are you examining all three bits?
The least significant two bits alone will have the same sequence in both forward and reverse directions.
 

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:
View attachment 325512

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
I think I've found the error, basically the counter should change value everytime the clk change, but I have posedge C and non posedge clk. The time that at least one of the input of ff does not change from 0 to 1 the counter stops, as there is not a posedge C that rule the flipflop.
 
Top