สารบัญ:

เกม Mastermind ใน VHDL: 3 ขั้นตอน
เกม Mastermind ใน VHDL: 3 ขั้นตอน

วีดีโอ: เกม Mastermind ใน VHDL: 3 ขั้นตอน

วีดีโอ: เกม Mastermind ใน VHDL: 3 ขั้นตอน
วีดีโอ: The Mastermind เล่นใส่เปิร์คที่คนใช้เยอะที่สุดในโลก | Dead By Daylight 2024, กรกฎาคม
Anonim
เกมบงการใน VHDL
เกมบงการใน VHDL
เกมบงการใน VHDL
เกมบงการใน VHDL

สำหรับโครงการของเรา เราได้สร้างเกม “Mastermind” ใน VHDL เพื่อเล่นบนกระดาน Basys3 Mastermind เป็นเกมถอดรหัสที่เล่นโดยใช้หมุดและกระดานเกม ผู้เล่นคนหนึ่งวางหมุดหลากสีในแถวที่ 4 ซ่อนจากผู้เล่นที่สอง จากนั้นผู้เล่นคนที่สองมีจำนวนการเดา 'x' โดยการวางหมุดบนกระดานในแถวที่ผู้เล่นคนหนึ่งมองเห็นได้ หลังจากการเดาแต่ละครั้ง ผู้เล่นสองคนจะได้รับแจ้งตัวเลข 2 ตัว: หมุดมีสีที่ถูกต้องจำนวนเท่าใด และหมุดอยู่ในตำแหน่งที่ถูกต้องในแถวจำนวนเท่าใด การใช้เบาะแสเหล่านี้ ผู้เล่นสองคนต้องเดาลำดับพินที่ถูกต้องของผู้เล่นคนใดคนหนึ่งที่อยู่ในจำนวนการเดาที่จัดสรรไว้

ในการใช้งานของเรา เกมนี้เป็นผู้เล่นคนเดียว โปรแกรมสร้างหมุดรวมกันแบบสุ่ม และผู้เล่นต้องใช้กระดาน Basys3 เพื่อเดาลำดับที่ถูกต้อง มี “สี” สี่สี แทนด้วยค่าเลขฐานสอง จอแสดงผล 7 ส่วนจะแสดงค่าสามค่า: รอบที่เหลือ จำนวนหมุดในตำแหน่งที่ถูกต้อง และจำนวนหมุดที่เป็นสีที่ถูกต้องในตำแหน่งที่ไม่ถูกต้อง (ค่าเหล่านี้เริ่มต้นที่ 9, 0 และ 0) ผู้เล่นใช้สวิตช์บนกระดานเพื่อเลือกค่าเลขฐานสองสำหรับการเดาของเขา/เธอ และพลิกสวิตช์อื่นเพื่อส่งการเดา หากถูกต้อง เกมจะจบลงและหน้าจอ 7 ส่วนจะแสดง "GG" หากไม่เป็นเช่นนั้น ตัวนับเทิร์นจะลดลง 1 และผู้เล่นจะได้รับคำติชมตามจำนวนหมุดในการเดาที่ตรงกับสีหรือตำแหน่งของหมุดในชุดค่าผสม หากผู้เล่นหมดรอบโดยไม่ได้เดาอย่างถูกต้อง หน้าจอจะแสดง "GO" (หมายถึงจบเกม) ผู้เล่นยังสามารถพลิกสวิตช์รีเซ็ตเพื่อเริ่มใหม่ได้ตลอดเวลา

ขั้นตอนที่ 1: วัสดุ

วัสดุ
วัสดุ
วัสดุ
วัสดุ
วัสดุ
วัสดุ

เนื่องจากทั้งเกมสามารถเล่นบนกระดานได้เอง วัสดุเพียงอย่างเดียวที่จำเป็นคือ บอร์ด Basy3, สายไมโคร USB เพื่อเชื่อมต่อกับบอร์ด และคอมพิวเตอร์/แล็ปท็อปที่คุณสามารถใช้ในการเขียนโค้ดได้!

ขั้นตอนที่ 2: รหัส

รหัส
รหัส
รหัส
รหัส

