Σχεδίαση κυκλωμάτων σε SystemVerilog: 1o μέρος

Σχετικά έγγραφα
Σχεδίαση κυκλωμάτων με VHDL: 1o μέρος

Λογική Σχεδίαση Ι - Εξεταστική Φεβρουαρίου 2013 Διάρκεια εξέτασης : 160 Ονοματεπώνυμο : Α. Μ. Έτος σπουδών:

Η κανονική μορφή της συνάρτησης που υλοποιείται με τον προηγούμενο πίνακα αληθείας σε μορφή ελαχιστόρων είναι η Q = [A].

Πράξεις με δυαδικούς αριθμούς

! Εάν ο αριθμός διαθέτει περισσότερα bits, χρησιμοποιούμε μεγαλύτερες δυνάμεις του 2. ! Προσοχή στη θέση του περισσότερο σημαντικού bit!

Παράδειγμα αντιστοίχισης κυκλώματος σε FPGA

Εργαστήριο Εισαγωγής στη Σχεδίαση Συστημάτων VLSI

i Το τρανζίστορ αυτό είναι τύπου NMOS. Υπάρχει και το συμπληρωματικό PMOS. ; Τι συμβαίνει στο τρανζίστορ PMOS; Το τρανζίστορ MOS(FET)

Ψηφιακή Λογική και Σχεδίαση

Ψηφιακά Συστήματα. 6. Σχεδίαση Συνδυαστικών Κυκλωμάτων

Ελίνα Μακρή

Behavioral & Mixed VHDL Architectures Finite State Machines in VHDL

ΗΜΥ211 Εργαστήριο Ψηφιακών Συστημάτων

Πανεπιστήμιο Πατρών Τμήμα Φυσικής Εργαστήριο Ηλεκτρονικής. Ψηφιακά Ηλεκτρονικά. Συνδυαστική Λογική. Επιμέλεια Διαφανειών: Δ.

ΠΛΗ10 Κεφάλαιο 2. ΠΛH10 Εισαγωγή στην Πληροφορική: Τόμος Α Κεφάλαιο: : Αριθμητική περιοχή της ALU 2.5: Κυκλώματα Υπολογιστών

Behavioral & Mixed VHDL Architectures Finite State Machines in VHDL

Συνδυαστικά Κυκλώματα

Ολοκληρωμένα Κυκλώματα

Πράξεις με δυαδικούς αριθμούς

K15 Ψηφιακή Λογική Σχεδίαση 7-8: Ανάλυση και σύνθεση συνδυαστικών λογικών κυκλωμάτων

ΗΜΥ 210 ΣΧΕΔΙΑΣΜΟΣ ΨΗΦΙΑΚΩΝ ΣΥΣΤΗΜΑΤΩΝ. Χειµερινό Εξάµηνο 2016 ΔΙΑΛΕΞΗ 15: Καταχωρητές (Registers)

ΕΙΣΑΓΩΓΗ ΣΤΟΥΣ ΥΠΟΛΟΓΙΣΤΕΣ. ΜΑΘΗΜΑ 2 ο. ΑΛΓΕΒΡΑ Boole ΛΟΓΙΚΑ ΚΥΚΛΩΜΑΤΑ

"My Binary Logic" Ένας προσομοιωτής λογικών πυλών στο Scratch

Ψηφιακά Κυκλώματα (1 ο μέρος) ΜΥΥ-106 Εισαγωγή στους Η/Υ και στην Πληροφορική

Σχεδιασμός Ολοκληρωμένων Κυκλωμάτων VLSI II

4.1 Θεωρητική εισαγωγή

Περίληψη. ΗΜΥ-210: Λογικός Σχεδιασµός Εαρινό Εξάµηνο Παράδειγµα: Καταχωρητής 2-bit. Καταχωρητής 4-bit. Μνήµη Καταχωρητών

ΠΛΗ21 Κεφάλαιο 2. ΠΛΗ21 Ψηφιακά Συστήματα: Τόμος Α Κεφάλαιο: Παράσταση Προσημασμένων Αριθμών Συμπληρώματα

ΗΜΥ 210: Σχεδιασμός Ψηφιακών Συστημάτων. Καταχωρητές 1

Τμήμα Χρηματοοικονομικής & Ελεγκτικής ΤΕΙ Ηπείρου Παράρτημα Πρέβεζας. Πληροφορική Ι. Μάθημα 4 ο Πράξεις με bits. Δρ.

26-Nov-09. ΗΜΥ 210: Λογικός Σχεδιασμός, Χειμερινό Εξάμηνο Καταχωρητές 1. Διδάσκουσα: Μαρία Κ. Μιχαήλ

HY430 Εργαστήριο Ψηφιακών Κυκλωμάτων.

9. OIΚΟΥΜΕΝΙΚΕΣ ΠΥΛΕΣ ΠΟΛΛΑΠΛΩΝ ΕΙΣΟ ΩΝ

ΕΙΣΑΓΩΓΗ ΣΤΗΝ ΠΛΗΡΟΦΟΡΙΚΗ

ΘΕΜΑΤΑ & ΕΝΔΕΙΚΤΙΚΕΣ ΛΥΣΕΙΣ

Ενότητα 9 ΑΡΙΘΜΗΤΙΚΑ & ΛΟΓΙΚΑ ΚΥΚΛΩΜΑΤΑ

Προβλήματα, αλγόριθμοι, ψευδοκώδικας

Εισαγωγή στους Ηλεκτρονικούς Υπολογιστές

Εισαγωγή στη γλώσσα περιγραφής υλικού VHDL. Βασικές εντολές και η περιγραφή συνδυαστικών κυκλωµάτων. Ψηφιακή Σχεδίαση µε CAD ΙΙ - ιάλεξη 2 -

ΗΜΥ 100 Εισαγωγή στην Τεχνολογία

Κεφάλαιο 8. Αριθμητική Λογική μονάδα

Ηλεκτρολόγοι Μηχανικοί ΕΜΠ Λογική Σχεδίαση Ψηφιακών Συστημάτων Διαγώνισμα κανονικής εξέτασης Θέμα 1ο (3 μονάδες)

ΠΡΟΓΡΑΜΜΑ ΣΠΟΥ ΩΝ ΠΛΗΡΟΦΟΡΙΚΗΣ

«Σχεδιασμός Ολοκληρωμένων Κυκλωμάτων» Χειμερινό εξάμηνο Συντρέχων Κώδικας

Μία μέθοδος προσομοίωσης ψηφιακών κυκλωμάτων Εξελικτικής Υπολογιστικής

ΗΜΥ-210: Σχεδιασμός Ψηφιακών Συστημάτων

Εκτέλεση πράξεων. Ψηφιακά Ηλεκτρονικά και Δυαδική Λογική. Πράξεις με δυαδικούς αριθμούς. Πράξεις με δυαδικούς αριθμούς

«Σχεδιασμός Ολοκληρωμένων Κυκλωμάτων» Χειμερινό εξάμηνο Ακολουθιακός Κώδικας

ΑΣΚΗΣΗ 4 ΣΧΕΔΙΑΣΗ ΑΡΙΘΜΗΤΙΚΩΝ ΛΟΓΙΚΩΝ ΚΥΚΛΩΜΑΤΩΝ

w x y Υλοποίηση της F(w,x,y,z) με πολυπλέκτη 8-σε-1

Υπάρχουν δύο τύποι μνήμης, η μνήμη τυχαίας προσπέλασης (Random Access Memory RAM) και η μνήμη ανάγνωσης-μόνο (Read-Only Memory ROM).

ΕΡΓΑΣΤΗΡΙΟ ΗΛΕΚΤΡΟΝΙΚΩΝ ΕΦΑΡΜΟΓΩΝ

