Noch einer (f8); 8bit-Computing mit FPGA

OP #7694175
Lesenswert?

Nun gibt es hier einen weiteren Versuch, eine neue 8-Bit-Architektur vorzustellen. Alles ist noch vorläufig, vom Namen (f8, nicht zu verwechseln mit dem Fairchild F8 aus den 1970ern), bis zum Instruktionssatz (wo aber nur noch geringe Änderunge zu erwarten sind) und der Opcode-Map.

Schon lange hatte ich mit dem Gedanken gespielt, mich an einer eigenen 8-Bit-Architektur zu versuchen. Den Ausschlag gab dann die (inzwischen teils zurückgenommene) Abkündigung der STM8 durch ST, da ich diese als eine der elegantesten bisherigen 8-Bit-Architekturen ansehe.

Hauptziel war es, eine effiziente Zielarchitektur für C-Compiler zu entwickeln, insbesondere im Hinblick auf den Speicherbedarf. Aufgrund meines Hintergrunds im Übersetzerbau ist mir dies vermutlich besser gelungen, als die Architektur auf effiziente Implementierbarkeit in Hardware zu optimieren.

Es fehlt noch vieles (insbesondere nahezu alle Dokumentation), aber es gibt bereits ein bischen Code (https://sourceforge.net/p/sdcc/code/14908/tree/branches/f8/):

  • Mein erster Versuch einer Implementierung in Verilog. Single-cycle, benötigt recht aufwendigen Speicher mit mehreren Ports.
  • Mein zweiter Versuch einer Implementierung in Verilog. Multi-cycle. Kommt mit deutlich einfacherem Speicher aus.
  • Jeweils ein einfaches SoC dazu (f8-Kern, Speicher, Watchdog, Timer, Interrupt controller, 2xGPIO).
  • Letzteres habe ich bisher auf zwei FPGA-Boards portiert: iCEBreaker und GateMateA1-EVB.
  • Einfache Beispielprogramme (LED blinken, "Hello, world!" via Software-emuliertem UART, Dhrystone, etc) laufen.
#7698918
Lesenswert?

Hauptziel war es, eine effiziente Zielarchitektur für C-Compiler zu entwickeln, insbesondere im Hinblick auf den Speicherbedarf. Aufgrund meines Hintergrunds im Übersetzerbau ist mir dies vermutlich besser gelungen, als die Architektur auf effiziente Implementierbarkeit in Hardware zu optimieren.

Was genau hast Du denn hier implementiert, was die Codedicht ggü. AVR oder STM8 verbessert?

#7698978
Lesenswert?

Wf88 schrieb:

Philipp Klaus K. schrieb:

(f8, nicht zu verwechseln mit dem Fairchild F8 aus den 1970ern)

Nicht böse gemeint: das ist doch scheisse so, gleich beim Namen schon ein AAAABER

+++ Eine Reinkarnation des Fairchild F8 waere immerhin interessant (gewesen).

Wer dem STM8 nachgetrauert haette, haette sich ja auch mal (nur als Beispiel) bei den RL78 umsehen koennen. Und da gibt es durchaus noch mehr Familien, die von der "Machart" aehnlich sind...

OP #7699218
Lesenswert?

Tim  . schrieb:

Nett!

Eine bischen Dokumentation wäre hilfreich, vor allem da die Navigation durch den Source auf sourceforge nicht so einfach ist. (warum nicht Github?)

Ein klein wenig Dokumentation kam inzwischen dazu: https://sourceforge.net/p/sdcc/code/HEAD/tree/branches/f8/f8/hardware/

SourceForge, da SDCC dort ist, und der f8 durch Erfahrungen aus dem Schreiben von SDCC-Backends für andere Architekturen motiviert ist. Wenn der f8 weitere Fortschritte macht, könnte sich das noch ändern (Simulator, Compiler und Assembler würden bei SDCC bleiben).

Anscheinend liegen auch die Sources beider CPU-Varianten im gleichen Verzeichnis? Etwas verwirrend.

Es gibt ein paar Quelldateien, die in beiden Varianten verwendet werden.

Philipp

OP #7699446
Lesenswert?

Motopick schrieb:

Wer dem STM8 nachgetrauert haette, haette sich ja auch mal (nur als Beispiel) bei den RL78 umsehen koennen.

Dem RL78 mangelt es im Vergleich zum STM8 am Stackpointer-relativen Adressierungsmodus. Es gibt ihn beim RL78 nur bei wenigen Befehlen. Ein effizienter, bei vielen Befehlen verfügbarer Stackpointer-relativer Adressierungsmodus ist sehr nützlich zum effizienten Zugriff auf lokale Variablen in C-Programmen.

OP #7699482
Lesenswert?

Tim  . schrieb:

Was genau hast Du denn hier implementiert, was die Codedicht ggü. AVR oder STM8 verbessert?

Der STM8 ist bezüglich der Codegröße bereits recht gut, insbesondere durch seinen effizienten Stackpointer-relativen Adressierungsmodus. Insbesondere im Vergleich zum Z80 und Rabbit fällt auf, dass der STM8-Code oft effizienter ist. Die Ausnahme ist Code, bei dem die meisten lokalen Variablen in die Register des Z80 passen, oder bei denen die etwas mächtigeren 16-Bit-Befehle des Rabbit hilfreich sind. Daher war es naheliegend, dem f8 ein paar Register zu geben, die sich (wie beim Z80) als zweiten Operanden neben dem Akkumulator verwenden lassen, und einige 16-Bit-Befehle.

Das hat anscheinend funktioniert: obwohl an den stm8, z80 und r3ka-Ports von SDCC viele Jahre gearbeitet wurde, erzeugt der im Vergleich noch etwas einfache f8-Port meist bereits kompakteren Code.

P.S.: Natürlich wurde gegenüber dem STM8 auch auf manches verzichtet, z.B. Divisionsbefehle, Zero-Page-Adressierungsmodus und einige komplexere Adressierungsmodi.

#7699706
Lesenswert?

Philipp Klaus K. schrieb:

Motopick schrieb:

Wer dem STM8 nachgetrauert haette, haette sich ja auch mal (nur als Beispiel) bei den RL78 umsehen koennen.

Dem RL78 mangelt es im Vergleich zum STM8 am Stackpointer-relativen Adressierungsmodus. Es gibt ihn beim RL78 nur bei wenigen Befehlen. Ein effizienter, bei vielen Befehlen verfügbarer Stackpointer-relativer Adressierungsmodus ist sehr nützlich zum effizienten Zugriff auf lokale Variablen in C-Programmen.

Ist mir bei meinem Ausflug in die RL78-Welt gar nicht so aufgefallen. Zum Laden der Parameter von und zum Stack hat es jedenfalls gereicht. Und in einem Assemblerprogramm gab es dann auch, wie ich fand, bessere Alternativen als relativ zum Stack zu adressieren. Ich werde mir interessehalber mal anschauen, wie der von mit benutzte Compiler damit umgeht.

Die Geruechte zum vorzeitigen Ableben des STM8 haben sich ja auch nicht bestaetigt. Waere ja auch schade drum.

#7700714
Lesenswert?

Sieht sehr CISCig aus, und schon fast nach einem 16 bit Prozessor. Um das in einem effizienten 8-bit Datenpfad unterzubringen benötigt man viele Taktzyklen pro Befehl.

Ich frage mich immer, warum es so weniger 16 bit Prozessoren gibt - eigentlich ja nur den MSP430. Viele 8bit Architekturen kommen aber mit 16 bit Registern, was ja zeigt, dass 8 bit eigentlich nicht genug sind (AVR, STM8, etc.). Warum also nicht gleich 16 bit? In einer Technologie <0.5µm sollte ein 16 bit Datenpfad eigentlich kein Problem sein. Heutzutage mit <100nm, sowieso nicht.

OP #7700740
Lesenswert?

Tim  . schrieb:

Sieht sehr CISCig aus, und schon fast nach einem 16 bit Prozessor. Um das in einem effizienten 8-bit Datenpfad unterzubringen benötigt man viele Taktzyklen pro Befehl.

Ich frage mich immer, warum es so weniger 16 bit Prozessoren gibt - eigentlich ja nur den MSP430. Viele 8bit Architekturen kommen aber mit 16 bit Registern, was ja zeigt, dass 8 bit eigentlich nicht genug sind (AVR, STM8, etc.). Warum also nicht gleich 16 bit? In einer Technologie <0.5µm sollte ein 16 bit Datenpfad eigentlich kein Problem sein. Heutzutage mit <100nm, sowieso nicht.

Tatsächlich haben meine beiden Implementierungen einen 16-Bit-Datenpfad innerhalb der CPU, und ich hätte den f8 wohl oben besser als 8/16-Bit-Architektur bezeichnen sollen. Dennoch wäre eine 8-Bit-Implementierung möglich.

Um einen hinreichend großen Speicher zu adressieren, und eine gute Zielarchitektur für C-Compiler zu sein, müssen nunmal 16-Bit Daten (für Zeiger und für int) effizient verarbeitet werden können. Andererseits wollte ich aber auch 8-Bit Daten gut unterstützen, damit, wo diese ausreichen, kein Speicher verschwendet wird. D.h. insbesondere, dass die Opcodes 8-Bit sind (mit Präfixbytes für seltener genutzte), und char 8 Bit hat.

#7700832
Lesenswert?

Tim  . schrieb:

Ich frage mich immer, warum es so weniger 16 bit Prozessoren gibt - eigentlich ja nur den MSP430.

Du meinst vermutlich Microcontroller, nicht -Prozessoren.

16-Bit-Prozessoren waren z.B. 8088/8086 bzw. 80188/80186. Lange davor gab es den TMS9900:

https://en.wikipedia.org/wiki/TMS9900

Pedanten bezeichneten auch den Motorola 68000 als 16-Bit-Prozessor (obwohl der mit 32-Bit-Registern arbeitete, enthielt er nur eine 16-Bit-ALU, und hatte auch nur einen 16-Bit-Datenbus) - aber das ist eine Spitzfindigkeit, das Ding hatte einen 32-Bit-Befehlssatz.

16-Bit-Microcontroller waren

Motorola 68HC12 und 68HC16

https://en.wikipedia.org/wiki/Motorola_68HC12 https://en.wikipedia.org/wiki/Motorola_68HC16

Intel MCS-96

https://en.wikipedia.org/wiki/Intel_MCS-96

#7700857
Lesenswert?

Tim  . schrieb:

Ich frage mich immer, warum es so weniger 16 bit Prozessoren gibt

Wenn den 8-Bittern der Adressraum ausgeht, löst man das einfacher durch 32-Bitter, als durch 16-Bitter, die das gleiche Problem haben. Gerade die MSP430 sind ein Beispiel dafür. Jenseits 64 KB gibt es da zwar, aber die Eleganz der rein auf einen einzigen 64 KB Adressraum optimierten Architektur blieb bei diesem Schritt auf der Strecke.

Gerade als gute Zielarchitektur für C hat man mit 8/16-Bit jenseits 64 KB seine liebe Not, und mit Pointern unterschiedlicher Länge in unterschiedliche Adressräume zu tun. Mit 32-Bit ist das völlig verschwunden.

#7700872
Lesenswert?

(prx) A. K. schrieb:

Harald K. schrieb:

16-Bit-Microcontroller waren

Zwei schöne Gründe, weshalb man sich nicht unbedingt mit 16-Bittern beschäftigen will, sind 65816 und MAXQ2000. :)

