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
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.
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
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
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.
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...
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.
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.
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!
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"
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?
Robert K. schrieb: > Kann / Muss man beim Lattice das DDR in VHDL beschreiben? Die Antwort lautet zweimal: "Nein"
Einfach um Lothars Aussage noch mal zu bekraeftigen: Nein und Nein!
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.
>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.
> 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?
Es wird ein rein kombinatorischer LPM_DIVIDE generiert, also Latenz = 0.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.