Monday, June 25, 2018

Last attempt with the M/S J-K Flip-Flop

With nominal gate delays added to all the TTL parts in my SAP-1 Verilog simulation, I decided to give the Master/Slave version of the 74107 J-K flip-flop one more try. And it flopped.

At first I tried the behavioral implementation of this device, using a final pair of assign statements to insert the inertial delays given in the datasheet. The code looked like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
module sn74ls107 (
    input  wire CLK,    // Data clock (active falling edge)
    input  wire CLR,    // Async reset (active low)
    input  wire J,      // Set
    input  wire K,      // Reset
    output wire Q,      // True Q output
    output wire QN      // Inverted Q output
    );

    wire MQ, MQn;
    wire SQ, SQn;
    assign MQ  = ~(MQn & ~(J & SQn & CLK)) & CLR;
    assign MQn = ~(MQ  & ~(K & SQ  & CLK));

    assign SQ  = ~(SQn & ~(MQ  & ~CLK)) & CLR;
    assign SQn = ~(SQ  & ~(MQn & ~CLK));

    assign #25 Q  = SQ;
    assign #25 QN = SQn;
endmodule

This worked in the single unit test and in the ring counter test. In the program counter test it counted properly but generated a number of glitches as the counter advanced.

Thinking might work better with a structural implementation, I created yet another version using nand and not gates. Here's the schematic view of this implementation:
This also allowed me to specify separate rise and fall delays on each gate, based on the datasheets for the 7400, 7404, 7410, and 7420 TTL gates. This is the translation to structural Verilog:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
module sn74ls107 (
    input  wire CLK,    // Data clock (active falling edge)
    input  wire CLR,    // Async reset (active low)
    input  wire J,      // Set
    input  wire K,      // Reset
    output wire Q,      // True Q output
    output wire QN      // Inverted Q output
    );

    wire CLKn;
    not #(9,10) U9(CLKn, CLK);

    wire N1, N2;
    nand #(9,10) U1(N1, J, QN, CLK, CLR);
    nand #(9,10) U2(N2, K, Q,  CLK);

    wire N3, N4;
    nand #(9,10) U3(N3, N1, N4);
    nand #(9,10) U4(N4, N2, N3, CLR);

    wire N5, N6;
    nand #(9,10) U5(N5, N3, CLKn);
    nand #(9,10) U6(N6, N4, CLKn);

    nand #(9,10) U7(Q,  N5, QN);
    nand #(9,10) U8(QN, N6, Q, CLR);
endmodule

My unit test produced timing very close to that given by the datasheet. The total delay with low-to-high output transitions is a couple of nanoseconds longer than the datasheet maximum number, but the high-to-low output transitions are a few nanoseconds under the datasheet maximum. I consider that a completely valid simulation.

Again, the ring counter gives acceptable results, but the program counter has noticeable glitches. Trying it in the full SAP-1 simulation produced erroneous calculations, as the sensitivity of the flip-flop to changes in the J and K inputs while the clock is high caused the PC to increment twice per CPU cycle: appropriately in the middle of state T2, and inappropriately in the middle of state T3.

Given that this simulation runs properly with the simulated edge-triggered 74LS107A parts regardless of delays, I'm going to conclude that the SAP-1 would not be reliable and might not work at all using the Master/Slave 74107 parts.

No comments:

Post a Comment