ซอฟต์แวร์จัดการการอ้างอิง

การอ้างอิง (Reference) จัดว่าเป็นภาระหนักอันหนึ่งในงานเขียนเชิงวิชาการ เพราะนักวิจัยต้องอ้างอิงจากแหล่งข้อมูลจำนวนมาก ต้องเรียงลำดับการอ้างอิงให้ถูกต้อง และรูปแบบบรรณานุกรม (Citation styles) ก็ยังมีความหลากหลาย จึงมีการออกแบบซอฟต์แวร์จัดการการอ้างอิง (Reference Management Software) โดยเฉพาะ ซอฟต์แวร์จัดการการอ้างอิงมักแยกการจัดเก็บ ออกจากการแสดงผลบรรณานุกรม ทำให้เกิดความยืดหยุ่น เพราะเก็บแหล่งข้อมูลในมาตรฐานกลาง และสามารถปรับให้แสดงผลบรรณานุกรมต่างๆ ได้ในภายหลัง

ซอฟต์แวร์จัดการการอ้างอิงที่แนะนำในที่นี้คือ Zotero ระบบของ Zotero สร้างส่วนเสริม (Add-ons) สำหรับซอฟต์แวร์ต่างๆ ที่จำเป็นต่อการเขียนเชิงวิชาการ เช่น เว็บบราวเซอร์ หรือ Microsoft Word ตัว Zotero ช่วยจัดเก็บและอ้างอิงบรรณานุกรมในรูปแบบต่างๆ อย่างง่ายดาย

Continue reading

Posted in เทคนิควิธีการ | Tagged , , , | Leave a comment

Toward the Age of Thought Movement: Research Topics in Argumentation

สคริปต์ที่ใช้ในการประชุม MIND Lab วันที่  9 มกราคม 2555

เกริ่นนำ

ผมเพิ่งเสร็จจากการไปนำเสนอผลงานวิชาการที่ Fifth International Workshop on Juris-informatics(JURISIN 2011) ซึ่งเป็ Conference เกี่ยวกับสนเทศศาสตร์ทางด้านกฎหมาย(Juris-informatics) ที่เมือง Takamatsu จังหวัด Kagawa [1]  ประเทศญี่ปุ่น เรื่องที่ผมทำอยู่ตอนนี้อาจตั้งชื่อเล่นได้ว่า “Prologกับกฎหมาย”  แต่ถ้าจะให้ตรงกว่าต้องพูดว่าผมทำเรื่อง Argumentation [2]  Argumentation เป็นชื่อเรียกศาสตร์แขนงใหม่[3] คล้ายๆ Social Network Analysis  แต่ยังอยู่ในหมวดย่อยเดียวกับ Prolog คือ Representation ในหมวดใหญ่ AI เช่นเดิม Argumentation  จึงเป็นเรื่องที่ผมแนะนำในวันนี้

Continue reading

Posted in บทความ | Tagged , , | Leave a comment

Knowledge Discovery in Astronomy

สคริปต์ที่ใช้ในการประชุม MIND Lab วันที่  30 มิถุนายน 2554

เกริ่นนำ

เรื่องที่ผมจะพูดในวันนี้มีชื่อว่า “Knowledge Discovery in Astronomy” หรือ “การค้นความรู้ในวิชาดาราศาสตร์”  เราลองไปดูว่าในสาขาวิชาอื่น ซึ่งในที่นี้คือดาราศาสตร์ เขาจะมีเทคนิคการค้นความรู้อย่างไรบ้าง เหตุใดการค้นความรู้ทางดาราศาสตร์จึงเป็นเรื่องสำคัญและน่าสนใจ ลักษณะเฉพาะของข้อมูลทางดาราศาสตร์มีอะไรบ้าง ในยุคคอมพิวเตอร์อย่างนี้ เขาประยุกต์ใช้คอมพิวเตอร์ในการค้นความรู้ทางดาราศาสตร์อย่างไร และส่วนหนึ่งจะพูดถึงแนวโน้มหรือ Trend ของงานวิจัยการค้นความรู้ในวงการคอมพิวเตอร์ในอีกสัก 10-20 ปี อนึ่งเมื่อเราพูดถึง Trend แล้วมันแค่ “อาจจะเป็นไปได้” กล่าวคือมีความน่าจะเป็นที่จะเป็นไปได้เท่านั้น ไม่ใช่เป็นไปแน่ๆ ซะทีเดียว และสุดท้ายก็จะพูดถึงความพร้อมของไทยในงานวิจัยการค้นความรู้ทางดาราศาสตร์ด้วย
Continue reading

Posted in บทความ | Tagged , | Leave a comment

บทกลอนไหว้ครู วศม. ประจำปีการศึกษา 2554

(*  จริงๆ บทกลอนไหว้ครูปีนี้ ผมแต่งไว้ตั้งแต่ปีที่แล้วด้วยความเข้าใจผิด ก็เลยเก็บไว้มาใช้ในปีนี้ ไหนๆ ก็ถือว่าอยู่ปริญญาโทแล้ว ไม่ค่อยมีวิชาเรียนโดยเฉพาะ ก็เลยถือโอกาสรวบรวมคำศัพท์ที่เกี่ยวข้องกับคอมพิวเตอร์ตอนปริญญาตรีตามสไตล์ของผม ก็เป็นกลอนสั้นๆ มี Prerequisite Course ก่อนเช่นเคย สำหรับใครที่ลืมๆ ไปแล้วก็มีลิงก์วิกิพีเดียช่วย

Prerequisite: Prog Lang Prins, Network, Algorithm, OS, Prog Meth, Programming, Comp Org*)

เปรียบชีวิต เหมือน execute โปรแกรมหนึ่ง
ซึ่งลึกซึ้ง กว่า NP เป็นไหนไหน
ยอดคนคิด ยอด code ได้ฉันใด
ยอดอาจารย์ ย่อมสร้างให้ เป็นยอดคน

ดุจ router คอยชี้ทาง แนะนำศิษย์
สู่เป้าหมาย ในชีวิต สำเร็จผล
ดุจนายแบงก์ คอยตรวจจับ การอับจน
คอยไขข้อ ฉงน ให้คลี่คลาย

ท่านคอยจัด หลักสูตร ดุจ OS
ท่านออกแบบ Testcase ยากเหลือหลาย
ท่านคอย loop สร้างลูกศิษย์ หลายร้อยราย
พระคุณท่าน จึง WriteLine ไม่เพียงพอ

ขอพระคุณ ครูมากล้น เมกะบิต
จงปกปักษ์ นิสิต ให้เกิดก่อ
อันคุณใด ที่ข้าเคย กระทำทอ
ปวงข้าขอ จำเริญ return ครู ;

Posted in กิจกรรม | Tagged | 2 Comments

ลิงก์ที่น่าสนใจเกี่ยวกับ AVR

AVR C Library
HomePage
http://www.nongnu.org/avr-libc/
Online Mannual
http://www.nongnu.org/avr-libc/user-manual/index.html

หน้าแนะนำให้อ่าน
FAQ
http://www.nongnu.org/avr-libc/user-manual/group__avr__sfr.html#ga11643f271076024c395a93800b3d9546
Special function registers
http://www.nongnu.org/avr-libc/user-manual/group__avr__sfr.html#ga11643f271076024c395a93800b3d9546

สำหรับปฏิบัติการ AVR มีจุดประสงค์สำคัญสองอย่างคือ
1. เขียน Assembly & C instruction ได้ ซึ่งตั้งแต่ lab_3 เป็นต้นไปก็จะไม่ค่อยมี instruction ใหม่ต้องเรียนรู้แล้ว
2. สามารถ Configure hardware ต่างๆ ซึ่งแต่ละ lab จะเรียนอันใหม่ไปเรื่อยๆ ตั้งแต่ LED, Switch, Seven-Segment PWM ฯลฯ

ซึ่งข้อ 1 สามารถศึกษาได้ในคู่มือที่แจกในแล็บและสำหรับภาษา C ศึกษาได้จาก Mannual ข้างบน
ส่วนข้อ 2 สามารถศึกษาได้จากคู่มือที่แจกในแล็บเช่นกัน โดยอ่านทีละ Register หรือศึกษาตามเว็บไซต์ต่างๆ อาจมีคำอธิบาย หรือตัวอย่าง Source code เช่น http://www.avr-asm-tutorial.net/avr_en/source/index.html เพื่อประยุกต์ใช้ และอ่านโจทย์ประกอบเพื่อจะได้เข้าใจ Structure

