Hallo,
ich habe folgendes Problem.
Um diverse Messungen durchzuführen brauche ich 2 Zählschleifen. Die eine
zählt mir die Anzahl der Loops und die andere die Anzahl an clk_cycles
in jedem Loop. Die Werte beider Counter müssen abgegriffen werden um
diverse Switches zu setzen. Nun habe ich das folgende Problem.
Der Gesamtaufbau läuft einwandfrei und hört immer genau passend nach
"set_n_samples" (dieser wert wird über twi gesetzt) auf.
Sobald ich nun aber die Werte der Counter abgreife "verzählt" sich
alles.
setze ich n_samples höher als 65535 so stoppt alles immer nach einer
bestimmten zeit, wobei mir unergründlich ist warum ausgerechnet an
diesem zeitpunkt. manchmal hört der aufbau auch ganricht auf zu zählen.
ich habe ein paar tests vorgenommen und im folgenden ist dies
rausgekommen("-" steht für "hält nicht an):
5->-
6->3
7->4
8->-
9->-
10->7
11->8
12->-
13->-
14->7
Ich habe absolut keine Ahnung wodran das liegt und hoffe ich kann hier
Hilfe bekommen. Das ganzemuss bis Ende der Woche fertig sein.
Würde es vll. helfen die Counterwerte vorher noch extra in Latches zu
legen? Ich bin mittlerweile echt ratlos. Der angehängte Code ist auch
nur einer mehrerer Auswüchse um dem Problem Herr zu werden
Mit freundlichen Grüßen
Das ist der Code nur mit Counter:
Böse, böse: viele verschiedene Takte.
Genauso böse: Takt aus Kombinatorik abgeleitet (help).
1
ifreset='0'then
2
counter<=0;
3
elsifstart_signal='0'then
4
counter<=1999;
5
elsifstart_signal='1'then
6
ifcounter=0then
7
counter<=1999;
8
elsifrising_edge(global_clk)andcounter>0then
Noch böser: kombinatorischer Reset.
Siehe dort:
http://www.lothar-miller.de/s9y/categories/34-Getakteter-Prozesshttp://www.lothar-miller.de/s9y/categories/35-Einsynchronisieren
Dein Design ist durch diese Verknotungen zwar noch Verhaltensimulierbar
(weil dort keine Laufzeiten und Timingverletzungen auftreten können),
aber es wird niemals zuverlässig auf Hardware laufen. Mein Postulat:
Ein Design (insbesondere ein Anfängerdesign) hat genau 1 Takt, der immer
auf dieselbe Flanke aktiv ist. Es gibt keinen (und schon gar keinen
asynchronen) Reset. Wenn du das einhältst, dann geht es.
BTW:
Das Design wird nicht mal richtig simuliert werden, denn hier ist die
Sensitivliste falsch:
1
process(global_clk,reset)
2
begin
3
ifreset='0'then
4
help<='0';
5
help_2<='0';
6
else
7
if(counter=0)then
8
:
9
endif;
10
11
if(stopper=0)then
12
:
13
endif;
14
endif;
15
endprocess;
Der global_clk wird im Prozess gar nicht verwendet, dafür fehlen
counter und stopper. Dieser Prozess wird in der Simulation aussehen
wie wenn er getaktet wäre, weil er ja mit einer Änderung von
global_clk neu berechnet wird. Dieses Verhalten ist aber falsch.
Klaus Falser schrieb:> Normalerweise sollte das so aussehen : process(clk, reset)> begin> if reset = '0' then> counter<=0;> elsif rising_edge(global_clk) then> if start_signal='0' then> counter<=1999;> elsif counter > 0 then> counter<=counter-1;> else> counter<=1999;> end if;> end if;> end process;
so sah es anfangs aus. da es nicht funktioniert hat habe ich es halt
umgeschrieben.
vielen dank für die antworten. wo die möglichkeit bestand habe ich die
tipps umgesetzt bzw teile neugeschrieben.
aber es ist immernoch so, dass richtig gezählt wird wenn ich die werte
nicht abgreife. implementiere ich nur das erste event, dann funktioniert
es noch.
aber sobald alle laufen herrscht wieder großes chaos.
es gibt 2 takte. der eine hat 100MHz , global_clk und ist nur zur
pulserzeugung da. das muss halt auf 10 ns genau sein.
der takt wird auf 1MHz runtergetaktet. dieser takt ist nur für die
datenverarbeitung zuständig.
aus dem "datensegment" kommt dann auch der kurze startpuls, der
umgeformt wird in ein sagen wir start_enable. die counter laufen während
dieser high ist. wenn die n_samples abgelaufen sind muss das enable
zurück gesetzt werden.
jetzt habe ich gerade einw enig ausprobiert und mir ist aufgefallen,
dass ich den counter mit maximal 2 abfragen belasten darf. durch
schreiben des counterwertes in ein latch kann ich dann auch 3 abfragen
erreichen.
dummerweise komme ich nicht unter den angegebenen 6 davon.
sobald ich auf 4 abfragen gehe ist irgendetwas nicht mehr koscher.
Flachmann schrieb:> jetzt habe ich gerade einw enig ausprobiert und mir ist aufgefallen,> dass ich den counter mit maximal 2 abfragen belasten darf. durch> schreiben des counterwertes in ein latch kann ich dann auch 3 abfragen> erreichen.> dummerweise komme ich nicht unter den angegebenen 6 davon.
Jetzt erzähle uns doch bitte einmal wie Du darauf kommst:
- Simulation oder Hardware, aber diese VHDL Files sollte man so
eigentlich nicht ohne Warnungen oder Fehler durch die Synthese bekommen.
- Welcher Simulator
- Welche Hardware
Gerade beim Simulieren kann man viele Sachen sehen, dann schaut man sich
den Zeitpunkt an bis wohin es stimmt und dann versucht man zu verstehen
was an dieser Stelle falsch läuft.
> es gibt 2 takte.
D.h. die ganzen andern abfragen auf rising_edge sind jetzt raus?
Alles, was mit rising_egde oder falling_edge oder 'event abgefragt wird,
ist ein Takt.
> der eine hat 100MHz , global_clk und ist nur zur> pulserzeugung da. das muss halt auf 10 ns genau sein.> der takt wird auf 1MHz runtergetaktet.
Dann ändere dein Design so, dass aus dem 1 MHz Takt ein 1 MHz
Clock-Enable wird. Erst dann ist das Design richtig synchron und
handhabbar.
> jetzt habe ich gerade einw enig ausprobiert und mir ist aufgefallen,> dass ich den counter mit maximal 2 abfragen belasten darf.
Innerhalb des FPGAs ist der Fan-Out wesentlich höher (min. 50) und falls
nötig werden von der Toolchain die Signale einfach dupliziert. Mit
asynchronen Abfragen auf den Counter und daraus resultierenden Resets
wirst du aber garantiert Probleme mit Glitches bekommen...
Und genauso sieht deine Fehlerbeschreibung aus :-o
> Die Simulation funktioniert ja einwandfrei.
Mit dem obigen Code? Dann wundert mich nichts, denn die Simulation ist
falsch. Siehe meine Anmerkungen oben:
>>> Dieser Prozess wird in der Simulation aussehen wie wenn er getaktet wäre
:-o
Lothar Miller schrieb:> Mit> asynchronen Abfragen auf den Counter und daraus resultierenden Resets> wirst du aber garantiert Probleme mit Glitches bekommen...
Der vorzufindende reset wird extern von einem µC erzeugt. Er dient nur
dazu das Ganze hart zu reseten. aus den abfragen heraus werden keine
resets generiert. wenn doch, dann erklär mit bitte wie das passiert.
> wenn doch, dann erklär mit bitte wie das passiert.
Das ist ein asynchroner kombinatorischer Reset:
1
ifreset='0'then
2
counter<=0;
3
elsifstart_signal='0'then
4
counter<=1999;
5
elsifstart_signal='1'then
6
ifcounter=0then
7
counter<=1999;
8
elsifrising_edge(global_clk)andcounter>0then
9
counter<=counter-1;
10
endif;
11
endif;
Bestehend aus dem counter und dem startsignal.
Der Knackpunkt in der Hardware ist aber hier:
1
ifcounter=0then
2
counter<=1999;
3
elsifrising_edge(global_clk)andcounter>0then
4
counter<=counter-1;
5
endif;
Denn wenn der Counter z.B. von binär 0001111 nach 0010000 zählt und nur
kurz einen Glitch mit 00000000 erzeugt, was passiert dann? Ratzdifatz:
der Counter ist für ein paar ps lang 0 und er wird auf 1999 gesetzt
(oder wenigstens ein paar FFs des Counters.
ja das seh ich auch ein. aber warum treten dann die glitches nur auf
wenn ich die abfragen für die anderen signale ala if counter<1600
then...
auf den counter lege? bei bis zu 2 abfragen scheinen ja keine glitches
aufzutreten. warum aber bei mehreren abfragen?
> warum aber bei mehreren abfragen?
Weil dann die Signale intern anders oder mehr belastet werden. Das Ganze
ist z.B. auch temperaturabhängig und spannungsabhängig. Kurz: unsauber.
Es könnte schon reichen, dass du irgendwas änderst und deshalb das
Design ein klein wenig anders platziert und gerouted wird und dann nicht
mehr zuverlässig läuft. Und voila: du suchst den Fehler an der falschen
Stelle, weil du meinst "vor der letzten Änderung ist es noch
gegangen...".
ah ja gut. ich dachte nicht, dass die belastung direkt mit den races zu
tun hat und auch nich, dass die races an besagten stellen auftreten. ich
hoffe das löst das problem. dankeschön!
Hmhmmmm:
if reset='0' or start_signal='0' then
Aber weil start_signal synchron gesetzt wird, können schon mal keine
Glitches mehr auftreten. Spannend könnte es allerdings werden, wenn
start_signal auf '1' geht, dann wird ziemlich zeitgleich mit dem Takt
der Reset weggenommen...
Was sagt denn die Synthese zum Thema "Maximalfrequenz des Designs"?
das dürfte doch egal sein. es passiert ja kein reset während
start_signal auf 1 geht. zur maximalen freuenz hab ich in xilinx' ise
jetzt leider ncihts gefunden. wo sollte das denn stehen? im
synthetisierungsbericht stand nix drin..
Flachmann schrieb:> das dürfte doch egal sein. es passiert ja kein reset während> start_signal auf 1 geht.
Doch, start_signal = 0 steht im Reset-Pfad der FFs, die davon
betroffenen FFs werden asynchron mit start_signal = 0 zurückgesetzt.
Erst wenn start_signal auf '1' geht, werden die FF's für den Takt
global_clk freigegeben.
aber die flipflops die durch start_signal gesteuert werden haben
keinerlei rückwirkung auf die ganze zähleinheit. welche auswirkung kann
das darauf haben, dass das signal stop_signal nicht mehr auf 1 gesetzt
wird, weil die anzahl samples nicht mehr erreicht wird?
Hast du denn überhaupt deinen 100 Mhz Takt mit einer Period Constraint
definiert. ?
Wenn ISE nicht weiss, wie schnell der Takt ist, dann gibt sich die
Toolchain auch keine mühe beim Placen.
> Das wäre die bessere Variante:
Am besten wäre es, auf einen generellen (insbesondere asnychronen) Reset
komplett zu verzichten. Dazu die Whitepapers WP272 und WP272 von Xilinx
und hier im Beitrag "Theoriefrage asynchroner Reset"