Man koennte die Aufzaehlung noch mit den Controllern der eCog1x-Serie fortsetzen. 24 bit Adressraum fuer Code, aber nur 16 bit fuer Daten. Und die MMU kann immer nur genau 2 Bereiche aus dem gesamten Datenraum in dieses 64 k Fensterchen hineinmappen.

Jenseits 64 KB gibt es da zwar, aber die Eleganz der rein auf einen einzigen 64 KB Adressraum optimierten Architektur blieb bei diesem Schritt auf der Strecke.

Auch sehr schoen beim Zilog Z8002 zu sehen. Die ganze "Einfachheit" und "Eleganz" ist dahin, wenn man mehr als 64 KB braucht. Die aufgebohrten MSP430 folgen da nahtlos.

OP #7700886
Lesenswert?

(prx) A. K. schrieb:

Gerade als gute Zielarchitektur für C hat man mit 8/16-Bit jenseits 64 KB seine liebe Not, und mit Pointern unterschiedlicher Länge in unterschiedliche Adressräume zu tun. Mit 32-Bit ist das völlig verschwunden.

Ich habe da eher den Vergleich mit kleinen 8-Bittern (Padauk, MCS-51) im Blick: Mit 8/16 Bit hat man die Möglichkeit, elegant einen einheitlichen 64KB-Adressraum zu verwenden (wie beim STM8, Z80, oder hier beim f8). Die Probleme mit unterschiedlichen Zeigertypen sind verschwunden.

