# Sequential Logic with always

A previous article showed different examples of using an `always`

block to implement combinational logic. An `always`

block is also mainly used to implement *sequential* logic which has memory elements like flip flops that can hold values.

## JK Flip Flop

A JK flip flop is one of the many types of flops used to store values and has two data inputs j and k along with one for reset rstn and another for clock clk. The truth table for a JK flop is shown below and is typically implemented using NAND gates.

rstn | j | k | q | Comments |
---|---|---|---|---|

0 | 0 | 0 | 0 | When reset is asserted, output is always zero |

1 | 0 | 0 | Hold value | When both j and k are 0, output remains the same as before |

1 | 0 | 1 | 1 | When k=1, output becomes 1 |

1 | 1 | 0 | 0 | When k=0, output becomes 0 |

1 | 1 | 1 | Toggle value | When j=1,k=1 output toggles current value |

The behavioral Verilog code for a JK flip-flop can be written as shown below

module jk_ff ( input j, // Input J input k, // Input K input rstn, // Active-low async reset input clk, // Input clk output reg q); // Output Q always @ (posedge clk or negedge rstn) begin if (!rstn) begin q <= 0; end else begin q <= (j & ~q) | (~k & q); end end endmodule

### Testbench

First declare all variables used in the testbench and start a clock using a simple `always`

block that can be driven to the design. Then instantiate the design and connect its ports with corresponding testbench variables. Note that q is of type `wire`

because it is connected to an output of the design which will be actively driving it. All other inputs to the design are of type `reg`

so that they can be driven within a procedural block such as `initial`

.

The stimulus first initializes all inputs to the design to zero and then de-asserts reset after some time. A `for`

loop is used to drive different values to j and k which are driven at random times. Once the loop is done, wait for some more time and finish the simulation.

module tb; // Declare testbench variables reg j, k, rstn, clk; wire q; integer i; reg [2:0] dly; // Start the clock always #10 clk = ~clk; // Instantiate the design jk_ff u0 ( .j(j), .k(k), .clk(clk), .rstn(rstn), .q(q)); // Write the stimulus initial begin {j, k, rstn, clk} <= 0; #10 rstn <= 1; for (i = 0; i < 10; i = i+1) begin dly = $random; #(dly) j <= $random; #(dly) k <= $random; end #20 $finish; end endmodule

Note from the simulation wave that at the posedge of clock, output q changes value based on the state of inputs j and k as given in the truth table.

## Modulo-10 counter

Modulus(MOD) counters simply count upto a certain number before rolling back to zero. A MOD-N counter will count from 0 to N-1 and then roll back to zero and start counting again. Such counters typically require log_{2}N number of flops to hold the count value. Shown below is the Verilog code for a MOD-10 counter that keeps counting up at every clock clk as long as reset rstn is deasserted.

Verilog parameters can be used to make a MOD-N counter which is more scalable.

module mod10_counter ( input clk, input rstn, output reg[3:0] out); always @ (posedge clk) begin if (!rstn) begin out <= 0; end else begin if (out == 10) out <= 0; else out <= out + 1; end end endmodule

### Testbench

The testbench first declares some variables that can be assigned some values and driven to the design inputs. The counter module is then instantiated and connected with the testbench signals which are later driven with some values in the stimulus. Since the counter also requires a clock, the testbench clock is modeled with an `always`

block. The stimulus simply sets default values at time 0ns, then deasserts reset after 10ns and the design is allowed to run for some time.

module tb; reg clk, rstn; reg [3:0] out; mod10_counter u0 ( .clk(clk), .rstn(rstn), .out(out)); always #10 clk = ~clk; initial begin {clk, rstn} <= 0; #10 rstn <= 1; #450 $finish; end endmodule

See that the counter module counts from zero to 9, rolls over to zero and starts counting again.

## 4bit Left Shift Register

Shown below is a 4-bit left shift register that accepts an input d into LSB and all other bits will be shifted left by 1. For example, if d equals zero and the initial value of the register is 0011, it will become 0110 at the next edge of the clock clk.

module lshift_4b_reg ( input d, input clk, input rstn, output reg [3:0] out ); always @ (posedge clk) begin if (!rstn) begin out <= 0; end else begin out <= {out[2:0], d}; end end endmodule

### Testbench

The testbench follows a similar template like the one shown before where some variables are declared, design module is instantiated and connected with the testbench signals. Then a clock is started and the stimulus is driven to the design using an `initial`

block. In this testbench example, different values of d has to be exercised and hence a `for`

loop is used to iterate 20 times and apply random values to the design.

module tb; reg clk, rstn, d; wire [3:0] out; integer i; lshift_4b_reg u0 ( .d(d), .clk(clk), .rstn(rstn), .out(out)); always #10 clk = ~clk; initial begin {clk, rstn, d} <= 0; #10 rstn <= 1; for (i = 0; i < 20; i=i+1) begin @(posedge clk) d <= $random; end #10 $finish; end endmodule

Note that each bit is shifted to the left by 1 and the new value of d is applied to LSB.