Gray counter 3 bit

Thread Starter

Dresten

Joined Mar 14, 2025
4
Hi guys, I'm really stuck and have been trying to figure this out for hours. I can't seem to understand what I'm doing wrong.


I need to build a 3-bit Gray counter with an input x that controls the counting order as follows:


  • When x = 0, the counter works in descending order (e.g., 000 → 001 → 011 → 010 → 110 → ...).
  • When x = 1, the counter works in ascending order (e.g., 000 → 100 → 101 → 111 → ...).

The tricky part is that I need to implement an asynchronous memory controlled by two signals, a and b, that follows the following transitions on the positive edge of the clock:
out/a,b​
00​
01​
11​
10​
0​
-​
0​
-​
1​
1​
1​
0​
1​
1​

i already did this much:
4 states

P=00 Q=01 R=11 S=10

c=0​
c=0​
c=0​
c=0​
c=1​
c=1​
c=1​
c=1​

st/ab​
00​
01​
11​
10​
00​
01​
11​
10​
OUT​
P​
P​
P​
P​
P​
-​
Q​
-​
S​
0​
Q​
P​
P​
P​
P​
Q​
Q​
Q​
Q​
0​
R​
R​
R​
R​
R​
1​
0​
1​
1​
1​
S​
R​
R​
R​
R​
S​
S​
S​
S​
1​




c=0​
c=0​
c=0​
c=0​
c=1​
c=1​
c=1​
c=1​

y1y2/ab​
00​
01​
11​
10​
00​
01​
11​
10​
OUT​
00​
00​
00​
00​
00​
-​
01​
-​
10​
0​
01​
00​
00​
00​
00​
01​
01​
01​
01​
0​
11​
11​
11​
11​
11​
10​
01​
10​
10​
1​
10​
11​
11​
11​
11​
10​
10​
10​
10​
1​

y1)



c=0​
c=0​
c=0​
c=0​
c=1​
c=1​
c=1​
c=1​

y1y2/ab​
00​
01​
11​
10​
00​
01​
11​
10​
OUT​
00​
0​
0​
0​
0​
-​
0​
-​
1​
0​
01​
0​
0​
0​
0​
0​
0​
0​
0​
0​
11​
1​
1​
1​
1​
1​
0​
1​
1​
1​
10​
1​
1​
1​
1​
1​
1​
1​
1​
1​


y2)



c=0​
c=0​
c=0​
c=0​
c=1​
c=1​
c=1​
c=1​

y1y2/ab​
00​
01​
11​
10​
00​
01​
11​
10​
OUT​
00​
0​
0​
0​
0​
-​
1​
-​
0​
0​
01​
0​
0​
0​
0​
1​
1​
1​
1​
0​
11​
1​
1​
1​
1​
0​
1​
0​
0​
1​
10​
1​
1​
1​
1​
0​
0​
0​
0​
1​


I noticed that y2= y1^clk
and
y1 = (y1&~clk) | (y1&!y2f) | (y1&y2&!a&!b) | (a&(y1^y2)&clk);

Then I wrote the moddule of this memory:
module ab_mem(

input wire clk, // Segnale di clock
input wire reset, // Segnale di reset asincrono
input wire a, // Ingresso a
input wire b, // Ingresso b
output reg Q // Uscita Q
);

wire y1,y2,y1f,y2f;

assign y1 = (y1f&~clk) | (y1f&!y2f) | (y1f&y2f&!a&!b) | (a&(y1f^y2f)&clk);
assign y2= (y1^clk);
assign y1f = y1 & ~reset;
assign y2f = y2 & ~reset;


assign Q = y1f;

endmodule

I made a simulation andd all the states work in the right combos.

then I had to write the gray counter so I introduced the 0'= 1->0 and 1'= 0->1 states.
and wrote this table:


x=0​
x=0​
x=1​
x=1​
Q(t)​
Q(t+1)​
y1y2y3​
Q(t+1)​
y1y2y3​
000​
001​
001’​
100​
1’00​
001​
011​
01’1​
000​
000’​
011​
010​
010’​
001​
00’1​
010​
110​
1’10​
011​
011’​
110​
111​
111’​
010​
0’10​
111​
101​
10’1​
110​
110’​
101​
100​
100’​
111​
11’1​
100​
000​
0’00​
101​
101’​

Now from the previous transaction table I wrote the excitation diagram for ab_mem:


a​
b​
0​
0​
-​
1​
-/1​
0/-​
0’​
0​
1​
1’​
1​
-​

and I searched the right function for every a_n,b_n:

y1:


y1y2/y3x​
00​
01​
11​
10​
00​
0​
1’​
0​
0​
01​
1’​
0​
0​
0​
11​
1​
0’​
1​
1​
10​
0’​
1​
1​
1​


a1:


y1y2/y3x​
00​
01​
11​
10​
00​
0​
1​
0​
0​
01​
1​
0​
0​
0​
11​
-/1​
0​
-/1​
-/1​
10​
0​
-/1​
-/1​
-/1​




b1:


y1y2/y3x​
00​
01​
11​
10​
00​
-​
-​
-​
-​
01​
-​
-​
-​
-​
11​
0/-​
1​
0/-​
0/-​
10​
1​
0/-​
0/-​
0/-​




y2:


y1y2/y3x​
00​
01​
11​
10​
00​
0​
0​
0​
1’​
01​
1​
1​
0’​
1​
11​
1​
1​
1​
0’​
10​
0​
0​
1’​
0​




a2:


y1y2/y3x​
00​
01​
11​
10​
00​
0​
0​
0​
1​
01​
-/1​
-/1​
0​
-/1​
11​
-/1​
-/1​
-/1​
0​
10​
0​
0​
1​
0​




b2:


y1y2/y3x​
00​
01​
11​
10​
00​
-​
-​
-​
-​
01​
0/-​
0/-​
1​
0/-​
11​
0/-​
0/-​
0/-​
1​
10​
-​
-​
-​
-​




y3:


y1y2/y3x​
00​
01​
11​
10​
00​
1’​
0​
0’​
1​
01​
0​
1’​
1​
0’​
11​
1’​
0​
0’​
1​
10​
0​
1’​
1​
0’​




a3:


y1y2/y3x​
00​
01​
11​
10​
00​
1​
0​
0​
-/1​
01​
0​
1​
-/1​
0​
11​
1​
0​
0​
-/1​
10​
0​
1​
-/1​
0​




b3:


y1y2/y3x​
00​
01​
11​
10​
00​
-​
-​
1​
0/-​
01​
-​
-​
0/-​
1​
11​
-​
-​
1​
0/-​
10​
-​
-​
0/-​
1​


I found the value of all a and b and put them in this module:
module gray2(
input wire clk, // Segnale di clock
input wire reset, // Segnale di reset
input wire x, // Segnale di input
output [2:0] z // Segnali di output
);

wire y1,y2,y3;
wire a1,b1,a2,b2,a3,b3;

assign a1 = (!y2&!y3&x) |(y2&!y3&!x);
assign b1 = (!y2&!y3&!x) |(y2&!y3&x);

assign a2 = (y3&!x&!y1)|(y3&x&y1);
assign b2 = (y3&!x&y1)| (y3&x&!y1);

assign a3= (!y1&y2&x) | (y1&!y2&x) | (!y1&!y2&!x) | (y1&y2&!x);
assign b3 = (y1&y2&x) | (!y1&y2&!x) | (!y1&!y2&x) | (y1&!y2&!x);


assign z[2]=y1;
assign z[1]=y2;
assign z[0]=y3;


ab_mem FF3(.clk(clk), .reset(reset), .a(a3), .b(b3), .Q(y3));
ab_mem FF2(.clk(clk), .reset(reset), .a(a2), .b(b2), .Q(y2));
ab_mem FF1(.clk(clk), .reset(reset), .a(a1), .b(b1), .Q(y1));


endmodule

but when I did the simulation, thisd was the result:
Screenshot From 2025-04-06 14-46-39.png

It doesn t work and i can't understand what am I doing wrong. pls help.

PS sorry for the bad english. Not my first language
 

Irving

Joined Jan 30, 2016
5,076
Welcome to AAC.

I get what you're trying to do, but why didn't you write the grey code generator and test it first, then add the memory module. I can see your grey code is only generating 4 of 8 possible states but the way you've conflated the grey code generation into the memory module obviously has caused an issue - though I can't immediately see it.

