Verilog #2: Struktur Program Verilog

February 22, 2026

 

Sahabat Robonesia, setelah pada artikel sebelumnya, kita telah mengenal pemrograman Verilog. Pada artikel ini, kita akan melanjutkan pembelajaran pemrograman Verilog, yaitu mengenai struktur bahasa pemrograman Verilog (Definisi Module) dan cara menginstansiasi module tersebut.

Struktur program Verilog yang akan penulis sajikan pada artikel ini terdiri atas empat versi standard pemrograman Verilog, yaitu struktur program standard Verilog-1985/1995 dan standard Verilog-2001/2005. Mengapa penuliskan untuk keempat standard tersebut? Karena ada perbedaan sintaksis pada kedua kelompok standard Verilog tersebut.

 

2.1 Struktur Program Verilog (Standard Verilog-1985/1995)

Tidak seperti struktur program VHDL, struktur umum program Verilog lebih sederhana. Dimana program utamanya merupakan definisi blok program “module.” Setiap blok program module dimulai dengan kata kunci “module” dan diakhiri dengan kata kunci “endmodule.” Berikut ini adalah syntax struktur utama kode program Verilog atau definisi module program mengikuti standard Verilog-1985 dan Verilog-1995.

Syntax 1: Definisi module | Standard Verilog-1985/1995

Pada syntax di atas, untuk membuat program desain rangkaian atau sistem digital menggunakan pemrograman Verilog, yang pertama harus ditentukan adalah nama_module. Kemudian dikuti nama sinyal atau nama port I/O di dalam daftar nama port/sinyal (port_list), tanpa menentukan tipe port/sinyalnya (input, output, atau inout). Tipe port/sinyal I/O harus di deklarasikan di dalam module. Setelah deklarasi I/O, maka baru kemudian dilanjutkan dengan penulisan pernyataan-pernyataan program (module_item) yang diperlukan untuk mengatur perilaku atau operasi internal module desain sistem digital yang sedang dibuat. Perlu selalu diingat, bahwa setiap pernyataan dalam pemrograman Verilog wajib diakhiri dengan karakter titik-koma (semicolon, “;”).

Pernyataan program atau module_item, dapat berupa:

  • Deklarasi tipe data (Klik di sini!).
  • Deklarasi parameter (Klik di sini!).
  • Instansiasi module (Klik di sini!).
  • Instansiasi Pre-define primitive (Klik di sini!).
  • Instansiasi User-define primitive (Klik di sini!).
  • Generate block (Klik di sini!).
  • Procedural block (Klik di sini!).
  • Continuous assignment (Klik di sini!).
  • Definisi task (Klik di sini!).
  • Definisi function (Klik di sini!).

 

Sebagai contoh, perhatikan program 1 dan Gambar 1-a. Deklarasi module memiliki nama two_gates. Semua sinyal input dan output ditulis di dalam daftar sinyal/port tanpa menentukan tipe sinyalnya, apakah itu input, output, atau inout. Deklarasikan port/sinyal input dan output diletakkan di dalam module. A, B, dan D adalah sinyal input. E adalah sinyal output. Sinyal C dideklarasikan di dalam modul sebagai wire karena merupakan sinyal internal. Program dilanjutkan dengan dua pernyataan concurrent yang mendeskripsikan dimana dua gerbang (NAND dan OR) ditempatkan dan modul diakhiri dengan kata kunci endmodule.

Program 1:

 

Gambar 1. Ilustrasi untuk sebuah module dalam program Verilog
Sumber: Digital Systems Design Using Verilog (Charles Roth, Lizy K. John, Byeong Kil Lee) – Pages 68-69

 

Bagian deklarasi I/O modul dapat dianggap sebagai gambar “kotak hitam” dari modul yang dirancang dan antarmuka eksternalnya, yaitu deklarasi I/O (A, B, D, dan E) yang mewakili interkoneksi modul tersebut dengan dunia luar. Lihat Gambar 1-b.

 

Gambar 2. Desain sistem digital multiplexer
Sumber: Verilog Quickstart, 3rd edition, James M Lee – Pages 14

 

Dengan memperhatian desain sistem digital multiplexer pada Gambar 2, berikut ini contoh program lengkap definisi program utama atau definisi module dalam pemrograman Verilog dengan mengikuti standard Verilog-1985/1995.

Program 2: Kode program Verilog Gate-level – Module “mux”

Penjelasan program 2:

Baris 1: module mux(OUT, A, B, SEL);
Baris ini mendeklarasikan nama modul dan daftar port input/output-nya.

 

