Flip flop JK adalah salah satu dari banyak jenis flop yang digunakan untuk menyimpan nilai dan memiliki dua input data j dan k bersama dengan satu untuk reset rstn dan satu lagi untuk clock clk. Tabel kebenaran untuk kegagalan JK ditunjukkan di bawah ini dan biasanya diimplementasikan menggunakan gerbang NAND.
pertama | j | k | q | Komentar |
0 | 0 | 0 | 0 | Saat reset ditegaskan, output selalu nol |
1 | 0 | 0 | Tahan nilai | Ketika j dan k keduanya 0, output tetap sama seperti sebelumnya |
1 | 0 | 1 | 1 | Saat k=1, output menjadi 1 |
1 | 1 | 0 | 0 | Saat k=0, keluaran menjadi 0 |
1 | 1 | 1 | Beralih nilai | Saat j=1,k=1 output mengubah nilai saat ini |
Kode Verilog perilaku untuk JK flip-flop dapat ditulis seperti yang ditunjukkan di bawah ini
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
Pertama-tama deklarasikan semua variabel yang digunakan di testbench dan mulai jam menggunakan always
simple sederhana blok yang dapat didorong ke desain. Kemudian buat instance desain dan hubungkan portnya dengan variabel testbench yang sesuai. Perhatikan bahwa q bertipe wire
karena terhubung dengan output dari desain yang akan secara aktif menggerakkannya. Semua input lain untuk desain bertipe reg
sehingga mereka dapat didorong dalam blok prosedural seperti initial
.
Stimulus pertama-tama menginisialisasi semua input ke desain ke nol dan kemudian membatalkan pengaturan ulang setelah beberapa waktu. Sebuah for
loop digunakan untuk mendorong nilai yang berbeda ke j dan k yang didorong pada waktu acak. Setelah loop selesai, tunggu beberapa saat lagi dan selesaikan simulasi.
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
Perhatikan dari gelombang simulasi bahwa pada posisi clock, output q berubah nilai berdasarkan keadaan input j dan k seperti yang diberikan pada tabel kebenaran.
Penghitung Modulo-10
Penghitung modulus (MOD) cukup menghitung hingga angka tertentu sebelum kembali ke nol. Penghitung MOD-N akan menghitung dari 0 hingga N-1 dan kemudian memutar kembali ke nol dan mulai menghitung lagi. Penghitung seperti itu biasanya memerlukan log2 N jumlah flop untuk menampung nilai hitungan. Ditampilkan di bawah ini adalah kode Verilog untuk penghitung MOD-10 yang terus menghitung di setiap jam clk selama reset pertama dimatikan.
Parameter Verilog dapat digunakan untuk membuat penghitung MOD-N yang lebih terukur.
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
Testbench pertama-tama mendeklarasikan beberapa variabel yang dapat diberikan beberapa nilai dan didorong ke input desain. Modul counter kemudian dipakai dan dihubungkan dengan sinyal testbench yang kemudian didorong dengan beberapa nilai dalam stimulus. Karena penghitung juga memerlukan jam, jam meja ujian dimodelkan dengan always
memblokir. Stimulus hanya menetapkan nilai default pada waktu 0 ns, kemudian deassert direset setelah 10 ns dan desain dibiarkan berjalan selama beberapa waktu.
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
Lihat bahwa modul penghitung menghitung dari nol hingga 9, berguling ke nol dan mulai menghitung lagi.
Register Shift Kiri 4bit
Diperlihatkan di bawah ini adalah register geser kiri 4-bit yang menerima input d ke LSB dan semua bit lainnya akan digeser ke kiri sebesar 1. Misalnya, jika d sama dengan nol dan nilai awal register adalah 0011, maka akan menjadi 0110 pada tepi jam berikutnya 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
Testbench mengikuti template serupa seperti yang ditunjukkan sebelumnya di mana beberapa variabel dideklarasikan, modul desain dipakai dan terhubung dengan sinyal testbench. Kemudian jam dimulai dan stimulus didorong ke desain menggunakan initial
memblokir. Dalam contoh testbench ini, nilai d yang berbeda harus dijalankan dan karenanya for
loop digunakan untuk mengulangi 20 kali dan menerapkan nilai acak ke desain.
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
Perhatikan bahwa setiap bit digeser ke kiri sebesar 1 dan nilai baru d diterapkan ke LSB.