Klar, wenn man noch mehr Speicher braucht, wiederholt sich das gleiche Spiel mit 16/8 vs 32 Bit, und dann nochmal mit 32 Bit vs. 64 Bit.

Ich sehe den Platz des f8 unterhalb von 32-Bittern wie RISC-V. Wie viel Platz es unterhalb des f8 für diskrete µC noch gibt, weiß ich nicht. Aber irgendwann lohnt es sich nicht mehr, beim Prozessor ein paar Gatter zu sparen, wenn die I/O-Pads schon die Größe des Die vorgeben. Für Softcores in FPGA sieht es da natürlich anders aus, da kann man die beim Prozessor eingesparten LUT ja immer noch anderweitig nutzen.

Philipp

P.S.: Beim STM8 ist das über-64KB-hinausgehen teils relativ elegant gelöst. Man kann den Code im Flash nach oben legen, und alle Daten in die unteren 64KB des Adressraums. Somit bleiben alle Objektzeiger bei 16 Bit, lediglich Funktionszeiger werden 24 Bit (so z.B. in SDCC wenn man mit -mstm8 --model-large kompiliert).

#7701117
Lesenswert?

Philipp Klaus K. schrieb:

Wie viel Platz es unterhalb des f8 für diskrete µC noch gibt, weiß ich nicht.

So sieht eine moderne MCU aus:

https://cpldcpu.wordpress.com/2024/05/01/decapsulating-the-ch32v203-reveals-a-separate-flash-die/

Gerade in China gibt es gerade viele Bestrebungen, low-cost Prozesse für PMIC und MCU zu entwickeln. Dazu werden ältere Logikprozesse vereinfacht, um bei gleichbleibenden Kosten die Logikdichte zu erhöhen.

#7701194
Lesenswert?

Motopick schrieb:

Auch sehr schoen beim Zilog Z8002 zu sehen. Die ganze "Einfachheit" und "Eleganz" ist dahin, wenn man mehr als 64 KB braucht. Die aufgebohrten MSP430 folgen da nahtlos.

Ja, die Probleme starten immer, wenn man den "nativen" Addressraum überschreitet. Trotzdem scheint es immer die Tendenz zu geben, Architekturen zu nutzen, die für die aktuelle Anwendung gerade zu klein sind.

z.B. einfache Sensoranwendung benötigt vielleicht 8kb Flash und 1kb Ram. Das sind typische Daten von Low-end MCUs für <0.20€.

Der ADC liefert aber nun 10bit -> 8 bit Datenregister reichen nicht aus. Das Programm ist größer als 256 bytes -> 8 bit PC, SP reichen nicht aus Und vielleicht gibt es irgwendwie eine lookup table oder UART string im Flash -> 8 bit pointer reichen nicht aus.

Beim AVR hat man das addressiert, in dem man viele Register eingeführt hat (32x8). Allerdings wäre die Architektur mit einer 16x16 Registerbank wahrscheinlich effizienter, da sie sowieso schon 16 bit Befehle (flash hat 16 bit datenbus) und viele 16 bit virtuelle Register nutzt.

Der einzige Grund für die 8 bit besteht im geringeren Platzbedarf für den Datenpfad auf dem Chip. Das war aber vermutlich nur bei uralt-Prozessen mit >1µm wirklich ein Vorteil.

Nun ja, aber man hat die 16 bit ja jetzt übersprungen und hat dafür 32 bit auch schon im low end, bis auf eine extreme ultra-low-cost Nischenprodukte. Bei denen scheinen PIC-ähnliche Architekturen aber auszureichen.

OP #7701330
Lesenswert?

Tim  . schrieb:

Philipp Klaus K. schrieb:

Wie viel Platz es unterhalb des f8 für diskrete µC noch gibt, weiß ich nicht.

So sieht eine moderne MCU aus:

https://cpldcpu.wordpress.com/2024/05/01/decapsulating-the-ch32v203-reveals-a-separate-flash-die/

Gerade in China gibt es gerade viele Bestrebungen, low-cost Prozesse für PMIC und MCU zu entwickeln. Dazu werden ältere Logikprozesse vereinfacht, um bei gleichbleibenden Kosten die Logikdichte zu erhöhen.

Dual-Die (0,5 mm² + 1,8 mm²). Das ist was großes, nicht "unterhalb des f8", und damit auch nicht billig.

Bei Padauk hat ein komplettes SoC nur 0,25 mm² bis 1 mm². Dort würde ich eigentlich gern auch mit dem f8 hinkommen.

#7701341
Lesenswert?

Philipp Klaus K. schrieb:

Bei Padauk hat ein komplettes SoC nur 0,25 mm² bis 1 mm². Dort würde ich eigentlich gern auch mit dem f8 hinkommen.

Ja, bei den Padauks hat man auch viel am "analogen" Teil optimiert, um den die klein zu bekommen. (LDO, ESD, GPIO etc.)

