Autor Thema: Logisim CPU  (Gelesen 119567 mal)

Tufelix

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #240 am: 13. July 2013, 13:04 »
Zitat
Doch ist es, vor allem da es nicht 1MB sondern ganze 4MB sind (jede Adresse enthält 4 Byte um 32Bit Adressen aufnehmen zu können). Das Gute daran ist, das es wenn der SRAM einmal beschrieben ist es nie zu PageFaults kommen kann. Der riesengroße Nachteil ist dass es ewig dauert bis bei einem Taskwechsel der RAM neu beschrieben ist. Den SRAM verkleinern kann man leider auch nicht so ohne weiteres, da mann ja für jede virtuelle Adresse die von der CPU kommt einen Eintrag haben muss. Jetzt könnte man ja versuchen die Adressen auf weniger Einträge zu verteilen, womit wir dann wieder am Anfang wären.
Man könnte ja die pagegröße erhöhen(z.b von 4kb auf 16 kb) dann benötigt man ja weniger Sram da es weniger Pages gibt oder ?

Zitat
Das klingt wieder so kompliziert und gibt bei einem sehr kleinen Kernel sehr viel verschwendeten Platz. Ich würde eher dafür sorgen dass der Kernel bestimmen kann wann er in den Usermode wechselt, und das unabhängig davon wo er sich gerade befindet. Wichtig ist nur das der Usermode nicht einfach in den Kernelmode springen kann, das sollte dann nur über Interrupts geschehen, da der dann ausgeführte Code vom Kernel ist und nicht vom User.
Naja wie wärs dann mit ein paar steuerbit in jedem SRAM eintrag ? Die dann bestimmen ob man auf das Page nur im kernel modus zugreifen kann oder im usermodus nur gelesen werden kann oder ob man es im usermodus lesen und beschreiben kann. Und joar, bei mir wirds auch so sein das man nur über interrupts in den kernelmode kommt.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #241 am: 18. July 2013, 13:49 »
Hallo,

Zitat
irgendwie gefällt mir dein Ansatz mit den erlaubten Bereichen und dem Co-Prozessor nicht. Das klingt alles so kompliziert.
Nun ok ich wollte eigentlich auch für die interruptbehandlung nen CO-prozessor einbauen(so ähnlich wie bei mips), soll ich den auch steichen?
Das hängt davon ab, wie kompliziert du dein Interruptsystem haben möchtest. Wenn du nicht jedem Interrupt eine eigene Leitung spendieren möchtest, brauchst du im Chipsatz eine Logik, die die ganzen Interruptquellen für die CPU verdaulich macht.

Zitat
Eine MMU ist im einfachsten Fall ein SRAM.
Mhh der SRAM muss ja dann 1 MB groß sein oder? Ist das nicht etwas zu viel ?
Bei einer 32-Bit-Architektur sind das sogar 4 MB. Darum legt man diese Tabellen auf solchen CPUs in den normalen Arbeitsspeicher und führt ein mehrstufiges System (Page Directory, Page Tables) ein, damit sich verschiedene Tasks möglichst viel dieser Tabellen teilen können.

Zitat
Wenn du für Hardware einen getrennten Adressraum vorsiehst, ist das recht einfach.
Naja hab eher an einen gemeinsamen Adressraum gedacht, wie wärs wenn ich den adressraum in 2 segmente unterteile(die größen der segmente sind immer gleich).
Das ist dasselbe in grün. Statt einer Steuerleitung, die zwischen Speicher und Hardware umschaltet, schaltet dann die oberste Adressleitung zwischen Segment 0 (Speicher) und Segment 1 (Hardware) um. Vorteil: Du kannst mit den normalen Befehlen deine Hardware erreichen. Nachteil: Jetzt muss jeder Befehl, der Speicher adressieren kann, den aktuellen CPU-Modus kennen...

Man könnte ja die pagegröße erhöhen(z.b von 4kb auf 16 kb) dann benötigt man ja weniger Sram da es weniger Pages gibt oder ?
Ja. Dann muss die MMU pro Task statt 4 MB nur noch 1 MB speichern - immernoch zu viel.

Naja wie wärs dann mit ein paar steuerbit in jedem SRAM eintrag ?
Das geht. Aus einer 32-Bit virtuellen Adresse machst du dann eine 30-Bit physische Adresse mit zwei Zugriffsbits. Das oberste Adressbit unterscheidet dann noch zwischen Speicher und Peripherie, fertig. Ergibt 512 MB maximalen RAM. ;-)

Gruß,
Svenska

streetrunner

  • Beiträge: 67
    • Profil anzeigen
