- 1 1. Verilog function คืออะไร? (แนวคิดพื้นฐานและบทบาท)
- 2 2. วิธีเขียน Verilog function【พร้อมตัวอย่างสำหรับผู้เริ่มต้น】
- 3 3. วิธีใช้งาน Verilog function【พร้อมโค้ดตัวอย่างจริง】
- 4 4. ตัวอย่างการประยุกต์ใช้ Verilog function (decoder และ ALU)
- 5 5. ข้อควรระวังในการใช้ Verilog function
- 6 6. 【FAQ】คำถามที่พบบ่อยเกี่ยวกับ Verilog function
1. Verilog function คืออะไร? (แนวคิดพื้นฐานและบทบาท)
Verilog HDL (Hardware Description Language) เป็นภาษาบรรยายฮาร์ดแวร์ที่ใช้สำหรับการออกแบบและการจำลองวงจรดิจิทัล ภายในนั้น function (ฟังก์ชัน) เป็นหนึ่งในกลไกที่ช่วยทำให้โค้ดถูกจัดโมดูลและนำกลับมาใช้ซ้ำได้ง่ายขึ้น
การทำความเข้าใจ Verilog function ไม่เพียงช่วยเพิ่มความสามารถในการอ่านและการบำรุงรักษาโค้ด แต่ยังนำไปสู่การออกแบบวงจรที่มีประสิทธิภาพมากขึ้น บทความนี้จะแนะนำแนวคิดพื้นฐานของ Verilog function และอธิบายวิธีการใช้งาน
function คืออะไร?
Verilog function คือ บล็อกที่ทำการคำนวณหรือประมวลผลเฉพาะแล้วส่งค่าหนึ่งค่าออกมา การใช้ function ช่วยลดความซ้ำซ้อนของโค้ดและทำให้งานออกแบบวงจรง่ายขึ้น
คุณสมบัติของ function
- สามารถกำหนด input ได้มากกว่าหนึ่ง (ใช้ได้เฉพาะ
input
) - output มีเพียงหนึ่งค่า (ค่าที่ return)
- ไม่สามารถใช้การหน่วงเวลา (delay เช่น
#10
) - ภายใน function ต้องอธิบายตรรกะการทำงานแบบ combinational logic เสมอ
- function ต้องถูกประกาศนอก always block และจะถูกประเมินผลทันที ต่างจาก task
กรณีที่ใช้ Verilog function
Verilog function มักถูกใช้งานในกรณีดังต่อไปนี้
1. การอธิบายวงจรแบบ combinational
function จะส่งค่ากลับทันทีตาม input จึงนิยมใช้ใน combinational logic
ตัวอย่าง: การบวก การลบ encoder และ decoder
2. เพิ่มการนำโค้ดกลับมาใช้ซ้ำ
ช่วยลดโค้ดที่ซ้ำซ้อนและรวมการประมวลผลที่ต้องใช้หลายครั้งให้ง่ายขึ้น
ตัวอย่าง: สมการที่ซับซ้อนซึ่งมีการตรวจสอบเงื่อนไข สามารถทำให้เป็น function เพื่อเพิ่มความอ่านง่าย
3. ลดความผิดพลาดในการออกแบบ
การรวมการคำนวณและการดำเนินการทางตรรกะไว้ที่เดียว ช่วยลดความผิดพลาดเมื่อต้องแก้ไข
ตัวอย่าง: การคำนวณ CRC (Cyclic Redundancy Check) หรือ parity check
ความแตกต่างระหว่าง function และ task
ใน Verilog นอกจาก function ยังมี task ซึ่งมีลักษณะคล้ายกัน แต่มีความแตกต่างดังนี้
หัวข้อ | function | task |
---|---|---|
output | มีเพียง 1 ค่า | มีได้หลายค่า |
input | มี | มี |
ตัวแปรภายใน | มี | มี |
delay (#10 ) | ไม่อนุญาต | อนุญาต |
การใช้งานใน always | ได้ | ไม่ได้ |
วิธีเรียกใช้งาน | ชื่อฟังก์ชัน(อาร์กิวเมนต์) | ชื่อตัว task(อาร์กิวเมนต์); |
กรณีที่ควรใช้ function
- เมื่อจำเป็นต้องได้ผลลัพธ์ทันที
- ตรรกะที่ไม่ต้องมีการหน่วงเวลา
- การประมวลผลที่เรียบง่ายและส่งค่ากลับเพียงค่าเดียว
กรณีที่ควรใช้ task
- เมื่อมีการหน่วงเวลา (เช่น
#10
) - เมื่อจำเป็นต้องมีหลาย output
- สำหรับการดีบักในการจำลอง (เช่น การ log ข้อมูล)
สรุป
- Verilog function คือ ฟังก์ชันที่รับ input และคืนค่าเพียง 1 ค่า
- เหมาะกับ combinational logic และไม่สามารถใส่ delay ได้
- ช่วยลดโค้ดที่ซ้ำซ้อนและเพิ่มความสามารถในการอ่าน
- function และ task มีความแตกต่าง ควรเลือกใช้งานตามวัตถุประสงค์
2. วิธีเขียน Verilog function【พร้อมตัวอย่างสำหรับผู้เริ่มต้น】
ในส่วนก่อนหน้าเราได้เรียนรู้แนวคิดพื้นฐานของ Verilog function แล้ว ที่นี่เราจะเจาะลึกวิธีการเขียน Verilog function อย่างละเอียด
โครงสร้างพื้นฐานของ function
Verilog function สามารถประกาศได้ตามโครงสร้างพื้นฐานดังนี้
function [ขนาดบิตของ output] ชื่อฟังก์ชัน;
input [ขนาดบิตของ input] ชื่อ input1, input2, ...;
begin
ชื่อฟังก์ชัน = นิพจน์การคำนวณ;
end
endfunction
จุดสำคัญ
- ใช้คีย์เวิร์ด
function
เพื่อประกาศ - ค่าที่ return จะใช้ชื่อตัวแปรเดียวกับชื่อฟังก์ชัน
- ต้องประกาศ input ด้วย
input
(ไม่สามารถใช้output
หรือinout
) - การประมวลผลต้องเขียนภายใน
begin ... end
- ต้องประกาศนอก
always
block
ตัวอย่าง Verilog function แบบง่าย
ด้านล่างนี้เป็นตัวอย่างฟังก์ชันที่ทำการบวกเลข 8 บิต
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
คำอธิบาย
add_function
เป็น ฟังก์ชันที่รับค่า input ขนาด 8 บิตสองตัว (a, b) และคืนค่าผลบวก- เรียกฟังก์ชันโดยใช้
sum = add_function(x, y);
และเก็บผลลัพธ์ไว้ในตัวแปรsum
- ภายใน
initial
block ใช้$display
เพื่อแสดงผล
การประกาศ input และ output ใน Verilog function
การประกาศ input
Verilog function สามารถกำหนดเฉพาะ input
เป็นอาร์กิวเมนต์ได้เท่านั้น
function [7:0] my_function;
input [7:0] in1, in2;
begin
my_function = in1 & in2; // การดำเนินการ AND
end
endfunction
หมายเหตุ: ไม่สามารถใช้ output
ได้ ค่าที่ return จะถูกส่งกลับด้วย ตัวแปรที่มีชื่อเดียวกับฟังก์ชัน
Verilog function ที่มีการใช้เงื่อนไข
สามารถใช้ if
หรือ case
ภายในฟังก์ชันเพื่อทำการตรวจสอบเงื่อนไขได้
function [3:0] max_function;
input [3:0] a, b;
begin
if (a > b)
max_function = a;
else
max_function = b;
end
endfunction
ฟังก์ชันนี้จะ คืนค่าที่มากกว่าระหว่าง a และ b
สรุป
- Verilog function ต้องถูกประกาศด้วยคีย์เวิร์ด
function
และคืนค่าเพียงหนึ่งค่า - input ต้องเป็น
input
เท่านั้น (ไม่สามารถใช้output
) - ผลลัพธ์จะถูกส่งคืนด้วยตัวแปรที่มีชื่อเดียวกับฟังก์ชัน
- สามารถใช้คำสั่งเงื่อนไข
if
และcase
ได้

3. วิธีใช้งาน Verilog function【พร้อมโค้ดตัวอย่างจริง】
ในส่วนก่อนหน้าเราได้เรียนรู้โครงสร้างและวิธีเขียน Verilog function
ที่นี่เราจะอธิบาย วิธีการนำฟังก์ชันไปใช้จริงในการออกแบบ พร้อมตัวอย่างโค้ด
วิธีเรียกใช้ function
Verilog function ถูกเรียกใช้ในรูปแบบเดียวกับตัวแปรทั่วไป โดยใช้ ชื่อฟังก์ชัน(อาร์กิวเมนต์)
ตัวอย่างต่อไปนี้เป็นฟังก์ชัน XOR ขนาด 8 บิตและการใช้งานภายในโมดูล
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); // เรียกใช้ฟังก์ชัน
$display("XOR Result: %b", result); // XOR Result: 01100110
end
endmodule
จุดสำคัญ
- เรียกฟังก์ชันด้วยรูปแบบ
ตัวแปร = function(อาร์กิวเมนต์);
- สามารถใช้ภายใน always block หรือ initial block ได้
- ทำงานในลักษณะ combinational logic
การใช้ function ภายใน combinational logic
Verilog function จะถูก ประเมินผลทันที (immediate evaluation) จึงเหมาะสำหรับการสร้าง combinational logic
ตัวอย่างต่อไปนี้แสดงการใช้ function เพื่อสร้าง 2-to-4 decoder
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); // ใช้ function
initial begin
select = 2'b01;
#10; // ใส่ delay เพื่อดูการเปลี่ยนแปลงในการจำลอง
$display("Decoded Output: %b", decoded_output); // Decoded Output: 0010
end
endmodule
คำอธิบาย
decoder
function จะ แปลง input ขนาด 2 บิต ให้เป็น output ขนาด 4 บิต- ใช้คำสั่ง
case
เพื่อเลือก output ตาม input - ใช้คำสั่ง
assign
เพื่อนำผลลัพธ์จาก function ไปเก็บที่decoded_output
→ function สามารถ ใช้เป็นส่วนหนึ่งของ combinational logic ได้
ความแตกต่างระหว่าง always และ function【ตารางเปรียบเทียบ】
ทั้ง Verilog function และ always
block ใช้สำหรับอธิบาย logic แต่มีวัตถุประสงค์และข้อจำกัดที่แตกต่างกัน
หัวข้อ | function | always |
---|---|---|
ตำแหน่งที่เขียน | นอก always block | ภายใน always block |
input | ใช้ได้เฉพาะ input | ใช้ได้ทั้ง reg , wire |
output | ได้เพียงค่าเดียว | อัปเดตได้หลายค่า |
delay (#10 ) | ไม่อนุญาต | อนุญาต |
การเก็บสถานะ | ไม่สามารถ (ประเมินผลทันที) | สามารถ (ใช้เป็น flip-flop ได้) |
การใช้งานหลัก | combinational logic | sequential logic หรือ event-driven |
แนวทางการเลือกใช้
- function ใช้สำหรับเขียน logic ที่เป็น combinational อย่างกระชับ
- always ใช้สำหรับวงจรที่มีสถานะ เช่น flip-flop
- ถ้าต้องใช้ delay (
#10
) ต้องใช้ always ไม่ใช่ function
สรุปการใช้งาน Verilog function
✅ เรียกใช้ function ด้วยรูปแบบ ชื่อฟังก์ชัน(อาร์กิวเมนต์)
✅ เหมาะสำหรับ combinational logic และมีบทบาทแตกต่างจาก always
✅ เขียน logic ที่ยืดหยุ่นได้ด้วย case
และ if
✅ เหมาะกับการใช้งานเช่น decoder และการคำนวณ
4. ตัวอย่างการประยุกต์ใช้ Verilog function (decoder และ ALU)
ที่ผ่านมาเราได้เรียนรู้โครงสร้างและวิธีใช้งาน Verilog function
ในส่วนนี้จะแสดง การประยุกต์ใช้ function ในการออกแบบวงจรจริง เช่น decoder และ ALU
การเขียน decoder ด้วย function (2-to-4 decoder)
decoder คือ วงจรที่แปลง input จำนวนน้อยบิตให้เป็น output ที่มีบิตมากขึ้น
เช่น input 2 บิต → output 4 บิต (2-to-4 decoder) เราสามารถเขียนได้โดยใช้ 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); // เรียกใช้ 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
การเขียน ALU ด้วย function (บวก ลบ AND OR)
ALU (Arithmetic Logic Unit) เป็นวงจรหลักใน CPU ที่ทำงานเกี่ยวกับการคำนวณ เช่น การบวก การลบ และการดำเนินการทางตรรกะ (AND, OR)
ที่นี่เราจะใช้ Verilog function เพื่อออกแบบ ALU 8 บิต แบบง่าย
module alu_example;
function [7:0] alu;
input [7:0] a, b;
input [1:0] op; // สัญญาณควบคุม 2 บิต
begin
case (op)
2'b00: alu = a + b; // บวก
2'b01: alu = a - b; // ลบ
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); // ใช้ 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
opcode = 2'b11; #10;
$display("OR Result: %b", result); // OR
end
endmodule
สรุป
✅ function เหมาะสำหรับ combinational logic เช่น decoder และ ALU
✅ สามารถใช้ case statement เพื่อกำหนดการทำงานได้อย่างยืดหยุ่น
✅ ช่วยให้โค้ดอ่านง่ายและนำกลับมาใช้ซ้ำได้
✅ function ใช้กับ combinational logic ได้ดี แต่ไม่เหมาะกับ sequential logic (ไม่สามารถใช้ delay ได้)
5. ข้อควรระวังในการใช้ Verilog function
Verilog function เป็นเครื่องมือที่ช่วยเพิ่มความสามารถในการอ่านและการนำโค้ดกลับมาใช้ซ้ำได้ แต่ก็มีข้อจำกัดบางอย่าง ส่วนนี้จะอธิบายรายละเอียดที่ควรระวัง
ไม่สามารถเรียกซ้ำ (recursive) ได้
ใน Verilog function ไม่อนุญาตให้เรียกซ้ำ (recursive call)
กล่าวคือ ไม่สามารถให้ function เรียกตัวเองได้
❌ ตัวอย่างที่ผิด: function แบบ recursive
function [3:0] factorial;
input [3:0] n;
begin
if (n == 0)
factorial = 1;
else
factorial = n * factorial(n - 1); // ❌ recursive call ไม่อนุญาต
end
endfunction
โค้ดนี้จะทำให้ เกิด error ระหว่าง simulation
✅ วิธีแก้: ใช้ loop
ถ้าต้องการทำงานแบบ recursive ควรใช้ always block พร้อม loop หรือใช้ task
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
การใช้ loop แบบนี้ช่วยหลีกเลี่ยง recursive ได้
ไม่สามารถใช้การหน่วงเวลา (delay #10) ภายใน function ได้
Verilog function จะถูก ประเมินผลทันที (ทำงานแบบ combinational logic)
ดังนั้นจึง ไม่สามารถใส่การหน่วงเวลา (เช่น #10
) ได้
❌ ตัวอย่างที่ผิด: function ที่มี delay
function [7:0] delay_function;
input [7:0] in;
begin
#10; // ❌ ไม่สามารถใช้ delay ภายใน function
delay_function = in + 1;
end
endfunction
โค้ดนี้จะทำให้เกิด compile error
✅ วิธีแก้: ใช้ always block
ถ้าต้องการใช้ delay ควรใช้ always block หรือ task
task delay_task;
input [7:0] in;
output [7:0] out;
begin
#10;
out = in + 1;
end
endtask
ดังนั้น หากต้องใช้ delay ต้องใช้ task แทน function
การเลือกใช้ function และ task อย่างเหมาะสม
ใน Verilog นอกจาก function ยังมีโครงสร้างที่เรียกว่า task
ทั้งสองมีความคล้ายคลึงกัน แต่มีวัตถุประสงค์ต่างกัน ต้องเลือกใช้ให้เหมาะสม
หัวข้อ | function | task |
---|---|---|
output | เพียงค่าเดียว (return ด้วยชื่อฟังก์ชัน) | ได้หลายค่า (กำหนดเป็น output ได้) |
input | เฉพาะ input | ใช้ได้ทั้ง input และ output |
ตัวแปรภายใน | ใช้ได้ | ใช้ได้ |
delay (#10 ) | ไม่อนุญาต | อนุญาต |
การใช้งานภายใน always | ได้ | ไม่ได้ |
วิธีเรียกใช้ | ชื่อฟังก์ชัน(อาร์กิวเมนต์) | ชื่อตัว task(อาร์กิวเมนต์); |
กรณีที่ควรใช้ function
✅ ต้องการผลลัพธ์ทันที (เช่น บวก ลบ การคำนวณทางตรรกะ)
✅ ใช้สำหรับ combinational logic ที่ไม่มี delay
✅ เหมาะกับการคืนค่าเพียง 1 ค่า
กรณีที่ควรใช้ task
✅ ต้องการใช้ delay (#10
เป็นต้น)
✅ ต้องการหลาย output
✅ ใช้สำหรับการ debug ในการจำลอง (monitoring, แสดงผล)
function ไม่สามารถประกาศภายใน always block ได้
Verilog function ไม่สามารถประกาศภายใน always block
ต้อง ประกาศภายนอกโมดูล แล้วเรียกใช้งานภายใน
❌ ตัวอย่างที่ผิด: การประกาศ function ภายใน always block
always @(a or b) begin
function [7:0] my_function; // ❌ ห้ามประกาศ function ใน always
input [7:0] x, y;
begin
my_function = x + y;
end
endfunction
end
โค้ดนี้จะทำให้เกิด compile error
✅ วิธีที่ถูกต้อง
ประกาศ function ภายนอก always block แล้วเรียกใช้งานภายใน
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); // ✅ เรียกใช้ function
end
ดังนั้น function ต้อง ถูกประกาศภายนอก always block เสมอ
สรุป
✅ Verilog function มีข้อจำกัดหลายอย่าง
✅ ไม่สามารถทำ recursive ได้ (ใช้ loop หรือ task แทน)
✅ ไม่สามารถใช้ delay (#10) (ต้องใช้ always หรือ task แทน)
✅ ไม่สามารถประกาศภายใน always block (ต้องประกาศภายนอก)
✅ คืนค่าได้เพียง 1 ค่า (ถ้าต้องการหลาย output ต้องใช้ task)
✅ ควรเลือกใช้ function และ task ให้เหมาะสม
6. 【FAQ】คำถามที่พบบ่อยเกี่ยวกับ Verilog function
ที่ผ่านมาเราได้อธิบายตั้งแต่พื้นฐานจนถึงการประยุกต์ใช้ และข้อควรระวังของ Verilog function
ในส่วนนี้คือ คำถามที่พบบ่อยและคำตอบ
ความแตกต่างระหว่าง function และ task คืออะไร?
Q. Verilog function และ task ต่างกันอย่างไร และควรใช้แบบไหน?
A. function คือ “การประมวลผลที่คืนค่าเพียงค่าเดียวทันที” ส่วน task ใช้สำหรับ “งานที่ต้องมีหลาย output หรือมี delay”
หัวข้อ | function | task |
---|---|---|
output | เพียงค่าเดียว (คืนค่าด้วยชื่อฟังก์ชัน) | ได้หลายค่า (กำหนด output ได้) |
input | input เท่านั้น | ใช้ได้ทั้ง input / output |
ตัวแปรภายใน | ใช้ได้ | ใช้ได้ |
delay (#10 ) | ไม่อนุญาต | อนุญาต |
การใช้งานภายใน always | ได้ | ไม่ได้ |
วิธีเรียกใช้ | ชื่อฟังก์ชัน(อาร์กิวเมนต์) | ชื่อตัว task(อาร์กิวเมนต์); |
กรณีที่ควรใช้ function
✅ ต้องการผลลัพธ์ทันที (เช่น บวก ลบ การดำเนินการทางตรรกะ)
✅ ใช้ใน combinational logic ที่ไม่มี delay
✅ ต้องการเพียงค่าเดียวเป็นผลลัพธ์
กรณีที่ควรใช้ task
✅ ต้องการใช้ delay (#10
เป็นต้น)
✅ ต้องการ output หลายค่า
✅ ใช้สำหรับการ debug ในการจำลอง (เช่น monitoring หรือ display)
สามารถใช้ reg ภายใน function ได้หรือไม่?
Q. ใน function สามารถประกาศตัวแปรแบบ reg
ได้หรือไม่?
A. ไม่สามารถใช้ reg
ได้ แต่สามารถใช้ integer
แทนสำหรับการคำนวณ
ภายใน Verilog function ไม่อนุญาตให้ใช้ตัวแปรประเภท reg
แต่สามารถใช้ integer
เพื่อเก็บค่าชั่วคราวในการคำนวณได้
✅ ตัวอย่างที่ถูกต้อง (ใช้ integer)
function [7:0] multiply;
input [3:0] a, b;
integer temp;
begin
temp = a * b;
multiply = temp;
end
endfunction
ควรใช้ function ในสถานการณ์ใด?
Q. function เหมาะสำหรับใช้ในสถานการณ์ใด?
A. function เหมาะกับ “การคำนวณที่เรียบง่าย” และ “การอธิบาย combinational logic”
ตัวอย่างที่เหมาะสม ได้แก่:
- การคำนวณ (บวก ลบ การดำเนินการทางตรรกะ)
- decoder และ encoder
- การเปรียบเทียบ (หาค่ามากสุด/น้อยสุด)
- การตรวจสอบ error (เช่น parity check)
แต่ ไม่เหมาะกับ sequential logic (เช่น flip-flop)
สามารถเรียกใช้ function อื่นภายใน function ได้หรือไม่?
Q. สามารถเรียก function อื่นภายใน Verilog function ได้หรือไม่?
A. ได้ แต่ต้องระวังลำดับความสัมพันธ์ระหว่างฟังก์ชัน
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; // เรียก function อื่นภายใน
end
endfunction
การเลือกใช้ function และ always ต่างกันอย่างไร?
Q. ควรเลือกใช้ function และ always อย่างไร?
A. function ใช้กับ “combinational logic” ส่วน always ใช้กับ “sequential logic”
หัวข้อ | function | always |
---|---|---|
delay (#10 ) | ไม่อนุญาต | อนุญาต |
การเก็บสถานะ | ไม่ได้ (ประเมินทันที) | ได้ (ใช้เป็น flip-flop หรือ counter) |
การใช้งานหลัก | combinational logic (การคำนวณทันที) | sequential logic (เช่น flip-flop, counter) |
ตัวอย่าง: การบวก
✅ function (combinational)
function [7:0] add;
input [7:0] a, b;
begin
add = a + b;
end
endfunction
✅ always (sequential)
always @(posedge clk) begin
sum <= a + b; // ทำงานเป็น flip-flop
end
สรุป
✅ function เหมาะกับการคำนวณง่ายๆ และ combinational logic
✅ ต้องเข้าใจความแตกต่างกับ task และเลือกใช้ให้ถูก
✅ ต้องแยกการใช้งานกับ always ให้ชัดเจน (sequential vs combinational)
✅ function ไม่สามารถใช้ delay (#10) หรือ array ได้ → ต้องใช้ task หรือ module