Du kannst Deine MCU ja mal mit dem flow aus TinyTapeout synthetisieren. (https://tinytapeout.com/). Der dort verwendete Prozess (180 nm FE + 130 nm BE, dual voltage) ist dem der Padauks einigermassen ähnlich (vermutlich 180nm FE+BE, single voltage 5V).

OP #7710203
Lesenswert?

Nun gibt es etwas mehr (wenn auch immer noch unvollständige) Dokumentation (siehe Anhang).

Auch habe ich mir nun einen vereinfachten Teilbefehlssatz f8l überlegt, der immer noch eine brauchbare Zielarchitektur für C Compiler ergibt, aber in FPGA-Implementierungen einen nur noch einen halb so großen Kern erfordert wie der volle f8 (nach ersten Experimenten gemessen in LUT des Lattice iCE40UP). Allerdings gibt es noch keinen C-Compiler, der sich auf die Erzeugung von f8l-Code beschränkt.

Angehängte Dateien:
Gast #7710258
Lesenswert?

Mit welchen Kosten muss man rechnen, wenn man nur den F8 ersetzen möchte und sonst keinen Bedarf für FPGA-Funktionen hat? Die kleinsten FPGA kosten auch schon einige Euro. Dafür bekommt man schon sehr leistungsfähigen MCU-Ersatz.

?

OP #7710283
Lesenswert?

Christoph M. schrieb:

Könntest du die Schätzgröße für die Anzahl der LUTs angeben?

Wenn ich den aktuellen Code aus dem Repo für den Lattice iCE40UP5K kompiliere, erhalte ich:

f8: 5180 logic cells (98% der verfügbaren)

f8l: 3268 logic cells (61% der verfügbaren)

Jeweils für ein einfaches SoC aus Multicycle-Kern, 1x Watchdog, 1x Timer, 1x Interrupt-Controller, 2x 8-Bit-GPIO, 9 KB ROM, 6 KB RAM.

#7710572
Lesenswert?

Simon R. schrieb:

Mit welchen Kosten muss man rechnen, wenn man nur den F8 ersetzen möchte und sonst keinen Bedarf für FPGA-Funktionen hat? Die kleinsten FPGA kosten auch schon einige Euro. Dafür bekommt man schon sehr leistungsfähigen MCU-Ersatz.

Der Kosten wegen macht man sowas nicht, denn da kann absolut KEIN FPGA mithalten. Man macht es bestenfalls aus Spaß an der Feude oder weil man glaubt, mit einem Soft-Core ein besseres SoC auf seinem FPGA basteln zu können. Das ist zwar in den meisten Fällen Selbstbetrug, hindert aber die Leute nicht, es trotzdem zu tun ;-)

Gast #7710695
Lesenswert?

Falk B. schrieb:

Das ist zwar in den meisten Fällen Selbstbetrug, hindert aber die Leute nicht, es trotzdem zu tun ;-)

Respekt vor der Leistung , einen ganzen Prozessor zu implementieren.

Meiner einer sucht aber nach effektiven MCUs (und mein Chef auch).

Und wer macht noch 8-Bit-Computing? Das war vlt vor 30 Jahren aktuell, aber hätte man 1990 nur 16 Bit CPUs gehabt, hätte man sie genutzt. Warum skaliert man die Topologie nicht einfach in die andere Richtung?

#7710751
Lesenswert?

Simon R. schrieb:

Das ist zwar in den meisten Fällen Selbstbetrug, hindert aber die Leute nicht, es trotzdem zu tun ;-)

Respekt vor der Leistung , einen ganzen Prozessor zu implementieren.

Meiner einer sucht aber nach effektiven MCUs (und mein Chef auch).

Die gibt es tonnenweise von allen möglichen Herstellern in allen möglichen Leistungsklassen. Wo liegt das Problem?

Und wer macht noch 8-Bit-Computing?

Alle Profis, für die 8 Bit ausreichen Leistung bietet. Man muss nicht jedes Problem mit einem 32 Bit Controller arschlagen, auch wenn die heute verdammt billig sind!

Warum skaliert man die Topologie nicht einfach in die andere Richtung?

Wie meinen?

Gast #7710980
Lesenswert?

Falk B. schrieb:

Warum skaliert man die Topologie nicht einfach in die andere Richtung?

Wie meinen?

Ich meine: Wenn schon eine eigene Architektur, dann bitte nicht weniger, als es schon gibt, sondern mehr. Denn, wie du sagtest:

Falk B. schrieb:

Die gibt es tonnenweise von allen möglichen Herstellern in allen möglichen Leistungsklassen.

... und das betrifft harte CPUs und solche die in einen programmierbaren Baustein kommen. Es sind aber 32 Bit-CPUs. Wie wäre es mit einer 64er / 128er?

OP #7710993
Lesenswert?

Falk B. schrieb:

Die gibt es tonnenweise von allen möglichen Herstellern in allen möglichen Leistungsklassen.

... und das betrifft harte CPUs und solche die in einen programmierbaren Baustein kommen. Es sind aber 32 Bit-CPUs. Wie wäre es mit einer 64er / 128er?

Wie ganz oben geschrieben, sehe ich eben noch Lücken im 8-Bit-Bereich, die insbesondere durch das Verschwinden des STM8 größer werden. Den 32- und 64-Bit-Bereich sehe ich hingegen mit RISC-V hinreichend abgedeckt.

#7711003
Lesenswert?

Philipp Klaus K. schrieb:

Die Dokumentation sollte nun in einem halbwegs brauchbaren Zustand sein.

Man hätte wenigste drei geschlossene Sätze in der Einleitung, neudeutsch Introduction verlieren können, WAS das Dokument beschreibt und was die Motivation und Ziel zum Bau dieser CPU war.

Bist du Motorla-geschädigt oder Araber? Warum ist Bit 0 bei dir links?

Die Registerübersicht würde ich auf ein Seite packen, ohne Seitenumbruch. Nomen est OMEN!

