Mục lục:

Trò chơi Mastermind trong VHDL: 3 bước
Trò chơi Mastermind trong VHDL: 3 bước

Video: Trò chơi Mastermind trong VHDL: 3 bước

Video: Trò chơi Mastermind trong VHDL: 3 bước
Video: How to Multiplex Seven Segment Displays on a Z80 2024, Tháng mười một
Anonim
Trò chơi Mastermind trong VHDL
Trò chơi Mastermind trong VHDL
Trò chơi Mastermind trong VHDL
Trò chơi Mastermind trong VHDL

Đối với dự án của chúng tôi, chúng tôi đã tạo trò chơi “Mastermind” trong VHDL để chơi trên bảng Basys3. Mastermind là một trò chơi phá mã theo truyền thống được chơi với các chốt và một bảng trò chơi. Người chơi một đặt các chốt của các loại màu vào hàng 4, ẩn khỏi người chơi hai. Sau đó, người chơi hai có số lần đoán là ‘x’ đặt các chốt trên bàn cờ trong một hàng hiển thị cho người chơi một. Sau mỗi lần đoán, người chơi hai được thông báo về 2 con số: có bao nhiêu chiếc chốt đúng màu và bao nhiêu chiếc chốt ở đúng vị trí trong hàng. Sử dụng các manh mối đó, người chơi hai phải đoán đúng chuỗi các chốt mà người chơi một đã đặt trong số đoán được phân bổ.

Trong cách triển khai của chúng tôi, trò chơi là người chơi đơn. Một sự kết hợp ngẫu nhiên của các chốt được tạo ra bởi chương trình và người chơi phải sử dụng bảng Basys3 để đoán chuỗi chính xác. Có bốn "màu", được biểu thị bằng các giá trị nhị phân. Màn hình 7 đoạn hiển thị ba giá trị: số lượt còn lại, số chân cắm ở vị trí chính xác và số chân cắm có màu chính xác ở vị trí sai (các giá trị này bắt đầu từ 9, 0 và 0). Người chơi sử dụng các công tắc trên bảng để chọn các giá trị nhị phân cho dự đoán của mình và lật một công tắc khác để gửi dự đoán. Nếu đúng, trò chơi kết thúc và màn hình 7 đoạn hiển thị “GG”. Nếu không, bộ đếm lượt giảm đi 1 và người chơi nhận được phản hồi dựa trên số lượng chân trong dự đoán của họ phù hợp với màu sắc hoặc vị trí của các chân trong tổ hợp. Nếu người chơi hết lượt mà không đoán đúng, màn hình hiển thị “ĐI” (thể hiện trò chơi kết thúc). Người chơi cũng có thể lật công tắc đặt lại để bắt đầu lại bất kỳ lúc nào.

Bước 1: Vật liệu

Vật liệu
Vật liệu
Vật liệu
Vật liệu
Vật liệu
Vật liệu

Vì toàn bộ trò chơi có thể được chơi trên chính bảng, vật liệu duy nhất cần có là Bảng Basys3, cáp micro USB để kết nối với bảng và một máy tính / máy tính xách tay mà bạn có thể sử dụng để viết mã!

Bước 2: Mã

Mật mã
Mật mã
Mật mã
Mật mã

Để trò chơi này hoạt động trên FPGA, cách đơn giản nhất để viết nó là tạo một máy trạng thái. Có một máy trạng thái cho phép trải nghiệm tuần tự và tương tác cần thiết để trò chơi thực sự hoạt động. Để mọi thứ chạy trơn tru, máy trạng thái sẽ dựa trên tín hiệu đồng hồ bên trong của FPGA, đảm bảo mọi thứ được đồng bộ hóa. Mô-đun chính là một máy trạng thái có bốn trạng thái; Trạng thái ban đầu (Initial), Trạng thái gửi trả lời (SubAns), Trạng thái hiển thị (Dis) và Trạng thái trò chơi kiểm tra (CheckEnd). Cùng với máy trạng thái, mô-đun chính có hai mô-đun con, Màn hình hiển thị bảy phân đoạn 4 chữ số (có mô-đun con ClkDivider của riêng nó) và Bộ tạo số ngẫu nhiên (thực sự là một bộ tạo số ngẫu nhiên psuedo). Ngoài ra còn có một khối quy trình cơ bản để bật đèn LED phía trên mỗi công tắc khi được bật như một cách để mọi người xem những gì họ đang nhập dễ dàng hơn. Tổng quan cơ bản về mã có thể được nhìn thấy trong bản đồ tư duy trong hình.

