Archiv für die Kategorie „Studiumsblog“

Webtipp: PATRICIA-Trie

Mittwoch, 7. Juli 2010

Schöne Einführung in den Aufbau und die Funktionsweise eines PATRICIA-Trie (oder Baum) findet man hier: http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Tree/PATRICIA/

Lokale Kopie:

PATRICIA -
Practical Algorithm to Retrieve Information Coded in Alphanumeric,
D.R.Morrison (1968).

A PATRICIA tree is related to a
Trie.
The problem with Tries is that when the set of keys is sparse,
i.e. when the actual keys form a small subset of the set of potential keys,
as is very often the case,
many (most) of the internal nodes in the Trie have only one descendant.
This causes the Trie to have a high space-complexity.

A Trie uses every part (bit, character, …) of the key,
in turn, to determine which subtree to select.
A PATRICIA tree instead nominates (by storing its position in the node)
which element of the key will next be used to determine the branching.
This removes the need for any nodes with just one descendant:

PATRICIA’s index differs from Fredkin’s Binary Trie structure in that the
index records only true [i.e. genuine] branches;
where a phrase has only
one proper right extension, it is not recorded in the index.
This fact reduces the number of index rows to only twice the number
of starts, amd makes it independent of the length of the stored phrases.

- Morrison 1968 pp520.


It is easiest to create a PATRICIA tree for
keys (strings) over an alphabet of size two: {a,b}, or {0,1}.
However, strings over an alphabet of more than two elements,
e.g. ascii, can be treated as strings over an alphabet of two
by taking the bits within each character of the larger alphabet.

The following example shows the growth of a PATRICIA tree
under a sequence of insertions:

 

12345 — number character positions
insert ababb — the key


—-> ababb


insert ababa;
search ends at ababb~=ababa;
1st difference is at position 5, so…


—-> [5] — i.e. test position #5
. .
a. . b
. .
ababa ababb


insert ba;
has no position #5;
can skip key positions but must test in order, so…


——–> [1]
. .
. .
. .
[5] ba
. .
. .
. .
ababa ababb


insert aaabba;
search ends at ababb~=aaabba;
can skip key positions but must test in order, so…


——–> [1]
. .
. .
. .
[2] ba
. .
. .
. .
aaabba [5]
. .
. .
. .
ababa ababb


insert ab;
ab is also a prefix of ababa and ababb;
must have ability to terminate at
an intermediate node, as with Tries.


——-> [1]
. .
. .
. .
[2] ba
. .
. .
. .
aaabba [3]—>ab
.
.
.
[5]
. .
. .
. .
ababa ababb

Dealing with a key, such as `ab’, which is the prefix
of another key, e.g. `ababa’,
can be handled in various ways. An actual, or notional,
terminating character, often denoted `$’ (or `\0′ in C and its relatives)
can be considered to be
a third character in the alphabet,
but only allowed to occur at the ends of keys.
This slight complication does not arise
in the special case that all keys have the same length.

PDF    Sende Artikel als PDF an

Website zum Berechnen von Wahrheitstabellen und Umwandeln in Normalformeln etc.

Montag, 28. Juni 2010

Webtipp: Sehr hilfreiche Seite zum Thema Boolsche Algebra, Wahrheitstabelle, Normalformeln etc.
http://logik.phl.univie.ac.at/~chris/gateway/formular-zentral.html

PDF erstellen    Sende Artikel als PDF an

Graphentheorie: Preorder, Inorder, Postorder

Freitag, 4. Juni 2010

Ausgangsgraph:

Preorder:

Inorder:

Postorder:

PDF erstellen    Sende Artikel als PDF an

Grundbegriffe der Graphentheorie

Donnerstag, 13. Mai 2010

