Autor |
Beitrag |
LLCoolDave
      
Beiträge: 212
Win XP
Delphi 2005
|
Verfasst: Do 18.01.07 22:00
Erstmal vorab: Die Zeichnung hier hab ich schnell in Paint hingeschludert, ich entschuldige schon mal im voraus für die Qualität.
Nehmen wir zunächst einmal als Ausgangspunkt folgende logische Schaltung:
Relativ offensichtlich ist, dass das Lämpchen auf der rechten Seite in diesem Zustand leuchtet. Nun schalten wir gleichzeitig einen Schalter vor der oberen und der Unteren Leitung um, und schauen, was sich daraus ergibt:
Mathematisch betrachtet fassen wir zunächst die beiden unteren Leitungen im AND zusammen, es ergibt sich eine 1. 0 OR 1 ergibt wiederrum 1, das Lämpchen leuchtet weiterhin.
Stellen wir uns den Schaltplan nun aber physikalisch gebaut vor, ergibt sich ein leicht anderes Bild: Die Information aus den beiden unteren Leitungen braucht länger, um am OR anzukommen, als die aus der oberen. Es kommt also oben die 0 bereits an, während sich die 1 der unteren Leitung noch irgendwo im AND oder vielleicht bereits in dem Leitungs-Darm befindet, zumindest herrscht am OR kurzzeitig ein 0 OR 0, was als Ausgabe 0 gibt, das Lämpchen ist aus. Zumindest, bis die 1 aus der unteren Leitung erneut für eine 1 als Output und somit zu Licht führt. In der Realität merken wir dies natürlich nicht, weil das Lämpchen zu träge ist, und wir ein solches Flackern sowieso in der Geschwindigkeit nicht mit unseren Augen wahrnehmen können.
Kritisch wird das Ganze jedoch, wenn wir zwischen OR und Lämpchen noch wie folgt ein RS-Flipflop aus NAND Bauteilen setzen (es ist zu Beginn des Experiments gesetzt, die Lampe leuchtet also):
Erneut werden die obere und untere Ausgangsleitung gleichzeitig umgeschaltet.
Mathematisch betrachtet liefert das OR weiterhin 1 als Output, das Flipflop bleibt gesetzt, die Lampe leuchtet.
Physikalisch gebaut produziert das OR jedoch kurzzeitig eine 0. Diese gelangt an den R Eingang des NAND Flipflops und führt zu einem Reset, die Lampe geht aus. Auch dass kurze Zeit darauf das OR wieder 1 liefert, rettet die Situation nicht mehr.
Folglisch ergibt die rein logische Betrachtung somit ein anderes Ergebnis als ein Physikalisches Experiment.
So, und nach dieser langen Vorrede kommt nun der Grund, warum dieser Thread nicht im Offtopic gelandet ist:
Ich habe vor, ein Programm zur Simulation von logischen Schaltungen zu schreiben. Ich gehe einfach mal davon aus, dass die oben geschilderte Situation soweit korrekt ist, ich habe leider derzeit nicht die Möglichkeit, sie in der Praxis zu testen. Wenn ich bereits dort einen Fehler habe, berichtigt mich bitte. Ich gehe mal stillschweigend und intuitiv davon aus, dass meine Beobachtung auf einen generellen und keinen speziellen Unterschied zwischen einem Formal-Mathematisch-Logischen Schaltkreis und einem Real-Physikalischen Schaltkreis beruhen, nicht zuletzt wegen der Begrenzung der Informationsverarbeitungs- und Informationsausbreitungsgeschwindigkeiten.
Die erste generelle Frage ist nun: Sollte ein Simulationsprogramm sich nun nach einem realen physikalischen oder einem mathematischen Modell orientieren? Ich tendiere derzeit eher zu der physikalischen Variante, nicht zuletzt deshalb, weil sie sich scheinbar zwangsläufig aus meinem derzeitigen Programmieransatz ergibt:
Der Simulationsablauf wird über eine Art Stack (formal wohl eher nur eine Liste, da ich auch mittendrin Befehle einschieben kann und muss) realisiert, der für jeden Eintrag eine n Befehl, die UID des Schaltelements, dass den Befehl ausführen soll sowie die Framenummer, in der dies geschehen soll, speichert. Die Liste ist nach der Framenummer sortiert und wird von oben herab abgearbeitet. Sind für den jetzigen Frame keine Befehle mehr auf dem Stack, geschehen einige Userinteraktionen (Manuelles Umschalten von Schaltern registrieren, Grafische Ausgabe etc.), die Framezahl wird erhöht und der Stack wieder für diesen Frame abgearbeitet. Die Befehle sind dann z.B. ORREFRESH, der das angegebene OR-Element dazu veranlasst, zu überprüfen was derzeit für Signale anliegen und anschließend wenn nötig die Ausgabe anzupassen. Dazu würde für das anliegende Kabel der Befehl zum übernehmen des neuen Signals auf den Stack gepusht.
Egal wie ich es drehe und wende, und wo ich in den Stack die Änderungs oder Refresh Befehle anordne und einschiebe, oder wenn ich das ganze rein rekursiv (was jedoch für meinen Programmansatz andere Nachteile bieten würde) löse, ich finde immer einen Schaltungsaufbau, der das Physikalische Flipflop-Wechseldich Problem birgt und somit nicht rein mathematisch simuliert. Ich denke, das ist mit meinem Ansatz schlicht nicht im allgemeinen Fall möglich.
Jetzt möchte ich wissen, ob jemandem eine Idee kommt, wie man eine solche Schaltung mathematisch korrekt auswerten lassen könnte, mir fällt im Moment nichts ein, was nicht um ein deutliches vielfaches schwerer umzusetzen wäre als mein relativ simpler Stack-Ansatz. Mir wäre die Möglichkeit des "formal korrekten" Ablaufs doch wichtig, sofern sich dieser mit realistischem Aufwand umsetzen liese.
|
|
RoYalKamü
Hält's aus hier
Beiträge: 14
|
Verfasst: Do 18.01.07 22:16
weiß jetzt net ob die antwort hilfreich ist aber wir haben einfach immer ne tabelle mit 0 und 1 gemacht und dann kannst gukken wann die lampe angeht dann bekommste die DNF oder die KNF raus und diese kannste als formel betrachten die du dann so auch in delphi umsetzen kannst.
|
|
Jetstream
      