ลองใช้ Module แนะนำที่เขียนในกระทู้นี้
http://www.avrportal.com/forum/index.php?topic=21.msg48#msg48

Posted in เทคนิควิธีการ, Lab Verilog | Tagged , | Leave a comment

หลักเกณฑ์การให้คะแนนรายงาน

บทนำสู่หลักเกณฑ์การให้คะแนนรายงาน

จุดประสงค์หลักของรายงานคือการสรุปให้ผู้อ่านได้เข้าใจถึงประเด็นสำคัญๆ ที่น่าสนใจ แต่ทว่าปัญหาหนึ่งของการทำรายงานคือผู้อ่านแต่ละคนสนใจไม่เหมือนกัน อย่างเช่นถ้าเราสร้างอุปกรณ์ใหม่มาสักตัวหนึ่ง แต่ละคนก็จะสนใจข้อมูลของอุปกรณ์ในแง่ที่แตกต่างกัน ผู้บริโภคก็จะสนใจว่าอุปกรณ์ใหม่นี้ใช้ยังไง ช่างเทคนิคก็จะสนใจกลไกการทำงานข้างใน ส่วนสปอนเซอร์หรือผู้ที่เราไปขอทุนมาสร้างก็จะสนใจว่าอุปกรณ์ชนิดนี้พิเศษอย่างไร มีความเป็นไปได้ที่จะขายได้กำไรหรือไม่ ฯลฯ ดังนั้นบางครั้งเราอาจจะเห็นเวลาทำรายงานเล่มใหญ่ๆ เนื้อหาบางบทอาจซ้ำซ้อนกัน ทั้งนี้ก็เพราะว่า ผู้ที่สนใจแต่ละคนก็จะข้ามไปอ่านเฉพาะบทที่ตนเองสนใจเท่านั้น ข้อมูลบางอันที่ควรรู้จึงถูกกล่าวถึงซ้ำๆ ในแต่ละบทด้วยภาษาที่แตกต่างกันไป

ในที่นี้เราจะมาเน้นถึงรายงานใน Lab ที่เราทำ ใน Lab นี้เป็นรายงานการออกแบบระบบเป็นส่วนใหญ่ ดังนั้นเราจึงควรเข้าใจว่าคนที่อ่านรายงานการออกแบบสามารถแบ่งออกเป็นกี่กลุ่ม และแต่ละกลุ่มสนใจอะไรบ้าง

ผู้เกี่ยวข้องกับการออกแบบระบบแบ่งได้เป็นกลุ่มใหญ่ๆ 3 กลุ่มคือ

  1. เจ้าของปัญหา หมายถึง องค์กรผู้จ้างให้เราทำงาน เจ้าของปัญหามักอยากรู้ความคิดเห็นของเราที่มีต่อปัญหานั้นๆ เช่นสิ่งนี้สร้างได้หรือไม่ ควรเจาะตลาดอย่างไร ฯลฯ เป็นต้น
  2. ช่างเทคนิค หมายถึง ผู้เกี่ยวข้องที่ควรรู้การทำงานข้างในของระบบ เพราะอาจใช้ในการบำรุงรักษา แก้ไขปรับปรุง ฯลฯ มักอยากรู้กลไกการทำงานของระบบเอง และพอจะรับศัพท์เทคนิคได้
  3. ผู้ใช้ หมายถึง ผู้ที่จะใช้ระบบของเรา ที่ไม่ค่อยรู้ศัพท์เทคนิค และไม่จำเป็นต้องเข้าใจการทำงานภายในของระบบ ผู้ใช้เพียงแค่อยากรู้ว่าระบบนี้ใช้งานอย่างไร กล่าวในเชิงเทคนิคคือ ระบบของเรามีส่วนต่อประสาน (interface) อย่างไร นั่นเอง

หลักเกณฑ์การให้คะแนนรายงาน: SCIDO

ด้วยเหตุผลที่กล่าวขั้นต้นพี่จึงตั้งเกณฑ์การให้คะแนนรายงานออกเป็น 5 เกณฑ์ เพื่อให้จำง่ายๆ ก็ขอเรียกรวมกันย่อๆ ว่า SCIDO (อ่านว่า ไซดู) หลักเกณฑ์การให้คะแนนรายงานมีดังต่อไปนี้ จากคะแนนเต็ม 10 คะแนน

  1. S ย่อมาจาก Signature เป็นเกณฑ์มาตลอดว่า ลายเซ็นที่ตรวจจะให้ 5 คะแนนเพียวๆ จาก 10 คะแนน หาก Lab นั้นมี n งานก็จะให้คะแนน 5/n คะแนน แบ่งตามสัดส่วนกันไป
  2. C ย่อมาจาก Command หมายถึง คะแนนจากผู้อ่านในฐานะ “เจ้าของปัญหา” คะแนนส่วนนี้จะพิจารณาจากการวิเคราะห์ปัญหา และความเห็นที่ให้ต่อปัญหา แต่เนื่องจากว่ารายงานสามารถแนบโจทย์มาได้ อีกทั้งพี่ TA เองก็มีใบโจทย์เช่นกัน จึงไม่จำเป็นต้อง Copy โจทย์มาให้ดูอีกครั้ง แต่สิ่งที่ควรทำก็คือ การรายงานว่าตนได้วิเคราะห์และให้ความเห็นต่อโจทย์ปัญหาอย่างไร ยกตัวอย่างเช่น รายงานว่าโจทย์ข้อนี้พิเศษอย่างไร เปรียบเทียบกับโจทย์ข้ออื่นว่าโจทย์ข้อนี้มีอะไรที่ต้องพึงระวังหรือพึงสังเกตเป็นพิเศษหรือไม่ หรือ ขยายความโจทย์เพิ่มเติมโดยใช้ตัวอย่างเช่น ยกตัวอย่าง Command ที่ใช้ใน CPU นี้บางตัว ฯลฯ เพื่อให้เห็นภาพชัดเจนมากขึ้น พูดง่ายๆ คือ “ถ้าเราเป็นอาจารย์ เราจะขยายความโจทย์เพิ่มเติมอย่างไร ให้ผู้ทำ Lab เข้าใจมากขึ้น”
  3. I ย่อมาจากหลายตัว ย่อมาจาก Inside Mechanism หรือกลไกภายในก็ได้ และก็ย่อมาจาก Invarriant ที่แปลว่าสิ่งที่พึงรักษาก็ได้ หรือย่อมาจาก Interest คือสิ่งที่น่าสนใจก็ได้ แต่โดยสรุปแล้วตัว I นี้หมายถึง คะแนนจากผู้อ่านในฐานะ “ช่างเทคนิค” ที่อยากรู้ว่ากลไกการทำงานภายในเป็นอย่างไร อาจแสดงด้วย แผนภาพ หรือบรรยายเป็นข้อความ หรืออธิบายประกอบ Source Code ฯลฯ และต้องแนบข้อพึงระวังหรือสิ่งที่น่าสนใจด้วย ข้อพึงระวังหมายถึงสิ่งที่ต้องรักษาไว้ มิฉะนั้นระบบอาจทำงานผิดพลาดเช่น ต้องไม่มี 2 ข้อมูลปล่อยมาใน Bus เดียวกัน หรือ Binary Search Tree สมาชิก subtree ซ้ายต้องมีค่าน้อย subtree ขวา เป็นต้น เพื่อให้ผู้ที่มาพัฒนาเพิ่มเติมพึงระวังไม่ไปแก้ไขเข้า ทั้งนี้ให้ถือว่า “ช่างเทคนิค” เข้าใจใน Code พอๆ กับเราแล้ว พูดง่ายๆ คือ “เราจะอธิบายเพื่อนอย่างไร เพื่อให้เพื่อนสามารถอ่านรายงานเราและพัฒนาแทนเราได้” (ทักษะนี้สำคัญมากเวลาพัฒนางานเป็นทีม)
  4. D ตัว D นี้ก็ย่อมาจากหลายตัวเหมือนกันทั้ง Data ที่แปลว่าข้อมูล Discuss ที่แปลว่าอภิปราย ฯลฯ ส่วน D นี้มองคล้ายๆ เป็นส่วนที่กล่าวถึงผลลัพธ์ที่ได้ กล่าวอีกนัยหนึ่งคือ คะแนนจากผู้อ่านในฐานะ”ผู้ใช้” Output เป็นอย่างไร อ่าน Output อย่างไร ต้อง Input อย่างไร เพื่อให้ Output เป็นอย่างที่ต้องการ เป็นต้น พูดง่ายๆ คือ “ถ้าเราเป็น TA เราต้องตรวจอย่างไร”
  5. O ย่อมาจาก Other นั่นเอง Other จะเป็นประเด็นละเอียดปลีกย่อยเช่น Format หน้าปก และหน้าให้คะแนนควรเขียนข้อมูลให้ครบถ้วนสมบูรณ์ กระดาษควรเรียงอย่างสวยงามและเย็บเล่มเรียบร้อย การจัด Layout หน้ากระดาษ เป็นต้น ส่วนนี้จะเพิ่มคะแนนให้ด้วย จากการใส่ข้อมูลเพิ่มเติมที่น่าสนใจเช่น อธิบายว่าลำดับฟีบอนักชีคืออะไร (Lab 4) หรือ Stack คืออะไร (Lab 3) หรือมี Tip & Tricks อะไรที่น่าสนใจอะไรในการใช้งานเป็นต้น ทั้งนี้จะไม่บวกคะแนนจนเกินคะแนนเต็มหรือเกินไปยังคะแนนลายเซ็น