Ein Graph wird definiert durch G=\{V, E\} wobei V die Menge der Knoten (vertexes) und E die Menge der Kanten (edges) ist.

  • Induzierter Teilgraph
    Ein Teilgraph, bei dem beliebige Knoten mit allen zugehörigen Kanten entfernt wurden. Allerdings bleiben alle Kanten zwischen Knoten erhalten, bei denen beide Knoten auch im Teilgraph enthalten sind!
  • azyklischen Graphen
    Ein Graph ist azyklisch, wenn er gerichtet ist, und keine Zyklen enthält.
  • Knoten- und Kantenendlichkeit
    knotenendlich: |V| < \infty
    kantenendlich: |E| < \infty
    -> Jeder knotenendliche Graph ist auch kantenendlich!
    -> Nicht jeder kantenendliche Graph ist auch knotenendlich!
  • Adjazenz
    Zwei Knoten heißen adjazent, wenn sie durch eine Kante verbunden sind.
  • schlichte oder einfache Graphen
    Graphen ohne Mehrfachkanten oder Schlingen.
  • Vorgänger und Nachfolger von Knoten
    Sei v_3 ein Knoten zu den Kanten von v_1, v_2 führen und Kanten zu dem Knoten v_4 abgehen.
    Sind die Vorgänger (precessor) von P(v_3) = \{v_1, v_2\} und
    der Nachfolger (successor) S(v_3) = \{v_4\}
  • Grad eines Knoten
    Der Grad eines Knoten ist die Anzahl der Kanten die diesen Knoten berühren, also sowohl ankommende als auch abgehende Kanten. Der Grad wird mit d angegeben.
    Bsp: Ein Knoten mit einer ankommenden und zwei abgehenden Kanten hat Grad d=3.
    Will man nur die Anzahl der ankommenden bzw. abgehenden Kanten wissen, so schreibt man d^- für ankommende, bzw. d^+ für abgehende. So hätte der Knoten aus dem Beispiel d^-=1 und d^+=2.
  • Regulärer Graph
    Alle Knoten haben den selben Grad.
  • Vollständiger Graph
    Jeder Knoten ist mit jedem verbunden.
  • Clique
    Ist ein Teilgraph, der (maximal) vollständig ist.
  • isomorphe Graphen
    Wenn zwei Graphen isomorph sind, so kann man jedem Knoten aus Graph 1 einen identischen Knoten in Graph 2 zuordnen. Das heißt insbesondere dass beide Graphen die selbe Anzahl von Knoten und Kanten und die selbe Anzahl von Knoten mit bestimmten Grad haben.
  • Wald und Baum
    Ein Wald ist ein ungerichteter azyklischer Graph der nicht zusammenhängend sein muss. Ist er indes zusammenhängend, so spricht man von einem Baum.
  • Planarer Graph
    In diesem Graph gibt es keine sich über kreuzenden Kanten. Siehe http://www.planarity.net/
  • (Minimaler) Spannbaum
    Ein Spannbaum ist ein Teilgraph eines Graphen bei dem alle Knoten verbunden sind, aber mit minimaler Kantenanzahl. Bei einem minimalem Spannbaum wird auch noch die Gewichtung der Kanten beachtet so dass das Gesamtgewicht minimal ist.

    von Wikipedia

  • Eulerkreis und Eulersche Linie
    Ein Eulerkreis ist ein Zyklus in einem Graphen der jede Kante genau einmal enthält. Dabei muss der Startknoten auch der Endknoten sein, deshalb auch Kreis. Bei der Eulerschen Linie ist der Startknoten ungleich dem Endknoten.
  • Hamiltonkreis
    Ist ein Weg in einem Graphen in dem jeder Knoten genau einmal enthalten ist.
PDF Drucker    Sende Artikel als PDF an

Scheme: Funktion mit internem privatem Attribut (private Variable)

Sonntag, 21. März 2010

Mit folgender Anweisung definiert man eine simple Zählfunktion in Scheme von der man beliebig viele unabhänge Zähler parallel erstellen kann.

(define (counter init)
  (local
    ((define i (- init 1)))
    (lambda ()
      (begin
        (set! i (+ i 1))
        i
      )
    )
  )
)

Wie man sieht definiert man zuerst eine Funktion namens counter die einen Parameter erwartet. Die Funktion hat intern eine lokale Variable die zu beginn auf den übergebenen Wert (vermindert um 1) gesetzt wird. Schließlich gibt die Funktion eine neue Funktion zurück die mit der eben erstellen lokalen Variable zählt. Diese interne private Variable kommt einem privaten Attribut einer Klasse einer modernen Programmiersprache nahe.
Somit ergeben folgende Anweisungen:

(define c1 (counter 0))
(define c2 (counter 1100))
(c1)
(c2)
(c2)
(c1)
(c1)
(c1)
(c2)
0
1100
1101
1
2
3
1102
PDF    Sende Artikel als PDF an

