Forum: FPGA, VHDL & Co. Welche Prozessorarchitektur (nach)bauen?


von AooA (Gast)


Lesenswert?

Kürzlich gab es die Diskussion, ob man in einem FPGA einen Prozessor 
implementieren kann. Und natürlich, man kann. Zu diesem Zweck (und um 
VHDL zu trainieren) habe ich mich hingesetzt. Ein paar Datenpfadelemente 
wie Multiplexer, Adressdecoder und Register habe ich bereits gebastelt, 
jetzt geht es aber an die Frage:

** Welche Architektur solls denn werden? **

Es gibt 2 Möglichkeiten:

1. Etwas eigenes.
Nachteil:
- Man muss sich selbst Assembler und Compiler basteln, wenn man das Ding 
richtig testen oder gar einsetzen möchte.

2. Eine bestehende Architektur nachbauen.
Nachteil:
- Man muss die bestehende Architektur komplett und korrekt 
interpretieren und nachbauen, um eine bestehende Toolchain zu benutzen. 
Vereinfachungen oder andere Modifikationen liegen nicht drin.


Jedenfalls suche ich nun nach ein paar Vorschlägen für Architekturen, es 
dürfen sowohl interessante bestehende Prozessoren sein oder auch Ideen 
für neue Ansätze.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

AooA schrieb:
> 2. Eine bestehende Architektur nachbauen.
> Vereinfachungen oder andere Modifikationen liegen nicht drin.
Warum nicht?
Auch die ganzen 8051-Derivate, die seit 1995 erschienen sind, sind 
Opcode-kompatibel und trotzdem bis zu 12 mal schneller als der 
Original-8051. Und das nicht wegen der Erhöhung der Taktfrequenz, 
sondern weil die Befehle in 1 statt in 12 Taktzyklen ausgeführt 
werden...

von Fpgakuechle K. (Gast)


Lesenswert?

AooA schrieb:
> Kürzlich gab es die Diskussion, ob man in einem FPGA einen Prozessor
> implementieren kann. Und natürlich, man kann. Zu diesem Zweck (und um
> VHDL zu trainieren) habe ich mich hingesetzt. Ein paar Datenpfadelemente
> wie Multiplexer, Adressdecoder und Register habe ich bereits gebastelt,
> jetzt geht es aber an die Frage:
>
> ** Welche Architektur solls denn werden? **
>
> Es gibt 2 Möglichkeiten:
>
> 1. Etwas eigenes.
> Nachteil:
> - Man muss sich selbst Assembler und Compiler basteln, wenn man das Ding
> richtig testen oder gar einsetzen möchte.


Oder man nimmt einen Assembler mit ähnlichen output und sortiert die 
bits um. Das ist dann einfacher als einen assembler komplett selbst zu 
schreiben.

Die op-codes sind nicht so unterschiedlich, irgendwelche bits 
adressieren die register, andere die Operation, und da mal ein paar bits 
zu verschieben sollte das nicht das problem sein. Und gab es da nicht 
Assembler-Compiler?, Also Software mit der du deinen Assembler selbst 
zusammenstricken kannst. Oder waren das Universalassembler?. GNU hat 
bestimmt auch was im Quellcode, das sollte das assembler.basteln auch 
nicht so schwierig sein.

MfG,

von Rene B. (themason) Benutzerseite


Lesenswert?

@AooA

ich bin gerade ebenfalls mit einem Softcore dran. Allerdings habe ich 
mich für Lösung 2 entschieden. Es ist zwar kein schneller Prozessor 
(durch ein langsames aber universelles Speicherinterface, kein RISC, und 
"klassisches" Design brauche ich viele Takte bis der Befehl abgearbeitet 
ist) aber mir geht es auch erstmal um einen Einstieg in die Softcores um 
zu sehen welche Teile eines Prozessors am meisten Logik benötigen, bzw 
wie man was anders gestalten kann um einen solchen Prozessor klein zu 
bekommen.
Den Reiz am selbstentworfenen Design finde ich darin das ich selbst 
bestimmen kann was der Prozessor kann. Ich habe bei mir z.b. eine 16-Bit 
Architektur in der nahezu jeder Befehl bedingt ausführbar ist, weil ich 
das von der programmierung her elegant finde. Einen Assembler dafür zu 
bauen ist kein Problem. Ein C-Compiler dürfte um Klassen komplexer sein 
(wenn ich das überhaupt in Angriff nehme). Aber da ist man wieder bei 
pro und contra Selbstbau/Nachbau :-)

von klaaus (Gast)


Lesenswert?

Rene Böllhoff schrieb:
> kein RISC, und
> "klassisches" Design brauche ich viele Takte bis der Befehl abgearbeitet
> ist

Ich für meinen Teil würde schwer zu einem RISC tendieren. Es ist von 
Architektur und Simulation her einfach deutlich übersichtlicher, wenn 
die Daten in jedem Prozessortakt einmal durch den ganzen Datenpfad 
laufen und wieder sauber zurückgeschrieben werden. Bei einem CISC 
hingegen wird man die ganzen Zwischenzustände in jedem Mikroschritt 
analysieren müssen.

von Hendrik L. (hlipka)


Lesenswert?

Wie wäre es mit der Architektur von Chuck Thacker: 
http://lambda-the-ultimate.org/node/3232 ?
"Presents the design of a complete CPU in under two pages of FPGA-ready 
Verilog. The TC3 is a Harvard architecture 32-bit RISC with 1KB of 
instruction memory, 1KB of data memory, and 128 general-purpose 
registers."

Alternativ gäbe es noch MMIX von Donald Knuth: 
https://secure.wikimedia.org/wikipedia/en/wiki/MMIX . Dort bekommt dann 
z.B. den gcc dafür.

von AooA (Gast)


Lesenswert?

Ein kleiner 4-Bitter im Stil eines Intel 4004 habe ich mal 
aufgezeichnet. Den dürfte man wohl fast in ein CPLD bringen, was man als 
ziemlich coole Bastelei präsentieren könnte. Problematisch bei 
Architekturen mit so geringer Wortbreite ist aber immer das Handling von 
Programmcounter, Stack und Instruktionsregister. Diese sind viel breiter 
als die Datenregister und können somit, im Gegensatz zu einer 
Architektur mit grösserer Wortbreite, nicht direkt über den normalen 
Datenpfad abgewickelt werden.

Beispielsweise eine call-Anweisung bei 4 Bit Wortbreite, 12 Bit 
Programmcounter und 12 Bit Datenadressen. Alleine das Speichern des 
Programmcounters auf dem Stack benötigt also 3 Speicherzugriffe, die 
wiederum jeweils 3 Addieroperationen brauchen, um den Stackpointer 
nachzuführen.

von Fpgakuechle K. (Gast)


Lesenswert?

Hendrik Lipka schrieb:
> Wie wäre es mit der Architektur von Chuck Thacker:
> http://lambda-the-ultimate.org/node/3232 ?

> Alternativ gäbe es noch MMIX von Donald Knuth:
> https://secure.wikimedia.org/wikipedia/en/wiki/MMIX . Dort bekommt dann
> z.B. den gcc dafür.


Der obere ist bereits von der Architectur her an (Xilinx-) FPGA's 
angepasst, indem er die Prozessorregister statt aus einzelnenen FF- aus 
einem Embeded DualPort bastelt. Allerdings scheint mir (nach flüchtiger 
Durchsicht) ein Unterprogrammaufruf zu fehlen, ebenso wie ein Interrupt.