Εισαγωγή στην επιστήμη των υπολογιστών. Πράξεις με μπιτ

K24 Ψηφιακά Ηλεκτρονικά 6: Πολυπλέκτες/Αποπολυπλέκτες

8 η Θεµατική Ενότητα : Εισαγωγή στις Γλώσσες Περιγραφής Υλικού: Μοντέλα Συνδυαστικών Κυκλωµάτων

Γ2.1 Στοιχεία Αρχιτεκτονικής. Γ Λυκείου Κατεύθυνσης

100 ΕΡΩΤΗΣΕΙΣ ΜΕ ΤΙΣ ΑΝΤΙΣΤΟΙΧΕΣ ΑΠΑΝΤΗΣΕΙΣ ΓΙΑ ΤΟ ΜΑΘΗΜΑ ΨΗΦΙΑΚΑ ΚΥΚΛΩΜΑΤΑ

ΣΧΕΔΙΑΣΗ ΨΗΦΙΑΚΩΝ ΣΥΣΤΗΜΑΤΩΝ

Πανεπιστήμιο Δυτικής Μακεδονίας. Τμήμα Μηχανικών Πληροφορικής & Τηλεπικοινωνιών. Ψηφιακή Σχεδίαση

Εισαγωγή στην επιστήμη των υπολογιστών. Υπολογιστές και Δεδομένα Κεφάλαιο 4ο Πράξεις με μπιτ

Εισαγωγή στην πληροφορική

9 ο Μαθητικό Συνέδριο Πληροφορικής Κεντρικής Μακεδονίας. "My Binary Logic" Ένας προσομοιωτής λογικών πυλών στο Scratch

«Σχεδιασμός Ολοκληρωμένων Κυκλωμάτων» Χειμερινό εξάμηνο Τύποι Δεδομένων και Τελεστές

Ολοκληρωμένα κυκλώματα 1 ο σετ ασκήσεων

ΠΕΡΙΕΧΟΜΕΝΑ. Πρόλογος...9 ΚΕΦ. 1. ΑΡΙΘΜΗΤΙΚΑ ΣΥΣΤΗΜΑΤΑ - ΚΩΔΙΚΕΣ

ΑΣΚΗΣΗ 8 η -9 η ΣΧΕΔΙΑΣΗ ΑΡΙΘΜΗΤΙΚΗΣ ΛΟΓΙΚΗΣ ΜΟΝΑΔΑΣ ΤΕΣΣΑΡΩΝ ΔΥΑΔΙΚΩΝ ΨΗΦΙΩΝ

ΒΑΣΙΚΕΣ ΑΡΧΕΣ ΨΗΦΙΑΚΗΣ ΤΕΧΝΟΛΟΓΙΑΣ. Κεφάλαιο 3

ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ Ανώτατο Εκπαιδευτικό Ίδρυμα Πειραιά Τεχνολογικού Τομέα. Σχεδίαση Ψηφιακών Συστημάτων. Ενότητα: ΚΑΤΑΧΩΡΗΤΕΣ - ΑΠΑΡΙΘΜΗΤΕΣ

Δομές Ακολουθίας- Επιλογής - Επανάληψης. Δομημένος Προγραμματισμός

Ασκήσεις Φροντιστηρίου «Υπολογιστική Νοημοσύνη Ι» 5 o Φροντιστήριο

C D C D C D C D A B

Εισαγωγή στη γλώσσα περιγραφής υλικού VHDL. Γενικά χαρακτηριστικά, σύνταξη και τύποι. Ψηφιακή Σχεδίαση µε CAD ΙΙ - ιάλεξη 1 -

Μάθημα 5: Χαρακτηριστικά της Κ.Μ.Ε.

Περίληψη. ΗΜΥ 210: Λογικός Σχεδιασµός, Εαρινό Εξάµηνο υαδική Αφαίρεση. υαδική Αφαίρεση (συν.) Ακόµη ένα παράδειγµα Αφαίρεσης.

ΤΙΤΛΟΣ ΕΡΓΑΣΤΗΡΙΑΚΗΣ ΑΣΚΗΣΗΣ ΣΕΙΡΙΑΚΗ ΠΡΟΣΘΕΣΗ

ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ Ανώτατο Εκπαιδευτικό Ίδρυμα Πειραιά Τεχνολογικού Τομέα

Εφαρμοσμένη Πληροφορική ΙΙ (Θ) Είσοδος/Έξοδος Μεταβλητές Τύποι Μεταβλητών Τελεστές και Προτεραιότητα Μετατροπές Μεταξύ Τύπων

Εισαγωγή στην επιστήμη των υπολογιστών. Υπολογιστές και Δεδομένα Κεφάλαιο 4ο Πράξεις με μπιτ

Μοντέλα. χαρακτηριστικά χωρίς να συνοδεύεται από λεπτοµέρειες.

Οργάνωση της φυσικής δομής του ολοκληρωμένου κυκλώματος

Εργαστήριο Αρχιτεκτονικής Υπολογιστών Ι. Εισαγωγή στη VHDL

Εισαγωγή στην επιστήμη των υπολογιστών. Υπολογιστές και Δεδομένα Κεφάλαιο 4ο Πράξεις με μπιτ

Αθροιστές. Ημιαθροιστής

Οργάνωση Η/Υ. Γιώργος Δημητρίου. Μάθημα 2 ο Σύντομη Επανάληψη. Πανεπιστήμιο Θεσσαλίας - Τμήμα Πληροφορικής

Θέμα 1ο (3 μονάδες) Υλοποιήστε το ακoλουθιακό κύκλωμα που περιγράφεται από το κατωτέρω διάγραμμα

Διαδικασιακός Προγραμματισμός

Μελέτη και σχεδίαση µιας υποτυπώδους κεντρικής µονάδας επεξεργασίας στα 32 µπιτ.

Περιεχόμενα. Πρώτο Κεφάλαιο. Εισαγωγή στα Ψηφιακά Συστήματα. Δεύτερο Κεφάλαιο. Αριθμητικά Συστήματα Κώδικες

Συνδυαστικά Λογικά Κυκλώματα

Ενότητα 7 ΑΠΟΚΩΔΙΚΟΠΟΙΗΤΕΣ - ΚΩΔΙΚΟΠΟΙΗΤΕΣ ΑΠΟΠΛΕΚΤΕΣ - ΠΟΛΥΠΛΕΚΤΕΣ

Άσκηση 3 Ένα νέο είδος flip flop έχει τον ακόλουθο πίνακα αληθείας : I 1 I 0 Q (t+1) Q (t) 1 0 ~Q (t) Κατασκευάστε τον πίνακα

ΑΣΚΗΣΗ 10 ΣΧΕΔΙΑΣΗ ΑΚΟΛΟΥΘΙΑΚΩΝ ΚΥΚΛΩΜΑΤΩΝ

Αλγόριθμος. Αλγόριθμο ονομάζουμε τη σαφή και ακριβή περιγραφή μιας σειράς ξεχωριστών οδηγιών βημάτων με σκοπό την επίλυση ενός προβλήματος.

1 η Θεµατική Ενότητα : Αριθµητικά Κυκλώµατα. Επιµέλεια διαφανειών: Χρ. Καβουσιανός

ΚΕΦΑΛΑΙΟ 8 Η ΓΛΩΣΣΑ PASCAL

Εισαγωγή στον Προγραμματισμό

Κυκλώµατα µε MSI. υαδικός Αθροιστής & Αφαιρέτης

Εργαστήριο Ψηφιακών Συστηµάτων ΗΜΥ211

