Archiv für die Kategorie „TGdI“

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

Sende Artikel als PDF an PDF Drucker

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).

Sende Artikel als PDF an PDF erstellen

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}

Sende Artikel als PDF an PDF Creator

Tri-State-Logik

Donnerstag, 12. November 2009
von Wikipedia Commons

von Wikipedia Commons

Ein Tri-State ist ein spezielles Bauelement, das dem Multiplexer sehr ähnlich ist. Es hat allerdings noch ganz besondere Eigenschaften. Ein Tri-State kann – genau wie ein Muxltiplexer – einen Eingang auf den Ausgang legen oder auch nicht. Der Tri-State hat dabei allerdings nur einen Eingang und nicht wie der Mux beliebig viele. Des weiteren gibt es auch einen Selecteingang, mit dem man auswählen kann, ob der Tri-State den Eingang durch schalten soll oder nicht. Wenn der Ausgang Tri-State deaktiviert ist, wird auf dem Ausgang weder der Wert 0 (LOW) noch 1 (HIGH) ausgegeben, sondern der spezielle Wert Z. Z steht auch für hochohmig.
Der Vorteil von Tri-States ist, dass mehrere parallel geschalten sein können ohne das es einen Kurzschluss gibt. Mit dem Select-Signal kann man auswählen welches Eingangssignal durch geleitet wird. Würde man mehrere Multiplexer parallel schalten so gibt es die Möglichkeit das es einen Kurzschluss gibt, weil jeder Mux entweder 0 oder 1 ausgibt.

Sende Artikel als PDF an PDF Download

Multiplexer

Dienstag, 10. November 2009
von Wikipedia Commons

von Wikipedia Commons

Multiplexer (oder kurz Mux) wählen als Ausgangssignal das aktuelle Signal auf einem der Eingänge in Abhängigkeit des Wertes am Selecteingang/an den Selecteingängen.
Es gibt also an einem Mux mehrere EIngangstypen: Den Selecteingang und den “normalen” Dateneingang. Der Multiplexer macht nichts anderes als das Signal eines Dateneinganges auszugeben. Welcher Eingang dazu benutzt wird, wird durch den Selecteingang ausgewählt.

Ein einfaches Beispiel: 2:1 Mux
Nehmen wir einen Multiplexer mit 2 Dateneingängen an. Da wir nur 2 Dateneingänge haben, reicht 1 Selecteingang.

D0 D1 S Y
0 0 0 0
0 0 1 0
0 1 0 0
0 1 1 1
1 0 0 1
1 0 1 0
1 1 0 1
1 1 1 1

Man sieht also, das der Multiplexer einfach nur die Leitung von Eingang zum Ausgang durch schaltet, wobei man den Eingang mit dem Selector wählen kann.

Vereinfacht bedeutet das:

D0 D1 S Y
X X 0 D0
X X 1 D1

Logik mit Multiplexern

Man kann Multiplexer auch als logische Bausteine benutzen. Gehen wir zum Beispiel von einem 4:2 Mux aus, den wir als AND nutzen wollen. Dazu schließen wir an die Eingänge 0 – 2 LOW (also 0) an und an den Eingang 3 HIGH (also 1). Der Mux schaltet den HIGH Wert nur auf den Ausgang durch, wenn beide Selecteingänge 1. Andernfalls ist der Ausgang 0.

Sende Artikel als PDF an PDF Download

Boolsche Begriffe

Donnerstag, 5. November 2009
  • Komplement
    Eine invertierte (negierte) boolsche Variable (wird dargestellt als die Variable mit einen waagerechten Balken).
  • Literal
    Eine beliebige boolsche Variable (auch Komplemente).
  • Implikant
    Das Produkt von Literalen (also mit AND Verknüpfte Literale).
  • Primimplikant
    Primimplikanten sind die kürzest möglichen Konjunktionsterme. Sie sind in einen Karnaugh-Veitch-Diagramm dargestellt als die größt möglichen Bereiche.
    aus http://de.wikipedia.org/wiki/Karnaugh-Veitch-Diagramm

    aus http://de.wikipedia.org/wiki/Karnaugh-Veitch-Diagramm

  • Minterm
    Das Produkt (AND) von allen Eingangsvariablen.
  • Maxterm
    Die Summe (OR) von allen Eingangsvariablen.
Sende Artikel als PDF an PDF Drucker

Schaltungen

Donnerstag, 5. November 2009

Eine Schaltung besteht mindestens aus Eingängen, Ausgängen, einer Spezifikation der Funktion sowie des Zeitverhaltens – also was die Schaltung macht, und wie lang sie dafür benötigt. Dabei kann man sich eine Schaltung wie eine Black-Box vorstellen. Es interessiert nicht, wie sie das tut was sie tun soll, solange sie es in der spezifizierten Art und Weise tut. Das ist ein wichtiger Grundsatz der Abstraktion (Beherrschung von Komplexität). Eine Schaltung kann intern aus weiteren Schaltungen bestehen, für die natürlich genau das gleiche gilt.

Dabei gibt es zwei grundlegende Arten von Schaltungen:

  • Kombinatorische Logik
    Der Zustand der Ausgänge hängt nur vom Zustand der Eingänge ab. Es ist also jeder Ausgangswert reproduzierbar, wenn man den gleichen Eingangswert erneut anlegt.
  • Sequentielle Logik
    Hier hängt der Zustand der Ausgänge nicht nur von den Eingängen ab, sondern auch von den vorherigen Zuständen. Die sequentielle Logik kann also Zustände speichern und bei späteren Berechnungen einbeziehen.

Dabei gibt es eine Reihe von Regeln, wie Schaltungen verknüpft werden dürfen:

  • Jedes Element der Schaltung muss kombinatorisch sein.
  • Jeder Verbindungsknoten ist ein Eingang in eine Schaltung oder an genau einem Ausgangsterminal angeschlossen. (Folie 6)
  • Die Schaltung enthält keine Zyklen, d.h. ein Ausgang einer Schaltung darf nicht gleichzeitig auch ein Eingang der gleichen Schaltung sein.

