🔧 Verilog’ta Task ve Function Kullanımı#
Task ve function yapıları, tekrarlayan kodları azaltmak ve yeniden kullanılabilir mantık blokları oluşturmak için kullanılır. Özellikle testbench ve simülasyon senaryolarında kodun okunabilirliğini artırır.
📌 task
#
Task yapıları, şu özelliklere sahiptir:
- Birden fazla giriş ve çıkış alabilir.
- Zamanlama kontrolleri içerebilir (
#
,@
,wait
gibi). - Diğer task veya function bloklarını çağırabilir.
- Eğer yerel değişken tanımlanmazsa, global değişkenleri değiştirebilir.
assign
içinde kullanılamaz.
✅ Örnek:#
task convert;
input [7:0] adc_in;
output [7:0] out;
begin
out = (9/5) * (adc_in + 32);
end
endtask
🔔 Kullanım:#
always @(adc_a) convert(adc_a, adc_a_conv);
📌 function
#
Function yapıları saf mantık işlemleri için kullanılır:
- Sıfır zaman içinde çalışmalıdır.
- Sadece tek bir değer döndürür.
- İçinde
#
,@
,wait
,posedge
gibi zamanlama ifadeleri kullanılamaz. - Sadece diğer function’ları çağırabilir, task çağrısı yapılamaz.
assign
ifadelerinde kullanılabilir.
✅ Örnek:#
function [7:0] myfunction;
input [3:0] a, b, c, d;
begin
myfunction = ((a + b) + (c - d));
end
endfunction
🔔 Kullanım:#
assign f = myfunction(a, b, c, d) ? e : 8'd0;
🧠 Karşılaştırma Tablosu#
Özellik | task | function |
---|---|---|
Dönüş Değeri | output portlar ile (birden fazla olabilir) | Tek bir değer döndürür |
Zamanlama | # , @ , wait gibi ifadeler kullanılabilir | Zamanlama ifadesi kullanılamaz |
İfade içinde kullanım | ❌ Kullanılamaz | ✅ Kullanılabilir |
Çağırma | Diğer task/function çağrabilir | Sadece function çağırabilir |
Kullanım Amacı | Prosedürel ve zamanlamalı işlemler | Kombinasyonel mantık |
Delay / Event | Kullanılabilir | Yasaktır |
⚠️ En İyi Kullanım Önerileri#
- Zamanlama içeren prosedürler için
task
kullanın.- Kombinasyonel hesaplamalar için
function
tercih edin.- Blokları modüler ve kısa tutmaya çalışın (tercihen 20 satırdan az).
module tb_task_function;
reg [7:0] adc_a = 8'd50;
wire [7:0] adc_a_conv;
wire [7:0] f;
reg [3:0] a = 1, b = 2, c = 5, d = 3, e = 8;
// Task usage
reg [7:0] adc_conv_result;
always @(*) convert(adc_a, adc_conv_result);
assign adc_a_conv = adc_conv_result;
// Function usage
assign f = myfunction(a, b, c, d) ? e : 8'd0;
// Task definition
task convert;
input [7:0] adc_in;
output [7:0] out;
begin
out = (9/5) * (adc_in + 32);
end
endtask
// Function definition
function [7:0] myfunction;
input [3:0] a, b, c, d;
begin
myfunction = ((a + b) + (c - d));
end
endfunction
endmodule