Prüfung - Institut für Kommunikationsnetze und Rechnersysteme ...
Prüfung - Institut für Kommunikationsnetze und Rechnersysteme ...
Prüfung - Institut für Kommunikationsnetze und Rechnersysteme ...
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
Universität Stuttgart<br />
INSTITUT FÜR<br />
KOMMUNIKATIONSNETZE<br />
UND RECHNERSYSTEME<br />
Prof. Dr.-Ing. Andreas Kirstädter<br />
Bachelor-/Master-<strong>Prüfung</strong><br />
Prüfer:<br />
Termin:<br />
Dauer:<br />
Verlangte Aufgaben:<br />
Zugelassene Hilfsmittel:<br />
Entwurf digitaler Systeme<br />
Kirstädter, Meyer<br />
23. Februar 2012<br />
120 Minuten<br />
alle<br />
alle<br />
Aufgabe 1<br />
Synchronisations-FIFO<br />
Bild 1 zeigt eine Anordnung, die der unidirektionalen Übertragung von Daten von einer<br />
Taktdomäne (Takt wclk) in eine andere Taktdomäne (Takt rclk) dient. Die Takte rclk <strong>und</strong> wclk<br />
weisen verschiedene Frequenzen auf <strong>und</strong> sind völlig asynchron zueinander.<br />
Zur Synchronisation der beiden Taktdomänen wird ein FIFO-Speicher verwendet (SyncFIFO),<br />
der synchron zum Takt wclk beschrieben <strong>und</strong> synchron zum Takt rclk gelesen wird, d.h. die<br />
Signale wena, wdata <strong>und</strong> full sind synchron zu wclk, die Signale rena, rdata <strong>und</strong> empty sind<br />
synchron zu rclk.<br />
Wenn während einer positiven Flanke des Taktes wclk das Signal wena aktiv ist, werden die<br />
Daten wdata in das FIFO übernommen. Dabei darf das Signal wena nur aktiv werden, wenn full<br />
inaktiv ist. Entsprechend wird ein Datum aus dem FIFO entnommen, wenn während einer<br />
positiven Flanke des Taktes rclk das Signal rena aktiv ist. Das Signal rena darf nur aktiv<br />
werden, wenn empty inaktiv ist.<br />
Hinweis: Alle Signale sind high-aktiv, d.h. ein aktives Signal hat den Wert logisch ’1’, ein<br />
inaktives Signal den Wert logisch ’0’.<br />
wclk<br />
rclk<br />
wena<br />
rena<br />
Source<br />
wdata<br />
rdata<br />
8 SyncFIFO<br />
8<br />
full<br />
empty<br />
Sink<br />
Bild 1<br />
Synchronisation zweier Taktdomänen wclk, rclk<br />
Bild 2 zeigt einen VHDL-Prozess syncfifo_process zur abstrakten Verhaltensmodellierung des<br />
Synchronisations-FIFOs. Dieser Prozess sei in eine Architecture zur Entity SyncFIFO<br />
eingebettet.
syncfifo_process: process(wclk, rclk) is<br />
constant N: natural := 5;<br />
subtype INDEX_RANGE is natural range 0 to N - 1;<br />
type fifo_t is array(INDEX_RANGE) of std_logic_vector(7 downto 0);<br />
variable fifo: fifo_t;<br />
variable rindex, windex: INDEX_RANGE;<br />
begin<br />
w_if: if wclk’event and wclk = ’1’ then<br />
if wena = ’1’ then<br />
fifo(windex) := wdata;<br />
windex := (windex + 1) mod N;<br />
end if;<br />
end if;<br />
r_if: if rclk’event and rclk = ’1’ then<br />
if rena = ’1’ then<br />
rdata
Um das Verhalten des Synchronisations-FIFOs in einer funktionalen Simulation zu überprüfen,<br />
wird in der Komponente Source (vgl. Bild 1) ein Prozess source_process realisiert. Dieser<br />
Prozess ist in Bild 3 angegeben.<br />
source_process: process is<br />
variable i: natural;<br />
begin<br />
loop<br />
wait until wclk’event and wclk = ’1’;<br />
-- Einfügemarke <strong>für</strong> Frage 4<br />
if full = ’0’ then<br />
wena
Ein zweiter Ansatz zur Lösung des Problems ist, das Signal full durch ein Signal almost_full zu<br />
ersetzen. Dieses Signal soll nicht nur bei vollem FIFO aktiv werden, sondern auch dann, wenn<br />
das FIFO nur noch einen freien Eintrag enthält.<br />
Frage 5 a) Zeichnen Sie auch <strong>für</strong> diesen Fall ein Signal-Zeit-Diagramm entsprechend<br />
Frage 3a). In diesem Diagramm soll das Signal full durch das Signal<br />
almost_full ersetzt werden.<br />
b) Zeigt Ihre Simulation "von Hand" nun das gewünschte Verhalten? Begründen<br />
Sie Ihre Antwort!<br />
c) Ergänzen Sie den Prozess syncfifo_process in Bild 2 so, dass eine Variable<br />
fill_level geeigneten Typs stets den aktuellen Füllstand des FIFOs anzeigt.<br />
Leiten Sie aus dieser Variablen das Signal almost_full ab. Gehen Sie davon<br />
aus, dass das Signal almost_full als Port von SyncFIFO deklariert ist.<br />
Es genügt, die neu hinzukommenden Code-Teile anzugeben (einschließlich<br />
Variablendeklaration) mit einem kurzen Hinweis, an welcher Stelle im<br />
ursprünglichen Prozess der Code jeweils einzufügen ist.<br />
d) Ergänzen Sie den Prozess syncfifo_process entsprechend um die Erzeugung<br />
eines Signals almost_empty, das aktiv wird, wenn das FIFO leer ist oder nur<br />
noch einen gültigen Eintrag enthält. Leiten Sie auch almost_empty aus der<br />
Variablen fill_level ab. Gehen Sie davon aus, dass das Signal almost_empty<br />
als Port von SyncFIFO deklariert ist.<br />
Frage 6 a) Geben Sie analog zum Prozess source_process in Bild 3 einen Prozess<br />
sink_process an, der in der Komponente Sink (vgl. Bild 1) realisiert werden<br />
soll. Der Prozess soll mit der steigenden Flanke des Taktes rclk immer dann<br />
einen Eintrag aus dem FIFO entfernen, wenn almost_empty inaktiv ist. Die<br />
gelesenen Daten dürfen ignoriert werden.<br />
b) Könnte der Prozess sink_process anstelle des Signals almost_empty das<br />
Signal empty auswerten? Begründen Sie Ihre Antwort.<br />
Abschließend sollen Teile einer synthetisierbaren Implementierung der Komponente SyncFIFO<br />
betrachtet werden.<br />
Frage 7<br />
Aus welchem Gr<strong>und</strong> bzw. aus welchen Gründen ist der Prozess syncfifo_process<br />
in Bild 2 nicht synthetisierbar?<br />
Frage 8 a) Welche Probleme muss man in einem synthetisierbaren Modell des FIFOs<br />
lösen, wenn der Schreibindex windex synchron zum Takt wclk <strong>und</strong> der<br />
Leseindex rindex synchron zum Takt rclk modifiziert wird? Es genügt die<br />
Beschreibung der Probleme, eine Lösung ist nicht verlangt.<br />
b) Welche Probleme muss man in einem synthetisierbaren Modell des FIFOs<br />
lösen, wenn beide Indizes (d.h. Schreibindex windex <strong>und</strong> Leseindex rindex)<br />
synchron zum gleichen Takt modifiziert werden (wahlweise wclk oder<br />
rclk)? Es genügt wieder die Beschreibung der Probleme, eine Lösung ist<br />
nicht verlangt.<br />
Aufgabe 1 Seite 4
Es soll nun eine Lösung betrachtet werden <strong>für</strong> den Fall, dass die Frequenz f r des Lesetaktes rclk<br />
mindestens ca. 2,5 mal so hoch ist wie die Frequenz f w des Schreibtaktes wclk, d.h. es gelte<br />
f r > 2.5 f w . Weiterhin sollen windex <strong>und</strong> rindex entsprechend Frage 8b) synchron zum selben<br />
Takt modifiziert werden.<br />
Frage 9 a) Sollten windex <strong>und</strong> rindex synchron zu wclk oder zu rclk modifiziert werden?<br />
Begründen Sie Ihre Antwort.<br />
b) Warum ermöglicht die Randbedingung f r > 2.5 f w eine einfache Lösung?<br />
Eine Komponente write_detector soll die Signale wclk <strong>und</strong> wena auswerten <strong>und</strong> daraus ein zum<br />
Takt rclk synchrones Signal wena_r erzeugen, das im Falle eines Schreibvorgangs genau eine<br />
Periodendauer des Taktes rclk lang aktiv ist. Somit kann wena_r in weiteren, hier nicht näher<br />
betrachteten Schaltungsteilen verwendet werden, um den Schreibindex windex synchron zu rclk<br />
zu modifizieren.<br />
Frage 10 a) Beschreiben Sie stichwortartig, wie man die Komponente write_detector<br />
realisieren könnte. VHDL-Code ist nicht verlangt.<br />
b) Warum muss bei der Implementierung der Komponente das Problem Metastabilität<br />
berücksichtigt werden?<br />
c) Welches Problem entsteht durch die Verzögerung, die durch die Synchronisation<br />
verursacht wird?<br />
d) Wie kann man dieses Problem prinzipiell lösen?<br />
Aufgabe 1 Seite 5
Aufgabe 2<br />
Write Buffer<br />
Ein Write Buffer in einem Rechnersystem dient dazu, einen schnellen Prozessor von einem<br />
langsamen Hauptspeicher zu entkoppeln. Sobald der Write Buffer die zu schreibenden Daten<br />
übernommen hat, kann der Prozessor weiterarbeiten <strong>und</strong> muss nicht warten, bis die Daten tatsächlich<br />
im Hauptspeicher angekommen sind. Weiterhin fasst ein Write Buffer Schreibzugriffe<br />
auf benachbarte Adressen zusammen, um diese dann effizient in Form sogenannter Bursts in<br />
den Hauptspeicher zu übertragen.<br />
Im Rahmen dieser Aufgabe soll ein Write Buffer <strong>für</strong> einen einfachen Prozessor mit einer<br />
Adressbreite von 16 Bit <strong>und</strong> einer Datenbreite von 8 Bit in VHDL modelliert werden. Der<br />
Hauptspeicher weise ebenfalls eine Datenbreite von 8 Bit auf <strong>und</strong> unterstütze Burst-Zugriffe der<br />
Länge 4, d.h. vier aufeinanderfolgende Bytes können in vier aufeinanderfolgenden Takten effizient<br />
in den Hauptspeicher geschrieben werden. Dabei muss ein Burst immer an einer durch 4<br />
teilbaren Adresse beginnen.<br />
Bild 1 zeigt die Schnittstelle zwischen Prozessor <strong>und</strong> Write Buffer, Bild 2 ein Signal-Zeit-Diagramm,<br />
das beispielhaft 8 Schreibzugriffe illustriert <strong>und</strong> Bild 3 den Zustand des Write-Buffers<br />
nach den in Bild 2 skizzierten Schreibzugriffen. Das illustrierte Szenario geht davon aus, dass<br />
im betrachteten Intervall kein Datum in den Hauptspeicher geschrieben werden konnte.<br />
clk<br />
res_n<br />
p_wreq<br />
Prozessor<br />
16<br />
8<br />
p_wa<br />
p_wd<br />
Write Buffer<br />
Bild 1<br />
Schnittstelle zwischen Prozessor <strong>und</strong> Write Buffer<br />
clk<br />
1 2 3 4 5 6 7 8 9<br />
p_wreq<br />
p_wa<br />
$2341 $2556 $2557 $2340<br />
$2342<br />
$----<br />
$2340<br />
$2344 $2555<br />
p_wd<br />
$FE<br />
$BA<br />
$BE<br />
$CA<br />
$AA<br />
$--<br />
$EE<br />
$DA<br />
$ED<br />
Bild 2<br />
Signal-Zeit-Diagramm <strong>für</strong> Schreibzugriffe auf den Write Buffer<br />
2344<br />
2554<br />
2340<br />
DA<br />
ED BA<br />
EE FE AA<br />
BE<br />
Bild 3<br />
Zustand des Write Buffers nach den in Bild 2 skizzierten Schreibzugriffen<br />
Aufgabe 2 Seite 6
Bild 3 zeigt, dass der Write Buffer zeilenweise organisiert ist. Dabei besteht eine Zeile aus<br />
einem sogenannten Adress-Tag <strong>und</strong> vier Datenbytes, denen jeweils ein Valid-Bit zugeordnet<br />
ist.<br />
Frage 1 a) Welche beiden Bits einer 16-Bit-Adresse werden zur Auswahl eines Bytes<br />
innerhalb einer Zeile verwendet?<br />
b) Geben Sie die Deklaration eines entsprechenden Natural-Untertyps<br />
OFFSET_RANGE an.<br />
c) Wozu ist der Adress-Tag erforderlich?<br />
d) Welche Bits einer 16-Bit-Adresse werden <strong>für</strong> den Adress-Tag verwendet?<br />
e) Geben Sie die Deklaration eines entsprechenden Natural-Untertyps<br />
TAG_RANGE an.<br />
f) Wozu sind die Valid-Bits erforderlich?<br />
Frage 2 a) Deklarieren Sie zur Modellierung eines Adress-Tags einen Typ tag_type als<br />
Untertyp von std_logic_vector. Verwenden Sie dazu den Typ TAG_RANGE.<br />
b) Deklarieren Sie einen Typ vbyte_type zur Modellierung eines Datenbytes<br />
einschließlich Valid-Bit. Modellieren Sie dabei das Byte als Untertyp von<br />
std_logic_vector <strong>und</strong> das Valid-Bit als boolean.<br />
c) Deklarieren Sie einen Typ vbyte_array_type zur Modellierung einer Zeile<br />
ohne Adress-Tag.<br />
d) Deklarieren Sie einen Typ line_type zur Modellierung einer vollständigen<br />
Zeile.<br />
e) Deklarieren Sie eine Konstante CAPACITY geeigneten Typs mit dem Wert<br />
16. Deklarieren Sie danach einen Typ buffer_mem_type zur Modellierung<br />
der Speichermatrix eines Write-Buffers mit CAPACITY Zeilen sowie ein<br />
Signal buffer_mem mit diesem Typ.<br />
f) Geben Sie eine Anweisung an, die Bit 0 im Byte 2 der Zeile 5 von<br />
buffer_mem auf ’1’ setzt.<br />
Frage 3 a) Zu welchen Taktzeitpunkten (vgl. Bild 2) wird im Write Buffer eine Zeile<br />
hinzugefügt?<br />
b) Zu welchen Taktzeitpunkten erfolgt ein sogenanntes Write Merge, d.h. zu<br />
welchen Taktzeitpunkten wird im Write Buffer eine bereits bestehende<br />
Zeile ergänzt?<br />
c) Zu welchen Taktzeitpunkten erfolgt ein sogenanntes Update, d.h. zu welchen<br />
Taktzeitpunkten wird im Write Buffer ein Byte durch ein aktuelleres<br />
Byte überschrieben?<br />
Aufgabe 2 Seite 7
Im Folgenden sollen Teile einer Architecture zur Modellierung des Write Buffers in VHDL entwickelt<br />
werden. Bild 4 zeigt die Struktur des Write Buffers in Form zweier miteinander kommunizierender<br />
Prozesse Process S <strong>und</strong> Process B.<br />
clk<br />
res_n<br />
p_wreq<br />
p_wa<br />
p_wd<br />
16<br />
8<br />
Process B<br />
buffer_mem<br />
Process S<br />
hit<br />
hit_index<br />
remove<br />
Bild 4<br />
Interne Struktur eines Teils des Write Buffers<br />
Die Entity des Write Buffers mit den in Bild 1 dargestellten Ports sei gegeben. Gehen Sie davon<br />
aus, dass die Deklarationen aus Frage 1 <strong>und</strong> Frage 2 sowie die Deklarationen aller in Bild 4 dargestellten<br />
Signale im Deklarationsteil der Architecture bereits enthalten sind. Gehen Sie weiter<br />
davon aus, dass die in Bild 4 dargestellten Ports vom Typ std_logic bzw. vom Typ<br />
std_logic_vector sind.<br />
Frage 4 a) Implementieren Sie eine Funktion is_valid, die <strong>für</strong> eine als Parameter übergebene<br />
Zeile vom Typ line_type nur dann TRUE zurückgibt, wenn mindestens<br />
ein Byte gültig ist.<br />
b) Kann die Funktion is_valid als pure function deklariert werden? Begründen<br />
Sie Ihre Antwort.<br />
c) Eine Prozedur invalidate soll alle Valid-Bits einer Zeile auf FALSE setzen.<br />
Der Index der Zeile innerhalb des Write Buffers werde der Prozedur als<br />
Parameter übergeben. Wo muss diese Prozedur deklariert werden, damit das<br />
Signal buffer_mem nicht als Parameter übergeben werden muss?<br />
d) Implementieren Sie die Prozedur invalidate.<br />
Der Pufferspeicher wird in Form eines Ringpuffers verwaltet. Eine Variable rindex verweise<br />
auf die älteste Zeile, die Variable windex auf die der jüngsten Zeile folgende Zeile, d.h. auf die<br />
erste freie Zeile. Beim Entfernen einer Zeile muss demzufolge rindex erhöht werden, beim Hinzufügen<br />
einer Zeile entsprechend windex. Beachten Sie, dass die Operationen auf windex <strong>und</strong><br />
rindex "modulo CAPACITY" erfolgen müssen. Eine boolesche Variable empty zeige an, ob der<br />
Write Buffer leer ist. Der Einfachheit halber sollen Schreibversuche bei vollem Write Buffer<br />
keine Auswirkung auf seinen Inhalt haben.<br />
Aufgabe 2 Seite 8
Frage 5 a) Warum ist die Variable empty neben den Variablen windex <strong>und</strong> rindex erforderlich,<br />
wenn es möglich sein soll, alle Zeilen des Write Buffers gleichzeitig<br />
zu nutzen?<br />
b) Beginnen Sie damit, Process B (vgl. Bild 4) zu implementieren. Betrachten<br />
Sie dabei zunächst Schreibzugriffe. Gehen Sie weiter davon aus, dass ein<br />
Schreibzugriff eine neue Zeile erfordert, d.h. schließen Sie die Fälle Write<br />
Merge <strong>und</strong> Update (vgl. Frage 3) vorerst aus.<br />
Hinweis: Beachten Sie dabei, dass Sie die Variable empty sowohl auswerten<br />
als auch ggf. ändern müssen.<br />
c) Ergänzen Sie Process B um Lesezugriffe. Ein Lesezugriff entferne die älteste<br />
Zeile aus dem Write Buffer <strong>und</strong> erfolge immer dann, wenn zur steigenden<br />
Taktflanke das Signal remove (vgl. Bild 4) aktiv ist.<br />
Hinweis: Die Weiterverarbeitung der gelesenen Daten werde im Rahmen<br />
dieser Aufgabe nicht betrachtet.<br />
Um bei einem Schreibzugriff die Fälle Write Merge <strong>und</strong> Update zu erkennen, muss geprüft werden,<br />
ob der Write Buffer zu ergänzende oder zu aktualisierende Einträge enthält. Dazu diene<br />
Process S.<br />
Frage 6<br />
Frage 7<br />
Implementieren Sie Process S vollständig. Nutzen Sie die Signale hit <strong>und</strong><br />
hit_index (vgl. Bild 4) mit jeweils geeignetem Typ, um Process B vom Ergebnis<br />
der Überprüfung zu informieren.<br />
Ergänzen Sie Process B nun um die Fälle Write Merge <strong>und</strong> Update.<br />
Aufgabe 2 Seite 9