Forum: FPGA, VHDL & Co. Seriell-Parallel-Wandlung mit VHDL


von Chris2k (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich komme bei einem Problem nicht weiter.

Situation: Ich habe einen ADC, der mir digitalisierte Daten seriell 
ausgibt. Dazu gibt er Taktsignal (knapp 40 MHz), Wortleitung und 
Datensignal aus. Im Anhang dazu das Bild. Ich möchte mit einem FPGA 
(derzeit MachXO2 Breakout Board von Lattice, samt Lattice Diamond) die 
Daten zunächst seriell->parallel wandeln, eh ich damit weiter rumspiele. 
Die Daten des ADC werden mit DDR übertragen, d.h. ich muss die Daten mit 
steigender und fallender clk-Flanke übernehmen. Ein Datenwort ist 7 bit 
breit und wird mit 8 MHz ausgegeben.

Die gute Nachricht: Die Synthese funktioniert einwandfrei, ohne Fehler. 
Auch die Simulation auf RTL-Ebene funktioniert so, wie ich mir das 
vorstelle (bis auf den ersten Wert (Testbench: 0x01), der geht verloren, 
aber egal).
Die schlechte Nachricht: Die Gate-Level-Simulation will nicht, der 
parallele Ausgang wird mit "UU" (unbekannt) gekennzeichnet.

Ich hatte einige Probleme damit, die fertig parallelisierten Daten 
(zeitrichtig) auszugeben, also das genau dann der Ausgabeport 
aktualisiert wird, wenn die Daten zur Verfügung stehen. Und dann soll 
auch noch ein Pin "ready" anzeigen, dass die Daten zur Abholung 
bereitstehen. Etwas friemelig für mich als Anfänger...

Hat einer eine Idee, was in meinem Code nicht richtig ist?

Im Anhang mein VHDL-Code mit einfacher Testbench, Skop-Bild (zeigt 
Ausgangssignale vom ADC), RTL-Simulationsergebnis und 
Gate-Level-Simmulationsergebnis.

Danke.
Chris2k

von dasdgw (Gast)


Lesenswert?

Hm,

steigende und fallende Flanke in einem Process und keine Warnings oder 
Error vom Synthese-Tool?
Also bei ISE und Quartus geht das glaub ich nicht.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Chris2k schrieb:
> Auch die Simulation auf RTL-Ebene funktioniert
Meinst du die Verhaltenssimulation (ohne Verzögerungszeiten, und ohne 
Synthese)?

> Die schlechte Nachricht: Die Gate-Level-Simulation will nicht
Welcher Gate-Level? Warum machst du das überhaupt? Ich habe irgendwann 
vor zig Jahren meine letzte Place&Route Simulation mit Gatterlaufzeiten 
gemacht. Seither nehme ich nur noch geeignete Constraints und die 
statische Timinganalyse.

> Die Gate-Level-Simulation will nicht, der
> parallele Ausgang wird mit "UU" (unbekannt) gekennzeichnet.
Das bringt evtl. Licht ins Dunkel:
'U' heißt "uninitialized", nicht "unknown"...

Wie schon gesagt:
1
    if reset='1' then -- asynchronous reset
2
       :
3
    elsif falling_edge(clk) then  -- clock uneven bits into shift register
4
       :
5
    elsif rising_edge(clk) then   -- clock even bits into shift register
6
       :
7
    end if;
Bist du sicher, dass der Synthesizer deine Beschreibung korrekt in 
DDR-IO-Zellen packt?

> Die Synthese funktioniert einwandfrei, ohne Fehler.
Hmmmm...
> Ich hatte einige Probleme damit, die fertig parallelisierten Daten
> (zeitrichtig) auszugeben, also das genau dann der Ausgabeport
> aktualisiert wird, wenn die Daten zur Verfügung stehen.
Du hattest Probleme? Das heißt, das Design läuft in der Realität? Ich 
würde das sehr beeindruckend finden...

Hast du dir mal den RTL-Plan nach der Synthese angeschaut? Wird da evtl. 
einfach die Hälfte (oder noch mehr) wegoptimiert? Wie groß ist der 
Ressourcenverbrauch (insbesondere die Anzahl der Flipflops)? Deckt der 
sich mit deinen Erwartungen?

Ich würde meinen, man muss die DDR-Komponenten per Handschlag 
instatiieren. Sowas legt mir z.B. der Abschnitt "Implementing High-Speed 
Interfaces with MachXO2 Devices" aus dem "MachXO2 Family Handbook" nahe.

dasdgw schrieb:
> steigende und fallende Flanke in einem Process
> Also bei ISE und Quartus geht das glaub ich nicht.
Bei ISE geht es für die Coolrunner II CPLDs, weil die tatsächlich 
DDR-FFs im Inneren haben. Das war schon öfter mal da:
http://www.mikrocontroller.net/search?query=ddr+coolrunner&sort_by_date=1

von Thomas (Gast)


Lesenswert?

Lothar Miller schrieb:
> 'U' heißt "uninitialized", nicht "unknown"...
wenn ein FF mal gesetzt war, und dann von einer U-Quelle gespeist wird, 
also beim Takt ein Sig aufgeschalten wird, dass noch U ist, ist der 
FF-Ausgang auch wieder U. Das würde ich aber nicht als "nicht 
initialisiert" werten, denn mit "initial" = "erstmalig" hat das nichts 
zu tun.

Der Wert ist einfach undefiniert, weil er in der Praxis durchaus einen 
Wert hat nd die Schaltung zB. funktionieren kann.

Ist aber ein wenige Philophie

von Johann (Gast)


Lesenswert?

Beim Xilixn FPGA gibt es spezielle IDDR Register. Dort legt man das DDR 
Datensignal und den Takt an. Das Element hat 2 Bits als Ausgang. Mit 
jeder steiegenden CLK Flanke liegen dann die neuen Bits am Ausgang an.

Jedoch weiß ich nicht ob Dein FPGA auch solche Register besitzt.

Du kannst aber auch zwei seperate FlipFlops benutzen. Der erste reagiert 
auf die steigende Flanke und der 2. auf die fallende Flanke.

Da Du die Daten seriell zu parallel wandeln möchtest, nimmst Du am 
besten 2 Schieberegister. Das 1 Schieberegister arbeitet mit der 
steigenden Flanke und das 2. mit der fallenden Flanke. Wenn alle Daten 
in beiden Schieberegistern vorhanden sind kopierst Du die Daten aus 
beiden Schieberegister ein einen neuen Speicher der doppelt so groß ist. 
Die Daten werden dann ich Reißverschlußverfahren zusammengesetzt.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Thomas schrieb:
> Das würde ich aber nicht als "nicht initialisiert" werten,
> denn mit "initial" = "erstmalig" hat das nichts zu tun.
Naja, der Typ std_logic ist einfach so definiert :
1
a signal or variable of this type can take on the following values:
2
    'U': uninitialized. This signal hasn't been set yet.
3
    'X': unknown. Impossible to determine this value/result.
4
    '0': logic 0
5
    '1': logic 1
6
    'Z': High Impedance
7
    'W': Weak signal, can't tell if it should be 0 or 1.
8
    'L': Weak signal that should probably go to 0
9
    'H': Weak signal that should probably go to 1
10
    '-': Don't care.
(Quelle: 
http://www.cs.sfu.ca/~ggbaker/reference/std_logic/1164/std_logic.html)

> Ist aber ein wenige Philophie
Ja, da kann man lang diskutieren, wann denn jetzt die erstmalige 
(=initiale) Zuweisung eines Werts an ein Signal erfolgt...
Und insbesondere, ob eine Zuweisung eines 'U' an ein Signal als 
erstmalige Zuweisung gelten darf. Und dann danach alle folgenden 
Zuweisungen nur noch "undefined" sind...

> wenn ein FF mal gesetzt war, und dann von einer U-Quelle gespeist wird,
> also beim Takt ein Sig aufgeschalten wird, dass noch U ist, ist der
> FF-Ausgang auch wieder U.
Richtig, die Auflösungstabelle zeigt klar: wenn mal ein Signal nicht 
mehr 'U' war, kann es nicht mehr so einfach 'U' werden. Bestenfalls noch 
durch eine (direkte oder indirekte) Zuweisung eines 'U'. Du brauchst 
also für ein 'U unbedingt ein anderes Signal, das noch nicht 
initialisiert wurde. Ansonsten ergibt sich bei Konflikten immer ein 
'X'...
1
VHDL std_logic resolution function table:
2
3
    U X 0 1 Z W L H -
4
    -----------------
5
U | U U U U U U U U U  
6
X | U X X X X X X X X    
7
0 | U X 0 X 0 0 0 0 X
8
1 | U X X 1 1 1 1 1 X
9
Z | U X 0 1 Z W L H X
10
W | U X 0 1 W W W W X
11
L | U X 0 1 L W L W X
12
H | U X 0 1 H W W H X
13
- | U X X X X X X X X
(Quelle: 
http://tams-www.informatik.uni-hamburg.de/applets/hades/webdemos/00-intro/03-stdlogic/resolution.html)


> Der Wert ist einfach undefiniert, weil er in der Praxis durchaus einen
> Wert hat nd die Schaltung zB. funktionieren kann.
Ja, klar, denn in der Praxis gibt es sowieso nur '0' und '1' (und 
bestenfalls einen Buskonflikt). Nicht mal ein 'Z' kannst du messen...

Ein 'U' (=uninitialized) wird vom Synthesizer stillschweigend durch eine 
'0' ersetzt. Jedes Flipflop, das nicht explizit auf eine '1' 
initialisiert wird, wird also '0'. Das steht im Handbuch zum 
Synthesizer...

von J. S. (engineer) Benutzerseite


Lesenswert?

Eigentlich sollte kein Simulator ein "nicht-mehr-U" nochmal in ein 
U-überführen, es sei denn, es wird aus einem anderen "U" direkt 
gespeist.

Vor allem sollte er dem Anwender aber nicht "ein X für ein U vormachen", 
um mal den naheliegenden Witz zu bemühen. Das tut die Tabelle aber 
leider:

    U X 0 1 Z W L H -
    -----------------
U | U U

... und ich halte das für einen groben Fehler!
***********************************************

Ein X ist entweder das Resultat von funktionell (Ablauf, Konzept) 
falschem - oder realisationstechnisch (Schaltungslogik oder Timing) 
falschem Verhalten, dass nicht erwünscht sein kann und im Falle von 
gegeneinander treibenden Bussen z.B. zu Schäden- und in jedem Fall zu 
einem Fehler führt. Daher muss ein auftauchedes X in einer Simulation 
immer einer Betrachtung und meistens auch einer Behandlung unterzogen 
werden.

Ein U hingegen deutet nicht zwangsweise auf ein funktionell falsches 
Verhalten hin und schon garnicht muss es aus Realisationssicht immer 
behandelt worden, wobei man natürlich auch da hinschauen muss, was los 
ist. Wenn ein Signal z.B. durch das funktionell richtige Verhalten 
rechtzeit auf einen sinnvollen Wert geschaltet wird, bevor es reelvant 
ist, was der Simulator nicht checken kann, kann das Verhalten i.O. sein. 
Das U deutet aber in jedem Fall darauf hin, dass keine Kollision 
entsteht oder Schäden zu erwarten sind. Bei einem Zähler, der einfach 
loslaufen und gegen Anschlag fährt, um später gestartet zu werden und 
ein Delay abzugeben, ist das U komplett unkritisch und bei einem 
Zufallsgenerator ist es sogar erwünscht!

Daher sollten U und X auseindergehalten werden. Ich mache das so, dass 
ich in Modelsim das X auf Violett schalte und das U auf rot behalte!
Zudem kann man alle Signale auf U setzen, um in der Sim zu prüfen, ob 
sie rechtzeitig gesetzt werden und die Schaltung aus allen Zuständen 
heraus anlaufen kann, z.B. auch im Fall des logischen Resets mitttendrin 
sich alle FSMs wieder fangen, auch wenn die Zustände der abgeleiteten 
Signale nicht ausdrücklich reintialisert werden. Das Vorbelegen der 
init-Zustände kostet nämlich gfs resourcen. Spätestens, wenn man 
ausdrückliche resets einbaut, die wieder definierte Zustände der Signale 
herstellen, wird das ein Problem. Bei kleinen Schaltungen versucht man 
daher, ohne Zusatzresorucen auszukommen, speziell bei PLDs.

Noch mal zum "X für ein U vormachen":

Aus meiner Sicht ist diese Resolving-Strategie falsch! Wenn ein U auf 
ein X trifft, muss der Wert auf X gesetzt werden, da das U ja nur ein 
Platzhalter für eine O oder 1 ist, der in einem der beiden Fälle zu 
einer Kollision führt. Das U ist demnach sozusagen eine Verharmlosung!

Meines Erachtens müsste man sogar noch weiter gehen und die U's als 
Variablen mitschleifen, um sie mit anderen U's zu verrechnen. Damit 
würden sich bestimmte Simulationen wieder fangen, wenn durch die 
Schaltung sichergestellt ist, dass wie bei einem Zähler oder toogle-FF 
der Zustand einrastet. Ist aber ein anderes Thema.

von J. S. (engineer) Benutzerseite


Lesenswert?

Zum TE:

Ich denke, dass hier entweder ein DDR-FF mit dem halben Takt benutzt 
werden muss, das auf einen manuellen Serializer geht (ein echter ist 
hier overkill, weil der mit 7 Bits im MS-mode laufen muss und man 
geraume Zeit braucht, bis das alles stimmt) oder man kurzerhand mit 
einem erhöhten Takt arbeitet. Meines Erachtens sollte es reichen, den 
eingehenden Takt mit genau der dreifachen Frequenz zu samplen und dann 
die Datenleitung manuell abtasteten. Wenn ich es richtig sehe wären das 
40MHz * x, wobei das irgendwie mit den Daten noch nicht ganz passt. 8MHz 
x (4,3) Bit wären 32 MHz. Ist da noch eine Pause von einem Bit?

Ich würde jetzt Folgendes tun: Einfach alles mit 7x8x3= 168MHz oder 
mindestens 7x8x2 +10% = 120 MHz absamplen, dann die 8MHz-Flanke suchen 
und die Bits direkt ablesen. Wenn es bei dem 2fach-Takt Probleme mit der 
Lage der Bits gibt, könnte man mit der PLL 2 passend verschobene Takte 
bilden, den einen zum Samplen des 8MHz Taktes, den anderen zum 
verzögerten Samplen der Datenleitungen. Damit tut man in etwa das, was 
mit einem SERDES zu machen wäre, der auch den langsamen und den 
schnellen Takt einer PLL braucht, wobei der eine passend verschoben 
wird.

Bei den geringen 8MH hier ist es aber möglich und einfacher, wie o.a. 
mit dem Faktor 3 zu samplen. Man filtert die hereinkommenden Daten mit 
einem simplen 3-Tap Filter mit Mehrheitsentscheid und macht eine 3:1 
DDC. Das beseitigt alle Störungen und Fehler infolge von Jitter, 
Taktversatz oder Sample mismatch. Man muss dann nur ungefähr den 
Dreifachen Takt haben, der innerhalb der 7 Bits nicht zu sehr wegläuft 
und ungefähr in der Mitte abtasten.

von Chris2k (Gast)


Lesenswert?

Hallo zusammen. Danke für die zahlreiche Resonanz.

dasdgw schrieb:
> steigende und fallende Flanke in einem Process und keine Warnings oder
> Error vom Synthese-Tool?

Ja das geht hier. Ich hab heute extra nochmal nachgesehen. Die einzige 
Warnung ist "Using local reset signal 'reset_c' to infer global GSR 
net.".

Lothar Miller schrieb:
> Meinst du die Verhaltenssimulation (ohne Verzögerungszeiten, und ohne
> Synthese)?

Also bei Diamond kann ich im Simulator als Process Stage einmal RTL und 
einmal Post-Map Gate-Level auswählen, letzteres nur nachdem das Design 
gemapped wurde und ein VHDL Simulation File erstellt wurde. Aber du hast 
wohl recht, das ist wohl eine Verhaltenssimulation, da lediglich die 
VHDL-Quelle samt Testbench-VHDL vorhanden sein müssen.

> Welcher Gate-Level? Warum machst du das überhaupt?
Siehe oben. Ich mach das, um zu sehen, ob meine VHDL-Datei vernünftig 
synthetisiert ist. Von Constraints habe ich leider noch gar keine 
Ahnung, bis auf Zuordnung der Pins (und der Taktfrequenz). Mehr wurde im 
Rahmen meiner Vorlesung nicht behandelt.

> 'U' heißt "uninitialized", nicht "unknown"...
Achso. Laut meinem Skript war U "unknown" und X "Treiberkonflikt". Aber 
das Skript ist erst in der Vorbereitung, daher sind dort Fehler nicht 
auszuschließen. Ist aber notiert.

> Bist du sicher, dass der Synthesizer deine Beschreibung korrekt in
> DDR-IO-Zellen packt?
Der Hinweis hat mich dazu gebracht, mich weiter in Diamond umzusehen, 
insbesondere mir HDL Analyst in Synplify näher anzuschauen. Heute morgen 
hab ich mir das Erzeugnis mal näher angesehen, und es wird nichts 
wegoptimiert. Der Clock wird invertiert, und mit der invertierten 
Version werden meine Anweisungen der fallenden Flanke durchgeführt. Ich 
habe anschließend nochmal die Simulation gestartet....und was soll ich 
sagen. Es scheint nun zu funktionieren, und zwar ohne jedwede Änderung 
(?!). Ich hatte ein ähnliches Erlebnis bereits zuvor mit Diamond, 
entweder liegt es an mir oder da ist was verbugged. Eben hab ich das 
Design auf den FPGA geschrieben. Der Praxistest ist insofern 
zufriedenstellend, als das mein rdy-Pin mit 8 MHz "blinkt" wie erwartet. 
Ob nun die Daten auch an den 7 Ausgangspins anliegen, soll ein Test an 
einem Logic Analyzer zeigen...

> Du hattest Probleme? Das heißt, das Design läuft in der Realität? Ich
> würde das sehr beeindruckend finden...

Ich hatte die Geschichte noch nicht auf den FPGA implementiert, ich 
wollte mich da auf die Simulation verlassen, eh ich mich weiter 
rumärgere. Aber nun scheint es zu funktionieren.
Kurz OT: Es wird immer behauptet, eine Division à la "erg <= inp0 / 
inp1" wäre in VHDL nicht synthetisierbar. Das liest man ja hier sehr 
oft, so hatte ich mir das natürlich im Hirn abgespeichert. Ich habs 
dennoch probiert...naja, es ist synthetisierbar und funktioniert, auch 
auf meinem MachXO2-Board in Praxis. Also generell schaffen 
Synthese-Tools sehr wohl, so etwas umzusetzen. Im Test hatte ich aber 
lediglich eine 8 bit Division, der Rest des Quotienten fiel hinten weg. 
Optimal wird die Umsetzung vielleicht auch nicht sein, aber das steht 
auf einem anderen Blatt.

> Hast du dir mal den RTL-Plan nach der Synthese angeschaut? Wird da evtl.
> einfach die Hälfte (oder noch mehr) wegoptimiert? Wie groß ist der
> Ressourcenverbrauch (insbesondere die Anzahl der Flipflops)? Deckt der
> sich mit deinen Erwartungen?

Nunja. Ehrlich gesagt finde ich VHDL ziemlich bescheiden, wenn ich mir 
tatsächlich so viele Gedanken machen muss. Ich dachte, dass VHDL doch 
eher abstrahiert. Dass ich in Hardware denken muss ist mir dabei schon 
klar ;) Insofern habe ich mir bis dahin noch keine Gedanken zum 
Ressourcenverbrauch gemacht. Ist das Usus, dass man darüber vorab 
nachdenkt? Erfahrung zur ersten Abschätzung habe ich nämlich keine. Bei 
einer eher einfachen Aufgabe wie dieser hier wäre das aber wohl möglich.

> Ich würde meinen, man muss die DDR-Komponenten per Handschlag
> instatiieren. Sowas legt mir z.B. der Abschnitt "Implementing High-Speed
> Interfaces with MachXO2 Devices" aus dem "MachXO2 Family Handbook" nahe.

Ich hatte mir natürlich ganz zum Anfang auch das Handbuch zur Brust 
genommen. Leider hatte ich nicht begriffen, was ein Gearing ist und wie 
man die ganze Geschichte dann auch in Betrieb nimmt. Daher dachte ich, 
dass ich das auch per Hand hinkriegen würde, Ergebnis hier ersichtlich 
;)

Noch zu meiner Vorgangsweise:
Ich hab das so realisiert, wie von Johann hier im Thread beschrieben. 
Ohne Verwendung von zwei (Schiebe-)Registern für steigende und fallende 
Flanke kommt es tatsächlich zu Fehlermeldung bei der Synthetisierung. Am 
Ende dann beide Flips Flops zu einem zusammenbauen.

J. S. schrieb:
> Meines Erachtens sollte es reichen, den
> eingehenden Takt mit genau der dreifachen Frequenz zu samplen und dann
> die Datenleitung manuell abtasteten. Wenn ich es richtig sehe wären das
> 40MHz * x, wobei das irgendwie mit den Daten noch nicht ganz passt. 8MHz
> x (4,3) Bit wären 32 MHz. Ist da noch eine Pause von einem Bit?

Oversamplen wollte ich vermeiden, da ich dann auf jeden Fall einen 
weiteren (externen) Takt verwenden müsste (oder den on Chip-Takt). Wie 
im Skop.png ersichtlich, gibt es tatsächlich Pausen zwischen den Bits, 
daher die Diskrepanz. Die tatsächliche Frequenz ist übrigens 37,5 MHz.
Hinter deine weiteren Ausführungen bin ich noch nicht so ganz gestiegen, 
aber ich schau mir das nochmal an.

Morgen geht's aber zunächst an den Praxistest, der mir hoffentlich ein 
"ok" bescheinigt :)

Vielen Dank!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Chris2k schrieb:
> Der Clock wird invertiert, und mit der invertierten
> Version werden meine Anweisungen der fallenden Flanke durchgeführt.
Das ist eine Möglichkeit, diesen Konflikt aufzulösen, !!aber!! damit 
kannst du eben nicht mit der fallenden und der steigenden Flanke auf 
das selbe Flipflop zugreifen. Du könntest also deinen Prozess ganz 
einfach in 2 Prozesse aufdröseln, weil der eine Prozess die Signale des 
anderen Prozesses nicht direkt beeinflusst.
> Ohne Verwendung von zwei (Schiebe-)Registern für steigende und fallende
> Flanke kommt es tatsächlich zu Fehlermeldung bei der Synthetisierung.
Ja, nachdem ich mir deinen Code nochmal angeschaut habe ist es klar, 
dass du genau so die Abhängigkeiten auseinander hältst:
1
    elsif falling_edge(clk) then  -- clock uneven bits into shift register
2
      sr0 <= sr0(2 downto 0) & SER_IN;
3
    elsif rising_edge(clk) then -- clock even bits into shift register
4
      sr1 <= sr1(1 downto 0) & SER_IN;
5
    end if;
Du hast hier also 2 kurze Schieberegister (4 Bit + 3 Bit) und verknotest 
die beiden Dinger dann hinterher miteinander zu einem Wort...

> Ich hatte mir natürlich ganz zum Anfang auch das Handbuch zur Brust
> genommen. Leider hatte ich nicht begriffen, was ein Gearing ist und wie
> man die ganze Geschichte dann auch in Betrieb nimmt.
Das Gearing ist vereinfacht genau das, was du jetzt gerade händisch 
machst:
> Am Ende dann beide Flips Flops zu einem zusammenbauen.
Ein Zacken vom einen Zahnrad, dann der Zacken vom anderen Zahnrad...

Letztlich brauchst du nur 1 einziges DDR-Flipflop, das quasi das Bit der 
"falschen" Flanke (z.B. die fallende, wenn der Rest deiner Designs auf 
die steigende Flanke hört) zwischenspeichert. Mit der nächsten 
"richtigen" Flanke hast du dann gleich 2 Bits empfangen....

> Nunja. Ehrlich gesagt finde ich VHDL ziemlich bescheiden, wenn ich mir
> tatsächlich so viele Gedanken machen muss. Ich dachte, dass VHDL doch
> eher abstrahiert.
VHDL an sich kann viel viel mehr, als die Synthese dann in Hardware 
umsetzen kann. Das Problem mit der Abstraktion ist also nicht VHDL, 
sondern die Toolchain...
Darum geht es auch im 
Beitrag "Re: ISE übersetzt irgend wie nur Mist"

von Robert K. (Firma: Medizintechnik) (robident)


Lesenswert?

Lothar Miller schrieb:
> Ja, nachdem ich mir deinen Code nochmal angeschaut habe ist es klar,
>
> dass du genau so die Abhängigkeiten auseinander hältst:    elsif 
falling_edge(clk) then  -- clock uneven bits into shift register
>
>       sr0 <= sr0(2 downto 0) & SER_IN;
>
>     elsif rising_edge(clk) then -- clock even bits into shift register
>
>       sr1 <= sr1(1 downto 0) & SER_IN;
>
>     end if;
>
>
>
>
>
> Du hast hier also 2 kurze Schieberegister (4 Bit + 3 Bit) und verknotest
>
> die beiden Dinger dann hinterher miteinander zu einem Wort...

Ist das Deiner Ansicht nun richtig oder nicht richtig so?

Kann / Muss man beim Lattice das DDR in VHDL beschreiben?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Robert K. schrieb:
> Kann / Muss man beim Lattice das DDR in VHDL beschreiben?
Die Antwort lautet zweimal: "Nein"

von berndl (Gast)


Lesenswert?

Einfach um Lothars Aussage noch mal zu bekraeftigen:
Nein und Nein!

von Chris2k (Gast)


Lesenswert?

Hallo nochmal,