Gespeichert
« Antwort #242 am: 18. July 2013, 14:44 »
Zitat
Ergibt 512 MB maximalen RAM
Aber nur wenn du darauf aus bist deine Pages kreuz und quer über den RAM zu verteilen. Wenn man die Pages z.B. 4k aligned über den Speicher verteilt dann würden zu den 29 Bit nochmal 12 dazu kommen, damit gibt das dann weit mehr als 512MB an RAM.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #243 am: 18. July 2013, 22:20 »
Ich bin davon ausgegangen, dass die unteren 12 Adressbits an der MMU vorbei durchgeschleift werden. Dann bleiben nur 2^17 Pages á 4 KiB übrig, also maximal 512 MiB. Das hat den Vorteil, dass die MMU beim Lesen und Schreiben die gleiche Belegung der Adressleitungen verwendet und einem so einen Multiplexer erspart.

streetrunner

  • Beiträge: 67
    • Profil anzeigen
Gespeichert
« Antwort #244 am: 19. July 2013, 14:05 »
Ich verstehe nicht ganz was Du meinst.  :?

Tufelix

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #245 am: 19. July 2013, 23:20 »
Zitat
Das ist dasselbe in grün. Statt einer Steuerleitung, die zwischen Speicher und Hardware umschaltet, schaltet dann die oberste Adressleitung zwischen Segment 0 (Speicher) und Segment 1 (Hardware) um. Vorteil: Du kannst mit den normalen Befehlen deine Hardware erreichen. Nachteil: Jetzt muss jeder Befehl, der Speicher adressieren kann, den aktuellen CPU-Modus kennen...
Naja die speziellen Befehle die auf die hardware zugreifen können, müssen doch auch den CPU modus kennen oder ?  :-)

Zitat
Ja. Dann muss die MMU pro Task statt 4 MB nur noch 1 MB speichern - immernoch zu viel.
Mhh wie wärs wenn ich mein altes konzept wieder aufgreife(das mit den beschränkte bereiche und dem CO-prozessor) und anstatt es über ein co-prozessor zu integrieren ,einfach an den bus anschließe.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #246 am: 20. July 2013, 22:28 »
Ich verstehe nicht ganz was Du meinst.  :?
Du hast Recht. :oops:

Naja die speziellen Befehle die auf die hardware zugreifen können, müssen doch auch den CPU modus kennen oder?
Ja, genauso wie die Befehle für die Interruptverwaltung und ähnliches. Aber es geht dabei nur um 2 Befehle (4 Opcodes: IN Reg, Imm und IN Reg, Reg sowie OUT Reg, Imm und OUT Reg, Reg), die im Usermode immer eine Exception werfen. Für den normalen Speicheradressbereich gibt es dafür die MMU, die entsprechend Pagefaults wirft. Allerdings kannst du die MMU selbst nicht dafür benutzen, um Zugriffe zur MMU zu kontrollieren - dafür brauchst du ein eigenes System. Das kann entweder ein I/O-Adressraum (IN, OUT) sein oder eine spezielle MMU-Unterstützung in der CPU (PG-Bit in CR0, CR3 und INVLPG bei x86). Übrigens implementiert sich immer als Bedingung sehr leicht in Logik. :-P

Mhh wie wärs wenn ich mein altes konzept wieder aufgreife(das mit den beschränkte bereiche und dem CO-prozessor) und anstatt es über ein co-prozessor zu integrieren ,einfach an den bus anschließe.
Es ist deine CPU.

Gruß,
Svenska

Tufelix

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #247 am: 22. July 2013, 17:21 »
Zitat
Es ist deine CPU.
Mhh nun wenn keiner ne andere idee hat, bau ich mein system ein.

Auserdem hab ich jetzt mir mal gedanken zum Interruptcontroller gemacht, kann man den ein interrupt in einer interrupt-service-routine auslösen ?

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #248 am: 23. July 2013, 03:21 »
Zitat
Es ist deine CPU.
Mhh nun wenn keiner ne andere idee hat, bau ich mein system ein.
Beide Ansätze wurden aus meiner Sicht ausreichend behandelt. Für was du dich am Ende entscheidest, bleibt schlichtweg dir als Designer überlassen.

Auserdem hab ich jetzt mir mal gedanken zum Interruptcontroller gemacht, kann man den ein interrupt in einer interrupt-service-routine auslösen ?
Normale CPUs haben ein Flag, mit dem man Interrupts ein- oder ausschalten kann. Wenn die CPU in eine ISR wechselt, wird dieses Flag meistens auf "Interrupts ausschalten" gestellt. Selbstverständlich kann man dieses Flag auch zurücksetzen und Interrupts auch innerhalb einer ISR auslösen lassen, um softwareseitig priorisierte Interrupts zu realisieren; da das praktisch aber verdammt schwierig fehlerfrei hinzukriegen ist, wird das eher nur in Ausnahmefällen (Echtzeitsysteme mit garantierten geringen Latenzen bei gleichzeitig geringem Jitter) so gemacht. Allerdings sollte eine ISR sich nie selbst unterbrechen können: Ist sie nicht reentrant, zerstören die Instanzen sich gegenseitig; feuert der Interrupt zu oft, läuft der Stack über.

