Hallo,
ich habe zwei Probleme die mir gerade ein wenig Kummer bereiten. Problem
Nummer eins ist der Select eines MUX. Ich habe eine Datenfolge von
010101010101 usw.
Immer bei einer Steigenden Flanke möchte ich den Select auf 1 setzen.
Bei einer fallenden Flanke auf 0.
Mit diesem Select schalte ich dann einen MUX. Meine Idee klappt leider
nicht. der CLK hat 100MHz und das Data Signale 100khz. Geht meine Idee
nicht weil „sel" dann in einem Takt auf 1 steht und beim Übergang nicht
gewechselt werden kann?
1
process(clk,Data)
2
begin
3
ifrising_edge(data)then
4
sel<='1';
5
iffalling_edge(data)then
6
sel<='0';
7
endif;
8
endif;
9
endprocess;
Anschließend würde ich dann mit diesem sel auf den Mux gehen. Das war
die Idee mit einem 1:2 MUX.
Zweites Problem wo ich noch keine Lösung habe. Nach 14 Data Signalen
will ich ein Sync Bit einschieben.
Meine Idee war einen Zähler aufzubauen welcher mir die „Data" Zählt.
Anschließend den „sel" (müsste dann ein vector sein also signal sel :
unsigned(1 downto 0) := "00“) auf Wert 10 schreibt.
Damit könnte ich dann einen 1:3 MUX schalten.
Also im kurzen Überblick:
Steigende Flanke sel = „00“
Fallende Flanke sel = „01“
15tes Bit = „10“
Ist das alles so möglich wie ich mir das vorstelle?
Viele Grüße
Fabi
> Ich habe eine Datenfolge von 010101010101 usw.> Immer bei einer Steigenden Flanke möchte ich den Select auf 1 setzen.> Bei einer fallenden Flanke auf 0.
Das ergibt doch wieder das Originalsignal.
foobar schrieb:>> Ich habe eine Datenfolge von 010101010101 usw.>> Immer bei einer Steigenden Flanke möchte ich den Select auf 1 setzen.>> Bei einer fallenden Flanke auf 0.>> Das ergibt doch wieder das Originalsignal.
Nein eigentlich nicht. Nur wenn alle an den Ports anliegenden Signale
die gleiche Frequenz haben. Das ist bei mir aber nicht der Fall,
Fabian Z. schrieb:> Geht meine Idee nicht weil „sel" dann in einem Takt auf 1 steht und beim> Übergang nicht gewechselt werden kann?
Die geht nicht, weil es kein solches Bauteil gibt, das zwei Takteingänge
hat, die auf 1 und das selbe Signal wirken.
> Immer bei einer Steigenden Flanke möchte ich den Select auf 1 setzen.> Bei einer fallenden Flanke auf 0.
Du hast die völlig falsche Denkweise. In einem FPGA gibt es im
einfachsten Idealfall nur 1 Takt. Und es wird nur auf 1 der Flanken
dieses Taktes reagiert. Das nennt sich synchrones Design. Und nur das
funktioniert auch tatsächlich in der Realität.
Such mal nach "Postulate" hier im FPGA-Forum. Da waren schon andere auf
dem selben Holzweg... ;-)
> Ist das alles so möglich wie ich mir das vorstelle?
Warum beschreibst du nicht einfach mal, was du hast und was damit
angestellt werden soll? Denn so, wie du es machen willst lässt sich
das mit der aktuellen Technik nicht vollumfänglich realisieren. Aber ich
kann mir gut vorstellen, dass die Aufgabe mit "üblicher" Strategie
leicht lösbar ist...
> Mit diesem Select schalte ich dann einen MUX. Meine Idee klappt leider> nicht. der CLK hat 100MHz und das Data Signale 100khz.
Also 1000 mal langsamer. Dann takte dieses schnarchlangsame Datensignal
ein (musst du soweiso machen...) und setze hinterher die
Allerweltsflankenerkennung drauf.
Sieh dir das da mal an:
http://www.lothar-miller.de/s9y/categories/18-Flankenerkennunghttp://www.lothar-miller.de/s9y/archives/41-Einsynchronisieren-von-asynchronen-Signalen.html
Und am besten den Rest auch. Dann siehst du, wie dein Design sicher
laufen wird....
Fabian Z. schrieb:> Immer bei einer Steigenden Flanke möchte ich den Select auf 1 setzen.> Bei einer fallenden Flanke auf 0.
Villt hätte ich es so ausdrücken müssen das der Select abhängig von low
und high Pegeln geschalten werden soll. Sowie auch noch mitteilen das
die Datenfolge (0011010101111) unterschiedliche Werte annehmen kann.
Ziel ist es ähnlich wie bei einer Modulation zwischen die Datenwerte
andere von Data Signale einzulegen. Also bei einem high von Data gebe
ich eine schnellere Bitfolge aus, bei einem Data Low eine langsamere.
Aber immer nur solange wie mein Data ein high oder low hat. Eben es
ähnelt ziemlich einer Modulation.
Somit muss ich die Flanken erkennen. Das mache ich mit
rising_edge und falling_edge und wollte dies auf ein Schaltsignal sel
für den MUX legen. Des Weiteren wie oben erwähnt muss ich noch eine Bit
einschieben. als
> Nach 14 Data Signalen will ich ein Sync Bit einschieben.>> Meine Idee war einen Zähler aufzubauen welcher mir die „Data" Zählt.> Anschließend den „sel" (müsste dann ein vector sein also signal sel :> unsigned(1 downto 0) := "00“) auf Wert 10 schreibt.>> Damit könnte ich dann einen 1:3 MUX schalten.>> Also im kurzen Überblick:>> Steigende Flanke sel = „00“> Fallende Flanke sel = „01“> 15tes Bit = „10“>> Ist das alles so möglich wie ich mir das vorstelle?>> Viele Grüße> Fabi
Ich hoffe ich konnte es ein bisschen besser erläutern.
Fabian Z. schrieb:> Das mache ich mit rising_edge und falling_edge
Geht aber bestenfalls in der Simulation...
Wie gesagt: ein synchrones FPGA-Design, das hinterher tatsächlich
funktioniert, hat einen "ausreichend schnellen" Takt, der so schnell
ist, dass er es erlaubt, alle Eingangssignale oft genug abzutasten. Und
wenn du 100MHz FPGA-Takt hast und 100kHz Signalfrequenz, dann schaffst
du da 1000fache Überabtastung. Also: Flanken werden am Einfachsten nach
Einsynchronisieren des Signals mit einem Schieberegister ausgewertet.
> Ich hoffe ich konnte es ein bisschen besser erläutern.
Ich kann die Thematik noch überhaupt nicht einschätzen (und ich bin
eigentlich gut im Raten...), denn mir fehlen da ein paar Zahlen zur
Prosa: welche Frequenzen/Pulsdauern sind da unterwegs? Was ist
"schnell", was ist "langsam"? Was wird erzeugt, was ausgewertet?
Fabian Z. schrieb:> Problem Nummer eins ist der Select eines MUX. Ich habe eine Datenfolge von> 010101010101 usw.> Immer bei einer Steigenden Flanke möchte ich den Select auf 1 setzen.> Bei einer fallenden Flanke auf 0.
Das geht ganz einfach
sel <= data;
Als concurrent Statement ohne Process o.ä.
Tom
Lothar M. schrieb:> Und es wird nur auf 1 der Flanken dieses Taktes reagiert. Das> nennt sich synchrones Design. Und nur das funktioniert auch> tatsächlich in der Realität.
Dann verraten wir Fabian lieber nicht, dass es auch z.B. Xilinx
Coolrunner II mit beidseitiger Flankenerkennung gibt. Schließlich hat er
überhaupt nicht erwähnt, unbedingt ein FPGA einsetzen zu wollen/müssen.
Diese Behauptung wurde erst von Lothar aufgestellt.
Trotzdem ist es höchstwahrscheinlich eine sehr, sehr schlechte Idee, das
erste Design mit solch einer Sondertechnik durchzuführen, da auch ich
ganz schwer davon ausgehe, dass Fabian einfach nicht in der Lage ist,
sein Problem auch nur ansatzweise zu beschreiben.
Tom schrieb:> Und geht es nicht so?
Ich bezweifle nach wie vor, dass das nötig ist. Denn die einzigen
belastbaren Zahlen, die hier auftauchen sin 100kHz und 100MHz. Und dann
ist die richtige Strategie, eben nicht solche Tricksereien und
"Speziallösungen" anzuwenden, auch wenn sie in der HDL-Beschreibung
"elegant und kompakt" aussehen.
Andreas S. schrieb:> Schließlich hat er überhaupt nicht erwähnt, unbedingt ein FPGA einsetzen> zu wollen/müssen. Diese Behauptung wurde erst von Lothar aufgestellt.
Ich würde basierend auf dem Beitrag "VHDL erste Schritte beim Zähler"
sogar eine Wette eingehen, dass es so ist. Wer hält dagegen?
Lothar M. schrieb:> Die geht nicht, weil es kein solches Bauteil gibt, das zwei Takteingänge> hat, die auf 1 und das selbe Signal wirken.
Sagen wir mal: In FPGAs gibt es das so! nicht, abgesehen von den
ODDR-FFs im z.B. Spartan, die in der Tat beide Takteingänge haben. -
Scheinbar zumindest, denn real sind dort nur Takt und invertierter Takt
erlaubt.
Man kann solche Systeme aber durchaus bauen und dies sogar auch in FPGAs
(im "analog mode" wie Ich es gerne nenne), aber a) macht es für die
gewünschte Applikation meistens wenig Sinn und b) macht es in FPGAs als
zielführende Designmethode keinen Sinn.
Anfänger sollten sich vor Augen führen, dass VHDL ewig alt ist und
ursprünglich mal zur Verifikation von ASICs und später dann zu deren
Synthese etnwickelt wurde.
Das bedeutet auf Deutsch:
1) VHDL enthält Konstrukte, Methoden und Sprachelemente, die einzig für
die Simulation taugen.
2) VHDL enthält weitere der o.g. Punkte, die zwar zur Synthese verwendet
werden können, aber nicht unbedingt dafür praktisch oder sinnvoll sind.
Function Calls, waits, explizite Timing-Angaben sind z.B. solche.
3) VHDL enthält wiederum noch weitere der o.g. Punkte, welche für
Synthesen tauglich sind und auch durchaus praktisch verwendbar sind,
allerdings eben nur für ASICs, weil nur der ASIC-Compiler was damit
anfangen kann, da nur er diese Freiheitsgrade hat, das zu bauen, was da
steht. Die doppelten Taktflanken, doppelte Resetleitungen, Buffer im
Design, Signale mit invertiertem Signal-Pegel (also "lo active") sind
solche Dinge. Diese beinhalten Physikvorgaben, die sich im FPGA nicht-
oder nicht so umsetzen lassen, bzw wenn es der Compiler probiert, zu
logischen - aber vom Nutzer ungewollten Ergebnissen führen. D.h. der
Compiler baut unter Berücksichtigung der Vorgaben im Sinne eines
FPGA-Designs zwar objektiv richtige Hardware, aber der Anwender wollte
was komplett anderes.
4) VHDL enthält wiederum nochmals andere der o.g. Punkte, die zwar auch
für FPGA-Synthesen taugen und die auch zu nutzbarer und sinnvoller
Hardware führen, die sich aber nicht für das Designprinzip der
Logiksynthese eignen, weil es keine mathematische Schaltungslogik ist
oder weil sie nicht taktabhängig ist. Asynchrone Latches, gegatete
Takte, kombinatorische Schleifen, asynchrone Rückkopplungen mit
Verzeigung, Anti-Glitch-Redundanzen und asynchrone Delays sind solche
Dinge. Das sind allesamt Sachen, die sich nicht mit der synchronen
Synthese behandeln lassen und zu Schaltungen führen, die sich nicht im
timing optimieren- oft nicht berechnen und damit nicht automatisch in
ein synchrones Design eingliedern lassen.
Von all diesen Punkten sollte der Anfänger die Finger lassen.
Jürgen S. schrieb:> Von all diesen Punkten sollte der Anfänger die Finger lassen.
Naja, ein Wort zu
> 1) VHDL enthält ... die einzig für die Simulation taugen.
Der Anfänger sollte natürlich durchaus sein Design vor der
Implementierung simulieren. Und dort darf er auch Sachen machen, die
(heute noch) kein Synthesizer in Hardware gießen kann wie z.B. wait for
1 ms;
;-)
Aber sonst eine insgesamt sehr treffliche Zusammenfassung der "NoGo"s
Lothar M. schrieb:> Und dort darf er auch Sachen machen, die> (heute noch) kein Synthesizer in Hardware gießen kann wie z.B. wait for> 1 ms;
Es wäre sicherlich ein Leichtes, solch eine Funktionalität zu
implementieren. Für synthesefähigen Code sollte man aber unbedingt
verlangen, dass der zugrundeliegende Takt bzw. eine Art
Taktdomänenbeschreibung angegeben werden muss. Oder so etwas wie "wait
for rising_edges(clk, 123);".
Aber wollen wir das wirklich?
Andreas S. schrieb:> Aber wollen wir das wirklich?
Wo Ich das zufällig lese: Meiner Meinung nur ein weiterer Fallstrick für
den Anfänger. Weniger Sprachelemente wären sicher einfacher zu
handhaben. VHDL sit sehr offen und lose, das schafft Platz für
Missverständnisse. Siee Variablen.
Da wir aber schon dabei sind, exotische Taktabfragen zu diskutieren,
mein Beispiel:
Wie würde man dies umsetzen:
if rising_edge (SystemTakt);
if rising_edge (SystemTakt);
-- Behandlung des Zusammenfallens der Flanken
else
-- Behandlung eines leeren Taktes ohne Aktion
end if;
else
if rising_edge (SystemTakt);
-- Behandlung eines Datentaktwechsels ohne Takt
else
-- nichts von beiden
end if;
end if;
Simulationsmässig geht es.
Markus W. schrieb:> Simulationsmässig geht es.
Das ist der Trick an VHDL: in der Simualtion kannst du alles machen.
Umsetzbar in reale Hardware sind dagegen bestenfalls 10% (oder eher nur
5%) der VHDL-Sprachkonstrukte. Welche in Hardware abgebildet werden
können, das steht im Userguide zum Synthesizer.
Lothar M. schrieb:> Welche in Hardware abgebildet werden> können, das steht im Userguide zum Synthesizer.
Und das was der bzw. die Synthesizer aller Hersteller können sollten,
steht in
"ANSI/IEEE 1076.6-2004 - IEEE Standard for VHDL Register Transfer Level
(RTL) Synthesis"
https://standards.ieee.org/findstds/standard/1076.6-2004.html
Duke
Duke Scarring schrieb:> Und das was der bzw. die Synthesizer aller Hersteller können sollten
Du hast auch keine Angst vor Enttäuschungen... ;-)
Denn wenn ein Synthesizer etwas nicht kann, was er sollte, ist es
enttäuschend.
Und wenn er etwas Tolles kann, was da nicht drinsteht, dann sollte ich
es zwecks Portabilität nicht verwenden. Eigentlich auch schade.
Markus W. schrieb:> -- Behandlung des Zusammenfallens der Flanken
So etwas ist ganz, ganz schlecht. Man muss sich entscheiden, welches der
Signale als Takt und welches als Datensignal herangezogen werden soll.
Und mit dem Takt tastet man das Datensignal ab. Oder man verwendet noch
einen weiteren, vorzugsweise wesentlich höheren, FPGA-internen Takt, mit
dem man beide externen Signale einsynchronisiert. Es gibt Unmengen an
Abhandlungen, die dieses Thema und die möglichen Stabilitätsprobleme
behandeln.
Wenn tatsächlich Zustandsänderungen von Daten und Takt gleichzeitig
auftreten können, ist das entweder ein Zeichen für ein sehr schlechtes
Design oder dafür, dass man die falsche Flanke verwendet. Nicht umsonst
gibt es z.B. bei SPI vier verschiedenen Betriebsarten mit
unterschiedlicher Lage und Polarität des Taktes.
Falls man z.B. einen externen klassischen Bus mit /CS, /RD, /WR,
Adresse, Daten hat und ein FPGA daran anschließen will, tut man in
vielen Fällen gut daran, einen hohen internen Takt zu verwenden und
damit die Steuersignale einzutakten. Die Datensignale dürfen hingegen
nicht direkt abgetastet werden, sondern nur mit den schon
einsynchronisierten Steuersignalen als interne (Clock-)Enables. Dadurch
beseitigt man Mehrdeutigkeiten, wenn mehrere Flanken in geringem
zeitlichen Abstand auftreten können.
Ganz wichtig: nur ECHTE Taktsignale dürfen mit rising_edge() oder
falling_edge() abgefragt werden, niemals Datensignale. Für diese muss
man einen getakten Prozess verwenden und den Zustandswechsel manuell
abfragen:
1
entityxis
2
port(
3
clk:instd_logic;
4
data:instd_logic
5
);
6
endx;
7
8
architecturebhvofxis
9
signaldata_old:std_logic:='0';
10
11
begin
12
processbegin
13
waituntilrising_edge(clk);
14
data_old<=data;
15
if(data='1')and(data_old='0')then
16
-- Mach irgendwas bei einer steigenden Flanke von data
Markus F. schrieb:> "Withdrawn Standard".> Durchlesen lohnt sich also nicht unbedingt.
Ja, aber ein Update scheint es nicht zu geben...
Oder ich hab es nicht gefunden.
Lothar M. schrieb:> Denn wenn ein Synthesizer etwas nicht kann, was er sollte, ist es> enttäuschend.> Und wenn er etwas Tolles kann, was da nicht drinsteht, dann sollte ich> es zwecks Portabilität nicht verwenden
Ja, so ist das mit dem kleinsten gemeinsamen Nenner.
Zum Glück habe ich keine Projekte die herstellerübergreifend laufen
müssen.
Da kann ich jedes Mal das nehmen, was der Chip und die Synthesesoftware
an Spezialitäten bieten.
Duke
Andreas S. schrieb:> Ganz wichtig: nur ECHTE Taktsignale dürfen mit rising_edge() oder> falling_edge() abgefragt werden
Nicht nur "dürfen" sondern "müssen". Fragt man Takte in irgendeiner
Weise anders ab, entsteht eine andere Anforderung, als eine logische
Flankenabfrage und dann landen wir wieder bei den gegateten Takten.
> niemals Datensignale. Für diese muss> man einen getakten Prozess verwenden
Für Simulationen kann man durchaus auch Datensignale, also externe Takte
z.B., so abfragen. Das ist sogar zweckmäßig, um die Ausführungszeiten
und Aufwände der Simu klein zu halten und einfache Formulierungen zu
erhalten. Da gibt es eine Reihe Strategien bei der Optimierung von
Simu-Modellen.
Aber das gilt eben nur bei Simulationen!