Kultspiel Plumber (Java, Open Source)

Sonntag, 21. März 2010

Dieses Spiel ist das Ergebnis eines zweiwöchigen Uni Praktikums. Es waren daran 4 Personen ca. 3h täglich beteiligt. Das Spiel ist komplett in Java geschrieben, die benötigten Librarys sind in den jeweiligen Downloads enthalten. Um das Spiel zu starten benutzen Sie bitte die plumber.bat unter Windows und die plumber.sh unter Unix.

Spiel:
plumber.tar.gz
plumber.zip

Source (mit Librarys und Dokumentation):
plumber-src.tar.gz

PDF erstellen    Sende Artikel als PDF an

Quicksort in Scheme

Mittwoch, 17. März 2010
(define (my-quicksort l)
  (if (empty? l)
      empty
      (append
       (my-quicksort (filter (lambda (x) (<= x (first l))) (rest l)))
       (list (first l))
       (my-quicksort (filter (lambda (x) (> x (first l))) (rest l)))
      )
  )
)

Aufruf z.B. mit

(my-quicksort '(8 7 5 -4 2 22 9 4 -4 4 11 1 0))

produziert

(list -4 -4 0 1 2 4 4 5 7 8 9 11 22)
PDF Drucker    Sende Artikel als PDF an

Berechnung der Determinante einer NxN Matrix in MIPS Assembler

Samstag, 6. Februar 2010

Dieser Assemblercode kann die Determinante einer NxN Matrix berechnen. Dabei wird die NxN-Matrix mit Hilfe des Laplaceschen Entwicklungssatzes in N N-1xN-1-Matrixen zerlegt (eine 4×4-Matrix wird in 4 3×4-Matrixen zerlegt, usw).

Das Programm funktioniert leider nicht für “große” Matrixen (z.B. 10×10), weil das Programm dann aus dem Heap raus schreibt. Aber für Matrixen bis 5×5 funktioniert es definitiv, eventuell auch für Größere, das habe ich aber nicht getestet.

.data

dim:
#.word 2
#.word 3
#.word 4
.word 5
#.word 10

matrix:
#2x2-Martrix; solution = -2
#.word 3, 4, 5, 6
#3x3-Matrixx; solution = 4
#.word 3, 4, 5, 9, 4, 9, 1, 2, 2
#4x4-Matrix; solution = -19
#.word 3, 4, 5, 9, 4, 9, 1, 2, 2, 1, 3, 5, 7, 9, 3, 5
#solution = 0
.word 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25
#.word -2, 1, 1, -2, -1, -1, -1, 3, -2, -3, 0, -1, -1, -4, -5, -5, 3, 2, -4, 1, 1, 1, 0, 3, 2, 0, 3, 3, 2, 0, 2, -3, 0, -1, 4, -1, -2, -3, 0, -1, 2, -3, -3, -5, -3, -5, -3, -1, -5, 3, 0, -5, 0, -5, -5, -1,  2,  1, -4, -1, -5, -4,  1,  1, -4,  2,  3,  4, -3, -1, 1, -2,  0, -3,  1, -5,  4,  3, -1, -4, -5,  2, -5, -2, -3, -3,  3, -2,  1, -3, 1, -1, -3,  2,  0, -5,  3,  2,  3, -5

det:    .asciiz "Die Determinante ist: "
###############################################################################

.text

main:
###################################
###################################
#Hier soll das Programm stehen
#Das Ergebnis muss am Ende in $s6 stehen.

    addi    $s7, $0, 0x10040000 # initialize default heap pointer
 
    la      $a0, matrix
    lw      $a1, dim
    jal     calcDet
    addi    $s6, $v0, 0

    j       ende

###################################
# Calculates the determinante of a NxN matrix.
# expects:  adress of array with N^2 elements in $a0
#           dimension of matrix in $a1
# returns det. of given matrix in $v0
###################################
# Documentation
# $a0   -> matrix
# $a1   -> dim
# ----------------
# $s0   -> sum of det. of matrixes
calcDet:
    # if
    slti    $t0, $a1, 2         # if $a1(=dim) < 2
    beq     $0, $t0, calcDetIf  # jump to the if part
                                # if $t0 == $t1(=1) or
                                # if 2 < dim
    # else
    lw      $v0, 0($a0)
    jr      $ra                 # jump back to caller

calcDetIf:                      # The if part
    # reduce maxtrix and call recursive for each
    # reduced matrix
    addi    $sp, $sp, -4        # get some space on stack
    sw      $ra, 0($sp)         # store return adress in stack
   
    addi    $s0, $0, 0          # initialize $s0 (sum) with 0
    addi    $t0, $0, 0          # initialize $t0 (i) with 0
   
calcDetLoop:                    # loop over all sub-matrixes
    beq     $t0, $a1, calcDetLoopDone
                                # while $t0(=i) != $a1(=dim)

    addi    $sp, $sp, -16       # get some space on stack
    sw      $s0, 0($sp)         # store sum
    sw      $t0, 4($sp)         # store $t0 (i)
    sw      $a0, 8($sp)         # store $a0
    sw      $a1, 12($sp)        # store $a1

                                # dont need to copy any adress
                                # in $a0 because its already there
                                # dont need to copy any dimension
                                # of matrix in $a1 because its already there
    addi    $a2, $t0, 0         # copy i into $a2
    jal     reduceMatrix        # jump to reduceMatrix
   
    addi    $a0, $v0, 0         # copy result adress of reduceMatrix
                                # into argument register for recursive call
    sub     $a1, $a1, 1         # $a1 = dim - 1
    jal     calcDet             # call myself recursively
   
    lw      $a1, 12($sp)        # load $a1
    lw      $a0, 8($sp)         # load $a0
    lw      $t0, 4($sp)         # load $t0 (i)
    lw      $s0, 0($sp)         # load sum
    addi    $sp, $sp, 16        # clean up the stack

    addi    $t2, $0, 1          # initialise pow(er) with 1
    and     $t1, $t0, 1         # $t1 = $t0 & 0x00000001
    beq     $t1, $0, calcDetLoopJump
                                # skip one line, if $t0 % 2 = 1
    addi    $t2, $0, -1         # set power to -1
calcDetLoopJump:               

    addi    $t1, $0, 4          # $t1 = 4 (because one word = 4 bytes)
    mult    $t0, $t1            # i * $t1(=4)
    mflo    $t3                 # get result in $t3
    add     $t3, $a0, $t3       # add calulated offset to start adress of matrix
    lw      $t3, 0($t3)         # load value at calulated adress

    mult    $t2, $t3            # power * (i-th element in matrx (always in first row))
    mflo    $t4                 # get result in $t4
    mult    $t4, $v0            # multiply calcDet-result with calculated stuff
    mflo    $t4                 # get result in $t4
    add     $s0, $s0, $t4       # add to sum

    addi    $t0, $t0, 1         # $t0++ or i++

    j       calcDetLoop


calcDetLoopDone:                # loop finished, calculated all matrixes
    addi    $v0, $s0, 0         # copy sum into return register

    lw      $ra, 0($sp)         # load return adress from stack
    addi    $sp, $sp, 4         # get some space on stack

    jr      $ra
###################################


###################################
# Extracts _one_ (N-1) matrix from a
# NxN matrix. The argument
# $a2 says which (N-1) matrix should
# be returned.
# expects:  adress of array with N^2 elements in $a0
#           dimension of matrix in $a1
#           index of the smaller matrix (0-based) in $a2
# returns adress of (N-1) matrix in $v0
###################################
# Documentation
# $a0   -> matrix
# $a1   -> dim
# $a2   -> index of matrix that should be returned
# ----------------
# $s0   -> dim - 1
# $s1   -> counter for the current position in the SOURCE matrix
# $s2   -> counter for the current position in the TARGET matrix
reduceMatrix:
    addi    $s0, $a1, -1        # $s0 = dim - 1
    mult    $s0, $s0            # $s0*$s0 or
                                # (N-1)^2 or (dim-1)^2
                                # is also the size of the
                                # new matrix
    mflo    $t1                 # get result into $t1
                                # $t1 contains now the number of words required
    addi    $s1, $a0, 0         # copy start adress of source matrix in $s1
    addi    $s2, $s7, 0         # save current position of heap pointer in $s2
    addi    $v0, $s7, 0         # copy target array adress in return register
    addi    $t0, $0, 4          # set $t0 = 4
    mult    $t1, $t0            # multiply $t0(=4) * $t1(=(dim-1)^2)
                                # -> amount of necessary bytes
    mflo    $t0                 # copy result in $t0
    add     $s7, $s7, $t0       # get (N-1)^2 space of heap

    addi    $t0, $0, 4          # set $t0 = 4
    mult    $a1, $t0            # $a1(=dim)*$t0(=4)
                                # number of bytes that must be skipped to
                                # skip the first row of source matrix
    mflo    $t0
    add     $s1, $s1, $t0       # skip dim-elements or
                                # skip the first row of source matrix
    addi    $t0, $s0, 0         # initialize counter for loop 1; used as i
    add     $t2, $t0, $a2       # $t2 = $t0 + $a2 or
                                # $t2 = i + index
reduceMatrixLoop1:              # loop 1
    beq     $t2, $t0, reduceMatrixLoop1Done
                                # while index != i

    lw      $t1, 0($s1)         # load next entry from source matrix in $t1
    sw      $t1, 0($s2)         # store the entry in the target matrix
    addi    $s1, $s1, 4         # increase pointer $s1 = $s1 + 4
    addi    $s2, $s2, 4         # increase pointer $s2 = $s2 + 4

    addi    $t0, $t0, 1         # $t0 = $t0 + 1 or
                                # $t0++ (i++)
    j       reduceMatrixLoop1   # jump up to the beginning of the loop
reduceMatrixLoop1Done:          # endloop 1
reduceMatrixLoop2:              # loop 2
    mult    $a1, $a1
    mflo    $t1
    beq     $t0, $t1, reduceMatrixLoop2Done
                                # while i < dim^2

    addi    $s1, $s1, 4         # skip one element in SOURCE matrix
    addi    $t0, $t0, 1         # $t0 = $t0 + 1 or
                                # $t0++ or i++
   
    mult    $a1, $a1            # $a1^2 or dim^2
    mflo    $t2                 # get the result in $t2
    sub     $t2, $t2, 1         # sub 1 from $t2, because I want to compare
                                # it with $t0 (0-based) or
                                # (dim^2)-1
    sub     $t2, $t2, $t0       # $t2-$t0 or (dim^2)-1-i
    # if
    slt     $t3, $t2, $s0       # (dim^2)-1-i < dim-1 or
                                # if $t3 == 1, you reached the last
                                # row and already skipped
    beq     $t3, $0, reduceMatrixLoop2Else
                                # jumps, if (dim-1)^2 - i < dim - 1 is false
                                # in human words: if the programm
                                # is NOT in the last row of the source matrix
    # if case
    # copy the last elements of source into target and exit function! :)
    mult    $a1, $a1            # dim^2
    mflo    $t2                 # get result in $t2
reduceMatrixLoop2Loop1:
    beq     $t2, $t0, reduceMatrixLoop2Done
                                # jump if dim^2-1 == i or jump if
                                # end of source matrix is reached
   
    lw      $t1, 0($s1)         # load next entry from source matrix in $t1
    sw      $t1, 0($s2)         # store the entry in the target matrix
    addi    $s1, $s1, 4         # increase pointer $s1 = $s1 + 4
    addi    $s2, $s2, 4         # increase pointer $s2 = $s2 + 4

    addi    $t0, $t0, 1         # $t0 = $t0 + 1 or
                                # $t0++ or i++
    j       reduceMatrixLoop2Loop1
                                # jump up again, because its a loop!

    j       reduceMatrixLoop2Endif
                                # leave if case
                                # never used because if loop is finished
                                # it will jump to the end of the function

reduceMatrixLoop2Else:          # else case
    # copy dim - 1 elements
    add     $t2, $t0, $s0       # $t2 = $t0(=i) + $s0(=dim-1)
reduceMatrixLoop2ElseLoop:
    beq     $t2, $t0, reduceMatrixLoop2
                                # if $t2 = $t0 jump to main loop

    lw      $t1, 0($s1)         # load next entry from source matrix in $t1
    sw      $t1, 0($s2)         # store the entry in the target matrix
    addi    $s1, $s1, 4         # increase pointer $s1 = $s1 + 4
    addi    $s2, $s2, 4         # increase pointer $s2 = $s2 + 4
   
    addi    $t0, $t0, 1         # $t0 = $t0 + 1 or
                                # $t0++ or i++
    j       reduceMatrixLoop2ElseLoop
                                # jump up to the beginning of the loop

reduceMatrixLoop2Endif:         # endif


    addi    $t0, $t0, 1         # $t0 = $t0 + 1 or
                                # $t0++ or i++
    j       reduceMatrixLoop2   # jump up to the beginning of the loop
reduceMatrixLoop2Done:          # endloop 2
    jr      $ra                 # jump to caller function
                                # return value ($v0) is set at beginning
                                # of this function
###################################

###################################
###################################

ende:
#Ausgabe

la $a0 det
li $v0 4
syscall

move $a0, $s6
li $v0, 1
syscall

###################################
#Ende
li $v0, 10
syscall

PDF Creator    Sende Artikel als PDF an

Parallelität

Sonntag, 17. Januar 2010

Parallelität bedeutet, dass man Aufgaben oder Teilaufgaben parallel – also gleichzeitig – bearbeitet. Dabei gibt es zwei grundsätzliche Arten:

  • Räumliche Parallelität
    Bei der räumlichen Parallelität gibt es die arbeitenden Teile mehrfach, sie sind also physikalisch mehrfach vorhanden. Ein gutes Beispielt sind Multicore CPUs. Da kann auch pro Core eine Aufgabe ausgeführt werden, also mehrere parallel.
    Das Problem der räumlichen Parallelität ist, dass man nicht jede Aufgabe so aufteilen kann, dass sie parallel ausgeführt werden kann. Es kann zum Beispiel Probleme mit Abhängigkeiten geben, dass der nachfolgende Teil das Ergebnis des Vorgängers benötigt.
  • Zeitliche Parallelität (Pipelining)
    Um die zeitliche Parallelität zu verstehen, ist es sinnvoll sich mit den Zeitanforderungen an sequenzielle Schaltungen auseinanderzusetzen. Siehe dazu meinen Artikel zum Thema Timing und Glitches.

    Umso mehr Logik man in einem Takt durchlaufen will, umso mehr Zeit benötigt man (t_{pd}). Umso größer diese Zeit allerdings wird, umso kleiner wird die Taktfrequenz. Also teilt man die komplexe Logik in viele und simplere Logikblöcke auf, die nacheinander (nicht parallel!) durchlaufen werden. Da jeder dieser Blöcke das Ergebnis schnell bereit stellen kann, kann man die Taktfrequenz wieder hoch drehen. In Hardware wird dieses Verfahren auch als Pipelining bezeichnet, weil man die Logik verlegt und zwischen jeden Block ein Flipflop baut, dass das jeweilige Ergebnis bis zur nächsten Taktflanke zwischenspeichert.
    Das Problem beim Pipelining ist das man die Logikblöcke nur bis zu einem bestimmten Maß verkleinern kann. Außerdem steigt durch die zusätzlichen Flipflops die Latenz (also die Zeitspanne die benötigt wird, bis nach der Eingabe der Daten das Ergebnis bereit steht).
    Die zeitliche Parallelität kann man vergleichen mit dem Fließbandprinzip bei der Autofertigung. Um so mehr Arbeitsstationen man hat, und umso kürzer die Zeit ist, die pro Station benötigt wird, umso mehr Autos können auch produziert werden.

Durch die parallele Berechnung schafft man immer einen höheren Durchsatz (man kann also mehr Datensätze pro Zeiteinheit berechnen).

PDF erstellen    Sende Artikel als PDF an

Timing und Glitches

Sonntag, 17. Januar 2010

Jedes Bauelement benötigt einen Moment, bis es auf eine Änderung am Eingang reagiert. Natürlich sind diese Zeiten bei einzelnen Element sehr gering, aber wenn man richtige Schaltung baut, dann kann es sehr schnell zu Problemen kommen.

Schaltungen aus primitiven Elementen

Bei Schaltungen mit einfachen Bauteilen halten sich die Zeiten, die berücksichtigt werden müssen, in Grenzen. Es gibt nur 2: t_{cd} und t_{pd}. Mit t_{cd} (engl. contamination delay) gibt man die minimale Zeit an, bis die Schaltung den neuen Wert ausgibt. Mit t_{pd} (engl. propagation delay) dagegen die maximale Zeit, bis der neue Wert feststeht.
Zu beachten ist, dass es zwischen t_{cd} und t_{pd} zu mehreren Änderungen am Ausgang der Logik geben kann, auch wenn sich der Eingangswert nur ein einziges mal geändert hat. Das sind die sogenannten Glitches.

Glitches

In Logikschaltungen gibt es Pfade in denen nur wenige Elemente liegen (engl. short path), die das Ergebnis also sehr schnell berechen. Natürlich gibt es dann auch Pfade in denen viele (oder einfach mehr Elemente als in short path) liegen (engl. critical path), und deren Ergebnis erst später fertig ist. Deshalb kann es vorkommen, dass sich der Ausgang einer Logikschaltung zwischen t_{cd} und t_{pd} mehrmals ändert, bis er dann nach t_{pd} stabil das Ergebnis zeigt.
Beispiel in der Wikipedia.

Sequenzielle Logik

In sequentielle Logik sind sowohl Logikbausteine als auch Flip-Flops verbaut. Die Logikbausteine berechnen den neuen Wert, der dann am Eingang von einem Flip-Flop anliegt, das den Wert dann zur nächsten Taktflanke übernimmt. Daraufhin kann die Logik hinter einem Flip-Flop nach der Taktflanke eine neue Berechnung beginnen, da sich die Eingangswert eventuell geändert haben.
Da die Logik eine bestimme Zeit benötigt bis sie die Berechnung definitiv abgeschlossen hat, muss genügend Zeit zwischen zwei Taktflanken zur Verfügung stehen. Da man aber nicht 100%tig sagen kann wann das Flip-Flop den neuen Wert übernimmt und wann der neue Wert ausgegeben wird, brauchen wir auch einen Zeitpuffer für das Flip-Flop.
Genau gesagt, darf sich t_{setup} vor der Taktflanke bis t_{hold} nach der Taktflanke nichts mehr am Eingangssignal des Flip-Flops ändern. Nach dem das Flip-Flop den neuen Wert übernommen hat (man spricht auch von sampled), können wieder die Berechnungen durch die Logik stattfinden. Beide Zeiten werden als Abtastzeit bezeichnet, also das Zeitintervall um die Taktflanke herum in dem sich das Eingangssignal nicht ändern darf – es muss stabil sein. t_{a}=t_{setup}+t_{hold}

t_{a} ist also ein Zeitpuffer um die Taktflanke herum, falls ein Flip-Flop etwas früher oder etwas zu spät sampled.

Allerdings gibt es bei Flop-Flops noch weitere Verzögerungen die zu beachten sind: Ähnlich wie bei Logik kann es eine bestimme Zeit dauern, bis der neue Wert nach einer Taktflanke ausgegeben wird. Dazu gibt es zwei Zeiten: t_{ccq} (engl. contamination delay) gibt die minimal Zeit an, nach der der Ausgang bereits wieder aktuell sein könnte. Des weiteren sagt sie aus, wie lang nach einer Taktflanke definitiv keine Änderungen am Ausgang auftreten.
Schließlich gibt t_{pcq} (engl. propagation delay) die Zeit an, nach der der Ausgang in jedem Fall den korrekten Wert hat. Zwischen t_{ccq} und t_{pcq} könnte der Ausgang – genau wie bei Logikschaltungen – glitchen.

Taktfrequenz

Mit diesen Zeitanforderungen lässt sich bestimmen wie hoch der Takt maximal für eine Schaltung sein kann.
Wir müssen folgende Zeiten berücksichtigen:

  • t_{pcq}
    die Zeit die das Flip-Flop braucht, bis es nach einer Taktflanke den neuen Wert ausgibt
  • t_{pd}
    die Zeit die die Logik maximal braucht, bis sie den neuen Wert berechnet hat
  • t_{setup}
    die Zeit in der das Signal vor einer Taktflanke stabil sein muss

Die Zeit zwischen 2 Takten muss mindestens die Summe dieser drei Zeiten sein, also ist die Formel: T_c = t_{pcq} + t_{pd} + t_{setup}. Damit lässt sich dann auch die Taktfrequenz berechnen: f = \frac{1}{T_c}

PDF Download    Sende Artikel als PDF an