Hallo
folgenden code habe ich von lothar-miller ein binaer counter, nun wollte
ich den code so verändern das ich den Takt clk in 2^x stufen dividieren
kann.
Dazu habe ich ein Singal "takt" erzeugt das nach jedem durchlauf
getoggelt wird (not) und mit max_tick auf dem output verbunden ist. Nun
meldet Xilinx ISE 11.5 aber ein Latch:
WARNING:Xst:737 - Found 1-bit latch for signal <takt>. Latches may be
generated from incomplete case or if statements. We do not recommend the
use of latches in FPGA/CPLD designs, as they may lead to timing
problems.
Frage wo liegt mein Problem bei diesem if?
takt <= not takt when r_reg=(2**N-1) else takt;
wo liegt mein Denkfehler?
>Dazu habe ich ein Singal "takt" erzeugt das getoggelt wird
Ja.
>Dazu habe ich ein Singal "takt" erzeugt das nach jedem durchlauf getoggelt wird
Nein.
Das Signal toggelt solange mit der maximal möglichen Frequenz hin und
her wie r_reg=(2**N-1) gilt. Du willst aus takt ein Flipflop machen, das
seinen Zustand nur bei einer Taktflanke ändert.
Stimmt testbench fehlt... (hab ich mich noch nicht damit befasst)
Habs jetzt so gemacht, frage mir kommt das umständlich vor hat jemand
eine "sauberere Lösung"?
Hallo mchii
Du hast noch ein paar Probleme in dem Verständnis, was der unterschied
zwischen Software und Hardwarebeschreibung ist. Versuche Dich von dem
Gedanken zu lösen, dass du Hardware programmierst.
Um ein Signal stabil in einem Zustand zu halten bedarf es ein
Speicherelement. Dies sollte im FPGA (oder CPLD) immer ein FlipFlop
sein. Ein Latch ist immer zu vermeiden.
Um ein FF zu beschreiben bedarf es (für den Anfänger) immer ein Prozess
mit einem Takt. Dein folgender Ansatz
1
process(flag)
2
begin
3
ifrising_edge(flag)then
4
takt<=nottakt;
5
endif;
6
endprocess;
ist daher nicht verkehrt. Das Signal Takt invertiert sich immer wenn das
Singal flag eine steigende Flanke hat.
Allerdings stellt das Signal flag hier das Problem dar:
1
flag<='1'whenr_reg=(2**N-1)else'0';
Warum: Was hier beschrieben ist ist eine sogenannte beiläufige
Anweisung. Es entsteht hier eine Schaltungslogik die aus den
Grundgattern (UND, ODER, NAND...) zusammengebaut ist. Wenn sich nun ein
oder mehrere Signale am Eingang dieser Gatterkombination (also ein bit
aus r_reg) ändert, dann hat das zur Folge dass sich ev. das Signal flag
ändert. Wenn Du aber pech hast, dann ändert wegen der Laufzeiten auf den
Leitungen (Signal) und den Durchlaufzeiten in den Gattern dein
flag-Signal für einen kurzen Moment obwohl es sich aus Deiner Logik
nicht ändern sollte. Dies nennt man Glitch.
Als Feste Regel sollte daher sein, dass ein Takt immer nur exakt eine
Quelle haben sollte. Das flag-Signal von Dir wir ja als Takt verwendet.
Um das ganze trotzdem korrekt zu lösen, könntest Du folgendes tun:
1
process(clk)
2
begin
3
ifrising_edge(clk)then
4
ifr_reg=(2**N-1)then
5
takt<=nottakt;
6
endif;
7
endif;
8
endprocess;
Was hier entsteht ist ein FF dessen Ausgang invertiert auf den Eingang
zurück geführt wird. Die Verknüfung r_reg=(2**N-1) ergibt dann ein
Signal das an den Enable Eingang des FF geführt wird.
mchii schrieb:> kurzer nachtrag Code ist NICHT von lothar miller...
Richtig. Ich mache (so gut wie keine) Latches...
> entschuldigung für die falsche angabe...
Du bist hiermit entschuldigt... ;-)
Matthias G. schrieb:> Um das ganze trotzdem korrekt zu lösen...
Diese Lösung entspricht nicht ganz dem ursprünglichen Problem:
>>> flag <= '1' when r_reg=(2**N-1) else '0';
Das ist eigentlich kein TAKT, sondern ein ENABLE, das alle 2**N
Taktzyklen für genau 1 Taktzyklus aktiv ist. Takte (Mehrzahl) gibt es in
einem Anfängerdesign nicht. Sondern es gibt nur 1 Takt. Fertig.
Die Lösung sieht also so aus:
Hallo
Danke für die Hilfe mgottke und ausführliche Erklärung, dadurch ergeben
sich jedoch ein paar fragen.
1, meinst du damit das ich IMMER nur clk auf die empfindlichkeits liste
setzen soll?
2.) die Lösung hier funktioniert, was ist jedoch wenn der Fall
r_reg=(2**N-1) für 2 oder GÜLTIG wäre, dann bräuchte ich ja wieder eine
Flanke... wie mach ich es da?
Dieses beispiel hier dürfte ja nicht "richtig" sein...
process(clk)
begin
if rising_edge(clk) then
if rising_edge(flanke) then
....
@lothar
ebenfalls danke für die hilfe, dein Beispiel ist ein Enable, ich jedoch
wollte dieses Enable als Flag nutzen um den Takt in entsprechende Stücke
zu teilen....
lg mchii
korrektur von 2.)
2.) die Lösung hier funktioniert, was ist jedoch wenn der Fall
r_reg=(2**N-1) für 2 oder mehr takte GÜLTIG wäre, dann bräuchte ich ja
wieder eine
Flanke... wie mach ich es da?
> hm der code erzeugt noch immer ein Latch, aber ohne Xilinx ise warning.
Bei mir gibt es da kein Latch. Für N=2 entsteht die Schaltung im Bild.
@ Lothar
> Diese Lösung entspricht nicht ganz dem ursprünglichen Problem:
Da hast Du schon recht. Ich hatte noch die gleichen Gedanken dazu. Hier
liegt aber so ein bisschen ein Sonderfall zu. max_tick (spich takt) ist
hier ein Ausgang. Sehr vermutlich wird aber der Block, und daher auch
der Takt, im FPGA weiter verwendet. Das wäre ungünstig.
Ich wollte erst mal nur ein Problemchen beleuchten um das Verständnis
dafür zu wecken.
Für Anfänger: Es gibt nur genau 1 Takt im Design. Alles andere läuft
über Enable.
Für Fortgeschrittene und Profis: Es gibt auch nur 1 Takt. Ausnahmen
bestätigen die Regel. Taktübergänge sind immer kritisch.
Du hast recht da kommt kein latch, jedoch updatet das "View RTL
schematic" nicht bei änderungen selbst wenn ich force klicke, irgend
eine idee wie ich das im XilinxISE mache ohne neu zu starten?
bleiben noch meine Fragen zu vorhin:
2.) die Lösung hier funktioniert, was ist jedoch wenn der Fall
r_reg=(2**N-1) für 2 oder mehrere Takte GÜLTIG wäre, dann bräuchte ich
ja wieder eine
Flanke... wie mach ich es da?
Dieses beispiel hier dürfte ja nicht "richtig" sein...
process(clk)
begin
if rising_edge(clk) then
if rising_edge(flanke) then
....
lg Michi
michi m. schrieb:> Dieses beispiel hier dürfte ja nicht "richtig" sein...> process(clk)> begin> if rising_edge(clk) then> if rising_edge(flanke) then> ....
So ein Bauteil mit 2 Takteingängen gibt es nicht in einem FPGA. Für die
Simulation darfst du das aber trotzdem so hinschreiben... ;-)
mchii schrieb:> 1, meinst du damit das ich IMMER nur clk auf die empfindlichkeits liste> setzen soll?
Auf die Sensitvliste (die ausschliesslich für den Simulator interessant
ist!) gehören alle Signale, die eine Neuberechnung des Prozesses für die
Simulation nötig machen.
KURZ: die Sensitivliste ist nur für die Simulation interessant.
ABER: wenn die Sensitivliste nicht korrekt ist, stimmt auch die
Simulation nicht!
mchii schrieb:> hm der code erzeugt noch immer ein Latch, aber ohne Xilinx ise warning.
Ich kann Matthias nur bestätigen: dieses Bild gehört nicht zu dem dazu
geposteten Code.
Lothar Miller schrieb:> So ein Bauteil mit 2 Takteingängen gibt es nicht in einem FPGA. Für die> Simulation darfst du das aber trotzdem so hinschreiben... ;-)>
Ja das war mir bewusst, nur meinte Matthias ich solle nur eine
"Taktquelle" verwenden im ganzen Design (wenn ich das richtig gelesen
hab) nun war aber meine Frage wenn dieses Enable als Flag nutzen will,
das Enable aber über 2 oder Mehr taktzyklen aktiv ist wie ich hier dann
auf die Flanke Triggern soll, wenn im ganzen Design nur ein Takt
existieren soll.
> mchii schrieb:>> hm der code erzeugt noch immer ein Latch, aber ohne Xilinx ise warning.Lothar Miller schrieb:> Ich kann Matthias nur bestätigen: dieses Bild gehört nicht zu dem dazu> geposteten Code.
Ja wie schon oben geschrieben hat mein Xilinx RTL Schematic den Plan
nicht aktuallisiert.... (selbst bei expliziter aufforderung)
lg Michi
michi m. schrieb:> das Enable aber über 2 oder Mehr taktzyklen aktiv ist wie ich hier dann> auf die Flanke Triggern soll, wenn im ganzen Design nur ein Takt> existieren soll.
Ich würde das so machen, wenn das Enable ein externes Signal wäre:
http://www.lothar-miller.de/s9y/categories/19-SpikePuls
Oder so:
http://www.lothar-miller.de/s9y/categories/18-Flankenerkennung> wenn dieses Enable als Flag nutzen will,> das Enable aber über 2 oder Mehr taktzyklen aktiv ist
Ich verstehe das Problem nicht ganz: wenn du das Enable imFPGA
erzeugst, dann ist es genauso lang, wie du es beschrieben hast.
Danke für die Hilfe.
Ich verstehe deine Bedenken, nun ist halt eine Anfängerfrage da macht
man sich um solche Dinge gedanken auch wenn das Signal von einem Selbst
erzeugt wird.
Danke für die Links.
lg Michi