SCIDO Check-List

เพื่อให้เป็นมาตรฐานเดียวกัน การตรวจจะตรวจตาม SCIDO Check-List ดังนี้

S: (5 คะแนน)
คิดจากลายเซ็น

C: (1.25 คะแนน)
ต้องมีการอภิปรายโจทย์เช่น

  • เขียนว่าโจทย์ข้อนี้พิเศษอย่างไร หรือ
  • เปรียบเทียบกับโจทย์ข้ออื่นว่าโจทย์ข้อนี้มีอะไรที่ต้องพึงระวังหรือพึงสังเกตเป็นพิเศษหรือไม่ หรือ
  • ขยายความโจทย์เพิ่มเติมโดยใช้ตัวอย่าง เช่นยกตัวอย่าง Command ที่ใช้ใน CPU นี้บางตัว ฯลฯ

I: (1.25 คะแนน)
ต้องมีการอธิบายการทำงาน อาจใช้

  • แผนภาพ  (Diagram) เช่น ASM Chart, Flow Chart ฯลฯ หรือ
  • บรรยายเป็นข้อความ หรือ
  • อธิบายประกอบ Source Code

ควรมีข้อพึงระวังที่น่าสนใจในการออกแบบด้วย

D: (1.25 คะแนน)
ต้องมี Data ที่โจทย์กำหนดให้ใส่ เช่น

  • ถ้าโจทย์สั่งให้วาด ASM Chart ส่งก็ต้องมี ASM Chart ส่ง
  • ลักษณะผลลัพธ์ที่ทำงานถูกต้อง
  • Code เฉพาะส่วนที่สำคัญ (ดูเพิ่มเติมใน “หมายเหตุเฉพาะ Lab”)

ควรสอนวิธีอ่าน Output และวิธีใส่ input ด้วย เช่น

  • [Lab4] ให้ดู Ram address ที่ 17 จะเห็นว่าแสดงค่า 13 อันเป็นฟีโบนักชีตัวที่ 7 ซึ่งเลข 7 นี้ต้องใส่ใน Ram Address ที่ 13 ก่อน execute binary code
  • [ตัวอย่างสมมติ] สังเกตว่าค่า a จะสลับไปตาม clock ซึ่งตรงกับที่โจทย์กำหนดไว้

O: (1.25 คะแนน)
ประเด็นที่ตรวจ

  • ข้อมูลบนหน้าปกที่สำคัญต้องครบ ได้แก่ ชื่อ นามสกุล รหัสนิสิต Lab ที่ เท่าไหร่ Lab ชื่ออะไร วิชา รหัสวิชา Sec ที่เรียน
  • การเย็บเล่มต้องเย็บให้เรียบร้อย กระดาษทุกอันในรายงานต้องถูกเย็บ กระดาษไม่กลับหน้า-หลัง หรือ บน-ล่าง
  • หัวกระดาษหน้าให้คะแนนต้องกรอกข้อมูลที่สำคัญครบดังกล่าวขั้นต้น
  • ลำดับการจัดรายงาน หน้าให้คะแนนต้องวางไว้หน้าแรกสุดของรายงานต่อจากปกนอกเลย (แม้มีใบโจทย์แนบมาในรายงานด้วย ก็ขอให้เอาไว้หน้าโจทย์) มีการใช้ font ที่แตกต่างกันในการแสดงหัวข้อ และเรียงลำดับรายงานแล้วอ่านเข้าใจง่าย

ประเด็นเพิ่มคะแนน

1. ข้อมูลประกอบน่าสนใจยกตัวอย่างเช่น

  • [Lab 4] อธิบายว่าฟีบอนักชีนั้นลำดับอย่างไร
  • [Lab 3] Stack ทำงานอย่างไร

2. เสนอ Tips & Tricks ที่ใช้ในการทำแล็บครั้งนั้น ที่คิดว่าน่าสนใจ

วิธีการคิดคะแนน

แต่ละส่วนจะมีส่วนที่ต้องมีหรือบังคับให้มี หากไม่มีให้ถือว่าได้ 0 คะแนนในส่วนนั้น หากมีจะคิดว่าได้ 1 คะแนนเต็มก่อน และค่อยๆ หักจุดที่อธิบายผิดหรือจุดที่ควรอธิบายแต่ไม่ได้อธิบายจุดละ 0.25 คะแนน แต่รวมแล้วจะไม่หักเกิน 1 คะแนน กล่าวอีกแบบหนึ่งคือ ผิดจุดหนึ่งหักจุดละ 0.25 คะแนน แต่ถ้าผิดมากกว่า 4 จุดจะหักแค่ 1 คะแนนเท่านั้น

การหักเนื่องจากควรอธิบายแต่ไม่อธิบายมีอยู่ 2 ส่วนเท่านั้นคือ ข้อพึงระวังในส่วน I และวิธีการอ่าน Output และกรอก Input ในส่วน D ทั้งนี้ จุดที่ควรอธิบายนี้อิงจากคนส่วนใหญ่ คือถ้าคนส่วนใหญ่เกิน 80% เห็นว่าประเด็นนี้พึงอธิบาย จะถือว่าเป็นจุดที่พึงอธิบาย ทั้งนี้ประกอบกับวิจารณญาณของ TA อีกทีหนึ่ง แต่จะมีการชี้แจงเหตุผลในแต่ละ Lab ไป และจะให้คะแนนในทิศทางที่น้องได้คะแนนมากกว่า (คือในบางครั้งหากมีน้องอธิบายในประเด็นดังกล่าวเกิน 80% แต่ TA ไม่เห็นว่าจำเป็นต้องอธิบายก็จะไม่หักคะแนนน้อง แต่ประเด็นไหนที่น้องอธิบายไม่ถึง 80% แต่ TA เห็นว่าควรจะอธิบาย TA ก็จะยกประโยชน์ให้จำเลยไม่หักคะแนนน้องเช่นกัน)

สำหรับส่วน O นี้จะเห็นว่าเป็นคะแนนที่พยายามจะให้เต็มๆ กัน ดังนั้นอย่าพลาดที่จะเก็บคะแนนส่วนนี้ไว้ ในส่วน O นี้ยังมีประเด็นเพิ่มคะแนนอีกด้วย แต่อย่าใส่ประเด็นเพิ่มคะแนนนี้มาเกินความจำเป็น มิฉะนั้นจะถือเสมือนว่าไม่ใส่ข้อมูลนั้นมาเช่นกัน โดยการเพิ่มคะแนนในส่วน O นี้จะสามารถหักกลบกับคะแนนในส่วน C I และ D ได้ แต่จะไม่ไปเพิ่มเกินส่วน S และไม่เพิ่มเกินคะแนนเต็ม 10 คะแนนไปยัง Lab อื่น เนื่องจากประเด็นที่เพิ่มคะแนนมี 2 ประเด็นประเด็นละ 0.25 คะแนน ดังนั้นคะแนนโบนัสจะเพิ่มได้ไม่เกิน 0.5 คะแนน