Über die Formatierung deiner Befehlsdokumentation kann man streiten. So schlimm wie die BO8 isses nicht, aber wirklich gut ist es auch nicht.

#7711005
Lesenswert?

Simon R. schrieb:

Warum skaliert man die Topologie nicht einfach in die andere Richtung?

Wie meinen?

Ich meine: Wenn schon eine eigene Architektur, dann bitte nicht weniger, als es schon gibt, sondern mehr.

Nicht zwingend. Mehr im Sinne von mehr Bitbreite und Power ist nicht das einzige Optimierungskriterium und auch nicht die einzigste Motivation, sowas zu machen.

Denn, wie du sagtest:

Falk B. schrieb:

Die gibt es tonnenweise von allen möglichen Herstellern in allen möglichen Leistungsklassen.

... und das betrifft harte CPUs und solche die in einen programmierbaren Baustein kommen. Es sind aber 32 Bit-CPUs. Wie wäre es mit einer 64er / 128er?

Relativ sinnlos, erst recht in einem FPGA. Erstens sind solche Datenbreiten für normale Aufgaben unnötig und zweitens fressen sie viel Ressourcen und drittens ist deren Umsetzung im FPGA noch ineffizienter. FPGAs können ihre Stärken bei problemangepasster Datenverarbeitung ausspielen und nicht beim Kopieren von (seriell) arbeitenden CPUs. Zum Lernen und Spielen mit CPUs sind sie sehr gut geeignet.

#7711449
Lesenswert?

Philipp Klaus K. schrieb:

Hauptziel war es, eine effiziente Zielarchitektur für C-Compiler zu entwickeln, insbesondere im Hinblick auf den Speicherbedarf.

Dann schau Dir mal den 8051 an. Viele Befehle sind nur 1..2 Byte lang, wenn mit den 8 Registern gearbeitet wird. Und da der Großteil von Funktionen nicht reentrant sein muß, können lokale Variablen überlagert werden. Dazu werden vorzugsweise die 128 Byte direkt RAM benutzt. Der Stack wird nur selten benötigt, im Prinzip nur für die Returnadressen bei Calls und lokale Variablen in Interrupts. Daher werden auch keine komplexen Adressierungsarten für den Stack benötigt. Im Vergleich z.B. zum AVR-GCC benötigt der Keil C51 so deutlich weniger Flash für die gleiche Funktionalität.

Was der 8051 nicht so gut kann, ist riesen Datenarrays hin und her zu schaufeln. Das ist aber auch nicht die typische Aufgabe von 8-Bittern, dafür gibt es ja schon reichlich 32-Bitter zur Auswahl. Das Hauptanwendungsfeld von 8-Bittern sind Ablaufsteuerungen.

OP #7711472
Lesenswert?

Peter D. schrieb:

Philipp Klaus K. schrieb:

Hauptziel war es, eine effiziente Zielarchitektur für C-Compiler zu entwickeln, insbesondere im Hinblick auf den Speicherbedarf.

Dann schau Dir mal den 8051 an. […]

Meiner Erfahrung nach ist MCS-51, selbst wenn die lokalen Variablen nicht auf den Stack kommen, von der Codegröße her deutlich ineffizienter als STM8.

Vor einiger Zeit hatte ich Dhrystone mit SDCC 3.7.0 kompiliert (für MCS-51 ohne --stack-auto). Der war für MCS-51 ein Drittel größer (und deutlich langsamer) als für STM8.

Mit --model-large --stack-auto für mcs51 und aktuellem SDCC sieht es für Dhrystone bei den Codegrößen so aus:

  • mcs51: 13491 B
  • stm8: 6519 B
  • z80: 9161 B
  • r3ka: 8185 B
  • f8¹: 6549 B

Mehr Benchmarks, mit Codegrößen und Scores auf https://sourceforge.net/p/sdcc/code/HEAD/tree/trunk/sdcc-extra/historygraphs/ (wobei beim Whetstone mcs51 den Vorteil hat, dass die Gleitkommaroutinen für mcs51 in Assembler geschrieben sind, die für die anderen SDCC-Ports in C).

¹ Experimenteller f8-Port von SDCC, der noch nicht so gut optimiert, wie der stm8-Port.

#7711557
Lesenswert?

Philipp Klaus K. schrieb:

Vor einiger Zeit hatte ich Dhrystone mit SDCC 3.7.0 kompiliert

Dhrystone ist ein rein akademischer Test und hat für praktische µC Aufgaben keinerlei Aussagekraft. Ich kenne keine einzige µC Anwendung, die auch nur entfernt Dhrystone ähnlichen Code benutzt. Dagegen sind für die Programmierung von Steuerungen die Bitbefehle des 8051 sehr effektiv. Ich benutze sehr häufig Bitvariablen.

Philipp Klaus K. schrieb:

Mit --model-large

Ja, das ist der typische Anfängerfehler, um den Code explodieren zu lassen. Default ist small und der Herr Keil hat sich dabei schon was gedacht. Wie schon gesagt, riesen Datenmengen sind dem 8051 nicht seins. Der ist auf Bitvariablen optimiert, wie eine SPS.

Gast #7711575
Lesenswert?

@Phillip:

Ich verstehe das akademische Interesse auch mal eine eigene CPU zu bauen. Einfach aus Jux, weil man es kann.

Da aber von leistungsfähigen MCUs für einstellige Centbeträge bis krassen Soc für wenige € und allem dazwischen, nun wirklich kein Mangel an MCUs für wirklich jeden Bedarf besteht, wie ernst ist es Dir aus der f8 mehr machen zu wollen als eine benutzbare und dokumentierte BO8 mit C-Compiler Support?

Ich frage weil ich zwar den Hut ziehe vor Deiner Leistung und das bestimmt auch ganz toll für FPGA Enthusiasten ist die mal an einer MCU herumschrauben wollen, aber das wars dann auch schon. Weil, kein Schw... in der realen Entwicklerwelt interessiert sich noch für 10% weniger codesize oder 1,5 weniger CPU Zyklen.

