Moin,
ich habe in meinem Code (besser gesagt in der Simulation der
Konfiguration) gerade ein merkwürdiges Verhalten entdeckt. Eigentlich
ging ich davon aus, dass die letzte gültige Zuweisung eines Signals
gewinnt. Bei mir ist dem nicht so (nachfolgend ein kleiner
Codeausschnitt mit nur den nötigsten Zeilen):
1
MemFsm:process(MemUiCLK,pSysRstN)
2
begin
3
-- default assignment
4
+NextSampleAddrReq<='0';
5
6
-- reset
7
ifpSysRstN='0'then
8
NextSampleAddrReq<='0';
9
...
10
11
-- execute statemachine
12
elsifrising_edge(MemUiCLK)then
13
case(MemFsmState)is
14
whenfsmIdle=>
15
...
16
whenfsmWrite=>
17
*NextSampleAddrReq<='1';
18
...
19
endcase;
20
endif;
21
endprocess;
Man sollte meinen, dass wenn die entsprechenden Bedingungen erfüllt
sind, die Zuweisung in der mit * markierten Zeile die Zuweisung in der
mit + markierten Zeile überschreibt. Dem ist aber nicht so! Warum nicht?
Wenn ich die Zeile + auskommentiere, dann wird, wie erwartet, die
Zuweisung in Zeile * gesetzt.
Hat jemand eine Idee? Ist bestimmt was ganz simples... :(
Ach, was ganz Dummes wars: ich hatte den MemFsmState mit in der
Sensitivylist. Dh sobald ich den state geändert habe (auch das passierte
in when fsmIdle), wurde der process erneut aufgerufen und das Signal
NextSampleAddrReq in der default Zuweisung wieder genullt... In der Sim
war da nciht mal ein Peak zu sehen, weswegen ich dachte, das Signal ist
die ganze Zeit null...
Sebastian schrieb:> Eigentlich ging ich davon aus, dass die letzte gültige Zuweisung eines> Signals gewinnt.
Ja, das ist so.
> Hat jemand eine Idee? Ist bestimmt was ganz simples... :(
Was da steht, ist: das Signal ist immer '0', ausser während einer
Taktflanke. Wie lange dauert ein Takt bzw. eine Taktflanke? Richtig:
in der Theorie genau 0ps. Wie lange ist also dein Signal '1'? Richtig:
genau 0ps!
Probiers mal wie der Rest der Welt:
1
-- reset
2
ifpSysRstN='0'then
3
NextSampleAddrReq<='0';
4
...
5
6
-- execute statemachine
7
elsifrising_edge(MemUiCLK)then
8
-- default assignment
9
+NextSampleAddrReq<='0';
10
11
case(MemFsmState)is
12
whenfsmIdle=>
13
...
14
whenfsmWrite=>
15
*NextSampleAddrReq<='1';
Sebastian schrieb:> Ach, was ganz Dummes wars: ich hatte den MemFsmState mit in der> Sensitivylist.
Das Proble ist, dass du dir zwar die Simulation hintricksen kannst, der
Synthese so etwas aber trozdem "einbaut". Also wird er in deinem obigen
Fall eher sagen, dass der ganze Prozess unnötig ist, weil das Signal
sowieso immer '0' sei.
Lothar M. schrieb:> Probiers mal wie der Rest der Welt:
Ja, bin gerade wieder dabei mich in VHDL einzuarbeiten. Das letzte Mal
ist ne ganze Weile her und da passieren nun die ein oder anderen Fauxpas
:)
Was ich übrigens ganz witzig finde ist folgende Erkenntnis, die mir die
Simulation gerade gezeigt hat (bin mir nicht sicher, ob das die Synthese
überlebt):
Dadurch, dass ich außerhalb der synchronen if-Bedingung direkt zu Beginn
des Prozesses Zuweisungen habe, reagiert der Prozess auf steigende und
fallende Flanken des Clock Signals. Gelesen habe ich jedoch, dass eine
solche Hardware nicht synthetisiert werden kann.
Die FlipFlops in den Coolrunnern können auf
steigende UND fallende Flanken reagieren, das
macht der Synthesizer auch mit.
Mit etwas Getue und 2 "normalen" FFs sollte man
das auch hinkriegen können. Ob das dann automagisch
synthetisiert werden kann ist eine andere Frage.
Gruß, Gerhard
Sebastian schrieb:> Dadurch, dass ich außerhalb der synchronen if-Bedingung direkt zu Beginn> des Prozesses Zuweisungen habe, reagiert der Prozess auf steigende und> fallende Flanken des Clock Signals.
Das tut er nur in der Simulation. In der Realität teilt dir der
Synthesizer lapidar mit, dass die Sensitivliste nicht vollständig sei
und deshalb die Simulation nicht zu der Realität passe.
> Gelesen habe ich jedoch, dass eine solche Hardware nicht synthetisiert> werden kann.
Es gibt Bausteine wie den Coolrunner mit solchen "Inselbegabungen". In
FPGAs gibt es sowas alerdings nicht. Die DDRFF in deren IO-Zellen sind
eigentlich 2 Flipflops, von denen das eine auf die steigende und das
andere auf die fallende Flanke reagiert.
Gerhard H. schrieb:> Mit etwas Getue und 2 "normalen" FFs sollte man> das auch hinkriegen können. Ob das dann automagisch> synthetisiert werden kann ist eine andere Frage.
Und man hätte damit auch nichts gewonnen, ausser dass sich bei
unverändertem Design letztlich die maximale Taktfrequenz bestenfalls
einfach nur halbieren würde (aber dann eben durch die Reaktion auf beide
Flanken der halbierten Frequenz letztlich die gleiche
Systemgeschwindikeit herauskäme).
Sebastian schrieb:> Dadurch, dass ich außerhalb der synchronen if-Bedingung> direkt zu Beginn des Prozesses Zuweisungen habe, reagiert> der Prozess auf steigende und fallende Flanken des Clock> Signals.
Nicht dadurch. Das tut er immer, wenn sich ein Signal der Sensitivity
List ändert (das ist ja deren Sinn). Allerdings verhindert bei richtiger
Anwendung das "if rising_edge()", dass bei der fallenden Flanke
irgendwas passiert.
> Gelesen habe ich jedoch, dass eine> solche Hardware nicht synthetisiert werden kann.
Das ist das schöne an der Simulation, woran ich mich auch erstmal
gewöhnen musste. Man kann machen, was man will und muss sich nicht um
Einschränkungen der Synthese kümmern.
Eine eigene Frage?
Dieser Thread ist über 5 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.