0
\$\begingroup\$

I am creating a 4-bit up counter using Verilog in Vivado.

For this counter, I would like to use flip-flops to represent each bits from Q0 to Q4.

For simplification, I used D flip flop to represent Q3, Q1, and Q0, and JK flip flop to represetn Q2.

However, I ran into a strange problem with Q3.

Long story short, If using assign d3 = ~RESET & (Q[3] ^ (Q[2] & Q[1] & Q[0]));, the simnulation output looks perfect. But If I use assign d3 = ~RESET & ((Q[3] & ((~Q[2]) + (~Q[1]) + (~Q[0]))) + ((~Q[3]) & Q[2] & Q[1] & Q[0])); or assign d3 = ~RESET & (Q[3] & (~Q[2] + ~Q[1] + ~Q[0]) + (~Q[3] & Q[2] & Q[1] & Q[0])); the output for D3 looks strange, see screenshots from simulation output at the bottom of this post.

However, the two latter cases are equivalent to the Q[3] XOR (Q[2] and Q[1] and Q[0]), so what is going on here?

The transition table is here for convience:

enter image description here

And here's the flip-flop transition table for Q3 to Q0: My original plan was to use RS for Q3, and T for Q1, however, for troubleshooting purposes, I changed Q3 and Q1 to D flip flop, so please ignore R3 S3, and T1. enter image description here

module Four_bits_Up_Counter(input CLK, RESET, output [3:0] Q);    
    wire d0, d1, d3; 
    //wire t1; 
    wire j2, k2;
    //wire r3, s3;
    
    D_FF D0 (.D(d0), .CLK(CLK), .Q(Q[0]));
    D_FF D1 (.D(d1), .CLK(CLK), .Q(Q[1]));
    //T_FF F1   (.T(t1), .CLK(CLK), .Q(Q[1]));    
    JK_FF JK2 (.J(j2), .K(k2), .CLK(CLK), .Q(Q[2]));
    //RS_FF RS3 (.R(r3), .S(s3), .CLK(CLK), .Q(Q[3]));
    D_FF D3 (.D(d3), .CLK(CLK), .Q(Q[3]));

    assign d0 = (~RESET) & (~Q[0]);
    
    assign d1 = ~RESET & (Q[1] ^ Q[0]);
    
    //assign t1 = (RESET & Q[1]) | (~RESET & Q[0]);
    
    assign j2 = (~RESET & Q[1] & Q[0]);
    assign k2 = (RESET | (Q[1] & Q[0]));
    
    //assign r3 = (RESET | (Q[2] & Q[1] & Q[0]));
    //assign s3 = ((~RESET) & Q[2] & Q[1] & Q[0]);
    //assign d3 = ~RESET & ((Q[3] & ((~Q[2]) + (~Q[1]) + (~Q[0]))) + ((~Q[3]) & Q[2] & Q[1] & Q[0])); // this doesn't work
    //assign d3 = ~RESET & (Q[3] & (~Q[2] + ~Q[1] + ~Q[0]) + (~Q[3] & Q[2] & Q[1] & Q[0]));     // this also does not work
    assign d3 = ~RESET & (Q[3] ^ (Q[2] & Q[1] & Q[0])); // this one works
endmodule


module D_FF(input CLK, D, output reg Q);
    always @ (posedge CLK)
        Q <= D;
endmodule
                               
module T_FF(input CLK, T, output reg Q);
    always @ (posedge CLK)
        Q <= (Q ^ T);     
endmodule

module JK_FF(input CLK, J, K, output reg Q);
    always @ (posedge CLK)
        Q <= (J & ~Q) | (~K & Q);
endmodule

module RS_FF(input CLK, R, S, output reg Q);
    always @ (posedge CLK)
        Q <= S | (Q & ~R);
endmodule

Test bench

module Four_bits_Up_Counter_TB();
    reg CLK;
    reg R;
    wire [3:0] Q;
    
    Four_bits_Up_Counter TB(.CLK(CLK), .RESET(R), .Q(Q));
    
    initial
        CLK = 0;
        always
            #5 CLK = ~CLK;
            
     initial
     begin
        R = 0;  
        #20;
        R = 1;
        #10;
        R = 0;
        #197;
        R = 1;
        #20;
        R = 0;
        #100;
        $finish;
     end
endmodule

Simulation output:

Workign D3:

assign d3 = ~RESET & (Q[3] ^ (Q[2] & Q[1] & Q[0])); // this one works

It counts upto 16 working D3

Not working D3:

assign d3 = ~RESET & ((Q[3] & ((~Q[2]) + (~Q[1]) + (~Q[0]))) + ((~Q[3]) & Q[2] & Q[1] & Q[0]));

It only counts upto 9 Not working D3

Not working D3:

assign d3 = ~RESET & (Q[3] & (~Q[2] + ~Q[1] + ~Q[0]) + (~Q[3] & Q[2] & Q[1] & Q[0]));

It only counts upto 7 Also not working D3

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

I figured out the problem in my codes. Insrtead of using +, I should have used | for or operation.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.