หากในแล็บมีหลายข้อย่อย ก็ให้คิดทีละข้อย่อยและหารเฉลี่ยเอา หากส่งรายงานสายจะหักวันละ 1 คะแนน ไม่นับวันหยุดราชการ และการเพิ่มคะแนนในส่วน O ก็ไม่สามารถมาเพิ่มคะแนนที่หักได้

สิ่งที่ไม่ได้พิจารณาคะแนนให้

อีกปัญหาหนึ่งที่เจอบ่อยในการทำรายงานคือ ทำรายงานมากเกินไป จึงขอกำหนดไว้ให้ชัดเจนเลยว่าสิ่งใดที่ไม่ได้พิจารณาคะแนนให้ ซึ่งได้แก่

การทวนโจทย์ซ้ำ คำใดที่ระบุในโจทย์แล้ว ให้ถือว่า TA รู้แล้ว การ Copy โจทย์มาจึงไม่ถือว่าเป็นการวิเคราะห์โจทย์แต่อย่างใด ทั้งนี้ไม่นับการกล่าวถึงโจทย์ซ้ำในอีกคำพูดหนึ่งซึ่งจะคิดคะแนนให้ (แต่จะเขียนซ้ำก็ได้ ถ้าจำเป็น ไม่ได้หักคะแนนแต่อย่างใด เพียงแต่ไม่คิดคะแนนให้เฉยๆ )

การอธิบายกลไกสองครั้ง การอธิบายแผนภาพแล้วมาอธิบายโค้ดอีกทีเป็นสิ่งที่ไม่จำเป็น ให้เลือกอธิบายอย่างใดอย่างหนึ่ง ถ้าอธิบายมาสองอย่าง จะตรวจทั้งสองอันแล้วเลือกอันที่ได้คะแนนมากสุดเพียงอันเดียว อีกอันหนึ่งจะไม่พิจารณาคะแนนให้แต่อย่างใด

การอธิบาย Syntax ของโค้ด ไม่ต้องอธิบายวิธีการเขียน Syntax ของโค้ด อธิบายเฉพาะเนื้อหาโดยคร่าวๆ พอ ไม่ต้องอธิบายถึงขั้น Programming Style

การอธิบายวิธีใช้โปรแกรม ให้ถือว่า TA รู้ว่าโปรแกรมใช้อย่างไรอยู่แล้ว ไม่ต้องอธิบายวิธีใช้โปรแกรม ยกเว้นแต่ว่า interface ส่วนนั้นเป็น Tip & Trick ก็อนุโลมให้

Capture หน้าจอ ไม่จำเป็นต้อง Capture หน้าจอมากเกินไป Capture มาเฉพาะส่วน Output ก็พอ หรือ Output จริงๆ ไม่ต้อง Capture ก็ได้ เขียนอธิบายเป็นคำพูดเอาก็ได้คะแนนเต็มได้เหมือนกัน

Output ที่ไม่เกี่ยวข้อง ยกตัวอย่างเช่น CPU ไม่ได้ดู Timing Diagram และก็ไม่ได้ดู Test Fixture ด้วย (แต่ดูข้อมูล Ram ใน Notepad) จึงไม่ได้ตรวจ Timing Diagram และ Test Fixture ให้

Dump Code ไม่ต้องใส่ Code มาทั้งหมด ให้ใส่เฉพาะส่วนขงอง Code ที่สำคัญ และไม่จำเป็นต้อง Hilight Syntax  (การใส่ keyword ในโค้ดเป็นสีๆ) และไม่ต้องขยาย font ให้อ่านง่าย การใส่ Code ในรายงานนี้เป็นการดูว่าตรงกับที่ Design และเอาไว้ให้น้องอ่านประกอบเท่านั้น

Layout ถึงแม้ว่าจะตรวจลำดับการจัดหน้า แต่ไม่ได้ตรวจรูปแบบการจัดหน้า ไม่ได้บังคับว่าต้องมีเลขหน้า Heading หรือ ตัวตกแต่ง (Decorator) ในรายงาน

ข้อมูลหน้าปก มีบางข้อมูลที่ไม่ชัดเจนเช่นชื่ออาจารย์ประจำแล็บ ไม่เคยชัดเจนสักปี อันนี้เข้าใจได้ ไม่จำเป็นต้องกังวลว่าจะกรอกผิดหรือไม่ หรือไม่ต้องกรอกก็ได้ หรือวันที่ จะกรอกวันที่อะไร กรอกผิดก็ไม่เป็นไร แต่อยากให้กรอกวันที่ส่งรายงาน (แต่ในใบตรวจให้กรอกวันที่ทำแล็บ) หากใครติดธุระอะไรแล้วยื่นใบลาแล้ว อยากให้กรอกวงเล็บไว้มุมขวาบนของใบตรวจว่าไปทำอะไรเช่น ACM เป็นต้น ส่วน Department จะกรอก CP วิศวกรรมคอมพิวเตอร์ วิศวกรรมศาสตร์ อะไรก็ได้ ที่จะคิดคะแนนในส่วน O จะคิดเฉพาะข้อมูลสำคัญๆ  เท่านั้นได้แก่ ชื่อ นามสกุล รหัสนิสิต Lab ที่ เท่าไหร่ Lab ชื่ออะไร วิชา รหัสวิชา Sec ที่เรียน เพราะเป็นข้อมูลสำคัญเวลาค้นหาและตรวจรายงาน อยากให้กรอกให้ถูกต้อง จะได้ไม่ต้องไปตาม (กรอกผิดหักคะแนน🙂 ) บางคนถามว่า Lab ที่เท่าไหร่กับ Lab ชื่ออะไร นี่กรอกบนหน้าปกยังไง เพราะกรอกได้หลายแบบมาก คำตอบคือ กรอกยังไงก็ได้ให้หมด แต่อยากแนะนำให้กรอกตรง Problem Set เช่น Lab 4 Simple Microprocessor เป็นต้น

วิธีการกรอกคะแนน

การกรอกคะแนนจะกรอกคะแนนในใบตรวจคะแนน ขอย้ำว่าให้เอาใบตรวจไว้หน้าแรกสุดของรายงาน ต่อจากปกนอกเลย การกรอกคะแนนจะกรอกในช่องลายเซ็น 5-10 ช่อง 5,6,7,8,9 จะเป็นประเด็น S-C-I-D-O ตามลำดับ และช่อง 10 เป็นคะแนนรวมที่ได้ จะเขียนเฉพาะประเด็นที่หักคะแนน หากไม่เขียนอะไรในช่องไหน ถือว่าช่องนั้นได้คะแนนเต็ม จะเขียนอธิบายเหตุผลไว้ที่ช่องหมายเหตุด้วย

หมายเหตุเฉพาะ Lab

Lab 3-4
เนื่องจาก Lab 4 เป็น Lab ที่พี่ลองตรวจด้วยเกณฑ์นี้เป็นครั้งแรก เพื่อเทียบดูว่าในความเป็นจริงจะเป็นการกดหรือเพิ่มคะแนนมากไปไหม อีกทั้งเป็น Lab ที่ Code มาจาก Sheet โดยตรง ก็จะหักตรงส่วน O มากกว่าคือ กรอกข้อมูล Heading ใบตรวจคะแนนไม่ครบ ยังไม่หักคะแนนส่วนอื่นๆ แต่บางคนจะได้หมายเหตุ discuss ในช่อง 8 คือส่วน D เอาไว้ แต่ยังไม่ให้คะแนน คืออยากให้มีการอธิบายว่าวิธีว่า output ที่ได้มานั้นอ่านอย่างไร (จะดู Output ว่า Output นี้ถูกได้อย่างไร)  แต่มีคนที่ใส่ Ram (Notepad) มาลอยๆ และไม่ได้อธิบายอะไร พี่ก็จะหักคะแนนส่วน D ไปเลย (ส่วน D เป็น 0 คะแนน)  ทั้งนี้พยายามอิงเกณฑ์ Logic เดิมไปก่อนคือดูที่การกรอกข้อมูลรายงาน ส่วนใหญ่จึงได้คะแนนเต็ม