Die Folien von Prof. Andreas Koch (TU Darmstadt, http://www.esa.informatik.tu-darmstadt.de/twiki/bin/view/Lectures/TGdI09De.html) wurden als Vorlagen benutzt.

Sende Artikel als PDF an PDF Creator

Transmissionsgatter

Donnerstag, 5. November 2009

Transmissionsgatter (engl. transmission gate) verbinden die Vorteile von nMOS und pMOS Transistoren. Somit ist ein solches Gatter ein sehr guter Schalter, der sowohl 0 als auch 1 gut schalten kann.

Transmissionsgatter

Er besteht aus 2 Transistoren, also jeweils ein nMOS und pMOS. Beide schalten das gleiche Signal A; das Ergebnis ist das Signal B. Auch das Signal das die Transistoren schaltet ist bei beiden gleich, mit dem Unterschied das es am pMOS Transistor negiert anliegt. Da sich ein pMOS mit einem negiertem Gate-Signal verhält wie ein nMOS schalten beide immer gleich, aber es werden die jeweiligen Vorteile ausgenutzt.
Bei einer 1 leitet hauptsächlich der pMOS; bei einer 0 hauptsächlich der nMOS. Damit hat man einen “perfekten” Schalter.

Sende Artikel als PDF an PDF

Disjunktive und Konjunktive Normalform

Dienstag, 3. November 2009

Diese beiden Normalformen werden besonders in der boolschen Algebra benutzt um boolsche Funktionen darzustellen. Boolsche Funktionen beschrieben die Ausgänge einer Schaltung als eine Funktion der Eingänge.

Zwischen DNF und KNF gibt es nur einen kleinen – aber entscheidenden – Unterschied:

  • Disjunktive Normalform
    Alle Ausdrücke (der obersten Ebene) werden durch OR Verknüpft: A \lor B \lor C.
    Dabei können die Ausdrücke auch komplexere Ausdrücke sein, die untereinander dann mit AND Verknüpft sind: (A_1 \land A_2) \lor B \lor (C_1 \land C_2 \land C_3).
  • Konjunktive Normalform
    Alle Ausdrücke (der obersten Ebene) werden durch AND Verknüpft: A \land B \land C.
    Dabei können die Ausdrücke auch komplexere Ausdrücke sein, die untereinander dann mit OR Verknüpft sind: (A_1 \lor A_2) \land B \land (C_1 \lor C_2 \lor C_3).

Anwendung

Gehen wir von folgender Wahrheitstabelle aus:

a b Y
0 0 0
0 1 1
1 0 1
1 1 0

DNF
Wenn man diese boolsche Funktion nun in der DNF darstellen will, sucht man sich alle Ausgänge Y die 1 sind. In diesem Fall also wenn a=0 und b=1 oder a=1 und b=0. Wenn der Eingang 0 ist, so muss mal den Eingang in der Formel negieren, ist er 1 so bleibt er unverändert. Und genau das ist auch schon die Form in der man als DNF darstellt:
Y=\neg AB \vee A \neg B

KNF
Bei der KNF ist es etwas anders. Man sucht sich alle Ausgänge Y die 0 sind und negiert die positiven Eingänge:
Y=(A+B)(\neg A + \neg B)

Sende Artikel als PDF an PDF erstellen

nMOS und pMOS Transistoren

Dienstag, 3. November 2009

Die Aufgabe eines Transistors ist es, zwei Anschlüsse abhängig von einem Dritten zu schalten. Es ist also im Grunde ein elektrischer Schalter.

nMOS

Beide Transistoren sind sich sehr ähnlich, deshalb möchte ich den Aufbau am Beispiel des nMOS beschrieben:

nMOS Transistor (ausgeschaltet)

Auf der rechten Seite ist ein Querschnitt eines nMOS Transistors abgebildet. Der Körper des Transistors besteht aus einem p-dotiertem Material an dem die niedrigste Spannung des Systemes anliegt (LOW, GND). p-dotiert heißt, das es frei bewegliche positive Löcher gibt. Darin sind die beiden Kontakte eingebettet die jeweils aus einem n-dotiertem Material bestehen – da gibt es also frei bewegliche negative Ladungsträger. Zwischen diesen Kontakten kann kein Strom fließen, weil die Materialen aus unterschiedlichen Dotierungen bestehen.
In der Mitte ist das so genannte Gate. Damit vom Gate zum Körper kein Strom fließen kann, ist eine isolierende Schicht eingebracht (heute meist Glas).
Der Strom soll in den nMOS und pMOS Transistoren von Source nach Drain fließen. Wenn am Gate kein Strom anliegt, fließt auch kein Strom zwischen S und D. Wenn man jedoch Strom (HIGH, also die höchste Spannung im System, V_{DD}) an das Gate legt, dann entsteht ein elektrisches Feld zwischen dem Gate und dem eigentlichem Körper. Strom kann aufgrund des Isolators nicht zwischen Gate und Körper fließen. Durch das Feld werden die positiven Ladungen zum Gate gezogen, und negative nach unten gedrückt.

nMOS (eingeschaltet)

Damit bildet sich zwischen den beiden Kontakten (Source und Drain) ein Kanal (channel) durch den ein Strom zwischen Source und Drain fließen kann.

pMOS

Im pMOS ist alles im Grund umgedreht. Der Körper besteht aus n-dotiertem und die Source und Drain Kontakte aus p-dotiertem Material. Der Körper ist an die höchste Spannung im System angeschlossen. Wenn am Gate auch V_{DD} anliegt ist der pMOS Transistor geschlossen, bei GND geöffnet.

Leitungseigenschaften

Das Problem bei der ganzen Sache ist, das jeder Typ nur einen Wert sehr gut leitet. Das heißt der nMOS leitet eine 0 sehr gut, aber eine 1 schlecht. Beim pMOS ist es genau andersrum; pMOS leitet die 1 sehr gut, aber die 0 schlecht.
Deshalb verbaut man meist beide Arten, und nutzt die jeweiligen Vorteile aus.

Bilder von Wikimedia Commons.

Sende Artikel als PDF an PDF erstellen