Verilog
Seperti yang kita lihat di artikel sebelumnya, desain yang lebih besar dan kompleks dibangun dengan mengintegrasikan beberapa modul secara hierarkis. Modul dapat dibuat instance dalam modul dan port lain dari instance ini dapat dihubungkan dengan sinyal lain di dalam modul induk.
Koneksi port ini dapat dilakukan melalui daftar yang dipesan atau berdasarkan nama.
Salah satu metode untuk membuat koneksi antara ekspresi port yang terdaftar dalam instantiasi modul dengan sinyal di dalam modul induk adalah dengan daftar terurut .
mydesign adalah module
dipakai dengan nama d0 di modul lain yang disebut tb_top. Port terhubung dalam urutan tertentu yang ditentukan oleh posisi port tersebut dalam daftar port dari deklarasi modul. Misalnya, b di testbench terhubung ke y dari desain hanya karena keduanya berada di posisi kedua dalam daftar port.
module mydesign ( input x, y, z, // x is at position 1, y at 2, x at 3 and
output o); // o is at position 4
endmodule
module tb_top;
wire [1:0] a;
wire b, c;
mydesign d0 (a[0], b, a[1], c); // a[0] is at position 1 so it is automatically connected to x
// b is at position 2 so it is automatically connected to y
// a[1] is at position 3 so it is connected to z
// c is at position 4, and hence connection is with o
endmodule
Urutan port dalam modul desain harus diketahui untuk koneksi yang benar.
Ini sangat merepotkan karena urutannya mungkin berubah jika port baru ditambahkan ke daftar atau ketika jumlah port dalam desain sangat besar.
Cara yang lebih baik untuk menghubungkan port adalah dengan secara eksplisit menautkan port di kedua sisi menggunakan nama port .
Titik .
menunjukkan bahwa nama port yang mengikuti titik adalah milik desain. Nama sinyal yang harus dihubungkan dengan port desain diberikan berikutnya dalam tanda kurung ( )
.
module design_top;
wire [1:0] a;
wire b, c;
mydesign d0 ( .x (a[0]), // signal "x" in mydesign should be connected to "a[0]" in this module (design_top)
.y (b), // signal "y" in mydesign should be connected to "b" in this module (design_top)
.z (a[1]),
.o (c));
endmodule
Direkomendasikan untuk mengkodekan setiap koneksi port dalam baris terpisah sehingga setiap pesan kesalahan kompilasi akan menunjuk dengan benar ke nomor baris tempat kesalahan terjadi. Ini jauh lebih mudah untuk di-debug dan diselesaikan dibandingkan dengan tidak mengetahui port mana yang membuat kesalahan jika semuanya berada di baris yang sama.
Karena hubungan ini dibuat berdasarkan nama, urutan kemunculannya tidak relevan. Koneksi port instance beberapa modul tidak diizinkan.
module design_top;
mydesign d0 ( .x (a[0]),
.z (a[1]), // z at second position is okay because of explicit connection
.y (a[1]),
.x (b), // illegal - x is already connected to a[0]
.o (c));
endmodule
Port yang tidak terhubung ke kabel apa pun di modul instantiating akan memiliki nilai impedansi tinggi.
module design_top;
mydesign d0 ( // x is an input and not connected, hence a[0] will be Z
.y (a[1]),
.z (a[1]),
.o ()); // o has valid value in mydesign but since
// it is not connected to "c" in design_top, c will be Z
endmodule
Mari kita ambil contoh register geser yang telah kita lihat sebelumnya, dan biarkan beberapa port tidak terhubung.
module shift_reg ( input d,
input clk,
input rstn,
output q);
wire [2:0] q_net;
dff u0 (.d(d), .clk(clk), .rstn(rstn), .q(q_net[0]));
dff u1 (.d(q_net[0]), .clk(clk), .rstn(rstn), .q()); // Output q is left floating
dff u2 (.d(q_net[1]), .clk(clk), .rstn(rstn), .q()); // Output q is left floating
dff u3 (.d(q_net[2]), .clk(clk), .rstn(rstn), .q(q));
endmodule
Perhatikan bahwa output dari instance u1 dan u2 dibiarkan tidak terhubung dalam skema RTL yang diperoleh setelah sintesis. Karena input d ke instance u2 dan u3 sekarang terhubung ke jaring yang tidak digerakkan oleh apa pun, itu di-ground.
Dalam simulasi, port yang tidak terhubung tersebut akan dilambangkan sebagai impedansi tinggi ('hZ) yang biasanya ditampilkan dalam bentuk gelombang sebagai garis oranye yang disejajarkan secara vertikal di tengah.
Semua deklarasi port secara implisit dideklarasikan sebagai wire
dan karenanya arah port cukup dalam kasus itu. Namun output
port yang perlu menyimpan nilai harus dideklarasikan sebagai reg
tipe data dan dapat digunakan dalam blok prosedural seperti always
dan initial
saja.
Port jenis input
atau inout
tidak dapat dideklarasikan sebagai reg
karena mereka didorong dari luar terus menerus dan tidak boleh menyimpan nilai, melainkan mencerminkan perubahan sinyal eksternal sesegera mungkin. Sangat sah untuk menghubungkan dua port dengan ukuran vektor yang berbeda-beda, tetapi port dengan ukuran vektor yang lebih rendah akan digunakan dan bit yang tersisa dari port lain dengan lebar yang lebih tinggi akan diabaikan.
// Case #1 : Inputs are by default implicitly declared as type "wire"
module des0_1 (input wire clk ...); // wire need not be specified here
module des0_2 (input clk, ...); // By default clk is of type wire
// Case #2 : Inputs cannot be of type reg
module des1 (input reg clk, ...); // Illegal: inputs cannot be of type reg
// Case #3: Take two modules here with varying port widths
module des2 (output [3:0] data, ...); // A module declaration with 4-bit vector as output
module des3 (input [7:0] data, ...); // A module declaration with 8-bit vector as input
module top ( ... );
wire [7:0] net;
des2 u0 ( .data(net) ... ); // Upper 4-bits of net are undriven
des3 u1 ( .data(net) ... );
endmodule
// Case #4 : Outputs cannot be connected to reg in parent module
module top_0 ( ... );
reg [3:0] data_reg;
des2 ( .data(data) ...); // Illegal: data output port is connected to a reg type signal "data_reg"
endmodule
Verilog
Sebuah for loop adalah loop yang paling banyak digunakan dalam perangkat lunak, tetapi terutama digunakan untuk mereplikasi logika perangkat keras di Verilog. Ide di balik for loop adalah untuk mengulangi satu set pernyataan yang diberikan dalam loop selama kondisi yang diberikan benar. Ini sangat m
case pernyataan memeriksa apakah ekspresi yang diberikan cocok dengan salah satu ekspresi lain dalam daftar dan bercabang sesuai. Biasanya digunakan untuk mengimplementasikan multiplexer. Konstruksi if-else mungkin tidak cocok jika ada banyak kondisi yang harus diperiksa dan akan disintesis menjadi
Parameter adalah konstruksi Verilog yang memungkinkan modul untuk digunakan kembali dengan spesifikasi yang berbeda. Misalnya, penambah 4-bit dapat diparameterisasi untuk menerima nilai jumlah bit dan nilai parameter baru dapat diteruskan selama pembuatan modul. Jadi, penambah N-bit bisa menjadi pen
Verilog adalah bahasa deskripsi perangkat keras dan tidak ada persyaratan bagi desainer untuk mensimulasikan desain RTL mereka agar dapat mengubahnya menjadi gerbang logika. Jadi apa yang perlu disimulasikan? Simulasi adalah teknik menerapkan stimulus input yang berbeda ke desain pada waktu yang