Lab 5-6, Lab 7-8
Lab 5-6, Lab 7-8 พี่จะถือว่ามี Data ที่ต้องส่งมีสองอันคือ

  • ASM Chart+Data Path+Code เฉพาะส่วน always@* (block 2 ของ Finite State Machine) รวมกันเป็น Output หนึ่งอัน (ส่วน ASM Chart+Data Path จะได้คะแนนเต็มอยู่แล้ว  เพราะตรวจแล้ว จะหักคะแนนส่วนนี้ก็ต่อเมื่อ ASM Chart+Data Path ไม่ตรงกับ Code จะหักเฉพาะเมื่อ ASM Chart Design อีกแบบหนึ่ง แต่ Code ไปอีกแบบหนึ่ง เพราะถือว่าไม่ซื่อตรงต่อ Design อาจไปก็อบใครมาก็ได้)
  • Ram (Notepad) และอธิบายวิธีการอ่านค่า Output และกรอกค่า Input

ไม่ต้องส่ง Timing Diagram และ Test Fixture

Posted in บทความ, Lab Verilog | Tagged , , | 4 Comments

CP Sport Week

CP Sport Week เป็นงานกีฬาประจำภาควิชาวิศวกรรมคอมพิวเตอร์ที่จัดขึ้นทุกปี ปีนี้จัดในวันที่ 29 พฤศจิกายน – 4 ธันวาคม 2553 (ต่อจากกีฬาเอเชียนเกมส์พอดี🙂 )

ทีมการแข่งขัน

การแข่งขันแบ่งออกเป็น 4 ทีมได้แก่

  1. นิสิตปริญญาตรีปี 2
  2. นิสิตปริญญาตรีปี 3
  3. นิสิตปริญญาตรีปี 4
  4. นิสิตปริญญาโท ปริญญาเอก นิสิตปริญญาตรีปี 1 ศิษย์เก่า (มาร่วมก็ได้นะ) อาจารย์ บุคลากร หรือบุคคลอื่นๆ ที่ได้รับอนุญาตจากอาจารย์

ชนิดกีฬาที่แข่งขัน

  1. ฟุตบอล
  2. บาสเกตบอล
  3. ดอทเอ
  4. วินนิ่ง
  5. กีฬาฮาเฮ
  6. แบดมินตัน
  7. ปิงปอง
  8. แชร์บอล

ลิงก์ข้อมูล

ประชาสัมพันธ์

Posted in กิจกรรม | Tagged | Leave a comment

Verilog Programming Style: Finite State Machine

บล็อกนี้เป็นบล็อกที่ต่อมาจากบล็อก Verilog Programming Style: Declaration

ในบล็อกนี้เรามาดูส่วนสำคัญนั่นคือ Finite State Machine ซึ่งเป็นส่วนควบคุมหลัก Finite State Machine ใน module ATM จะเขียนแบบ two-block ดังนี้

 //state
 reg[2:0] ps=0,ns=0;
 always@(posedge clock)begin
 if(command==RESET) ps<=0;
 else ps<=ns;
 end

 always@*begin

enT=0;enFh=0;enH=0;nT=memT;nFh=memFh;nH=memH;nBalance=balance;nDraw=draw;ready=0;

ns=0;
 case(ps)
 0:begin ns=1;  ready=1; nDraw=0; nT=0; nFh=0; nH=0; end
 1:begin
 ready=1;
 case(command)
 DEPOS: ns=2;
 WDRAW:ns=3;
 default:ns=0;
 endcase
 end
 2:begin
 nBalance=balance+(t<<3)+(t<<1)+(fh<<2)+fh+h;
 ns=0;
 end
 3:begin
 if(balance<need_money) ns=0;
 else begin nBalance=balance-need_money; nDraw=need_money; ns=4; end
 end
 4:begin
 if(draw>10) begin nDraw=draw-10; nT=memT+1; ns=4; end
 else begin ns=5; end
 end
 5:begin
 if(draw>5) begin nDraw=draw-5; nFh=memFh+1; ns=5; end
 else begin nH=draw; ns=6; end
 end
 6:begin enT=1; enFh=1; enH=1; ns=0; end
 default: begin ns=0; end
 endcase
 end

คราวนี้เราก็มาดูเป็นส่วนๆ เหมือนเช่นเคย

Block ที่ 1 ของ Finite State Machine

 //state
 reg[2:0] ps=0,ns=0;
 always@(posedge clock)begin
 if(command==RESET) ps<=0;
 else ps<=ns;
 end

Block ที่ 1 นั้นก็เหมือนการประกาศ register ปกตินั่นคือ register ps และ ns เป็น next signal ใน ISE Design คำว่า ps มักถูก hilight เป็นสีน้ำเงิน ไม่ต้องตกใจ ps ไม่ได้เป็นคำสงวนที่ห้ามใช้ประกาศเป็นชื่อแต่อย่างใด เพียงแต่โดน hilight ให้มันดูเด่นขึ้นเฉยๆ น่าจะเกิดจากการที่ ps ไปตรงกับตัวย่อคำว่า “picosecond” พอดี

Default Value

always@*begin

enT=0;enFh=0;enH=0;nT=memT;nFh=memFh;nH=memH;nBalance=balance;nDraw=draw;ready=0;

ns=0;

Block ที่ 2 เป็นบล็อกที่ผมมักเรียกว่า star block บล็อกนี้มักเป็นบล็อกเดียวใน module ที่มี always@* ถ้าในวงจรนี้ไม่มี combinational logic ส่วนอื่นๆ เช่น encoder หรือ decoder อีก หลัง always@* มักมีการประกาศกำหนดค่าปริยาย (Default Value) ของ signal ต่างๆ signal ที่จะถูกควบคุมจะใน star block นี้แบ่งได้ออกเป็น 4 ประเภท คือ enable signal ของ inout, next signal ของ register, control signal ของ register พิเศษเช่น counter และ flag signal เช่น ready ของ module เอง ทั้งนี้ควรระบุค่า default ทั้งหมดของ signal ที่จะถูก Finite State Machine ควบคุม เพื่อกันไม่ให้วงจร synthesis signal ดังกล่าวเป็น Latch ได้ (ซึ่ง Latch นี่เองมักจะนำไปสู่ “บั๊ก”)

ทั้งนี้พึงสังเกตว่า เราไม่ควรจะไปควบคุม register ต้นแบบโดยตรง แต่ควรควบคุมผ่าน next signal ของ register และเพื่อให้ปรับเป็นค่าใหม่นั้นใน clock ถัดไป

State Label และ Reset State

 case(ps)
 0:begin ns=1;  ready=1; nDraw=0; nT=0; nFh=0; nH=0; end

การสร้าง state transition table นั้นเรามักใช้ switch-case เพื่อทำให้โค้ดดูดีขึ้น (Clean Code) เราอาจตั้งชื่อ state ผ่าน parameter ได้ แต่ไม่แนะนำเวลาทำ Lab เพราะเวลาแก้ไขจะต้องแก้ไขซ้ำซ้อน คือต้องไปเพิ่มตรงที่ประกาศ parameter และก็ต้องมาเพิ่มชื่อ state ดังกล่าวใน star block อีก ทางที่ดีหากไม่อยากสับสนให้ comment ไว้เหนือ state จะดีกว่า

state 0 มักถูกเก็บไว้เป็น reset state คือยังไม่ใช่ส่วนที่เริ่มต้นจริงๆ แต่เป็นส่วนที่ clear ค่าต่างๆ เพื่อพร้อมที่จะเริ่มทำงานต่อไป เป็น state ที่จะกระโดดมาเวลา reset ตอนเริ่มต้นออกแบบมักจะเขียนกันไว้ว่า

 case(ps)
 0:begin ns=1; end

อย่างนี้ก่อนเป็น passing state เปล่าๆ หนึ่งอัน แล้วค่อยมาวิเคราะห์ต่อว่าค่าใดเป็นค่าที่ต้อง clear ก่อนเพื่อให้ module พร้อมที่จะทำงานในรอบใหม่ต่อไป

Command Choice

 1:begin
    ready=1;
    case(command)
       DEPOS: ns=2;
       WDRAW:ns=3;
       default:ns=0;
    endcase
    end