Thành phần đầu tiên cần xem xét là Bộ tạo số ngẫu nhiên (randomgen). Vì về mặt kỹ thuật không thể lấy các số ngẫu nhiên thực sự được tạo ra từ phần cứng, giải pháp đơn giản nhất là tạo ngẫu nhiên thực sự là một Thanh ghi dịch chuyển phản hồi tuyến tính (LFSR). LFSR có đầu vào là clk và đầu ra là “a” (số 12 bit). Mỗi chu kỳ đồng hồ, một số 12 bit mới được tạo bắt đầu từ “000000000001”, cuối cùng trải qua tất cả các kết hợp 12 bit của 1 và 0 trước khi tự lặp lại. Đầu ra “a” được đưa ra mỗi chu kỳ đồng hồ, vì vậy nó liên tục chạy trong suốt. Clk được ánh xạ tới Clk từ mô-đun chính và “a” được ánh xạ tới tín hiệu RandNum trong mô-đun chính.

Mô-đun con thứ hai là Hiển thị 7 phân đoạn 4 chữ số. Đây là một cách khá đơn giản để hiển thị Màn hình 7 phân đoạn 4 chữ số. Màn hình được đặt trên Clk từ mô-đun chính, nhưng mô-đun con này có mô-đun con riêng của một ClkDivider. ClkDivider (được đặt thành 1298 Hz) được sử dụng để tăng tốc đồng hồ cho Seven Segment để tất cả các chữ số xuất hiện cùng một lúc (vì chỉ có một chữ số thực sự có thể được bật tại một thời điểm). Biến "chữ số" được sử dụng để chuyển qua các điểm trên màn hình và với mỗi chữ số đi kèm các điều kiện của màn hình đầu vào 4 bit cơ bản, với các tùy chọn để hiển thị các chữ số từ 0 đến 9 và cũng không có gì. Chữ số xa nhất bên trái trên màn hình được đặt thành không vì nó không được sử dụng trong trò chơi này.

Mô-đun chính bao gồm máy trạng thái. Bốn trạng thái trong quy trình là Initial, SubAns, Dis và CheckEnd. Khi ở trạng thái ban đầu, nếu SubmitBtn (công tắc được sử dụng để gửi câu trả lời của bạn để kiểm tra) được đặt thành ‘1’, thì máy sẽ chuyển sang Trạng thái SubAns. Bất cứ lúc nào Rbtn (công tắc được sử dụng để đặt lại máy) được đặt thành ‘1’, sau đó máy trở về trạng thái Ban đầu. Khi ở trạng thái SubAns, khi SubmitBtn = ‘0’ một lần nữa, nó chuyển sang trạng thái Dis. Khi ở trạng thái Dis, nếu Countdown = 0 (Lượt sang trái để đoán rơi xuống 0) hoặc nếu RSpotCount = 4 (nghĩa là người chơi đặt tất cả các màu chính xác vào đúng vị trí), máy sẽ chuyển sang Trạng thái CheckEnd. Nếu cả hai điều đó đều không xảy ra, thì khi SubmitBtn = ‘1’ một lần nữa, nó sẽ trở lại trạng thái SubAns để cho phép một phỏng đoán khác. Khi ở trạng thái CheckEnd, đây là kết thúc của trò chơi và cách duy nhất để thoát ra là nhấn thiết lập lại, đưa nó về Trạng thái ban đầu. Điều này có thể dễ dàng xem trong sơ đồ máy trạng thái. Về mặt hành vi, Trạng thái ban đầu khởi tạo mọi thứ trở lại vị trí ban đầu. Đếm ngược (tín hiệu lưu số lượt người chơi còn lại) được đặt thành 9, RSpotCount (tín hiệu lưu bao nhiêu màu bạn đoán ở đúng vị trí) được đặt thành 0, RColorCount (tín hiệu lưu bao nhiêu màu các màu bạn đoán là đúng nhưng sai vị trí) được đặt thành 0 và số đếm ngược nhỏ (tín hiệu cuối cùng được ánh xạ tới Đếm ngược thực sự thay đổi mỗi lượt ở các trạng thái sau) được đặt thành 9. Ngoài ra, ở Trạng thái ban đầu, RandNum (psuedo-số được tạo ngẫu nhiên) được chia thành bốn lần kiểm tra khác nhau (một lần cho mỗi màu 3 bit) và được lưu vào các tín hiệu check1, check2, check3, check4. Những kiểm tra này là những gì bạn phỏng đoán thực sự được so sánh với, vì vậy mặc dù LFSR luôn khiến RandNum thay đổi mỗi chu kỳ, khi bạn rời khỏi trạng thái Ban đầu, các kiểm tra vẫn giữ nguyên, cho phép một giá trị đã lưu để so sánh câu trả lời của bạn với. Điều này cũng có nghĩa là bất cứ khi nào máy được đặt lại, người chơi sẽ có một giá trị mới để đoán.

