Paliwanag sa mga Function ng Verilog: Sintaks, Mga Halimbawa, at Pagkakaiba sa mga Gawain

目次

1. Ano ang Verilog Function? (Pangunahing Konsepto at Papel)

Ang Verilog HDL (Hardware Description Language) ay isang wika para sa paglalarawan ng hardware na ginagamit sa pagdidisenyo at pagsasagawa ng simulation ng mga digital na circuit. Sa mga tampok nito, ang function ay isang mekanismo na nagpapahintulot sa iyo na i-modularize ang mga tiyak na operasyon at gawing muling magamit. Ang pag-unawa sa mga Verilog function ay hindi lamang nagpapabuti sa nababasa at napapanatiling code, kundi nagdudulot din ng mas epektibong disenyo ng circuit. Sa artikulong ito, ipapaliwanag namin ang pangunahing konsepto ng mga Verilog function at kung paano ito ginagamit sa totoong disenyo.

Ano ang function?

Ang Verilog function ay isang bloke na nagsasagawa ng tiyak na kalkasyon o operasyon at nagbabalik ng isang solong halaga. Sa pamamagitan ng paggamit ng mga function, maaari mong bawasan ang paulit-ulit na code at gawing mas simple ang paglalarawan ng iyong circuit.

Pangunahing Katangian ng mga Function

  • Maaaring magtakda ng isa o higit pang input (tanging input lamang ang pinapayagan)
  • Isang output lamang (ang return value ng function)
  • Hindi pinapayagan ang mga time delay (hal., #10)
  • Dapat laging maglarawan ng combinational logic ang mga function
  • Ang mga function ay tinutukoy sa labas ng mga always block at agad na sinusuri (hindi tulad ng mga task)

Kailan Gagamitin ang mga Verilog Function

Ang mga Verilog function ay karaniwang ginagamit sa mga sumusunod na sitwasyon:

1. Paglalarawan ng Combinational Logic

Dahil agad na nagbabalik ng resulta ang mga function batay sa mga input, madalas itong gamitin sa combinational logic. Halimbawa: pagdaragdag, pagbabawas, mga encoder, decoder, at iba pang arithmetic na operasyon.

2. Pagpapabuti ng Reusability ng Code

Maaari mong alisin ang paulit-ulit na code sa pamamagitan ng pagsasama ng madalas gamitin na lohika sa mga function. Halimbawa: gawing function ang isang komplikadong conditional expression upang mapabuti ang nababasa sa loob ng isang module.

3. Pagbawas ng mga Error sa Disenyo

Sa pamamagitan ng pagsentro ng mga kalkulasyon o lohikal na operasyon sa isang function, maaari mong mabawasan ang mga pagkakamali kapag nagbabago ng code. Halimbawa: mga kalkulasyon ng CRC (Cyclic Redundancy Check) o parity checks.

Pagkakaiba ng mga Function at Task

Sa Verilog, may isa pang konstruksyon na tinatawag na task. Bagaman magkatulad ang mga function at task, may mga mahalagang pagkakaiba:
ItemPunsyonGawain
KinalabasanIsa lamangMaramihang pinapayagan
IpasokOoOo
Local VariablesPinapayaganPinahintulutan
Pagkaantala (#10)Hindi pinapayaganPinapayagan
Paggamit sa loob ng alwaysPinahintulutanHindi pinapayagan
Invocationfunction_name(arguments)task_name(arguments);

Kailan Gagamitin ang Function

  • Kapag kailangan mo ng agarang resulta ng kalkulasyon
  • Para sa lohika na walang kasamang delay
  • Kapag sapat na ang isang solong return value

Kailan Gagamitin ang Task

  • Kapag ang proseso ay may kasamang delay (hal., #10)
  • Kapag kailangan ng maraming output
  • Para sa simulation/debug na layunin (hal., log output)

Buod

  • Ang Verilog function ay isang function na tumatanggap ng mga input at nagbabalik ng isang solong halaga.
  • Pinakamainam itong gamitin para sa paglalarawan ng combinational logic at hindi maaaring maglaman ng delay.
  • Kapaki-pakinabang para mabawasan ang paulit-ulit na code at mapabuti ang nababasa.
  • May pagkakaiba ang mga function at task; ang pagpili ng tama ay depende sa gamit.

2. Paano Sumulat ng Verilog Function [Beginner-Friendly Example]

Sa nakaraang seksyon, tinalakay natin ang pangunahing konsepto ng mga Verilog function. Dito, susuriin natin ang aktwal na syntax at kung paano sumulat ng mga Verilog function sa praktika.

Pangunahing Syntax ng isang Function

Isinusulat ang isang Verilog function gamit ang sumusunod na pangkalahatang syntax:
function [output_bit_width] function_name;
    input [input_bit_width] input1, input2, ...;
    begin
        function_name = expression;
    end
endfunction

Mahahalagang Punto

  • Ideara gamit ang keyword na function
  • Ang return value ay itinalaga sa isang variable na may parehong pangalan ng function
  • Ideklara ang mga input gamit ang input (hindi maaaring gumamit ng output o inout)
  • Isagawa ang mga kalkulasyon sa loob ng begin ... end
  • Tukuyin ang function sa labas ng isang always block

Simpleng Halimbawa ng Verilog Function

Ang sumusunod na halimbawa ay nagpapakita ng isang function na nagsasagawa ng 8-bit addition:
module example;
    function [7:0] add_function;
        input [7:0] a, b;
        begin
            add_function = a + b;
        end
    endfunction

    reg [7:0] x, y, sum;

    initial begin
        x = 8'b00001100; // 12
        y = 8'b00000101; // 5
        sum = add_function(x, y);
        $display("Sum: %d", sum); // Sum: 17
    end
endmodule

Paliwanag

  • add_function ay tumatanggap ng dalawang 8-bit na input (a at b) at nagbabalik ng kanilang kabuuan
  • Tinatawag ang function gamit ang sum = add_function(x, y); at inilalagay ang resulta sa sum
  • Ang initial block ay gumagamit ng $display upang ipakita ang resulta

Pagdedeklara ng mga Input Output sa isang Function

Pagdedeklara ng mga Input

Ang isang Verilog function ay maaari lamang tumanggap ng mga input na argumento.
function [7:0] my_function;
    input [7:0] in1, in2;
    begin
        my_function = in1 & in2; // AND operation
    end
endfunction
Tandaan: Hindi mo maaaring magdeklara ng output sa isang function. Ang return value ay palaging ang variable na may parehong pangalan tulad ng function.

Function na may Conditional Statements

Maaari mo ring gamitin ang mga if o case na pahayag sa loob ng isang function.
function [3:0] max_function;
    input [3:0] a, b;
    begin
        if (a > b)
            max_function = a;
        else
            max_function = b;
    end
endfunction
Ang function na ito ay nagbabalik ng mas malaking halaga sa pagitan ng a at b.

Buod

  • Ang isang Verilog function ay tinutukoy gamit ang keyword na function at nagbabalik ng isang solong halaga
  • Tanging input na mga argumento lamang ang pinapayagan (walang output)
  • Ang return value ay inilalagay sa variable na may parehong pangalan tulad ng function
  • Ang mga pahayag na if at case ay maaaring gamitin para sa conditional logic

3. Paano Gamitin ang Verilog Functions [With Practical Code Examples]

Sa nakaraang seksyon, natutunan natin ang pangunahing syntax at kung paano sumulat ng Verilog functions. Dito, ipapaliwanag natin kung paano ilapat ang mga function sa totoong disenyo gamit ang mga praktikal na halimbawa.

Paano Tumawag ng Function

Ang isang Verilog function ay tinatawag katulad ng karaniwang pag-aassign ng variable, gamit ang format na function_name(arg1, arg2, ...). Ang sumusunod na halimbawa ay nagde-define ng 8-bit XOR function at ginagamit ito sa loob ng isang module:
module function_example;
    function [7:0] xor_function;
        input [7:0] a, b;
        begin
            xor_function = a ^ b;
        end
    endfunction

    reg [7:0] x, y, result;

    initial begin
        x = 8'b11001100;
        y = 8'b10101010;
        result = xor_function(x, y); // calling the function
        $display("XOR Result: %b", result); // XOR Result: 01100110
    end
endmodule

Mahahalagang Punto

  • Tinatawag ang isang function sa anyong variable = function(arguments);
  • Maaari itong gamitin sa loob ng mga always o initial na block
  • Ang mga function ay gumagana bilang combinational logic

Paggamit ng mga Function sa Combinational Logic

Dahil ang mga Verilog function ay palaging sinusuri kaagad, kapaki-pakinabang ang mga ito sa pagbuo ng combinational logic. Ipinapakita ng sumusunod na halimbawa ang 2-to-4 decoder na ipinatupad gamit ang isang function:
module decoder_example;
    function [3:0] decoder;
        input [1:0] sel;
        begin
            case (sel)
                2'b00: decoder = 4'b0001;
                2'b01: decoder = 4'b0010;
                2'b10: decoder = 4'b0100;
                2'b11: decoder = 4'b1000;
                default: decoder = 4'b0000;
            endcase
        end
    endfunction

    reg [1:0] select;
    wire [3:0] decoded_output;

    assign decoded_output = decoder(select); // using the function

    initial begin
        select = 2'b01;
        #10; // add delay to observe simulation changes
        $display("Decoded Output: %b", decoded_output); // Decoded Output: 0010
    end
endmodule
  • Ang decoder function nagko-convert ng 2-bit na input tungo sa 4-bit na decoder output
  • Gumagamit ng case statement upang magpasya ng output base sa input
  • Ang assign ay ginagamit upang i-map ang output ng function sa decoded_output → Ang function ay gumagana bilang bahagi ng combinational logic

Mga Function vs. Always Blocks [Comparison Table]

Parehong ginagamit ang mga Verilog function at always block upang ilarawan ang lohika, ngunit magkaiba ang kanilang layunin at mga limitasyon.
ItemPunsyonLaging Harang
Lokasyon ng DepinisyonSa labas ng always na mga blokeSa loob ng always na mga bloke
Mga Inputinputregwire
Mga OutputIsang halaga lamangMaaari mag-update ng maraming halaga
Pagkaantala (#10)Hindi pinapayaganPinapayagan
Pagpapanatili ng EstadoHindi pinapayaganPinahintulutan
Main UsageKombinasyonal na lohikaSunud-sunod na lohika o pagproseso batay sa pangyayari

Mga Pangunahing Patnubay

  • Gumamit ng mga function upang pasimplehin ang mga simpleng operasyon ng lohika (combinational logic)
  • Gumamit ng always block para sa mga circuit na nagtataglay ng estado (hal., flip-flops)
  • Kung kailangan mo ng mga delay (tulad ng #10), gumamit ng always block imbis na function

Buod: Paano Gamitin ang Verilog Functions

✅ Tawagin ang isang function gamit ang function_name(arguments)Ang mga function ay pinakamainam para sa combinational logic at naiiba sa always block ✅ Gumamit ng case o if statements upang ilarawan ang flexible na lohika ✅ Kapaki-pakinabang para sa mga decoder, arithmetic operations, at iba pa

4. Praktikal na Aplikasyon ng Verilog Functions (Disenyo ng Decoder at ALU)

Sa ngayon, natutunan na natin ang pangunahing syntax at paggamit ng Verilog functions. Sa seksyong ito, titingnan natin kung paano ilapat ang mga function sa totoong disenyo ng digital circuit, gamit ang decoder at ALU (Arithmetic Logic Units) bilang mga halimbawa.

Implementasyon ng Function para sa Decoder (2-to-4 Decoder)

Ang decoder ay isang circuit na nagko-convert ng maliit na bilang ng input bits patungo sa mas malaking bilang ng output bits. Halimbawa, ang 2-to-4 decoder ay nagko-convert ng 2-bit na input tungo sa 4-bit na output. I-implement natin ito gamit ang isang function:
module decoder_example;
    function [3:0] decoder;
        input [1:0] sel;
        begin
            case (sel)
                2'b00: decoder = 4'b0001;
                2'b01: decoder = 4'b0010;
                2'b10: decoder = 4'b0100;
                2'b11: decoder = 4'b1000;
                default: decoder = 4'b0000;
            endcase
        end
    endfunction

    reg [1:0] select;
    wire [3:0] decoded_output;

    assign decoded_output = decoder(select); // using the function

    initial begin
        select = 2'b00; #10;
        $display("Decoded Output: %b", decoded_output);
        select = 2'b01; #10;
        $display("Decoded Output: %b", decoded_output);
        select = 2'b10; #10;
        $display("Decoded Output: %b", decoded_output);
        select = 2'b11; #10;
        $display("Decoded Output: %b", decoded_output);
    end
endmodule

Implementasyon ng Function para sa ALU (Addition, Subtraction, AND, OR)

Ang ALU (Arithmetic Logic Unit) ay ang pangunahing circuit ng CPU, na responsable sa pagsasagawa ng mga arithmetic at logic na operasyon tulad ng addition, subtraction, AND, at OR. Dito, magdidisenyo tayo ng simpleng 8-bit na ALU gamit ang isang Verilog function:
module alu_example;
    function [7:0] alu;
        input [7:0] a, b;
        input [1:0] op; // 2-bit control signal
        begin
            case (op)
                2'b00: alu = a + b; // Addition
                2'b01: alu = a - b; // Subtraction
                2'b10: alu = a & b; // AND
                2'b11: alu = a | b; // OR
                default: alu = 8'b00000000;
            endcase
        end
    endfunction

    reg [7:0] x, y;
    reg [1:0] opcode;
    wire [7:0] result;

    assign result = alu(x, y, opcode); // using the function

    initial begin
        x = 8'b00001100; // 12
        y = 8'b00000101; // 5

        opcode = 2'b00; #10;
        $display("Addition Result: %d", result); // 12 + 5 = 17

        opcode = 2'b01; #10;
        $display("Subtraction Result: %d", result); // 12 - 5 = 7

        opcode = 2'b10; #10;
        $display("AND Result: %b", result); // AND operation

        opcode = 2'b11; #10;
        $display("OR Result: %b", result); // OR operation
    end
endmodule

Buod

Maaaring magamit nang epektibo ang mga function sa mga kombinasyonal na sirkito tulad ng mga decoder at ALUAng paggamit ng case statements ay nagbibigay-daan sa flexible na paglalarawan ng operasyonPinapabuti ng mga function ang nababasa at ginagawang mas muling magamit ang disenyoAng mga function ay pinakaangkop para sa kombinasyonal na lohika, ngunit hindi para sa sequential na mga sirkito (dahil hindi ito maaaring maglaman ng mga delay)

5. Mahahalagang Pagsasaalang-alang sa Paggamit ng Verilog Functions

Ang mga Verilog function ay makapangyarihang kasangkapan na nagpapabuti sa nababasa ng code at muling magamit, ngunit may ilang limitasyon din ito. Sa seksyong ito, ipapaliwanag namin ang mga pangunahing punto na dapat mong malaman kapag gumagamit ng mga function.

Hindi Pinapayagan ang Recursive Calls

Sa mga Verilog function, pinagbabawalan ang recursive calls. Ibig sabihin, hindi maaaring tawagin ng isang function ang sarili nito sa loob ng kanyang katawan.

❌ Halimbawa NG: Recursive Function

function [3:0] factorial;
    input [3:0] n;
    begin
        if (n == 0)
            factorial = 1;
        else
            factorial = n * factorial(n - 1); // ❌ Recursive call not allowed
    end
endfunction
Magdudulot ang code na ito ng simulation error.

✅ Solusyon: Gumamit ng Loops Sa Halip

Kung kailangan ang recursion, gumamit ng loop sa loob ng always block o task sa halip.
task factorial_task;
    input [3:0] n;
    output [15:0] result;
    integer i;
    begin
        result = 1;
        for (i = 1; i <= n; i = i + 1)
            result = result * i;
    end
endtask
Sa pamamagitan ng paggamit ng loops, maiiwasan ang recursion.

Hindi Maaaring Gamitin ang Time Delays (#10) sa Loob ng Functions

Dahil ang mga Verilog function ay agad na ine-evaluate (gumagana bilang kombinasyonal na lohika), hindi ito maaaring maglaman ng mga time delay tulad ng #10.

❌ Halimbawa NG: Delay Sa Loob ng Function

function [7:0] delay_function;
    input [7:0] in;
    begin
        #10; // ❌ Delay not allowed inside functions
        delay_function = in + 1;
    end
endfunction
Magdudulot ang code na ito ng compilation error.

✅ Solusyon: Gumamit ng Always Blocks Sa Halip

Kung kailangan ang mga delay, gumamit ng always task sa halip na function.
task delay_task;
    input [7:0] in;
    output [7:0] out;
    begin
        #10;
        out = in + 1;
    end
endtask
Sa madaling salita, gamitin ang mga task para sa mga operasyon na may kasamang delay.

Pagpili sa Pagitan ng Functions at Tasks

Sa Verilog, parehong functions at tasks ang umiiral. Bagaman magkatulad ang itsura, may iba’t ibang gamit ang mga ito at dapat piliin nang naaayon.
ItemPunsyonGawain
KinalabasanIsa lamangMaramihang pinapayagan
Ipasokinputinputoutput
Local VariablesPinapayaganPinahintulutan
Pagkaantala (#10)Hindi pinapayaganPinahintulutan
Paggamit sa loob ng alwaysPinapayaganHindi pinapayagan
Invocationfunction_name(arguments)task_name(arguments);

Kailan Gagamitin ang Function

✅ Kapag kailangan mo ng agarang resulta ng kalkulasyon (hal., pagdaragdag, pagbabawas, mga operasyon sa lohika) ✅ Para sa paglalarawan ng kombinasyonal na lohika nang walang delay ✅ Kapag isang solong return value lamang ang kinakailangan

Kailan Gagamitin ang Task

✅ Kapag kinakailangan ang mga delay (#10, atbp.) ✅ Kapag maramihang output ang kailangan ✅ Para sasimulation/debug na mga operasyon** (monitoring, display, atbp.)

Hindi Maaaring Idefine ang Functions sa Loob ng Always Blocks

Ang mga Verilog function hindi maaaring idefine sa loob ng always block. Dapat idefine ang function sa labas at tawagin ito sa loob ng always.

❌ Halimbawa NG: Pagde-define ng Function Sa Loob ng Always

always @(a or b) begin
    function [7:0] my_function; // ❌ Not allowed inside always
        input [7:0] x, y;
        begin
            my_function = x + y;
        end
    endfunction
end
Magdudulot ang code na ito ng compilation error.

✅ Tamang Halimbawa

Idefine ang function sa labas ng always at tawagin ito sa loob:
function [7:0] add_function;
    input [7:0] x, y;
    begin
        add_function = x + y;
    end
endfunction

always @(a or b) begin
    result = add_function(a, b); // ✅ call the function
end

Buod

May ilang limitasyon ang mga Verilog functionWalang recursive na tawag (gumamit ng mga loop o task imbes) ✅ Walang delay (#10) (gumamit ng always o task imbes) ✅ Hindi maaaring ideklara sa loob ng always block (kailangang ilagay sa labas) ✅ Isang return value lamang (gamitin ang mga task kung kailangan ng maraming output) ✅ Gamitin nang tama ang mga function at task batay sa sitwasyon

6. [FAQ] Mga Madalas Itanong Tungkol sa Verilog Functions

Sa ngayon, natalakay na natin ang mga pangunahing kaalaman, advanced na paggamit, at mahahalagang konsiderasyon ng Verilog functions. Sa seksyong ito, binubuod namin ang mga madalas itanong at sagot tungkol sa Verilog functions.

Ano ang pagkakaiba ng function at task?

Q. Ano ang pagkakaiba ng Verilog function at task? Alin ang dapat kong gamitin?

A. Ginagamit ang function kapag kailangan mong “agad na magbalik ng isang solong halaga,” samantalang ginagamit ang task kapag kailangan mo ng “maramihang output o mga operasyon na may kasamang delay.”

ItemGawainGawain
KinalabasanIsa lamangMaramihang pinapayagan
Ipasokinputinputoutput
Local VariablesapayaganPinahintulutan
Pagkaantala (#10)Hindi pinapayaganPinahintulutan
Paggamit sa loob ng alwaysPinapayaganHindi pinapayagan
Invocationfunction_name(arguments)task_name(arguments);

Kailan Dapat Gumamit ng Function

✅ Kapag kailangan mo ng agarang resulta ng kalkulasyon (hal., pagdaragdag, pagbabawas, lohikal na operasyon) ✅ Para sa paglalarawan ng combinational logic nang walang delay ✅ Kapag isang return value lamang ang kailangan

Kailan Dapat Gumamit ng Task

✅ Kapag kailangan mo ng mga delay (hal., #10) ✅ Kapag maramihang output ang kinakailangan ✅ Kapag sumusulat ng debug/monitoring code para sa simulation

Maaari ko bang gamitin ang reg sa loob ng isang function?

Q. Maaari ba akong magdeklara ng mga variable na reg sa ng isang function?

A. Hindi, hindi mo maaaring gamitin ang reg sa loob ng function, pero maaari kang gumamit ng integer imbes.

Sa mga Verilog function, hindi ka maaaring magdeklara ng mga variable na uri ng reg, pero maaari mong gamitin ang integer para sa mga kalkulasyon.

✅ Tamang Halimbawa (Gumagamit ng integer)

function [7:0] multiply;
    input [3:0] a, b;
    integer temp;
    begin
        temp = a * b;
        multiply = temp;
    end
endfunction

Kailan dapat akong gumamit ng mga function?

Q. Sa anong mga sitwasyon angkop na gumamit ng mga function?

A. Ang mga function ay pinakaangkop para sa “simpleng arithmetic operations” at “combinational logic.”

Mga halimbawa kung saan kapaki-pakinabang ang mga function ay kinabibilangan ng:
  • Mga operasyon sa arithmetic (pagdaragdag, pagbabawas, lohika)
  • Mga decoder at encoder
  • Mga paghahambing (paghanap ng pinakamataas/pinakamababa na halaga)
  • Pagpapatunay ng error (hal., parity check)
Gayunpaman, hindi angkop ang mga function para sa mga sequential circuit na may kasamang flip-flops.

Maaari bang tumawag ang isang function sa ibang function?

Q. Maaari bang tumawag ang isang Verilog function sa ibang function sa loob nito?

A. Oo, maaaring tumawag ang isang function sa ibang function, pero mag-ingat sa mga dependency.

function [7:0] add;
    input [7:0] a, b;
    begin
        add = a + b;
    end
endfunction

function [7:0] double_add;
    input [7:0] x, y;
    begin
        double_add = add(x, y) * 2; // calling another function
    end
endfunction

Paano ko dapat piliin sa pagitan ng mga function at always block?

Q. Paano ko dapat magpasya kung gagamit ng function o always block?

A. Ginagamit ang mga function para sa “combinational logic,” samantalang ginagamit ang mga always block para sa “sequential logic.”

ItemPunsyonPalaging Harang
Pagkaantala (#10)Hindi pinapayaganPinahintulutan
Pagpapanatili ng EstadoHindi pinapayaganPinahintulutan
Pangunahing PaggamitKombinasyunal na lohika (agad-agad na kalkulasyon)Sequential na lohika (flip-flops, mga bilang)
Halimbawa, kapag gumagawa ng pagdaragdag:

✅ Function (Combinational Logic)

function [7:0] add;
    input [7:0] a, b;
    begin
        add = a + b;
    end
endfunction

✅ Always Block (Sequential Logic)

always @(posedge clk) begin
    sum <= a + b; // works as a flip-flop
end

Buod

Ang mga function ay pinakamahusay para sa simpleng operasyon at combinational logicUnawain ang pagkakaiba ng mga function at task at gamitin nang tamaAng mga always block ay para sa sequential logic, ang mga function ay para sa combinational logicHindi maaaring magsama ang mga function ng delay (#10) o arrays — gumamit ng mga task o module imbes