Wenn du diese Ausnahmefälle unterstützen möchtest, muss dein Interruptcontroller das Maskieren einzelner Interrupts unterstützen und damit eine Busschnittstelle besitzen.

Gruß,
Svenska

Tufelix

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #249 am: 25. July 2013, 10:52 »
Mhh, ok. Hätte da noch eine weitere frage:
Sollte bei einem interrupt eher die adresse vom befehl der gerade unterbrochen wird, abgespeichert werden oder die Adresse die im Programmcounter steht und auf den nächsten Befehl zeigt?


streetrunner

  • Beiträge: 67
    • Profil anzeigen
Gespeichert
« Antwort #250 am: 25. July 2013, 11:27 »
Es ist einfacher einen Befehl nicht zu unterbrechen, sondern ihn immer zu Ende laufen zu lassen. Wenn man dann den IP speichert, der ja schon auf den nächsten Befehl zeigt, kann man nach einem 'iret' einfach da weitermachen wo man unterbrochen wurde.

Tufelix

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #251 am: 25. July 2013, 18:33 »
Zitat
Es ist einfacher einen Befehl nicht zu unterbrechen, sondern ihn immer zu Ende laufen zu lassen. Wenn man dann den IP speichert, der ja schon auf den nächsten Befehl zeigt, kann man nach einem 'iret' einfach da weitermachen wo man unterbrochen wurde.
Ah ok, ich hab jetzt mal dann ein Interrupt-Controller entwickelt. Zunächst mal führt meine CPU jetzt ein Befehl immer in 2 takt-zykluse aus ( 1 Takt:Befehl laden,IP erhöhen ; 2 Takt: Befehl ausführen). Nun nur der erste Takt-zyklus( 1 Takt:Befehl laden,IP erhöhen) kann durch ein Interrupt  unterbrochen werden. Tritt ein Interrupt auf während sich die CPU im 2 Zyklus befindet, muss gewartet werden bis sich die CPU wieder im ersten Zyklus befindet.

So jetzt zum eigentlichem Interrupt-Controller: Es gibt 2 arten von Interrupts -die "normale Interrupts" und die "Notfall Interrupts"-  Ein Normales Interrupt kann nur durch ein Notfall-Interrupt unterbrochen werden. Und ein Notfall-interrupt kann nie unterbrochen werden. Nun der Controller ist ähnlich aufgebaut wie der Interrupt-Controller von Mips. Bei einem Interrupt wird der IP in ein sogenanntes EPC-Register geladen, danach wird die Adresse von Interrupt-Handler in den IP und die Ausnahmen-Ursache in das Register R30 geladen.Das EPC-Register und Das register für die Adresse des interrupt-Handler sind jeweils an den Bus angeschlossen.Treten 2 Interrupts vom selben Typ auf, wird nach dem round-robin-verfahren entschieden wer als erstes dran kommt. Tritt ein Notfall interrupt und ein Normales Interrupt gleichzeitig auf hat das Notfall-Interrupt natürlich vorrang.

streetrunner

  • Beiträge: 67
    • Profil anzeigen
Gespeichert
« Antwort #252 am: 25. July 2013, 18:52 »
Zitat
nur der erste Takt-zyklus( 1 Takt:Befehl laden,IP erhöhen) kann durch ein Interrupt  unterbrochen werden
Unterbrechen würde ich nur nach ganzen Befehlen, also jeweils am Ende deiner 2 Taktzyklen. Das erspart dir jede Menge Arbeit, da du nicht speichern musst wo dein erster Zyklus unterbrochen wurde (zu Beginn, nach dem Befehl hohlen, nach dem IP inkrementieren)

Und denke dran für deine Notfall-Interrupts ein änliches Register wie das EPC vorzusehen, sonst kann es sein dass es Probleme mit dem Wiedereintritt in deinen eigendlichen Interrupt-Handler gibt.

Jonathan

  • Beiträge: 22
    • Profil anzeigen
Gespeichert
« Antwort #253 am: 25. July 2013, 23:15 »
Du solltest außerdem Interrupts zuerst latchen, bevor du sie ausführst, damit kein Int verloren geht, der während einem anderen gleichrangigen Int auftritt.


Gruß
Jonathan