ΠΑΝΕΠΙΣΤΗΜΙΟ AΙΓΑIΟΥ & ΑΕΙ ΠΕΙΡΑΙΑ Τ.Τ. Τμήματα Ναυτιλίας και Επιχειρηματικών Υπηρεσιών & Μηχ. Αυτοματισμού ΤΕ. Εισαγωγή στη Python

ΕΡΓΑΣΤΗΡΙΟ ΜΙΚΡΟΫΠΟΛΟΓΙΣΤΩΝ ΚΑΙ ΨΗΦΙΑΚΩΝ ΣΥΣΤΗΜΑΤΩΝ : Κ. ΠΕΚΜΕΣΤΖΗ

Transcript:

Σχεδίαση κυκλωμάτων σε SystemVerilog: 1o μέρος Γιώργος Δημητρακόπουλος Το πρώτο σας κύκλωμα Τα ψηφιακά κυκλώματα είναι μια συλλογή από λογικές πύλες και ακολουθιακά στοιχεία αποθήκευσης (ή συγχρονισμού) όπως τα flip-flops. Αποτελούνται επίσης εξειδικευμένες μονάδες αποθήκευσης πληροφορίας όπως οι μνήμες τις οποίες θα πρέπει μεταχειριστούμε χωριστά από τα υπόλοιπα κυκλωματικά στοιχεία στην περίπτωση που περιγράφουμε τη λειτουργία των κυκλωμάτων με μια γλώσσα περιγραφής υλικού. Όπως και στην παρουσίαση των βασικών αρχών της ψηφιακής σχεδίασης θα ξεκινήσουμε από τα συνδυαστικά κυκλώματα και τον τρόπο περιγραφής τους και στη συνέχεια θα ασχοληθούμε με συνθετότερες δομές που μπορούν και θυμούνται προηγούμενες καταστάσεις λειτουργίας τους επαυξάνοντας ταυτόχρονα τις δυνατότητες που μας δίνει η VHDL στην περιγραφή των κυκλωμάτων. Ένα απλό παράδειγμα συνδυαστικής λογικής φαίνεται στο σχήμα που ακολουθεί. assign A = (B & C) (~D); Το κύκλωμα αποτελείται από 3 καλώδια εισόδου Β, C, και D και υπολογίζει μια έξοδο Α. H περιγραφή της λειτουργίας του κυκλώματος σε SystemVerilog περιλαμβάνει απλές λογικές πράξεις and &, or και not ~ οι οποίες θα εφαρμόζονταν πάνω στα καλώδια των εισόδων για να υπολογίσουν μια νέα έξοδο. Στο παράδειγμα αυτό τα A, B, C και D είναι ονόματα των σημάτων της περιγραφής σε SystemVerilog, τα οποία αντιστοιχούν σε απλά καλώδια στην πραγματικότητα. H ανάθεση στο σήμα Α γίνεται μέσω της απευθείας ανάθεσης assign A = αφού πρώτα υπολογιστεί η λογική συνάρτηση που συνδέει τις τιμές των υπολοίπων σημάτων. Οι παρενθέσεις μας επιτρέπουν να καθορίσουμε τη σειρά υπολογισμού των λογικών εκφράσεων, ενώ κάθε ανάθεση σε ένα σήμα ολοκληρώνεται με ένα ; στο τέλος της πρότασης. Κάθε φορά που κάποιο από τα σήματα στη δεξιά πλευρά της ανάθεσης assign <> = <> αλλάξει τιμή, πχ το B, το C, ή το D, τότε υπολογίζεται αυτόματα μια νέα τιμή για το σήμα στην αριστερή πλευρά της ανάθεσης. Η λογική αυτή μας επιτρέπει να πούμε πως οι απευθείας αναθέσεις αυτές περιγράφουν τη λειτουργία μιας οποιαδήποτε συνδυαστικής λογικής. Η πιο απλή μορφή ανάθεσης είναι αυτή μιας σταθερής λογικής τιμής και γράφεται ως εξής: assign Α = 1 b1; Η τιμή του λογικού 0 και 1 τοποθετείται μετά την παράσταση 1 b το οποίο δηλώνει πως η ποσότητα που θα ακολουθήσει είναι του ενός μπιτ. Για τα ψηφιακά κυκλώματα με περισσότερες από μία εξόδους χρησιμοποιούμε περισσότερες αναθέσεις, μία για κάθε έξοδο του κυκλώματος. Αυτό φαίνεται στο παρακάτω παράδειγμα του κυκλώματος του πλήρη αθροιστή, όπου tα σήματα στην έξοδο του κυκλώματος S και Co υπολογίζονται ως λογικές συναρτήσεις των εισόδων A, Β και Ci. assign S = A ^ B ^ Ci; assign Co = (A & B) ((A ^ B) & Ci); Δομή κάθε περιγραφής σε SystemVerilog Όπως σε κάθε ψηφιακό κύκλωμα πέρα από την περιγραφή της λειτουργίας του πρέπει να είμαστε σε θέση να ορίσουμε με σαφήνεια τις εισόδους και τις εξόδους του καθώς και να του δώσουμε ένα όνομα που θα μας επιτρέπει να το ξεχωρίζουμε από τα υπόλοιπα. Έτσι η πλήρης περιγραφή σε SystemVerilog του κυκλώματος του πλήρη αθροιστή φαίνεται παρακάτω: 1

