
เริ่มต้นเส้นทางสู่โลกแห่งตรรกะดิจิทัลด้วยคู่มือ Verilog สำหรับผู้เริ่มต้นฉบับนี้
เป็นเวลานานที่ภาษาโปรแกรมคอมพิวเตอร์ เช่น FORTRAN, Pascal และ C ถูกนำมาใช้เพื่ออธิบายโปรแกรมคอมพิวเตอร์ โดยการทำงานของโค้ดจะดำเนินการตามลำดับ แต่ไม่มีภาษาใดที่ใช้สำหรับอธิบายวงจรดิจิทัลโดยเฉพาะ จึงเป็นจุดเริ่มต้นของภาษาอธิบายฮาร์ดแวร์ (Hardware Description Language: HDL) นอกจากนี้ HDL ยังได้รับความนิยมในการใช้งานเพื่อการตรวจสอบความถูกต้องอีกด้วย โดย HDL มีอยู่ 2 ประเภทหลัก ได้แก่
หมายเหตุ: Verilog HDL และ VHDL ไม่ใช่ภาษาเดียวกัน โดย VHDL ถูกนำมาใช้งานก่อนที่ Verilog จะถือกำเนิดขึ้น
Verilog เป็นภาษาอธิบายฮาร์ดแวร์ที่ใช้สร้างวงจรดิจิทัลผ่านการเขียนโค้ด Verilog HDL นิยมใช้สำหรับการออกแบบ (RTL) และการตรวจสอบความถูกต้อง (การพัฒนา Testbench) สำหรับทั้ง Field Programmable Gate Arrays (FPGA) และวงจรรวมเฉพาะงาน (Application-Specific Integrated Circuits: ASIC)
Verilog มีระดับนามธรรม (Abstraction) หลัก 3 ระดับ ซึ่งหมายถึงมุมมองหรือวิธีการที่แตกต่างกันในการพิจารณาหรือวิเคราะห์การออกแบบ ได้แก่
หมายเหตุ: ก่อนที่จะศึกษาเกี่ยวกับระดับนามธรรมต่าง ๆ เรามาทำความเข้าใจ RTL กันก่อน
ระดับการถ่ายโอนข้อมูลระหว่างรีจิสเตอร์ (Register Transfer Level: RTL): RTL เป็นระดับนามธรรมระดับต่ำที่ใช้ในการออกแบบดิจิทัล เพื่ออธิบายพฤติกรรมและการทำงานของวงจรหรือระบบดิจิทัล RTL เป็นแนวทางทั่วไปที่ใช้อธิบาย วงจร ดิจิทัลในแง่ของการไหลของข้อมูลระหว่าง รีจิสเตอร์
หากวงจรถูกแสดงโดยใช้เกตพื้นฐานทั้งหมด จะเรียกวิธีนี้ว่าการจำลองวงจรในระดับเกต ตัวอย่างเช่น วงจร Half Adder ด้านล่าง ซึ่งสามารถแสดงได้อย่างง่ายดายโดยใช้ เกต AND และ เกต XOR