Baris 2: output OUT;
Baris ini memberi tahu compiler kode program Verilog arah port OUT. “OUT” adalah nama port yang merupakan port keluaran. “output” adalah kata kunci program Verilog yang digunakan untuk mendeklarasikan arah port keluaran.

 

Baris 3: input A, B, SEL;
Baris ini memberi tahu compiler kode program Verilog arah port A, B, dan SEL yang kesemuanya merupakan port masukan. “input” adalah kata kunci program Verilog yang digunakan untuk mendeklarasikan arah port masukan.

 

Baris 5: not g_NOT (output_not, SEL);
Baris ini membuat instansiasi primitive bawaan “not” (Gerbang NOT). Sinyal pertama, output_not, adalah sinyal output, dan sinyal kedua, SEL, adalah sinyal input yang terhubung ke input gerbang NOT tersebut. “g_NOT” adalah nama instansiasi dari primitive bawaan “not”.

 

Baris 6: and g_AND1 (output_and1, A, SEL); 
Baris ini membuat instansiasi dari primitive bawaan AND (Gerbang AND) yang pertama. Gerbang ini memiliki nama instansiasi g_AND1. A dan SEL adalah sinyal input gerbang AND pertama tersebut, sedangkan “output_and1” adalah sinyal output gerbang AND pertama (AND1).

 

Baris 7: and  g_AND2 (output_and2, output_not, B);
Baris ini membuat instansiasi dari primitive bawaan AND (Gerbang AND) yang kedua. Gerbang ini memiliki nama instansiasi g_AND2. Output_not dan B adalah sinyal input gerbang AND kedua tersebut, sedangkan “output_and2” adalah sinyal output gerbang AND kedua (AND2).

 

Baris 9: or g_OR (OUT, output_and1, output_and2);
Baris ini membuat instansiasi dari primitive bawaan OR (Gerbang OR). Gerbang ini memiliki nama instansiasi g_OR. Output_and1 dan output_and2 adalah sinyal input gerbang OR tersebut yang merupakan sinyal output dari masing-masing gerbang AND1 dan AND2, sedangkan “OUT” adalah sinyal output gerbang OR yang juga merupakan sinyal output dari desain digital sistem multiplexer.

 

Baris 10: endmodule
Baris ini menandai akhir modul MUX yang di akhiri dengan kata kunci “endmodule”.

 

2.1.1 Instansiasi Module (Standard Verilog-1985/1995)

Instansiasi module dalam pemrograman Verilog adalah cara menggunakan suatu module yang telah didefinisikan sebelumnya dari dalam module utama desain sistem digital yang dibangun.

Berikut adalah langkah-langkah cara menginstansiasi module dalam pemrograman Verilog mengikuti standard Verilog-1985/1995:

Langkah 1: Mendefinisikan Module
Pertama-tama, kita harus mendefinisikan module yang ingin diinstansiasi. Module didefinisikan di dalam blok program module menggunakan kata kunci “module”, diikuti dengan nama module dan daftar port-port input/output/inout yang terkait dengan modul tersebut, dan diakhiri dengan kata kunci “endmodule.” Program 3 adalah contoh pendefinisian sebuah module.

 

Program 3: Module “adder”

Penjelasan Program 3:
Pada contoh di atas, kita mendefinisikan modul dengan nama “adder” yang memiliki dua input “a” dan “b”, serta satu output “sum”. Fungsi dari modul ini adalah menjumlahkan input “a” dan “b”, sehingga menghasilkan sinyal output “sum”.

 

Langkah 2: Menginstansiasi Module
Untuk menginstansiasi module, kita membuat module utama desain sistem digital yang sedang kita bangun. Kemudian untuk menginstansiasi module lain yang telah didefinisikan sebelumnya (pada Program 3), tuliskan satu baris kode program di dalam module utama yang elemennya ditulis secara berurutan, yaitu module_name, instance_name, dan daftar_port yang terkait dengan instance tersebut. Sila melihat syntax 2.

Syntax 2:

 

Program 4 adalah contoh module utama yang menginstansiasi module “adder” pada program 3.

Program 4: Module “top”

Penjelasan Program 4:
Pada contoh di atas, kita menginstansiasi module “adder” dari dalam module “top” dengan nama instance “u_adder”. Kemudian menghubungkan port “a”, “b”, dan “sum” dari modul “adder” dengan sinyal “r”, “s”, dan “jumlah”  yang didefinisikan dalam module “top”.

 

Penulisan Program Verilog Lengkap
Berikut adalah Program 5, program Verilog lengkap yang menunjukkan definisi module “adder” dan penginstansiasiannya dalam module “top”:

Program 5:

Penjelasan Program 5:
Pada contoh di atas, kita mendefinisikan modul “adder” dan menginstansiasinya dalam modul “top”. Kita menghubungkan port-port “a”, “b”, dan “sum” dari modul”adder” dengan sinyal “r”, “s”, dan “jumlah”  yang didefinisikan dalam modul “top”. Kita juga menghubungkan output “jumlah” dari instance “u_adder” dengan sinyal “result” dalam modul “top”. Akhirnya, kita menampilkan hasil penjumlahan “r” dan “s” menggunakan $display.

 

2.2 Struktur Program Verilog (Standard Verilog-2001/2005)

Struktur utama kode program Verilog atau definisi module pada standard Verilog-2001/2005 tetap sama di awali dengan kata kunci “module” dan di akhiri dengan kata kunci “endmodule,” namun ada sedikit perbedaan, yaitu perbedaan dalam deklarasi port I/O dan penambahan deklarasi parameter (bersifat opsional). Berikut adalah penjelasan selangkapnya.

 

1. Perbedaan dalam deklarasi port I/O

Pada standard Verilog-2001/2005, dalam definisi module, daftar_port (port-list) ditulis sebagai deklarasi port I/O dan langsung ditulis lengkap dengan arah sinyalnya, yaitu input, output, atau inout. Port-list ditulis dengan gaya ANSI-C atau gaya bahasa pemrogram C). Setelah penulisan deklarasi port I/O, kode program dilanjutkan dengan penulisan module_item yang diperlukan. Perhatikan Syntax 3 berikut:

 

Syntax 3: Definisi module – Standard Verilog-2001/2005.

 

Contoh 1:

Penjelasan Contoh 1:
Pada contoh di atas, kita mendefinisikan sebuah modul adder yang memiliki tiga port, yaitu Port a adalah input 4-bit, Port b adalah input 4-bit, dan Port sum adalah output 4-bit. Fungsi dari modul ini adalah menjumlahkan sinyal input a dan b dan menghasilkan sinyal output sum.

 

2. Penambahan deklarasi parameter (Opsional)

Dalam mendefinisikan module kode program Verilog dengan mengikuti standard Verilog-2001/2005, kita dapat menambahkan deklarasi parameter, namun hal ini bersifat pilihan (Opsional). Deklarasi parameter ditulis di dalam tanda kurung dengan diawali penulisan karakter hastag “#”. Setelahnya, diikuti dengan deklarasi port I/O (input, output, atau inout), dan penulisan pernyataan program atau module_item yang diperlukan. Perhatikan Syntax 4 berikut:

 

Syntax 4:
Definisi module mengikuti standard Verilog-2001/2005 dengan deklarasi parameter.

 

Contoh 2:

Penjelasan Contoh 2:
Perhatikan bahwa kita menggunakan deklarasi parameter BIT_WIDTH untuk menentukan lebar bit dari input dan output. Dengan demikian, kita dapat dengan mudah mengubah lebar bit dari modul adder tanpa harus mengubah kode program.

Dengan deklarasi parameter, kita dapat membuat modul yang lebih fleksibel dan dapat digunakan dalam berbagai situasi. Selain itu, kita juga dapat memberikan nilai default untuk parameter, sehingga jika kita tidak memberikan nilai parameter saat instansiasi modul, maka nilai default akan digunakan.

 

2.2.1 Instansiasi Module (Standard Verilog-2001/2005)

Instansiasi module dalam pemrograman Verilog dengan mengikuti standar Verilog-2001/2005 dapat dilakukan dengan tanpa menambahkan deklarasi parameter dan dengan menambahkan deklarasi parameter. Berikut ini adalah penjelasan selengkapanya.

 

A. Instansiasi Module Tanpa Deklarasi Parameter

Instansiasi module tanpa deklarasi parameter dapat dilakukan berdasarkan koneksi port-nya, yaitu koneksi berdasar urutan port (Port order connection) dan koneksi berdasar nama port (Port name connection). Untuk sintaksis penulisannya, silakan melihat Syntax 5 dan Syntax 6.

Syntax 5: Port order connection

Syntax 6: Port name connection