เพื่อให้เกมนี้ทำงานบน FPGA วิธีที่ง่ายที่สุดในการเขียนก็คือการสร้างเครื่องของรัฐ การมีเครื่องสถานะช่วยให้ประสบการณ์แบบต่อเนื่องและแบบโต้ตอบที่จำเป็นสำหรับเกมทำงานได้จริง เพื่อให้ทุกอย่างทำงานได้อย่างราบรื่น เครื่องสถานะจะยึดตามสัญญาณนาฬิกาภายในของ FPGA เพื่อให้แน่ใจว่าทุกอย่างซิงค์กัน โมดูลหลักเป็นเครื่องของรัฐที่มีสี่สถานะ สถานะเริ่มต้น (เริ่มต้น) สถานะ SubmitAnswer (SubAns) สถานะการแสดงผล (Dis) และสถานะ CheckEndGame (CheckEnd) นอกเหนือจากเครื่องของรัฐแล้ว โมดูลหลักยังมีโมดูลย่อยสองโมดูล ได้แก่ จอแสดงผลเซเว่นเซกเมนต์ 4 หลัก (ซึ่งมีโมดูลย่อย ClkDivider ของตัวเอง) และตัวสร้างตัวเลขสุ่ม (จริง ๆ แล้วเป็นเครื่องกำเนิดตัวเลขสุ่มเทียม) นอกจากนี้ยังมีบล็อกกระบวนการพื้นฐานเพื่อให้ไฟ LED ที่ด้านบนแต่ละสวิตช์เปิดขึ้นเมื่อเปิดเครื่องเพื่อให้ผู้คนเห็นว่าพวกเขากำลังป้อนข้อมูลอะไรได้ง่ายขึ้น ภาพรวมพื้นฐานของรหัสสามารถดูได้ในแผนที่ความคิด

องค์ประกอบแรกที่ควรพิจารณาคือ Random Number Generator (randomgen) เนื่องจากเป็นไปไม่ได้ในทางเทคนิคที่จะได้รับตัวเลขสุ่มที่แท้จริงจากฮาร์ดแวร์ วิธีแก้ปัญหาที่ง่ายที่สุดคือการมี randomgen จริง ๆ แล้วเป็น Linear-feedback Shift Register (LFSR) LFSR มีอินพุตของ clk และเอาต์พุต "a" (ตัวเลข 12 บิต) ทุกรอบสัญญาณนาฬิกา หมายเลข 12 บิตใหม่จะถูกสร้างขึ้นโดยเริ่มต้นที่ "0000000000001" ในที่สุดก็จะผ่านชุดค่าผสม 12 บิตของ 1 และ 0 ทั้งหมดก่อนที่จะทำซ้ำ เอาต์พุต "a" จะได้รับทุกรอบสัญญาณนาฬิกา ดังนั้นจึงทำงานอย่างต่อเนื่องตลอด clk ถูกจับคู่กับ Clk จากโมดูลหลัก และ “a” ถูกแมปกับสัญญาณ RandNum ในโมดูลหลัก

โมดูลย่อยที่สองคือจอแสดงผล Seven Segment 4 หลัก นี่เป็นวิธีการแสดง Seven Segment Display 4 หลักที่ค่อนข้างตรงไปตรงมา จอแสดงผลถูกตั้งค่าบน Clk จากโมดูลหลัก แต่โมดูลย่อยนี้มีโมดูลย่อยของ ClkDivider ClkDivider (ตั้งค่าเป็น 1298 Hz) ใช้เพื่อเร่งความเร็วนาฬิกาสำหรับ Seven Segment เพื่อให้ตัวเลขทั้งหมดปรากฏพร้อมกัน (เนื่องจากสามารถเปิดได้ครั้งละหนึ่งหลักเท่านั้น) ตัวแปร “หลัก” ใช้เพื่อวนผ่านจุดต่างๆ บนจอแสดงผล และด้วยตัวเลขแต่ละหลักจะเป็นเงื่อนไขของการแสดงผลอินพุต 4 บิตพื้นฐาน พร้อมตัวเลือกในการแสดงตัวเลข 0 ถึง 9 และไม่มีอะไรเลย ตัวเลขทางซ้ายสุดบนจอแสดงผลถูกตั้งค่าเป็นไม่มีอะไรเนื่องจากไม่ได้ใช้ในเกมนี้