Ohne den MMIX genau zu kennen befürchte ich, das dieser nicht für FPGA's 
angepasst wurde und daher wahrscheinlich langsam ist.

MfG,

von tom (Gast)


Lesenswert?

Wenn du zukunftsfähig bleiben willst, dann versuch dich an einem 
ARM-Klon

von Valko Z. (hydravliska)


Lesenswert?

Sorry fuer den Offtopic, ich habe aber eine Frage bezueglich ein ARM 
Klon.
Ich habe hier ein Spartan 3E 500K Board und ueberlege was ich damit 
machen sollte. Reicht eigentlich ein Spartan 3E fuer ein ARM Klon oder 
braeuchte man mindestens ein Virtex2? Ich habe mir die ARM Architecture 
Reference Manual(fast 1200 Seiten) runtergeladen und will es die Tagen 
mal angucken.

Danke im voraus.


Gruss,
Valentin

von Frank K. (fchk)


Lesenswert?

Vor 30 Jahren war der 6502 der Inbegriff von RISC: wenig Register 
(A,X,Y,SP,PC,Flags), hartverdrahtete Befehle (zumindest in der 
NMOS-Version), einfache Architektur. Wenn Du dann noch Energie hast, 
darfst Du Dich gerne bis zum 65816 hocharbeiten. Siehe 6502.org

Willst Du eine aktuelle Architektur, wäre MIPS erwähnenswert, weil 
wirklich ziemlich RISCig.

fchk

von D. I. (Gast)


Lesenswert?

Ich würde auch zu einer RISC Architektur raten.
Einen eigenen Assembler zu machen ist eigentlich kein großes Ding und 
wie aufwändig die Hardware wird hängt davon ab, wie du deine Befehle 
kodierst und welche Adressierungsarten du dir gönnen magst. Hinzukommen 
dann evtl. noch solche Sachen wie Interrupts, Exceptions, 
Branch-Prediction, Pipelining usw. je nach Zeitaufwand halt.

No RISC no fun ;)

von Fpgakuechle K. (Gast)


Lesenswert?

Frank K. schrieb:
> Vor 30 Jahren war der 6502 der Inbegriff von RISC: wenig Register
> (A,X,Y,SP,PC,Flags),

?Ist es nicht gerade ein Merkmal von RISC viele Register in der CPU zur 
Verfügung zu stellen?

MFG,

von Fpgakuechle K. (Gast)


Lesenswert?

AooA schrieb:
> Kürzlich gab es die Diskussion, ob man in einem FPGA einen Prozessor
> implementieren kann. Und natürlich, man kann. Zu diesem Zweck (und um
> VHDL zu trainieren) habe ich mich hingesetzt. Ein paar Datenpfadelemente
> wie Multiplexer, Adressdecoder und Register habe ich bereits gebastelt,
> jetzt geht es aber an die Frage:
>
> ** Welche Architektur solls denn werden? **
>
> Es gibt 2 Möglichkeiten:
>
> 1. Etwas eigenes.
> Nachteil:
> - Man muss sich selbst Assembler und Compiler basteln, wenn man das Ding
> richtig testen oder gar einsetzen möchte.


Es sollte recht einfach sein, sich einen Quick und dirty assembler per 
Spreadsheet (Excel;OO Calc)zusammenzubasteln. Ein Instruction wort mit 
seiner seinen fest zugeordneten Bitfeldern ist doch recht einfach auf 
einige Spalten Excel abgebildet, meinetwegen noch mit Auswahlmenü für 
die Operations-Mnemonics.
zum Schluss wird dann der Inhalt eines Feldes mit einer Zweierpotenz 
multipliziert, alle Felder addiert und in Hex angezeigt.

Weitere Vorschläge schnell einen Assembler zu schreiben.
MfG

von Skua (Gast)


Lesenswert?

Fpga Kuechle schrieb:
> ?Ist es nicht gerade ein Merkmal von RISC viele Register in der CPU zur
> Verfügung zu stellen?

Nein (Ja (Jain))

Siehe
http://de.wikipedia.org/wiki/RISC

von Fpgakuechle K. (Gast)


Lesenswert?

D. I. schrieb:
 Hinzukommen
> dann evtl. noch solche Sachen wie Interrupts, Exceptions,
> Branch-Prediction, Pipelining usw. je nach Zeitaufwand halt.



Pipelining (und damit verbunden Sprungvorhersage) erfodert schon größere 
Umbauten an der CPU, das ist kein "hinzukommen" mehr. Man sollte schon 
im voraus eine sinvolle Anzahl von Pipelinestufen abschätzen. Bei einem 
FPGA mit 6er oder 4er LUT sollten es  2 oder drei sein. Bei einer so 
kurzen Pipeline macht sprungvorhersage wenig Sinn. Und mit einer 
Ein-takt maschine ohne Pipeline kann man in einem FPGA schon (für 
Embedded) ordentliche taktraten von 60 - 100 MHz erreichen.

Der Aufwand einen IRQ nachzurüsten ist eher gering. sollte aber meines 
erachtens von anfang an in dem Programmcounter mit eingebaut sein. 
Notwendigkeit von Exceptions ist nicht ersichtlich, welche 
Ausnahmebehandlung meinst Du?

MfG,

von (prx) A. K. (prx)


Lesenswert?

Frank K. schrieb:

> Vor 30 Jahren war der 6502 der Inbegriff von RISC: wenig Register
> (A,X,Y,SP,PC,Flags), hartverdrahtete Befehle (zumindest in der
> NMOS-Version), einfache Architektur.

Das passiert, wenn man RISC nur als Reduktion des Befehlssatzes sieht.
Sieht man es eher als Reduktion des Ablaufes (IBM Power: C=complexity
statt computing) durch ein Architekturschema mit einfachen Operationen
auf Register und davon getrennten einfachen Lade/Speicheroperationen,
also einer Load/Store-Architektur, dann ist der 6502 aufgrund des recht
komplexen Befehlsablaufs speicherindirekter Rechenoperationen kein
bischen RISC.

Unter den frühen 8-Bittern passt ins RISC-Schema eher RCA 1802.

von Rene B. (themason) Benutzerseite


Lesenswert?

Ich knüpfe mal an die RISC Diskussion an, da ich noch ein wenig 
Schwierigkeiten habe mir bestimmte Abläufe vorzustellen.
Das Prinzip das mit jedem Takt ein Befehl abgearbeitet wird ist klar. 
Das (je nach Anzahl der Stufen) dadurch eine Sprungvorhersage nötig wird 
ist auch klar. Und das die Einheiten (Fetch/Decode/Execute) parallel 
arbeiten und mit jedem Takt ein Ergebnis ausspucken auch.
Mein Problem beginnt bei der Umsetzung. Wenn ich z.b. einen einzigen 
Speicherbereich habe greife ich mit jedem Takt ja auf diesen Speicher 
lesend zu (um meinen Opcode rauszufischen). Aber wenn ich nun ein 
Ergebnis in den Speicher zurückschreiben möchte, muß ich ja eine andere 
Adresse, ein Datenwort und die Toggle-Leitung für RW/OE (klassisches 
SRAM) bedienen. Da ich aber ja auch noch Setup/Holdzeiten beachten muß, 
bzw erstmal einen Takt warten muß bevor ich mein Datenwort auf den 
Datenbus lege (nachdem ich diesen vorher in Tri-State geschaltet habe, 
damit möglicherweise 2 Ausgänge nicht gegeneinander treiben) habe ich ja 
schon mindestens zwei Takte um den Speicherzugriff umzuschalten.
Und da ist mein Problem. Das eine ALU oder ein Dekoder in einem Takt 
fertig sein kann, kein Thema. Aber wie läuft das bei Speicherzugriffen 
die allein durch die Umschaltung schon evtl. mehrere Takte benötigen ?
Oder wird da unterschieden zw. Systemtakt und Prozessortakt die in einem 
festen Verhältnis (2:1, 3:1, 4:1) stehen damit auch 
Lese/Schreiboperationen möglich sind während die Stufen fröhlich vor 
sich hintakten.
Oder ist da ein Denkfehler meinerseits ?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Grundlegend: das Speicherinterface ist nicht Bestandteil des Prozessors.
Dieses Interface muß natürlich so aufgebaut sein, dass der Code und die 
Daten hinreichend schnell bereitgestellt werden. Sonst muß der Prozessor 
Wartezyklen einlegen.

