ΗΥ220 Εργαστήριο Ψηφιακών Κυκλωµάτων Τµήµα Επιστήµης Υπολογιστών Χειµερινό Εξάµηνο 2007-2008 Εκφώνηση Εργαστηρίου Στο εργαστήριο του µαθήµατος σας ζητείται να σχεδιάσετε, να υλοποιήσετε και να επαληθεύσετε στην πλακέτα του εργαστηρίου ένα απλό παιχνίδι µε τη χρήση της γλώσσας Verilog. Το συνολικό παιχνίδι θα υλοποιηθεί σε 3 φάσεις που θα παραδίδονται σε κάθε ένα από τα 3 εργαστήρια της κάθε οµάδας κατά τη διάρκεια του εξαµήνου. Το παιχνίδι που θα υλοποιήσετε λέγεται «Μάντεψε τον Αριθµό» και θα χρησιµοποιεί τις 4 οθόνες seven segment, τα 4 leds και τα 4 push-buttons που διαθέτει η πλακέτα του µαθήµατος. Στο απλό αυτο παιχνίδι, το σύστηµα θα γεννάει έναν τυχαίο κρυφό αριθµό µε βάση κάποια εσωτερική γεννήτρια και ο παίκτης θα προσπαθεί να βρεί τον αριθµό σχηµατίζοντας ένα προς ένα τα ψηφία ( στο δεκαεξαδικό, χρησιµοποιώντας buttons για up και down και next) και τα οποία θα φαίνονται στις οθόνες seven segment. Όταν σχηµατιστούν όλα τα ψηφία, το σύστηµα θα ενηµερώνει τον παίκτη µεσω των leds εάν ο αριθµός που δοκίµασε είναι µικρότερος, µεγαλύτερος ή ίσος σε σχέση µε τον κρυφό αριθµό. Μετά ο παίκτης θα ξαναπροσπαθεί έως έναν µέγιστο αριθµό προσπαθειών. Αν ο παίκτης βρεί τον αριθµό πρίν τελειώσουν οι προσπαθειές του τότε έχει κερδίσει! Περισσότερες λεπτοµέρειες για την πλήρη λειτουργικότητα του παιχνιδιού θα υπάρχουν στην εκφώνηση κάθε µιας από τις φάσεις του παιχνιδιού που θα υλοποιήσετε.
Εργαστήριο 3 (Φάση 3) Εβδ. 10/12 έως 14/12 Group A. Εβδ. 17/12 έως 21/12 Group B Στο εργαστήριο 3 θα υλοποιήσετε το τελευταίο κοµµάτι που ελέγχει την ροή του παιχνιδιού. Θα πρέπει να φτιάξετε µια κεντρική FSM όπως περιγράφεται λεπτοµερώς παρακάτω και το παιχνίδι θα παίζεται ώς εξής: αρχικά πρέπει να γεννηθεί εσωτερικά ένας µυστικός αριθµός, µετά ο παίκτης θα σχηµατίζει τον αριθµό, κάθε ψηφίο ξεχωριστα, µε τα inc (inc - S1) και dec (dec - S2) ενώ µε το select (select - S3) επιλέγει το επόµενο ψηφίο. Όταν τελειώσει µε τα ψηφία του αριθµού, πατώντας το select, το παιχνίδι θα ελέγχει αν ο αριθµός που έδωσε ο παίκτης είναι µεγαλύτερος, µικρότερος ή ίσος µε µυστικό αριθµό και θα µας ενηµερώνει στις οθόνες. Η διαδικασία αυτή επαναλαµβάνεται µέχρι να βρεί ο παίκτης τον αριθµό ή να τελειώσει ο µέγιστος αριθµός των προσπαθειών. Θα πρέπει να έρθετε στο εργαστήριο µε τον κώδικα προετοιµασµένο-έτοιµο, να διορθώσετε τυχόν λάθη και να δείξετε στον βοηθό του εργαστηρίου οτι δουλεύει σωστά. Το διάγραµµα των blocks για το εργαστήριο 3 είναι το παρακάτω: Το σχεδιό µας τώρα (Lab3_Top) έχει την εξής ιεραρχία (παρόµοια µε το Lab2): Τα 3 instances από NumberGenerators που γεννάνε αριθµούς απο το 0 έως το 15 (από το Lab2). Το block RandomNumber το οποίο γεννάει έναν νέο ψευδοτυχαίο αριθµό των 12-bits µε βάση ένα σήµα go (από το Lab2). Το block ButtonDebounce που σας δίνεται έτοιµο µαζί µε την εκφώνηση και ουσιαστικά παράγει έναν παλµό κάθε φορά που πατιέται ένα από τα 3 κουµπιά (από το Lab2). SSController που δέχεται 4 αριθµούς των 4-bit από τον GameController και δηµιουργεί την κατάλληλη έξοδο για να απεικονιστούν στις οθόνες seven segment στο δεκαεξαδικό (από το Lab2).
Το block GameController το οποίο είναι ο «εγκέφαλος» του παιχνιδιού και πρέπει να το µετατρέψετε σύµφωνα µε τις προδιαγραφές που δίνονται παρακάτω.θα το υλοποιήσετε εσείς!!! 1. GameController: Ο GameController είναι ο «εγκέφαλος» του παιχνιδιού και ελέγχει τη ροή και τα βήµατα για το παιχνίδι. Θα πρέπει να χρησιµοποιήσετε το κέλυφος (ίδιες πόρτες) του GameController από το Lab2, να προσθέστε µια νέα πόρτα για leds (και στο Top block επίσης), να δηµιουργήσετε µια FSM και τη σχετιζόµενη λογική. Γενικές προδιαγραφές: Στις οθόνες 0,1,2 πάντα πρέπει να εµφανίζουµε τους αριθµούς από τους NumberGenerators εκτός αν µας ζητηθεί κάτι άλλο σε κάποια κατάσταση. Στην οθόνη 3 εµφανίζουµε πάντα την κατάσταση της FSM (την τιµή της εσωτερικής κωδικοποίησης καταστάσεων που έχετε κάνει εσεις διευκολύνει πολύ το debugging στην πλακέτα) εκτός αν ζητείται κάτι άλλο σε κάποια κατάσταση. Τα leds (active-low) είναι σβηστά εκτός έαν ζητείται διαφορετικά από κάποια κατάσταση. Υπάρχει ένας µετρητής που θυµάται τον εναποµείναντα αριθµό προσπαθειών που µπορεί να δοκιµάσει ο παίκτης. Αρχικοποιείται στον αριθµό 10 (κάντε το παραµετρικό). Η FSM θα πρέπει να υποστηρίζει τα εξής βήµατα: 1. Αρχικά (µετά το reset) πάµε στην κατάσταση idle στην οποία ενεργοποιούµε το σήµα go του RandomNumber και έτσι όσο είµαστε εκεί σε κάθε κύκλο γεννιέται ένα τυχαίος αριθµός (ο οποίος δεν φαίνεται στις οθόνες). Όταν πατηθεί το select, ξεκινάει ουσιαστικά το παιχνίδι και πάµε στην επόµενη κατάσταση (σε καµία άλλη κατάσταση δεν πρέπει να ενεργοποιείται το go, φεύγοντας από την κατάσταση idle ο RandomNumber σταµατάει να γεννάει αριθµούς και ο παίκτης πρέπει βρεί τον αριθµό που έχει γεννηθεί τελευταίος). Επίσης επαναφέρουµε τον αριθµό των προσπαθειών στην αρχική του τιµή. 2. Μετά την idle πάµε σε µια κατάσταση show_tries που µας δείχνει τον εναποµείναντα αριθµό προσπαθειών του παίκτη στην οθόνη 3. Όση ώρα είµαστε στην κατάσταση αυτή τα 4 leds (active-low) πρέπει να είναι όλα αναµένα. Με το select πάµε σε επόµενη κατάσταση. 3. Μετα την show_tries πάµε σε µια κατάσταση dig0 όπου θα σχηµατίσουµε το ψηφίο 0 του αριθµού που θέλουµε να δοκιµάσουµε. Κατά τη διάρκεια της κατάστασης τα σήµατα inc και dec προωθούνται στον NumberGenerator που είναι υπεύθυνος για το ψηφίο 0. Όση ώρα είµαστε στην κατάσταση αυτή το led0 (active-low) πρέπει να είναι αναµένο. Με τo select πάµε σε άλλη κατάσταση για να σχηµατίσουµε το ψηφίο 1. 4. Κατάσταση dig1 όπου θα σχηµατίσουµε το ψηφίο 1 του αριθµού που θέλουµε να δοκιµάσουµε. Κατά τη διάρκεια της κατάστασης τα σήµατα inc και dec προωθούνται στον NumberGenerator που είναι υπεύθυνος για το ψηφίο 1. Όση ώρα είµαστε στην κατάσταση αυτή το led1 (active-low) πρέπει να είναι αναµένο. Με τo select πάµε σε άλλη κατάσταση για να σχηµατίσουµε το ψηφίο 2. 5. Κατάσταση dig2 όπου θα σχηµατίσουµε το ψηφίο 2 του αριθµού που θέλουµε να δοκιµάσουµε. Κατά τη διάρκεια της κατάστασης τα σήµατα inc και dec προωθούνται στον NumberGenerator που είναι υπεύθυνος για το ψηφίο 2.
Όση ώρα είµαστε στην κατάσταση αυτή το led2 (active-low) πρέπει να είναι αναµένο. Με τo select πάµε σε άλλη κατάσταση για να µειώσουµε τον αριθµό των προσπαθειών και ελέγξουµε τον αριθµό που σχηµατίσαµε. 6. Κατάσταση decrease µειώνουµε τον αριθµό των προσπαθειών κατά 1 και πάµε στην κατάσταση check. 7. Κατάσταση check συγκρίνουµε τα 12-bits του RandomNumber µε τα 12-bits του αριθµού που σχηµατίσαµε και εµφανίζουµε στην οθόνη 3: την τιµη b (bigger) αν η τιµή που βάλαµε είναι µεγαλύτερη από αυτή του RandomNumber την τιµη 5 (το 5 µοιάζει µε S στην seven segment display - smaller)αν η τιµή που βάλαµε είναι µικρότερη από αυτή του RandomNumber την τιµη Ε (equal) αν η τιµή που βάλαµε είναι ίση µε αυτή του RandomNumber. Με το select πάµε σε άλλη κατάσταση, εάν έχουµε βρεί τον αριθµό ή έχει τελειώσει ο αριθµός των προσπαθειών τότε πάµε στην κατάταση show διαφορετικά µπορούµε να ξαναπροσπαθήσουµε νέο αριθµό πηγαίνοντας στην κατάσταση show_tries. Όση ώρα είµαστε στην κατάσταση αυτή το led3 (active-low) πρέπει να είναι αναµένο. 8. Κατάσταση show ουσιαστικά τελειώνει το παιχνίδι και εµφανίζει στις οθόνες 0,1,2 την τιµή του RandomNumber που προσπαθούσαµε να βρούµε. Με το select ξαναπάµε στην idle και µπορούµε να ξαναξεκινήσουµε το παιχνίδι. Hint: Είναι πιο εύκολο την συνδυαστική λογική για τις εξόδους να την γράφετε µε wires, εκτός του always block που έχει τις µετάβασεις των καταστάσεων. (π.χ. ιαφάνεια 18 FSM) 2. Lab3_Top : Είναι το top block για το εργαστήριο το οποίο έχει τα instances από όλα τα blocks. Θέλουµε ένα instance του SSController, 3 instances των NumberGenerators όπου όλοι ξεκινούν απο το 0, ένα instance του RandomNumber, ένα instance του ButtonDebounce και ένα instance του GameController. Αφού γράψετε τον κώδικα, να κάνετε προσοµοίωση σε Verilog στα εργαλεία που είδατε στο φροντιστήριο µε κάποιο testbench. Σηµείωση µόνο για την προσοµοίωση: Επειδή το block ButtonDebounce κάνει δειγµατολειψια κάθε αρκετές χιλιάδες κύκλους (δεν είναι βολικό για τα tests), µην το προσοµειώσετε µαζί. Μην δηµιουργήσετε instance και συνδέστε τις πόρτες των buttons του top block απευθείας στον GameController. Από το testbench γεννήστε απλά θετικούς παλµούς 1 κύκλου ανάλογα µε την συµπεριφορά που θέλετε να πετύχετε. Ένας προσοµοιωµένος κώδικας έχει πολύ περισσότερες πιθανότητες να δουλέψει σωστά στο εργαστήριο.
Στο εργαστήριο αφού φτιάξετε το project στο Quartus, διορθώσετε τυχόν λάθη και προγραµµατίσετε την FPGA πατήστε το button S4 που είναι το reset για να αρχίσει να δουλεύει σωστά το κύκλωµα. Θα πρέπει να µπορείτε να παίξετε το παιχνίδι δοκιµάζοντας αριθµούς µε το inc, dec και select, να βλέπετε αν ο αριθµός που επιλέξατε είναι µικρότερος, µεγαλύτερος ή ίσος από τον κρυφό αριθµό και επίσης να βλέπετε τις προσπάθειες που σας αποµένουν. Εφαρµόστε δυαδική αναζήτηση για να έχετε µεγαλύτερη πιθανότητα εύρεσης του αριθµού. Παρατηρείστε ότι χρειάζεστε log2(4096) = 12 προσπάθειες για να βρείτε σίγουρα τον αριθµό ενώ το παιχνίδι σας δίνει µόνο 10. Χρειάζεστε και λίγη τύχη Μπορείτε να κάνετε πιο εύκολο ή πιο δύσκολο το παιχνίδι αλλάζοντας τον αριθµό των προσπαθειών, σε ένα παραµετρικό design γίνεται πολύ εύκολα. ΟΙ ΑΝΤΙΓΡΑΦΕΣ ΚΩ ΙΚΑ ΘΑ ΤΙΜΩΡΟΥΝΤΑΙ ΜΕ ΜΗ ΕΝΙΣΜΟ ΤΩΝ ΟΜΑ ΩΝ ΠΟΥ ΕΧΟΥΝ ΤΟΝ Ι ΙΟ ΚΩ ΙΚΑ ΑΝΕΞΑΡΤΗΤΩΣ ΑΠΟ ΤΟ ΣΕ ΠΟΙΑ ΟΜΑ Α ΑΝΗΚΕΙ Ο ΚΩ ΙΚΑΣ ΚΑΙ ΠΟΙΑ ΕΚΑΝΕ ΧΡΟΝΙΚΑ ΠΡΩΤΗ ΤΟ ΕΡΓΑΣΤΗΡΙΟ!!! ΕΙΝΑΙ ΥΠΟΧΡΕΩΣΗ ΣΑΣ ΝΑ ΜΗΝ ΙΑΝΕΜΕΤΕ ΤΟΝ ΚΩ ΙΚΑ!!!
Pin Assignments Pin Name Input / Output Active (High / Low) Pin Number Clock (18MHz) I - 43 Reset_n (Button 4 - S4) I L 64 Segment A O L 67 Segment B O L 70 Segment C O L 69 Segment D O L 66 Segment E O L 73 Segment F O L 65 Segment G O L 72 Segment Dot O L 71 Segment1 Enable (DIG1) O H 5 Segment2 Enable (DIG2) O H 83 Segment3 Enable (DIG3) O H 79 Segment4 Enable (DIG4) O H 80 Led1 (LD1) O L 53 Led2 (LD2) O L 58 Led3 (LD3) O L 60 Led4 (LD4) O L 62 Button 1 (S1) I L 54 Button 2 (S2) I L 59 Button 3 (S3) I L 61