โมดูลหลักประกอบด้วยเครื่องสถานะ สี่สถานะในกระบวนการ ได้แก่ Initial, SubAns, Dis และ CheckEnd เมื่ออยู่ในสถานะเริ่มต้น หาก SubmitBtn (สวิตช์ที่ใช้ส่งคำตอบเพื่อตรวจสอบ) ถูกตั้งค่าเป็น '1' เครื่องจะย้ายไปยังสถานะ SubAns ทุกเวลา Rbtn (สวิตช์ที่ใช้รีเซ็ตเครื่อง) ถูกตั้งค่าเป็น '1' จากนั้นเครื่องจะกลับสู่สถานะเริ่มต้น เมื่ออยู่ในสถานะ SubAns เมื่อ SubmitBtn = '0' อีกครั้ง มันจะย้ายไปยังสถานะ Dis เมื่ออยู่ในสถานะ Dis หากการนับถอยหลัง = 0 (เลี้ยวซ้ายเพื่อเดาตกไปที่ 0) หรือหาก RSpotCount = 4 (หมายถึงผู้เล่นเป็นสีที่ถูกต้องทั้งหมดในจุดที่ถูกต้อง) เครื่องจะเข้าสู่สถานะ CheckEnd หากไม่มีสิ่งเหล่านี้เกิดขึ้น เมื่อ SubmitBtn = '1' อีกครั้ง มันจะกลับไปที่สถานะ SubAns เพื่ออนุญาตให้เดาอีกครั้ง เมื่ออยู่ในสถานะ CheckEnd นี่คือจุดสิ้นสุดของเกม และทางเดียวที่จะออกจากเกมได้คือการกดปุ่มรีเซ็ต กลับสู่สถานะเริ่มต้น สามารถดูได้ง่ายในไดอะแกรมเครื่องสถานะ สถานะเริ่มต้นจะเริ่มต้นทุกอย่างกลับสู่ตำแหน่งเริ่มต้นตามพฤติกรรม การนับถอยหลัง (สัญญาณที่บันทึกจำนวนเทิร์นที่เหลือของผู้เล่น) ถูกตั้งค่าเป็น 9 RSpotCount (สัญญาณที่บันทึกจำนวนสีที่คุณเดาอยู่ในจุดที่ถูกต้อง) ถูกตั้งค่าเป็น 0, RColorCount (สัญญาณที่บันทึกจำนวนสี สีที่คุณเดาถูก แต่อยู่ในจุดที่ไม่ถูกต้อง) ถูกตั้งค่าเป็น 0 และ smallcountdown (สัญญาณที่แมปสุดท้ายกับ Countdown ซึ่งจะเปลี่ยนแต่ละเทิร์นในรัฐภายหลัง) ถูกตั้งค่าเป็น 9 นอกจากนี้ ในสถานะเริ่มต้น RandNum (ตัวเลขที่สร้างขึ้นโดยสุ่มเทียม) ถูกแบ่งออกเป็นสี่การตรวจสอบที่แตกต่างกัน (หนึ่งรายการสำหรับทุกๆ 3 บิตสี) และบันทึกลงในสัญญาณ check1, check2, check3, check4 การตรวจสอบเหล่านี้เป็นสิ่งที่เปรียบเทียบกับการเดาของคุณจริงๆ ดังนั้นแม้ว่า LFSR จะทำให้ RandNum เปลี่ยนแปลงทุกรอบเสมอ เมื่อคุณออกจากสถานะเริ่มต้น การตรวจสอบจะยังเหมือนเดิม ทำให้ค่าที่บันทึกไว้สามารถเปรียบเทียบคำตอบของคุณได้ นอกจากนี้ยังหมายถึงทุกครั้งที่มีการรีเซ็ตเครื่อง ผู้เล่นจะมีค่าใหม่ให้เดา

สถานะ SubmitAnswer (SubAns) เปลี่ยนตัวเปิดใช้งานการนับถอยหลัง (สัญญาณ "เปลี่ยน") เป็น '1' สิ่งนี้จำเป็นในภายหลังเพื่อให้การติดตามผลเลี้ยวทำงาน หลังจากนั้น สถานะจะเปรียบเทียบอินพุตของเครื่องเล่นจากสวิตช์กับการตรวจสอบที่ทำในสถานะข้างต้น สัญญาณ rs1, rs2, rs3, rs4 และสัญญาณ rc1, rc2, rc3, rc4 เป็นประเภทจำนวนเต็มซึ่งขึ้นอยู่กับคำสั่ง If ที่ถูกตั้งค่าเป็น 1 หรือ 0 สัญญาณ rs มีไว้สำหรับจุดที่ถูกต้องและ rc สำหรับสีที่ถูกต้อง ตัวอย่างเช่น หากผู้เล่น 1 สีเดาเท่ากับ check1 ของ RandNum ดังนั้น rs1 = 1 เนื่องจากนั่นหมายถึงสีที่ถูกต้องอยู่ในจุดที่ถูกต้อง หากสี 1 ไม่เท่ากับการตรวจสอบ 1 แต่เท่ากับการตรวจสอบอื่น ๆ ดังนั้น rc = 1 จะทำสำหรับแต่ละสีและการตรวจสอบแต่ละครั้ง

