SR latch
1. Gate-level modeling (using NAND gates):
module SR_latch_nand(input S, input R, output Q, output Qbar);
nand n1(Qbar, R, Q);
nand n2(Q, S, Qbar);
endmodule
2. Dataflow modeling (using assign statements):
module SR_latch_dataflow(input S, input R, output Q, output Qbar);
assign Qbar = ~(Q & R);
assign Q = ~(Qbar & S);
endmodule
4. Behavioral modeling (using always blocks):
module SR_latch_behavioral(input S, input R, output reg Q, output reg Qbar);
always @(*) begin
if (S == 1 && R == 0) begin
Q <= 1;
Qbar <= 0;
end else if (S == 0 && R == 1) begin
Q <= 0;
Qbar <= 1;
end else begin
Q <= Q; // Hold previous state
Qbar <= Qbar;
end
end
endmodule
SR-FF
Gate level
module srff_gate(q, qbar, s, r, clk);
input s,r,clk;
output q, qbar;
wire nand1_out; // output of nand1
wire nand2_out; // output of nand2
nand (nand1_out,clk,s);
nand (nand2_out,clk,r);
nand (q,nand1_out,qbar);
nand (qbar,nand2_out,q);
endmodule
Dataflow
module srff_dataflow(q,qbar,s,r,clk);
input s,r,clk;
output q, qbar;
assign q = clk? (s + ((~r) & q)) : q;
assign qbar = ~q;
endmodule
Behavioral
module srff_behave(s,r,clk, q, qbar);
input s,r,clk;
output reg q, qbar;
always@(posedge clk)
begin
if(s == 1)
begin
q = 1;
qbar = 0;
end
else if(r == 1)
begin
q = 0;
qbar =1;
end
else if(s == 0 & r == 0)
begin
q <= q;
qbar <= qbar
end
end
endmodule
Test bench
module dff_test;
reg S,R, CLK;
wire Q, QBAR;
srff_behavior dut(.q(Q), .qbar(QBAR), .s(S), .r(R),
.clk(CLK)); // instantiation by port name.
$monitor("simtime = %g, CLK = %b, S = %b, R = %b, Q = %b,
QBAR = %b", $time, CLK, S, R, Q, QBAR);
initial begin
clk=0;
forever #10 clk = ~clk;
end
initial begin
S= 1; R= 0;
#100; S= 0; R= 1;
#100; S= 0; R= 0;
#100; S= 1; R=1;
end
JK FF
Gate level
module jkff_gate(q,qbar,clk,j,k);
input j,k,clk;
output q,qbar;
wire nand1_out; // output from nand1
wire nand2_out; // output from nand2
nand n1(nand1_out, j,clk,qbar);
nand n2(nand2_out, k,clk,q);
nand n3(q,qbar,nand1_out);
nand n4(qbar,q,nand2_out);
endmodule
Dataflow
Describing a flip flop using dataflow modeling is not applicable. Flip flops are supposed to work on edge-
triggered clocks. In dataflow modeling, it is not possible to construct an edge-triggered flip flop. It works
more like a latch. Also, when modeling sequential circuits with dataflow, it can sometimes result in an
unpredictable output during a simulation. Hence, we prefer the highest level of abstraction (behavioral
modeling) to describe sequential circuits like flip flops.
Behavioral Modeling
module jkff_behave(clk,j,knq,qbar);
input clk,j,k;
output reg q,qbar;
always@(posedge clk)
begin
if(k = 0)
begin
q <= 0;
qbar <= 1;
end
else if(j = 1)
begin
q <= 0;
qbar <= 0;
end
else if(j = 0 & k = 0)
begin
q <= q;
qbar <= qbar;
end
else if(j = 1 & k = 1)
begin
q <= ~q;
qbar <= ~qbar;
end
end
Test bench
module jkff_test;
reg J,K, CLK;
wire Q, QBAR;
jkff_behavior dut(.q(Q), .qbar(QBAR), .j(J), .k(K), .clk(CLK));
$monitor("simtime = %g, CLK = %b, J = %b, K = %b, Q = %b, QBAR =
%b", $time, CLK, J, K, Q, QBAR);
initial begin
clk=0;
forever #10 clk = ~clk;
end
initial begin
J= 1; K= 0;
#100; J= 0; K= 1;
#100; J= 0; K= 0;
#100; J= 1; K=1;
end
endmodule
D-ff
module dff_behavioral(d,clk,clear,q,qbar);
input d, clk, clear;
output reg q, qbar;
always@(posedge clk)
begin
if(clear== 1)
q <= 0;
qbar <= 1;
else
q <= d;
qbar = !d;
end
endmodule
T-FF
module tff ( input clk, input rstn, input t, output reg q);
always @ (posedge clk) begin
if (!rstn)
q <= 0;
else
if (t)
q <= ~q;
else
q <= q;
end
endmodule