Trạng thái SubmitAnswer (SubAns) thay đổi trình kích hoạt đếm ngược (tín hiệu “thay đổi”) thành ‘1’. Điều này là cần thiết sau này để theo dõi rẽ hoạt động. Sau đó, trạng thái sẽ so sánh các đầu vào của người chơi từ các công tắc với các kiểm tra được thực hiện ở trạng thái trên. Tín hiệu rs1, rs2, rs3, rs4 và tín hiệu rc1, rc2, rc3, rc4 là kiểu số nguyên tùy thuộc vào câu lệnh If được đặt thành 1 hoặc 0. Tín hiệu rs dành cho đúng vị trí và rc cho đúng màu. Ví dụ: nếu người chơi đoán màu 1 bằng séc 1 của RandNum, thì rs1 = 1 vì điều đó có nghĩa là màu phù hợp ở đúng vị trí. Nếu màu 1 không bằng séc 1, nhưng lại bằng một trong các séc kia, thì rc = 1. Việc này được thực hiện cho từng màu và từng séc.

Trạng thái hiển thị (Dis) trước tiên sẽ tìm kiếm bộ kích hoạt đếm ngược. Nếu nó là ‘1’, thì smallcountdown giảm xuống 1 (vì vậy ở lượt đầu tiên, nó sẽ tăng từ 9 xuống 8, v.v.). Nếu không, lượt đi không thay đổi. Bất kể kích hoạt đó ở đâu, tất cả các giá trị rs từ trên đều được cộng lại và được gán để báo hiệu RSpotCounter. Ngoài ra, tất cả các giá trị rc được thêm vào và gán cho RColorCounter. Cuối cùng Countdown được gán giá trị của smallcountdown. Các tín hiệu RSpotCounter, RColorCounter và Countdown đều được chuyển đổi thành 4-bit std_logic_vectors bên ngoài quy trình và được đẩy sang mô-đun con hiển thị Bảy Phân đoạn thông qua bản đồ cổng. Bằng cách này, màn hình hiển thị những điều phù hợp cho đến khi bạn gửi câu trả lời mới.

Trạng thái CheckEnd dành cho việc bạn thắng hay thua. Nếu bạn đã thắng (tất cả 4 màu đều ở đúng vị trí, hay còn gọi là RSpotCounter = 4), thì “GG” (được hiển thị về mặt kỹ thuật là 66) sẽ hiển thị trên Seven Segment để cho biết bạn đã thắng. Nếu bạn đã thua (Đếm ngược về 0) thì “ĐI” (về mặt kỹ thuật là 60) được hiển thị trên màn hình cho Game Over. Với một trong hai kết quả, việc bật công tắc đặt lại sẽ đưa máy trở lại Trạng thái ban đầu để chơi lại.

Mã nguồn có thể được tìm thấy ở đây.

Bước 3: Kết luận

Hoàn thành dự án này đã dạy chúng tôi rất nhiều về việc xây dựng các mạch phức tạp hơn. Thiết kế ban đầu của chúng tôi không phải là một cỗ máy trạng thái hữu hạn. Chúng tôi thấy khó gỡ lỗi và viết lại mã nhiều lần bằng các phương pháp khác nhau (bao gồm cả FSM). Theo gợi ý của người hướng dẫn, chúng tôi đã mắc kẹt với phương pháp FSM và chúng tôi đã có thể hoàn thành trò chơi. Chúng tôi nhận ra rằng thiết kế mã dựa trên phần cứng sẽ hiệu quả hơn nhiều so với cách tiếp cận lập trình truyền thống. Chúng tôi cũng phải đối mặt với một số thách thức liên quan đến hiển thị bảy phân đoạn. Rất khó để nó hiển thị nhiều số mà không bị “bóng mờ” và chúng tôi phải sử dụng bộ chia đồng hồ để thực hiện điều này. Nếu chúng tôi phát triển thêm dự án này, chúng tôi sẽ kết nối các đèn LED màu với Basys3 để người dùng có thể nhìn thấy màu sắc (giống như trong trò chơi truyền thống) chứ không phải là các biểu diễn số của màu sắc. Cuối cùng, chúng tôi đã hiểu rõ hơn về thiết kế mạch phức tạp, các ứng dụng trong cuộc sống thực và những thách thức của việc sử dụng phần cứng hơn là chạy mô phỏng với các điều kiện hoàn hảo.

Đề xuất: