Ich hatte das Engineering-Model für eine Laserquelle mit genau definierter Frequenz, die ein methangefülltes Röhrchen als Absolutreferenz benutzt, mit microCore programmiert. Nur die I/O-Treiber und Busverwaltung waren VHDL, die Regelungsebene Forth. Das hat den Kunden glücklich gemacht. Beim Flight-Model sollte aber auch die Regelungseben reines VHDL werden, um den Aufwand für die Prozessorverifikation zu sparen. Und damit stellte sich die Frage nach der Resourcenverwaltung neu. Bei der Software ist es einfach: Es gibt einen Multitasker, der hat parallele Tasks (Prozesse), die die komplexe Regelung erledigen. Jede Peripherieeinheit hat ein "Busybit" und kann nur benutzt werden, wenn es nicht gesetzt ist, ansonsten aktiviert der Scheduler solange die nächste Task, bis das Busybit nicht mehr gesetzt ist. Das funktioniert nur deshalb, weil in der Software NIEMALS zwei Prozesse versuchen, gleichzeitig auf eine Resource zuzugreifen. Die Tasks sind nämlich gar keine parallelen Prozesse, sie sind nur pseudoparallel. In Wirklichkeit ist IMMER nur EIN Prozess aktiv. Bei VHDL sieht es ganz anders aus: Jeder unabhängige Prozess ist prinzipiell vollparallel und läuft dauernd. Und deshalb kann es zu Konkurrenz zwischen mehreren Prozessen um eine Resource kommen. Klassischerweise löst man das mit einem priorisierten REQUEST/GRANT Handshake für jeden Prozess und seine benutzten Resourcen. Es ist also ein Kreuzprodukt von Prozesse*Resourcen und das auch noch *2 (REQUEST hin, GRANT her) und das auch manchmal quer durchs Chip. Nun hatte ja die Softwarelösung bereits bewiesen, dass man aus Performancegründen keine volle Parallelität braucht, sondern die Regelungsaufgaben locker von einem Prozess sequentiell erledigt werden können. Deshalb habe ich in VHDL den Multitasker modelliert: Es gibt insgesamt sechs (Regelungs)prozesse, die hintereinander aktiviert werden. Ist nichts mehr zu tun, wird die Kontrolle an den nächsten Prozess gegeben, und der letzte aktiviert wieder den ersten. Es wird sozusagen das Aktivierungstoken herumgereicht. Dadurch gibt es - wie bei der Software - jeweils nur einen Prozess, der auf eine Resource zugreifen möchte, und das Busybit, das von einer Resource an alle Prozesse verteilt wird, reicht für die Resourcenverwaltung völlig aus, ein Handshake ist gar nicht mehr erfoderlich. Wir haben also den Aufwand von Prozesse*Resourcen*2 reduziert auf Resourcen. Das hat natürlich Auswirkungen auf die Architektur. Sämtliches I/O wird über einen einzigen Bus angesteuert und der Bus wird über Multiplexer auf den gerade aktiven Prozess geschaltet. Zusätzlich hat jeder Prozess einen identischen Registerbereich, der auch gemultiplext wird. Sowohl Buszuteilung also auch Registerbereich lassen sich prima in einem Array verpacken, dessen Index der gerade laufenden Task entspricht. Dann kann man sich einen Zoo von Procedures schreiben, die den Aktionen nachgebildet sind, die vorher in Software abgelaufen sind. Die Procedures sind sozusagen die Opcodes und jeder einzelne dieser Prozesse kann sich mit einem Zähler (aka Program Counter) durch ein großes CASE-Statement hangeln. Das hat den großen Vorteil, dass die Struktur der Software prinzipiell erhalten bleibt und man deshalb den ehemaligen Programmcode ohne viel Gehirnschmalz in entsprechendes VHDL umsetzen kann. In VHDL kann man mehr machen, als mit einem beschränkten Opcode-Inventar und deshalb wird die VHDL-Lösung auf jeden Fall schneller sein und mit sehr viel weniger Jitter behaftet sein, als die Softwarelösung. Der Jitter der Softwarelösung lag bei 1 msec, bei VHDL wird das sicher auf wenige usec reduziert.
:
Bearbeitet durch User
Klaus S. schrieb: > Das funktioniert nur deshalb, weil in der Software NIEMALS zwei Prozesse > versuchen, gleichzeitig auf eine Resource zuzugreifen Welche Resourcen wären das denn ? I/O Pins kaum, sind ja angelötet, Timer und UART in VHDL ebenfalls nicht, es kann ja nur um volatile Variablen zur Steuerung gehen, da sehe ich bei uC auf der einen und VHDL Hardware auf der anderen kein Semaphorenproblem.
Klaus S. schrieb: > Deshalb habe ich in VHDL den Multitasker modelliert: Es gibt insgesamt > sechs (Regelungs)prozesse, die hintereinander aktiviert werden. Ist > nichts mehr zu tun, wird die Kontrolle an den nächsten Prozess gegeben, > und der letzte aktiviert wieder den ersten. Das nennt der Hardware-experte Round-Robin-Arbiter. Den haste grade wie das sprichwörtliche Rad ein Zweites Mal erfunden. https://fpgasite.wordpress.com/2016/04/15/vhdl-arbiter/
Ich würde ja eher ein ProcessManager die Prozesse umschalten lassen, der auch ein Timeout für jeden Process kennt. Was passiert wenn das "Token" nicht weiter gegeben wird, weil auf ein nicht eintreffendes externes Ereignis gewartet wird etc...
1. Wo ist deine Frage? 2. Ich bin verwirrt. In Beitrag "Re: microCore, ein Echtzeitprozessor in VHDL für FPGAs" hast du geschrieben, dass microCore fliegt, also ging ich davon aus, dass er verifiziert ist. Aber jetzt schreibst du, dass sich euer Kunde die Verifikation "sparen" will von etwas das 20 Jahre erprobt ist? Klaus S. schrieb: > Ich hatte das Engineering-Model [...] > Beim Flight-Model sollte aber auch die Regelungseben reines VHDL werden, > um den Aufwand für die Prozessorverifikation zu sparen. Ich finde das gerade irgendwie unüblich, zwischen EM und FM noch so essentielle Dinge zu wechseln. Wo ist die Risikobewertung dazu? Klaus S. schrieb: > Der Jitter der Softwarelösung lag bei 1 msec, bei VHDL wird das sicher auf wenige usec reduziert. Was sagen die Requirements? Reicht auch 1 s? Wird hier etwas vergoldet das schon gut genug ist? Ein kleines unbekannteres RTOS (FemtoOS) hat einen pre-emptive Scheduler der es bei mir schafft auf einem 8 MHz AVR vier 7-Segment Anzeigen zu multiplexen ohne Jitter (bei 400 Hz, hab eine Oszilloskope Messung mit infinite persistance mal für ein paar Minuten laufen lassen). Multiplexing wird im Task mit höchster Priorität gemacht und nutzt das Scheduler feature taskDelayFromWake (Delay the task a number of ticks, starting at the last wake time).
MaWin schrieb: > Welche Resourcen wären das denn ? 10 12-bit DACs, 3 8-Kanal ADCs, 3 Laserswitches, 1 Wavemeter Bei den ADCs (kompliziertester Fall) wird das busy-bit so gesteuert: Es gibt ein internes ADC Register. Die Wandlung startet, wenn eine Kanalnummer in das Register geschrieben wird. Da gibt es zwei Möglichkeiten: 1) busy=0 Es wird busy gesetzt. Der ADC wird mit Wandlung beauftragt. 2) busy=1 Es wird der Folgeprozess aktiviert. Das Ergebnis wird abgeholt, indem das Register gelesen wird. Wieder gibt es zwei Möglichkeiten: 1) busy=0 Der ADC ist fertig und wird ausgelesen. Busy wird rückgesetzt. 2) busy=1 Es wird der Folgeprozess aktiviert.
Jonas B. schrieb: > Ich würde ja eher ein ProcessManager die Prozesse umschalten lassen, der > auch ein Timeout für jeden Process kennt. Was passiert wenn das "Token" > nicht weiter gegeben wird, weil auf ein nicht eintreffendes externes > Ereignis gewartet wird etc... Bei (noch) nicht eingetroffenem externen Ereignis, z.B. eine leere UART, wird sofort zum nächsten Prozess gesprungen. Und "verloren gehen" kann das Token auch nicht, weil die Aktivierung des nächsten Prozesses nichts anderes ist, als das Hochzählen eines Counters. Das System ist stabil. Ausnahmen wie immer Metastabilität und nukleare Strahlung.
Christoph Z. schrieb: > 1. Wo ist deine Frage? Das ist eine Anregung. > jetzt schreibst du, dass sich euer Kunde die > Verifikation "sparen" will von etwas das 20 Jahre erprobt ist? Das war eine Entscheidung der Geschäftsleitung, alles Mechaniker, wenn auch lange im Raumfahrtgeschäft. Es war ja Technologie ohne Heritage, was ich da trieb. > Was sagen die Requirements? Jitter 5 msec hätte noch ins Timing gepasst.
Klaus S. schrieb: > Es gibt ein internes ADC Register. Die Wandlung startet, wenn eine > Kanalnummer in das Register geschrieben wird. Da gibt es zwei > Möglichkeiten: Bei einem Mehrkanal-ADC mache ich eine State-Machine, welche die Werte aller Kanäle kontinuierlich ausliest und dann alle Werte parallel zur Verfügung stellt. Dazu wird ein Flag getriggert und die Verarbeitung kann starten. Alternativ holt sich eine CPU die Werte aus Registern, wenn sie der Meinung ist, neue Werte zu brauchen. Bei Deiner Methode sehe ich nur mehr Aufwand, ohne mehr Nutzen. Oder habe ich etwas übersehen? Duke
Duke Scarring schrieb: > Bei Deiner Methode sehe ich nur mehr Aufwand, ohne mehr Nutzen. Oder > habe ich etwas übersehen? PLONK! - So machte das Brett vor meinem Kopf. Meine Güte, so einfach. Ein typischer Fall von, wie VHDL Strukturen davon beieiflusst sind, ob man von der Software oder der Hardware her denkt. Eine völlige Entkopplung der I/O-Prozesse von den Regelungsprozessen wäre in dem Projekt locker mögliche gewesen. Und mit Registern gibt es dann kein Problem, parallel zuzugreifen. Und viel Sorge um Strahlungstoleranz muss man auch nicht haben, die Register werden ja zyklisch neu gesetzt. Es gibt da 10 msec im Ablauf, bei denen zwei ADC-Kanäle während der Belichtungszeit des Wavemeters im Dauereinsatz sind, aber da könnte man einfach alle anderen I/Os ruhen lassen. Wie gehst Du denn mit Speicher um, der von mehreren Prozessen genutzt wird?
>Wie gehst Du denn mit Speicher um, der von mehreren Prozessen genutzt >wird? Mutex z.B.?
Klaus S. schrieb: > Wie gehst Du denn mit Speicher um, der von mehreren Prozessen genutzt > wird? Bisher hab ich jedem Submodul, was Speicher benötigt hat einen eigenen Speicher gegönnt. Hast Du evtl. ein Beispiel, wo man Speicher teilen möchte? Und nur zum Verständnis: Wir reden hier nicht von Dual-Port-RAMs, wie man sie z.B. für FIFOs benötigt, oder? Duke
Duke Scarring schrieb: > Hast Du evtl. ein Beispiel, wo man Speicher teilen möchte? Ein Dual-Port RAM, das an einem Port Spacewire angeschlossen hat, mit dem der Hostrechner sich die Werte anschauen kann zur Systemüberwachung und -optimierung. Am anderen Port sitzen vier parallele Prozesse, die die Daten generieren und das RAM auch als Speicher für Zustandsvariablen der Regelung nutzen.
Klaus S. schrieb: > Am anderen Port sitzen vier parallele Prozesse, die > die Daten generieren und das RAM auch als Speicher für Zustandsvariablen > der Regelung nutzen. Greifen diese schreibend auf die gleichen Adressen zu? Wenn ja, dann kommst du um einen Arbiter in irgendeiner Form und Mux nicht darum herum. Wenn diese Prozesse von gleichen Adressen lesen, das ist ja schon mal alles gut. Wenn diese Prozesse im Speicher komplett getrennte Adressbereiche haben (also der Speicher partitioniert ist), dann ist er ja gar nicht geteilt und ich würde 4 separate Dual-Port RAMs bauen und sie auf der Spacewire Seite logisch (simpler Adressdecoder) zu einem grossen zusammenfassen.
Christoph Z. schrieb: > Greifen diese schreibend auf die gleichen Adressen zu? Wenn ja, dann > kommst du um einen Arbiter in irgendeiner Form und Mux nicht darum > herum. Die greifen auf dieselben Adressbereiche zu, schreiben aber wenigstens niemals auf identische Adressen. Aber um eine Arbitration kommt man nicht herum, weil die Prozesse manchmal gleichzeitig den Speicher nutzen wollen. Da sind wir dann wohl beim Request/Grant angekommen, oder?
Evtl. koenntest du dir auch ueberlegen ein verbreitetes Bussystem, z.B. Wishbone (oder AXI wenns etwas aufwendiger sein soll) zu verwenden. Da gibts dann schon fertige Loesungen (oder zumindest Design Patterns) fuer entsprechende Arbitrierungen im Multimaster Betrieb. Das ist allerdings nurmal so in Raum geworfen, keine Ahnung ob das fuer deine Prozessor Architektur praktikabel ist.
Wenn ich ein Prozessorinterface benutze, dann gibt es keine Arbitrierung um konkurrierende Prozesse, weil ein einzelner Prozessor niemals real parallel ist. Mit einem Prozessor ist der Zugriff auf Memorybereiche IMMER unproblematisch, wenn das in einem Zyklus passiert. Das war ja der Ausgangspunkt meiner Überlegungen hier (1. Posting). Und das fand Duke Scarring - zu Recht - zu umständlich, wenn es um's reine PeripherieIO geht. Bei der Frage nach der Memoryarbitrierung geht es nicht um microCore, sondern um die flugfähige Version, die ohne Prozessor auskommen soll wegen der Verifikationskosten für den Prozessor.
:
Bearbeitet durch User
Christoph Z. schrieb: > Ich finde das gerade irgendwie unüblich, zwischen EM und FM noch so > essentielle Dinge zu wechseln. Wo ist die Risikobewertung dazu? EMs (breadboards) müssen nur funktionell weitgehend passen. Ich vermisse hier aber mindestens einen Zwischenschritt. Üblich sind Qualifikationsmodelle (QM), Protoflight (PFM) und/oder letztens dann die FMs. Letztere aber allesamt vollständig "form fit & function" sowie gleiche qual-levels der Komponenten. Bei Änderungen zieht sich das durch alle Stufen. Nur bei low-budget geht es z. T. einfacher. Aber danach klingt das Ganze nicht. Will man alles verifizieren, validieren, simulieren bis hin zu Coverage, Stress, WCAs, FMECAs, Radiation mit allem Drum und Dazu, TVac, EMC etc., schafft man den Sprung ohnehin nicht. Oder es kostet Jahre und der Aufwand für ein neues EM-Design geht darin unter. Heritage ist ebenfalls wichtig. Ich würde mal auf die aktuelle Enwicklung der von der ESA forcierten LEON-Prozessorentwicklung (SPARC-V8-Design, inzwischen mit bis zu 4 cores) schauen, da geht so einiges. Auch sind abseits vom Antifuse-RTAX bereits im Flug konfigurierbare PGAs im Einsatz, so dass man Designänderungen per TCs noch hinterherschicken kann. Ich würde jedenfalls nochmal mit den Kollegen ein ausgewogenes Hardware-Software-Co-Design durchgehen, bevor ich mich für so einen Schritt entscheide. Notfalls den µC/die CPU gegen einen Baustein mit Heritage tauschen. Der LEON ist aktuell auch als µC in Entwicklung bzw. wurde schon angekündigt. Vlt. ist der Umstieg damit einfacher.
Klaus S. schrieb: > Wenn ich ein Prozessorinterface benutze, dann gibt es keine Arbitrierung > um konkurrierende Prozesse, weil ein einzelner Prozessor niemals real > parallel ist. Willkommen in der Neuzeit wo wir Systeme mit Muli-core Prozessoren und DMA bauen (DMA ist mittlerweile ein Feature das in 2$ STM32 drin ist). Nein, das ist keine Rocket-Science mehr, das ist deine Kompaktknipse, dein Fernseher, dein verstellbarer Rückspiegel am Auto etc. Tobias B. schrieb: > Da gibts dann schon fertige Loesungen (oder zumindest Design Patterns) > fuer entsprechende Arbitrierungen im Multimaster Betrieb. Klaus S. schrieb: > Wenn ich ein Prozessorinterface benutze, dann gibt es keine Arbitrierung > um konkurrierende Prozesse, AXI und Whishbone sind keine "Prozessorinterfaces", das sind on-chip Bussysteme (Sie erfüllen den selben Zweck wie z. B. PCI auf Leiterplattenebene). Bei deren Entwicklung war schon lange klar das damit parallele Systeme gebaut werden sollen (jetzt halt mit Standard verglichen mit noch älteren Custom-systemen).
>Die greifen auf dieselben Adressbereiche zu, schreiben aber wenigstens >niemals auf identische Adressen. Dann benutze halt ein Dualport-Ram und es gibt keine Probleme. Und bilde dich mal weiter, das kann man ja gar nicht mehr aushalten deine Steinzeitwissen.
dfIas schrieb: > Will man alles verifizieren, validieren, simulieren bis hin zu Coverage, > Stress, WCAs, FMECAs, Radiation mit allem Drum und Dazu ... Danke für die Auflistung. Und da wollte man sich nicht auch noch einen Prozessorkern ohne Heritage ans Bein binden. Ja, natürlich gibt es auch ein QM, aber das ist elektrisch identisch (außer ein paar Bufixes) zum FM. > Ich würde mal auf die aktuelle Enwicklung der von der ESA forcierten > LEON-Prozessorentwicklung (SPARC-V8-Design, inzwischen mit bis zu 4 > cores) schauen, da geht so einiges. Damit hatte ich vor 7 Jahren zu tun, mein Quereinstieg in die Raumfahrt. Der SPARC im LEON2 ist Originalzustand mit Kommentaren, die in die 70er Jahre zurückreichen und der Code ist dank der seitdem gemachten Änderungen schwer durchschaubar. Da hilft es auch nicht, dass Jiri Gaisler schönen Code drumherum schreibt. Die ganze Architektur mit den Parameterübergabepages ist ätzend, weil es letztlich immer wieder "nicht genug" sind und deshalb für Echtzeit das Paging weggeworfen werden muss. Vielleicht für Interruptprocessing, aber das wars. Die NASA war schlauer, die haben den ARM gepäppelt.
>Die ganze Architektur mit den Parameterübergabepages ist ätzend, weil es >letztlich immer wieder "nicht genug" sind und deshalb für Echtzeit das >Paging weggeworfen werden muss. Vielleicht für Interruptprocessing, aber >das wars. Die NASA war schlauer, die haben den ARM gepäppelt. Bei >Jitter 5 msec hätte noch ins Timing gepasst. redest du von Echtzeit. Das Vitamin B das dich in den Job gebracht hat ist aber mächtig.
:
Bearbeitet durch User
Jonas B. schrieb: > Dann benutze halt ein Dualport-Ram und es gibt keine Probleme. Was nützt mir das, wenn ich mehr als zwei konkurrierende Prozesse habe? Ich habe jetzt mal einen Arbitrator für 3 Prozesse gebaut. Eine vollständige Testbench als Datei, hier der Kern der Sache:
1 | clk_en <= '0' WHEN (req1 AND grant1) = '1' |
2 | OR (req2 AND grant2) = '1' |
3 | OR (req3 AND grant3) = '1' |
4 | ELSE '1'; |
5 | |
6 | arbitrator: PROCESS (clk, reset) |
7 | BEGIN
|
8 | IF reset = '1' THEN |
9 | grant1 <= '0'; |
10 | grant2 <= '0'; |
11 | grant3 <= '0'; |
12 | ELSIF rising_edge(clk) THEN |
13 | IF clk_en = '1' THEN |
14 | IF req1 = '1' THEN |
15 | grant1 <= '1'; |
16 | ELSIF req2 = '1' THEN |
17 | grant2 <= '1'; |
18 | ELSIF req3 = '1' THEN |
19 | grant3 <= '1'; |
20 | END IF; |
21 | END IF; |
22 | IF req1 = '0' THEN grant1 <= '0'; END IF; |
23 | IF req2 = '0' THEN grant2 <= '0'; END IF; |
24 | IF req3 = '0' THEN grant3 <= '0'; END IF; |
25 | END IF; |
26 | END PROCESS arbitrator; |
In der Simulation sieht man schön, dass REQ3 der gearschte Prozess ist, der bis zuletzt warten muss.
Schön einen asynchronen Reset gebaut, aber Hauptsache irgendwelche Raumschiffe bauen...
PS: Aber jetzt muss jeder Prozess per Multiplexern aufs Memory geschaltet werden, wenn sein Grantsignal aktiv ist. Also im Prinzip das, was Duke Scarring weiter oben so qualifiziert hatte: Beitrag "Re: parallele Prozesse konkurrieren um Peripherals" > Bei Deiner Methode sehe ich nur mehr Aufwand, ohne mehr Nutzen. Oder habe > ich etwas übersehen? Da ich aber, wenn Memorybereiche zum IO dazugehören, sowieso multiplexen muss, kann ich auch gleich die ADCs und DACs auch als Memory mapped in diese erweiterte IO-Struktur einbeziehen, wie ich es im ersten Beitrag skizziert habe. Das hatte Duke übersehen, und mir ist es jetzt beim Koden der Arbitrierung klar geworden. Dann sticht der Vorteil meiner Idee: Arbitration ist nicht notwendig, es reicht ein "Busy" jeder Ressource, die mehr als einen Zyklus Verarbeitungszeit braucht.
:
Bearbeitet durch User
https://www.xilinx.com/support/documentation/application_notes/xapp228.pdf Das lässt sich beliebig erweitern. Suche doch einfach mal, du bist doch nicht der erste der so Probleme hat.
Ich empfehle dir dringend mal die Grundlagen zu lernen: http://www.lothar-miller.de/s9y/categories/34-Getakteter-Prozess "Wesentlich schlimmer als nur der zusätzliche Ressourcenverbrauch ist aber, dass ein asynchroner Reset zu undefiniertem Verhalten des Designs beim Verlassen des Resetzustands führen kann. Aufgrund unterschiedlicher Laufzeiten innerhalb des FPGAs sehen einzelne Register den Reset zeitverzögert weggehen. Wenn dann gerade ein Takt kommt, kann es sein, dass die eine Hälfte des FPGAs noch im Resetzustand ist, die andere Hälfte aber schon arbeitet."
Klaus S. schrieb: > In der Simulation sieht man schön, dass REQ3 der gearschte Prozess ist, > der bis zuletzt warten muss. Da gibt es unterschiedliche vorghensweisen, abhaengig von deinen Anforderungen. Was du z.B. machen kannst, wenn alle Prozesse ungefaher gleich haeufig auf die Ressourcen zugreifen wollen, die Request in ein FIFO schreiben und dann nach und nach abarbeiten. Dann werden sie auch in der Reihenfolge bearbeiten in der die Zugriffe kommen. Deine Methode ist dann wieder besser geeignet, wenn du kritische, aber selten auftretende Prozesse hast. Ich bin da auch kein absoluter Fachmann, aber da muessten sich haufenweise Lesestoff finden lassen zum Thema Multiport Memory Controller in dem verschiedene Arbitrierungsarten diskutiert werden.
:
Bearbeitet durch User
Lothar Miller wurde im Beitrag #6617310 Zitiert: > "Wesentlich schlimmer als nur der zusätzliche Ressourcenverbrauch ist > aber, dass ein asynchroner Reset zu undefiniertem Verhalten des Designs > beim Verlassen des Resetzustands führen kann. Also, weil Du keine Ruhe gibst: Die interne Logik muss mit synchronem Reset laufen, insofern habe ich den Arbitrator verhunzt. Aber die Pins müssen mit asynchronem Reset in den Safe State versetzt werden. Es kann nämlich auch der Oszillator ausfallen, und dann würden bei synchronem Reset die Pins im letzten Zustand herumhängen.
Beitrag #6617646 wurde von einem Moderator gelöscht.
Beitrag #6617674 wurde von einem Moderator gelöscht.
Beitrag #6617681 wurde von einem Moderator gelöscht.
Klaus S. schrieb: > In der Simulation sieht man schön, dass REQ3 der gearschte Prozess ist, > der bis zuletzt warten muss. Ja, und genau so wie es Tobias geschrieben hat, gibt es viel Lesestoff zu Arbitrierung. In etwas so viel wie OS Scheduling Algorithmen, weil das sehr ähnlich bzw. aus mathematischer Sicht das selbe Problem ist (bitte korrigiert mich, falls ich das falsch interpretiert habe).
Christoph Z. schrieb: > Ja, und genau so wie es Tobias geschrieben hat, gibt es viel Lesestoff > zu Arbitrierung. In etwas so viel wie OS Scheduling Algorithmen, weil > das sehr ähnlich bzw. aus mathematischer Sicht das selbe Problem ist > (bitte korrigiert mich, falls ich das falsch interpretiert habe). das interpretierst du schon richtig. Ein Aspekt ist aber: im Augenblick versucht Klaus die gesamte Arbitrierung in einem Taktzyklus durchzuführen. Wenn es bei dieser einfachen (und schnellen) Herangehensweise bleiben soll, ist die umsetzbare Komplexität der Verteilungsalgorithmen ziemlich eingeschränkt. Aber Klaus schreibt auch, dass er sich Reaktionszeiten im µs-Bereich erhofft. Das lässt locker zu, dass z.B. bei jedem Request ein Prio-Liste durchsucht, der Zugriff danach vergeben und die Prio-Liste für den nächsten Request umsortiert wird. Für nur drei Teilnehmer könnte man das vielleicht noch sinnvoll in einen Taktzyklus reinquetschen, für viele Teilnehmer wäre es sinnvoll, das von einer FSM in mehreren Taktzyklen durcharbeiten zu lassen (und kann damit immer noch leicht im µs-Bereich bleiben).
Achim S. schrieb: > Ein Aspekt ist aber: im Augenblick > versucht Klaus die gesamte Arbitrierung in einem Taktzyklus > durchzuführen. Wenn es bei dieser einfachen (und schnellen) > Herangehensweise bleiben soll, ist die umsetzbare Komplexität der > Verteilungsalgorithmen ziemlich eingeschränkt. Das ist aber für meine Anwendung keine Einschränkung. Ausgangspunkt war ja, das die gesamte Regelung der Anwendung mit einem Prozessor (microCore) erledigt wurde mit nicht-präemptivem OS und fünf Tasks. Von daher war klar, dass die Regelungsebene nicht zeitkritisch ist, weil das alles pseudoparallel abgearbeitet werden konnte inklusive Overhead für den Scheduler. Und sämtliches IO war auch schon wie üblich Memory-mapped. Eine Voll-VHDL Lösung ist auf jeden Fall schneller, weil der Scheduler-Overhead wegfällt. Zumal ja auch bei meiner vorgeschlagenen Methode, das Processor-OS in VHDL zu emulieren, so dass zu jeder Zeit nur ein einziger Regelungsprozess aktiv ist, gar keine Arbitration benötigt, sondern nur ein Busy-Signal der IOs, die mehr als einen Taktzyklus brauchen, um ein Ergebnis zu liefern. Für ADCs kann man das mit Duke Scarrings Methode auf einen Zyklus reduzieren, indem die Ergebnisse dieser "Langläufer" von einem autonomen Modul zyklisch in Registern bereitgestellt werden. Dieses "Sampling" der ADCs wäre in meiner Anwendung auch kein Problem gewesen. Lediglich bei seriellen DACs sehe ich keinen Weg um das Busy herum. Aber das ist eine einzige Leitung je DAC, die an alle Prozesse geliefert wird, die es benötigen. Ich wage die These, dass diese Methode für die meisten Regelungssysteme sinnvoll ist, in denen mehrere Prozesse auf Speicherbereiche zugreifen müssen. Denn: Die "High-Performance" Anwendungen mögen zwar mehr sexy sein, sie sind aber eher selten. Das Brot-und-Buttergeschäft sind sie eher nicht. Auch in meiner Anwendung gibt es einen high-performance Teil, das Wavemeter, das so anspruchsvoll im Timing ist, das es eine eigene VHDL-Entity geworden ist, die sich von der Regelungsebene her als langsames, autonomes IO mit Busysignal darstellt. In der Struktur ist es auch trivial, eine zentrale Resource wie z.B. einen 27x27-bit Multiplizierer (wenn es keine DSP Einheiten gibt wie bei A3PE) allen Prozessen zur Verfügung zu stellen.
Klaus S. schrieb: > Für ADCs kann man das mit Duke Scarrings Methode auf einen Zyklus > reduzieren, indem die Ergebnisse dieser "Langläufer" von einem autonomen > Modul zyklisch in Registern bereitgestellt werden. sehe ich auch so. Klaus S. schrieb: > Lediglich bei > seriellen DACs sehe ich keinen Weg um das Busy herum. Aber das ist eine > einzige Leitung je DAC, die an alle Prozesse geliefert wird, die es > benötigen. warum funktioniert da sinngemäß nicht dasselbe wie bei den ADCs: deine verschiedenen Prozesse schreiben jeweils den aktuell gewünschten Spannungswerte in ein Register. Und ein Prozess läuft ständig alle DAC-Kanäle durch. Wo sich ein Registerwert geändert hat, gibt er den neuen Wert auf den gewünschten DAC aus, und geht dann zum nächsten DAC-Kanal weiter.
Aus Interesse an dem Thema bin ich gestern auf ein Paper gestossen welches den Matrix Arbiter erklaert: https://www.researchgate.net/publication/4079961_Low-Latency_Virtual-Channel_Routers_for_On-Chip_Networks Seite 6, Abschnitt "Precomputing Arbitration Decisions". Ist relativ einfach implementiert, allerdings skaliert das ziemlich schlecht (zumindest wenn man in jedem Zyklus eine Entscheidung vom Arbiter anstrebt). Hier mal was zur Inspiration: https://gitlab.com/baumannt/matrix-arbiter Die ganze XOR Verknuepfung in HDL zu machen, habe ich mir gespart. Macht der Synthesizer besser als ich das kann. ;-) Auch habe ich das leicht modifiziert und die Diagonalelemente alle 1 gesetzt und dabei den Reihen/Spalten Set/Reset vertauscht. Das macht die if Abfrage etwas nicer, vom Logikaufwand reduziert es allerdings nichts. Performance Tests kann ich keine anbieten, mit 16 LUTs und 4 FFs (in einem Artix 7) bei 4 Arbiter Ports kann es aber nicht allzu langsam sein. Keine Ahnung wie weitverbreitet die Idee des Matrix Arbiters ist, ich hab davon gestern zum ersten mal gelesen und finde die Idee sehr smart. Vielleicht interessiert sich ja noch jemand dafuer. :-D
Klaus S. schrieb: > Ich wage die These, dass diese Methode für die meisten Regelungssysteme > sinnvoll ist, in denen mehrere Prozesse auf Speicherbereiche zugreifen > müssen. Kommt drauf an. Ich habe solche Systeme dauernd am werkeln. Lösung: Schatten-RAMs zum Lesen und verjüngende Anfragepipelines zum Schreiben, nach der Methode der "eingeschränkten Schreiberprio" mit 2-stufigem mutal exclusion. Damit ist determinierbar, wie lange ein Schreibzugriff maximal warten muss und das System kann skaliert werden. Braucht halt händische Semaphoren. Ein Tipp noch: Du denkst zu sehr in Prozessen. Diese Abläufe, die da in SW formuliert sind, laufen nicht auf dem FPGA. Sie laufen in der Simulations- und Synthesesoftware. Du brauchts IMMER eine Vorrangschaltung oder eine Veroderung um Information zusammenlaufenzulassen. Das gilt für einfach LEDs, die von zwei Schaltungen gesteuert werden, wie auch komplette Motoren. Als Beispiel aus der Regelung sei noch der Fall der Übernahme einer Regelung durch eine andere beschrieben, weil eine ausgefallen ist oder ihre Überwachung sagt, dass sie ausser Tritt ist. Dann musst du alle Ausgänge "analog" überblenden.
Jonas B. schrieb: > Ich empfehle dir dringend mal die Grundlagen zu lernen: > http://www.lothar-miller.de/s9y/categories/34-Getakteter-Prozess Da habe ich mich erstmal ins Bockshorn jagen lassen :( Auch Miller ist nicht ganz klar. Es gibt sozusagen zwei Sachen, die man asynchrones Reset nennen kann: 1.) Der Reset-Input von außen, bevor er, wie alle externen asynchronen Ereignisse, mit der Systemclock und zwei hintereinandergeschalteten FFs "einsynchronisiert" wird. 2.) Der vor allem bei Xilinx beliebte autonome Reset Eingang an jedem FF. Der Reset ist asynchron und wartet nicht auf die clock am FF-Eingang. Wenn man einen asynchronen Reset gemäß 1. auf den asynchronen Reset Eingang gemäß 2. gibt, kann es zu Clockflankeninterferenz aka Metastabilität kommen. Das kann ein FPGA reichlich durcheinanderbringen und ich erinnere Situationen, in denen es nur noch durch Strom aus/Strom an wieder zurückgeholt werden konnte. Das gleiche gilt aber auch für ein per Logik erzeugtes synchrones Reset eines FF. Wenn da das Reset-Signal nicht einsynchronisiert war, kann es genauso böse enden. Wenn man nun das Resetsignal ordentlich einsynchronisiert hat, kann man es ohne Gefahr sowohl auf den asychronen Reseteingang eines FFs geben, als auch dem FF per synthetisierter Logik unterjubeln. Das ist dann eine Frage der Resourcennutzung. Ich glaube, dass man auch gegen ausfallenden Oszillator gewappnet ist, wenn das äußere Reset so einsynchronisiert wird:
1 | -- reset_a kommt direkt vom Pin
|
2 | SIGNAL reset, reset_1 : STD_LOGIC; |
3 | |
4 | sync_reset : PROCESS (clk, reset_a) |
5 | BEGIN
|
6 | IF reset_a = '1' THEN |
7 | reset_1 <= '1'; |
8 | reset <= '1'; |
9 | ELSIF rising_edge(clk) THEN |
10 | reset_1 <= reset_a; |
11 | reset <= reset_1; |
12 | END IF; |
13 | END PROCESS sync_reset; |
Mit dem reset müsste man jetzt sowohl die interne Logik als auch die Pins treiben können.
Klaus S. schrieb: > 2.) Der vor allem bei Xilinx beliebte autonome Reset Eingang an jedem > FF. Der Reset ist asynchron und wartet nicht auf die clock am > FF-Eingang. Wo gibt es bei Xilinx einen autonomen Reset Eingang? Ungeachet dessen obliegt es dem designer, zu entscheiden, was er bauen möchte. Und wer asynchrone Resets braucht, der muss sich eben mit dessen Eigenschaften herumschlagen. Ich verwende seit 15 Jahren keine mehr.
Klaus S. schrieb: > sync_reset : PROCESS (clk, reset_a) > BEGIN > IF reset_a = '1' THEN > reset_1 <= '1'; > reset <= '1'; > ELSIF rising_edge(clk) THEN > reset_1 <= reset_a; > reset <= reset_1; > END IF; > END PROCESS sync_reset; Das hier ist so eine Sache: Man sollte den letzten Reset völlig synchron betreiben, wenn man einen braucht, weil man sonst ein Problem mit dessen Loslassen bekommt. Was ich dazu nur sagen kann: Finger weg davon! Gerade Xilinx nutzt überall hin- und her-gesychte Resets, die als "asynchron" auf andere Bausteine gehen, nur um sie dort nochmal einzusynchronisieren. Das ist zwar technisch ok, führt jedoch zu einem völlig verworrenen Resetbaum im System, wo keiner mehr weiss, wer wann vor wem losgelassen wurde. Als Resultat hat man ein nichtvorhersagbares Anlaufverhalten und das ist das absoluti wichtigere, als der Vorteil alles schlagartig totlegen zu können. Daher 1. RESET-EINGANG von extern auf ASYNCH-RESET der Master-PLL 2. LOCKED der Master-PLL invertiert auf alle anderen PLLs. 3. LOCKED aller PLLs einsynchronisieren und in der Master-Domain auswerten 4. Wenn alle gestartet, dann nacheinander in der richtigen Reihenfolge resets der Module loslassen und zwar so, dass ausreichend Taktflanken dazwischen sind. 5. Alle Module synchen diesen Reset ein und nutzen ihn lokal für ihre Schaltungen. 6. Module, die mehr als eine domain nutzen, brauchen alle Resets, mit denen sie ihre Schaltungsteile resetten und Signale einsynchen. Das alles sind aber Grundlagen und lösen nicht das vom TE gestellte Problem der Multi-Zugriffe. Dazu lese man sich in die klassischen Methoden des Multi-Taskings ein. Dort sind alle erdenklichen Fälle behandelt und Lösungen publiziert.
FPGA-Master schrieb im Beitrag #6618323: > Das hier ist so eine Sache: Man sollte den letzten Reset völlig synchron > betreiben, wenn man einen braucht, weil man sonst ein Problem mit dessen > Loslassen bekommt. Verdammt, ja, der sync_reset Prozess ist dann zwar der einzig Verbliebene, der mit einem externen asynchronen Reset an seinem asynchronen Reseteingang belästigt wird, kann deshalb aber natürlich selbst aus dem Gleis geworfen werden. Mist. Das mit dem "sofort alles schlagartig totlegen" ist ja tatsächlich nur für die Erzeugung eines Safe-States der Outputpins wichtig. Das muss auch dann funktionieren, wenn der Oszillator steht. Aber dafür kann man getrost den externen, asynchronen Reset nehmen, solange in den Outputpads keine FFs benutzt werden.
:
Bearbeitet durch User
FPGA-Master schrieb im Beitrag #6618323: > Das alles sind aber Grundlagen und lösen nicht das vom TE gestellte > Problem der Multi-Zugriffe. Genau, zu Reset Fragen gibt es hier im FPGA Forum viele Threads, da es immer wieder Diskussions- und Klarstellungsbedarf gibt (und geben wird). War ein Thema das in meinem Studium definitiv vernachlässigt wurde... Klaus S. schrieb: > Aber die Pins > müssen mit asynchronem Reset in den Safe State versetzt werden. Es kann > nämlich auch der Oszillator ausfallen, und dann würden bei synchronem > Reset die Pins im letzten Zustand herumhängen. Ja, diese Anforderung gibt es öfter in sicherheitskritischen Anwendungen. Typische Lösung dazu: Asynchroner Eintritt in den Resetzustand und synchroner Austritt. Genau weil sonst beim Austritt Metastabilität auftreten kann (oder schon mal die verschiedenen Blöcke zu unterschiedlichen Taktflanken zu arbeiten beginnen.)
Christoph Z. schrieb: > (oder schon mal die verschiedenen Blöcke > zu unterschiedlichen Taktflanken zu arbeiten beginnen.) Christoph Z. schrieb: > Klaus S. schrieb: >> Aber die Pins >> müssen mit asynchronem Reset in den Safe State versetzt werden. Es kann >> nämlich auch der Oszillator ausfallen, und dann würden bei synchronem >> Reset die Pins im letzten Zustand herumhängen. Soweit mir bekannt lassen sich die PLLs im FPGA so konfigurieren, dass sie weiterlaufen, wenn die externe PLL ausfällt. So einen Schaltungsblock haben wir hier auf der Basis eines SPARTAN6. Einmal getaktet, rennt der weiter mit ungefähr derselben Frequenz. Also eben die die voreingestellt ist. Wahrscheinlich geht das über die feedback PLL oder den zweiten Eingang.
Tippgeber schrieb: > Soweit mir bekannt lassen sich die PLLs im FPGA so konfigurieren, dass > sie weiterlaufen, wenn die externe PLL ausfällt. So einen > Schaltungsblock haben wir hier auf der Basis eines SPARTAN6. Einmal > getaktet, rennt der weiter mit ungefähr derselben Frequenz. Auch interessant, ja. Im Raumfahrtbusiness musst du den Kunden zuerst mal überzeugen um überhaupt mal eine PLL einsetzen zu dürfen. Aber dann ist das eine Variante. Microchip/Microsemi/Actel hat einen Block in ihren FPGAs um Clocks glitch-frei umzuschalten, damit lässt sich eine Oszillator redundanz bauen.
Noch ein paar Ergänzungen: Klaus S. schrieb: > Ich habe jetzt mal einen Arbitrator für 3 Prozesse gebaut [..] Das ist ein ganz normaler Priority-Arbiter. Alternativ gibt es noch den Round-Robin-Arbiter für gleichverteiltem Zugriff. Ich finde diese zwei Typen reichen für die meisten Fälle aus. Selbst bei Xilinx kann man diese im Interconnect auswählen. Der aktuelle ist fest auf 3 Eingänge ausgelegt. Schaut man jedoch bei den Herstellern in die IPs oder in der Literatur, dann reicht für das generische priority enconding wenige Operationen. Der RR basiert auf dem gleichen Prinzip, hat jedoch zusätzlich einen laufenden Zähler als Basis, wodurch nach jedem Zugriff der nächste Teilnehmer bevorzugt wird. Nochmal zum asynchronen Reset. Verschiedene Standards zur funktionalen Sicherheit verlangen diesen. Auch bei der ESA wird dieser bevorzugt. ..und selbstverständlich ist der Reset-Release immer einsynchronisiert.
Klaus S. schrieb: > Wenn man nun das Resetsignal ordentlich einsynchronisiert hat, kann man > es ohne Gefahr sowohl auf den asychronen Reseteingang eines FFs geben, > als auch dem FF per synthetisierter Logik unterjubeln. Das ist dann eine > Frage der Resourcennutzung. Ich habe jetzt microCore auf Lattice XP2 alternativ implementiert. (In beiden Fällen wird das externe Resetsignal erstmal über 2 FFs einsynchronisiert.) Sowohl Synplify als auch das Lattice P&R hatten einen Clock-Constraint von 25 MHz. 1.) Mit Reset in der Logik 3074 synthetisierte LUTs 31.7 MHz predicted Speed 2097 tatsächlich verbrauchte SLICES 26.3 MHz tatsächliche Speed 2.) Mit Reset am (asynchronen) Reset Eingang der FFs 3006 synthetisierte LUTs 32.5 MHz predicted Speed 2017 tatsächlich verbrauchte SLICES 26.3 MHz tatsächliche Speed Man sieht deutlich, was zu erwarten war: Die Nutzung des separaten Reset-Eingangs vermindert die nötigen Logikresourcen und macht das Design ein kleines bischen schneller.
:
Bearbeitet durch User
Ein Softcore ohne gcc oder llvm frontend ist einfach unbrauchbar, viel zu exotisch. Aber das willst du ja nicht hören.
Jonas B. schrieb: > Ein Softcore ohne gcc oder llvm frontend ist einfach unbrauchbar, viel > zu exotisch. Aber das willst du ja nicht hören. Du bist gerne eingeladen, das für microCore zu realisieren. Ich werde das nicht tun, weil ich nicht einsehe, warum ich freiwillig eine Zwangsjacke wie C anziehen soll. In den letzten 20 Jahren habe ich mit microCore acht eingebettete Projekte realisiert. Soviel zu "unbrauchbar". Der C-compiler auf Basis LCC hat übrigens als Output Forth erzeugt. Dann hat der Crosscompiler zum Abschluss die Peephole-Optimierungen gemacht und die "Symboltabelle" für den Debugger aufgebaut. Dabei ist eines klar geworden: Wegen der Bytementalität von C sind Unions mit microCore nicht möglich, es sein denn, man beschränkt sich auf eine Version mit 16 oder 32 bit Wortbreite und implementiert zusätzliche Byteoperationen per read-modify-write. Letztere bringen aber an Processingpower gar nichts.
Beitrag #6624855 wurde von einem Moderator gelöscht.
Klaus S. schrieb: > Du bist gerne eingeladen, das für microCore zu realisieren. Ich werde > das nicht tun, weil ich nicht einsehe, warum ich freiwillig eine > Zwangsjacke wie C anziehen soll. Naja, C ist Industriestandard. Gegenfrage: Warum sollte sich heute ein Ingenieur mit der Forth-Nische befassen? Klaus S. schrieb: > Der C-compiler auf Basis LCC hat übrigens als Output Forth erzeugt. Dann > hat der Crosscompiler zum Abschluss die Peephole-Optimierungen gemacht > und die "Symboltabelle" für den Debugger aufgebaut. Dabei ist eines klar > geworden: Wegen der Bytementalität von C sind Unions mit microCore nicht > möglich, es sein denn, man beschränkt sich auf eine Version mit 16 oder > 32 bit Wortbreite und implementiert zusätzliche Byteoperationen per > read-modify-write. Letztere bringen aber an Processingpower gar nichts. Wie hier in div. anderen Threads schon nachzulesen ist, macht der LCC wegen seiner nicht-C99-compliance (u.a. designated initializers) eine sehr schlechte Nummer. Auch wenn die CPU-Power auf der Strecke bleibt und man die Multiplexer-Logik fuer Byte/Word-Zugriffe unbedingt sparen will, sollte man wenigstens Byte-Zugriffe emulieren. Es geht dabei vor allem darum, dass sich C-libs wiederverwerten lassen. Dazu kann ich nur raten, die ZPU-Architektur eingehend zu studieren. Ist quasi State-of-the Art, was gut verifizierbare Stackmaschinen (Safety...) mit anstaendigem Compilersupport (GCC, LLVM) angeht. Das Rad mit den Tools will man nicht neu erfinden..
Klakx -. schrieb: > Nochmal zum asynchronen Reset. > Verschiedene Standards zur funktionalen Sicherheit verlangen diesen. > Auch bei der ESA wird dieser bevorzugt. Das funktioniert aber nur, wenn man den reset nicht einsynchronisiert. Die meisten designs sind aber so aufgezogen. Siehe hier: Klaus S. schrieb: > > beiden Fällen wird das externe Resetsignal erstmal über 2 FFs > einsynchronisiert.)
Tippgeber schrieb: > Klakx -. schrieb: >> Nochmal zum asynchronen Reset. >> Verschiedene Standards zur funktionalen Sicherheit verlangen diesen. >> Auch bei der ESA wird dieser bevorzugt. > > Das funktioniert aber nur, wenn man den reset nicht einsynchronisiert. > Die meisten designs sind aber so aufgezogen. Wenn der Reset kommt -> asynchron, wenn der Reset geht -> synchron. Und nur für FF, die das wirklich brauchen. Ich mache keine Raumfahrt und keine ASICs, daher verzichte ich fast immer auf den Reset... Duke
Duke Scarring schrieb: >> Das funktioniert aber nur, wenn man den reset nicht einsynchronisiert. >> Die meisten designs sind aber so aufgezogen. > > Wenn der Reset kommt -> asynchron, > wenn der Reset geht -> synchron. Also so, wenn reset_n vom Pin kommt:
1 | reset_a <= NOT reset_n; |
2 | sync_reset: synchronize PORT MAP (clk, reset_a, reset_s); |
3 | reset <= reset_a OR reset_s; |
Und DAS reset kann man metastabilitätsfrei sowohl an die Pins, an die Logik und die "asynchronen" reset Eingänge der FFs anlegen. > Und nur für FF, die das wirklich brauchen. Ich mache keine Raumfahrt und > keine ASICs, daher verzichte ich fast immer auf den Reset... Wird auch dort so gehalten: Reset nur dann, wenn erforderlich.
Jonas B. schrieb: > Ein Softcore ohne gcc oder llvm frontend ist einfach unbrauchbar, viel > zu exotisch. Aber das willst du ja nicht hören. JaJaJa. Ich hab's inzwischen kapiert, ist ja gut. Ich suche jetzt nach einem Informatik-Masterstudenten, der das als Abschlussarbeit machen würde. Das wird mindestens 2 Jahre dauern, bis da was Brauchbares existiert. Solange kann microCore halt nur im Assembler programmiert werden. Und das Arduino-Board muss dann auch noch so lange warten. Das gibt mir die Zeit, einen 10baseT-PHY im FPGA zu entwickeln und den Code für UDP zu portieren. Ich vermute mal, dass das mit deutlich weniger Strom auskommt, als ein externer 10/100baseT-PHY. Und dann wäre das geplante Arduinoboard IoT-fähig.
Martin S. schrieb: > Dazu kann ich nur raten, die ZPU-Architektur eingehend zu studieren. Ist > quasi State-of-the Art, was gut verifizierbare Stackmaschinen > (Safety...) mit anstaendigem Compilersupport (GCC, LLVM) angeht. Ja, aber wo finde ich eine Beschreibung und ein Bild der ZPU-Architektur? Bisher habe ich bei meiner Suche nur Code gefunden.
Klaus S. schrieb: > 10baseT-PHY im FPGA Ganz rudimentär findet man das hier: https://www.fpga4fun.com/10BASE-T0.html Der Stromverbrauch bei Ethernet kommt m.E. wegen der Treiber. Man will ja nach 200 m Kabel noch Signal haben. Klaus S. schrieb: > Ja, aber wo finde ich eine Beschreibung und ein Bild der > ZPU-Architektur? Die Doku ist etwas versteckt: https://github.com/zylin/zpu/tree/master/zpu/docs Bilder gibt es glaube ich (noch) keine... Hier hat jemand den praktischen Einsatz dokumentiert: https://www.mikrocontroller.net/articles/ZPU:_Softcore_Implementierung_auf_Spartan-3_FPGA Duke
Klaus S. schrieb: > Ja, aber wo finde ich eine Beschreibung und ein Bild der > ZPU-Architektur? Noch eine Schnell-Referenz: http://www.alvie.com/zpuino/zpu_instructions.html Auch eine gute Quelle war die alte Mailing-Liste (http://zylin.com/pipermail/zylin-zpu_zylin.com/), die ist leider aber nicht mehr erreichbar. Der ZPU-Erfinder Oyvind Harboe ist auch seit Jahren nicht sonderlich aktiv an der Front. Die Architektur ist so simpel, dass sie kaum dokumentiert werden muss, allerdings wuerde ich mir die 'Zealot'-Variante anschauen. Ansonsten gabs noch bei papilio.cc etwas Community-Arduino-Bewegung. Klaus S. schrieb: > Ich suche jetzt nach einem Informatik-Masterstudenten, der das als > Abschlussarbeit machen würde Ich lese das mal als 'ironisch gemeint' :-) Falls doch nicht: Es geistert auch noch ein LLVM-Backend zur ZPU(ng) herum, was man sich fuer Stack-Maschinen als Vorbild nehmen kann, allerdings muss deine CPU offset-Adressierung (relativ zum SP) koennen. Von GCC wuerde ich persoenlich die Finger lassen, da das ganze GIMPLE/RTL-Geraffel auf registerbasierte Architekturen ausgerichtet ist. Und erst die Wartungsarbeit fuers Mainlining: Viel Gratis-Arbeit fuer die FSF angesagt und schlussendlich wird dein 'Copyright' entfernt.
Martin S. schrieb: > > http://www.alvie.com/zpuino/zpu_instructions.html Wirklich sehr schlank. Unklar ist mir aber, ob die ZPU einen Return- und einen Datenstack hat, oder ob die Datenoperationen auch alle auf dem Returnstack stattfinden. Wieso kommen die dann nicht mit den Rücksprungadressen ins Gehege? Auf was operieren die NOT, AND, + usw. denn, und wo landet das Ergebnis? Was die Literale angeht: Das macht uCore genauso wie die ZPU. > Ich lese das mal als 'ironisch gemeint' :-) Nein nein, keineswegs, ich habe meine akademischen Kontakte schon angefunkt. > Falls doch nicht: Es geistert auch noch ein LLVM-Backend zur ZPU(ng) > herum, was man sich fuer Stack-Maschinen als Vorbild nehmen kann, > allerdings muss deine CPU offset-Adressierung (relativ zum SP) koennen. Auf llvm als bessere Alternative zu gcc haben mich andere auch schon aufmerksam gemacht. Und ja, microCore kann relativ zum Returnstack adressieren und der Returnstack liegt im Datenspeicher. Zudem wurde für eine frühere uCore-Version bereits das Frontend des lcc modifiziert, so dass Stack- statt Registerallokation gemacht wird. Damit konnten fast alle Zugriffe auf lokale Variablen in Returnstackframes durch den Datenstack und allfällige "Umsortierungsoperationen" ersetzt werden. Kurz: uCore ist mit guter Stackallokation ein ziemlich effizienter C Prozessor. Bleibt nur das blöde Thema Bytes. uCore hat eine konfigurierbare Datenwortbreite und in letzter Zeit benutze ich meist 27 Bits, weil: 1) 16 ist oft zu wenig. 2) 24 ist meist genug. 3) blockRAMs sind 9 Bits breit, warum da was wegwerfen? -> 27 Bits.
Klaus S. schrieb: >> Ich lese das mal als 'ironisch gemeint' :-) > > Nein nein, keineswegs, ich habe meine akademischen Kontakte schon > angefunkt. Dann halte ich es aber fuer bedenklich wenn du deinen microCore verkaufen moechtest. Oder stellst du en Studenten in der Zwischenzeit als an Werkstudent an und bezahlst ihn auch entsprechend?
Tobias B. schrieb: > Dann halte ich es aber fuer bedenklich wenn du deinen microCore > verkaufen moechtest. Ja, finde ich auch. Ich stelle mit dem nächsten Update auf git den VHDL-Code unter eine Public License, die im Prinzip wie BSD oder LGPL ist. "Nimm es und mach was draus." Die Forth-Nische stellt schon sicher, dass ich nicht von Supportanforderungen überwältigt werde ;)
Klaus S. schrieb: > Ich stelle mit dem nächsten Update auf git den VHDL-Code unter eine > Public License, die im Prinzip wie BSD oder LGPL ist. "Nimm es und mach > was draus." Very nice! :-D
Klaus S. schrieb: > Beim Flight-Model Klaus S. schrieb: > Ich suche jetzt nach einem Informatik-Masterstudenten, der das als > Abschlussarbeit machen würde. Klaus S. schrieb: > das geplante Arduinoboard Also verwendest du "Flight-Model" nur als coole Bezeichnung? Das ist ja nicht wirklich etwas mit Luft&Raumfahrt? mfg
A. K. schrieb: > Also verwendest du "Flight-Model" nur als coole Bezeichnung? > Das ist ja nicht wirklich etwas mit Luft&Raumfahrt? Das sind zwei verschiedene Projekte: Das letzte Projekt vor meiner Verrentung war die Steuerung der "Frequency Reference Unit" für das deutsch/französische MERLIN-Projekt. Damit wird der Methangehalt der Atmosphäre aus 400 km Höhe gemessen werden. Das Zukunftsprojekt ist "Arduinoboard", das jetzt erstmal warten muss, bis eine traditionelle Entwicklungsumgebung für microCore steht.
:
Bearbeitet durch User
Klaus S. schrieb: > Wirklich sehr schlank. Unklar ist mir aber, ob die ZPU einen Return- und > einen Datenstack hat, oder ob die Datenoperationen auch alle auf dem > Returnstack stattfinden. Wieso kommen die dann nicht mit den > Rücksprungadressen ins Gehege? Auf was operieren die NOT, AND, + usw. > denn, und wo landet das Ergebnis? Was die Literale angeht: Das macht > uCore genauso wie die ZPU. Die ZPU kommt mit einem Stack aus, die Operationen laufen auf TOS/NOS, in der obigen ZPUino-Uebersicht ist das pro opcode in Pseudocode beschrieben, wer was wie macht. Etwas knapp, aber umsetzbar. Als Assembly-Hacker muss man halt das Stack-Unwinding im Blick haben, und der C-Compiler es richtig machen :-). Klaus S. schrieb: > Bleibt nur das blöde Thema Bytes. uCore hat eine konfigurierbare > Datenwortbreite und in letzter Zeit benutze ich meist 27 Bits, weil: Das Problem hat grundsaetzlich die abgespeckte ZPU-Variante auch, die emulierten Befehle (wenn nicht in HW implementiert, wird in den Emulation-'uCode'-Bereich gesprungen) sind dir bestimmt aufgefallen. Hier waeren das also LOADB/STOREB. An der Stelle spare ich mir lieber verstopfende Logik und lasse den Byte-I/O die DMA-Engine erledigen. Vorbild hier: Blackfin-Architektur. Braucht dann auch kaum noch Interrupts, aber mindestens Dual-Port-Memory.
>Das Zukunftsprojekt ist "Arduinoboard", das jetzt erstmal warten muss, >bis eine traditionelle Entwicklungsumgebung für microCore steht. Das scheint mir hier ganz passend: https://www.eejournal.com/article/fpga-based-arduino-clones-on-steroids/ Die große Kunst ist ja, die Einfachheit der Arduinowelt auf ein FPGA zu übertragen. Das ist aber meiner Meinung nach Arduino selbst nicht gelungen: https://store.arduino.cc/arduino-mkr-vidor-4000
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.