วิธีการทดลอง
จงออกแบบวงจรดิจิลัทโดยใช้ภาษา VHDL สำหรับนำไปสร้างเป็นวงจรในชิป FPGA โดยใช้บอร์ดที่มีอยู่ในห้องแล็ป
วงจรดิจิทัลมี I/O ดังนี้
- CLK (input) มีความถี่ 50MHz ใช้สำหรับกำหนดจังหวะการทำงานของวงจรทั้งหมด (เป็นการออกแบบวงจรดิจิทัลแบบ Synchronous Design)
- RST_B (input) เป็นอินพุตสำหรับใช้รีเซตแบบ Asynchronous สำหรับการทำงานของวงจรโดยรวม (ทำงานแบบ Active-Low) ซึ่งได้จากวงจรปุ่มกด (Push Button)
- PB (input) เป็นอินพุตจากปุ่มกด 1 ปุ่ม ทำงานแบบ Active-low เพื่อใช้ในการเปลี่ยนสีของ WS2812 RGB LED จำนวน 1 ดวง
- DATA (output) เป็นเอาต์พุตสำหรับนำไปควบคุมการทำงานของ WS2812 RGB LED เพียง 1 ดวง ซึ่งเป็นสัญญาณตามข้อกำหนดของชิป WS2812 เพื่อส่งข้อมูลจำนวน 24 บิต
พฤติกรรมการทำงานเป็นดังนี้
- เมื่อเริ่มต้นหรือกดปุ่มรีเซต (RST_B) จะทำให้ค่าสีเป็น 0x000000 (24 บิต) และส่งออกไปยัง WS2812 RGB LED หนึ่งครั้ง
- เมื่อมีการกดปุ่ม PB แล้วปล่อยในแต่ละครั้ง จะมีการเปลี่ยนค่าสี 24 บิต แล้วส่งออกไปยัง RGB LED ใหม่หนึ่งครั้ง ตามลำดับดังนี้
0x000000 -> 0x0000FF -> 0x00FF00 -> 0xFF0000 แล้ววนซ้ำ
แนวทางการออกแบบและทดสอบ
นำวงจรเดิม (WS2812 RGB LED) ที่ได้ออกแบบไว้ด้วยภาษา VHDL ในการทดลองที่ 2 มาแก้ไข โดยแบ่งวงจรเดิม (design partitioning) ในระดับ top-level design ให้มีหรือประกอบด้วย component อย่างน้อย 3 ส่วน และออกแบบแต่ละส่วน ให้สามารถนำกลับมาใช้ได้อีก (design for reuse) และเมื่อนำมาร่วมกัน ยังสามารถทำงานได้ตามเดิม อธิบายการทำงานของแต่ละส่วนว่า มีอินเทอร์เฟส (interface) หลักการทำงาน และใช้เพื่อวัตถุประสงค์ในวงจร + การจำลองการทำงาน (Simulation) ของแต่ละส่วนด้วย VHDL Testbench (Unit Testing) และใช้ VHDL testbench เดิมทดสอบระบบรวม (Integration Testing)
แนวทางการออกแบบ
ออกแบบวงจรรวมที่จะประกอบด้วย 3 components ย่อย
ประกอบด้วย
ส่วนที่ 1 : toggle_switch
I/O port :
รับสัญญาณ clk(std_logic) 50MHz
รับสัญญาณ pb(std_logic) จากวงจรปุ่มกดแบบ Active Low
ส่งสัญญาณ Q(std_logic) ออกซึ่งหากมีการกดปุ่มจะทำให้สัญญาณ Q เป็น logic HIGH ความยาว 1 clk (จาก clk ขาลงถึง clk ขาลง)
Generic Parameter :
[push_delay] ค่า delay ระยะเวลาการกดปุ่ม (หน่วย clk)
Note : ในการจำลอง (Simulation) กำหนดค่าเป็น 100 เมื่อนำไปใช้จริงกำหนดค่าเป็น 1000000
หน้าที่ : ใช้ป้องกันสัญญาณที่ไม่เสถียรจากปุ่มกด และส่งสัญญาณให้วงจร shiftregis เพียง 1 clk ต่อการกดปุ่ม 1 ครั้ง (จาก clk ขาลงถึง clk ขาลง)
รูปแผนภาพ Finite State Machine :
โค้ด VHDL การทำงานของวงจร :
โค้ด VHDL testbenchของวงจร :
ส่วนที่ 2 : shiftregis
I/O port :
รับสัญญาณ clk(std_logic) 50MHz
รับสัญญาณ rst_b(std_logic) รีเซตเพื่อรีเซตแบบ Asynchronous
รับสัญญาณ pb(std_logic) จากวงจร toggle_switch
ส่งสัญญาณ start(std_logic) สำหรับบอกว่าจะเริ่มมีการส่งค่า (Active High)
ส่งสัญญาณ data(std_logic) สำหรับบอก index ของสีที่อยู่ใน Array ในวงจร led_pwm_generator
Generic Parameter :
[bit_num] จำนวนบิตของตัวเลข index ที่จะส่งออกไป
[color_num] จำนวนสีใน Array
หน้าที่ : ส่งสัญญาณที่จะเลือก index ของสีที่อยู่ใน Array ในวงจร led_pwm_generator ซึ่งถ้ารับเป็นสัญญาณ pb จะเพิ่ม index ทีละ 1 วนไปเรื่อยๆ และถ้าเป็นสัญญาณ rst_b จะรีเซตไปเป็น 0
รูปแผนภาพ Finite State Machine :
โค้ด VHDL การทำงานของวงจร :
โค้ด VHDL testbenchของวงจร :
ส่วนที่ 3 : led_pwm_generator
I/O port :
รับสัญญาณ clk(std_logic) 50MHz
รับสัญญาณ rst_b(std_logic) รีเซตเพื่อรีเซตแบบ Asynchronous
รับสัญญาณ start(std_logic) สำหรับบอกว่าเริ่มมีการอ่านค่าได้
รับสัญญาณ data(std_logic) สำหรับบอก index ของสีที่อยู่ใน Array
ส่งสัญญาณ pwm(std_logic) สำหรับควบคุมวงจร RGB LED WS2812
Generic Parameter :
[led_number] จำนวนหลอด RGB LED
[data_bit] ความยาวของ data ที่รับเข้ามา (หน่วย บิต)
[color_num] จำนวนสีใน array
[pwmcycle] จำนวนลูกคลื่นสัญญาณที่ใช้ควบคุม WS2812 ต่อ 1 สี ต่อ 1 ดวง
[T0H] ความกว้าง pulse ช่วง high ของลอจิก '0' (หน่วย clk)
[T1H] ความกว้าง pulse ช่วง high ของลอจิก '1' (หน่วย clk)
[bit_width] ความยาว 1 ลูกคลื่นสัญญาณ (หน่วย clk)
[reset_width] ความยาวช่วงรีเซตของสัญญาณควบคุม WS2812 (หน่วย clk)
หน้าที่ : รับค่า index ของสีเข้ามาและสร้างสัญญาณควบคุม WS2812 ตามสีนั้น หากมี WS2812 ต่อกันหลายดวงสีจะเลื่อนไปเรื่อยๆ (สีของดวงที่ n จะเป็นสีของดวงที่ n+1 ในการกดปุ่มครั้งต่อไป)
รูปแผนภาพ Finite State Machine :
โค้ด VHDL การทำงานของวงจร :
โค้ด VHDL testbenchของวงจร :
โค้ด VHDL การทำงานของวงจรรวม
(จากการแปลง schematic file เป็น vhdl file ด้วยโปรแกรม Quartus II)
โค้ด VHDL testbench ของวงจรรวม
ผลการทดลอง
ผลการทดลองวงจรย่อย (Unit Test)
วงจร toggle_switch
ผลการสังเคราะห์โค้ด VHDL เป็นวงจรในชิปและการใช้ทรัพยากรของบอร์ด FPGA
ผลการจำลองการทำงานด้วย ModelSim
วงจร shiftreg
ผลการสังเคราะห์โค้ด VHDL เป็นวงจรในชิปและการใช้ทรัพยากรของบอร์ด FPGA
ผลการจำลองการทำงานด้วย ModelSim
ส่งข้อมูลขนาด 2 bits
กำหนด data_bit_number : integer := 2;
color_number : integer := 4;
data = 0 ("00")
data = 1 ("01")
data = 2 ("10")
data = 3 ("11")
ส่งข้อมูลขนาด 3 bits
กำหนด data_bit_number : integer := 3;
color_number : integer := 8;
data = 0 ("000")
data = 1 ("001")
data = 2 ("010")
data = 3 ("011")
data = 4 ("100")
data = 5 ("101")
data = 6 ("110")
data = 7 ("111")
วงจร led_pwm_generator
ผลการสังเคราะห์โค้ด VHDL เป็นวงจรในชิปและการใช้ทรัพยากรของบอร์ด FPGA
ผลการจำลองการทำงานด้วย ModelSim
วิธีการอ่าน data
สัญญาณควบคุม WS2812 1 ดวง
สัญญาณ x"000000" (ไม่สว่าง)
สัญญาณ x"0000FF" (สีน้ำเงิน)
สัญญาณ x"00FF00" (สีแดง)
สัญญาณ x"FF0000" (สีเขียว)
สัญญาณควบคุม WS2812 2 ดวง
สัญญาณ x"000000 000000" (ดวงแรกไม่สว่าง ดวงหลังไม่สว่าง)
สัญญาณ x"0000FF 000000" (ดวงแรกสีน้ำเงิน ดวงหลังไม่สว่าง)
สัญญาณ x"00FF00 0000FF" (ดวงแรกสีแดง ดวงหลังสีน้ำเงิน)
สัญญาณ x"FF0000 00FF00" (ดวงแรกสีเขียว ดวงหลังสีแดง)
สัญญาณ x"000000 FF0000" (ดวงแรกไม่สว่าง ดวงหลังสีเขียว)
ผลการทดลองวงจรรวม
ภาพวงจรแบบ RTL View
ผลการสังเคราะห์โค้ด VHDL เป็นวงจรในชิปและการใช้ทรัพยากรของบอร์ด FPGA
ภาพวงจรที่จะใช้ในการจำลองสัญญาณ
Note : ในการจำลอง (Simulation) กำหนดค่าเป็น 100 เมื่อนำไปใช้จริงกำหนดค่าเป็น 1000000
ผลการจำลองการทำงานด้วย ModelSim
ส่งข้อมูล 2 bits (4 สี)
กดปุ่ม pb แล้วออกเป็นไม่สว่าง
กดปุ่ม pb แล้วออกเป็นสีน้ำเงิน
กดปุ่ม pb แล้วออกเป็นสีแดง
กดปุ่ม pb แล้วออกเป็นสีเขียว
กดปุ่ม rst_b
ส่งข้อมูล 3 bit (8 สี)
ส่งข้อมูล 2 bits (4 สี) สำหรับ LED 2 ดวง
สัญญาณ x"000000 000000" (ดวงแรกไม่สว่าง ดวงหลังไม่สว่าง)
สัญญาณ x"0000FF 000000" (ดวงแรกสีน้ำเงิน ดวงหลังไม่สว่าง)
สัญญาณ x"00FF00 0000FF" (ดวงแรกสีแดง ดวงหลังสีน้ำเงิน)
สัญญาณ x"FF0000 00FF00" (ดวงแรกสีเขียว ดวงหลังสีแดง)
สัญญาณ x"000000 FF0000" (ดวงแรกไม่สว่าง ดวงหลังสีเขียว)
ผลการทดลองบนบอร์ด FPGA Altera Cyclone III
การกำหนด pin
ผลการทดลองจากเครื่องออสซิลโลสโคป
ภาพโดยรวมการทดลองโดยแสดงสัญญาณผ่านเครื่องออสซิลโลสโคป
ส่งสัญญาณไฟ 1 ดวง 24 bit (RGB) แต่ละสีมีความยาวสีละ 8 bit ทดลองแสดงค่าสีตามลำดับ [ไม่มีไฟ,B,R,G]
สัญญาณเริ่มต้นจากบอร์ด FPGA เมื่อยังไม่ได้กดปุ่ม
สัญญาณ x"000000" (ไม่สว่าง)
เมื่อกดปุ่มครั้งแรก จะได้สัญญาณ x"0000FF" (ไฟสีน้ำเงิน)
เมื่อกดปุ่มครั้งที่ 2 จะได้สัญญาณ x"00FF00" (ไฟสีแดง)
เมื่อกดปุ่มครั้งที่ 3 จะได้สัญญาณ x"FF0000" (ไฟสีเขียว)
เมื่อกดปุ่มครั้งที่ 4 (กลับมาที่สัญญาณเริ่มต้น) จะได้สัญญาณ x"000000" (ไม่สว่าง)
เมื่อทำการกดปุ่ม Reset จะได้สัญญาณเริ่มต้น สัญญาณ x"000000" (ไม่สว่าง)
ส่งสัญญาณไฟ 2 ดวง
สัญญาณเริ่มต้นจากบอร์ด FPGA เมื่อยังไม่ได้กดปุ่ม
สัญญาณ x"000000 000000" (ดวงแรกไม่สว่าง ดวงหลังไม่สว่าง)
เมื่อกดปุ่มครั้งแรก จะได้สัญญาณ x"0000FF 000000" (ดวงแรกสีน้ำเงิน ดวงหลังไม่สว่าง)
เมื่อกดปุ่มครั้งที่ 2 จะได้สัญญาณ x"00FF00 0000FF" (ดวงแรกสีแดง ดวงหลังสีน้ำเงิน)
เมื่อกดปุ่มครั้งที่ 3 จะได้สัญญาณ x"FF0000 00FF00" (ดวงแรกสีเขียว ดวงหลังสีแดง)
เมื่อกดปุ่มครั้งที่ 4 จะได้สัญญาณ x"000000 FF0000" (ดวงแรกไม่สว่าง ดวงหลังสีเขียว)
เมื่อกดปุ่มครั้งที่ 5 (กลับมาที่กดปุ่มครั้งแรก)
จะได้สัญญาณ x"0000FF 000000" (ดวงแรกสีน้ำเงิน ดวงหลังไม่สว่าง)
เมื่อกดปุ่ม Reset จะได้สัญญาณ x"000000 000000" (ดวงแรกไม่สว่าง ดวงหลังไม่สว่าง)
ผลการทดลองเมื่อนำไปต่อวงจรจริง
ภาพรวมของวงจร โดยใช้ WS2812 RGB LED 2 ดวง
ภาพรวมของวงจร โดยใช้ WS2812 RGB LED 2 ดวง
วีดีโอ ผลการทดลอง
เมื่อกดปุ่มจะแสดงสี(4 แบบ) ตามลำดับคือ สีน้ำเงิน , สีแดง , สีเขียว , ไม่สว่าง
ทดลองเปลี่ยนสีเมื่อกดปุ่มโดยจะเพิ่มสีที่แสดงเข้าไปและแก้ไขค่าสี
ทดลองเปลี่ยนสีเมื่อกดปุ่มโดยแก้ไขค่าสี