2 Bit Counter using JK Flip Flop in Verilog

Eduardo Romero picture Eduardo Romero · Oct 2, 2014 · Viewed 13.1k times · Source

I'm writing verilog code of 2 Bit Counter using JK Flip Flop that counts 0-3 and back to 0. I'm using Xilinx EDA. However I'm keep getting one error and I don't know what it means? The line numbers doesn't show up here, but error is located at "always @(posedge clk)".

ERROR:HDLCompiler:1401 - "C:\Users\Eduardo\Documents\SFSU\Fall 2014\Engr 378\Lab 3\TwoBitCounter\twobitcounter.v" Line 30: Signal q in unit jkff is connected to following multiple drivers:

`timescale 1ns / 1ps
module twobitcounter( q_out, qbar_out, j,k, clk, reset);
    input [1:0] j; input [1:0] k; input clk; input reset;
    output [1:0] q_out;
    output [1:0] qbar_out;
    wire [1:0] q_out;
    wire [1:0] qbar_out;
    wire clk;

    assign qbar_out[0] = ~q_out[0];
    assign j[0] = 1;
    assign k[0] = 1;
    assign j[1] = q_out[0];
    assign k[1] = q_out[0]; 

    jkff M1(q_out[0], qbar_out[0], j[0], k[0], clk, reset);
    jkff M2(q_out[1], qbar_out[1], j[1], k[1], qbar_out[0]);

endmodule

module jkff(output q_out, output qbar_out,
  input j, input k, input clk, input reset);

    reg q;
    assign q_out = q;
    assign qbar_out = ~q;

    initial begin 
        q = 1'b0;
        end
    always @(posedge clk)
        begin
        case({j,k})
        {1'b0, 1'b0}: begin
            q = q;
            end
        {1'b0, 1'b1}: begin
            q = 1'b0;
            end
        {1'b1, 1'b0}: begin
            q = 1'b1;
            end
        {1'b1, 1'b1}: begin
            q = ~q;
            end
        endcase
        end

    always @(posedge reset)
        begin
        q = 1'b0;
        end
endmodule

Answer

Greg picture Greg · Oct 2, 2014

The issue is q is being set in two always blocks, which is not allowed in synthesis. Merge the two always blocks. Also, q is a flop, so it should be assigned using non-blocking assignment (<=), not blocking assignment (=).

always @(posedge clk or posedge reset)
begin
  if (reset == 1'b1) begin
    q <= 1'b0;
  end
  else begin
    case({j,k})
    {1'b0, 1'b0}: begin
        q <= q;
        end
    {1'b0, 1'b1}: begin
        q <= 1'b0;
        end
    {1'b1, 1'b0}: begin
        q <= 1'b1;
        end
    {1'b1, 1'b1}: begin
        q <= ~q;
        end
    endcase
  end
end

You should almost never use initial blocks in synthesizable code. Most FPGAs allow it for initialization. ASICs designs however do not support it. For both cases, if there is an asynchronous reset/set then it initial block shouldn't be used.