Beiträge: 222
|
Verfasst: Do 18.01.07 22:17
Lampe mit nur einem Kabel leuchtet nicht.
_________________ Die folgenden Klangbeispiele sind Ergänzungen zum methodischen Aufbau der Textbeilage und dürfen nicht losgelöst von dieser behandelt werden.
|
|
RoYalKamü
Hält's aus hier
Beiträge: 14
|
Verfasst: Do 18.01.07 22:18
jetstream der schaltplan stellt nur die log. verknüpfungen dar nicht die Stromkabel 
|
|
LLCoolDave 
      
Beiträge: 212
Win XP
Delphi 2005
|
Verfasst: Do 18.01.07 22:31
Jetstream hat folgendes geschrieben: | Lampe mit nur einem Kabel leuchtet nicht. |
Mit so einer (wenig hilfreichen, aber dennoch berechtigten) Antwort habe ich gerechnet. Stell dir die Lampe an einer Stromquelle angeschlossen vor, dabei ist in den Stromkreis ein Transistor eingebaut, der bei logisch 1 den Strom durchlässt und bei logisch 0 sperrt. Dann leuchtet die Lampe bei 1 und bei 0 nicht. Mit der eigentlichen Problematik hat das nichts zu tun. Bei uns in Informatik haben wir z.B. Platinen mit logischen Bauteilen, die man oberhalb mit Kabeln zusammenstecken kann. Diese werden dennoch Zwecks Funktionalität mit Strom versorgt, jedoch muss man sich da nicht auch noch selber darum kümmern. Der logische Schaltplan stellt nur die sichtbare verknüpfung der Elemente dar. Desweiteren dient die Lampe nur als Indikator, der logische Zustand wäre ohne sie der selbe.
RoYalKamü: Ja, so einen Ansatz hatte ich im Sinn, mir fällt jedoch kein sinnvolles Verfahren ein, einen allgemeinen logischen Schaltplan in eine solche Zustandstabelle zu übersetzen. Sonst wäre die Sache ja schnell gegessen.
|
|
RoYalKamü
Hält's aus hier
Beiträge: 14
|
Verfasst: Do 18.01.07 22:38
na dann google mal oder mach dein tafelwerk auf wenn du sowas hast.
jede verkn. kann nur in bestimmte zustände wechseln da gibbet dann eben so eine tabelle mit prioritäten
www.elektrotechnik-f...che-verknuepfung.php
gukk ma hier sowas musst du bei dir auch machen.
das dann nach den prioritäten geordnet also 1.not 2.nand 3. nor 4. and 5. or 6.xor
aber sag ma wer hat dir den diese aufgabe gegeben weil die schaltung sieht völlig unlogisch aus, mussteste dir ausdenken oder haste bekommen?
|
|
LLCoolDave 
      