state หนึ่งที่น่าสนใจคือ state ที่เลือก command; state นี้มักจะอยู่เป็น state ที่ 1 ต่อจาก reset state; state นี้ไว้พิจารณาดูว่าขณะนี้มี command อะไรเข้ามาบ้าง; command choice มักอยู่ในรูปแบบ switch-case และที่สำคัญเช่นกันคืออย่าลืม default case (เดี๋ยวจะถูกเข้าใจเป็น latch อีก) และที่ต่างจากภาษาโปรแกรมส่วนใหญ่คือ switch-case ใน Verilog จะไม่ต้อง break; และใช้ keywork case แทน keyword switch ทั้งนี้เตือนเพราะจะสับสนเวลาเขียนโปรแกรมในภาษาอื่น

Arithmetic Logic Transition

2:begin
   nBalance=balance+(t<<3)+(t<<1)+(fh<<2)+fh+h;
   ns=0;
   end

หลายครั้งที่ในวงจรต้องมีการคำนวณที่ซับซ้อนเช่น คูณหรือหาร แต่ทว่านี่ไม่ใช่ภาษาโปรแกรมเชิงซอฟต์แวร์ ดังนั้นเราจึงต้องคิดว่าการคำนวณเหล่านั้นจะ synthesis ออกมาเป็นวงจรอย่างไร สำหรับการคูณหรือหารด้วยค่าคงที่บางจำนวน เช่น 2n อาจลดรูปเป็นวงจรได้ง่ายด้วยการ shift คูณ 2 ก็ shift left 1 ที คูณ 4 ก็ shift left 2 ที เป็นต้น

การหารก็ในทางกลับกัน หาร 2 ก็ shift right 1 ที หาร 4 ก็ shift right 2 ที หากคูณค่าคงที่ที่ไม่ใช่ 2n ก็อาจใช้กฎการแจกแจงเข้าช่วยเช่น t*10 ก็กระจายเป็น (t*8)+(t*2) ก็กลายเป็น (t<<3)+(t<<1) จะใช้เลขอะไรช่วยแจกแจงนั้นก็สามารถดูได้ด้วยการเปลี่ยนเลขนั้นเป็นไบนารีดูเช่น t*15 15 มีเลขไบนารีเป็น 1111 หรือกล่าวอีกนัยหนึ่งว่า 15=8+4+2+1 ได้นั่น เอง ก็จะได้ว่า t*15= (t*8)+(t*4)+(t*2)+(t*1) = (t<<3)+(t<<2)+(t<<1)+t นั่นเอง

สำหรับการหารเลขที่ไม่ใช่ 2n อาจมีปัญหาสักหน่อย เพราะไม่มีกฎการแจกแจงการหาร เราเปลี่ยนการหารเป็นการคูณไมได้เพราะจะสร้างเป็นทศนิยมซ้ำ เช่น t/3=t*1/3 1/3 ในไบนารีก็จะเป็น 0.01010101… อาจทำให้เสียความแม่นยำลงไปได้ ทางที่ดีเราอาจใช้วน loop แล้วค่อยๆ ลบเอา ระหว่างนั้นก็เพิ่มตัวหาร หรือที่เรากันว่า childish algorithm จะดีกว่า

สำหรับการคูณหารค่าใน register 2 ตัวก็อาจทำโดยใช้ loop ด้วยการบวกไปเรื่อยๆ สำหรับการคูณ หรือลบไปเรื่อยๆ สำหรับการหาร หรืออาจจะใช้ algorithm การ shift หรือเลือกใช้การ represent ตัวเลขด้วยระบบ floating point เพราะหากมีการคำนวณจำนวนมาก floating point จะใช้ logarithm เข้าช่วยเพื่อเปลี่ยนการคูณ-หารเป็นการบวก-ลบได้ สำหรับ balance ในที่นี้เราสามารถมองได้เป็น nBalance=balance+(t*10)+(fh*5)+h จะสังเกตเห็นได้ว่า แบงค์พัน แบงค์ห้าร้อย และแบงค์ร้อยจะถูกคูณแค่ 10 5 และ 1 ตามลำดับเท่านั้น นั่นเพราะเราเก็บ balance ในหน่วยร้อยบาทนั่นเอง การออกแบบวิธีการ represent ข้อมูลอย่างเหมาะสมสามารถช่วยลดความซับซ้อนในการคำนวณได้

บางการคำนวณมีวงจรสำเร็จอยู่แล้วเช่น บวกและลบ บางการคำนวณต้องคำนึงถึงอัลกอริทึมและโครงสร้างข้อมูลที่ใช้เก็บเอง ดังนั้น เราจึงต้องคำนึงถึงทรัพยากรที่เรามีอยู่นอกเหนือจากความต้องการทางด้านการใช้งานเพียงเดียว

Type of State and Looping State

3:begin
 if(balance<need_money) ns=0;
 else begin nBalance=balance-need_money; nDraw=need_money; ns=4; end
 end
 4:begin
 if(draw>10) begin nDraw=draw-10; nT=memT+1; ns=4; end
 else begin ns=5; end
 end
 5:begin
 if(draw>5) begin nDraw=draw-5; nFh=memFh+1; ns=5; end
 else begin nH=draw; ns=6; end
 end
 6:begin enT=1; enFh=1; enH=1; ns=0; end
 default: begin ns=0; end
 endcase
 end
//โค้ดส่วนนี้แสดงอัลกอริทึมการทอนเงินใน Lab 2 ให้ดูด้วย

ถ้าหากลองพิจารณาดูจะพบว่าลักษณะการเขียน state แบ่งได้เป็น 3 แบบใหญ่ๆ คือ

  1. Passing State คือ state ที่จะไป state ถัดไปแน่นอน แต่มาแวะผ่านเพื่อ set ค่า, clear ค่า, รอการทำงาน และ อื่นๆ เช่น Reset State ดังกล่าวขั้นต้น
  2. Choice State คือ state ที่พิจารณาว่าสถาการณ์ในปัจจุบันนี้ควรจัดการด้วยการไปที่ state ไหน ส่วนมากจะใช้พิจารณา command
  3. Looping State คือ state ที่จะดักทำการเปลี่ยนค่าให้สอดคล้องกับเงื่อนไขก่อน แล้วจึงปล่อยให้ระบบไปยัง state อื่นต่อไป ลักษณะสำคัญของ state แบบนี้คือจะมีการทำงานหลัง if เพื่อดักให้ค่าที่ไม่เหมาะสมเข้ามา เปลี่ยนค่าต่างๆ และกำหนดให้ nextstate เป็น state เดิม จนกว่าจะผ่านเงื่อนไขจึงจะผ่านไปได้ ดังนั้นจึงทำให้ Looping State มักถูกออกแบบแบบ Mealy เพราะมีการเปลี่ยนแปลงหลังจากที่ผ่านการเช็คเงื่อนไขแล้ว หรือเขียนใน ASM Chart เป็นรูปวงรี

การเขียนวิธีการควบคุม control signal ในแต่ละ state มีหลายแบบ บ้างเขียนไล่ control signal ที่จะควบคุมใน state นั้นๆ การไล่ก็มี 2 แบบ บ้างก็เขียนไล่ในบรรทัด ซึ่งมีข้อดีคือจะทำให้โค้ดดูสั้นเป็นพิเศษ แต่โค้ดจะดูยากหรือจะเขียนไล่สัญญาณละบรรทัดก็ได้ แต่ if else หรือ case ส่วนมากจะเขียน case ละบรรทัด บางคนอาจแยก control signal บางอันออกมา เขียนนอก Finite State Machine เป็น Mealy Assignment เช่น

assign flag= (ps==2)||(ps==8);

ข้อดีของวิธีนี้คือสามารถลด control signal ที่ Finite State Machine ควบคุมแต่ข้อเสียคือถ้าจะเปลี่ยน state จะต้องแก้หลายที่ แต่ก็สามารถทำได้ แต่โค้ดที่ไม่ควรทำเลยคือการไป hack state คือไปเก็บ state ไปเปลี่ยน state นอก Finite State Machine กล่าวโดยง่ายคือพยายามทำอะไรที่พยายามไปควบคุม Finite State Machine ซึ่งไม่ควร เพราะ Finite State Machine ควรจะเป็นตัวที่ควบคุมทั้งหมด ทั้งนี้การพยายามควบคุม Finite State Machine จะทำให้ synthesis ได้วงจรที่ซับซ้อนและมักจะตามมาด้วยปัญหาเสมอ

