1
\$\begingroup\$

I am new to Verilog and I was trying to make a Decade counter. I simply took the reference of an actual circuit that implements the decade counter using JK-Flip Flops. So I wrote a sub-module for JK-Flip Flop and a top-module that would connect all the Flip-Flops.

Here is my code for the JK-Flip Flop:

module JK(
    input j,
    input k,
    input clk,
    input reset,
    output reg q
    );

initial q=0;

always @ (*)
    begin
        if (reset)
            q=0;
    end

always @ (negedge clk)
    begin
        if (~j&&k)
            q=0;
        else if (j&&~k)
            q=1;
        else if (j&&k)
            q=~q;
    end

endmodule

and my code for the circuit:

module DECADECOUNTER(
    input clk,
    output q0,
    output q1,
    output q2,
    output q3
    );

JK jk0(1'b1,1'b1,clk,q1&q3,q0);
JK jk1(1'b1,1'b1,q0,q1&q3,q1);
JK jk2(1'b1,1'b1,q1,q1&q3,q2);
JK jk3(1'b1,1'b1,q2,q1&q3,q3);

endmodule

So the idea is that the last input is a reset and will clear all of my flip-flops if both q1 and q3 are 1 (1010).

But when I try to simulate the circuit on Xilinx, I get the following result:

enter image description here

This screen is from very instant the simulation starts. As you can see q0 and q1 are 0 but q2 and q3 are not. My guess is that after resetting q1, the condition q1&q3 went false and hence q2 and q3 remained to be 1. This seems as if the circuit is asynchronous. But that isn't the way Verilog is supposed to work right? If something is present in the ports, ideally its value should be propagated to other ports before it changes. Because that's how a real-world circuit is supposed to work.

\$\endgroup\$
  • 1
    \$\begingroup\$ JK Flip-Flops are not used any more (except to pose difficult questions to electronic engineers), definitely not in FPGAs or ASICs. Use standard D-registers instead. \$\endgroup\$ – Oldfart Oct 13 '18 at 7:05
  • \$\begingroup\$ Kinda hard for anything to happen when the clock is Z. Where is your test bench? \$\endgroup\$ – Greg Oct 13 '18 at 19:40
2
\$\begingroup\$

Two problems:

  1. In a sequential always block (one on the clock) always always always use the "non blocking assignment" which looks like a less than/equal to sign (<=).

  2. Never ever assign to a signal from two always blocks. If you want q to be asynchronously reset, make the always block sensitive to negedge clock or posedge reset. Then have if reset first, followed by else for the other conditions. This probably isn't causing your problem now, but it will cause problems eventually.

\$\endgroup\$
1
\$\begingroup\$

I figured out it was best to not try and emulate hardware using code (As I was trying to emulate a traditional decade counter circuit using JK-Flip Flop). Instead, it's better to write a code that emulates the output. And the rest should be left to Xilinx to synthesize and convert code into a working piece of hardware.

So here is my new code for the Decade Counter:

module DecadeCounter(
     input clk,
     input reset,
     output q0,
     output q1,
     output q2,
     output q3
    );

reg [3:0]q;
initial q = 0;

assign q0 = q[0];
assign q1 = q[1];
assign q2 = q[2];
assign q3 = q[3];

always @ (posedge clk or posedge reset)
    begin
        if(reset||q[1]&&q[3])
            q <= 0;
        else
            q <= q + 1'b1;
    end

endmodule

This code simulates really well and the best part is that it doesn't comes with the usual and nasty surprises of Verilog. It's as natural as writing code on C/C++.

enter image description here

\$\endgroup\$
  • \$\begingroup\$ You should always use nonblocking assignments for outputs from sequential always blocks, failure to do so is likely to lead to unpredictable behaviour and/or mismatches between simulation and synthesis. \$\endgroup\$ – Peter Green Oct 15 '18 at 19:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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