module fulladder ( input logic A, input logic B, // input bits for this stage input logic Ci, // carry into this stage output logic S, // sum bit output logic Co ); // carry out of this stage assign S = A ^ B ^ Ci; assign Co = (A & B) ((A ^ B) & Ci); Η περιγραφή του πλήρη αθροιστή (full adder) αποτελείτε από 2 μέρη. To πρώτο μέρος (module) περιγράφει το όνομα του κυκλώματος και τις πόρτες εισόδου και εξόδου του, ενώ το δεύτερο μέρος περιλαμβάνει την περιγραφή της λειτουργίας του. Το όνομα του κυκλώματος δηλώνεται αμέσως μετά την ειδική λέξη module. Κάθε δήλωση ξεκινά με τη γραμμή module <όνομα> (πόρτες εισόδου/εξόδου); και τελειώνει με τη δήλωση. Για τον πλήρη αθροιστή διαλέξαμε το όνομα fullαdder. Μέσα στη δήλωση κάθε module περιλαμβάνουμε μια λίστα με τις δηλώσεις των εισόδων και των εξόδων του κυκλώματος. Η λίστα αυτή εμπεριέχεται μέσα σε παρενθέσεις. Για κάθε πόρτα του κυκλώματος μας πρέπει να δηλώσουμε το όνομα του σήματος που συνδέεται σε αυτήν μέσα στο κύκλωμα, αν πρόκειται για είσοδο ή έξοδο του κυκλώματος και τον τύπου του σήματος. Στο παράδειγμα μας ο πλήρης αθροιστής διαθέτει 2 εξόδους και 3 εισόδους εκ των οποίων η μία είναι το σήμα B το οποίο είναι τύπου logic. Αυτό το καταλαβαίνουμε κοιτώντας τη δήλωση module fulladder (., input logic B, );. Για όλα τα κυκλώματα που θα σχεδιάσουμε στη συνέχεια θα διαλέξουμε ο τύπος των καλωδίων που θα χρησιμοποιήσουμε θα είναι πάντα logic. Ο τύπος logic αντιστοιχεί ουσιαστικά σε όλες τις τιμές που μπορεί να πάρει ένα καλώδιο στην πραγματικότητα και δεν είναι άλλες από το λογικό 0 το λογικό 1, απροσδιόριστες τιμές εξαιτίας λανθασμένης ή πολλαπλής οδήγησης και μη οδηγούμενη τιμή (floating). Τη δήλωση της διεπαφής (interface) του κυκλώματος ακολουθεί η περιγραφή της λειτουργίας του, η οποία αποτελείται από δύο απευθείας αναθέσεις στα σήματα Χ. Υ που αποτελούν τις εξόδους του κυκλώματος μας. Για την πλήρη περιγραφή ενός κυκλώματος απαιτείται τόσο η δήλωση του module όσο και η περιγραφή της λειτουργίας του. Η μεν δήλωση του module έχει να κάνει μόνο με το όνομα του κυκλώματος και τα ονόματα των σημάτων που συνδέονται στις πόρτες εισόδου και εξόδου του, ενώ το κύριο σώμα της περιγραφής δηλώνει ακριβώς τη συμπεριφορά του κυκλώματος πάνω στα σήματα εισόδου. Για παράδειγμα κάθε φορά που δηλώνουμε ένα module είναι σαν να σχεδιάζουμε ένα κενό κουτί με εισόδους και εξόδους όπως φαίνεται στο παρακάτω σχήμα. Με την περιγραφή της συμπεριφοράς του είναι σαν να γεμίζουμε το άδειο κουτί με ένα λογικό διάγραμμα. Τέλος όπως και σε κάθε κώδικα έτσι και στη SystemVerillog χρειαζόμαστε σχόλια τα οποία θα συνοδεύουν την περιγραφή του κυκλώματος κάνοντας την πιο ευανάγνωστη. Τα σχόλια ξεκινούν με δύο πλάγιες γραμμές // (όπως στη C) και δε επηρεάζουν σε τίποτε την υπόλοιπη περιγραφή. Καλό είναι να βάζετε κατανοητά σχόλια στον κώδικα σας στα σημεία που απαιτούν περισσότερες διευκρινήσεις. Στην περιγραφή του fullαdder που δείξαμε μέχρι στιγμής όλα τα σήματα του κυκλώματος είναι είτε είσοδοι είτε έξοδοι του κυκλώματος. Φυσικά μπορούμε να έχουμε χωριστά ονόματα και για τα εσωτερικά καλώδια (σήματα) του κυκλώματος μας. Για παράδειγμα θα μπορούσαμε να περιγράψουμε τη συμπεριφορά του πλήρη αθροιστή ως εξής: 2

logic X; assign X = A ^ B; assign S = X ^ Ci; assign Co = (A & B) (X & Ci); Στην περίπτωση αυτή για την περιγραφή του πλήρη αθροιστή χρησιμοποιήσαμε ένα επιπλέον εσωτερικό καλώδιο Χ στο οποίο αναθέσαμε την τιμή του A ^ Β ( δλδ A xor B). Στη συνέχεια χρησιμοποιήσαμε την τιμή αυτού του καλωδίου ώστε να υπολογίσουμε τις τιμές των σημάτων της εξόδου S και Co. Για να χρησιμοποιήσουμε το καλώδιο αυτό θα έπρεπε να το δηλώσουμε μέσα στο σώμα της περιγραφής του κυκλώματος. H δήλωση όλων των εσωτερικών σημάτων ακολουθεί πάντα την ίδια δομή logic <όνομα>;. Οι απευθείας αναθέσεις στα σήματα Χ, S και Co πραγματοποιούνται ταυτόχρονα και στα 3 σήματα και το αποτέλεσμα τους είναι ανεξάρτητο από τη σειρά που έχουν τοποθετηθεί στον κώδικα. Για παράδειγμα οι δύο παρακάτω παραλλαγές assign X = A ^ B; assign S = X ^ Ci; assign Co = (A & B) (X & Ci); assign Co = (A & B) (X & Ci); assign X = A ^ B; assign S = X ^ Ci; θα είχαν ακριβώς το ίδιο αποτέλεσμα, εφόσον στις απευθείας αναθέσεις τις SystemVerilog δεν υπάρχει η έννοια της σειριακής εκτέλεσης των εντολών όπως σε ένα πρόγραμμα. Μία απευθείας ανάθεση assign <signal> <= f(<signals>) αντιστοιχεί σε ένα κομμάτι ενός κυκλώματος με μία έξοδο. Το σήμα στην αριστερή πλευρά της ανάθεσης είναι η έξοδος του υποτιθέμενου κυκλώματος και τα σήματα στη δεξιά πλευρά οι είσοδοι του. Στο παράδειγμα μας το κύκλωμα που περιγράφουμε αποτελείται από 4 υποκυκλώματα τα οποία ενώνονται με καλώδια. assign p2 = a2 a3; assign p3 = p2 ^ a1; assign p1 = (~a1) & a2; assign p4 = p1 & p3; Όταν ένα καλώδιο (όπως τα p1, p3) συμμετέχει τόσο στη δεξιά όσο και στην αριστερή πλευρά κάποιων αναθέσεων υπονοείται πως πρόκειται για ένα καλώδιο που ενώνει δύο υποκυκλώματα. Όπως και στα πραγματικά κυκλώματα λογικών πυλών έτσι και στη SystemVerilog οι αναθέσεις υπολογίζονται εκ νέου κάθε φορά που τα σήματα (καλώδια) στη δεξιά πλευρά των αναθέσεων αλλάζουν τιμή ανεξάρτητα από τη σειρά που έχουν γραφεί στον κώδικα. Άλλωστε όταν ζωγραφίζουμε ένα κύκλωμα δεν παίζει ρόλο ούτε η σειρά με την οποία ζωγραφίσαμε τις πύλες στο χαρτί ούτε πια βάλαμε μπροστά και ποια πίσω αρκεί να τις συνδέσαμε σωστά με τα καλώδια που έχουμε στη διάθεση μας. Αυτό όμως που πρέπει οπωσδήποτε να αποφεύγουμε είναι να έχουμε περισσότερες από μία απευθείας αναθέσεις στο ίδιο σήμα. Στο παρακάτω παράδειγμα το σήμα y ανατίθεται περισσότερο από μια φορές με απευθείας ανάθεση. assign y = a c; assign y = a & b; assign x = y & d; Οι αναθέσεις αυτές αν και συντακτικά σωστές παρουσιάζουν ένα ουσιαστικό λάθος. Το κύκλωμα στο οποίο αντιστοιχούν αποτελείται από 2 AND πύλες και μια OR. Η μία ΟR πύλη συνδυάζει τις εισόδους a και b και παράγει το σήμα y. To ίδιο όμως ακριβώς προσπαθεί να παράγει και η AND πύλη που συνδυάζει τις εισόδους a και c. Το αποτέλεσμα αυτού του διπλού υπολογισμού του y μέσω απευθείας αναθέσεων οδηγεί σε ένα βραχυκύκλωμα πάνω στο καλώδιο y η τιμή του οποίου θα είναι άγνωστη στην περίπτωση που η πάνω και η κάτω πύλη προσπαθούν να το οδηγήσουν σε αντίθετες λογικές τιμές. 3

Απευθείας αναθέσεις υπό συνθήκη Οι λογικές σχέσεις not, and, or, xor αρκούν για να περιγράψουν τη λειτουργία ενός οποιοδήποτε συνδυαστικού κυκλώματος. Παρόλα αυτά, συνήθως χρησιμοποιούμε υπό-συνθήκη αναθέσεις οι οποίες κάνουν την περιγραφή πιο κατανοητή. Μια τέτοια ανάθεση υπό-συνθήκη στο σήμα d περιγράφεται στη VHDL ως εξής assign d = (a==b)? '1': (c==1 b1)? b : ~a; Το σήμα d παίρνει την τιμή του λογικού 1 όταν τα οι τιμές των σημάτων a και b είναι ίσες. Αν αυτό δεν ισχύει αλλά η τιμή του c είναι ίση με 1 τότε στο d ανατίθεται η τιμή του b. Αν τίποτε από αυτά δεν ικανοποιείται τότε το d παίρνει την αντίστροφη τιμή του a. Το πρώτο που πρέπει να παρατηρήσετε είναι πως ο έλεγχος της συνθήκης ισότητας γίνεται το διπλό τελεστή ισότητας ==. Οι υπο-συνθήκη αναθέσεις μας επιτρέπουν να περιγράψουμε με ένα κατανοητό τρόπο απευθείας τη λειτουργία της πολύπλεξης. Για παράδειγμα η αντιστοίχιση της πιο πάνω υπο-συνθήκη ανάθεσης σε κύκλωμα φαίνεται στο παρακάτω σχήμα. Το ισοδύναμο κύκλωμα αποτελείται από 2 εν σειρά πολυπλέκτες οι οποίοι καθορίζουν ποια από τις 3 επιλογές που έχουμε για την ανάθεση, δηλαδή το '1', το b ή το not a θα περάσει τελικά στο d. Ποιο από τα 3 πιθανά μονοπάτια θα ενεργοποιηθεί τελικά εξαρτάται από την ικανοποίηση η όχι των επιμέρους συνθηκών οι οποίες συνδέονται στη γραμμή επιλογής του κάθε πολυπλέκτη. Θεωρούμε πως όταν μια συνθήκη ικανοποιηθεί τότε η έξοδος του αντίστοιχου κυκλώματος που την υλοποιεί οδηγείται στο λογικό 1. Εφόσον όλα τα σήματα του κυκλώματος μας είναι του 1 δυαδικού ψηφίου τότε ο έλεγχος της ισότητας μπορεί να γίνει μέσω μιας πύλης XNOR. Κάθε υπό-συνθήκη ανάθεση ακολουθεί τη γενική δομή του παρακάτω σχήματος. assign x = (cond#1)? Value#1 : (cond#2)? Value#2 :... (cond#n)? value#n-1 : value#n. Όταν η υπο-συνθήκη ανάθεση υλοποιηθεί αντιστοιχεί σε μια σειριακή δομή από πολυπλέκτες. Η είσοδος επιλογής του κάθε πολυπλέκτη συνδέεται στο αντίστοιχο κύκλωμα ικανοποίησης της συνθήκης ελέγχου, με τις εισόδους του πολυπλέκτη η μια να συνδέεται στην τιμή προς ανάθεση ενώ η άλλη στην έξοδο του προηγούμενο πολυπλέκτη. Οι πολυπλέκτες που βρίσκονται πιο κοντά στην έξοδο είναι αυτοί που ελέγχουν τις συνθήκες πιο κοντά στην ανάθεση. Ο πιο απλός πολυπλέκτης 2 σε 1 θα γραφόταν ως εξής assign x = (s==1 b1)? a : b; Ομάδες καλωδίων από κοινού επεξεργασία Στην πραγματικότητα σε πολλές περιπτώσεις τα κυκλώματα μας καλούνται να επεξεργαστούν ταυτόχρονα ομάδες από καλώδια τα οποία αποτελούν μια φυσική οντότητα αρκετών δυαδικών ψηφίων. Κάθε τέτοιο σήμα είναι ουσιαστικά μια συλλογή από απλά σήματα logic του ενός δυαδικού ψηφίου. Για παράδειγμα ένα σήμα Χ των 8 καλωδίων δηλώνεται ως εξής: logic [7:0] X; 4

Μαζί με την δήλωση του τύπου (logic) του σήματος Χ οφείλουμε να δηλώσουμε και το εύρος του. Δηλαδή το δείκτη της πρώτης και της τελευταίας θέσης του πίνακα, [7 : 0]. Το σήμα X δεν είναι τίποτε άλλο από 8 παράλληλα καλώδια τύπου logic το καθένα. Μπορούμε να αναφερθούμε σε κάθε ένα από αυτά χρησιμοποιώντας αγκύλες και το δείκτη του κάθε καλωδίου. Για παράδειγμα το πρώτο καλώδιο είναι το Χ[0] ενώ το τελευταίο το X[7]. Επίσης μπορούμε να αναφερθούμε απευθείας σε κάποιες συνεχόμενες υπο-ομάδες του Χ. Για παράδειγμα, μπορούμε να αναφερθούμε στα 4 καλώδια Χ[6], Χ[5], Χ[4] και Χ[3], ως X[6:3]. Οι αναθέσεις σε ομάδες καλωδίων γίνονται ακριβώς όπως και στα απλά σήματα, με τη μόνη διαφορά ότι ο λογικός τελεστής που ενδεχομένως να συνοδεύει την ανάθεση εφαρμόζεται παράλληλα σε όλα τα δυαδικά ψηφία της ομάδας των καλωδίων. Για παράδειγμα, στο σήμα Χ των 8 δυαδικών ψηφίων που δηλώσαμε πιο πριν μπορούμε να αναθέσουμε μια σταθερή τιμή assign Χ = 8 b01001010; Αυτή η απευθείας ανάθεση ισοδυναμεί με την ανάθεση σε ένα-ένα τα δυαδικά ψηφία του Χ των σταθερών τιμών assign Χ[7] = 1 b0; assign Χ[6] = 1 b1; assign Χ[5] = 1 b0; assign X[4] = 1 b0; assign X[3] = 1 b1; assign X[2] = 1 b0; assign X[1] = 1 b1; assign X[0] = 1 b0; Προσέξτε πως στην περίπτωση τις ανάθεσης σταθερής τιμής σε ομάδες καλωδίων τοποθετούμε σωστά το πλήθος των μπιτ πριν το b. Επίσης σε περίπτωση λογικών πράξεων μπορούμε να περιγράψουμε 8 παράλληλες AND πύλες χωρίς να χρειάζεται να περιγράψουμε τη λογική πράξη για κάθε ζεύγος από δυαδικά ψηφία χωριστά ( assign Χ[0] = ~(Α[0] & B[0]);... assign Χ[7] = ~(Α[7] & B[7]);) όπως φαίνεται στο σχήμα που ακολουθεί. assign X = ~(A & B); Σε αυτό το σημείο πρέπει να προσέξετε πως για να είναι η ανάθεση αυτή σωστή θα πρέπει το εύρος των εισόδων Α και Β να ταιριάζει με το εύρος του σήματος Χ. Δεν επιτρέπεται η λογική πράξη μεταξύ ενός logic vector των 6 δυαδικών ψηφίων με ένα των 7 δυαδικών ψηφίων. Αν θέλουμε να εφαρμόσουμε λογικές πράξεις πάνω σε σήματα διαφορετικού εύρους πρέπει πρώτα να εξισώσουμε τα μεγέθη τους. Για παράδειγμα η εφαρμογή μιας μάσκας mask στα 8 μπιτς ενός 8μπιτου σήματος θα έπρεπε να περιγραφεί ως εξής: logic [7:0] X, Y; logic [7:0] temp; logic mask; assign temp = { 8{mask} }; // repeat mask 8 times assign Y = X & temp; // bitwise and Με την ανάθεση αυτή κάθε μπιτ Χ[i] του σήματος Χ γίνεται and με το ίδιο σήμα mask. Αυτό συμβαίνει γιατί μέσω της δήλωσης { 8{mask} } αντιγράψαμε σε κάθε θέση του temp ένα αντίγραφο του mask. 5

Με την ίδια λογική μπορούμε να περιγράψουμε απευθείας αναθέσεις υπό συνθήκη σε ομάδες καλωδίων. Αυτό κάνουμε για ένα πολυλέκτη 2-σε-1 των 4 δυαδικών ψηφίων. module mux_4bits ( input logic [3:0] A, input logic [3:0] B, input logic sel, output logic [3:0] Z); assign Χ = (sel == 1 b1) B : A; Σε αυτό το παράδειγμα αξίζει να προσέξουμε δύο στοιχεία. Πρώτον οι ομάδες καλωδίων μπορούν να χρησιμοποιηθούν ως είσοδοι και έξοδοι του κυκλώματος μας. Δεύτερον η συνθήκη sel==1 b1 που ελέγχει την ανάθεση συνδέεται σε 4 παράλληλους 2-σε-1 πολυπλέκτες του ενός δυαδικού ψηφίου παράγοντας στην έξοδο μια 4μπιτη ποσότητα Χ. Ακόμη και στην περίπτωση που η συνθήκη περιέχει μια λογική σχέση ( για το OR, && για το AND και! για το ΝΟΤ), το αποτέλεσμα της πράξης αυτής μοιράζεται σε όλους του πολυπλέκτες, όπως στο παράδειγμα που ακολουθεί. assign Χ = ( C D)? B : A; Επίσης η υπο-συνθήκη απευθείας αναθέσεις μπορούν να αφορούν σε χωριστά μέρη του ίδιου σήματος όπως στις δυο αναθέσεις που ακολουθούν. assign Χ[1:0] = (sel == 1 b1) 2 b10: 2 b00; assign Χ[3:2] = (sel == 1 b0) 2 b11: 2 b00; Στο σχηματισμό συνθηκών ελέγχου μπορούν να συμμετέχουν και ομάδες καλωδίων τύπου std_logic_vector, τόσο σε αναθέσεις που αφορούν πολλά δυαδικά ψηφία όσο και σε αναθέσεις που αφορούν ένα καλώδιο. Για παράδειγμα ένας αποκωδικοποιητής 2-σε-4 μπορεί πολύ εύκολα να περιγραφεί ως εξής: module decoder_2to4 ( input logic [1:0] A, input logic en, output logic [3:0] Z); logic [3:0] A _dec; assign A_dec = (A==2 b00)? 4 b0001: (A==2 b01)? 4 b0010: (A==2 b10)? 4 b0100: (A==2 b11)? 4 b1000: 4 b0001; assign Z = (en==1 b1) A_dec: 4 b0000; Στο παράδειγμα μας η έξοδος του αποκωδικοποιητή ελέγχεται ταυτόχρονα και από ένα σήμα επίτρεψης en. Στην περίπτωση που το σήμα αυτό έχει την τιμή '0' τότε όλα τα καλώδια του αποκωδικοποιητή οδηγούνται στο λογικό 0. Αν εκτελέσετε όλες τις 6

λογικές απλοποιήσεις που προκύπτουν από τις σταθερές τιμές στην είσοδο των πολυπλεκτών θα προκύψει η δομή του decoder που θυμάστε από την ψηφιακή σχεδίαση. Μέσω της συνένωσης (concatenation) {,, } μπορούμε να παράγουμε μεγαλύτερες συλλογές καλωδίων. logic [ 3:0] A; logic [ 3:0] B; logic [ 3:0] C; logic [11:0] D; assign D = {A, B, C}; Στο παράδειγμα η 12μπιτή ποσότητα D προκύπτει από τη συνένωση 3 4μπιτων σημάτων Α, Β και C. Τα μπιτς του Α καταλαμβάνουν τις 4 πιο σημαντικές θέσεις στο σήμα D ενώ τα μπιτς του Β τις τέσσερις λιγότερο σημαντικές. Ισοδύναμα η παραπάνω απευθείας ανάθεση στο D θα μπορούσε να περιγραφεί ως εξής: assign D[11:8] = A; assign D[ 7:4] = B; assign D[ 3:0] = C; Τέλος στην περίπτωση που θέλουμε να μειώσουμε (reduction) τα μπιτς ενός πολύμπιτου σήματος σε μόνο ένα εφαρμόζοντας αναδρομικά την ίδια λογική συνάρτηση θα μπορούσαμε να χρησιμοποιήσουμε τις αναθέσεις μείωσης. logic [ 3:0] A; logic X, Y, Z; assign X = A; // D <- A[0] or A[1] or A[2] or A[3] assign Y = &A; // D <- A[0] and A[1] and A[2] and A[3] assign Z = ^A; // D <- A[0] xor A[1] xor A[2] xor A[3] Tα σήματα ως αριθμοί Σε πολλές περιπτώσεις οι ομάδες καλωδίων, δεν είναι απλά μια ομαδοποίηση ομοειδών σημάτων, αλλά περιγράφουν αριθμούς είτε θετικούς είτε αρνητικούς με τους οποίους θα θέλαμε να εκτελέσουμε αριθμητικές πράξεις. Για παράδειγμα όταν στο σήμα Χ των 4 δυαδικών ψηφίων (logic [3:0]) αναθέτουμε την τιμή 4 b1110 αυτό έμμεσα σημαίνει ότι το Χ είναι ο αριθμός 14. Το Χ δηλαδή ακολουθεί την unsigned αναπαράσταση στα 4 μπιτς. Με άλλα λόγια οι δύο παρακάτω αναθέσεις είναι ισοδύναμες. logic [3:0] X; assign X = 4 b0011; assign X = 3; Λόγω αυτής της ισοδυναμίας μπορούμε στα σήματα μας να χρησιμοποιήσουμε τους τελεστές αριθμητικών πράξεων +, - ή και αριθμητικών συγκρίσεων >, <, >=, <=, ==. Σύνθετοι υπολογισμοί όπως *, /, %, ** οδηγούν σε μεγάλα κυκλώματα τα οποία δεν παράγονται αυτόματα από πολλά προγράμματα λογικής σύνθεσης με αποτέλεσμα να μην μπορούμε να τους χρησιμοποιήσουμε. module test ( input logic [3:0] a, b, c, output logic [3:0] x, y, z, output logic res); assign x = a + b + 2; assign y = c + 1; assign z = c 2; assign res = (a > b)? 1 : 0; // the last line can be equivalently written as // assign res = (a > b); 7

Οι απευθείας αναθέσεις του παραδείγματος προσθέτουν, αφαιρούν και συγκρίνουν logic vectors θεωρώντας πως αυτά περιγράφουν αριθμούς χωρίς πρόσημο. Αυτήν την υπόθεση θα κάνει και το εργαλείο προσωμοίωσης και της λογικής σύνθεσης του σχεδιασμού μας. Αν τα αποτελέσματα δεν είναι τα ζητούμενα εξαιτίας μη επαρκούς ακρίβειας ή δυναμικής περιοχής (απαιτούμενο πλήθος από δυαδικά ψηφία) είναι πρόβλημα του σχεδιαστή και δε μπορεί να αντιμετωπιστεί αυτόματα. Για παράδειγμα η πρόσθεση y = c + 1 του παραδείγματος θα δώσει στο y την τιμή 0000 όταν το c είναι ίσο με 1111. Αυτή η συμπεριφορά wrap around οφείλετε στο γεγονός πως το ζητούμενο αποτέλεσμα απαιτεί 5 δυαδικά ψηφία για να υπολογιστεί ενώ το y διαθέτει μόνο 4. Σε κάποιες εφαρμογές όπως στη σχεδίαση μετρητών (counter) η συμπεριφορά αυτή είναι επιθυμητή, ενώ σε κάποιες άλλες μπορεί να δώσει λαναθσμένα αποτελέσματα. module average_of_four ( input logic [3:0] b, c, d, output logic [3:0] avg); // We increase the bitwidth of the vectors for avoiding overflow logic [3:0] sumab, sumcd; logic [4:0] sum; assign sumab = a + b; assign sumbc = c + d; assign sum = sumab + sumbc; // average = sum/4. Division by 4 is equivalent to 2 positions // right shift for unsigned numbers assign avg = sum[5:3]; Στην περίπτωση που θέλετε να χρησιμοποιήσετε στην περιγραφή σας τόσο αριθμούς χωρίς πρόσημο (unsigned) όσο και προσημασμένους αριθμούς στην αναπαράσταστη συμπλήρωμα ως προς 2 (signed) τότε πρέπει να χρησιμοποιείτε συναρτήσεις επιλογής τύπου ώστε να περιγράψετε με σαφήνεια την αριθμητική αναπαράσταση που έχετε επιλέξει κάθε φορά. Κάτι τέτοιο φαίνεται στο παράδειγμα που ακολουθεί. assign x = $signed(a) + $signed(b); assign y = $signed(c+1); assign z = $signed(c-2); Τέλος, τα σήματα logic vector από τη στιγμή που τους προσδίδουμε αριθμητική σημασία μπορούν να χρησιμοποιηθούν ως δείκτες (διευθύνσεις) για την επιλογή από ένα σύνολο από δεδομένα επιτρέποντας μας να περιγράψουμε-σχεδιάσουμε αποκωδικοποιητές, πολυπλέκτες και άλλα κυκλώματα με ένα πολύ σύντομο τρόπο. Για παράδειγμα θέλουμε από ένα logic [3:0] με το όνομα data να επιλέξουμε εκείνα τα δεδομένα που βρίσκονται στη θέση που δηλώνει ένα άλλο σήμα τύπου logic [1:0] των 2 δυαδικών ψηφίων με όνομα sel. module mux4 ( input logic[3:0] datain, input logic[1:0] sel, output logic dataout); assign dataout = datain[sel]; Ιεραρχία κατά τη σχεδίαση - υποκυκλώματα Κατά τη σχεδίαση σύνθετων κυκλωμάτων διαλέγουμε πολλές φορές να σχεδιάσουμε τα κυκλώματα μας ιεραρχικά χωρίζοντας το κύκλωμα μας σε υπο-κυκλώματα. Το τελικό κύκλωμα προκύπτει μετά από μια απλή σύνδεση με καλώδια των υποκυκλωμάτων που έχουμε σχεδιάσει. Πως όμως μπορούμε να επαναχρησιμοποιήσουμε έτοιμα κυκλώματα και να τα συνδέσουμε μεταξύ τους σε VHDL; Αυτό μπορούμε πολύ εύκολα να το μάθουμε χρησιμοποιώντας ως παράδειγμα ένα 4μπιτο αθροιστή τον οποίο θα κατασκευάσουμε συνδέοντας σε σειρά τους 4 πλήρης αθροιστές. 8

module adder4 ( input logic [3:0] A, input logic [3:0] B, input logic Ci, output logic [3:0] S, output logic Cout); -- internal carry signals logic [3:0] C; fulladder b0 (A[0],B[0], Ci,S[0],C[1]); fulladder b1 (A[1],B[1],C[1],S[1],C[2]); fulladder b2 (A[2],B[2],C[2],S[2],C[3]); fulladder b3 (A[3],B[3],C[3],S[3], Co); Στην περίπτωση αυτή το κύκλωμα μας adder4 δέχεται στην είσοδο του δύο σήματα A και Β των 4 δυαδικών ψηφίων και ένα κρατούμενο εισόδου Ci. Αφού το κύκλωμα ολοκληρώσει την πρόσθεση δίνει στην έξοδο του το άθροισμα Α + Β + Ci στην έξοδο S και το κρατούμενο εξόδου στην έξοδο Co. Στο κομμάτι της περιγραφής της συμπεριφοράς του κυκλώματος παρατηρούμε ότι δε πραγματοποιούνται αναθέσεις σε κάποια από τα σήματα εξόδου αλλά οι τιμές των εξόδων προκύπτουν από την επαναχρησιμοποιήση 4 κυκλωμάτων πλήρων αθροιστών fulladder. Για να μπορέσουμε να χρησιμοποιήσουμε το υποκύκλωμα fulladder μέσα στo adder4 πρέπει να δημιουργήσουμε ενα στιγμιότυπο (instance) για κάθε ένα που θέλουμε να χρησιμοποιήσουμε και να συνδέσουμε τις εισόδους και τις εξόδους του στα αντίστοιχα καλώδια. Στο παράδειγμα μας χρησιμοποιούμε 4 φορές το υποκύκλωμα του fulladder, χρησιμοποιώντας 4 δηλώσεις της μορφής. fulladder b0 (A[0],B[0], Ci,S[0],C[1]); Κάθε τέτοια δήλωση ενός υποκυκλώματος περιλαμβάνει το όνομα του υποκυκλώματος που χρησιμοποιoύμε (πχ fulladder), ένα όνομα για το υποκύκλωμα ώστε να το ξεχωρίζουμε από τα υπόλοιπα (πχ b0), καθώς και την αντιστοίχιση των καλωδίων του adder4 (είσοδοι, έξοδοι και εσωτερικά σήματα) στις πόρτες του fulladder. Στο παράδειγμα μας η λίστα αντιστοίχισης των εισόδων και των εξόδων με εξωτερικά καλώδια γίνεται με βάση τη σειρά δήλωσης των ονομάτων των καλωδίων. Δηλαδή το καλώδιο εισόδου του adder4 A(0) συνδέεται στην είσοδο Α του fulladder όπως φαίνεται στη σελίδα 2. Αντίστοιχα, το σήμα Ci που είναι 3ο στη λίστα της δήλωση για το instance b0 συνδέεται με το 3ο σήμα του fulladder που είναι η είσοδος C. H SystemVerilog επιτρέπει επίσης τη σύνδεση των καλωδίων στις εισόδους και εξόδους κάθε υποκυκλώματος με βάση το όνομα της κάθε πόρτας εισόδου και εξόδου χωρίς να είναι αναγκαία η τήρησης της σειράς με την οποία δηλώθηκαν οι πόρτες στο αρχικό modules. Για παράδειγμα θα μπορούσαμε να γράψουμε: fulladder b0 (.A( A[0] ),.B ( B[0] ),.S( S[0] ),.Ci( Ci ),.C0 ( C[1] ) ); Στο παράδειγμα αυτό φαίνεται σε πια ακριβώς πόρτα συνδέονται τα σήματα του adder4 μέσω της αντιστοίχισης.<όνομα πόρτας> (<όνομα σήματος>). Φυσικά σε κάθε περίπτωση πρέπει να προσέξετε ο τύπος της πόρτας στην οποία συνδέεται ένα εξωτερικό καλώδιο να ταιριάζει ακριβώς με τον τύπο του καλωδίου (ή ομάδας καλωδίων αντίστοιχα). Τι θα έπρεπε όμως να κάνουμε στην περίπτωση που θα θέλαμε να σχεδιάσουμε ένα 32μπιτο αθροιστή; Η επαναχρησιμοποίηση 32 πλήρων αθροιστών (fulladder) θα απαιτούσε τη δήλωση 32 υποκυκλώμάτων και τη σύνδεση 5x32 συνολικά καλωδίων, παρόλο που η συνδεσμολογία σε κάθε υποκυκλωμα ακολουθεί μια επαναληπτική δομή. Για να δείτε τη δομή των επαναλήψεων αρκεί να παρατηρήσετε τις συνδέσεις στα υποκυκλώματα b1 και b2 του adder4. O fulladder που βρίσκεται στη θέση i συνδέεται πάντα με τα καλώδια Α[i], Β[i], C[i] ενώ παράγει στην έξοδο του τα καλώδια S[i] και C[i+1] το οποίο θα χρησιμοποιηθεί ως είσοδος από το fulladder της επόμενης θέσης. Επομένως θα μας ήταν πολύ βολικό αν στη SystemVerilog 9

υπήρχε κάποιος τρόπος να δηλώναμε όσα υποκυκλώματα επιθυμούσαμε με έναν επαναληπτικό τρόπο χωρίς να χρειάζεται να δηλώνουμε το καθένα χωριστά. Ευτυχώς ο τρόπος αυτός υπάρχει και ονομάζεται επαναλήψεις γέννησης υποκυκλωμάτων (generate for loops). H δημιουργία του ίδιου αθροιστή των 4 δυαδικών ψηφίων μέσω τέτοιων επαναλήψεων φαίνεται στο παράδειγμα που ακολουθεί. module adder4 ( input logic [3:0] A, input logic [3:0] B, input logic Ci, output logic [3:0] S, output logic Cout); -- internal carry signals logic [4:0] C; assign C[0] = Ci; generate genvar i; for (i=0; i < 4; i=i+1) begin : fa fulladder b (A[i],B[i],C[i],S[i],C[i+1]); end endgenerate assign Co = C[4]; Η δήλωση των υποκυκλωμάτων περιέχεται μέσα σε μια επαναληπτική δομή τύπου for generate στην οποία είμαστε υποχρεωμένοι να δώσουμε ένα όνομα επανάληψης και να ορίσουμε μια μεταβλητή επανάληψης (genvar). Τη μεταβλητή δεν απαιτείται να την έχουμε δηλώσει κάπου πιο πριν. Αυτό που πρέπει να προσέξουμε είναι τα όρια των επαναλήψεων να είναι στατικά ορισμένα και να μην εξαρτώνται από τις τιμές άλλων σημάτων του κυκλώματος μας. Μην ξεχνάτε ότι ο ρόλος των επαναλήψεων for generate δεν είναι η υλοποίηση των επαναλήψεων ενός αλγορίθμου αλλά η εύκολη δημιουργία ενός συγκεκριμένου αριθμού υποκυκλωμάτων των οποίων το πλήθος και τον τρόπο που συνδέονται τον γνωρίζουμε εξαρχής. Τέλος παρατηρήστε πως στη δήλωση των υποκυκλωμάτων fulladder μέσα στην επανάληψη τύπου for generate χρησιμοποιήσαμε το ίδιο όνομα b. Αυτό δε μας ενοχλεί καθώς το εργαλείο λογικής σύνθεσης θα αντιληφθεί την επαναληπτική διαδικασία και θα δώσει ένα διαφορετικό όνομα σε κάθε υποκύκλωμα (πχ b_0, b_1, ανάλογα με την τιμή του δείκτη της επανάληψης που τα γέννησε). Διαπιστώνοντας τη χρησιμότητα αυτής της επαναληπτικής δήλωσης των υποκυκλωμάτων έρχεται στο νου μας η εξής επιθυμητή ιδιότητα για τις περιγραφές των κυκλωμάτων μας σε SystemVerillog. Πως θα μπορούσαμε να είχαμε περιγράψει σε SystemVerilog μόνο έναν αθροιστή και αλλάζοντας απλά την τιμή μιας μεταβλητής να μπορούσαμε να έχουμε στη διάθεση μας κατά περίπτωση ένα αθροιστή των 4 bits είτε ένα των 32 bits χωρίς να αλλάξουμε ξανά τον κώδικα μας. Κάτι τέτοιο μπορεί να γίνει μέσω της δήλωσης των παραμετρικών μεταβλητών για το κύκλωμα μας όπως φαίνεται από την περιγραφή ενός αθροιστή των N δυαδικών ψηφίων ο οποίος εσωτερικά αποτελείται από Ν πλήρεις αθροιστές (fulladder). module adder #( parameter N = 10 )( input logic [N-1:0] A, input logic [N-1:0] B, input logic Ci, output logic [N-1:0] S, output logic Cout); -- internal carry signals logic [Ν-1:0] C; generate genvar i; for (i=0; i < N; i=i+1) begin : fa 10

fulladder b (A[i],B[i],C[i],S[i],C[i+1]); end endgenerate Στο παράδειγμα αυτό το μόνο που προσθέσαμε στον κώδικα μας και μας επέτρεψε να γενικεύσουμε τη λειτουργία του κυκλώματος μας είναι η δήλωση #(parameter N=10) μεταξύ της δήλωσης του module και της λίστας των εισόδων και εξόδων του. Η μεταβλητή Ν, της οποίας την τιμή δεν επιτρέπεται να αλλάξουμε, είναι ένας σταθερός ακέραιος αριθμός, με βασική τιμή το 10, και περιγράφει το πλήθος των δυαδικών ψηφίων του αθροιστή. Έτσι μπορούμε να τη χρησιμοποιήσουμε για να θέσουμε τα όρια για όλα τα σήματα εισόδου και εξόδου του adder, για τα εσωτερικά καλώδια του καθώς και για τα όρια της επανάληψης for generate. Έτσι δηλώνοντας τα όρια των σημάτων μας συναρτήσει του Ν και αποφεύγοντας τη χρήση σταθερών ορίων, όπως logic [3:0] μπορούμε να περιγράψουμε αυθαίρετα μικρά ή μεγάλα κυκλώματα τα οποία ακολουθούν πάντα την ίδια δομή. Πως όμως θα χρησιμοποιούσαμε ως υποκύκλωμα την περιγραφή του παραμετροποιημένου adder; Με άλλα λόγια πως μπορώ να αναθέσω μια τιμή στην παράμετρο N του adder ανάλογα με την εφαρμογή που θέλω να τον χρησιμοποιήσω. Ας πάρουμε ως παράδειγμα τη σχεδίαση ενός κυκλώματος πρόσθεση και αφαίρεσης των 32 δυαδικών ψηφίων. Το κύκλωμα αυτό δέχεται ως είσοδο δύο αριθμούς Α και Β. Όταν operation==1 τότε το κύκλωμα τους προσθέτει δίνοντας στην έξοδο S το Α+Β, ενώ όταν οperation==0 τους αφαιρεί δίνοντας στην έξοδο το Α-Β. Για την εκτέλεση της αφαίρεσης η πράξη που εκτελεί είναι η Α + Bb+1. Το κύκλωμα πρόσθεση/αφαίρεσης χτίζεται γύρω το γενικό κύκλωμα αθροιστή (adder) που μόλις περιγράψαμε το οποίο ουσιαστικά εκτελεί την πράξη A + (operation xor Β) + οperation. Όπου το σήμα operation τοποθετείται ως κρατούμενο εισόδου στον αθροιστή adder. module addersubstractor ( input logic [31:0] A, input logic [31:0] B, input logic Ci, inputu logic op, output logic [31:0] sum, output logic Cout); adder #(32) addx (.A(A),.B(B),.S(sum),.Co(Cout),.Ci(Ci),.operation(op)); Για να μπορέσουμε να επαναχρησιμοποιήσουμε τον adder στο νέο κύκλωμα addersubtractor απλά δηλώνουμε τον adder ως ένα υποκύκλωμα με το όνομα addx. Τώρα μαζί με τη λίστα αντιστοίχισης των εισόδων/εξόδων είμαστε υποχρεωμένοι να συμπεριλάβουμε και μία τιμή για την παράμετρο N, #(32),μεταξύ του ονομάτος του module και του ονόματος του instance. Ετσι έμμεσα αναθέτουμε στην εσωτερική παράμετρο Ν του adder την τιμή 32. H αρχική τιμή 10 που δώσαμε στο N μέσα στο κύκλωμα του adder αγνοείται και αντικαθίσταται από τη νέα τιμή 32. Η αρχική τιμή θα έπαιζε ρόλο μόνο αν ξεχνούσαμε να δηλώσουμε μια τιμή στο Ν κατά την αντιστοίχιση των παραμέτρων. 11