Auch bei AVR-Controllern brauchen Befehle, die auf den Programmspeicher 
gehen, mehrere Zyklen. Zugriffe auf den Datenspeicher laufen aber wegen 
der Harvard-Architektur parallel zu Programmspeicherzugriffen.

von Rene B. (themason) Benutzerseite


Lesenswert?

>Dieses Interface muß natürlich so aufgebaut sein, dass der Code und die
>Daten hinreichend schnell bereitgestellt werden

Wäre eine Lösung dieses Problems also das Speicherinterface mit der 
doppelten oder vierfachen Geschwindigkeit laufen zu lassen damit 
"parallel" zu einem Lese-befehl ein Schreib-Befehl ausgeführt werden 
kann ?

>Harvard-Architektur

Ok, da ist das Problem vllt nicht so gegeben, obwohl ich da ja u.u. auch 
mehrere Takte benötige. Aber ich dachte eher an von-Neumann, da man dort 
je nach Speicher einfach mehr "drankleben" kann, ohne direkt einen 2. 
Adress/Daten/Steuer-Bus haben zu müssen.

Wie könnte ein solches Speicherinterface aussehen ? Ich meine ich 
brauche ja auch u.u. noch 1-2 Takte Latenz damit der Prozessor bescheid 
weiß das der Speicher mal wieder nen Snickers braucht.

Ich arbeite bei mir momentan immer mit einer Trigger und Ready-Leitung. 
Dadurch kann der Speicher intern oder extern/schnell oder langsam sein. 
Aber die Zugriffe da, benötigen noch mehr Zeit (zw 4-6. Takte).
Irgendwie tu ich mich mit dem Speicherzugriff bzw "parallelen" Zugriff 
etwas schwer.

von (prx) A. K. (prx)


Lesenswert?

Rene Böllhoff schrieb:

> Mein Problem beginnt bei der Umsetzung. Wenn ich z.b. einen einzigen
> Speicherbereich habe greife ich mit jedem Takt ja auf diesen Speicher
> lesend zu (um meinen Opcode rauszufischen).

Solange du nur ein Speicherinterface hast, ist das mit einem Takt pro 
Befehl auf Lade/Speicherbefehle nicht anwendbar.

Daher führen Lade/Speicherbefehle entweder zu Befehlen, die mehr als 
einen Takt benötigen, oder es existieren mehrere Interfaces, getrennt 
nach Code und Daten. Letzteres ist bei Caches und bei internem Speicher 
von Controllern recht verbreitet (AVR, Cortex-M3, ...).

> Und da ist mein Problem. Das eine ALU oder ein Dekoder in einem Takt
> fertig sein kann, kein Thema. Aber wie läuft das bei Speicherzugriffen
> die allein durch die Umschaltung schon evtl. mehrere Takte benötigen ?

Es stellt sich die Frage, ob das wirklich sein muss. Oder ob durch 
geeignetes Pipelining Zugriffe teilweise überlappen können.

von (prx) A. K. (prx)


Lesenswert?

Lothar Miller schrieb:

> Grundlegend: das Speicherinterface ist nicht Bestandteil des Prozessors.

Kommt drauf an, wo man mit dem Begriff "Speicher" ansetzt. Wenn man 
Caches als Speicher sieht, dann sind diese durchaus Bestandteil des 
Prozessors. Wenn man das Interface erst jenseits der Caches sieht, dann 
kann man das ggf. getrennt betrachen.

von Valko Z. (hydravliska)


Lesenswert?

Hardvard Architecture,
Contrast with von Neumann architectures

Under pure von Neumann architecture the CPU can be either reading an 
instruction or reading/writing data from/to the memory. Both cannot 
occur at the same time since the instructions and data use the same bus 
system. In a computer using the Harvard architecture, the CPU can both 
read an instruction and perform a data memory access at the same time, 
even without a cache. A Harvard architecture computer can thus be faster 
for a given circuit complexity because instruction fetches and data 
access do not contend for a single memory pathway .

von (prx) A. K. (prx)


Lesenswert?

Beispiele für eine Architektur mit nur einem Speicherinterface und mit 
den daraus resultierenden Nebeneffekten hinsichtlich des kritischen 
Speichertimings sind die älteren ARM Cores (ARM2..ARM7).

ARM2 war noch für externen Speicher ohne Cache konzipiert und 
unterschied zwischen sequentiellen Zugriffen und nichtsequentiellen. 
Sprünge waren klarerweise nichtsequentiell, aber auch 
Lade/Speicherbefehle führten dazu, erstens beim Datenzugriff selbst, 
zweitens beim darauf folgenden Codezugriff. In vielen Systemen waren 
nichtsequentielle Zugriffe einen Takt langsamer. Entsprechendes Timing 
ist m.W. auch beim ARM7 noch dokumentiert.

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

A. K. schrieb:
> ARM2 war noch für externen Speicher ohne Cache konzipiert und
> unterschied zwischen sequentiellen Zugriffen und nichtsequentiellen.
> Sprünge waren klarerweise nichtsequentiell, aber auch
> Lade/Speicherbefehle führten dazu, erstens beim Datenzugriff selbst,
> zweitens beim darauf folgenden Codezugriff. In vielen Systemen waren
> nichtsequentielle Zugriffe einen Takt langsamer. Entsprechendes Timing
> ist m.W. auch beim ARM7 noch dokumentiert.

Richtig. Erst mit dem ARM8 Kern wurde die Pipeline auf fünf Stufen 
verlängert, so daß Address und Datenphase in unterschiedlichen Stufen 
ablaufen. Seit dem kann man register- und datenunabhängige, 
nichtsequentielle Speicherzugriffe ohne Wartezyklen ausführen, 
vorausgesetzt, der Speicher kann mithalten.

Bei den moderneren Cores mit dreistufiger Pipeline (Cortex-M) werden 
wiederum andere Tricks angewandt, um die Speicherzugriffe meist ohne 
Wartezyklen ablaufen zu lassen. Das ist aber nicht immer möglich.

@Rene:
Zum Thema Tri-State: Vergiss es. Keine moderne Architektur verwendet 
mehr echte Busse. Orientiere Dich lieber and den verschiedenen 
"Bus"-Systemen, die kommerziell eingesetzt werden.

Ich könnte an dieser Stelle auf einen Artikel verweisen: 
http://www.doulos.com/knowhow/arm/Migrating_from_AHB_to_AXI/
Mach' ich aber nicht, da es als Eigenwerbung verstanden werden könnte 
:-)

Gruß
Marcus

von Rene B. (themason) Benutzerseite


Lesenswert?

@Markus

Hätte ich das mit dem "Tri-State-Vergessen" so zu verstehen das ähnlich 
wie bei den FPGA's es keine bidirektionalen Busse mehr gibt, sondern nur 
noch unidirektionale, und die "schnelle" Umschaltung an der Anbindung 
zum RAM (egal ob SRAM/SDRAM/DDR-RAM) der Speichercontroller vornimmt ? 
Also das intern ein Data-In- und Data-Out-Bus existiert der das Timing 
auf intern einen Takt herunterbricht ?
Ich habe die Werbung gekonnt ignoriert und werde sie später gekonnt 
nicht durchlesen :-) ... Danke für den Hinweis.

Für mich ist das bisher immer so gewesen das die SRAMs/SDRAMs ja noch 
einen Bidirektionalen Bus haben, und die Anbindung an den 
Speichercontroller muß ja genauso funktionieren. Nur was intern (zw. 
Prozessor und Speichercontroller) gemacht wird ist ja was anderes. Daher 
bin ich mir nicht sicher ob ich o.g. richtig dargestellt habe.

von Duke Scarring (Gast)


Lesenswert?

Rene Böllhoff schrieb:
> SRAMs/SDRAMs ja noch
> einen Bidirektionalen Bus habe

Das gilt z.B. für QDR-SRAMs nicht mehr. Durch DDR auf den Datenleitungen 
bleibt die Pinzahl konstant und man trennt hin- und rücklaufende Daten.

Duke

von Rene B. (themason) Benutzerseite


Lesenswert?

@Duke

Ok, lassen wir mal die neuesten RAM-Typen weg. Um die 
1-Takt-Zyklus-Philosophie umzusetzen müsste ich also entweder den 
Prozessor-Takt im einem festen Verhältnis zueinander setzen, damit das 
System dem Prozessor bei jedem Takt ein Datenwort liefert bzw eines 
wegschreiben kann, oder aber dafür sorgen das der Datenbus für jede 
Richtung einmal vorhanden ist.
Wie das jetzt realisiert ist, ob ich das in einem getrennten 
Speichercontroller mache oder aber im FPGA "In-the-Box" ist ja erstmal 
egal. Aber wäre das ein Ansatz dafür ?
Ich wüsste sonst nicht wie man allein mit Überlappung der 
Schreib/Lese-Anweisungen auf einen Takt kommt ohne Wartezeiten zu 
bekommen, die ich ja beim Schreiben allein schon für das setzen und 
rücksetzen der WE-Leitung/Address/Datenleitungen brauche.
Irgendwie scheinen mir diese Überlegungen schwieriger zu sein, als ein 
Design in CISC (oder zumindest eben nicht gepipelined). Aber vllt brauch 
ich einfach mal nur ein einfaches, gut und vor allem vollständig 
dokumentiertes VHDL-RISC-Beispiel um da klarer zu sehen. Hätte da jemand 
mal vllt einen Link ? Ich hab schon einiges gefunden, aber eine 
wirkliche detaillerte Beschreibung aber so noch nicht.

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Rene Böllhoff schrieb:
> Hätte ich das mit dem "Tri-State-Vergessen" so zu verstehen das ähnlich
> wie bei den FPGA's es keine bidirektionalen Busse mehr gibt, sondern nur
> noch unidirektionale, und die "schnelle" Umschaltung an der Anbindung
> zum RAM (egal ob SRAM/SDRAM/DDR-RAM) der Speichercontroller vornimmt ?
> Also das intern ein Data-In- und Data-Out-Bus existiert der das Timing
> auf intern einen Takt herunterbricht ?

Genau so. Wobei bei Anbindung externer Speicher mit bidirektionalen 
Datenleitungen natürlich die Read-After-Write Zyklen immer noch 
auftreten können und dann auch intern sichtbar werden.

Was ich meinte bezog sich allerdings auf die internen Buszyklen. Wenn da 
schon Zwangspausen eingelegt werden, kannst Du auch mit idealem Speicher 
nichts mehr richten.

Bei typischen on-chip Bussen (die eigentlich keine mehr sind), kann z.B. 
die Adressphase des nächsten Transfers mit der Datenphase des aktuellen 
Transfers überlappen.

--
Marcus

von Rene B. (themason) Benutzerseite


Lesenswert?

>Bei typischen on-chip Bussen (die eigentlich keine mehr sind), kann z.B.
>die Adressphase des nächsten Transfers mit der Datenphase des aktuellen
>Transfers überlappen.

Genauso hab ich mir die Überlappung auch vorgestellt. Ich kam nur nicht 
damit zurecht das ich u.u. eben doch mehr als nur einen Takt benötige, 
das passt irgendwie nicht in das Pipelining "Muster" ohne das 
Wartezyklen entstehen.

Bei einem vielfachen des Systemtaktes gegenüber dem Prozessortakt lässt 
sich dann ein gepipelintes Design besser handlen denke ich. Ich glaube 
ich werd (wenn mein aktuelles Design fertig ist) das mal bei einer 
Überarbeitung mit einfließen lassen.

Danke für die Hinweise. Allerdings wäre ich noch dankbar wenn jemand ein 
gutes Tutorial bzw ein gutes (einfaches) Design mit ausführlicher Doku 
hat, damit ich mir das nochmal alles verinnerlichen kann.
Viele Infos hab ich hier aus dem Forum, aus Wikipedia, und viele Dinge 
sind auch einfach klar. Aber bei so manchen "Feinheiten" da komm ich 
schonmal ins Trudeln.

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

Sehr interessantes Thema,
Ich wollte auch eine Cpu zum Vertauschen von Werten in einem Array 
bauen.

> Danke für die Hinweise. Allerdings wäre ich noch dankbar wenn jemand ein
> gutes Tutorial bzw ein gutes (einfaches) Design mit ausführlicher Doku
> hat, damit ich mir das nochmal alles verinnerlichen kann.
> Viele Infos hab ich hier aus dem Forum, aus Wikipedia, und viele Dinge
> sind auch einfach klar. Aber bei so manchen "Feinheiten" da komm ich
> schonmal ins Trudeln.

vielleicht hilft Dir die Fundstelle weiter,
Yann Guidon beschäftigt sich schon länger mit CPU's

http://f-cpu.seul.org/cedric/unstable/
http://yasep.org/

Gibt es noch interessante Hinweise für Assamblerprogramme für die 
eigenen Softcores?



Es muss doch was Simples geben, was für den eigenen Befehlsatz 
abwandelbar ist. Am liebsten wäre mir der gas aus den Binutils, doch ich 
habe noch nie eine eigene CPU-Architektur angepasst.
Eine Skriptsprache würde ich auch nicht schlecht finden.

von Rene B. (themason) Benutzerseite


Lesenswert?

@Rene

Danke für den Link. Werd mir das mal anschauen.

Ich habe hier in der Codesammlung einen Parser geschrieben. Mit diesem 
lässt sich leicht ein einfacher Assembler zusammenbauen. Für die 
Simulation meines eigenen Softcores habe ich mir ein Assembler für 
diesen Softcore auf Basis des Parsers geschrieben. Falls interesse 
besteht kann ich das was ich dazu habe mal posten. Es lässt sich einfach 
erweitern und anpassen (allerdings sollte man nicht versuchen den Code 
zu verstehen wenn man mit dem Präprozessor auf Kriegsfuß steht :-))

Gruß
Rene :-)

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

Ja wenn du was hast, würde ich es mir schon mal anschauen.