My Verilog is a bit rusty, its been a while, but I'm not convinced by your "output reg Q" then "assign Q = y1f", but if I recall correctly, you can't assign to a reg only to a wire?
 

Thread Starter

Dresten

Joined Mar 14, 2025
4
You are right! In fact I changed it with wire and now when I simulate I got this:Screenshot From 2025-04-06 19-03-02.png

I don't understand well what do you mean with "why didn't you write the grey code generator and test it first, then add the memory module". What I had to do was writing the gray counter in ascending and descending order based on x values.Did I make some mistakes in the definition of states/ defining of an and bn or there are other issues. I don't understand.
 

Irving

Joined Jan 30, 2016
5,076
I'm still not sure thats working correctly. I'm only seeing 4 of the 8 states when x is low. In your 1st post, when x = 0 you said 000 → 001 → 011 → 010 → 110 → . yet above after 011 it reverts to 111 and the sequece is different.
 

Thread Starter

Dresten

Joined Mar 14, 2025
4
I'm still not sure thats working correctly. I'm only seeing 4 of the 8 states when x is low. In your 1st post, when x = 0 you said 000 → 001 → 011 → 010 → 110 → . yet above after 011 it reverts to 111 and the sequece is different.
Then what should I do to make it works? I was prettty confident with the fact that I was doing the things in the correct order. i don' t really understand why it doesn t work. I can't understand if the problem is in my verilog code or I didn t calculate an,bn correctly.
 

Thread Starter

Dresten

Joined Mar 14, 2025
4
hi guys maybe I did it:

from the gary moidule i kept the variable an bn etc
module gray2(
input wire clk, // Segnale di clock
input wire reset, // Segnale di reset
input wire x, // Segnale di input
output wire [2:0] z // Segnali di output
);

wire y1,y2,y3;
wire a1,b1,a2,b2,a3,b3;

assign a1 = (!y2&!y3&x) |(y2&!y3&!x);
assign b1 = (!y2&!y3&!x) |(y2&!y3&x);

assign a2 = (y3&!x&!y1)|(y3&x&y1);
assign b2 = (y3&!x&y1)| (y3&x&!y1);

assign a3= (!y1&y2&x) | (y1&!y2&x) | (!y1&!y2&!x) | (y1&y2&!x);
assign b3 = (y1&y2&x) | (!y1&y2&!x) | (!y1&!y2&x) | (y1&!y2&!x);

assign z[2]=y1;
assign z[1]=y2;
assign z[0]=y3;

ab_mem FF1(.clk(clk), .reset(reset), .a(a1), .b(b1), .Q(y1));

ab_mem FF2(.clk(clk), .reset(reset), .a(a2), .b(b2), .Q(y2));

ab_mem FF3(.clk(clk), .reset(reset), .a(a3), .b(b3), .Q(y3));

endmodule

The issue was in the MEMORY module.
I had an asynchronous module and was trying to do some crazy sinchronous work.
I just had to force the update of Q during the clock (so making like a synchronous)


module ab_mem(

input wire clk, // Segnale di clock
input wire reset, // Segnale di reset asincrono
input wire a, // Ingresso a
input wire b, // Ingresso b
output reg Q // Uscita Q
);

wire y1,y2,y1f,y2f;

assign y1 = (y1f&~clk) | (y1f&!y2f) | (y1f&y2f&!a&!b) | (a&(y1f^y2f)&clk);
assign y2 = (y1^clk);
assign y1f = y1 & ~reset;
assign y2f = y2 & ~reset;


always @(posedge clk or posedge reset) begin
if (reset)
Q <= 1'b0; // Reset Q a 0
else
Q <= y1f; // Aggiorna Q con y1f al fronte di clock
end

//assign Q = y1f;

endmodule


Screenshot From 2025-04-06 22-27-52.pngI

I am not still sure that THIS IS the right solution. but now it does work!!! Guys pls I need a feedback to know if I did somethingh legit based on the fact that my homework asked for:
"Next, design an asynchronous memory device controlled by two signals a and b that exhibits the following transitions on the rising edges of the synchronization signal (clock).
Screenshot From 2025-04-06 22-31-45.png

Then, use it in place of the flip-flops (FF) to create the desired counter.
Verify through appropriate simulations that both circuits function in the same way."
 
Top