โดยภาพรวมแล้วโค้ด Verilog จะมีความยาวหลายบรรทัด แต่มี pattern ซ้ำๆ กันจนดูเหมือน copy paste ไปๆมาๆ ทั้งนี้ก็เพื่อเหตุผลเดียวอันเป็นหัวใจสำคัญของการเขียน Verilog นั่นคือ ให้วงจรสามารถ synthesis ได้ง่ายและตรงประเด็นที่สุด

Posted in เทคนิควิธีการ, Lab Verilog | Tagged , , | Leave a comment

Verilog Programming Style: Declaration

Programming Style เป็นกฎหรือข้อชี้แนะที่ใช้ในการเขียนโค้ด ซึ่งกฎหรือข้อชี้แนะเหล่านี้จะช่วยให้โปรแกรมอ่านแล้วเข้าใจง่าย ช่วยให้โปรแกรมเมอร์ทำงานร่วมกันได้ง่ายเพราะใช้ Style เหมือนกัน และที่สำคัญคือช่วยป้องกันไม่ให้เกิด “บั๊ก” ได้ [ดัดแปลงมาจาก Wikipedia: Programming Style]

Verilog นั้นแม้เป็นภาษาบรรยายเชิงฮาร์ดแวร์ (Hardware Description Language) แต่ทว่า Programming Style ใน Verilog กลับเป็นสิ่งที่ควรคำนึงถึงอย่างยิ่ง เพราะรูปแบบของโค้ดเป็นองค์ประกอบสำคัญในการพิจารณาการสังเคราะห์ฮาร์ดแวร์ (Hardware Synthesis) ถึงขนาดใน Xilinx ISE Design ต้องมี Language Template เพื่อให้สังเคราะห์ฮาร์ดแวร์ได้ตรงตามความต้องการ

Style ที่ดีคือ Style ที่ช่วยป้องกันไม่ให้เกิดบั๊กได้ เนื่องจากบั๊กส่วนมากมักไม่ได้เกิดจากการออกแบบครั้งแรก แต่มักเกิดจากการเปลี่ยนใจและเข้าแก้ไขโค้ดในภายหลัง ดังนั้น Style ที่ดีจึงควรเอื้อต่อการปรับเปลี่ยนในภายหลังได้ ทั้งนี้ไม่ได้หมายความว่า Style ที่ไม่ดีจะทำงานไม่ได้หรือทำได้ไม่ดี เพียงแต่อาจจะปรับเปลี่ยนภายหลังได้ยาก คราวนี้เราลองตั้งโจทย์ที่ครอบคลุม Lab 1-3 เพื่อยกตัวอย่าง Style หลักๆ ที่ใช้ และแสดงให้เห็นว่า Style เหล่านั้นสามารถปรับเปลี่ยนได้ง่ายอย่างไร?

โจทย์จำลองที่เราจะพูดถึงในบล็อกนี้คือ ATM ATM นี้มี 4 คำสั่ง (Command) คือ RESET DEPOS WDRAW และ NOPER ใน ATM จะมีหน่วยความจำส่วนหนึ่งไว้เก็บเงินในบัญชี (balance) ไว้เพียงบัญชีเดียว (เอาง่ายๆ) แต่ละคำสั่งจะทำงานดังนี้

  1. RESET จะทำการเคลียร์ค่าทั้งหมดใน ATM ยกเว้น balance จะเก็บค่าเดิมไว้
  2. DEPOS จะทำการฝากเงิน (คือบวกเงินเพิ่มใน balance) ซึ่งการฝากเงินนั้นจะใส่ผ่านช่องทาง (Channel) 3 ช่องคือ t (thousand ช่องใส่แบงค์พัน) fh( five hundred ช่องใส่แบงค์ห้าร้อย) และ h (hundred ช่องใส่แบงค์ร้อย) ช่องทางดังกล่าวเป็นลักษณะ inout คือฝากก็ฝากที่นี่ถอนก็ถอนที่นี่
  3. WDRAW คือการถอน ต้องใส่เงินที่ต้องการผ่าน need_money ถ้าเงินที่จะถอนมากกว่าเงินที่มีอยู่ ก็จะถอนไม่ได้ ถ้าถอนได้ก็จะถอนออกมาผ่านช่องทาง t fh และ h
  4. NOPER ย่อมาจาก No Operation แปลว่าไม่ต้องทำอะไร เป็นคำสั่งเปล่านั่นเอง

ATM นี้ยังมีความสามารถและข้อจำกัดอื่นๆ ที่ยังไม่ได้กล่าวในรายละเอียดเช่น จำนวนเงินฝากรับได้สูงสุด และยังไม่ใช่การออกแบบฮาร์ดแวร์ที่ดี เช่นในการออกแบบฮาร์ดแวร์ดังกล่าวไม่ใส่ Single Pulser เป็นต้น ทั้งนี้เพื่อลดรายละเอียดที่ไม่จำเป็นและแสดง Style ให้ชัดเจนยิ่งขึ้น โค้ด ATM ที่ออกแบบมาเป็นดังนี้

module atm(
 input clock,
 input[9:0] need_money,
 input[1:0] command,
 inout[6:0] t,
 inout[6:0] fh,
 inout[6:0] h,
 output reg [2:0] ps=0,
 output reg[9:0] balance,
 output reg ready
 );

 //command
 parameter[1:0] RESET=0,DEPOS=1,WDRAW=2,NOPER=3;

 //inout config
 reg enT=0,enFh=0,enH=0;
 reg[6:0] memT=0,memFh=0,memH=0,nT=0,nFh=0,nH=0;
 assign t=  enT?memT:7'bz;
 assign fh= enFh?memFh:7'bz;
 assign h=  enH?memH:7'bz;

 always@(posedge clock)begin
 if(command==RESET) memT<=0;
 else memT<=nT;
 end

 always@(posedge clock)begin
 if(command==RESET) memFh<=0;
 else memFh<=nFh;
 end

 always@(posedge clock)begin
 if(command==RESET) memH<=0;
 else memH<=nH;
 end

 //balance
 reg[9:0] nBalance=0;
 always@(posedge clock)begin
 if(command==RESET) balance<=0;
 else balance<=nBalance;
 end

 //draw
 reg[9:0] draw=0,nDraw=0;
 always@(posedge clock)begin
 if(command==RESET) draw<=0;
 else draw<=nDraw;
 end

 //state
 reg[2:0] ns=0;
 always@(posedge clock)begin
 if(command==RESET) ps<=0;
 else ps<=ns;
 end

 always@*begin

enT=0;enFh=0;enH=0;nT=memT;nFh=memFh;nH=memH;nBalance=balance;nDraw=draw;ready=0;

ns=0;
 case(ps)
 0:begin ns=1;  ready=1; nDraw=0; nT=0; nFh=0; nH=0; end
 1:begin
 ready=1;
 case(command)
 DEPOS: ns=2;
 WDRAW:ns=3;
 default:ns=0;
 endcase
 end
 2:begin
 nBalance=balance+(t<<3)+(t<<1)+(fh<<2)+fh+h;
 ns=0;
 end
 3:begin
 if(balance<need_money) ns=0;
 else begin nBalance=balance-need_money; nDraw=need_money; ns=4; end
 end
 4:begin
 if(draw>10) begin nDraw=draw-10; nT=memT+1; ns=4; end
 else begin ns=5; end
 end
 5:begin
 if(draw>5) begin nDraw=draw-5; nFh=memFh+1; ns=5; end
 else begin nH=draw; ns=6; end
 end
 6:begin enT=1; enFh=1; enH=1; ns=0; end
 default: begin ns=0; end
 endcase
 end

endmodule

คราวนี้เราลองมาวิเคราะห์ Style ในแต่ละบรรทัดกัน

วิธีการประกาศ output

module atm(
 //...
 output reg [2:0] ps=0,
 output reg[9:0] balance,
 output reg ready
 );

output ส่วนมากจะเป็น reg อยู่แล้ว เราไม่จำเป็นต้อง assign ค่า output และประกาศ output เป็น wire และในเมื่อ output เป็น reg อยู่แล้ว เราก็ควรประกาศควบคู่กันซะเลย เพื่อให้เวลาแก้ไขชื่อหรือจำนวนบิตก็จะแก้ที่เดียว หาก Simulate ควรเอาสิ่งที่น่าสนใจออก output ให้หมด เพื่อเวลา Generate Test Fixture จะได้ Generate ได้ง่าย output ที่ควรออกเช่น state เป็นต้น