Tufelix

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #254 am: 25. July 2013, 23:25 »
Zitat
Unterbrechen würde ich nur nach ganzen Befehlen, also jeweils am Ende deiner 2 Taktzyklen. Das erspart dir jede Menge Arbeit, da du nicht speichern musst wo dein erster Zyklus unterbrochen wurde (zu Beginn, nach dem Befehl hohlen, nach dem IP inkrementieren)
Mhh bei mir dauert ein takt-zyklus ,1 takt( also 2 takte für einen befehl) Nun wird der erste Takt-zyklus unterbrochen und stattdessen der Interrupt-Befehl ausgeführt, ist das doch am ende der beiden letzten taktzyklen ?   

Zitat
Und denke dran für deine Notfall-Interrupts ein änliches Register wie das EPC vorzusehen, sonst kann es sein dass es Probleme mit dem Wiedereintritt in deinen eigendlichen Interrupt-Handler gibt.
Ah danke, das hab ich ganz übersehen :D

Zitat
Du solltest außerdem Interrupts zuerst latchen, bevor du sie ausführst, damit kein Int verloren geht, der während einem anderen gleichrangigen Int auftritt.
Joar stimmt, dann bau ich das auch ein.

streetrunner

  • Beiträge: 67
    • Profil anzeigen
Gespeichert
« Antwort #255 am: 26. July 2013, 09:13 »
Zitat
ist das doch am ende der beiden letzten taktzyklen ?
Unterbrechen ist bei mir 'mit etwas beginnen und nicht fertig werden', was Du meinst ist das Dein erster Takt überhaupt nicht ausgeführt wird. Ja, ich denke mal so wäre es richtig, es sei denn irgendwer hätte noch eine andere Idee.

Tufelix

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #256 am: 27. July 2013, 17:31 »
Mhh nun der Interrupt-Controller ist dann auch schon fertig geplant.  Naja und der VHDL-Code vom meiner CPU ist auch schon fast fertig. Ich glaub jetzt kann ich mir gedanken zu hardware-umsetzung machen :D. Hat dazu jemand ne idee wie ich das am besten mache ?

Tufelix

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #257 am: 30. July 2013, 23:20 »
Naja ich glaub ich überschätz mich wieder total :-D , aber ich hab jetzt ein Demoboard entwickelt. Hier mal das grobe Design.



3bit - Sysbus beinhaltet : RAS0,CAS0, WE
2bit Sysbus beinhaltet : takt, WE.

Nun es gibt nur 1 SIMM-Modul das 16MB groß ist und nur bei Defekt gewechselt wird.
Bei einem Reset wird zunächst das Bios von der ROM in den Ram geladen und ausgeführt.
Und der SS-Bus ist dafür da einer der drei Slaves(Atmega16, Atmega32 & SID 6581) auszuwählen.
Auserdem kann der ATmega 32 nur einen schwarz-weiß textmode ausführen.

So was hält ihr davon, und hat jemand noch dazu ne frage ?

chris12

  • Beiträge: 134
    • Profil anzeigen
Gespeichert
« Antwort #258 am: 31. July 2013, 02:22 »
Du hast also extra ports an deiner cpu für diese spezielle peripherie? ich würde tatsächlich einen MMIO Design verwenden, sodass du einfach den IO in den speicher einblendest über einen AdressController, der im bestenfall einfach ein multiplexer ist. Je nach andresse kannst du dann ja die peripherie endweder nach deinem design an den bis anschliessen, sodass es einen port als controllpfad gibt und einen als datenpfad, oder aber gleich einen port je peripherie, oder mehr.

aber das ist nur meine idee
OS? Pah! Zuerst die CPU, dann die Plattform und _dann_ das OS!

Tufelix

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #259 am: 01. August 2013, 15:30 »
Zitat
Du hast also extra ports an deiner cpu für diese spezielle peripherie? ich würde tatsächlich einen MMIO Design verwenden, sodass du einfach den IO in den speicher einblendest über einen AdressController, der im bestenfall einfach ein multiplexer ist. Je nach andresse kannst du dann ja die peripherie endweder nach deinem design an den bis anschliessen, sodass es einen port als controllpfad gibt und einen als datenpfad, oder aber gleich einen port je peripherie, oder mehr.
Naja Der I/O bus und der Ram-Bus wollte ich eigentlich über einen sogenannten Bus-Controller in der CPU miteinander Verbinden. So das es zu ein MMIO design wird.

Nun,  ich glaub ich lass das wieder mit dem eigenem Demoboard sein und kauf mir ein Fertiges FPGA board. Ein eigenes Demoboard zu entwickeln wird einfach zu schwierig für mich ...
Naja kann mir einer ein FPGA board empfehlen ?

 

Einloggen