Beiträge: 212
Win XP
Delphi 2005
|
Verfasst: Do 18.01.07 22:51
Mmh, ich glaube wir reden aneinander vorbei. Die generelle Vorgehensweise mit Aufstellen einer Wahrheitstabelle habe ich verstanden, jedoch fehlt es mir noch an der Umsetzung in einen Algorithmus (sofern es das ist, was du überhaupt vorschlägst). Zumal dann ja auch lediglich das Ergebnis (Lampen leuchten oder leuchten nicht z.B.) klar ist, ich aber gerne das Ganze System visualisieren würde, indem z.B. Verbindungen, die logisch 1 sind, andersfarbig gezeichnet werden. Ausserdem müssen da ja auch noch Schaltelemente mit Gedächtnis berücksichtigt werden wie z.B. Flipflops, was die Zustandstabelle bei komplexeren Schaltungen ruckzuck aufbläht, zumal mir noch nicht ganz klar ist, wie ich diese im allgemeinen mit einem Algorithmus erstellen kann. (Dass das nicht in polynomialer Luafzeit geht, weis ich immerhin =)). Vielleicht bin ich gerade auch durch Doppelspalte und optische Gitter so durcheinander, dass ich dir nicht ganz folgen kann.
|
|
RoYalKamü
Hält's aus hier
Beiträge: 14
|
Verfasst: Do 18.01.07 22:54
ok das problem ist das ich net weiß was du mit flipflops meinst aber ansicht müste doch nur [wenn (a =1) und (b=1) dann .... mach das und das farbig und nur wenn das eben farbig ist dann mach das.da das ja alels nach prioritäten geht ist die abfolge ja immer gleich
|
|
LLCoolDave 
      
Beiträge: 212
Win XP
Delphi 2005
|
Verfasst: Do 18.01.07 23:15
RoYalKamü hat folgendes geschrieben: | ok das problem ist das ich net weiß was du mit flipflops meinst aber ansicht müste doch nur [wenn (a =1) und (b=1) dann .... mach das und das farbig und nur wenn das eben farbig ist dann mach das.da das ja alels nach prioritäten geht ist die abfolge ja immer gleich |
Ich schätze, wir reden aneinander vorbei. Natürlich ist mir klar, dass das mit der Tabelle ein "Wenn das und das und das und das dann mach das" ist, das problem ist das erstellen einer solchen Tabelle. Für ein gegebenes Schaubild ist das von Hand kein Problem, das Problem ist das per Algorithmus für jede beliebige Schaltung zu realisieren.
Das du keine Flipflops kennst, macht die Sache auch nicht gerade leichter =/ Ein Flipflop ist quasi ein 1-Bit Speicher. Baut man ein einfaches RS-Flipflop aus NAND Gates auf, so hat es zwei Eingänge R und S und zwei Ausgänge Q und Q quer. Dabei gilt ist Q=1 ist Q quer=0 und umgekehrt. Setzen tut man es, in dem man am S Eingang eine 0 anlegt, dann wird Q 1. Dieser Zustand bleibt, unabhängig von dem Wert bei S, solange so, bis man an R 0 anlegt, dann wird das Flipflop zurückgesetzt, Q wird 0. Es kann nur wieder durch eine 0 an S gesetzt werden. Der Zustand R=S=0 ist im allgemeinen undefiniert und muss unbedingt vermieden werden  Das ist in groben Zügen die Funktionsweise eines Flipflop.
PS: Ich habe aus Testgründen mal schnell bei der "Konkurrenz" LOCAD geschaut, dort verhält sich ein selbstgebautes RS-Flipflop exakt wie von mir oben physikalisch vorausgesagt. Verwende ich stattdessen die R und S Eingänge eines JTK-Flipflop, so lässt sich Q alleine durch R bestimmen. Ob das das normale Verhalten ist, kann ich gerade nicht sagen, ich kenne mich mit denen (NOCH) nicht aus, ich tippe mal auf ja. Im Moment muss ich erstmal Physik lernen und kann mich deshalb nicht informieren
Naja, die mathematisch korrekte Behandlung fände ich schon noch ein nettes Feature, vielleicht hat ja jemand noch einen Geistesblitz, entweder für die Zustandstabelle oder einen anderen Ansatz, mir fällt im Moment nichts weiter ein.
|
|
eruhenon
      
Beiträge: 53
|
Verfasst: Sa 20.01.07 00:00
Wie wärs mit ner verketteten Liste?
Du könntest ja pro Symbol eine Funktion haben die du dann einfach in sone Liste lädst. Dann speicherst du den status global (kannst ja nen dyn. array für die Leitungen machen) und dann einfach die Liste abarbeiten. Das Problem beim abbrechen seh ich darin, dass es ja auch die bausteine negiert gibt und somit ja auch nullen genau das sein können was man braucht. also am besten in eine for schleife packen und durcharbeiten und imer die Werte der Leitungen Global speichern...
vll isses auhc alles müll was ich hier geredet hab aber es ist atm meine einzige idee.
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 20.01.07 01:55
Also ich würde das ganze auch verkettet machen. Ich hab sowas ähnliches (nur sehr viel simpler) schonmal gemacht. Ich hatte nur recht wenige Bauteiltypen...
Was ich gemacht habe, ist folgendes:
Ich habe für jeden Bauteiltyp (Lampe, ...) eine Klasse erstellt, die dessen Eigenschaften (an, aus, ...) und die Position auf der Zeichenfläche enthielt. Dazu hatten diese Klassen für jeden Anschluss ein Property vom Typ einer Oberklasse TElement. So konnte ich dann von der Stromquelle ausgehen und die Werte jeweils aktualisieren.
Dabei könnte dann zu der jeweiligen Property auch die Länge des Anschlusskabels zum nächsten Baustein gespeichert werden und dementsprechend die kürzere Leitung zuerst aktualisiert werden.
|
|
LLCoolDave 
      
Beiträge: 212
Win XP
Delphi 2005
|
Verfasst: Sa 20.01.07 09:37
jaenicke hat folgendes geschrieben: | Also ich würde das ganze auch verkettet machen. Ich hab sowas ähnliches (nur sehr viel simpler) schonmal gemacht. Ich hatte nur recht wenige Bauteiltypen...
Was ich gemacht habe, ist folgendes:
Ich habe für jeden Bauteiltyp (Lampe, ...) eine Klasse erstellt, die dessen Eigenschaften (an, aus, ...) und die Position auf der Zeichenfläche enthielt. Dazu hatten diese Klassen für jeden Anschluss ein Property vom Typ einer Oberklasse TElement. So konnte ich dann von der Stromquelle ausgehen und die Werte jeweils aktualisieren.
Dabei könnte dann zu der jeweiligen Property auch die Länge des Anschlusskabels zum nächsten Baustein gespeichert werden und dementsprechend die kürzere Leitung zuerst aktualisiert werden. |
Mmh, so ähnlich ist mein Aufbau ja, nur das Kabel auch als Schaltelemente gehandelt werden, das macht es dem User leichter, die Schaltung zu verändern (Einfach mal noch ein Kabel heran ziehen wenn man noch etwas anschließen will, oder einfach mal schnell bischen umstecken und den output an einen anderen Anschluss ziehen), ohne dass ich dabei jedesmal die Verkabelung neu berechnen müsste. Mal davon abgesehen, dass dein Ansatz ebenfalls so asynchron wie meiner funktioniert, und wohl in meine Beispiel ganz oben auch das Flipflop umstellen würde, wenn ich es richtig verstanden habe.
Der Unterschied in meinem Ansatz ist, dass die Objekte nicht über eine Liste verknüpft sind, sondern über eine art Map ausgewertet werden. Will ein AND z.B. einen neuen Wert ausgeben, übergibt es an eine Prozedur, an welcher Position relativ zu seiner eigenen der output stattfinden soll. Die Prozedur schaut dann, ob dort etwas ist dass aus dieser Richtung einen input akzeptiert, und wenn ja wird der Input aktualisiert und dem Bauteil per Stack aufgetragen, sich doch mal zu aktualisieren. Dabei ist es völlig egal, was dort eigentlich liegt  Der Stack ist dazu da, um Dinge wie z.B. einen Takter oder ein automatisches Delay in bauteilen (zur besseren grafischen Verfolgung) leicht zu realisieren.
Langsam habe ich aber das Gefühl, dass sich eine mathematische Abhandlung doch deutlich schwieriger darstellt, als ich anfangs dachte, und sich wohl in meinen Ansatz ohne weiteres nicht als alternative einbinden lässt. Naja, was solls, muss ich mich mit dem hier zufrieden geben, wird schwer genug sein, das zum Laufen zu kriegen.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Sa 20.01.07 11:41
Vielleicht wirfst Du mal einen Blick auf das Programm PSpice. Das gibt's als Eval-Version kostenlos (ohne Zeitbegrenzung). Das nutzen wir an der Uni zur Simulation. Das einzige, was in der Eval fehlt, sind einige Bibliotheken von Bauelementen (die man aber nachinstallieren kann).
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Sa 20.01.07 15:02
Unter einer "mathematischen" Lösung verstehe ich eine Auswertung einer Schaltung, die man als Formel mit AND, OR und NOT aufs Blatt schreiben kann: "1 and (0 or 1)". Sowas kann man dann auch in eine Baumstruktur bringen und auswerten. Hast du jedoch zyklische Beziehungen drin, so kann man sich einen Speicherbaustein basteln, und man kann das ganze nicht mehr als einfache Formel aufschreiben oder in eine Baumstruktur bringen.
Wenn du Zyklen zulassen willst, so wird das ganze etwas schwieriger, da die Zeit mitspielt (man kann nicht alles auf einen Schlag lösen, sondern es gibt eine zeitliche Abfolge von Events). Das kannst du mit einer diskreten Event Simulation lösen. Du berechnest dir jeweils den Zeitpunkt des nächsten Events (dafür musst du die Verzögerung von Kabel und Bausteinen genau kennen) und handelst dann entsprechend. Du musst dann auch kritische Fälle ganz genau definieren - was z.B. passieren soll, wenn bei einem AND ein Eingang von 0 auf 1 wechselt, und der andere Eingang von 1 auf 0: Soll es einen kurzen Peak geben, oder nicht. Du machst dir also eine Liste von Events, sortiert nach der Zeit, und arbeitest die ab. Die Liste muss natürlich nach jedem Event entsprechend upgedatet oder neu aufgebaut werden, wenn entsprechende Abhängigkeiten bestehen.
(Oder wenn du es "noch physikalischer" machen willst, dann diskretisierst du die Zeit in z.B. 0.0001 Sekunden und rechnest für jeden Baustein in jedem Zeitschritt den Output aus den Inputs aus. Dabei kannst du die zeitliche Abhängigkeit von Input zu Output beliebig selbst definieren. Du kannst z.B. eine Kurve angeben, wie schnell ein Zustand von 0 zu 1 ändern soll, usw.. D.h. du würdest das ganze für gebrochene Zustände definieren... Der Zeitschritt muss dann in jedem Fall hinreichend klein gewählt werden, damit das ganze funktioniert.)
|
|
|