สถานะการแสดงผล (Dis) จะค้นหาตัวเปิดใช้งานการนับถอยหลังก่อน หากเป็น '1' การนับถอยหลังขนาดเล็กจะลดลง 1 (ดังนั้นในเทิร์นแรกจะเปลี่ยนจาก 9 เป็น 8 เป็นต้น) มิฉะนั้นการเลี้ยวจะไม่เปลี่ยนแปลง ไม่ว่าจะเปิดใช้งานใน ค่า rs ทั้งหมดจากด้านบนจะถูกเพิ่มและกำหนดให้กับสัญญาณ RSpotCounter นอกจากนี้ ค่า rc ทั้งหมดจะถูกเพิ่มและกำหนดให้กับ RColorCounter ในที่สุด Countdown จะได้รับการกำหนดค่าของ smallcountdown สัญญาณ RSpotCounter, RColorCounter และ Countdown ทั้งหมดจะถูกแปลงเป็น std_logic_vector 4 บิตนอกกระบวนการ และผลักไปที่โมดูลย่อยการแสดงผล Seven Segment ผ่านแผนที่พอร์ต ด้วยวิธีนี้ จอแสดงผลจะแสดงสิ่งที่ถูกต้องจนกว่าคุณจะส่งคำตอบใหม่

สถานะ CheckEnd มีไว้สำหรับว่าคุณชนะหรือแพ้ หากคุณชนะ (ทั้ง 4 สีอยู่ในตำแหน่งที่ถูกต้อง หรือที่เรียกว่า RSpotCounter = 4) จากนั้น “GG” (แสดงทางเทคนิคเป็น 66) จะแสดงบนเซเว่นเซกเมนต์เพื่อแสดงว่าคุณชนะ หากคุณแพ้ (นับถอยหลังถึง 0) แล้ว “GO” (แสดงทางเทคนิคเป็น 60) จะปรากฏขึ้นบนจอแสดงผลสำหรับเกมโอเวอร์ ด้วยผลลัพธ์อย่างใดอย่างหนึ่ง การกดปุ่มรีเซ็ตเป็นเปิดจะทำให้เครื่องกลับสู่สถานะเริ่มต้นเพื่อเล่นอีกครั้ง

รหัสที่มาสามารถพบได้ที่นี่

ขั้นตอนที่ 3: บทสรุป

การทำโปรเจ็กต์นี้ให้สำเร็จสอนเรามากมายเกี่ยวกับการสร้างวงจรที่ซับซ้อนยิ่งขึ้น การออกแบบเริ่มต้นของเราไม่ใช่เครื่องจักรที่มีขอบเขตจำกัด เราพบว่ายากต่อการดีบัก และเขียนโค้ดใหม่หลายครั้งโดยใช้วิธีการต่างๆ (รวมถึง FSM) ตามคำแนะนำของผู้สอน เรายึดติดกับแนวทาง FSM และเราก็สามารถจบเกมได้ เราได้เรียนรู้ว่าการออกแบบโค้ดตามฮาร์ดแวร์มีประสิทธิภาพมากกว่าวิธีการเขียนโปรแกรมแบบเดิม เรายังเผชิญกับความท้าทายหลายประการที่เกี่ยวข้องกับการแสดงผลทั้งเจ็ดส่วน การแสดงตัวเลขหลายตัวโดยไม่มี "ภาพซ้อน" เป็นเรื่องยาก และเราต้องใช้ตัวแบ่งนาฬิกาเพื่อทำสิ่งนี้ให้สำเร็จ หากเราต้องพัฒนาโครงการนี้ต่อไป เราจะเชื่อมต่อ LED สีกับ Basy3 เพื่อให้ผู้ใช้เห็นสี (เช่นในเกมทั่วไป) มากกว่าการแสดงสีที่เป็นตัวเลข ในที่สุด เราก็มีความเข้าใจมากขึ้นเกี่ยวกับการออกแบบวงจรที่ซับซ้อน การใช้งานในชีวิตจริง และความท้าทายในการใช้ฮาร์ดแวร์มากกว่าการจำลองสถานการณ์ด้วยสภาวะที่สมบูรณ์แบบ

แนะนำ: