Menggunakan Quartus dan ModelSim

Saya selalu tertarik dengan sirkuit digital, khususnya, bahasa deskripsi perangkat keras - HDL. Saya memiliki sebuah buku karya David M. Harris dan Sarah L. Harris, "Sirkuit Digital dan Arsitektur Komputer," dalam daftar bacaan saya di masa depan untuk waktu yang lama, mengambil keuntungan dari waktu luang dengan isolasi diri, saya membaca buku yang indah ini. Dalam proses membaca, saya menemui beberapa kesulitan, khususnya, bagaimana menulis dan men-debug kode di Quartus Prime. Dalam proses pencarian, situs marsohod.org banyak membantu saya, tetapi proses simulasi rangkaian di situs ini dijelaskan menggunakan alat Quartus bawaan dan dalam versi modern program, alat bawaan ini tidak tersedia dan Anda perlu menggunakan ModelSim. Untuk entah bagaimana mensistematisasi pengetahuan yang saya peroleh dengan menggunakan Quartus dan ModelSim, saya memutuskan untuk menulis artikel ini. Dalam perjalanan artikel ini, sebagai contoh, saya akan menganalisis masalah dari buku "Sirkuit Digital dan Arsitektur Komputer" oleh David M. Harris dan Sarah L. Harris, khususnya masalah 3.26 tentang mesin air soda. Sepanjang artikel ini, saya akan menunjukkan kepada Anda cara menginstal Quartus, membuat proyek, menulis kode dan mensimulasikannya. Setiap orang yang tertarik dengan ini, selamat datang di bawah kucing.



gambar



Perumusan masalah



Anda dibujuk untuk mendesain mesin minuman ringan untuk kantor. Minuman sebagian ditanggung oleh serikat pekerja, sehingga harganya hanya 5 rubel. Mesin menerima koin 1, 2 dan 5 rubel. Segera setelah pembeli membuat jumlah yang diperlukan, mesin akan mengeluarkan minuman dan menyerahkan kembaliannya. Merancang mesin negara untuk mesin minuman ringan. Input mesin adalah 1, 2 dan 5 rubel, yaitu koin mana yang dimasukkan.



Asumsikan bahwa untuk setiap sinyal clock, hanya satu koin yang dimasukkan. Mesin memiliki output: tuangkan soda, kembalikan 1 rubel, kembalikan 2 rubel, kembalikan 2 untuk 2 rubel. Segera setelah 5 rubel (atau lebih) dikumpulkan di mesin penjual otomatis, ia menetapkan sinyal "FILL GASING", serta sinyal untuk kembalinya perubahan yang sesuai. Maka mesin harus siap menerima koin lagi.



Teori



Mesin negara terbatas atau mesin negara terbatas (FSM) termasuk dalam kelas sirkuit sekuensial sinkron yang mewakili sebagian besar sirkuit digital. Ini adalah bagaimana Anda harus mengimplementasikan proyek Anda (setidaknya pada awalnya). Metode ini memberikan pengulangan dan verifikasi sirkuit dan tidak tergantung pada rasio keterlambatan berbagai elemen rangkaian. Aturan untuk membangun sirkuit sekuensial sinkron menyatakan bahwa sebuah sirkuit adalah sirkuit sekuensial sinkron jika elemen-elemennya memenuhi kondisi berikut:



  • Setiap elemen sirkuit adalah register atau sirkuit kombinasional.
  • Setidaknya satu elemen skema adalah register.
  • Semua register diberi clock dengan sinyal clock tunggal.
  • Setiap jalur siklik mengandung setidaknya satu register.


Mesin negara memiliki beberapa negara, yang menyimpannya dalam register. Ketika sinyal jam tiba, mesin keadaan dapat mengubah statusnya, dan bagaimana persisnya keadaan akan berubah tergantung pada sinyal input dan keadaan saat ini. Dalam kasus yang paling sederhana, mungkin tidak ada sinyal input sama sekali, sehingga pembagi frekuensi berfungsi. Ada dua kelas utama dari mesin keadaan terbatas: otomat Moore, di mana sinyal keluaran hanya bergantung pada keadaan otomat saat ini, dan otomat Mealy, di mana sinyal keluaran bergantung pada keadaan saat ini dan sinyal masukan. Pada prinsipnya, setiap mesin negara terbatas dapat diimplementasikan baik sesuai dengan skema Moore dan skema Miley, perbedaan di antara mereka adalah bahwa robot Moore akan memiliki lebih banyak negara dan itu akan menjadi satu jam di belakang otomat Mily.Untuk sirkuit mesin soda, saya akan menggunakan sirkuit Miles. Mari kita tulis status mesin negara:

Simbol Deskripsi
S 0 Keadaan awal, jumlah akumulasi 0 rubel.
S 1 Jumlah yang terakumulasi adalah 1 gosok.
S 2 Akumulasi 2 rubel.
S 3 Akumulasi 3 rubel.
S 4 Akumulasi 4 rubel.


Sinyal input akan berupa bus dua bit, dengan kode denominasi koin berikut:

Simbol Nilai Deskripsi
Saya 1 01 1 RUB
Saya 2 sepuluh RUB 2
Saya 5 sebelas 5 gosok


Mari kita menggambar diagram keadaan otomat kita (pada diagram keadaan otomat Mealy, perlu untuk menunjukkan sinyal keluaran pada panah transisi keadaan, saya tidak akan melakukan ini, agar tidak mengacaukan diagram, semua sinyal keluaran akan dijelaskan dalam tabel di bawah):



gambar



Mari kita tuliskan tabel perubahan di negara bagian dan sinyal keluaran:

Serikat Sinyal input
S S' insert pour_water C 1 . change1 2 . change2 2 2 . change22
S0 S1 I1 0 0 0 0
S0 S2 I2 0 0 0 0
S0 S0 I5 1 0 0 0
S1 S2 I1 0 0 0 0
S1 S3 I2 0 0 0 0
S1 S0 I5 1 1 0 0
S2 S3 I1 0 0 0 0
S2 S4 I2 0 0 0 0
S2 S0 I5 1 0 1 0
S3 S4 I1 0 0 0 0
S3 S0 I2 1 0 0 0
S3 S0 I5 1 1 1 0
S4 S0 I1 1 0 0 0
S4 S0 I2 1 1 0 0
S4 S0 I5 1 0 0 1




Quartus Prime



Quartus memiliki Lite Edition gratis, yang memiliki beberapa keterbatasan dibandingkan dengan edisi profesional, batasan utama tidak lebih dari 10.000 baris kode sumber untuk mensimulasikan proyek. Mengunduhnya, setelah mendaftar, Anda dapat mengikuti tautannya , pada saat penulisan versi terbaru adalah 19.1, berdasarkan pengerjaan dengan versi ini, saya menulis sebuah artikel. Kami memilih Lite Edition, versi 19.1, sistem operasi Windows (harus dicatat bahwa ada versi Quartus untuk Linux dan berfungsi dengan baik, masalah timbul dengan ModelSim, yang 32 bit dan menggunakan versi lama dari pustaka tampilan font, jadi pada awalnya saya sarankan menggunakan versi Windows ), pilih tab File Gabungan. Ukuran arsip untuk unduhan sangat besar - 5,6 Gb, ingatlah ini. Luaskan arsip yang diunduh dan jalankansetup.bat . Instalasi berlangsung dengan cara standar, kami menggunakan pemilihan komponen standar.



Pembuatan proyek



Untuk membuat proyek baru, pilih File -> New ... oleh Project Wizard . Jendela Wizard pertama adalah informasi, klik Next , pada jendela kedua, pilih di mana proyek akan berlokasi, namanya "soda_machine" dan elemen desain tingkat atas "soda_machine" , seperti pada gambar:



gambar



Di jendela berikutnya, pilih "Empty project" . Jendela untuk menambahkan file "Tambah file" , jangan menambahkan apa pun. Jendela pemilihan perangkat "Family, Devices & Board Settings" sangat penting untuk proyek nyata, tetapi karena proyek kami bersifat mendidik dan jauh dari yang asli, kami meninggalkan pengaturan default di sini, seperti pada gambar:



gambar



Jendela untuk memilih pengaturan untuk alat lain"Pengaturan Alat EDA" , pilih untuk mensimulasikan proyek untuk menggunakan "ModelSim-Altera" dan format "System Verilog HDL" seperti pada gambar:



gambar



Jendela informasi terakhir "Ringkasan" , klik Selesai .



Menulis kode sumber



Kami akan memiliki dua file utama dengan kode sumber, ini adalah modul soda_machine itu sendiri dan bangku tesnya, kedua file ini akan menggunakan tipe data insert_type , yang menjelaskan bagaimana kami menyandikan denominasi koin dan logis untuk memisahkannya menjadi file terpisah. Tetapi ada beberapa kesulitan yang terkait dengan fitur kompilasi Quartus dan ModelSim. Quartus mengkompilasi semua file sumber dalam satu pass, dan ModelSim mengkompilasi setiap file secara terpisah untuk yang akan mengkompilasi Quartus'om muncul jenis override insert_type , saya menggunakan teknik C / C ++ termasuk penjaga, berdasarkan arahan prosesor makro. Selain itu, untuk ModelSim pastikan bahwa insert_type digunakan dalam modul soda_machinedan di bangku tes, satu dan sama, masukkan deskripsinya ke dalam paket soda_machine_types . Dengan memperhatikan persyaratan ini , file soda_machine_types.sv terlihat seperti ini:



soda_machine_types.sv
`ifndef soda_machine_types_sv_quard

package soda_machine_types;

	typedef enum logic [1:0] {I1=2'b01, I2=2'b10, I5=2'b11} insert_type;
	
endpackage

`define soda_machine_types_sv_quard
`endif




Sekarang modul soda_machine itu sendiri terletak di file soda_machine.sv :



soda_machine.sv
`include "soda_machine_types.sv"
import soda_machine_types::*;


module soda_machine(
	input logic clk,          // Clock 
	input logic reset,        // Active high level
	input insert_type insert,
	output logic pour_water,
	output logic change1,
	output logic change2,
	output logic change22);

	typedef enum logic [2:0] {S0, S1, S2, S3, S4} state_type;
	(* syn_encoding = "default" *) state_type state, nextstate;
	//       
	always_ff @(posedge clk, posedge reset)
	if (reset)
		state <= S0;
	else
		state <= nextstate;
	//            
	always_comb
		case (state)
			S0:
				case (insert)
					I1:
						nextstate = S1;
					I2:
						nextstate = S2;
					I5:
						nextstate = S0;
				endcase
			S1: 
				case (insert)
					I1:
						nextstate = S2;
					I2:
						nextstate = S3;
					I5:
						nextstate = S0;
				endcase
			S2:
				case (insert)
					I1:
						nextstate = S3;
					I2: 
						nextstate = S4;
					I5:
						nextstate = S0;
				endcase
			S3: 
				if (insert == I1)
					nextstate = S4;
				else
					nextstate = S0;
			S4:
				nextstate = S0;
		endcase
	//    
	assign pour_water = (state == S4) | (insert == I5) | (state == S3) & (insert == I2);
	
	assign change1 = (state == S1) & (insert == I5) | (state == S3) & (insert == I5) | (state == S4) & (insert == I2);
							
	assign change2 = (state == S2) & (insert == I5) | (state == S3) & (insert == I5);
	
	assign change22 = (state == S4) & (insert == I5);
	
endmodule




