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:
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.
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
Not working D3:
assign d3 = ~RESET & ((Q[3] & ((~Q[2]) + (~Q[1]) + (~Q[0]))) + ((~Q[3]) & Q[2] & Q[1] & Q[0]));
Not working D3:
assign d3 = ~RESET & (Q[3] & (~Q[2] + ~Q[1] + ~Q[0]) + (~Q[3] & Q[2] & Q[1] & Q[0]));