Ich sehe auch überhaut keine Lücke zwischen oder bei 8bit und 32bit. Auch preislich nicht. Die STM8 mochte ich auch. Aber mehr wegen der clever verschalteten HW die vieles ohne CPU erledigen konnte. Aber letzlich ist das doch egal was man nimmt, solange es den Job erledigt und preislich interessant ist.

OP #7711588
Lesenswert?

Peter D. schrieb:

Philipp Klaus K. schrieb:

Vor einiger Zeit hatte ich Dhrystone mit SDCC 3.7.0 kompiliert

Dhrystone ist ein rein akademischer Test und hat für praktische µC Aufgaben keinerlei Aussagekraft. Ich kenne keine einzige µC Anwendung, die auch nur entfernt Dhrystone ähnlichen Code benutzt. Dagegen sind für die Programmierung von Steuerungen die Bitbefehle des 8051 sehr effektiv. Ich benutze sehr häufig Bitvariablen.

Irgendwas muss man zum testen nehmen. Üblicherweise sind bekannte Benchmarks dazu nicht das schlechteste, sonst wären sie keine bekannten Benchmarks. Die Zahlen sehen mit Whetstone¹, stdcbench oder Coremark auch nicht wirklich anders aus.

Philipp Klaus K. schrieb:

Mit --model-large

Ja, das ist der typische Anfängerfehler, um den Code explodieren zu lassen.

Aber nötig, um so etwas wie Dhrystone überhaupt auf den 8051 bringen zu können.

¹ Whetstone ist zwar ein Benchmark, der viel Gleitkommaarithmetik verwendet, aber auf einem µC, der keine Hardwareunterstützung für Gleitkommaarithmetik bietet, wird diese in Software emuliert. Die Softwareimplementierung von Gleitkommaarithmetik verwendet reichlich ^,&,|,<<,>>, also Operationen die auch sonst auf kleinen µC viel verwendet werden.

#7711600
Lesenswert?

Philipp Klaus K. schrieb:

eine effiziente Zielarchitektur für C-Compiler

Worunter ich eine Architektur verstehe, die ohne Klimmzüge, wie verschiedene im Programm explizit zu benennende Speicherbereiche, in C nutzbar ist, und die über eine Art Stack adressierten lokalen Variablen unterstützt.

Es gibt Compiler, die für sowas wie 8051 oder 8-Bit PICs effizienten Code erzeugen, in Codegrösse gerechnet. Hut ab. Ob das aber immer noch gilt, wenn man den Compiler nicht schon kennt wie seine Westentasche, und dann auch den Programmieraufwand einrechnet?

Gerade der 8051 hat zudem in seinen Ports eine Eigenheit, die formal betrachtet auf C nicht abbildbar ist (r-m-w Befehle funktionieren anders, als explizit ausprogrammierte). Was aber kein Aas berücksichtigt. Für in Jahrzehnten ergraute Experten kein Problem, aber für C Kenner eigentlich unzulässig.

Wer also alte 8-Bitter seit Urzeiten nutzt - kein Problem. Auch keines, wenn man Anwendungen in riesigen Stückzahlen verkauft und jeden Cent dreimal umdreht. Aber sonst scheint es mir sinnvoller, eine Architektur zu verwenden, die in grossem Bereich skalierbar ist, von Zwerg bis Multicore mit FPU.

#7711607
Lesenswert?

Philipp Klaus K. schrieb:

Irgendwas muss man zum testen nehmen.

Man vergleicht aber keine Traktoren anhand ihrer Geschwindigkeit auf glatter Straße. Man könnte extra Tests für Steuerungen entwickeln, aber wozu? Die Aufgaben von 8-Bittern sind so verschieden und vielfältig, da kann man eben nicht den gleichen Hut über alle stülpen. Akademische Tests sind jedoch das letzte, was eine reale Beurteilung ermöglicht.

Philipp Klaus K. schrieb:

Die Zahlen sehen mit Whetstone¹, stdcbench oder Coremark auch nicht wirklich anders aus.

Da würde auch niemand etwas anderes erwarten. Das sind eben alle akademische Tests, die sich nicht an den Anwendungen orientieren.

Philipp Klaus K. schrieb:

Aber nötig, um so etwas wie Dhrystone überhaupt auf den 8051 bringen zu können.

Man kann auch im small model große Arrays verwenden. Man muß sie nur als XDATA definieren. Aber wie schon gesagt, große Datenmengen sind nicht sein Haupteinsatz. Es gab mal von Intel und Philips Versuche, den 8051 auf 16/24 Bit aufzubohren. Die haben aber kaum Anwender gefunden und sind wieder in der Versenkung verschwunden.

#7712322
Lesenswert?

Peter D. schrieb:

Der hat aber mit dem 80C51 nun überhaupt keine Ähnlichkeit.

Nun, dann haben wir uns etwas missverstanden. Ich bilde mir ein, mal irgendwo was gelesen zu haben, wo der x166 als 16-Bit Nachfolger für den x51 beworben wurde.

Aber sei es drum. Ich finde es gut, wenn es eine weitere Architektur gibt, die nicht nur mit einem Assembler, sondern auch mit einem C-Compiler kommt. Und dazu noch das ganze als Quelltext für's eigene FPGA...

#7712702
Lesenswert?

Ich suche einen µC vorrangig nach der benötigten Peripherie aus (IO-Pins, Timer/Counter, PWM, ADC, DAC, UART, CAN, SPI, I2C). Was hast Du denn bisher so implementiert bzw. noch geplant?

Schön ist es auch, wenn Interrupts kein riesen Bohei veranstalten müssen zur Kontextumschaltung, sondern schnell den Handlercode ausführen und wieder beenden. Wieviel Interruptlevel unterstützt Du denn?

Gast #7712730
Lesenswert?

Rick schrieb:

Und dazu noch das ganze als Quelltext für's eigene FPGA...