Bagaimana keadaan mesin negara akan dikodekan, saya menyerahkannya kepada Quartus. Untuk menunjukkan bagaimana tepatnya pengkodean harus dilakukan, atribut (* syn_encoding = "default" *) digunakan , opsi pengkodean lainnya dapat dilihat di sini .



Perlu dicatat bahwa dalam proyek nyata, sinyal output dari logika kombinasional dari otomat Mealy harus disimpan dalam register dan, sudah dari output register, diumpankan ke output FPGA. Sinyal input harus disinkronkan dengan frekuensi jam menggunakan sinkronisasi, untuk menghindari jatuh ke keadaan metastabil.



Untuk menambahkan file ke proyek, gunakan File -> New "SystemVerilog HDL File"dan berikan nama yang sesuai saat menyimpan. Setelah menambahkan dua file ini, proyek dapat dikompilasi dengan Memproses -> Mulai Kompilasi . Setelah kompilasi berhasil, Anda dapat melihat Alat skema yang dihasilkan -> Netlist Viewers -> RTL Viewer :



RTL Viewer
image



Untuk melihat diagram keadaan mesin negara Alat -> Netlist Viewers -> State Machine Viewer



Penampil mesin negara
image



Pada tab Pengodean, Anda dapat melihat bahwa Quartus menerapkan skema pengkodean "satu-panas", ini adalah ketika D-flip-flop terpisah digunakan untuk setiap negara, dan negara S 0 dikodekan 0, dan bukan 1 seperti untuk negara lain, ini dilakukan untuk menyederhanakan rangkaian reset ke awal. negara. Anda mungkin memperhatikan bahwa RTL Viewer tidak menunjukkan diagram yang sangat mendasar, ini lebih merupakan konsep. Untuk melihat diagram skematis, gunakan Tools -> Netlist Viewrs -> Technology Map Viewer (Pasca Pemasangan)



Simulasi



Pada prinsipnya, saat ini kami memiliki diagram mesin penjual otomatis untuk menjual air soda, tetapi kami perlu memastikan bahwa itu berfungsi dengan benar, untuk ini kami akan menulis bangku tes dan menempatkannya dalam file soda_machine_tb.sv :



soda_machine_tb.sv
`include "soda_machine_types.sv"
import soda_machine_types::*;

module soda_machine_tb;

	insert_type insert;
	
	logic [5:0] testvectors[10000:0];
	
	int vectornum, errors;
	
	logic clk, reset, pour_water, change1, change2, change22;
	logic pour_water_expected, change1_expected, change2_expected, change22_expected;
	//  
	soda_machine dut(
		.clk(clk),
		.reset(reset),
		.insert(insert),
		.pour_water(pour_water),
		.change1(change1),
		.change2(change2),
		.change22(change22)
	);
	//   
	always
		#5 clk = ~clk;
	//   
	initial begin
		//     
		$readmemb("../../soda_machine.tv", testvectors);
		vectornum = 0;
		errors = 0;
		clk = 1;
		//   
		reset = 1; #13; reset = 0;
	end
	//   
	always @(posedge clk) begin
		#1; {insert, pour_water_expected, change1_expected, change2_expected, change22_expected} = testvectors[vectornum];
	end
	// ,      
	always @(negedge clk)
		if (~reset) begin
			if ((pour_water !== pour_water_expected) || (change1 !== change1_expected) || (change2 !== change2_expected) ||
				(change22 !== change22_expected)) begin
				$error("%3d test insert=%b\noutputs pour_water=%b (%b expected), change1=%b (%b expected), change2=%b (%b expected), change22=%b (%b expected)", 
					vectornum + 1, insert, pour_water, pour_water_expected, change1, change1_expected, change2, change2_expected, change22, change22_expected);
				errors = errors + 1;
			end
			vectornum = vectornum + 1;
			if (testvectors[vectornum] === 6'bx) begin
				$display("Result: %3d tests completed with %3d errors", vectornum, errors);
				$stop;
			end
		end

endmodule




Untuk menguji modul kami, file vektor uji soda_machine.tv digunakan :



soda_machine.tv
01_0_0_0_0
01_0_0_0_0
01_0_0_0_0
01_0_0_0_0
01_1_0_0_0
10_0_0_0_0
10_0_0_0_0
10_1_1_0_0
11_1_0_0_0
10_0_0_0_0
10_0_0_0_0
11_1_0_0_1
10_0_0_0_0
11_1_0_1_0
01_0_0_0_0
01_0_0_0_0
01_0_0_0_0
11_1_1_1_0




Dua bit pertama adalah input insert, 4 bit berikutnya adalah harapan kami untuk output: pour_water, change1, change2, change22. Sebagai contoh, pada awal file, koin rubel dimasukkan 5 kali berturut-turut, pada koin kelima, kami mengharapkan sinyal pour_water muncul, sedangkan sinyal pengiriman perubahan tidak aktif. File soda_machine.tv ditambahkan ke proyek File -> New "Text File".



Untuk kenyamanan bekerja dengan ModelSim, tambahkan file soda_machine_run_simulation.do dengan konten berikut:



soda_machine_run_simulation.do
add wave /soda_machine_tb/dut/clk
add wave /soda_machine_tb/dut/reset
add wave /soda_machine_tb/dut/insert
add wave /soda_machine_tb/dut/state
add wave /soda_machine_tb/dut/nextstate
add wave /soda_machine_tb/dut/pour_water
add wave /soda_machine_tb/dut/change1
add wave /soda_machine_tb/dut/change2
add wave /soda_machine_tb/dut/change22
view structure
view signals
run -all
wave zoom full




Ini akan menjalankan simulasi dan mengeluarkan plot sinyal ke ModelSim. File soda_machine_run_simulation.do ditambahkan ke File -> Proyek baru "File skrip Tcl"



Sekarang kita akan mengatur proyek sehingga simulasi dimulai secara otomatis. Pilih item menu Tugas -> Pengaturan , pilih kategori Pengaturan Alat EDA -> Simulasi . Di pengaturan NativeLink, pilih Kompilasi bangku tes: dan klik tombol Test Benches ... di jendela Test Benches yang terbuka, klik tombol New ... Di jendela New Bench Settings Test yang terbuka, isi bidang nama bangku tes: soda_machine_tbdan klik tombol pilih file ... di bagian bawah jendela, pilih file soda_machine_tb.sv kami dan klik tombol Add . Seharusnya muncul seperti pada gambar:



gambar



Di jendela Pengaturan Tes Baru , klik OK . Jendela Test Benches akan terlihat seperti ini:

gambar



Di jendela Test Benches , klik OK . Dalam pengaturan NativeLink, atur skrip Gunakan untuk mengatur kotak centang simulasi dan pilih file soda_machine_run_simulation.do . Jendela Pengaturan

akan terlihat seperti ini:



gambar



Di jendela Pengaturan , klikOK , kami mengkompilasi proyek Memproses -> Mulai Kompilasi , menjalankan Alat simulasi -> Jalankan Alat Simulasi -> Simulasi RTL . ModelSim harus dimulai dan proyek akan disimulasikan. Penampilan tab transkrip:



Tab Transkrip ModelSim
image



Bingkai merah menandai output dari bangku tes kami tentang jumlah tes yang dilakukan dan kesalahan yang ditemukan. Penampilan tab gelombang:



Tab ModelSim Wave
image



Kode sumber proyek



Kode sumber untuk proyek ini ada di github.com/igoral5/soda_machine Klon proyek, kemudian buka proyek dengan File Quartus -> Open Project ...

pilih file soda_machine.qpf . Kemudian kompilasi pemrosesan Proyek -> Mulai Kompilasi dan mulai Alat simulasi -> Jalankan Alat Simulasi -> Simulasi RTL .



All Articles