Πανεπιστήμιο Κρήτης Τμήμα Επιστήμης Υπολογιστών Παράδειγμα αντιστοίχισης κυκλώματος σε FPGA Γιώργος Δημητρακόπουλος με τη βοήθεια του Βασίλη Παπαευσταθίου Στο παράδειγμα αυτό χρησιμοποιώντας μια πολύ μικρή επαναπρογραμματιζόμενη λογική θα δείξουμε τον τρόπο με τον οποίο μπορούμε να αντιστοιχίσουμε σε αυτήν ένα πολύ απλό κύκλωμα. Στην πραγματικότητα το πρόβλημα της αντιστοίχισης είναι πολύ πιο δύσκολο, κυρίως λόγο της πολύ μεγάλης πολυπλοκότητας των κυκλωμάτων που θέλουμε να υλοποιήσουμε και της σύνθετης δομής της επαναπρογραμματιζόμενης λογικής. Για το λόγο αυτό η διαδικασία αυτή εκτελείται από εξειδικευμένα εργαλεία. Πάντως, σε κάθε περίπτωση η εξοικίωση σας με τον τρόπο λειτουργίας της επαναπρογραμματιζόμενης λογικής είναι καθόλα χρήσιμη έστω και αν αυτή προκύψει μέσα από μικρά ενδεικτικά παραδείγματα. Αφού έχουμε περιγράψει το κύκλωμα μας σε Verilog και έχουμε περάσει τη διαδικασία της λογικής σύνθεσης προέκυψε το ακόλουθο κύκλωμα λογικών πυλών. Το κύκλωμα αποτελείται από 2 λογικές πύλες, μία ΝΑΝD και μία ΟR, καθώς και από ένα flip-flop. Το κύκλωμα δέχεται 3 εισόδους και παράγει μία έξοδο, ενώ για τη σύνδεση των πυλών απαιτείται ένα επιπλέον καλώδιο το Χ που συνδέει την έξοδο της πύλης NAND με την είσοδο της OR. Σκοπός της ανάλυσης μας είναι να αντιστοιχίσουμε τη λειτουργία του κυκλώματος μας στην επαναπρογραμματιζόμενη λογική της FPGA που έχουμε στη διάθεση μας. H δομή ενός πολύ μικρού FPGA φαίνεται στο σχήμα που ακολουθεί. Αποτελείται από δύο όμοια Logic elements και δυο routing switches. Κάθε logic element περιέχει ένα Look-up table (LUT) των 2 εισόδων, 1 flip-flop, επιπλέον πολυπλέκτες και ένα τρικατάστατο ενισχυτή (tristate buffer) ο οποίος επιτρέπει ή όχι τη σύνδεση της εξόδου του Logic Element με το υπόλοιπο κύκλωμα. Κάθε Logic Element μπορεί να υλοποιήσει μια οποιαδήποτε συνάρτησει των 2 εισόδων προγραμματίζοντας κατάλληλα τα κελιά της μνήμης κάθε LUT. Για παράδειγμα αν θέλαμε ένα LUT να υλοποιεί τη συνάρτηση XOR τότε για τους 4 συνδιασμούς των εισόδων 00, 01, 10, 11 οι αντίστοιχες θέσεις μνήμης του LUT θα έπρεπε να περιέχουν τις τιμές 0, 1, 1, και 0, αντίστοιχα. Έτσι, μετά τον προγραμματισμό, κατά τη 1
διάρκεια κανονικής λειτουργείας του κυκλώματος, αν οι είσοδοι του LUT έχουν την τιμή 11 τότε θα επιλεγεί η τιμή που περιέχει το τελευταίο κελί μνήμης από το πολυπλέκτη 4-σε-1 που υπάρχει μέσα σε κάθε LUT και η έξοδος του θα ήταν το ζητούμενο 0. Με την ίδια φιλοσοφία προγραμματίζονται και οι διασυνδέσεις των Logic Elements. Για παράδειγμα αν θέλουμε η έξοδος του κάθε Logic Element να προέρχεται από την έξοδο ενός flip-flop τότε θα έπρεπε να διαλέξουμε για το κελί μνήμης SEL1 του Logic Element την τιμή 1, η οποία δίνει στην έξοδο out, μέσω του πολυπλέκτη ΜUX1, την έξοδο του flip-flop και όχι απ ευθείας την έξοδο του LUT. Τα Logic Elements της επαναπρογραμματιζόμενης λογικής που έχουμε στη διάθεση μας συνοδεύονται και από ένα σύνολο καλωδίων τα οποία μπορούν να λειτουργήσουν είτε ως είσοδοι είτε ως έξοδοι ανάλογα με τον τρόπο που εμείς διαλέγουμε να τις χρησιμοποιήσουμε. Για παράδειγμα εφόσον θέλουμε η έξοδος του Logic Element 1 να συνδεθεί στη γραμμή B τότε πρέπει να φροντίσουμε το σήμα ελέγχου του 2
τρικατάστατου ενισχυτή να είναι στην τιμή 1. Τότε η γραμμή B oδηγείται από την έξοδο out του LE1. Η γραμμή αυτή μπορεί να χρησιμοποιηθεί σαν είσοδος στο επόμενο LE2 προγραμματίζοντας κατάλληλα το Switch 2 θέτοντας δηλαδή στις κατάλληλες τιμές τα σήματα ελέγχου των πολυπλεκτών που περιέχει. Μετά από αυτή τη μικρή εισαγωγή ας επιστρέψουμε στο παράδειγμα μας. Το πρώτο βήμα της αντιστοίχισης που θέλουμε να εκτελέσουμε είναι να διαλέξουμε ποια πύλη θα υλοποιηθεί από ποιο Logic Element. Εφόσον έχουμε δύο πύλες 2 είσοδων και το μεγαλύτερο LUT που έχουμε στη διάθεση μας είναι των 2 εισόδων τότε είμαστε αναγκασμένοι να χρησιμοποιήσουμε 2 LUTs. Aυτό έχει ως αποτέλεσμα να χρησιμοποιήσουμε και τα 2 Logic Elements γιατί κάθε Logic Element αποτελείται μόνο από 1 LUT. Στο ένα LE θα χρειαστούμε και το flip-flop που διαθέτει ενώ στο άλλο όχι. Έτσι το μοίρασμα της λογικής μας σε Logic Elements θα μπορούσε να μοιάζει με αυτό του παρακάτω σχήματος. Η επιλογή δεν είναι μοναδική και θα μπορούσατε να βρείτε και κάποιο ενναλακτικό μοίρασμα. Από τα στοιχεία του Logic Element 1 θα χρειαστούμε μόνο το LUT και όχι το flip-flop, ενώ από το Logic Element 2 θα χρησιμοποιήσουμε και τα δύο. Το LUT του Logic Element 1 θα υλοποιεί τη λογική συνάρτηση NAND ενώ το LUT του Logic Element 2 θα υλοποιεί τη συνάρτηση OR. Επίσης, παρατηρώντας το σχήμα, προσέχουμε ότι θέλουμε 3 γραμμές από τις γραμμές εισόδου/εξόδου της FPGA ώστε να συνδέσουμε τις εισόδους In0, In1 και Ιn2 και μία επιπλέον γραμμή ώστε να συνδέσουμε την έξοδο Out. Η γραμμή του ρολογιού δε μας απασχολεί εφόσον συνδέεται απ ευθείας στα flip-flops και των δύο Logic Elements. Για το μόνο που πρέπει να φροντίσουμε είναι το καλώδιο X που συνδέει την έξοδο της NAND με την OR πύλη που ακολουθεί. Γι αυτό παρατηρώντας το σχήμα της FPGA και σεβόμενοι την αντιστοίχιση που κάναμε μεταξύ πυλών και Logic Elements θα χρησιμοποιήσουμε τη γραμμή B της FPGA. Έτσι οι τελικές μας επιλογές είναι οι εξής: LUTs: Το LUT του logic element 1 προγραμματίζεται ώστε να εκτελεί τη λειτουργία της πύλης NAND. Το LUT του logic element 2 προγραμματίζεται ώστε να εκτελεί τη λειτουργία της πύλης OR. 3
Σήματα εισόδου: Αντιστοιχίζουμε το σήμα In0 στη γραμμή A της FPGA και το σήμα In1 στη γραμμή C. Δε μπορούμε να διαλέξουμε το B αντί του C για την Ιn1 για 2 λόγους. Πρώτον, θέλουμε να συνδέσουμε το B με την έξοδο του LE1 όποτε δε μπορεί να λειτουργεί ταυτόχρονα σαν είσοδος και έξοδος και δεύτερον τα σήματα A και B καταλήγουν στον ίδιο πολυπλέκτη ΜUX2 του Switch 1 με αποτέλεσμα να μην μπορούν να επιλεγούν και τα δύο για να συνδεθούν με το Logic Element1. Ακολουθώντας την ίδια στρατηγική η είσοδος In2 αντιστοιχίζεται στη γραμμή D της FPGA και επιλέγεται κατάλληλα σαν είσοδος του Logic Element 2 μέσω του Switch 2. Σήματα εξόδου: Το σήμα εξόδου Out του κυκλώματος μας συνδέεται με τη γραμμή F της FPGA ενώ η ενδιάμεση γραμμή X συνδέεται με τη γραμμή B της FPGA. Για να λειτουργήσει η γραμμή B ως είσοδος του Logic Element 2 φροντίσουμε να την επιλέξουμε στο Switch 2 προγραμματιζόντας κατάλληλα τις γραμμές επιλογής των πολυπλεκτών του Switch 2. To προγραμματισμένο πια FPGA μαζί με τη γραφική αναπαράσταση της ροής των δεδομένων φαίνεται στο σχήμα που ακολουθεί. 4
Παραρείστε πως το SEL1 του ΜUX 1 των δύο logic elements τίθεται σε διαφορετική τιμή. O λόγος γι αυτήν την επιλογή είναι πως στην περίπτωση του LE1 δε μας ενδιαφέρει η έξοδος του flip-flop ενώ για το LE2 συμβαίνει ακριβώς το αντίθετο. Όσο τα κελιά μνήμης κρατήσουν αυτές τις τιμές που τους αναθέσαμε το FPGA θα εκτελεί τη λειτουργία του κυκλώματος μας. Οποιαδήποτε αλλαγή στις τιμές αυτές θα οδηγήσει σε αλλαγή της λειτουργίας της FPGA. 5