Das will aber auch erst einmal verstanden und aufgearbeitet werden, um es nutzbar zu machen. Ich glaube kaum, dass es möglich ist, den FPGA-Code einfach in jeden X-beliebigen Baustein einzukippen und loszulegen.

Und wer weiß, ob der FPGA-Code nicht auch Fehler enthält(?)

Möchte man ein solches Paket benutzen, ist wieder viel Einarbeitung nötig und es bestehen dennoch Unsicherheiten.

Gast #7712753
Lesenswert?

Rick schrieb:

Ich finde es gut, wenn es eine weitere Architektur gibt, die nicht nur mit einem Assembler, sondern auch mit einem C-Compiler kommt.

Reichlich Auswahl ;-) https://opencores.org/projects?expanded=Processor

Das ist aus akademischer Sicht sicher alles ganz spannend und man kann auch sehr schön damit VHDL basteln.

Nur darf man eben nicht erwarten das das wirklich mal jemand einsetzt oder es jemals als ein Tape-out geben wird. Für den Entwickler eine Heidenarbeit, damit die flüchtig Interessierten ihm eine Menge Löcher in den Bauch fragen, herumkritisieren und wenn das Interesse erlahmt ohnehin bei dem bleiben was sie an jeder Ecke für einen schmalen Taler kaufen können.

Warum sollte ich mich mit einem sauteuren FPGA 8Bitter herumschlagen den niemand kennt, für den es nichts gibt, wenn ich bereits mit einem RP2040, dessen 133Mhz M0 und den PIOs oft Dinge in SW machen kann die man früher im FPGA getan hätte?

Das ist ein TO Spaßprojekt und das wird es bleiben. Der TO erlangt dadurch neue Fähigkeiten. Das wird aber sein einziger Nutzen bleiben, befürchte ich.

Ich ziehe den Hut vor Phillip und finde das super das er gleich den Compiler dazu baut. Aber wenn wir mal ehrlich sind, sind das brotlose Künste.

OP #7712760
Lesenswert?

Peter D. schrieb:

Ich suche einen µC vorrangig nach der benötigten Peripherie aus (IO-Pins, Timer/Counter, PWM, ADC, DAC, UART, CAN, SPI, I2C). Was hast Du denn bisher so implementiert bzw. noch geplant?

Bisher gibt es den f8 nur im FPGA, und somit auch keine analoge Peripherie (ASC, DAC, analoger Komparator). Es gibt GPIO und Timer. Langsame digitale Peripherie wie UART, CAN, SPI, I2C halte ich nicht für sinnvoll in Hardware zu implementieren, das kann man auch in software machen.

Schön ist es auch, wenn Interrupts kein riesen Bohei veranstalten müssen zur Kontextumschaltung, sondern schnell den Handlercode ausführen und wieder beenden. Wieviel Interruptlevel unterstützt Du denn?

Die Implementierung der Interrupts beschränkt sich bisher noch auf das allereinfachste: Es gibt noch keine verschiedenen Interruptlevel, und nur zwei Interrupts (beide vom Timer).

#7712798
Lesenswert?

Philipp Klaus K. schrieb:

Kannst du das kurz erläutern?

Wenn in reinen Lesebefehlen I/O-Ports gelesen werden, wird der Ist-Zustand der Pins abgefragt. Handelt es sich jedoch um Befehle, die in einem Befehl den Port lesen, Bits ändern, und zurückschreiben, wird nicht der Istzustand gelesen, sondern der Sollzustand des Ports.

Die Ports haben ja keine explizite Richtungssteuerung, und eine Open Drain Logik. Der Sollzustand, also der des Flipflops vom Pintreiber, kann "high" sein, der Port aber aufgrund externer Beschaltung "low".

Liest man den Istzustand und schreibt ihn unverändert in einem separaten Befehl zurück, wird aus einem Sollzustand "high" nun der Sollzustand "low", d.h. der Zustand des Flipflops wird verändert. Ändert sich der externe Zustand, bleibt der Pin danach trotzdem low, nun aber aufgrund des Pintreibers. Führt man diese Operation jedoch mittels eines Read-Modify-Write Befehls durch, wird der vorherige Sollzustand zurückgeschrieben und das Flipflop bleibt unverändert. Das ist an sich sehr sinnvoll, aber für Assembler-Programmierung gedacht.

Nur bedeutet es, dass eine C Operation port = port | 0x01; ohne Optimierung in Einzelbefehle umgesetzt, nicht identisch ist mit port |= 0x01; als einzelnem R-M-W Befehl. Der C Standard schreibt das jedoch vor. Und Standard hin oder her, man hat auf C Ebene keine echte Kontrolle über diese Feinheit. Muss ggf runter in den generierten Code sehen.

#7712803
Lesenswert?

Philipp Klaus K. schrieb:

Kannst du das kurz erläutern?

Um IO-Adressen zu sparen (?) liest man beim Lesen ein anderes Register, als beim Schreiben (alles auf derselben Adresse!). Wenn die CPU beim Bit setzen einen read-modify-write-Zugriff macht, wandern die meisten Werte vom gelesenen Register in's geschriebene Register. Das will man aber meist gar nicht.

Das gibt es auch bei anderen Architekturen, z.B. PIC. Oder beim Z8, wo die Logik für's Lesen eingespart wurde und man bestimmte Register nur schreiben darf.

P.S.: Zweiter...

#7712805
Lesenswert?

Das Grundproblem von Ports ohne separater Lese- und Schreibadresse durchzieht wohl alle frühen Architekturen, auch die 65xx Ports und viele andere. Auch manche der ersten ARM Microcontroller sind wohl nicht frei davon. Das ist unangenehm, hat aber nicht mit C zu tun.

Die Besonderheit beim 8051 liegt im unterschiedlichen Verhalten, je nachdem welche Art von Befehl genutzt wird. Genau genommen dürfte ein C Compiler für 8051 die R-M-W Befehle bei Ports nicht verwenden, man müsste über explizite intrinsics wie bitset(port,0x01) gehen, um das abweichende Verhalten zu dokumentieren. Macht natürlich niemand.

