Hallo,
habe ein Modul erstellt, mit welchem ich Werte > 8-Bit im FPGA ablegen
kann.
Sinn des Ganzen ist, dass ich per asynchronem Lesezugriff die ganze
Breite in einem Takt auslesen kann.
Zusätzlich soll der Wert über eine 8-Bit Schnittstelle gelesen und
geschrieben werden können (später via pico + adress-mux).
Synthese hat soweit geklappt, Zeiten scheinen auch ok zu sein, aber
subjektiv hat Pro7 - äh, meine natürlich RTL einen Haufen muxes
verbraten.
Frage: lässt sich der Code umformulieren, sodass weniger muxes verwendet
werden, ohne den Zugriff deshalb zu verlangsamen?
Ich würde nicht alles in dem CASE zustand Codieren was versprichst du
dir davon? Ich glaub das du es der Synthese damit nur unötig schwer
machst.
Ebenso das invert byte Order. Das würd ich rausnehmen und dafür ein
writehih/lo signal draus machen, denn was machst du falls du irgenwann
mal nicht mehr weisst in welchem Zustand du bist?
Also statt byteOrder z.B.
writeTmp : in std_logic; -- selects byte 0
und dann:
1
process
2
begin
3
waituntilrising_edge(clk);
4
-- synchronous 8-bit write with write enable
5
if(we='1')then
6
ifwriteTmp='1'then
7
tmp<=di;
8
else
9
data<=tmp&di;
10
endif;
11
endif;
12
-- synchronous 8-bit read with read enable
13
if(re='1')then
14
ifwriteTmp='1'then
15
do<=data(15downto8);
16
else
17
do<=data(7downto0);
18
endif;
19
endif;
20
endprocess;
Die Byte order hängt dann halt ganz normal von der Reihenfolge der
lese/schreibzugriffe ab, aber da wirst du ja eh ne SW einsetzen so wie
ich das verstanden habe?
Hallo Läubi,
Danke für Deine Aufmerksamkeit!
Ich hätte wohl etwas mehr über den pico dazu schreiben sollen.
Der hat einen 8-Bit Port und eine 8-Bit Adress-Ausgabe.
Meine Variablen, die größer 8 Bit sind, sollen in die Schnittstelle des
Pico passen, aber für die VHDL-Module, die die Werte verwenden, soll es
transparent sein, wer die Werte wie verändert.
Deshalb habe ich keine zusätzlichen Leitungen, die ich steuern könnte
(die Inv-Leitung würde ich mit einem Schiebeschalter verdrahten, über
den ich dann festlege, ob ich die UART- oder Ethernet-Schnittstelle
verwende).
Bei der 8-Bit Schnittstelle dachte ich mir, dass ich einfach 2 Lese-
bzw. 2 Schreibzyklen im Pico auf die (gleiche) Adresse mache. Dadurch
habe ich die Möglichkeit, dass das VHDL-Modul den geänderten Wert erst
nach dem 2. Schreibzyklus sieht. Somit können beide mit völlig
unterschiedlichen Frequenzen arbeiten.
Normalerweise bräuchte ich einen Zähler für die Anzahl der Zugriffe,
aber da es nur 2 Zugriffe sind, dachte ich, ich kann es mit in den Case
packen.
Das für das 3-stellige 'cmd' muxes erzeugt werden, ist mir völlig
einsichtig. Da bin ich mit einverstanden.
Aber dass für die Byte-Reihenfolge auch muxes verbraten werden, das ist
mir nicht unbedingt einsichtig.
Aber vielleicht fehlt es auch nur wieder am Verständnis?
Anfänger schrieb:
> Ich hätte wohl etwas mehr über den pico dazu schreiben sollen.> Der hat einen 8-Bit Port und eine 8-Bit Adress-Ausgabe.> Aber vielleicht fehlt es auch nur wieder am Verständnis?
Der hat aber auch noch einen Addresport!
Wenn nix dagegensprich würd ich einfach den verwenden.
> habe es geschafft zu reduzieren, indem ich tmp vergrößert und wie ein
Jezt hast du aber nicht mehr dein Forderung
'so the asynchronous read never sees an invalid intermediate value'
vieleicht so:
asData<=data;-- asynchronous read using full data width
6
7
process
8
begin
9
waituntilrising_edge(clk);
10
-- synchronous 8-bit write with write enable
11
ifwe='1'then
12
caseaddressis
13
whenx"01"=>
14
tmp<=di;
15
whenx"02"=>
16
ifinv='0'then
17
data<=di&tmp;
18
else
19
data<=tmp&di;
20
endif;
21
whenothers=>NULL;
22
endcase;
23
endif;
24
-- synchronous 8-bit read with read enable
25
if(re='1')then
26
caseaddressis
27
whenx"01"=>
28
do<=data(15downto8);
29
whenx"02"=>
30
do<=data(7downto0);
31
whenothers=>do<=(others=>'-');
32
endcase;
33
endif;
34
endprocess;
35
endstd;
> bzw. 2 Schreibzyklen im Pico auf die (gleiche) Adresse mache.
Das ist aber unpraktisch, nutze lieber den Addressport dafür, der Wert
wird eh im Zugriff auf den Port mitcodiert!
> den ich dann festlege, ob ich die UART- oder Ethernet-Schnittstelle
Naja ich würde mich für eine Byte order entscheiden und dann IM Modul
entsprechend "richtig rum" drauf zugreifen sonst hast du immer ne ganze
Menge Logik (zwangsweise) dazwischen für eine Umschaltung die dur
eigentlich nicht machen mußt. Weil ob du in einem Modul schreibst:
xyz <= meine16bit;
oder
xyz <= meine16bit(7 downto 0)&meine16bit(15 downto 8);
verbraucht im schlimsten falle nur etwas zusätzliche
Verdrahtungsrecourcen. Wenn du das aber umschaltbar machst wirst du
Immer logikrecource resp. einen Mux brauchen!
>> Ich hätte wohl etwas mehr über den pico dazu schreiben sollen.>> Der hat einen 8-Bit Port und eine 8-Bit Adress-Ausgabe.>> Aber vielleicht fehlt es auch nur wieder am Verständnis?> Der hat aber auch noch einen Addresport!> Wenn nix dagegensprich würd ich einfach den verwenden.
Sorry, wenn ich mit den Fachbegriffen (noch) nicht so vertraut bin.
Mit der 8-Bit Adress-Ausgabe meinte ich ja den Adressport. Der ist
schon in Verwendung, um auf das memory-Element zuzugreifen (ich setze
mehrere unterschiedliche Elemente über einen Multiplexer an den
out-port, bzw. in-port, brauche also die Adressen).
>> habe es geschafft zu reduzieren, indem ich tmp vergrößert und wie ein> Jezt hast du aber nicht mehr dein Forderung> 'so the asynchronous read never sees an invalid intermediate value'
Hast Du den Code angeschaut? - Ich meine, dass ich die Forderung
berücksichtigt habe. Wenn dem nicht so ist, würde ich mich über einen
konkreten Hinweis (Zeile, o.ä.) freuen.
>> bzw. 2 Schreibzyklen im Pico auf die (gleiche) Adresse mache.> Das ist aber unpraktisch, nutze lieber den Addressport dafür, der Wert> wird eh im Zugriff auf den Port mitcodiert!
Hm, könntest Du mir das bitte etwas deutlicher erklären?
Nehmen wir mal an, die Variable würde eine PWM-Frequenz beinhalten. Wenn
also das PWM-Modul aktiv ist, liest dieses (asynchron, weil andere
Frequenz als der Pico) die Variable in ganzer Breite aus.
Wenn ich jetzt per serieller Schnittstelle den Wert ändern will, kommt
der 16-Bit-Wert in einer anderen Byte-Reihenfolge in den FPGA, als wenn
ich ihn über die Ethernet-Schnittstelle ändere. Also muss ich doch an
der Benutzer-Schnittstelle die Bytereihenfolge beachten, nicht aber an
der PWM-Seite, die den Wert verwendet.
Wenn ich jetzt einfach ein Array von Speicherzellen nehme und mit dem
Pico ein Byte nach dem anderen beschreibe, wer verhindert dann, dass das
PWM-Modul nach dem ersten Schreibvorgang ausflippt, weil der Wert nicht
stimmt? Oder das DAC-Modul würde die Übertragung bei geändertem Wert
starten. Nach dem ersten Schreibvorgang des Pico ist der Wert zwar
geändert, aber falsch - d.h. das DAC müsste 2 Übertragungen ausführen?!?
Vielleicht denke ich ja auch zu kompliziert - keine Ahnung?
Ich habe bislang nix gefunden, was unkonsistente Mehrbyte-Werte bei
8-Bit Schnittstelle verhindern würde (mein Doppelschreibzyklus auf die
gleiche Adresse wirkt nach außen ja wie ein Latch, das erst nach dem
letzten Schreibzugriff wechselt).
> Ich habe bislang nix gefunden, was unkonsistente Mehrbyte-Werte bei> 8-Bit Schnittstelle verhindern würde.
Das ist das klassische Problem des Einsynchronisiserens:
Wenn du etwas in mehereren Schritten änderst, und ein anderer schaut
zwischendurch da drauf, dann sieht er falsche Daten.
Also mußt du erst alle Daten (z.B. 4 Bytes) nacheinander zu einem großen
Wort (z.B. Long) zusammensetzen, und dann mit einem Flag signalisieren,
dass dur fertig bist.
Bei uC wird es gern auch so gemacht, dass du eine bestimmte Reihenfolge
einhalten mußt (z.B. bei den 16-Bit-Timern des AVR). Wenn z.B. das LSB
geschrieben wird, wird gleichzeitig das MSB aus einem Schattenregister
mitgeschrieben. Also gilt dann: erst das MSB schreiben, dann das LSB.
> wer verhindert dann, dass das PWM-Modul nach dem ersten> Schreibvorgang ausflippt
Du selbst mußt das verhindern, du beschreibst die Hardware. Du hast
dafür zu sorgen, dass die Daten am Eingang des PWM-Moduls immer
konsistent sind.
> Wenn also das PWM-Modul aktiv ist, liest dieses (asynchron, weil andere> Frequenz als der Pico) die Variable in ganzer Breite aus.ImFPGA haben die Begriffe synchron und asynchron eine ganz bestimmte
Bedeutung. Synchron sind Baugruppen, die sich auf den selben Master-Takt
beziehen. Synchron sind auch Takte, die über einen DCM gewonnen werden.
Ein wirklich asynchrones Design mit 2 oder mehr unabhängigen Takten
solltest du unter allen Umständen vermeiden. Da mußt du dann
Einsynchronisieren.
Anfänger schrieb:
> Mit der 8-Bit Adress-Ausgabe meinte ich ja den Adressport. Der ist> schon in Verwendung, um auf das memory-Element zuzugreifen (ich setze
Dann ist dein Konzept noch etwas überholungsbedürftig ;)
Denn der Addressport wird ja bei jedem! Zugriff auf die in/out Ports
benuzt, wenn du den einfach an einen RAM legst kommt da kuddel muddel
raus.
> Hast Du den Code angeschaut? - Ich meine, dass ich die Forderung> berücksichtigt habe. Wenn dem nicht so ist, würde ich mich über einen> konkreten Hinweis (Zeile, o.ä.) freuen.
Ich kann mich irren aber
Eine 'variable' ist nur von begin bis end des Prozesses gültig! D.h. dir
geht die Funktionalität die du eigentlich haben wolltest verloren.
> Hm, könntest Du mir das bitte etwas deutlicher erklären?
Siehe mein Beispiel.
> Wenn ich jetzt per serieller Schnittstelle den Wert ändern will, kommt> der 16-Bit-Wert in einer anderen Byte-Reihenfolge in den FPGA, als wenn> ich ihn über die Ethernet-Schnittstelle ändere.
Für das Schreiben gilt das gleiche wie für das Lesen! Wenn deine
Schnittstelle halt eine andere Byteorder hat änderst du das direkt beim
Schreiben IN diesem Modul.
> 8-Bit Schnittstelle verhindern würde (mein Doppelschreibzyklus auf die> gleiche Adresse wirkt nach außen ja wie ein Latch, das erst nach dem> letzten Schreibzugriff wechselt).
Nur das du u.U. nicht weißt was "der lezte" war... Lothar hat ja schon
beschrieben wie es z.B. bei den AVR gemacht wird mein Beispiel
Funktioniert ähnlich.
Das schreiben auf Addresse 1 speichert den Wert zwischen, das Schreiben
auf Addresse 2 gibt den Wert und den gespeicherten aus.
Hallo und danke für Eure Unterstützung!
> Bei uC wird es gern auch so gemacht, dass du eine bestimmte Reihenfolge> einhalten mußt (z.B. bei den 16-Bit-Timern des AVR).
Yepp - das wusste ich z.B. auch von der AVR-ADC-Schnittstelle und wollte
etwas ähnliches realisieren.
> Eine 'variable' ist nur von begin bis end des Prozesses gültig! D.h. dir> geht die Funktionalität die du eigentlich haben wolltest verloren.Herzlichen Dank! Das ist doch wieder eine wertvolle Information, die
mir fehlte! Weiß jetzt nicht, ob ich das überlesen hatte oder einfach
nicht kapiert - egal. Dann hast Du natürlich recht!
> Für das Schreiben gilt das gleiche wie für das Lesen! Wenn deine> Schnittstelle halt eine andere Byteorder hat änderst du das direkt beim> Schreiben IN diesem Modul.
Das wird schwierig. Die serielle Schnittstelle transportiert doch nur
Bits, bzw. Bytes. Die weiß nichts über die logische Bedeutung der Daten.
Erst der Pico weiß, dass z.B. zwei Bytes zu einem Int zusammen gefasst
werden sollen.
Nach meiner Vorstellung sollten die Module zur Benutzerschnittstelle
aber wie Plugin-Blackboxes für den Pico sein, d.h. er bezieht seine
Daten und schreibt die dahin, wo es für den entsprechenden Befehl sein
soll. Die Konvertierung sollte auch für ihn transparent sein (so
zumindest meine Vorstellung).
Sorry, aber ich habe noch kein Gefühl dafür, wie stark der
Resourcenverbrauch einer bestimmten Idee ist. Kann sein, dass mein
"Konzept" garnicht in den Spartan3 reinpasst.
Im Moment versuche ich jedenfalls so viel wie möglich in
"Hardware"-Module zu packen und nur das, was nimmer anders geht, vom
Softcore machen zu lassen.
Ob das Vorgehen praktikabel oder praxistauglich ist - kann ich noch
nicht beurteilen. Es ist für mich zu großen Teilen noch ein ausprobieren
und "gegenseitiges" Kennenlernen.
Im Moment lasse ich mir die einzelnen Module synthetisieren und schaue
dann, wieviel Resourcen verbraucht wurden. Der Blick auf RTL sagt mir
dann, ob ich (Anfänger-gefühlsmäßig) zuviel Resourcen verbraucht habe
oder ob die Resourcen zur Aufgabenstellung passen.
Ob dann alle Module in den Chip passen, muss sich zeigen.
>> Wenn also das PWM-Modul aktiv ist, liest dieses (asynchron, weil andere>> Frequenz als der Pico) die Variable in ganzer Breite aus.> Im FPGA haben die Begriffe synchron und asynchron eine ganz bestimmte> Bedeutung. Synchron sind Baugruppen, die sich auf den selben Master-Takt> beziehen. Synchron sind auch Takte, die über einen DCM gewonnen werden.
Ja ok - wie müsste ich es dann richtig formulieren, wenn ich z.B. ein
Modul habe, das (jeweils vom gleichen Mastertakt abgeleitet) mit 50 MHz
läuft und ein anderes mit 200 MHz?
Ich weiß, dass mein Beispiel unglücklich gewählt war, da ein PWM eher zu
den gemütlichen Teilen zählt, aber mal angenommen, das Ändern der Daten
(über die 8-Bit Schnittstelle) würde mit 50 MHz vorgehen und das
Verwenden der Daten mit 200 MHz ...
... dann hätte ich doch 3 Zugriffe auf die Variable, die außerhalb des
Zugriffstaktes liegen (auch wenn sie zum gleichen Mastertakt gehören).
Anfänger schrieb:
> Das wird schwierig. Die serielle Schnittstelle transportiert doch nur> Bits, bzw. Bytes. Die weiß nichts über die logische Bedeutung der Daten.
Ja irgenwer muß die Daten aber zusammensetzen! Und diese Instanz "weiss"
auch um was für ein Modul es sich handelt und ob es Big oder Little
Endian ist.
> aber wie Plugin-Blackboxes für den Pico sein, d.h. er bezieht seine> Daten und schreibt die dahin, wo es für den entsprechenden Befehl sein
Ich würde mich trozdem nicht mit der Byteorder auf dieser Ebene
rumschlagen! Wer garantiert dir den das auf der Seriellen ein Zwei Byte
Wort mit dem LOW Byte zuerst kommt? Bei ETH ist es doch das gleiche da
sendet und empfängst du auch nur bytes, wie diese übers Kabel gehen
und das bestimmte Sachen (z.B. Addressen etc) ggf. ne feste Byteorder
haben ist später uninteresaant da die Nutzdaten von dir frei gewählt
werden können!
> Sorry, aber ich habe noch kein Gefühl dafür, wie stark der> Resourcenverbrauch einer bestimmten Idee ist. Kann sein, dass mein> "Konzept" garnicht in den Spartan3 reinpasst.
Reinpassen wirds schon, aber es wird schwer den Überblick zu behalten.
> Im Moment versuche ich jedenfalls so viel wie möglich in> "Hardware"-Module zu packen und nur das, was nimmer anders geht, vom> Softcore machen zu lassen.
Ich würde erstmal versuchen kleine Schritte zu gehen als gleich von
Anfang an das Ultimative super automatische hochkonfigurierbare System
schaffen zu wollen...
Pack erstmal nen PicoBlaze aufs Board samt Software der ne LED an/aus
machen kann. Dann kannst du noch ein PWM Modul dazubauen welches die LED
dimmt und von der UART den neuen PWM Wert empfangen kann.
Dann hast du erstmal ein Gefühl wie man etwas machen kann und wie das
Zusammenspiel funktioniert.
> dann, wieviel Resourcen verbraucht wurden. Der Blick auf RTL sagt mir> dann, ob ich (Anfänger-gefühlsmäßig) zuviel Resourcen verbraucht habe
Schau mal lieber auf die HDL/Macrostatistik der Synthese, da sagt er dir
welche Module und wieviele er erkannt hat und umsezt.
> Ja ok - wie müsste ich es dann richtig formulieren, wenn ich z.B. ein> Modul habe, das (jeweils vom gleichen Mastertakt abgeleitet) mit 50 MHz> läuft und ein anderes mit 200 MHz?
Es gibt nur einen Takt und das sind die 200Mhz. Die 50Mhz ergeben sich
z.B. dadurch das du immer nur alle 4 Takte etwas machst.
> (über die 8-Bit Schnittstelle) würde mit 50 MHz vorgehen und das> Verwenden der Daten mit 200 MHz ...
Ichj glaub irgenwo hab ich das schonmal beschrieben im Zusammenhang mit
PicoBlaze: Man verwendet einfach keine "geteilte" Speicherstelle,
sondern jedes Modul hat sein internes Register.
Der Picoblaze schreibt jezt in ein Hilfsregister(welches sich u.U.
mehrere Module teilen können) und gibt dann das Schreibsignal an das
entsprechende Modul. Dieses Modul übernimmt nun die Daten in einem
Rutsch in sein Internes Register und kann völlig ungestört
weiterarbeiten.
> Ja irgenwer muß die Daten aber zusammensetzen! Und diese Instanz "weiss"> auch um was für ein Modul es sich handelt und ob es Big oder Little> Endian ist.
Ersteres jein, letzteres Nein :)
Der Pico bekommt eine Befehlssequenz, bestehend aus n Bytes. Wie die zu
interpretieren sind, hängt vom Befehl ab.
> Bei ETH ist es doch das gleiche da> sendet und empfängst du auch nur bytes, wie diese übers Kabel gehen> und das bestimmte Sachen (z.B. Addressen etc) ggf. ne feste Byteorder> haben ist später uninteresaant da die Nutzdaten von dir frei gewählt> werden können!
Ok, das war ein Denkfehler von mir. Die Festlegung von bigendian bei ETH
gilt ja nur für die Framedaten, nicht aber für die Nutzdaten. Da hast Du
wiedermal recht :)
Also könnte ich mir die inv-Leitung doch schenken ;)
> Pack erstmal nen PicoBlaze aufs Board samt Software der ne LED an/aus> machen kann. Dann kannst du noch ein PWM Modul dazubauen welches die LED> dimmt und von der UART den neuen PWM Wert empfangen kann.> Dann hast du erstmal ein Gefühl wie man etwas machen kann und wie das> Zusammenspiel funktioniert.
Öhm, wenn ich das wollte, könnte ich mich doch mit
AVRMega-Experimentierboards beschäftigen. Ich will doch keinen FPGA mit
echtem HW-Multitasking verwenden, um dem dann wieder ne CPU zu
implantieren, die sequentiell arbeitet.
Sorry, aber das finde ich irgendwie pervers.
Abgesehen davon animiert mich der mögliche Lerneffekt auch nicht gerade
in die Richtung zu denken.
> Ich würde erstmal versuchen kleine Schritte zu gehen als gleich von> Anfang an das Ultimative super automatische hochkonfigurierbare System> schaffen zu wollen...
Einverstanden. Für mich sind es kleine Schritte und ich mag zwar ein
konfigurierbares System haben, denke aber nicht so extrem, wie Du es
gerade annimmst.
Ich komm halt aus der objektorientieren Ecke und denke über
Datenkapselung, Verantwortlichkeiten und Zuständigkeiten nach. Mag sein,
dass mein Denkprozess noch nicht genug an die neuen Anforderungen
angepasst ist - aber das nennt man doch Lernen, oder nicht?
So bemühe ich mich auch, die Module so autark wie möglich zu entwerfen.
Deshalb sind die Konfigurationsdaten in meinem Entwurf kein Bestandteil
der jeweiligen Module, die diese Daten verwenden - sondern ein
eigenständiger Bereich, der von den Modulen und dem Pico gleichermaßen
verwendet wird. Der Konfigurationsspeicher ist für die Module wie
externe Schiebeschalter für den FPGA - die Module lesen die Daten,
halten sie aber nicht.
Wenn der Pico den Modulen Schreibsignale geben soll, müsste er diese ja
kennen. Das soll ja garnicht der Fall sein. Deshalb sind die
Speicherbausteine so entworfen, dass sie asynchron gelesen werden können
und dass der Update in nur einem Takt erfolgt.
> Schau mal lieber auf die HDL/Macrostatistik der Synthese, da sagt er dir> welche Module und wieviele er erkannt hat und umsezt.
Yepp - das habe ich jetzt gemacht.
Als erstes habe ich aus tmp wieder ein Signal gemacht und den Code so
umgestellt, wie ich es für richtig hielt (Variante a).
Anschließend habe ich div. Varianten ausprobiert, mit dem Ergebnis, dass
keine andere Variante "besser" ist, bei gleicher Schnittstelle (äh, auch
ein Grund, warum ich die Adresse nicht innerhalb eines Speicherelementes
abfragen mag).
Die Statistik der einzelnen Varianten (RTL-Ansicht liegt auch bei):
1
Altera:
2
A B C D E
3
LE: 35 36 36 36 36
4
CF: 11 12 12 28 28
5
LR: 34 34 34 34 34
6
TR: 34 34 34 34 34
7
8
Xilinx:
9
A B C D E
10
SFF: 34 35 35 34 34
11
LUT: 24 32 32 26 26
12
Slices: 18 19 19 19 19
Witzig: zwischen Variante A und B habe ich nur einen völlig unnötigen
Schreibzugriff auf tmp auskommentiert :)
Interessant fand ich auch, dass bei gleichem Resourcenverbrauch
teilweise völlig andere RTL-Varianten rauskommen.
Anfänger schrieb:
> Öhm, wenn ich das wollte, könnte ich mich doch mit> AVRMega-Experimentierboards beschäftigen. Ich will doch keinen FPGA mit> echtem HW-Multitasking verwenden, um dem dann wieder ne CPU zu
Hm... meine FPGAS haben auf jedenfall kein Multitasking ;)
> implantieren, die sequentiell arbeitet.
Der PicoBlaze ist aber genau so eine CPU
> Sorry, aber das finde ich irgendwie pervers.> Abgesehen davon animiert mich der mögliche Lerneffekt auch nicht gerade> in die Richtung zu denken.
Der Lerneffekt wäre das du einzelne gekapselte Hardwaremodule entwirfst
und das in kleinen überschaubaren Schritten. (UART, IO, PWM) und diese
HW auch mal mit dem PB verbindest und nuzt!
Vorallem aber machst du etwas das auserhalb der Synthese auf dem Baord
funktioniert, Synthetisieren kann man viel ob es logisch das macht was
man möchte ist dann ein anderes Problem.
> Ich komm halt aus der objektorientieren Ecke und denke über> Datenkapselung, Verantwortlichkeiten und Zuständigkeiten nach.
Tjoar 90% meiner Zeit beschäftige ich mit Java und versuche solche
Konzepte auch in VHDL umzusetzen was sehr gut geht aber so wie du das
angehst hat das nix mit objektorientiert zu tun.
> verwendet wird. Der Konfigurationsspeicher ist für die Module wie> externe Schiebeschalter für den FPGA - die Module lesen die Daten,> halten sie aber nicht.
Das ist falsch, den jedes Schaltwerk hat einen Inneren Zustand (wie ein
Objekt) und speichert immer irgenwas, sosnt hättest du nur einen
kombinatorischen Prozess mit dem oft nicht auskommt.
> Wenn der Pico den Modulen Schreibsignale geben soll, müsste er diese ja> kennen. Das soll ja garnicht der Fall sein. Deshalb sind die
Ich denke du willst OO arbeiten? Der PicoBlaze hat ein Interface welches
sich aus je 8 bit Input+Output+Adresse sowie einen ReadEnable und einem
Write Enable besteht.
Und dieses Interface müssen deine HW Elemente implementieren.
Nun kannst du natürlich ein Modul bauen was dieses Interface
implementiert und zusätzlich zwei schreib/lese Zugriffe auf ein 16bit
Wort zusammenfaßt z.B. indem es das lezte Bit der Addresse verwendet wie
in meinem Beispiel. Andere Module könne jezt dein neues Interface,
welches 16 bit Output und 7bit Adresse hat wiederum in geeigenter Weise
nutzen...
Ich glaub dein Problem liegt irgenwie dabei das du denkst das wenn das
Modul den Wert zwischenspeichert irgenwas verloren geht... Tut es aber
nicht du verlagerst dieses "zwischenspeichern" nur in dein "memory
modul".
> Die Statistik der einzelnen Varianten (RTL-Ansicht liegt auch bei):
Das ist aber nicht das was ich meine die Sysnthese gibt dier sowas in
der Art aus:
Hi,
wenn du 'breite' Werte in einem Schuss mit dem Pico 'capturen' willst,
dann kannst du das machen, indem du eine kleine HW-Unit an den Pico
anschliesst, die z.B. bei einem Port-Write auf eine bestimmte Adresse
diese Werte in FFs laedt. Diese FFs kannst du nun byte-weise in den Pico
laden und damit was machen. Damit hast du gueltige Daten fuer einen
bestimmten Zeitpunkt. Wie soll es denn auch anders funktionieren? Also
wirst du etwas HW um den Pico herum spendieren muessen...
> die z.B. bei einem Port-Write auf eine bestimmte Adresse> diese Werte in FFs laedt. Diese FFs kannst du nun byte-weise in den Pico> laden und damit was machen. Damit hast du gueltige Daten fuer einen> bestimmten Zeitpunkt. Wie soll es denn auch anders funktionieren? Also> wirst du etwas HW um den Pico herum spendieren muessen...
Damit hast Du ziemlich genau beschrieben, was mein memory-Element macht,
bzw. machen soll.
Um bei meinem angefangenen Beispiel zu bleiben:
Natürlich hat das PWM-Modul innere Zustände, die werden aber
taktsynchron zum Takt des PWM-Moduls behandelt (beim Entwurf der Module
gehe ich erstmal davon aus, dass jedes Modul seinen eigenen Takt haben
kann! Ob die Modultakte später einen gemeinsamen Bezug zum Systemtakt
haben oder nicht, geht das jeweilige Modul nix an). Das PWM-Modul hat
z.B. 16-Bit breit einen (Eingangs-)Port für die Frequenz.
Es kann doch nicht angehen, dass sich das PWM-Modul darum kümmern muss,
wenn jemand von außen die 16-Bit Schnittstelle nicht bedienen kann und
ein Latch für den 8-Bit Zugriff in 2 Zyklen braucht.
Ich will jetzt auch keine Diskussion über objektorientierten Entwurf vom
Zaun brechen. Ich kann nur sagen, dass ich es für falsch halte, wenn ein
Element Leitungen abfragt, die garnicht zu seiner Schnittstelle gehören.
Die Adressleitungen gehören zu einem Multiplexer, der zwischen dem Pico
und den einzelnen Memory-Bausteinen liegt. Alle "meine" Memory-Bausteine
haben einen 8-Bit Datenport (unabhängig von ihrer tatsächlichen Größe)
und read- bzw. write-enable. Von Adressleitungen wissen die
Memorybausteine nichts. Alle Memorybausteine zusammen kann man mit einem
persistenten Datenobjekt (in Java-Sprache) vergleichen (auf die Weise
könnte ich Benutzereingaben so ablegen, dass sie nach einem Neustart
immer noch bekannt sind, bzw. wieder neu geladen werden können). Auch
solche Objekte gibt es in Java und die sind unabhängig von den
Businessobjekten.
Aber zurück zum FPGA und dem Pico: Nein, mir geht es nicht um die
Sichtweise des Pico. Der braucht keinen atomaren Zugriff auf die Daten.
Wohl aber das PWM-Modul. Egal ob die PWM-Frequenz jetzt innerhalb des
PWM-Moduls oder außerhalb liegt, sie muss für das PWM-Modul atomar sein.
Dies kann aber der Pico nicht gewährleisten - also muss noch eine
Hilfskonstruktion dazu kommen. Man könnte dies auch mit einem
Wrapperobjekt in der Java-Welt vergleichen.
Ach ja, Read- und Write-Strobe des Pico werden in Verbindung mit den
Adressen zu einem read- bzw. write-enable. Aber das sind Signale, die
z.B. das PWM-Modul in keinster Weise was angehen. Die Signale gehen bis
zum Speicherplatz und nicht weiter.
Das wäre ja genauso, als ob ich von allen VHDL-Modulen die
DDR-Schnittstelle fordern würde, nur weil ich zufällig auch DDR-Speicher
verwende ...
> Vorallem aber machst du etwas das auserhalb der Synthese auf dem Baord> funktioniert, Synthetisieren kann man viel ob es logisch das macht was> man möchte ist dann ein anderes Problem.
Naja, die Logik überprüfe ich mit Modelsim, dem Frequenzdiagram und den
entsprechenden Datenblättern (gut, soweit ich es gebacken bekomme).
Bis ich mal eine Firmware auf das Board laden kann, habe ich noch mehr
als nur eine Lektion zu lernen. Deshalb versuche ich einen Schritt nach
dem anderen zu gehen.
Einen Schritt kann ich aber erst dann als abgeschlossen betrachten, wenn
ich auch verstanden habe, was ich gemacht habe und warum es gut oder
schlecht war, was ich tat ...
Deshalb bin ich auch dankbar für die Denkanstöße und das Hinterfragen -
aber mein OO-Verständnis lasse ich mir nicht madig machen ;)
Falls es jemand interessiert:
Ich habe gerade mal das Speicherelement ohne die Invertierungs-Logik
synthetisiert und es wurde kein Logikelement eingespart. Das heißt für
mich, ich kann die Logik durchaus drin lassen und so die Speicherzellen
umschaltbar haben ;)
Anfänger schrieb:
> Es kann doch nicht angehen, dass sich das PWM-Modul darum kümmern muss,> wenn jemand von außen die 16-Bit Schnittstelle nicht bedienen kann und> ein Latch für den 8-Bit Zugriff in 2 Zyklen braucht.
Das PWM Modul übernimmt einfach 16bit wenn es den Schreib befehl
bekommt, das es sich ursprünlich um 2xbit handelte hat damit nix zu tun.
Ob dieses Latsch nun 'in' deinem PWM Modul liegt oder außen ist doch
egal!
> Ich will jetzt auch keine Diskussion über objektorientierten Entwurf vom> Zaun brechen. Ich kann nur sagen, dass ich es für falsch halte, wenn ein> Element Leitungen abfragt, die garnicht zu seiner Schnittstelle gehören.
Dein 'Problem' ist das du alles auf Zwang auf ein Shared Memmory Model
abbilden willst, das geht aber spätestens dann schief wenn ein Modul
sowohl lesen als auch schreiben will (inout geht nicht zwischen FPGA
internen Modulen...)
> und read- bzw. write-enable. Von Adressleitungen wissen die> Memorybausteine nichts. Alle Memorybausteine zusammen kann
Diese Logik Plazierst du nur unötigerweise kompliziert an anderer
Stelle, irgenwo mußt du zwangsläufig eine Zuordnung machen...
> PWM-Moduls oder außerhalb liegt, sie muss für das PWM-Modul atomar sein
s.o.
> Das wäre ja genauso, als ob ich von allen VHDL-Modulen die> DDR-Schnittstelle fordern würde, nur weil ich zufällig auch DDR-Speicher> verwende ...
Nein aber alle Module die in den "DDR Steckplatz" kommen sollen müssen
diese Interface bedienen können.
> Deshalb bin ich auch dankbar für die Denkanstöße und das Hinterfragen -> aber mein OO-Verständnis lasse ich mir nicht madig machen ;)
Na dann viel Erfolg noch ich klink mich hier erstmal aus da du ja eh
schon zu wissen scheinst was der beste Weg für dich ist...
... nur warum willst du Verbesserungsvorschläge wenn du von deinem
Konzept nicht abweichen möchtest?
>> Deshalb bin ich auch dankbar für die Denkanstöße und das Hinterfragen ->> aber mein OO-Verständnis lasse ich mir nicht madig machen ;)> Na dann viel Erfolg noch ich klink mich hier erstmal aus da du ja eh> schon zu wissen scheinst was der beste Weg für dich ist...
Beleidigt? - Fände ich sehr bedauerlich!
Da wo mir Deine Vorschläge eingeleuchtet haben, bzw. Du mich auf Fehler
hinweisen konntest, bin ich doch Deinen Vorschlägen gefolgt.
Ich denke, was die OO-Denke angeht, haben wir vielleicht eine andere
Granularität ...
Ob sich meine Vorstellung verwirklichen lässt - muss sich zeigen.
Vielleicht hast Du ja recht und ich lauf in eine Sackgasse. Bislang
konnte ich das jedenfalls nicht erkennen und die Argumente, den
VHDL-Modulen eine Pico-Schnittstelle zu verpassen, waren für mich
(noch?) nicht schlüssig.
> ... nur warum willst du Verbesserungsvorschläge wenn du von deinem> Konzept nicht abweichen möchtest?
Öhm, ich wollte Verbesserungsvorschläge, das Speicherelement knackiger
zu bekommen, aber nicht um dessen Verantwortung oder die Schnittstelle
zu ändern.
Ich hoffe Du wertest mein Festhalten an meinem Konzept jetzt nicht als
Infragestellen Deiner Kompetenz! Denn das ist es mit nichten!
Also nix für ungut - und noch einen schönen Rest vom Sonntag!
Nachtrag:
Dass das Weglassen der Invertierungslogik keine Logikelemente einspart
gilt nur für Altera. Bei Xilinx spare ich 15 LUTs ein, brauche aber
einen Slice mehr ...
... da ich ein Spartanboard habe, werde ich also die Invertierungslogik
weglassen ;)
> Bei Xilinx spare ich 15 LUTs ein, brauche aber einen Slice mehr ...
Du solltest dringendst mal nachschauen, wieviele LUTs ein Slice hat :-o
Dann hast du irgendwo noch ein paar Register eingebaut, anders liesse
sich das nicht erklären...
>> Bei Xilinx spare ich 15 LUTs ein, brauche aber einen Slice mehr ...> Du solltest dringendst mal nachschauen, wieviele LUTs ein Slice hat :-o
Ähm, ja. Ein Slice hat 2 LUTs, 2 Muxes und 2 FFs.
> Dann hast du irgendwo noch ein paar Register eingebaut, anders liesse> sich das nicht erklären...
Hm, jedenfalls nicht bewusst. Die Quellen sind ja in dem
Beitrag "Re: Verbesserungsvorschläge gesucht" und zwar jeweils die
A-Variante.
Wenn Du magst, kannst Du es ja selbst mal ausprobieren.
Nochmal ne Frage zum Takt:
Angenommen ich habe einen externen Systemtakt von 50 MHz. Den kann ich
ja per DCM intern hoch oder runter takten.
Was wenn ich jetzt z.B. einen seriellen Datenlieferant habe, der z.B.
mit 113,7219 MHz funkt. Dann müsste ich doch von diesem Takt einen
"Systemtakt" für das entsprechende Modul ableiten?!?
Wenn dann ein Datenaustausch mit Modulen stattfinden soll, die mit
DCM-Systemtakt laufen, ist der Austausch für eine Seite doch immer
asynchron - oder???
Anfänger schrieb:
> Beleidigt? - Fände ich sehr bedauerlich!
Nö, ich bin nur zu müde ewig lange texte zu tippen wenn du eh auf deinem
Weg beharrst, ist ja kein Problem man wird dadurch nicht dümmer ;)
Wenns doch noch Probleme gibt wirste dich schon melden denk ich :)
> einen seriellen Datenlieferant habe, der z.B. mit 113,7219 MHz funkt.> Dann müsste ich doch von diesem Takt einen "Systemtakt" für das> entsprechende Modul ableiten?!?
Das wäre elegant, wenn dieser Takt zum Eintakten in das FPGA verwendet
werden könnte. Anschliessend musst du ein Übergabesignal erzeugen, mit
dem die Daten über die Taktdomänengrenze hinweg geschafft werden können.
Sieh mal den Beitrag "Einsynchronsieren mit 2 FFs" an.
> Beleidigt? - Fände ich sehr bedauerlich!
Nö, ..., ist ja kein Problem man wird dadurch nicht dümmer ;)
Danke :)
> Das wäre elegant, wenn dieser Takt zum Eintakten in das FPGA verwendet> werden könnte. Anschliessend musst du ein Übergabesignal erzeugen, mit> dem die Daten über die Taktdomänengrenze hinweg geschafft werden können.> Sieh mal den Beitrag "Einsynchronsieren mit 2 FFs" an.
Danke für den Link. Habe die Beiträge gelesen, aber ...
Hm, ok - ich bin jetzt von seriellen Daten ala TWI oder SPI ausgegangen,
die immer einen Takt und eine Datenleitung haben. Dort kann man den
seriellen Takt ja zum einsynchronisieren der seriellen Daten nehmen.
Wenn ich die Daten dann im FPGA habe, sind das ja 2 Taktdomaine. Gibt es
irgendwelche Empfehlungen zu dem Frequenzverhältnis, sodass man keine
Daten verliert?
Also wenn die serielle Taktfrequenz 113,7219 MHz beträgt, könnte ich mir
vorstellen, dass man mit 110 Mhz oder 115 MHz Systemtakt Probleme mit
Datenverlust bekommt. Wie sieht es bei 150 MHz oder 200 Mhz aus?
Gibt es einen Weg, die "Schwebungen" ohne Verlust in den Griff zu
bekommen?
Gut, bei seriellen Daten könnte man die ja auch nach dem parallelisieren
über die Taktdomain-Grenze schieben. Dann müssten auch 100 MHz interner
Takt reichen.
> Gibt es einen Weg, die "Schwebungen" ohne Verlust in den Griff zu> bekommen?
Wenn du 2 unabhängige Taktquellen hast (vollkommen egal wie deren
Frequenzverhältnis zueinander ist), hast du das Problem mit dem
Taktdomänenübergang.
Üblicherweise gehst du dann so vor, dass der Übertragungstakt zum
Einlesen der Daten verwendet wird. Diese werden dann in einen
Zwischenspeicher abgelegt, und parallel dazu ein Handshake-Signal
einsynchronisiert (z.B. bei SPI der SlaveSelect). Wenn der über 2 FFs
eingetaktet wurde, dann sind auch die Daten im Zwischenspeicher stabil,
und können in der 2. Taktdomäne sicher verwendet werden.
BTW:
> Taktdomaine
Taktdomäne / Taktdomänen
Es ist cool, die englischen und die deutschen Fachbegriffe zu kennen und
bei Besprechungen alternierend ab und zu den einen oder den anderen
beiläufig einzustreuen ;-)
Hallo,
ich muss den Thread noch einmal aufwärmen :(
Habe das Modul jetzt auf einen Takt umgeschrieben (unter der Annahme,
dass der picoblaze mit internem FPGA-Takt läuft und die anderen Module
mit einem dazu in Bezug stehenden Takt).
Habe der Schnittstelle noch einen Status verpasst, damit ich den Zugriff
auf die Speicherstelle von außen synchronisieren kann.
Soweit so gut - die FFs sind, laut RTL alle getaktet.
Allerdings hat mich das Ergebnis bei Xilinx doch eher enttäuscht!
Dort wird nur 155 MHz für den Systemtakt zugelassen. Ich weiß jetzt
nicht, wie die Frequenzaussagen der beiden Konkurrenten zu werten sind -
bei Altera darf der gleiche Konstrukt mit ca. 250 MHz betrieben werden.
Gut, ich will "nur" 200 MHz, aber die hätte ich gerne auf dem Xilinx.
- Lassen sich irgendwelche Vergleiche umformulieren, damit der
kombinatorische Weg kürzer/schneller wird?
- lassen sich 16 Bit effizienter vergleichen?
- was könnte ich noch tun, um meine Idee effizienter umzusetzen?
Anfänger schrieb:
> - Lassen sich irgendwelche Vergleiche umformulieren, damit der> kombinatorische Weg kürzer/schneller wird?
Hab mir jezt den Code nicht angeschaut aber prinzipiel ist das alles
eine Frage von Fläsche und erlaubter Latenz. Zumden steht im PicoBlaze
UG auch drinne das man die Gechwindigkeit durch zusätzliche Register im
Addresspfad/Datenpfad beschleunigen kann da du aber das ja nicht so
machen willst fällt das wohl hier weg...
> - lassen sich 16 Bit effizienter vergleichen?
Kommt drauf an... größer? kleiner? gleich? signed/unsigned?
Mit einer Pipeline kann man zumindest für gewöhnlich die Zeit für den
Kombinatorischen Pfad auf kosten der Fläche reduzieren.
Ansosnten kann es auch helfen den optimization effort auf High zu
stellen udn ein Timing konstraint zu vergeben.
Guten Morgen Läubi,
schön von Dir zu lesen!
> ... Zumden steht im PicoBlaze> UG auch drinne das man die Gechwindigkeit durch zusätzliche Register im> Addresspfad/Datenpfad beschleunigen kann da du aber das ja nicht so> machen willst fällt das wohl hier weg...
Dachte mir doch, dass das nochmal auf den Tisch kommt.
Entweder ich habe seinerzeit Deine Tips nicht kapiert, oder Du schmeißt
jetzt 2 Sachen zusammen, die nicht zusammen gehören.
Ich hatte Deine Tipps so verstanden, dass ich meine Speicherzelle
funktional umstellen sollte - DAS wollte ich nicht.
Die zusätzlichen Register rund um den Pico habe ich mir schon
vorgenommen zu verwenden. Allerdings bin ich noch nicht beim pico,
sondern noch an der parallelen Schnittstelle.
> Mit einer Pipeline kann man zumindest für gewöhnlich die Zeit für den> Kombinatorischen Pfad auf kosten der Fläche reduzieren.
Könntest Du mir dafür mal bitte ein Beispiel geben? Mit dem Begriff
Pipeline im aktuellen Kontext kann ich nix anfangen.
> Ansosnten kann es auch helfen den optimization effort auf High zu> stellen udn ein Timing konstraint zu vergeben.
Das habe ich gerade versucht, jetzt ist das Ergebnis noch schlechter :(
Was ich auch nicht verstehe:
Xilinx und Altera kommen auf ungefär die gleiche Signal-Laufzeit (7,xx
ns) und doch meint Altera, dass clk einen Takt von knapp 250 MHz haben
dürfe, wärend es be Xilinx nur 150 MHz sind.
Ist Altera "dümmer" in der Berechnung der Abhängigkeiten, oder haben die
eine Optimierungsstufe, die Xilinx nicht kennt?
Ach ja, die RTL-Ansichten von beiden sind auch im Archiv dabei.
Achso du nuzt das Modul einzeln? Dann liegt das u.A. daran das alle
input/outputs auf I/O Pads gehen die nochmal extra delays drin haben...
Ansosnten ist die Synthese eher eine Schätzung auch kann das Ergebnis
von gewählten SPeedgrade abhängen.
> Achso du nuzt das Modul einzeln?
Naja - ich schau mir erstmal jedes Modul einzeln an. Sonst seh ich den
Wald vor lauter Bäumen nimmer. Erst wenn es plausibel bzw.
zufriedenstellend aussieht, gehe ich zur nächsten Baustelle.
Machst Du etwa alles auf einen Rutsch?
Beim CPLD mag das ja noch angehen, aber nen ganzen FPGA im Kopf zu haben
- da brauch ich noch ein paar graue Zellen :)
> Dann liegt das u.A. daran das alle input/outputs auf I/O Pads gehen die> nochmal extra delays drin haben...> Ansosnten ist die Synthese eher eine Schätzung auch kann das Ergebnis> von gewählten SPeedgrade abhängen.
Ne ne - sorry, aber das ist mir zu sehr im Trüben gefischt!
Alle Module haben die gleiche Chance, sprich den gleichen Chip, immer
gleichen Speedgrade - und für ein Modul wird ein max. Systemtakt von 280
MHz ermittelt, für das andere Modul ein Systemtakt von 150 MHz
... das lässt doch (ausschließlich?!?) direkte Rückschlüsse auf die Güte
des Moduls zu. Denkst Du nicht auch?
Ich weiß, dass die Synthese so keinen Sinn macht, aber ich denke, die
Timing-Berechnungen werden auch Bestand haben, wenn das Modul im
komplexeren Kontext eingebunden ist.
Anfänger schrieb:
> Machst Du etwa alles auf einen Rutsch?
Nö, ich erstell einzelne Module, schau ob sie sich so synthetisieren
lassen wie sie sollen, und dann wird das alles in nem Übergeordnetem
Modul verbunden.
Wenn man aussagen bezüglich der Geschwindigkeit haben willl wird das
ganze mit einem Register an Aus/Eingängen versehen die bei CLK die Daten
"nach innen" geben.
> Beim CPLD mag das ja noch angehen, aber nen ganzen FPGA im Kopf
Ich hab auch nicht alles im Kopf, sondern nur die Schnittstellen der
Module, mehr muß ich auf der Ebene des zusammenschaltens nicht wissen.
> ... das lässt doch (ausschließlich?!?) direkte Rückschlüsse auf die Güte> des Moduls zu. Denkst Du nicht auch?
Nö,
1) gibt es dafür keine Standard, deshlab Altera mit Xilinx zu
vergleichen ist sicher unzuverlässiger als der Wetterbericht.
2) Ohne Timing Konstraints läuft die Optimierung nach dem Prinzip: First
Fit First Choice. Sobald das Design in den (bei dir völlig leeren Chip)
paßt wird abgebrochen.
> Rückschlüsse auf die Güte
Welche Güte? Geschwindigkeit? Platzverbrauch? Latenz?
Wiederverwenbarkeit?
> Ich weiß, dass die Synthese so keinen Sinn macht, aber ich denke, die> Timing-Berechnungen werden auch Bestand haben, wenn das Modul im> komplexeren Kontext eingebunden ist.
Denken ist leider in der Hinsicht oft Glückssache wie ich schon mehrmals
fesstellen mußte...
Meist werden Designs durch hinzufügen von weiterer Logik schneller, und
manchmal langsamer das kommt auf den Kontext an und wenn die Synthese
200 Mhz verspricht der Fiter/Placer aber "umwege" beim Routen machen muß
weil halt der Chip voll ist hilfts auch nicht.
Ich kann eigentlich nur wiederholen was ich schonmal gesagt hab: Bau das
Teil einfachl in den FPGA oder wenigstens bis zur Programmingfile, sich
hier tage/wochenlang dran aufzuhängen bringt überhauptnix, optimieren
kann man später noch wenn man sieht das das Modul wirklich kritisch ist.
Selbst wenns am Anfang nur mit 1Mhz läuft hat man dan wenigstens etwas
wo man drauf ansetzen kann und nicht was theoretisch eigentlich laufen
sollte und würde wenn es könnte und man den hätte.