ระดับนามธรรมนี้เกี่ยวข้องกับการอธิบายวงจรโดยใช้เกตลอจิกพื้นฐาน เช่น AND, OR, XOR เป็นต้น ระดับนี้แสดงรายละเอียดโครงสร้างและลอจิกของวงจรได้อย่างชัดเจน ด้านล่างคือโค้ด RTL สำหรับ Half Adder
*module half_adder(input a,b, output sum,carry); *
*xor x1(sum, a, b); *
and a1(carry, a, b);
endmodule
ในระดับนามธรรมนี้ เราใช้ฟังก์ชันที่กำหนดการทำงานของวงจรแทนการระบุโครงสร้างเกตโดยตรง ระดับนามธรรมนี้มุ่งเน้นไปที่การไหลของข้อมูลผ่าน เกตลอจิก ของวงจร หรือนิพจน์เชิงฟังก์ชันเป็นหลัก
module half_adder(input a,b, output sum,carry);
assign sum = a ^ b;
assign carry = a & b;
endmodule
นี่คือระดับนามธรรมสูงสุดใน Verilog ในระดับนี้ นักออกแบบจะอธิบายการทำงานของวงจรโดยไม่จำเป็นต้องระบุรายละเอียดการทำงานและโครงสร้างของวงจรดิจิทัลโดยตรง การจำลองรูปแบบนี้มีประโยชน์เนื่องจากมุ่งเน้นไปที่สิ่งที่วงจรควรทำ มากกว่าวิธีการนำวงจรไปใช้งานจริง
module half_adder(input a,b, output reg sum,carry);
always@(*)
begin
sum = a ^ b;
carry = a & b;
endmodule
โทเค็นเชิงศัพท์เป็นองค์ประกอบพื้นฐานของโค้ด Verilog ซึ่งประกอบด้วยคำสงวน ตัวระบุ และตัวดำเนินการ โทเค็นเหล่านี้เป็นวิธีสื่อสารกับภาษาและมีประโยชน์ในการสร้างคำสั่งและนิพจน์ของ Verilog โทเค็นเชิงศัพท์บางประเภท ได้แก่
ช่องว่าง (White Space)
ใน Verilog เราใช้ช่องว่างเหล่านี้ในคำสั่งแสดงผล เช่น $display, $monitor, $strobe เป็นต้น โดย "\t" ใช้แทนช่องว่างแท็บ และ "\n" ใช้แทนการขึ้นบรรทัดใหม่
ข้อคิดเห็น (Comments)
การเขียนข้อคิดเห็นใน Verilog มี 2 วิธี วิธีแรกคือการครอบข้อความข้อคิดเห็นไว้ภายใน /*........*/ ซึ่งเหมาะสำหรับข้อคิดเห็นที่มีหลายบรรทัด อีกวิธีหนึ่งคือการเติม // ไว้ที่จุดเริ่มต้นของข้อความ ซึ่งเหมาะสำหรับข้อคิดเห็นที่มีเพียงบรรทัดเดียวหรือมีเนื้อหาสั้น ๆ
/* นี่คือตัวอย่างของคอมเมนต์หลายบรรทัด
สวัสดีครับ/ค่ะ
ยินดีต้อนรับสู่บทเรียน Verilog
*/
//นี่คือตัวอย่างของข้อคิดเห็นบรรทัดเดียว
//สวัสดี
ตัวเลข (Numbers)
Verilog ใช้ระบบตัวเลขหลัก ๆ 4 ระบบ ได้แก่
ดังนั้น ตัวเลขใน Verilog จึงแสดงในรูปแบบต่อไปนี้: ขนาด'ฐานตัวเลข (size'base number) โดย Verilog จะกำหนดขนาดเริ่มต้นไว้ที่ 32 บิต หากไม่ได้ระบุทั้งฐานและขนาด ระบบจะใช้ขนาดเริ่มต้น 32 บิตและถือว่าตัวเลขอยู่ในระบบฐานสิบ
ตัวอย่างเช่น 4'b1100 มีค่าเท่ากับ 4'd12 ในรูปแบบเลขฐานสิบ
'b0111 มีค่าเท่ากับ 00000000000000000000000000000111
โดยค่าเริ่มต้น 123 เป็นตัวเลขฐานสิบขนาด 32 บิต
หากมีการระบุตัวเลขติดลบ โดยค่าเริ่มต้นตัวเลขดังกล่าวจะถูกแปลงให้อยู่ในรูปแบบส่วนเติมเต็มสอง (Two's Complement)
ตัวดำเนินการ (Operators)
ตัวดำเนินการมี 3 ประเภทหลัก ได้แก่
- ความเร็วสูง (High-Speed)
ตัวดำเนินการเอกภาค (Unary Operators)
ในประเภทนี้ ตัวดำเนินการ เช่น +, -, ^, %, ~ จะปรากฏทางด้านซ้ายของตัวถูกดำเนินการ ตัวอย่างเช่น
x = ~y;
จากตัวอย่างนี้จะเห็นได้ว่าตัวดำเนินการอยู่ทางด้านซ้ายของตัวแปร y
ตัวดำเนินการทวิภาค (Binary Operators)
ในประเภทนี้ ตัวดำเนินการจะปรากฏอยู่ระหว่างตัวถูกดำเนินการ ตัวอย่างเช่น
X = Y ^ Z;
จากตัวอย่างนี้จะเห็นได้ว่าตัวดำเนินการ ^ อยู่ระหว่างตัวถูกดำเนินการ Y และ Z
ตัวดำเนินการไตรภาค/ตัวดำเนินการแบบมีเงื่อนไข (Ternary/Conditional Operators)
ตัวดำเนินการไตรภาคมีลักษณะคล้ายคำสั่ง if-else อย่างง่าย แต่เขียนให้อยู่ในบรรทัดเดียว โดยมีรูปแบบดังนี้
Conditional_expression ? True_expression : False_expression
ตัวอย่างเช่น
X = (A && B && C) : 1'b1 : 1'b0;
ในกรณีนี้ หากนิพจน์ (A && B && C) มีค่าเป็น 1 นิพจน์เมื่อเงื่อนไขเป็นจริง หรือ 1'b1 จะถูกส่งออกเป็นผลลัพธ์ มิฉะนั้นจะส่ง 1'b0 ออกเป็นผลลัพธ์
ตัวระบุและคำสงวน (Identifiers and Keywords)
ตัวระบุ (Identifier) คือชื่อที่กำหนดให้กับฟังก์ชัน งานย่อย (Task) หรือโมดูลใน Verilog ตัวระบุเหล่านี้ต้องเขียนด้วยตัวอักษรพิมพ์เล็กและมีความไวต่อตัวพิมพ์เล็ก-ใหญ่ (Case-Sensitive) สามารถใช้อักขระต่าง ๆ เช่น ตัวเลข เครื่องหมายขีดล่าง (_) และอักขระพิเศษ เช่น $ ในการตั้งชื่อตัวระบุได้ แต่ไม่สามารถใช้อักขระเหล่านี้เป็นตัวแรกของตัวระบุได้ เนื่องจากสงวนไว้สำหรับฟังก์ชันที่มีอยู่ภายใน Verilog
ตัวอย่างเช่น สามารถใช้ชื่อตัวระบุ my_identifier, my_identifier1 และ my_identifier$ ได้ แต่ชื่อตัวระบุอย่าง 1my_identifier และ $my_identifier ถือว่าไม่ถูกต้อง
ชนิดข้อมูล (Datatypes)
Verilog มีค่าพื้นฐาน 4 ค่า ได้แก่
วัตถุประสงค์หลักของการใช้ชนิดข้อมูลใน Verilog คือการแสดงองค์ประกอบสำหรับจัดเก็บข้อมูล เช่น บิตใน ฟลิปฟลอป และองค์ประกอบสำหรับส่งผ่านข้อมูล เช่น สายสัญญาณที่เชื่อมต่อระหว่างเกตลอจิก วงจรซีเควนเชียล และ วงจรคอมบิเนชัน โดยชนิดข้อมูลใน Verilog แบ่งออกเป็น 2 ประเภทหลัก ได้แก่
1. Nets
Nets ถูกขับสัญญาณอย่างต่อเนื่องโดยวงจรลอจิกคอมบิเนชัน ซึ่งหมายความว่าไม่สามารถจัดเก็บค่าใด ๆ ได้ โดยจะแสดงด้วยคีย์เวิร์ด wire ทางด้านซ้ายของนิพจน์ (LHS) ค่าเริ่มต้นของ net คือ Z ซึ่งเป็นสถานะอิมพีแดนซ์สูง
wire a, b, y;
assign y = a & b;
ในที่นี้ ตัวแปรต่าง ๆ ถูกประกาศด้วยชนิดข้อมูล wire และสำหรับตัวแปร y จะใช้คีย์เวิร์ด assign เพื่อส่งค่าจากนิพจน์ทางด้านขวา (RHS) คือ (a & b) ไปยัง y
2. Regs
สิ่งที่ควรทราบคือ reg แตกต่างจาก รีจิสเตอร์ ในฮาร์ดแวร์ การประกาศ reg ไม่ได้หมายความว่าเป็นการประกาศฟลิปฟลอปหรือ แลตช์ แต่ reg ใช้แทนองค์ประกอบจัดเก็บข้อมูล ซึ่งแตกต่างจาก net โดย reg เป็นชนิดข้อมูลที่สามารถใช้งานได้ผ่านคำสั่งเชิงกระบวนการ (Procedural Statements) เท่านั้น
reg a, b, y;
always@(posedge clock)
begin
y = a & b;
end
การประกาศโมดูล (Module Declaration)
ด้านล่างคือโค้ดสำหรับการประกาศโมดูล
module helper(a, b, y, z);
input a, b;
output y, z;
y = a & b;
z = a | b;
endmodule
module ใช้สำหรับประกาศโมดูล และ helper คือชื่อที่กำหนดให้กับโมดูล(a, b, y, z) คือพอร์ตอินพุตและเอาต์พุตของวงจรดิจิทัล โดยการประกาศพอร์ตนี้สามารถเว้นว่างไว้ได้เช่นกันa และ b ถูกประกาศเป็นพอร์ตอินพุต ส่วน y และ z ถูกประกาศเป็นพอร์ตเอาต์พุต;) ในโค้ดใช้แสดงการสิ้นสุดของคำสั่งy และ z ในโค้ดแสดงถึงคำสั่งแต่ละรายการภายในโมดูลendmodule ใช้แสดงการสิ้นสุดของโมดูลบล็อก Always เป็นบล็อกเชิงกระบวนการ ใช้อธิบายวงจรซีเควนเชียล เช่น แลตช์และ ฟลิปฟลอป หรือวงจรคอมบิเนชัน บล็อก Always ทั้งหมดทำงานแบบขนานกัน แต่ในความเป็นจริง ลำดับการทำงานจะถูกกำหนดโดยเครื่องมือจำลองสัญญาณ (Simulation Tool) สัญญาณที่กำหนดค่าภายในบล็อก Always ต้องเป็นชนิด reg
@ ไว้หน้าวงเล็บ* หมายถึงการเพิ่มอินพุตทั้งหมดลงในรายการความไวต่อการเปลี่ยนแปลง หากไม่ได้ระบุรายการนี้ บล็อก Always จะยังคงอยู่ในสถานะทำงานอย่าใช้ทั้งสองอย่างนี้ใน always block เดียวกัน
- Verilog-1995: Verilog-1995 หรือที่รู้จักกันในชื่อมาตรฐาน IEEE 1364-1995 เป็น Verilog เวอร์ชันเริ่มต้นที่นำเสนอไวยากรณ์พื้นฐานและคุณสมบัติของภาษา โดยมีโครงสร้างพื้นฐานสำหรับอธิบายวงจรดิจิทัล รวมถึงโมดูล พอร์ต ชนิดข้อมูล (wire, reg) และเทคนิคการจำลองเชิงพฤติกรรมและเชิงโครงสร้างขั้นพื้นฐาน
- Verilog-2001: Verilog-2001 เป็นส่วนขยายของ Verilog-1995 ซึ่งนำเสนอคุณสมบัติและการปรับปรุงใหม่หลายประการ เพื่อเพิ่มความอ่านง่ายของโค้ด การนำโค้ดกลับมาใช้ซ้ำ และความสะดวกในการออกแบบ เวอร์ชันนี้แก้ไขข้อจำกัดบางประการของเวอร์ชันก่อนหน้า พร้อมเพิ่มโครงสร้างใหม่เพื่อให้การจำลองและการตรวจสอบทำได้ดียิ่งขึ้น
- SystemVerilog: SystemVerilog เป็นส่วนขยายที่สำคัญของ Verilog ซึ่งเพิ่มคุณสมบัติและความสามารถใหม่ทั้งสำหรับการออกแบบและการตรวจสอบ โดยผสานคุณสมบัติจากภาษา Vera และ Specman เข้าด้วยกัน เพื่อให้เป็นโซลูชันที่ครอบคลุมสำหรับการออกแบบ การตรวจสอบ และการจำลองระบบในระดับระบบ
- Verilog-AMS (Analog and Mixed-Signal): Verilog-AMS เป็นส่วนขยายของ Verilog ที่ช่วยให้สามารถจำลองระบบแอนะล็อกและระบบสัญญาณผสมควบคู่ไปกับลอจิกดิจิทัลได้ โดยมีโครงสร้างสำหรับอธิบายพฤติกรรมแอนะล็อกแบบเวลาต่อเนื่อง เช่น แรงดันไฟฟ้าและกระแสไฟฟ้า นอกเหนือจากสัญญาณและลอจิกดิจิทัล
ตารางด้านล่างแสดงความแตกต่างระหว่าง Verilog HDL และ VHDL