Menguasai Fungsi Verilog untuk Desain RTL yang Efisien
Seringkali kita menemukan potongan kode yang berulang dan dipanggil beberapa kali dalam RTL. Sebagian besar tidak mengonsumsi waktu simulasi dan mungkin melibatkan perhitungan kompleks yang perlu dilakukan dengan nilai data yang berbeda. Dalam kasus tersebut, kita dapat mendeklarasikan function dan menempatkan kode berulang di dalam fungsi dan mengizinkannya untuk mengembalikan hasil. Ini akan mengurangi jumlah baris dalam RTL secara drastis karena yang perlu Anda lakukan sekarang adalah melakukan panggilan fungsi dan melewatkan data yang komputasi perlu dilakukan. Faktanya, ini sangat mirip dengan fungsi dalam C.
Tujuan dari sebuah fungsi adalah untuk mengembalikan nilai yang akan digunakan dalam ekspresi. Definisi fungsi selalu dimulai dengan kata kunci function diikuti oleh tipe pengembalian, nama, dan daftar port yang dibungkus dalam tanda kurung. Verilog tahu bahwa definisi fungsi selesai saat menemukan kata kunci endfunction. Perhatikan bahwa sebuah fungsi harus memiliki setidaknya satu input yang dideklarasikan dan tipe pengembalian akan menjadi void jika fungsi tidak mengembalikan apa pun.
Sintaks
function [automatic] [return_type] name ([port_list]);
[statements]
endfunction
Kata kunci automatic akan membuat fungsi reentrant dan item yang dideklarasikan dalam tugas dialokasikan secara dinamis daripada dibagikan antara berbagai pemanggilan tugas. Ini akan berguna untuk fungsi rekursif dan ketika fungsi yang sama dieksekusi secara bersamaan oleh N proses saat di-fork.
Deklarasi Fungsi
Terdapat dua cara untuk mendeklarasikan input ke sebuah fungsi:
function [7:0] sum;
input [7:0] a, b;
begin
sum = a + b;
end
endfunction
function [7:0] sum (input [7:0] a, b);
begin
sum = a + b;
end
endfunction
Mengembalikan Nilai dari Fungsi
Definisi fungsi akan secara implisit membuat variabel internal dengan nama yang sama dengan fungsi. Oleh karena itu ilegal untuk mendeklarasikan variabel lain dengan nama yang sama dalam cakupan fungsi. Nilai pengembalian diinisialisasi dengan menugaskan hasil fungsi ke variabel internal.
sum = a + b;
Memanggil Fungsi
Sebuah panggilan fungsi adalah operand dengan ekspresi dan memiliki sintaks seperti yang ditunjukkan di bawah ini.
reg [7:0] result;
reg [7:0] a, b;
initial begin
a = 4;
b = 5;
#10 result = sum (a, b);
end
Aturan Fungsi
- Fungsi tidak boleh berisi pernyataan yang dikontrol waktu seperti #, @, wait, posedge, negedge
- Fungsi tidak dapat memulai tugas karena mungkin mengonsumsi waktu simulasi, tetapi dapat memanggil fungsi lain
- Fungsi harus memiliki setidaknya satu input
- Fungsi tidak boleh memiliki penugasan non-blokir atau
force-release atau assign-deassign - Fungsi tidak boleh memiliki pemicu apa pun
- Fungsi tidak boleh memiliki output atau inout
Fungsi Rekursif
Fungsi yang memanggil dirinya sendiri disebut fungsi rekursif. Dalam contoh yang ditunjukkan di bawah ini, fungsi rekursif ditulis untuk menghitung faktorial dari suatu angka yang diberikan.
module tb;
initial begin
integer result = factorial(4);
$display("factorial(4) = %0d", result);
end
function automatic integer factorial(integer i);
integer result = i;
// This function is called within the body of this
// function with a different argument
if (i) begin
result = i * factorial(i-1);
$display("i=%0d result=%0d", i, result);
end else result = 1;
return result;
endfunction
endmodule
Log Simulasi
xcelium> run
i=1 result=1
i=2 result=2
i=3 result=6
i=4 result=24
factorial(4) = 24
xmsim: *W,RNQUIE: Simulation is complete