ลักษณะ Style ที่ไม่ค่อยดี

การทำให้ output เป็น wire เป็นการซ้ำซ้อน

module atm(
//...
 output r
 );

reg ready
assign r=ready;

ประกาศ output ทีแล้วก็ reg อีกทีเป็นการซ้ำซ้อนเช่นกัน (บางครั้ง ISE Design บางรุ่นก็ไม่ให้ประกาศเช่นนี้)

module atm(
//...
 output ready;
 );

reg ready

วิธีการประกาศ command

//command
parameter[1:0] RESET=0,DEPOS=1,WDRAW=2,NOPER=3;

command ควรจะประกาศเป็น parameter เพื่อให้ผู้อ่านเข้าใจได้ง่ายว่า command แต่ละอันใช้ทำหน้าที่อะไรและควรประกาศส่วนบนของ module เพื่อให้ผู้อ่านเข้าใจว่า module นี้มีลักษณะการทำงานแบบ command มี command อะไรบ้าง การประกาศแต่ละส่วนควรเว้นวรรคและ comment ไว้ข้างบนเพื่อให้รู้ว่าส่วนนี้เอาไว้ประกาศอะไร

วิธีการ config inout

 //inout config
 reg enT=0,enFh=0,enH=0;
 reg[6:0] memT=0,memFh=0,memH=0,nT=0,nFh=0,nH=0;
 assign t=  enT?memT:7'bz;
 assign fh= enFh?memFh:7'bz;
 assign h=  enH?memH:7'bz;

inout มักจะมีการ config เป็น tristate การ config inout หลายรูปแบบทั้งนี้ขึ้นอยู่กับว่าผู้เขียนมีมุมมอง inout ในรูปแบบไหน? ในที่นี้แสดงการ config แบบ Using assignment and ternary operation โดยมอง inout เหมือนช่องสัญญาณเน็ตเวิร์กในอินเตอร์เน็ต กล่าวเปรียบเทียบได้เหมือนเราสร้างเขื่อน ในขณะที่สัญญาณเข้ามาทาง inout เราก็ปิดเขื่อนคือ disable ซะ (ทำให้ enable เป็นศูนย์) ในขณะที่ถ้าเราอยากปล่อยสัญญาณออก เราก็เปิดเขื่อนหรือ enable ออกไป (ทำให้ enable เป็นหนึ่ง) เรามักเรียกส่วนที่กักเก็บค่าก่อนปล่อยออกมาว่า buffer และเรียกประตูที่ปล่อยสัญญาณว่า enable

ข้อดีของวิธีการนี้คือ Finite State Machine เราสามารถควบคุม inout ได้อย่างเบ็ดเสร็จ แต่บางครั้งการควบคุมเบ็ดเสร็จก็มีปัญหาในการออกแบบวงจร บางครั้งหลายคนจึงมักออกแบบวงจรให้การควบคุม inout ที่เป็นไปโดยอัตโนมัติเช่น

 //inout config
 assign databus=  (cs&&!rw) ? buff:8'bz;

ทั้งนี้มีข้อดีคือ finite state machine ไม่จำเป็นต้องควบคุมสัญญาณทุกอย่าง และการันตีว่า buffer จะถูกปล่อยหลังจากที่ทุกอย่างพร้อมแล้ว

มีอีกวิธีหนึ่งที่จะควบคุม inout คือการเขียนในลักษณะ Using always and if-else วิธีนี้แทนที่จะมองว่าเป็นปล่อยหรือไม่ปล่อย กลับมองว่าเราปล่อยสัญญาณทุกขณะ ขณะที่เราต้องการรับสัญญาณ เราก็จะมองว่าเป็นปล่อยสัญญาณ z (hi-impedance) เพื่อรับฟังสัญญาณด้วยเช่นกัน วิธีนี้อาจทำให้เกิดสัญญาณตีกันจึงมักแก้ด้วยการปล่อยสัญญาณ z บ่อยๆ วิธีนี้มักใช้กับอุปกรณ์ที่บังคับความเป็น inout เช่น RAM (ศึกษาเพิ่มเติมใน Language Template>Synthesis Construct>Coding Example>Tristates Buffer)

 reg[7:0] buff;
 assign databus=buff;
 always @* begin
 buff=8'bz;
 if (cs) begin
 if (rw) buff = ram[address];
 else begin ram[address] = databus; buff=8'bz; end
 end
 else buff=8'bz;
 end

inout มักถูกประกาศเป็นอันดับแรกของ module (ยกเว้นถ้ามี command parameter ตัว inout จะถูกประกาศเป็นอันดับสอง) เพราะ Verilog ต้องประกาศตัวแปรก่อนใช้และ buffer ใน inout เป็นตัวที่ใช้บ่อยๆ อีกทั้ง inout ยังเป็นส่วนต่อประสาน (interface) กับภายนอกจึงมักประกาศ config inout ไว้บนสุด

วิธีการประกาศ register

 //draw
 reg[9:0] draw=0,nDraw=0;
 always@(posedge clock)begin
 if(command==RESET) draw<=0;
 else draw<=nDraw;
 end

register เป็นหน่วยความจำซึ่งเปรียบเสมือน “ตัวแปร” ในโปรแกรมเชิงซอฟต์แวร์การประกาศ register มักจะประกาศในหน้าตาแบบนี้ (ศึกษาเพิ่มเติมใน Language Template>Synthesis Construct>Coding Example>Flip flop)

//สมมติว่าประกาศตัวแปร pc ขนาด 3 บิต
reg[2:0] pc=0,nextpc=0;
always @(posedge clock)
 if (reset) pc <= 0;
 else pc <= nextpc;

สังเกตว่าควรใส่ค่าเริ่มต้น (initial) ของ register ทุกครั้งและประกาศ next signal ซึ่งเป็นสัญญาณที่จะถูก assign ใน clock ต่อไป next signal มักประกาศติดกับ register ต้นแบบ (เพราะต้องมีจำนวนบิตเท่ากันอยู่แล้ว)  การตั้งชื่อ next signal มักจะใส่ตัว n ต่อหน้าเช่น next signal ของ register ชื่อ time มัีกตั้งชื่อว่า nTime เป็นต้น next signal นี่เองที่เป็นตัวที่บล็อกที่สองใน Finite State Machine คอยควบคุม

ในบางครั้ง register บางอันไม่ใช่หน่วยความจำ แต่ทำหน้าที่อื่นเช่น counter หากเป็น counter จะต้องมี control signal คอยควบคุมมักจะต้องชื่อ incX และ decX สำหรับ count up และ down ของ counter ชื่อ x ตามลำดับ

//พึงระวัง ควรเขียน else สุดท้ายให้ครบเพราะมิฉะนั้นวงจรจะ synthesis เป็น latch ได้
reg[2:0] pc=0;
reg incP,decP;
always @(posedge clock)
 if (reset) pc <= 0;
 else if(incP) pc<=pc+1;
 else if(decP) pc<=pc-1;
 else pc<=pc;

แต่ทั้งนี้ไม่ควรสร้าง control signal มากเกินควร เพราะเวลาแก้ไขจะต้องแก้ไขถึงสองสามที่ ควรทำ control signal เฉพาะการ count up one และ count down one เท่านั้น (เพราะการ generate counter up/down one จะประหยัด resource มากกว่าการสร้างหน่วยความจำและใส่ next signal ทีหลัง)

ลักษณะ Style ที่ไม่ดี

 reg[9:0] balance=0;
 reg incHundred,incFiveHundred,incThousand;
 always@(posedge clock)begin
 if(reset) balance<=0;
 else if(incHundred) balance<= balance+100;
 else if(incFiveHundred) balance<= balance+500;
 else if(incThousand) balance<=balance+1000;
 else balance<=balance

ควรแก้ไขเป็น

 reg[9:0] balance=0,nBalance=0;
 always@(posedge clock)begin
 if(reset) balance<=0;
 else balance<=nBalance;
//แล้วในบล็อกที่สองของ Finite State Machine ค่อยมาใส่ nBalance=Balance+100 ฯลฯ ทีหลัง

เดี๋ยวบล็อกถัดไปค่อยมาต่อเรื่อง Finite State Machine

Posted in เทคนิควิธีการ, Lab Verilog | Tagged , | 5 Comments