Den Ansatz von tdasm http://www.penguin.cz/~niki/tdasm/
finde ich ganz vernünftig, Tabelle anpassen und nicht einen ganzen 
Parser selberschreiben und lexikalische Ausdrücke zerpflücken.

> zu verstehen wenn man mit dem Präprozessor auf Kriegsfuß steht :-))
>

So ist es nun auch wi(e)der nicht. ;-)

René

von AooA (Gast)


Lesenswert?

Fpga Kuechle schrieb:
> Es sollte recht einfach sein, sich einen Quick und dirty assembler per
> Spreadsheet (Excel;OO Calc)zusammenzubasteln. Ein Instruction wort mit
> seiner seinen fest zugeordneten Bitfeldern ist doch recht einfach auf
> einige Spalten Excel abgebildet, meinetwegen noch mit Auswahlmenü für
> die Operations-Mnemonics.

Für einfachste Befehle dürfte das gehen. Sobald man aber Sprung- und 
Speicherlabels verwendet und somit einen Relokationsmechanismus braucht, 
wird es kompliziert. Von weiteren Makro-Instruktionen mal gar nicht zu 
sprechen.

Rene Böllhoff schrieb:
>>Harvard-Architektur
>
> Ok, da ist das Problem vllt nicht so gegeben, obwohl ich da ja u.u. auch
> mehrere Takte benötige. Aber ich dachte eher an von-Neumann, da man dort
> je nach Speicher einfach mehr "drankleben" kann, ohne direkt einen 2.
> Adress/Daten/Steuer-Bus haben zu müssen.

Intern arbeiten die meisten Prozessoren mit einer Harvard-Architektur. 
Es gibt dann also einen Daten- und einen Instruktionsspeicher, 
ausgeführt als zwei Caches. Über die Anbindung an den externen 
Hauptspeicher kümmert sich dann die Cache-Logik, während der 
Prozessorkern frei von solchem Ballast ist. (Siehe beispielsweise MIPS)


Rene Böllhoff schrieb:
> Bei einem vielfachen des Systemtaktes gegenüber dem Prozessortakt lässt
> sich dann ein gepipelintes Design besser handlen denke ich.

von AooA (Gast)


Lesenswert?

> Rene Böllhoff schrieb:
> Bei einem vielfachen des Systemtaktes gegenüber dem Prozessortakt lässt
> sich dann ein gepipelintes Design besser handlen denke ich.

Ups, letztes Zitat nicht beantwortet: Wie erwähnt bietet sich zu diesem 
Zweck eher an, zwei interne Speicher bzw. Caches zu haben und einen 
Harvard-Kern zu bauen, während ein zusätzliche Logik die Anbindung an 
den Hauptspeicher übernimmt. Man braucht sich dann beim Pipelining nicht 
noch zusätzlich um unterschiedliche Taktraten zu kümmern.

Die Cache-Lösung ist mit grösster Wahrscheinlichkeit auch schneller: 
Speicher haben gegenüber Logik verhältnismässig niedrige Taktraten. Es 
macht also keinen Sinn, das Speicherinterface mit einem Vielfachen der 
Logiktaktrate zu fahren, weil man dann die Logik extrem ausbremst. 
Besser hält man den Prozessor von Zeit zu Zeit komplett an, um neue 
Daten oder Instruktionen vom Hauptspeicher in den Cache zu laden. So oft 
ist das nämlich gar nicht notwendig, da - Lokalitätsprinzip - nahe 
beieinanderliegende Instruktionen und Daten auch zeitlich nahe 
beieinander und oft wiederholt benötigt werden.

Beispiel Schleife: Wenn eine Schleife aus 20 Instruktionen 100 mal 
ausgeführt wird, so habe ich gerademal 20 Hauptspeicherzugriffe um die 
Instruktionen in den Cache zu laden. Arbeite ich direkt auf dem 
Hauptspeicher, so muss ich 2000 Mal darauf zugreifen. Da ich mit der 
Cache-Variante höhere Taktraten fahren kann, lohnt sich der 
Zusatzaufwand allemal.

von MT (Gast)


Lesenswert?

Tag,

Ich finde es richtig Interessant eine Prozessorarchitektur bzw. einen 
kleinen Mikrocontroller auf dem FPGA selbst zu entwerfen.

Gibt es speziell zu diesem Thema eigentlich gute Lektüre?
Was ich jetzt beim stöbern gefunden habe ist das Buch VHDL Synthese von 
Jürgen Reichert und Bernd Schwarz.
Dieses enthält laut Inhaltsverzeichnis ein komplettes Kapitel über den 
Entwurf einer RISC Architektur.

Dass dieses Buch brauchbar ist glaube ich, so oft wie es hier 
vorgeschlagen wird ;)

Aber wie sieht es speziell mit diesem Kapitel aus auch brauchbar oder 
eher so mit eingebaut weil es grade In ist?

Gruß Tobias

von KlausR (Gast)


Lesenswert?

Der Artikel "Building a RISC System in an FPGA" von Jan Gray ist 
unbedingt lesenswert. Er beschreibt neben dem RISC Prozessor auch wie 
man einen C Compiler anpasst um den Prozessor in C programmieren zu 
können. Den Draft Artikel und die Dokumentation gibts auf 
http://www.fpgacpu.org/xsoc/cc.html

Das Buch "FPGA prototyping by VHDL examples" von Pong P. Chu finde ich 
recht gut. Es beschreibt als ein Beispiel den Xilinx Picoblaze 
Prozessor.

Ich selbst habe in den letzten Jahren schon mehrere SOCs mit eigenem 
Prozessoren auf Xilinx S3e und Nexys2 boards zum laufen gebracht, 
inklusive eigenen Java-like Compiler, OS, GUI toolkit und Apps. Sowas 
braucht natürlich einige Zeit. Das DRAM auf den FPGA boards anzusprechen 
ist meist der komplexeste Teil wenn man keinen fertigen memory 
controller hat.

von Fpgakuechle K. (Gast)


Lesenswert?

MT schrieb:
> Tag,
>
> Ich finde es richtig Interessant eine Prozessorarchitektur bzw. einen
> kleinen Mikrocontroller auf dem FPGA selbst zu entwerfen.
>
> Gibt es speziell zu diesem Thema eigentlich gute Lektüre?
> Was ich jetzt beim stöbern gefunden habe ist das Buch VHDL Synthese von
> Jürgen Reichert und Bernd Schwarz.
> Dieses enthält laut Inhaltsverzeichnis ein komplettes Kapitel über den
> Entwurf einer RISC Architektur.
>
> Dass dieses Buch brauchbar ist glaube ich, so oft wie es hier
> vorgeschlagen wird ;)
>
> Aber wie sieht es speziell mit diesem Kapitel aus auch brauchbar oder
> eher so mit eingebaut weil es grade In ist?


Schwarz hat zwei Vorteile: Es behandelt VHDL nicht als 
Programmierspracxhe aus sicht eines Informatikers und es ist auf 
deutsch. Also gut für Einsteiger in VHDL, aber weniger geeignet um sich 
mit dem Design eines Prozessors auseinanderzusetzen. Das Kapitel mit dem 
risc -beispiel ist mir nicht besonders in Erinnerung geblieben. Da ist 
besser Christian Siemers" Prozessorbau" ISBN: 3-446-19330-8. Auf der 
beiliegenden CD findet sich der VHDL-Code. das Buch hat allerdings schon 
über 10 jahre auf dem Buckel und ist hinsichtliche der PLD-Möglichkeiten 
nicht mehr state of the art.

