Forum: FPGA, VHDL & Co. Microblaze Timingprobleme


von Emp (Gast)


Lesenswert?

Hi

Nachdem ja das große Flashproblem gelöst ist bin ic jetzt wieder auf
der Suche nach der Lösung für mein eigentliches Problem.
Mal ein kurzer Überblick:
Ich bin dabei ein Sysem zu entwickeln mitdem es möglich ist Daten
zwischen PCM und LAN zu senden. Ich verwende das ML403 von Xilinx, den
Microblaze, uc/OS II als RTOS und den TCP/IP Stack von Micrium. Die
Entwicklunsumgebung ist das EDK von Xilinx.
Mein Problem ist das es sehr lange dauert bis eine Instruction
ausgeführt wird bzw. bis eine Funktion durchlaufen ist. Kurz gesagt,
irgendwie läuft das ganze System zu langsam. Der Interrupt des
PCM-Moduls kommt alle 125us und es soll in der ISR nur eine Semaphore
gepostet werden welches eine Task aufweckt. Die Ausführung dieser
Funktion dauert z.b. 12us, das ist eindeutig zu lange. Es funktioniert
sonst alles einwandfrei, PCM Interrupt kommt 8000 mal die Sekunde,
senden und empfangen von Daten über LAN klappt auch und auch meine
Tasks laufen wunderbar und machen das was sie sollen. Sobald ich das
Semaphore in der ISR poste, läuft nur nur die ISR und die Tasks kommen
nur noch sporadisch zum Zug. Ich habe schon mehrere Messungen mit dem
Oszilloskope durchgeführt und mit Chipscope ein paar Signale im FPGA
getriggert.
Dabei ist mir aufgefallen das zwischen den valid Instructions sehr
viele Taktzyklen nichts passiert.
Mit Xilinx bin ich auch jeden Tag am telefonieren, die haben aber auch
noch keine Erklärung dafür.
Da mein Programm aus dem DDR-RAM ausgeführt habe ich mal ein paar
Einstellungen für den I- und D-Cache vorgenommen.
Hier mal ein Auszug aus dem *.mhs File:

PARAMETER C_USE_ICACHE = 1
 PARAMETER C_CACHE_BYTE_SIZE = 8192
 PARAMETER C_USE_DCACHE = 1
 PARAMETER C_DCACHE_BYTE_SIZE = 8192
 PARAMETER C_ICACHE_USE_FSL = 1
 PARAMETER C_DCACHE_USE_FSL = 1
 PARAMETER C_ICACHE_BASEADDR = 0x28000000
 PARAMETER C_ICACHE_HIGHADDR = 0x28080000
 PARAMETER C_DCACHE_BASEADDR = 0x28000000
 PARAMETER C_DCACHE_HIGHADDR = 0x28080000
 PARAMETER C_ADDR_TAG_BITS = 6
 PARAMETER C_DCACHE_ADDR_TAG = 6
 BUS_INTERFACE DLMB = dlmb
 BUS_INTERFACE ILMB = ilmb
 BUS_INTERFACE DOPB = mb_opb
 BUS_INTERFACE IOPB = mb_opb
 BUS_INTERFACE IXCL = ixcl
 BUS_INTERFACE DXCL = dxcl

Wenn ich das aus der Dokumentation richtig verstanden hab müsste das so
passen. Ich cache nur die ersten 512 kb des DDR-RAM da mein Programm nur
310kb groß ist.
Ich weiß das es eigentlich nicht möglich ist bei einem solchen Projekt
eine Ferndiagnose zu stellen aber vielleicht hatte ja mal jemand ein
ähnliches Problem.

Ist auch alles ein bisschen kurz gefasst aber ich kann ja schlecht die
letzten Wochen hier niederschreiben ;).

Vielleicht kann mir ja von euch jemand helfen.

cu

Emp

von antti (Gast)


Lesenswert?

das 12uS scheint schohn glaubwurdig sein.

man muss damit leben das das MicroBlaze from ext RAM nicht so rasend
schnell lauft. Und die GCC macht auch nicht immer den besten job.

zb wenn ein MB system mit 50MHz gpio bitbang macht dann (mit
high level gpio treiber), dann ist es langsamer als mit 8MHz AVR!

du hast sysclock was 75MHz? die ext RAM zugriff kann 10 clocks sein, so
das wir dan effizienten instruction rate von 7MHz haben. 100
instructions furs register context save and exit von interrupts,
na ja haben wir ja deine 12uS fur die interrupt processing!

Antti

von breti (Gast)


Lesenswert?

Also der EMC (extended memory controller) hat laut Xilinx eine
Latenzzeit von 11-15 Zyklen für jeden Zugriff. Das Problem hatte ich
auch schon und hatte das daher mal nachgefragt. Angeblich gibts bald ne
optimierte Version (ob die auch DDR Ram kann, weiß ich nicht).

Gruß,
Thomas

von Emp (Gast)


Lesenswert?

Hi

Erstmal danke an euch, dass Problem ist in der Tat die Zugriffszeit auf
den DDR-RAM.

>Angeblich gibts bald ne optimierte Version

Ja das ist das Cachelinkinterface das auch über eine FSL angebunden
werden kann. Hab ich auch gemacht aber wenn ich mir mit Chipscope mal
die I bzw. D-Cachesignale angucke wird nicht einmal auf den Cache
zugegriffen.
Hat hier schon mal wer ein Projekt erzeugt in dem der Cache verwendet
wird? Das schlimme ist, dass ich jeden Tag mit Xilinx telefoniere und
die das auch nicht hinkriegen. Ganz schön scheiße, vor allem weil meine
Diplomarbeit ja schon läuft.

So hab ich es probiert und laut Xilinx ist das korrekt:

*.mhs:
microblaze
 PARAMETER C_USE_ICACHE = 1
 PARAMETER C_CACHE_BYTE_SIZE = 8192
 PARAMETER C_USE_DCACHE = 1
 PARAMETER C_DCACHE_BYTE_SIZE = 8192
 PARAMETER C_ICACHE_USE_FSL = 1
 PARAMETER C_DCACHE_USE_FSL = 1
 PARAMETER C_ICACHE_BASEADDR = 0x28000000
 PARAMETER C_ICACHE_HIGHADDR = 0x28080000
 PARAMETER C_DCACHE_BASEADDR = 0x28000000
 PARAMETER C_DCACHE_HIGHADDR = 0x28080000
 PARAMETER C_ADDR_TAG_BITS = 6
 PARAMETER C_DCACHE_ADDR_TAG = 6
 BUS_INTERFACE IXCL = ixcl
 BUS_INTERFACE DXCL = dxcl

DDR
 BUS_INTERFACE MCH0 = ixcl
 BUS_INTERFACE MCH1 = dxcl


Software:

  microblaze_init_icache_range(0x0000, 8192);

  microblaze_enable_icache();

(erstmal nur I-Cache)

Funktioniert aber nicht.

Hat einer ne Idee?

cu

Emp

von Emp (Gast)


Angehängte Dateien:

Lesenswert?

Hi

So der I-Cache funktioniert jetzt wohl, bringt aber leider nichts an
Geschwindigkeit. Leider kommt von Xilinx auch nicht mehr viel außer
Ausreden und viel um den heißen Brei gerede.
Ich poste hier mal ein Teil der Mail an Xilinx die mein Problem zeigt:


.... der I-Cache funktioniert jetzt allerdings ist die Ausführung des
Semaphores nicht schneller geworden.

Ich habe mal ein paar Sachen ausprobiert und habe nun ein paar Fragen:

Ich habe zunächst alle Variablen über das l-Skript in das BRAM
geladen:

.rodata,.sdata,.data

Als Test habe ich mal folgendes in meiner ISR gemacht

ISR
{
"Interrupts deaktivieren"

PCM_mWriteDEBUG(PCM0_BASEADDR, 0x01);

 ccx= 50+bb*100/20+cc; (alles globale Variablen)

PCM_mWriteDEBUG(PCM0_BASEADDR, 0x00);

"Interrupts aktivieren"
}

Meine erste Frage: Warum wird die gesamte Rechung gelöscht wenn ich die
Optimierung auf 1 oder höher stelle?


Wenn ich direkt den ersten Durchlauf triggere, sieht es so aus:
(Bild1)

Diese 4 Instructions benötigen also 7 oder 8 cycles, was ja zu passen
scheint.


Jetzt mal ein Bild wenn ich später noch einmal triggere:
(Bild2)

Die 2048 cycles die ich aufzeichne reichen nicht aus.

An der Vergrößerung sieht man das die Ausführungszeiten um mehr als das
10 fache länger geworden sind.

Auch der Zugriff auf das BRAM!


Beim posten des Semaphores zeigt sich ein ähnliches Bild, im ersten
durchlauf 1us und danach ca. 17us.

PCM_mWriteDEBUG(PCM0_BASEADDR, 0x01);

    os_err = OSSemPost(PCM_Signal);

PCM_mWriteDEBUG(PCM0_BASEADDR, 0x00);
(Bild3)

28002cdc:         b0002803           imm        10243
28002ce0:         e8a0f564           lwi        r5, r0, -2716
        // 2803f564 <PCM_Signal>
28002ce4:         b0000003           imm        3
28002ce8:         b9f4c494           brlid      r15, -15212
       // 2803f17c <OSSemPost>
28002cec:         80000000           or         r0, r0, r0

(Bild4)

2803f1d0:          f873001c           swi       r3, r19, 28
2803f1d4:          e873003c          lwi        r3, r19, 60
2803f1d8:          e063000a          lbui       r3, r3, 10
2803f1dc:          bc030044          beqi      r3, 68
2803f1e0:          e8b3003c          lwi        r5, r19, 60
2803f220:          e873003c          lwi        r3, r19, 60

Bei den Vergrößerungen sieht man auch, dass die meiste Zeit für das
Lesen und Schreiben auf den Speicher drauf geht.

Ich kann in meinem Projekt den Data Cache ja nicht aktivieren.

Wie kann ich den d-Cache verwenden?
(Funktioniert angeblich "manchmal nicht in Verbindung mit dem I-Cache.
Ist auch so eine Aussage die ich nicht nachvollziehen kann)


Hier noch ein Bild wenn ich später noch einmal triggere:
(Bild 5)

Da sind dann die 17us.

Eine Frage habe ich noch zum Linkerscript:

Ich habe versucht einige Codefiles in das BRAM zu linken und bin dabei
wie folgt vorgegangen:

.text : {
   __text_start = .;
*(EXCLUDE_FILE(C:/DiplomEDK/Final/PCMLAN/microblaze_0/libsrc/uCOS-II_v2_ 
81_a/src/os_sem.o).text)
   *(.text)
   *(.text.*)
   *(.gnu.linkonce.t*)
   __text_end = .;

} > DDR_SDRAM_64Mx32_C_MEM0_BASEADDR


.bram_text : {

   __bram_text_start = .;

C:/.../microblaze_0/libsrc/uCOS-II_v2_81_a/src/os_sem.o(.text)

   __bram_text_end = .;

} > ilmb_cntlr_dlmb_cntlr


Wenn ich das ganze ohne Pfadangabe mache wird das .o File nicht
gefunden.

Leider werden die Funktionen weiterhin ins DDR RAM geschrieben


Mal gucken ob von euch einer ne Idee hat. Das Problem ist das ich mich
jetzt mehr oder weniger damit abfinden muss.
Zum Glück muss ne Diplomarbeit kein Happy End haben.

bis dahin

Emp

von nimbus4 (Gast)


Lesenswert?

Es wird dir zwar vermutlich nicht weiterhelfen, aber es macht den
Eindruck, daß du die Mail an eine Xilinx-Vertretung in Deutschland
geschickt hast. Ich würde mal vermuten, daß die hier nur ein
beschränktes Fach- bzw. eher Anwenderwissen zum MicroBlaze besitzen.
Ab und zu taucht mal der Name des Typen im Netz auf, der den MicroBlaze
entwickelt hat. Vielleicht wäre es einen Versuch wert, dem mal ne Mail
zu schreiben.
Ansonsten bliebe noch die Möglichkeit, selbst Hand an den
DDR-RAM-Kontroller anzulegen. Wenn der MicroBlaze mit ~ 100Mhz läuft
und man das RAM mit ~ 200Mhz betreibt sollten wahlfreie Zugriffe in der
Regel in weniger als 5 CPU Zyklen möglich sein. Läd man direkt eine Art
ganze Cache-Line, muß der ganze Prozess deutlich zu beschleunigen
sein.
Ein Beispiel dafür kann ich dir im Moment leider noch nicht geben, da
ich mein Board mit DDR erst seit kurzem besitze und noch keine Zeit
hatte, mich an die Ansteuerung des DDR zu machen

von Emp (Gast)


Lesenswert?

Hi
Ich freue mich über jede Antwort die ich kriege ;).
Leider hast du was meinen Ansprechpartner angeht wohl recht, über allzu
viel Fachwissen scheint er wohl ehr nicht zu verfügen. Die hohe Laufzeit
durch Sprünge des RTOS zu erklären, obwohl ich von der Ausführungsdauer
einzelner Assembler Instructions rede ist schon sehr merkwürdig.

Am Zugriff auf denn DDR RAM scheint es aber auch nicht wirklich zu
liegen. Wie man auf Bild 2 erkennt dauert auch der Zugriff auf eine
Variable im BRAM mehr als 20 cyclen.
Ich kann mir das leider nicht erklären warum das so. An der
Ausführungsdauer eines Assemblerbefehls kann ich nun mal auch nichts
ändern.

Leider wird die Zeit langsam knapp.

Meine letzte Idee wäre einen Nonmaskable Interrupt für das PCM-Modul zu
verwenden und den Ext_NM_Brk Input Port vom Microblaze nutzen. Damit
umgeh ich zwar das RTOS und kann in der ISR keine Semaphores nutzen
aber die Verzögerung wäre wohl um einiges geringer.


Hat hier evtl. jemand Erfahrung???

Cu
Emp

von Fibunacci (Gast)


Lesenswert?

Hallo,

würdest du wieder eine Diplomarbeit mit dem MicroBlaze machen? Ich
stehe gerade vor der Entscheidung, ob ich ein Thema mit dem MicroBlaze
nehme oder nicht. Ist der MicroBlaze schon so weit, dass man mit ihm
arbeiten kann oder soll man lieber die Finger davon lassen?

Cu Fibunacci

von Emp (Gast)


Lesenswert?

Hi
Nein würde ich nicht machen, bei mir wurde das Thema jetzt auch etwas
angepasst. Es sollte zwar von Anfang an eine Machbarkeitsstudie sein
aber mit diesen Problemen hat wirklich niemand gerechnet.
Vielleicht lässt sich deine Diplomarbeit ja auf Alterabasis
durchführen.
Die sind auf diesem Gebiet um einiges weiter als Xilinx und die
Toolkette ist auch um einiges besser.
Wenn du fragen hast kannste dich gerne an mich wenden.

cu
Emp

von Fibunacci (Gast)


Lesenswert?

Hallo,

bei mir soll der Startschuss für die DA am 1. Oktober fallen. Habe aber
schon inoffiziell bei einer Firma zugesagt. Zum üben habe ich das
Demoboard Spartan 3E Starter Kit bekommen. Muss ganz ehrlich sagen,
dass es teilweise echt schwierig ist einen Überblich über alles zu
bekommen. Sehr viel habe ich auch bisher noch nicht zum Laufen bekommen
oder mich noch nicht daran getraut. Einfache Dinge funktionieren schon
(user IP). Was mir im Moment Kopfschmerzen bereitet ist das Thema
Interrupts.
Habe probiert einen einfachen Timer-Interrupt auszulösen Leider
vergeblich. (Der VHDL-Code wird ja dafür als Beispiel vom Wizard
generiert) Könntest du mir vielleicht ein paar Tips geben auf was ich
hier besonders achten muss.
Danke für deine Hilfe.

Gruß fibunacci

von Emp (Gast)


Lesenswert?

Hi

Habe im Moment ein bisschen Streß, werd nachher mal gucken ob ich noch
ein einfaches Projekt finde.
Wenn du mal im EDK Ordner guckst:
\\EDK\hw\XilinxProcessorIPLib\pcores

Da sind zu jeder Hardware Softwarebeispiele.

cu
Emp

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.