Penjelasan syntax 5 dan 6:

  1. Port order connection: Mencantumkan sinyal dalam urutan yang sama dengan daftar port dalam definisi modul. Port yang tidak terhubung ditandai dengan dua tanda koma tanpa sinyal yang tercantum.
  2. Port name connection: mencantumkan nama port dan sinyal yang terhubung dengannya, dalam urutan apa pun.
  3. instance_name: Penulisan instance_name adalah wajib. Digunakan untuk membuat beberapa instance dari modul yang sama unik satu sama lain.
  4. instance_array_range: Penulisan instance_array_range adalah opsional.  Digunakan untuk menginstansiasi beberapa modul, setiap instance terhubung ke bit yang berbeda dari sebuah vektor.
    • Rentang array ditentukan sebagai [left_hand_index : right_hand_index].
    • Jika lebar bit port modul dalam array sama dengan lebar sinyal yang terhubung dengannya, sinyal penuh akan terhubung ke setiap instance modul.
    • Jika lebar bit port modul berbeda dengan lebar sinyal yang terhubung ke port tersebut, setiap instance port modul dihubungkan ke bagian terpilih dari sinyal, dengan indeks instance paling kanan dihubungkan ke bagian paling kanan dari vektor, dan berlanjut ke kiri.
    • Harus ada jumlah bit yang tepat di setiap sinyal untuk terhubung ke semua instance (ukuran sinyal dan ukuran port harus merupakan kelipatan).
    • Array instance ditambahkan di Verilog-1995, tetapi banyak alat perangkat lunak tidak mendukungnya hingga Verilog-2001.
    • Beberapa instance modul juga dapat dibuat menggunakan blok generate (lihat artikel berjudul “Block generate pada Pemrograman Verilog”).

 

Program 6: Contoh instansiasi module tanpa deklarasi parameter

Penjelasan Program 6:

Module “Reg4”
Modul “reg4” adalah modul utama yang menginstansiasi modul “dff” sebanyak dua kali. Modul ini memiliki tiga port, yaitu:

  • Port “q”: Input 4-bit yang merepresentasikan nilai register.
  • Port “d”: Input 4-bit yang merepresentasikan data yang akan disimpan di register.
  • Port “clk”: Output clock yang merepresentasikan sinyal clock untuk mengupdate nilai register

 

Dalam modul “reg4”, terdapat dua instansiasi modul “dff”, yaitu:

  • Instansiasi “u1”: Instansiasi pertama dengan menggunakan metode port order connection, yaitu dengan menyebutkan nama port sesuai dengan urutan deklarasi port di modul “dff”`. Namun, port “qb” tidak dihubungkan.
  • Instansiasi “u2”: Instansiasi kedua dengan menggunakan metode port name connection, yaitu dengan menyebutkan nama port secara eksplisit menggunakan sintaks “.nama_porta(nama_port)”.

 

Module “DFF”
Modul “dff” adalah modul yang diinstansiasi oleh modul “reg4”. Modul ini memiliki empat port, yaitu:

  • Port “q”: Output yang merepresentasikan nilai register.
  • Port “qb”: Output yang merepresentasikan nilai invers dari “q”.
  • Port “data”: Input yang merepresentasikan data yang akan disimpan di register.
  • Port “clk”: Input clock yang merepresentasikan sinyal clock untuk mengupdate nilai register

 

Didalam modul “dff”, terdapat dua pernyataan:

  • dff_udp #(delay) (q, data, clk); : Pernyataan ini menginstansiasi modul “dff_udp” dengan “delay” selama 1ns untuk mengatur waktu tunda (delay) untuk mengupdate nilai register dan menghubungkan port “q”, “data”, dan “clk” ke modul “dff_udp”.
  • not (qb, q);  : Pernyataan ini menginstansiasi gerbang logika NOT yang menghasilkan nilai invers dari “q” dan menghubungkan keluarannya ke port “qb”.

 

B. Instansiasi Module dengan Deklarasi Parameter

Nilai parameter dalam suatu modul dapat didefinisikan ulang untuk setiap instansiasi module. Hanya deklarasi parameter yang dapat didefinisikan ulang, sedangkan konstanta localparam dan specparam tidak dapat didefinisikan ulang.

Berdasar cara melakukan definisi ulang (redefine) nilai parameter, instansiasi module yang menggunakan parameter dengan mengikuti standard Verilog-2001/2005 terdapat tiga model sintaksis, yaitu sebagai berikut:

 

1. Definisi ulang eksplisit menggunakan pernyataan defparam dengan nama hierarkis parameter.

Syntax 7: Explicit Parameter Redefinition

 

2. Definisi ulang implisit menggunakan tanda hastag “#” sebagai bagian dari instansiasi module. Nilai parameter didefinisikan ulang dalam urutan yang sama seperti saat dideklarasikan di dalam module.

Syntax 8: Implicit Parameter Redefinition

 

3. Definisi ulang eksplisit menggunakan tanda hastag “#” sebagai bagian dari instansiasi module. Nilai parameter dapat didefinisikan ulang dalam urutan apa pun. Definisi ulang parameter eksplisit ditambahkan pada standard Verilog-2001.

Syntax 7: Explicit Parameter Redefinition (added in Verilog-2001)

Berikut ini merupakan contoh instansiasi module dengan deklarasi parameter (Program 7).

 

Program 7: Contoh instansiasi module dengan deklarasi parameter

Penjelasan Program 7:

 

– Module Main:
Modul “main” adalah modul utama yang menginstansiasi modul “dff” sebanyak tiga kali. Modul ini memiliki tiga port, yaitu:

  • Port “q”: Output 4-bit yang merepresentasikan nilai register.
  • Port “d”: Input 4-bit yang merepresentasikan data yang akan disimpan di register.
  • Port “clk”: Input clock yang merepresentasikan sinyal clock untuk mengupdate nilai register.

 

Dalam modul “main”, terdapat tiga instansiasi modul “dff” dengan cara yang berbeda-beda:

  • Instansiasi “u3”: instansiasi pertama dengan menggunakan metode port order connection, yaitu dengan menyebutkan nama port sesuai dengan urutan deklarasi porta di modul “dff”. Namun, port “qb” tidak dihubungkan. Selain itu, parameter “delay” di modul “dff” diubah menjadi 3.2 menggunakan pernyataan “defparam”.
  • Instansiasi “u4”: instansiasi kedua dengan menggunakan metode port order connection, namun port “qb” tidak dihubungkan dan metode implicit parameter redefinition, yaitu parameter “delay” pada modul “dff” diubah menjadi 2 menggunakan syntax “#(2)”.
  • Instansiasi “u5”: instansiasi ketiga dengan menggunakan metode port order connection, namun port “qb” tidak dihubungkan dan metode explicit parameter redefinition, yaitu parameter “delay” di modul “dff” diubah menjadi 3 menggunakan syntax “#(.delay(3))”.

 

– Penggunaan Defparam
Pernyataan “defparam” digunakan untuk mengubah nilai parameter pada modul yang diinstansiasi. Dalam contoh ini, “defparam” digunakan untuk mengubah (redefine) nilai parameter “delay” pada modul “dff” u3 menjadi 3.2.

 

– Penggunaan Implicit dan Explicit Parameter Redefinition

  • Implicit parameter redefinition adalah cara untuk mengubah nilai parameter di modul yang diinstansiasi tanpa secara eksplisit menyebutkan nama parameter. Dalam contoh ini, syntax “#(2)” digunakan untuk mengubah nilai parameter “delay” di modul “dff” u4 menjadi 2.
  • Explicit parameter redefinition adalah cara untuk mengubah nilai parameter di modul yang diinstansiasi dengan secara eksplisit menyebutkan nama parameter. Dalam contoh ini, syntax “#(.delay(3))” digunakan untuk mengubah nilai parameter “delay” di modul “dff” u5 menjadi 3.

 

– Module DFF:
Modul “dff” adalah modul yang diinstansiasi oleh modul “main”. Modul ini memiliki empat port, yaitu:

  • Port “q”: Output yang merepresentasikan nilai register.
  • Port “qb”: Output yang merepresentasikan nilai invers dari “q”.
  • Port “data”: Input yang merepresentasikan data yang akan disimpan di register.
  • Port ”clk”: Input clock yang merepresentasikan sinyal clock untuk mengupdate nilai register

 

Modul “dff” juga memiliki parameter “delay” yang nilai default-nya adalah 1. Parameter ini digunakan untuk mengatur waktu tunda (delay) untuk mengupdate nilai register.

Di dalam modul “dff”, terdapat dua pernyataan:

  • dff_udp #(delay) (q, data, clk);  : Pernyataan ini menginstansiasi modul “dff_udp” dengan parameter “delay” dan menghubungkan port “q”, “data”, dan “clk” ke modul “dff_udp”.
  • not (qb, q); : Pernyataan ini menginstansiasi gerbang logika NOT yang menghasilkan nilai invers (kebalikan) dari sinyal output port “q” dan menghubungkan keluarannya ke port “qb”.

 

Author

Taufiq Dwi Septian Suyadhi

Degrees from electronics and industrial engineering. Enthusiast on electronics, embedded systems, and robotics. Motivation: “Never ending learning and sharing valuable knowledge to the others”.

Leave a Reply

Post Related

error: Content is protected !!