MfG,

von Fpgakuechle K. (Gast)


Lesenswert?

Rene Böllhoff schrieb:
> @Duke
>
> . Um die
> 1-Takt-Zyklus-Philosophie umzusetzen müsste ich also entweder den
> Prozessor-Takt im einem festen Verhältnis zueinander setzen, damit das
> System dem Prozessor bei jedem Takt ein Datenwort liefert bzw eines
> wegschreiben kann, oder aber dafür sorgen das der Datenbus für jede
> Richtung einmal vorhanden ist.
> Wie das jetzt realisiert ist, ob ich das in einem getrennten
> Speichercontroller mache oder aber im FPGA "In-the-Box" ist ja erstmal
> egal. Aber wäre das ein Ansatz dafür ?

Die FPGA internen Speicherblöcke sind in der Regel als Dual-Port 
ausgeführt, Da kann man locker in einem Takt lesen und schreiben. Daher 
kann man diese statt FF als Registerbank benutzen.

von Micha C. (Gast)


Lesenswert?

Hallo,

die Diskussion geht ja schon relativ tief in Details bestehender 
Prozessoren, aber wie wäre es denn mit einem Java-Bytecode-Prozessor?
Dokumentation ist vorhanden, reichlich Tools gibt es auch.

Allerdings kann ich nicht abschätzen, ob sich alle Bytecode-Befehle 
sinnvoll in VHDL umsetzen lassen. Vor allem virtuelle Funktionsaufrufe 
(für Vererbung) könnten aufwendig werden. Auch die eigentliche Anbindung
an die Hardware ist mir unklar.

Hätte auf jeden Fall auch einen gewissen Seltenheitswert.


Gruss

   Micha

von (prx) A. K. (prx)


Lesenswert?

Micha C. schrieb:

> Allerdings kann ich nicht abschätzen, ob sich alle Bytecode-Befehle
> sinnvoll in VHDL umsetzen lassen.

Naja, RISC geht anders. ;-)

Läuft bei einem Teil der Befehle auf komplexes Sequencing hinaus, für 
das man in traditionellen Architekturen Microcode einsetzt. Die Jazelle 
Engine in ARM9/11 erledigt nur 95% der ausgeführten Bytecodes selber und 
überlässt den Rest nativem ARM Code.

von xst (Gast)


Lesenswert?

Micha C. schrieb:
> Vor allem virtuelle Funktionsaufrufe
> (für Vererbung) könnten aufwendig werden.

Das läuft dann au eine CISC-Architektur hinaus. Die Daten laufen also 
nicht mehr straight-forward durch einen fixen Datenpfad, sondern werden 
von einem Mikrocodeprogramm sequentiell abgearbeitet. Und sowas ist 
schwer bis gar nicht zu pipelinen. Somit lässt sich kein wirklich 
schneller Prozessor bauen.

Gibt es eigentlich heute noch echte CISC-Architekturen? x86 ist ja 
bekanntlich ein CISC-Instruktionssatz, wird aber intern RISC-mässig 
verarbeitet.

von (prx) A. K. (prx)


Lesenswert?

xst schrieb:

> Gibt es eigentlich heute noch echte CISC-Architekturen? x86 ist ja
> bekanntlich ein CISC-Instruktionssatz, wird aber intern RISC-mässig
> verarbeitet.

Die Zerlegung komplexer Befehle in einfache Operationen kennzeichnet 
auch Microcode. Wenn du als x86 mit interner Befehlszerlegung in 
Einzelschritte als RISC betrachtest, dann trifft dies auch VAX und 68000 
zu. Nur erfolgt diese Zerlegung bei x86 meistens in Hardware statt 
Microcode und die Operationen spazieren nicht mehr im Gänsemarsch.

Zwar lassen sich CISC Befehle als Einheit schlecht pipelinen, für den 
Microcode muss das indes nicht gelten. Problematisch bei Java Bytecode 
ist jedoch die etwas pipelinewidrige Stack-Architektur.

Microcode ist übrigens keine Bedingung für CISC. Es gab auch welche 
ohne, wie Z8000. Hat Zilog zwar viele Transistörchen erspart, aber im 
Ausgleich so viel Zeit gekostet, dass es bei realer Verfügbarkeit ein 
Reinfall war.

Auch wenn sich Intels Core/Core i und AMDs K8 strukturell auf dieser 
Ebene recht ähnlich sehen: Es gibt beispielsweise auch den Atom, der 
etwas traditioneller gewirkt ist.

Ansonsten muss man nur mal von der Spitze weg in andere Gefilde blicken 
und man findet CISC. Nämlich im Controller-Sektor. Renesas M16C/80 und 
M32C haben eine blütenreine hochkomplexe CISC ISA, auch von der 
Implementierung ist nichts Gegenteiliges bekannt. Und ARMs Java Engine 
Jazelle hatte ich ja bereits genannt.

von (prx) A. K. (prx)


Lesenswert?

PS: Der interne Code von AMD ab K7 definiert auch Makroops wie
   <mem> = <mem> <op> <reg>/<const>
was dem klassischen RISC-Bild eindeutig widerspricht. In diesem Sinn 
zerlegt AMD den x86 Code also nicht in RISC Operationen sondern in 
einfachere schematischere CISC Operationen.

Bei Intel war es anno PentiumPro..PentiumIII sowie Pentium 4 noch 
einfach, die internen Codes waren ausgesprochen simpel strukturiert und 
letzlich RISC-artig. Mit dem Pentium-M und den Core/Core i entwickelte 
sich der interne Code wieder sukzessive vom RISC-Schema weg, etwas in 
Richtung AMD.

von Rene B. (themason) Benutzerseite


Lesenswert?

@Micha

Dieser Gedanke ist mir auch schon gekommen :-))

Aber wie die beiden vorherigen Posts schon beschrieben haben, dürfte der 
Java-Bytecode nicht, oder nur mit großem Aufwand auf einem FPGA direkt 
interpretiert werden können. Da ist es schon einfacher eine einfache 
Architektur aufzusetzen (egal ob bestehend oder eigens entworfen) und 
auf dieser Basis dann einen Java-Bytecode-Interpreter aufzuziehen.

von AooA (Gast)


Lesenswert?

Was meint ihr zum MSP430? Der Instruktionssatz jedenfalls scheint recht 
einfach und doch mächtig.

von MT (Gast)


Lesenswert?

AooA schrieb:
> Was meint ihr zum MSP430? Der Instruktionssatz jedenfalls scheint recht
> einfach und doch mächtig.

Halt ich persönlich für eine super Idee.
Gibt da sogar was bei OpenCores in der Richtung (leider in Verilog):
OpenMSP430:
http://opencores.com/project,openmsp430

Ich hätte selber jetzt vom Instruktinossatz an etwas 8051 kompatibles 
gedacht.

von Harald F. (hfl)


Lesenswert?

Ich habe schonmal einen 8051 im FPGA nachgebaut, so richtig from 
scratch. Das ist schon spassig, keine Frage, allerdings braucht man dazu 
auch einiges an Zeit und Ausdauer. Und man braucht eine 
Vergleichsmöglichkeit mit dem Original. Die verfügbare Dokumentation hat 
jedenfalls nicht gereicht. Irgendwann landet man bei so verrückten 
Fragen wie: Was macht der Prozessor beim Befehl "pop SP"?

Viel Erfolg!
Harald

von (prx) A. K. (prx)


Lesenswert?

Harald Flügel schrieb:

> jedenfalls nicht gereicht. Irgendwann landet man bei so verrückten
> Fragen wie: Was macht der Prozessor beim Befehl "pop SP"?

So verrückt sind diese Fragen garnicht. Bei den ersten x86-Generationen 
hat anhand genau solcher Fiesematentchen die verschiedenen Varianten 
unterschieden.

von Bernhard R. (barnyhh)


Lesenswert?

Harald Flügel schrieb:
> Und man braucht eine
> Vergleichsmöglichkeit mit dem Original. Die verfügbare Dokumentation hat
> jedenfalls nicht gereicht. Irgendwann landet man bei so verrückten
> Fragen wie: Was macht der Prozessor beim Befehl "pop SP"?

Es gibt noch eine andere Alternative: eine extrem saubere Dokumentation!
Die "Principles Of Operation" der IBM /360-Architektur umfaßte - 
vorsichtig geschätzt - allein gut 500 Seiten zur Beschreibung des 
Instruktionssatzes einschließlich der Sonderfälle und der 
modellabhängigen bzw. "kritischen" Operationen (z.B. Store an die Stelle 
der nächsten Instruktion - ein Graus in der x86-Architektur).

Bernhard

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

Das ganze ist auch etwas globaler zu betrachten. Wollt ihr eine 
theorische Rechenarchitektur bauen oder etwas was auch dann praktisch 
eingesetzt werden kann?


Dann muss ein Assembler oder besser ein C-Compiler nachgezogen werden.
Der MSP430 oder ein AVR hat den Vorteil es gibt schon Tools für die 
Architektur. Das muss alles bedacht werden.

Oft wird auch die MIPS Architektur nachgebaut, soll sich für FPGA 
Umsetzung sehr gut eignen, die hat hier noch keiner erwählt.

von Rene B. (themason) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hier mal von meiner Selbstbau-CPU der Befehlssatz.

Nahezu jeder Befehl lässt sich bedingt ausführen. Ausnahmen sind die 
Immediate Ladebefehle und die Befehle des Condition-Processing.
Ein Makro-Assembler dafür ist auch im Entstehen.
Das ganze ist zwar noch sehr langsam, da ich für ein universelles 
Speicherinterface viele Takte benötige, aber ich denke durch pipelining 
dürfte die CPU noch um einiges schneller werden. Mal schauen wie weit 
ich da komme. Bei Problemen bzw Hirnknoten werd ich mich bestimmt 
nochmal melden :-)
Falls interesse besteht kann ich die CPU hier ja auch mal posten bzw 
einen Artikel daraus machen. Hier mal eine kurze Feature Liste :

- 16Bit Daten&Adressraum (der Adressraum wird evtl auf 32Bit 
aufgestockt)
- 16x16Bit Register (im Moment nur 8x16Bit, um etwas Platz zu sparen)
- benötigt ca 47% der Slices eines Spartan 3-200
- nahezu alle Befehle bedingt ausführbar
- Bedingungsprozessor mit 4 benutzer bedingungen
- einfache Schleifenkonstrukte mit Mark/Loop (fußgesteuerte Schleife)
- Alle Instruktionen immer 16Bit breit (tlw. nachteillig, aber 
übersichtlich)

Ist bestimmt kein Vorzeigeprozessor, oder besonders ausgetüftelt, aber 
für meine erste Selbstbau-CPU unter VHDL denke ich brauchbar.

von (prx) A. K. (prx)


Lesenswert?

Wie funktioniert bei dir ein Vergleich zweier Werte mit Vorzeichen?

Traditionell gibt es da zwei Ansätze, wenn man sich schon für ein 
Statusregister entscheidet: Separate Vergleichsbefehle (IBM Tradition) 
oder separate Flags (z.B. Overflow-Flag).

Ist der Akkumulator ("acc") ein spezielles der 16(8) Register?

von Rene B. (themason) Benutzerseite


Lesenswert?

@A.K.

Ich habe in brute-force-Manier zwei Vergleicher-Zweige (einen Signed und 
einen Snsigned) gemacht und die Auswahl übernimmt ein Flag im 
Statusregister.
Bei den Shift Operationen geht das genauso. Da habe ich Flags für 
logischen/arithmetischen Shift sowie für Rotate.

Edit : Ich habe auch noch nicht alles bis ins kleinste 
durchgetestet/simuliert, da ich erstmal den Assembler fertig machen 
wollte damit das Testen und Simulieren einfacher wird.

Edit 2 : Es sind noch 16 SW-Interrupts vorhanden. 15 Hardware-Interrupts 
werden denke ich auch noch folgen. Aber da ist noch nicht viel getestet.

von (prx) A. K. (prx)


Lesenswert?

Rene Böllhoff schrieb:

> Ich habe in brute-force-Manier zwei Vergleicher-Zweige (einen Signed und
> einen Snsigned) gemacht und die Auswahl übernimmt ein Flag im
> Statusregister.

Aua! Zuviel 6502 programmiert? Will hoffen, dass du nicht auch noch 
einen Compiler dafür stricken willst... Sowas macht ähnlich viel Freude 
wie Bankswitching bei den PICs.

Sorry, wills dir nicht madig machen, aber solche Stati sind ein Graus.

von Rene B. (themason) Benutzerseite


Lesenswert?

Der Akku ist ein 32-Bit Register (für die Multiplikation die auch im 
moment nur unsigned ist). Das ist auch noch eine "unschönheit" an meinem 
Design. Die ALU bedient sich zweier Register, das Ergebnis landet aber 
immer im Akku und muß mit einem weiteren Befehl erst wieder in ein 
Register transferiert werden. Ich hab das gemacht damit das Register 
nicht automatisch überschrieben wird, sondern man sie freie wahl hat wo 
das Ergebnis landen soll.

Na ja ... mit dem 6502 hab ich angefangen :-)
Die signed/unsigned Problematik (bei Vergleichen, Status-Reg und 
Multiplikation und ALU) liegt mit sowieso noch was schwer im Magen.
Muß mir da auch mal anschauen wie das bei anderen Architekturen gelöst 
ist. So zufrieden bin ich damit ohnehin noch nicht.

von Rene B. (themason) Benutzerseite


Lesenswert?

Von einem Compiler bin ich noch soweit entfernt wie ein Tretroller von 
der Saturn V ;-)
Aber ich glaub aus solchen "Fehltritten" (selbst wenn es im ersten 
Moment erstmal ein Erfolg ist) lernt man auch. Was mich halbwegs erfreut 
ist das ich einen relativ einfachen Prozessor der aber auch schon das 
was ein Prozessor können muß beherrscht entworfen hab der auch noch 
einigermaßen wenig Ressourcen benötigt. Lässt sich sicherlich nicht mit 
einem Picoblaze (von der Größe her) oder mit einem Microblaze (von den 
Features und der Geschwindikeit) vergleichen, aber das war ja auch nicht 
die Intention :-)

Edit : Was wäre denn der bessere Weg ? Die Vergleiche und 
Logisch/Arithmetisch/Rotierenden Shift Befehle wirklich auszudekodieren 
(also ala SLL, SLR, SAL, SAR, ROL, ROR und CMPS, CMPU) ? Evtl wäre da ja 
noch Platz im Opcode-Raum.

von (prx) A. K. (prx)


Lesenswert?

Rene Böllhoff schrieb:

> Muß mir da auch mal anschauen wie das bei anderen Architekturen gelöst
> ist. So zufrieden bin ich damit ohnehin noch nicht.