#7719591
Lesenswert?

... es kann sehrwohl Sinn machen einen "kleinen" MikroContoller zusätzlich in einem FPGA mit zu implementieren ... wobei so ein 8051 wenig sinnreich erscheint - insbesondere wenn der in C programmiert werden soll ... ... bei den historischen 8bit Prozessoren gibt es eine sehr einfache Architektur die in den 70er Jahren unter dem Namen SC/MP von National Semiconductor angeboten wurde ... hat PC und 3 16bit PointerRegister ... damit sollte ein brauchbarer C-Compiller möglich sein ... einen Assembler gibt es ... zudem sind noch viele OpCodes frei für spezifische Erweiterungen im FPGA ... z.B. UART Rx / Tx mit nur einem 8bit Befehl - Status wird im C-Flag signalisiert ...

#7719596
Lesenswert?

Willi S. schrieb:

... bei den historischen 8bit Prozessoren gibt es eine sehr einfache Architektur die in den 70er Jahren unter dem Namen SC/MP von National Semiconductor angeboten wurde

Örks... Wie gut kennst du diese Architektur?

damit sollte ein brauchbarer C-Compiller möglich sein

Schon versucht? Das Teil ist bei näherer Betrachtung von beachtlicher Umständlichkeit.

3 16bit PointerRegister

Wovon schon mal 2 blockiert sind. Eines für Interrupts und eines für einen erst zu implementierenden Stack. Unterprogrammaufrufe gibts in der Originalversion keine und alle Sprünge ausserhalb +/-128 Bytes gehen nur indirekt.

Wirklich gut war der DLY Befehl (Delay), um Zeit tot zu schlagen. :)

Gast #7719632
Lesenswert?

Rick schrieb:

Um IO-Adressen zu sparen (?) liest man beim Lesen ein anderes Register, als beim Schreiben (alles auf derselben Adresse!).

Damit fällt aber die Rücklesefähigkeit weg, was heute immer mehr gefragt ist, wegen funktionaler Sicherheit. Solche Tricks aus den 1990ern kann man getrost zu den Akten legen.

Willi S. schrieb:

zudem sind noch viele OpCodes frei für spezifische Erweiterungen im FPGA ... z.B. UART Rx / Tx mit nur einem 8bit Befehl -

Noch so eine Idee, irgendetwas Sonderbares einzubauen.

Solche Heldenideen braucht kein Mensch.

#7720176
Lesenswert?

Manche meinen, ein Prozessor im FPGA müsse immer schneller als eine käuflich zu erwerbende MCU sein, sonst wäre das ja alles sinnlos. Das sind Leute, die von FPGAs so gar keine Ahnung haben. Oft braucht man im FPGA einen Steuerprozessor, der die schnellen Signalverarbeitungspfade konfiguriert und die Kommunikation zu externen Bediengeräten herstellt. Da ist ein 8Bit Prozessor, der sehr effizient mit Speicher und LUTs umgeht und in C effizient programmiert werden kann, ideal.
Insofern: super Projekt, weiter so !

#7722735
Lesenswert?

... wer Ports / Register in einem FPGA implementiert ... dem bietet sich eine sehr zweckmässige Lösung an ... es werden 4 Register geschaffen ... [00] der read/write Port ... [01] set-Port mit "write one to set" W1S ...[10] clear-Port mit "write one to clear" W1C ... [11] xor-Port mit "write one to xor" - läßt die Bits toogeln ... im FPGA werden keine weiteren Resourcen verbraucht ... weil dies in einer typischen 4bit LUT implementiert werden kann ... wird z.B. im RP2040 vom pico oder den PIC32 so angeboten ... Übrigens: das einzig wirklich interessante an der 8051- Familie sind die Bit-Befehle ... mit denen sich einzelne Bits in den Ports und manchen Registern manipulieren lassen ...

OP #7804273
Lesenswert?

Der f8 wächst langsam aus dem svn branch des SDCC-repo heraus.

Die f8-Unterstützung ist nun im SDCC selbst zu finden.

Erste Tutorials für einen f8 auf FPGA-Boards (insbesondere ICEBreaker und GateMateA1-EVB) sind auf github (https://github.com/f8-arch/fpga-board-tutorials), wohin später auch die Dokumentation des f8 (zur Zeit unter svn://svn.code.sf.net/p/sdcc/code/branches/f8/f8/doc), sowie die bisherigen Verilog-Implementierungen umziehen sollen.

Auch auf der FOSDEM wird es einen Vortrag zum f8 geben: https://www.fosdem.org/2025/schedule/event/fosdem-2025-4902-f8-an-8-bit-architecture-designed-for-c-and-memory-efficiency/

OP #7919146
Lesenswert?

Der Vortrag ist inzwischen ja offensichtlich online. Wäre interessant, Benchmarks zur Codegröße zu sehen.

Stand jetzt, SDCC aus dem f8l-Branch:

1
CPU   | Dhrystone | Whetstone | Beschreibung
2
------------------------------|-------------
3
f8    |    6277 B |    8476 B | f8 (Softcore auf iCEBreaker-Board)
4
f8l   |    7297 B |   10089 B | f8l (Softcore auf iCEBreaker-Board)
5
stm8  |    6614 B |    9197 B | STM8 (STM8AF-Board aus STM8A-Discovery)
6
r3ka  |    8189 B |   10703 B | Rabbit 3000 A (RCM3319-Board)
7
z80   |    9117 B |   13331 B | Z80 (Z80-MBC2-Board)
8
mcs51 |   12950 B |   18504 B | MCS-51 (C8051-Board)

Jeweils mit --opt-code-size kompiliert.

Bei f8 und f8l ist in der Codegröße zusätzlich eine Software-Implementierung eines UART (nur Senderichtung) enthalten, bei den anderen wird ein Hardware-UART verwendet. Insbesondere für f8l und r3ka erwarte ich noch kleinere Verbesserungen der Codegröße im Rest des Jahres.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren