0
\$\begingroup\$

I am a beginner in Verilog and my counter is not working. I'm not sure what I'm doing wrong. Below, I will type my code.

module jkfflop(
  input  J,
  input  K,
  input  clk,
  output Q);
  
  reg Q;
  
   always @(posedge clk) begin
    if(J==1'b0 && K==1'b1) begin
      Q <= 'b0;
    end
    else if(J==1'b1 && K==1'b0) begin
      Q <= 1'b1;
    end
    else if(J==1'b1 & K==1'b1) begin
      Q <= ~Q;
    end
  end
endmodule


module counter(
    input clk,
    output[3:0] q1,
    output[3:0] an,
    output a,b,c,d,e,f,g);
    
    wire sclk;
    wire t1, t2;
    and(t1,q1[1],q1[0]);
    and(t2,t1,q1[2]);
    slowClock ck1 (clk, 1'b1,sclk);
    jkfflop ff1(q1[0], 1'b1, 1'b1, sclk);
    jkfflop ff2(q1[1], q1[0], q1[0], sclk);
    jkfflop ff3(q1[2], t1, t2, sclk);
    jkfflop ff4(q1[3], t2, t2, sclk);
    
    sevseg S1(q1[0],q1[1],q1[2],q1[3],a,b,c,d,e,f,g,an);

endmodule

module sevseg(
    input A,
    input B,
    input C,
    input D,
    output a,b,c,d,e,f,g,
    output[3:0] an);
    
    assign an = 4'b1110;
    
    assign a = (~A & ~B & ~C & ~D) | (~A & B & ~C & ~D);
    assign b = (~B & ~C & D) | (~B & ~C & ~D);
    assign c = (~A & ~B & C & ~D);
    assign d = (B & ~C & ~D) | (B & C & D);
    assign e = D | (B & ~C);
    assign f = (C & D) | (~A & ~B & ~C) + (B & C & D);
    assign g = (~A & ~B & ~C) + (B & C & D);
    
endmodule
\$\endgroup\$
3
  • 2
    \$\begingroup\$ Have you written a testbench and run a simulation of this? That is a much better way to debug, and it is a good way for you to really learn how verilog works. \$\endgroup\$ – Elliot Alderson Mar 8 at 23:26
  • \$\begingroup\$ module jkfflop is declared with arguments J, K, clk, output reg Q, but when used in module counter with instance jkfflop ff1(q1[0], 1'b1, 1'b1, sclk), the argument list is in a different order -- q1[0] (as J), 1'b1 (as K), 1'b1 (as clk), sclk (as output reg Q), which is clearly not what you intended. \$\endgroup\$ – MarkU Mar 8 at 23:57
  • 1
    \$\begingroup\$ Following up on the previous comment, you should never rely on pott order to connect modules. I write modules with dozens or hundreds of ports, and you have to use name-based connection to manage that. We don't allow code like this. Also, you're writing very low-level code is this to get used to boolean logic? If I wanted to code this for real I'd write it completely differently, in a much more readable way (no and-or trees inside sevenseg, and no jk flip flops). \$\endgroup\$ – Matt Mar 9 at 3:11
3
\$\begingroup\$

Your module port order in your jkfflop instances doesn’t match the module definition.

A way to avoid this is to use ‘ANSI-C’ style port declaration in the instances.

Example:

jkfflop ff1 (
   .J(j-input),
   .K(k-input),
   .clk(clk-input),
   .Q(q-output)
);

Then there’s no issue with port order: the port-to-pin connections are explicit.

But... that’s the hard way to do a counter. Here’s an easier way: use a procedural block. Example:

reg [3:0] count;

always @ (posedge sclk)
begin
    if (reset)
        count <= 0;
    else
        count <= count + 1;
end

This will synthesize to four flops with appropriate carry logic. The reset is necessary if you want to simulate the counter, otherwise it starts up in an unknown state. Here the reset is synchonous, if you want asynchronous, add reset to the sensitivity list.

Another hint: a case statement for the segment decoder will be much easier to understand.

There’s a few other things that could be better; but understanding procedurals and case statements are two very powerful tools in the Verilog toolbox for making readable, error-free code.

\$\endgroup\$

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.