Traditionell wie 68xx, 68xxxx, ARM: 4 Flags, NZVC wie 6502, aber 2*7 
Bedingungen. Wird hier natürlich eng.

MIPS, Alpha: Ähnlich wie bei dir, nur Standardregister statt Flags, d.h. 
Ergebnis eines Vergleichsbefehls landet als 0/1 im Zielregister. Aber da 
hat man dann getrennte Vergleichsbefehle für signed/unsigned, 
grösser/kleiner usw.

IBM 360/POWER: willst du nicht wirklich wissen ;-).

Kannst dir als Anregung die Thumb2-Variante vom ARM mal ansehen. 
Bedingte Ausführung aller Befehle ist ziemliche Ressourcenverschwendung, 
ganz besonders bei 16bit-Codierung. Dort gibt es einen Präfix-Befehl, 
der den nächsten maximal 4 Befehlen die Bedingung vorgibt, d.h. eine 
Bedingung für alle, und ob jeweils wahr oder falsch. Kostet zwar bei 
einfachem Ablauf einen Takt, setzt aber anderswo dringender benötigte 
Bits im Opcode frei.

von Rene B. (themason) Benutzerseite


Lesenswert?

Danke für die kleine Übersicht.

Aber soweit ich weiß gibt es beim 6502 keine speziellen signed/unsigned 
Vergleichsbefehle. Da gibt es meine ich nur einen CMP-Befehl und das 
wars. Ist aber auch schon ein paar Jährchen her das ganze.

Na ja. An eine IBM360 hatte ich bestimmt nicht vor mich anzulehnen :-)

>Bedingte Ausführung aller Befehle ist ziemliche Ressourcenverschwendung,
>ganz besonders bei 16bit-Codierung.

Kannst du mir das mal genauer erklären ? Mir ist nicht klar wie das 
zusammenhängt a) mit dem Ressourcenverbrauch und b) warum speziell 
16Bit-Codierung (meinst wegen den Bits für die Bedingung die mir dann im 
Opcode "fehlen") ?!

von (prx) A. K. (prx)


Lesenswert?

Rene Böllhoff schrieb:

> Design. Die ALU bedient sich zweier Register, das Ergebnis landet aber
> immer im Akku

Was eigentlich nur sinnvoll ist, wenn z.B. acc=R0 gilt. Die obere 
Produkthälfte wird (wurde) nicht selten in einem separaten Register 
verbuddelt. Solange man kein Pipelining im Auge hat ist das vertretbar - 
IBM hatte das gemacht und anlässlich des Übergangs von Power zu PowerPC 
in den Hintern gebissen.

von (prx) A. K. (prx)


Lesenswert?

Rene Böllhoff schrieb:

> Aber soweit ich weiß gibt es beim 6502 keine speziellen signed/unsigned
> Vergleichsbefehle.

Aus den 4 Flags des 6502 lassen sich alle 14 üblichen Bedingungen 
ableiten, darunter sowohl "grösser mit Vorzeichen" als auch "grösser 
ohne Vorzeichen". Die entsprechenden Sprungbefehle mit Vorzeichen 
fehlten beim 6502, aber der Vorgänger 6800 hatte sie alle.

Wobei man natürlich bei einer Architektur mit vollständig symmetrischem 
Vergleichsbefehl ein paar Bedingungen einsparen kann (z.B. "grösser" vs. 
"kleiner").

> Mir ist nicht klar wie das zusammenhängt a) mit dem Ressourcenverbrauch

Alle Befehle eines konkreten Programmablaufs, die nicht wirklich bedingt 
ausgeführt werden, verschwenden bei dir 3 Bits von 16 des Opcode-Space. 
Die sich anderswo ggf. besser einsetzen liessen.

> und b) warum speziell 16Bit-Codierung

3 "verlorene" Bits in einem in 16 Bits codierten Befehl tun mehr weh als 
4 Bits von 32 (ARM). In Thumb1 gabe es deshalb garkeine bedingte 
Ausführung, was aber hinsichtlich Laufzeit auch nicht so der Knüller 
war, also brachte Thumb2 den erwähnten Präfix.

von Rene B. (themason) Benutzerseite


Lesenswert?

Der Hintergedanke mit dem getrennten Akku (der wirklich getrennt ist, 
also nicht auf irgendein Register gemappt wird) war der das ich aus dem 
Akku eine MAC-Einheit mache die dann evtl über ein dann eingespartes 
Flag im SR bei jedem ALU-Befehl mitläuft.

Ok. Das mit den (wir bauen uns aus den Status-Flag-bits die 
entsprechende Bedigung heraus) hab ich verstanden. Das hatte ich auch so 
in erinnerung.

Mit den "fehlenden" Bits ist dann klar. 3 von 16 sind eben mehr als 4 
von 32 :-)
Der Ursprungsgedanke war auch so ausgelegt das ich versuche wenige 
Befehle zu implementieren, habe dann aber gemerkt das das dann nur mit 
immensem SW Aufwand zu machen ist. Daher z.b. auch die SWAP8 und SWAP4 
Befehle. Mit der ALU hätte man sich nen Wolf programmiert (Shift-Wert 
laden, shiften, zurückschreiben, usw).

von (prx) A. K. (prx)


Lesenswert?

Rene Böllhoff schrieb:

> Der Hintergedanke mit dem getrennten Akku (der wirklich getrennt ist,
> also nicht auf irgendein Register gemappt wird) war der das ich aus dem
> Akku eine MAC-Einheit mache die dann evtl über ein dann eingespartes
> Flag im SR bei jedem ALU-Befehl mitläuft.

Ja, aber ich fürchte du verlierst mehr als du gewinnst. Es sei denn du 
baust einen DSP. Datenrechnung ist bei normalen Programmen nicht so 
dominant, als dass sich sowas lohnt.

Denk übrigens auch an die Frage der Adresserzeugung. Bei dir bestehen ja 
recht wenig Möglichkeiten, mit Speicher überhaupt etwas anzufangen. Die 
Lade/Speicherbefehle hatte ich im zweiten Anlauf gefunden ;-) aber eine 
Antwort auf die Frage, wie in leidlich ökonomischer Weise eine Adresse 
der sehr beliebten Form [pointer+offset] im RegX landet, noch nicht.

von Rene B. (themason) Benutzerseite


Lesenswert?

Du hast mich irgendwie entlarvt :-)
Eine DSP Option hatte ich nicht nur im Kopf gehabt sondern war auch 
irgendwo mit der Ausgangspunkt. Bei meinem Audio-DSP habe ich zwar reine 
DSP-Befehle, aber alles andere nicht. Da kam mir der Gedanke das ich 
zwar eine MAC-Einheit brauche, diese aber ja durchaus von einem 16-Bit 
Core gesteuert und gefüttert werden kann. Das ganze ist aber nachher 
soch "ausgeartet" das ein "normaler" Prozessor daraus entstanden ist.

Das mit der Adresserzeugung ist in der Tat echt blöd gemacht. Da hätte 
ich mehr Hirnschmalz reinstecken müssen. So sachen wie Indirekt 
indiziert, Autoincrement und dergleichen wären sinnvoll gewesen.

Einen Wert (egal ob Datum oder Adresse) lässt sich nur über 2 Move 
Befehle machen. Dafür gibt es die Move High-Byte/Low-Byte Befehle.

Um also von Adr 0x2345 einen Wert nach Register 1 zu laden muß man 
folgendes machen :

6234 MOVE H#$23, R4
7234 MOVE L#$45, R4
5041 MOVE A, [R4], R1

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.