nachdem ich nun mittels Logic Analyzer die seriellen mit den 
parallelisierten Werten verglichen hab, kann ich ein Funktionieren 
bescheinigen =)

Lothar Miller schrieb:
> Letztlich brauchst du nur 1 einziges DDR-Flipflop, das quasi das Bit der
> "falschen" Flanke (z.B. die fallende, wenn der Rest deiner Designs auf
> die steigende Flanke hört)

Danke, das ist mir nun klar. Nächstes Mal werde ich dann das fertige 
DDR-Modul in Diamond verwenden.

von Xenu (Gast)


Lesenswert?

>Es wird immer behauptet, eine Division à la "erg <= inp0 /
>inp1" wäre in VHDL nicht synthetisierbar.
>[...] Ich habs dennoch probiert...naja, es ist synthetisierbar und funktioniert,
>auch auf meinem MachXO2-Board in Praxis


Welche VHDL-Konstrukte synthetisierbar sind, steht normalerweise (bzw. 
hoffentlich) im Handbuch der Synthese-Software. Bei Altera synthetisiert 
er auch Divisionen, falls die Signale Integer sind. Daraus generiert er 
Dir dann eine LPM_DIVIDE-Megafunction.

von Robert K. (Firma: Medizintechnik) (robident)


Lesenswert?

> Daraus generiert er Dir dann eine LPM_DIVIDE-Megafunction.
Und wie ist das mit dem Timing? Wenn der Ausgang der Division 
weiterverwendet wird, muss er zeitlich in der pipeline zu anderen Daten 
passen. Ein divider injiziert aber Latenz. Wie wird das berücksichtigt?

Von Altera weiss ich, dass man die Latenz einstellen kann. Was nimmt er 
da?

von Xenu (Gast)


Lesenswert?

Es wird ein rein kombinatorischer LPM_DIVIDE generiert, also Latenz = 0.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Robert K. schrieb:
> Ein divider injiziert aber Latenz. Wie wird das berücksichtigt?
Er hat keine Latenz, sondern nur eine Laufzeit, solange der Divider 
kombinatorisch aufgebaut ist. Klar läuft dann dieser Pfad des Designs 
nicht mehr mit 300MHz, sondern nur noch mit 30...  :-o

von Robert K. (Firma: Medizintechnik) (robident)


Lesenswert?

Xenu schrieb:
> Es wird ein rein kombinatorischer LPM_DIVIDE generiert, also Latenz = 0.

Ok, das hatte ich jetzt überlesen. Einen Kombi-Divider zu instanziieren 
ist funktionell immer richtig, stimmt.

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.