Electronic – JK-flip flop using gate level description in Verilog give me a timming error

fpgalatticeverilog

I still playing in the lowest Verilog level (gate level).
I found this post:
Is it possible to create a working JK-flip flop using gate level description in Verilog
in that I could understand that shoud work the idea, and I could solve to have a Master-Slave JK Flip-Flop for use it as a frequency divider. I use Icestorm toolchain, Yosys is not complaining, but Next-PNR is giving me this error:

ERROR: timing analysis failed due to presence of combinatorial loops, incomplete specification of timing ports, etc.

This is my code:

module syncRX(clk, signal, detect);
    output wire [7:0] detect;
    input clk, signal;
    
    reg [6:0] det = 7'b1001010;
    
    assign detect = {det, jk5_out};
    
    jk_flip_flop_edge_triggered jk0(.Q(jk5_out), .Qn(Qn), .C(clk), .J(1), .K(1), .RESETn(0));

endmodule // top

module jk_flip_flop_edge_triggered(Q, Qn, C, J, K, RESETn);
   output Q;
   output Qn;
   input  C;
   input  J;
   input  K;
   input  RESETn;

   wire   Kn;   // The complement of the K input.
   wire   D;   
   wire   D1;   // Data input to the D latch.   
   wire   Cn;   // Control input to the D latch.
   wire   Cnn;  // Control input to the SR latch.
   wire   DQ;   // Output from the D latch, inputs to the gated SR latch (S).
   wire   DQn;  // Output from the D latch, inputs to the gated SR latch (R).

   assign D1 = !RESETn ? 0 : D;  // Upon reset force D1 = 0

   not(Kn, K);   
   and(J1, J, Qn);
   and(K1, Kn, Q);   
   or(D, J1, K1);   
   not(Cn, C);
   not(Cnn, Cn);   
   d_latch dl(DQ, DQn, Cn, D1);
   sr_latch_gated sr(Q, Qn, Cnn, DQ, DQn);   
endmodule

module d_latch(Q, Qn, G, D);
   output Q;
   output Qn;
   input  G;   
   input  D;

   wire   Dn; 
   wire   D1;
   wire   Dn1;

   not(Dn, D);   
   and(D1, G, D);
   and(Dn1, G, Dn);   
   nor(Qn, D1, Q);
   nor(Q, Dn1, Qn);
endmodule

module sr_latch_gated(Q, Qn, G, S, R);
   output Q;
   output Qn;
   input  G;   
   input  S;
   input  R;

   wire   S1;
   wire   R1;
   
   and(S1, G, S);
   and(R1, G, R);   
   nor(Qn, S1, Q);
   nor(Q, R1, Qn);
endmodule

Well, I can imagine the answer if I ask what happends, I would like to know why and how make it works! Thanks to all!

Best Answer

I found this post: Is it possible to create a working JK-flip flop using gate level description in Verilog

Notice that the earlier question seems to be asking only about formally describing the JKFF in Verilog and simulating its behavior. While you seem to want to actually synthesize the device and implement it in an FPGA. These are two different problems.

I would like to know why

The real problem is that FPGAs aren't designed that way. They provide certain logic resources, mainly look-up tables (LUTs) which are just small RAMs that can be configured to act like arbitrary logic gates, and D flip-flops (DFFs), typically with a choice of asynchronous or synchronous reset. They also have routing resources, that is, paths for signals to travel between the logic blocks.

You can configure some LUTs to act like AND, OR, and NOT gates. And hook them up together to act like a JK flip-flop. But this isn't a very efficient use of resources, when you could use a DFF that is actually built in to the FPGA.

Therefore, the synthesis tool is simply not designed to work with this kind of design. It is designed to work with designs where all the combinatorial logic is implemented in LUTs and all the state is stored in DFFs. When your tool sees a feedback path in combinatorial logic that will preserve state, it simply isn't built to handle that, so it reports an error.

and how make it works!

The best way to make an FPGA design work is to design it around the resources that the FPGA actually provides: LUTs and DFFs. You can design your frequency divider to use D flip-flops instead of JK, and it will use much fewer FPGA resources and the synthesis tool will be much better able to optimize it. It will even likely use additional special-purpose logic resources (like carry chains) to optimize the counter implementation.