Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Industrial programming >> Verilog

Logika Sekuensial dengan selalu

Artikel sebelumnya menunjukkan berbagai contoh penggunaan always blok untuk mengimplementasikan logika kombinasional. Sebuah always blok juga terutama digunakan untuk mengimplementasikan sequential logika yang memiliki elemen memori seperti sandal jepit yang dapat menyimpan nilai.

JK Flip Flop

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.


Verilog

  1. Tutorial - Menulis Kode Kombinasi dan Sekuensial
  2. Sirkuit Dengan Sakelar
  3. Sirkuit Terintegrasi
  4. Programmable Logic Controllers (PLC)
  5. Pengantar Aljabar Boolean
  6. Penyederhanaan Logika Dengan Karnaugh Maps
  7. Logika Digital Dengan Umpan Balik
  8. Penghitung Mod-N Verilog
  9. Penghitung Abu-abu Verilog
  10. Selalu Finishing Halus dengan Mesin Penggiling Okamoto