Forum: FPGA, VHDL & Co. böser code oder passt es?


von Max (Gast)


Lesenswert?

Hallo.

Wenn ich zB für eine Art SPI-Slave folgendes Code-stück verwende, ist 
das dann gröbster Müll, wegen gated clock oder wird das zu einem 
clock-enable? kann man es prinzipiell so machen, also dass die 
rising_edge so wie da nach einer bedingung abgefragt wird?

1
p_getData : process(spiClk,reset,FrameSync,...)  
2
  begin
3
    if(reset = '1')then
4
      --reset the regs
5
    elsif(FrameSync = '0' and enAddressGen = '1')then
6
      if(state = OPERATE)then
7
        if(spiClkCnt = timeslot-'1')then 
8
          serial_busy_flag <= '1';
9
        end if;
10
      else  -- 16 bit-mode
11
        serial_busy_flag <= '1';
12
      end if;
13
      
14
      if(rising_edge(spiClk))then
15
        spiClkCnt := spiClkCnt + '1';
16
                                ...

von max (Gast)


Lesenswert?

ja. böser code!
1
p_getData : process(spiClk,reset,FrameSync,...)  
2
  begin
3
    if(reset = '1')then
4
      --reset the regs
5
    elsif(rising_edge(spiClk))then
6
7
       if(FrameSync = '0' and enAddressGen = '1')then
8
         if(state = OPERATE)then
9
           if(spiClkCnt = timeslot-'1')then

von Peter (Gast)


Lesenswert?

also zumindest ist es seeehr unüblich auf solche weise synchrone und 
asynchrone Zuweisungen innerhalb eines Prozesses zu vermischen. Das wäre 
nämlich ein beliebtes Stilmittel  für einen Obfurscated VHDL Contest :D

von Max (Gast)


Lesenswert?

Ok danke, ich dachte es mir schon.

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


Lesenswert?

Peter schrieb:
> Obfurscated VHDL Contest
Da ist ein 'r' zuviel drin...  ;-)

Wie auch immer: der original gepostete Code wäre ein Extrembeispiel für 
einen eigenartigen Clock-Enable. Aber die Synthesetools können 
heutzutage einiges ab:
http://www.lothar-miller.de/s9y/categories/6-Clock-Enable

Max schrieb:
> eine Art SPI-Slave
Der sieht schon auf die paar geposteten Zeilen bezogen unglaublich 
umständlich aus. SPI ist erst mal nicht anderes als zwei 
Schieberegister, und alles was du "dranbastelst", macht die Sache sicher 
nicht besser. Bestenfalls umständlicher.

Was mir noch auffällt:
1
      if(rising_edge(spiClk))then
Was ist die Zielplattform? CPLD/FPGA?
Wieviele Takte hast du?
1
        spiClkCnt := spiClkCnt + '1';
1. Warum eine Variable?
2. Nimm besser einen Integer zum Zählen.

Das wäre mein SPI fürs CPLD:
http://www.lothar-miller.de/s9y/categories/26-SPI-Slave

von Max (Gast)


Lesenswert?

Hallo.

Danke für die Antworten!
Was ich bauen wollte/will ist ein SPI-Slave der sich mittels TDMA in 
einen 4096-Tick-langen Frame einhängt. Der Mechanismus an sich passt 
soweit mal (also das die Slaves wissen wann wer dran kommt, die zählen 
SpiClk-ticks mit...).
Ich habe jetzt den "bösen" Code geändert:

gated clocks weggetan, alles mit signale realisiert mehr processe mit 
mehr flags, usw
4 processe:
+ einen für die rising_edge der spiClk, fürs shiften selber und SDI 
reinladen
+ einen für die falling_edge der spiClk, für um die Daten mal aufn Bus 
zu legen
+ einen rein kombinatorischen für diverse interne enable-flags
+ und noch einen richtigen synchronen, der eine State-Machine enthaltet 
und eben die asynchron empfangenen Daten in die synchronen Register 
schreibt, die  dann nachher noch verarbeitet werden.

Wie ich bemerkt habe, ist diese Vorgehensweise nicht das Optimum, da es 
(zumindest für mich noch) echt kompliziert ist den Überblick zu 
behalten. Vor allem aber hatte ich dann aber das Problem das man nicht 
in zwei Prozessen auf dasselbe Signal schreiben darf. Genau das bräuchte 
ich aber um im synchronen process die Daten, wenn die SPI nicht busy 
ist, in das Schieberegister zu schreiben. Sind shared variablen cool 
oder gehören die auch in die Kategorie "böser Code" (also wenn die 
wirklich geschützt sind)?

Was mir als Lösung einfiel war, da die Systemclock 100MHz und die 
SPI-Clock nur 16MHz hat, die SCLK zu samplen und so die Flankenwechsel 
mitzubekommen. Dann hätte ich nur mehr zwei Prozesse: einen von der 
rising_edge von der SCLK(spiclock) und einen mit dem Systemtakt.

@Lothar:
Danke für die Links. Ich kannte die zwar schon, aber schaue sie mir 
immer wieder gerne durch, da ich mehr und mehr nachvollziehen kann :) 
Zielplattform wird wahrscheinlich ein FPGA werden.

Wenn man zB sowas in der Art schreibt:
1
process (SpiClk,falling_edge_was_detected)
2
begin
3
  if(falling_edge_was_detected = '1')then
4
        there_was_a_falling_edge <= '0';
5
  elsif(falling_edge(SpiClk))then
6
        there_was_a_falling_egde <= '1';
7
  end if;
8
end process;
9
10
11
process (SpiClk,rising_edge_was_detected)
12
begin
13
-- dasselbe wie oben, aber halt rising_edge und anderen "reset" des FF
14
end process;
15
16
process (SysClk)
17
-- handle alles rund um die Buffer und Schieberegister...
18
end process
Meiner Ansicht ist das abgesehen, dass mit diesem "Mechanismus" bei 
komplexeren Aufgaben ein schnelleres Verwirren erreicht wird, der 
Vorteil, dass weniger Systemticks vergehen, als wenn man die SpiClk in 
einem Prozess absampled. Ist das so oder wieder mal 
epic-beginner-logic-fail?

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


Lesenswert?

Max schrieb:
> Ist das so oder wieder mal epic-beginner-logic-fail?
Ja.
Weil du wieder 2 "Takte" hast, die zueinander asynchron sind: den 
100MHz-Master-Takt und den SPI-Takt. Du wirst also auch mit trickreicher 
Umschreibung immer noch den Taktdomänenübergang vor dir haben. Und so 
einen Übergang bekommst du auch mit dem Prinzip "Sand in die Augen 
streuen" nicht weg.

Kurz: der SPI-Takt ist in deinem Design kein Takt. Deshalb steht er auch 
nicht hinter rising_edge oder falling_edge. Eine steigende oder fallende 
Flanke in diesem Signal (namens SPI-Takt) wird wie bei jedem anderen 
Signal auch nach dem Einsynchronisieren mit einem Schieberegister 
ermittelt:
1
signal spiclk_sr : std_logi_vector(2 downto 0);
2
:
3
spiclk_sr <= spiclksr(1 downto 0) & SpiClk when rising_edge(SysClk); -- das Schieberegister: Einsynchronisieren und Flanke(n) erkennen
4
:
5
process begin
6
  wait until rising_edge(SysClk);       -- es kann nur einen geben!
7
  if (spiclksr(2 downto 1) = "10") then -- fallende Flanke
8
     :
9
  end if;
10
  if (spiclksr(2 downto 1) = "01") then -- steigende Flanke
11
     :
12
  end if;
13
end process;

von Max (Gast)


Lesenswert?

Lothar Miller schrieb:
> Weil du wieder 2 "Takte" hast, die zueinander asynchron sind: den
> 100MHz-Master-Takt und den SPI-Takt. Du wirst also auch mit trickreicher
> Umschreibung immer noch den Taktdomänenübergang vor dir haben.

Ja, den Taktdomänenübergang den hab ich dann ja im Prozess mit der 
100MHz-Systemclock. Also wenn asynchron zu diesem mittels falling_- und 
rising_edge(spiclk) ein DFF gesetzt wird und dessen Ausgang dann im 
100MHz-Prozess abgefragt wird, dann erkenne ich das Problem nicht so 
deutlich. Ist das Problem oder mein Denkfehler, dass das asynchron 
getriggerte DFF auch metastabile Zustände haben kann und deshalb das 
nicht 100% korrekt im 100MHz-Takt übernommen wird?

Oder passt es dann doch, weil ja nur bei einer gewissen Schwelle das 
Flag there_was_edge_detected gesetzt wird und erst dann im 100MHz Takt 
wahrgenommen und über ein Rücksignal reseted wird?

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


Lesenswert?

Max schrieb:
> Ist das Problem oder mein Denkfehler, dass das asynchron
> getriggerte DFF auch metastabile Zustände haben kann
Nein, das wird es sicher nicht, denn der SpiClk ist zu seinen Daten ja 
synchron. Aber hier geht es nicht um metastabile Zustände
(davon wirst du bei 100MHz eh nichts merken, siehe 
http://www.lothar-miller.de/s9y/archives/41-Einsynchronisieren-von-asynchronen-Signalen.html 
und 
http://www.lothar-miller.de/s9y/archives/62-Testaufbau-Metastabilitaet.html), 
sondern um die Frage: was passiert, wenn dieser SPI-Clock das FF kurz 
vor der Systemtaktflanke setzt (und damit die Setup-Zeit eines FF in der 
100MHz-Domäne verletzt)?
Nach dem Lesen von 
http://www.lothar-miller.de/s9y/archives/64-State-Machine-mit-asynchronem-Eingang.html 
wird dir klar: nicht die Metastabilität ist dein Problem, sondern 
einfach die Laufzeit im FPGA. Dadurch kann es sein, dass diese kurz vor 
einem Systemtakt angekommene SpiClk Flanke nicht von allen beteiligten 
Elementen in der SysClk-Domäne gesehen wird und deshalb deine FSM Amok 
läuft (und: schon ein Zähler ist eine FSM).

Max schrieb:
> Wenn man zB sowas in der Art schreibt: ...
Das was du da vorgeschlagen hast, ist nichts anderes als das hier
http://www.lothar-miller.de/s9y/archives/19-Kurzer-Spike-in-Puls-umgewandelt.html
aber ohne das 2. Flipflop...  :-o

von Max (Gast)


Lesenswert?

Danke für die ausführliche Antwort.

Ja, vom Prinzip her ist das wie die Spikeerkennung ohne dem zweiten FF. 
Ich habe ja dann auch ein DFF im wirklich synchronen Prozess, das nur 
gesetzt wird wenn mir die Asynchronen eine Flanke detektiert haben. Wenn 
Metastabilität eh bei 100MHz unkritisch ist, dann wird falls die beiden 
Flanken, also spiclock und sysclock wirklich "schlecht zueinander" 
stehen, doch höchstens die Flanke von der Spiclock einen Takt später 
erkannt, was auch egal ist. Das reset-signal für das asynchrone DFF 
kommt aus dem synchronen Prozess und wird nur gecleared, wenn es 
ausgelesen und dann there_was_edge_detected gesetzt wurde. Oder kommts 
genau da zu Problemen, falls die Flanken ein unglückliches Timing haben? 
Meiner Ansicht nach nicht, weil diese Signale eigentlich implizit 
zusammenhängen, also mein synchroner Prozess wird nie erst so spät ein 
detection_flag clearen, dass eine SPI-Clk-Flanke verloren geht.

Was ich vorher meinte war nachstehender Code (um ggf Missverständnisse 
zu vermeiden):
1
process (SpiClk,falling_edge_was_detected)
2
begin
3
  if(falling_edge_was_detected = '1')then
4
        there_was_a_falling_edge <= '0';
5
  elsif(falling_edge(SpiClk))then
6
        there_was_a_falling_egde <= '1';
7
  end if;
8
end process;
9
10
11
process (SpiClk,rising_edge_was_detected)
12
begin
13
if(rising_edge_was_detected = '1')then
14
        there_was_a_rising_edge <= '0';
15
  elsif(rising_edge(SpiClk))then
16
        there_was_a_rising_egde <= '1';
17
  end if;
18
end process;
19
20
process (SysClk)
21
  if(there_was_a_rising_edge = '1')then
22
    spiClkCnt <= spiClkCnt + '1'; -- nur prinzipmäßig...
23
    -- usw
24
    rising_edge_was_detected <= '1';
25
  else
26
    rising_edge_was_detected <= '0';
27
  end if;
28
29
  if(there_was_a_falling_edge = '1')then
30
    -- lege Daten auf Bus
31
    falling_edge_was_detected <= '1';
32
  else
33
    falling_edge_was_detected <= '0';
34
  end if;
35
end process

Was ich aber nicht ganz verstehe, wenn ich mein Teil betrachte und den 
Testaufbau vom Lothar dann ist ja so, dass mein Signal ja nur von einem 
FF aus dem synchronen Prozess bewertet wird, daher ist meiner Meinung 
nach ein Laufzeitunterschied nicht gegeben (zu einem zweiten FF synchron 
zum SysTick). Aber wie Lothar schreibt: "Besser 2 FFs um auf Nummer 
sicher zu sein."... weil das Prinzip dann wirklich immer funktioniert, 
auch wenn mehrere FF ein asynchrones Signal einsynchronisieren.

Noch immer Denkfehler?

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


Lesenswert?

Max schrieb:
> process (SysClk)
>   if(there_was_a_rising_edge = '1')then
Eine kleine Korrektur vorab:
1
 process (SysClk) begin
2
   if rising_edge(SysClk) then  -- das hat gerade noch gefehlt  ;-)
3
     if(there_was_a_rising_edge = '1')then 
4
        spiClkCnt <= spiClkCnt + '1';


Max schrieb:
> dass mein Signal ja nur von einem FF aus dem synchronen Prozess
> bewertet wird
Eben nicht! Der nächste Zählerwert wird vom Systemtakt UND vom Enable 
(=there_was_a_rising_edge) UND vom aktuellen Zählerwert bestimmt. Und 
damit wirkt dein Enable auf ALLE Flipflops deines Zählers. Und wie breit 
ist der?

Und damit sieht das also so aus:
1
process (SpiClk,rising_edge_was_detected)
2
begin
3
  if(rising_edge_was_detected = '1')then 
4
        there_was_a_rising_edge <= '0';
5
  elsif(rising_edge(SpiClk))then           -- eine steigende Flanke zum Zeitpunkt t=99.9ns
6
        there_was_a_rising_egde <= '1';    -- sorgt dafür, dass dieses Enablesignal gesetzt wird.
7
  end if;
8
end process;
9
10
process (SysClk) begin
11
   if rising_edge(SysClk) then              -- der Takt kommt dann zum Zeitpunkt t=100ns (also 100ps später).
12
      if(there_was_a_rising_edge = '1')then -- Frage: ist dieses Enablesignal (there_was_a_rising_edge)
13
          spiClkCnt <= spiClkCnt + '1';     -- dann schon an allen Zähler-FFs stabil und gültig?

von Max (Gast)


Lesenswert?

Danke Lothar.

Ja, LOL... das hab ich gleich mal vergessen, also begin und so, aber 
gemeint so wie du es ausgebessert hast.

Zur Frage: ist dieses Enablesignal (there_was_a_rising_edge)dann schon 
an allen Zähler-FFs stabil und gültig?

Ich denke mir "egal", wenn nur der eine Zähler mitzählt, dann ist das 
Enablesignal (there_was_a_rising_edge) noch nicht bemerkt worden, und 
deshalb erst beim nächsten Systemtick high und erst dann ist das 
if-gültig und das flag wird gecleared. Verloren gehen tut nix und wenn 
wirklich nur an einer Stelle das Signal abgefragt wird, dann muss es 
doch egal sein? Bitte sag ja ,Lothar! ;)

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


Lesenswert?

Max schrieb:
> und wenn wirklich nur an einer Stelle das Signal abgefragt wird
Wenn es wirklich nur genau 1 Stelle ist, dann ist es das jetzt noch 
fehlende Synchronisations-Flipflop. Oder hat dein Zähler nur 1 Flipflop?

> Ich denke mir "egal", wenn nur der eine Zähler mitzählt...
Es geht nicht um "den einen Zähler", sondern darum, dass jedes einzelne 
Flipflop dieses einen Zählers einen falschen Zustand annehmen kann/wird. 
Und das bedeutet: dein Zähler zählt falsch. Stell dir mal vor, ein 
3-Bit-Zähler steht auf 0111. Mit dem nächsten Enable werden also die 
unteren 3 Bits zu 000 und das oberste gesetzt. Wenn aber jetzt das 
oberste Bit den Enable nicht/zu spät bekommt, dann werden die unteren 
auf 000 umschalten, das oberste aber NICHT! Und dann wird der neue 
Zählerstand 0000 statt 1000 sein... :-o

> Bitte sag ja ,Lothar! ;)
Kann ich schon. Hilft dir aber nicht. Glaub es oder probiers aus...  ;-)

von Max (Gast)


Lesenswert?

Ok, vielen Dank für Deine Hilfe.
Ich glaub es Dir und werde es im größeren Projekt so machen wie von Dir 
vorgeschlagen und dann für mich noch mal in einem Mini-Beispiel 
anschauen.

von Max (Gast)


Lesenswert?

Hallo.

Ich versteh das Einsynchronisierprinzip vom Lothar nicht
http://www.lothar-miller.de/s9y/categories/35-Einsynchronisieren

Krieg ich da nicht nur das asynchrone Signal 2 Takte verschoben zurück? 
Wo findet die das Einsychronisieren statt? Müsste man nicht das Signal 
"samplen" oder irgendwie vergleichen, wenn man wirklich sicher sein will 
dass alles synchron ist?
Das zweite FF hat nach dem 2. Takt doch den Wert des Ersten und wenn das 
Signal schlecht zum system-tick kam, dann steht im ersten FF von vorhin 
ein Mist und das Zweite kriegts weiter...
LOL,ich checks nicht.

:(

von berndl (Gast)


Lesenswert?

wenigstens mal jemand, der sich mit der Materie wohl wirklich befasst 
:o)

Angenommen, deine Chipclock ist >> als deine SPIclock (also 100MHz vs. 
10MHz oder so):

* Vergiss Metastabilitaet, sie wird bei dir normalerweise nie und nimmer 
auftreten
* Du kannst also im ersten Synchronisier-FF einen Wert eintakten, der 
evtl. die Setup/Hold-Zeit verletzt
* Da du dich um Metastabilitaet aber nicht kuemmerst, kannst du getrost 
davon ausgehen, dass das 2. FF dahinter ein sauberes und stabiles Signal 
sieht und auch eintaktet

-> Du wirst also eine Flanke sehen, die kann aber zeitlich um einen Takt 
(FPGA Takt) zu spaet kommen
-> Hinter der Flankenerkennung hocken jetzt Zaehler oder FSMs, die 
werden sicher ein stabiles Signal am Eingang haben und damit richtig 
funktionieren

von berndl (Gast)


Lesenswert?

PS: Ich hab' mir gerade Lothars Seite angesehen und kann mir da einen 
[Haarspaltmodus] nicht verkneifen:

Wenn du nur 2 FFs verwendest, dann kann dir bei Setup/Holdtime 
Verletzung folgendes passieren: Dein erstes FF hat eben nicht bei tH 
einen gueltigen Wert, sondern etwas spaeter (z.B. 100ps). Wenn du jetzt 
dieses und das 2. FF zur Flankenerkennung nimmst (also "01" bzw. "10"), 
dann verlierst du zum ansteuern deiner nachfolgenden Logik eben diese 
z.B. 100ps. Und das kann und wird dir der Timinganalyzer nicht melden, 
er weiss es einfach nicht.

Ganz sicher bist du, wenn du noch ein 3. FF einbaust und die FFs 2 und 3 
zur Flankenerkennung verwendest (also noch einen Takt Latency). Dann 
kann auch die Toolchain sicher damit umgehen.

PPS: Wegen der Metastabilitaet: Der Hersteller garantiert dir, dass ein 
FF innerhalb eines gewissen Taktes definitiv auf einen stabilen '0' oder 
'1' Wert geht. Metastabil waere, wenn das im naechsten Takt auch noch 
'oszillieren' wuerde. Und bei z.B. 100MHz hast du da normalerweise nie 
ein Problem

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


Lesenswert?

Max schrieb:
> Das zweite FF hat nach dem 2. Takt doch den Wert des Ersten und wenn das
> Signal schlecht zum system-tick kam, dann steht im ersten FF von vorhin
> ein Mist und das Zweite kriegts weiter...
Der Fachbegriff dazu heißt (wie schon erwähnt) Metastabilität. Und das 
gnaze ist bei heutigen FPGAs und Takten unter ca. 200MHz kein Thema. Bis 
zur nächsten Taktflanke ist das FF entweder wieder stabil high oder low. 
"Mist" hat also eine extrem kurze Halbwertszeit... ;-)

berndl schrieb:
> * Du kannst also im ersten Synchronisier-FF einen Wert eintakten, der
> evtl. die Setup/Hold-Zeit verletzt
Also jedes asynchrone externe Signal...

berndl schrieb:
> Ganz sicher bist du, wenn du noch ein 3. FF einbaust
Aber mein Code macht das doch:
1
signal insr  : std_logic_vector(2 downto 0); -- hier sind die 3 FFs
2
:
3
process begin
4
   wait until rising_edge(clk);
5
   -- Schieberegister
6
   insr <= insr(1 downto 0) & input;
7
end process;
8
9
process begin
10
   wait until rising_edge(clk);
11
   if (insr(2 downto 1) = "10") then    
12
      -- fallende Flanke von input
13
   end if;
14
   if (insr(2 downto 1) = "01") then 
15
      -- steigende Flanke von input
16
   end if;
17
end process;

> Wenn du nur 2 FFs verwendest
Ist da auf meiner HP noch irgendwo so eine Leiche?  :-/

von Max (Gast)


Lesenswert?

Mit dem ersten schieberegister speichert man doch ggf den metastabilen 
zustand. Zb zählerstand 1000 statt den wechsel von 1111 auf 0000. Wie 
wird durch zwei oder mehr FF ein falsch "eingefangener" wert durch im 
takt herumschieben besser? Falsch ist der zählerstand auch nach 4 FFs. 
Wisst ihr was ich mein?

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


Lesenswert?

Max schrieb:
> Mit dem ersten schieberegister speichert man doch ggf den metastabilen
> zustand.
Beim Frequenzen unter 200MHz ist beim nächsten Takt keines der Flipflops 
mehr in einem ungültigen Zustand. Und vor allem: ein Flipflop KANN 
keinen metastabilen Zustand SPEICHERN!

> Zb zählerstand 1000 statt den wechsel von 1111 auf 0000.
Wo kommt in einem Schieberegister ein Zähler vor? Ein Schieberegister 
sind Flipflops hintereinander. Da weiß das Vierte erst nach 3 Takten 
was vom Ersten. Beim Schieberegister gibt es keine direkte Beeinflussung 
des vierten FFs durch das erste. Beim Zähler schon...
Sieh dir mal den RTL-Schaltplan an:
http://www.lothar-miller.de/s9y/archives/52-Kompakte-Flankenerkennung.html
Wenn ich dort die FFs so benenne:
 A  B  C  D
       E  F
Dann sind die FFs A,B und E einfach nur hintereinander verdrahtet, und 
dann erst geht es in die weitere Schaltung...

> Wisst ihr was ich mein?
Nein.

von Max (Gast)


Lesenswert?

Danke für Eure Erklärmühen!

In meinem Design habe(werde haben) ich einen Zähler, der die die 
master-spi-clock zählt und sich entsprechend des Zähler standes auf den 
Bus hängt (TDMA). Ist der Wert erreicht bei dem die eigenen Daten gerade 
reingeshiftet wurde, lese ich diese Daten aus dem Schieberegister. Mit 
diesem Schieberegister meine ich aber nicht das oben beschriebene, 
sondern oben rede ich von dem Einsynchronisieren, das man anscheinend 
über zwei FF macht und für mich ein Schieberegister darstellt. Meine 
Statemachine lauft mit dem FPGA Takt, aber ein Zähler der für das 
Weiterschalten benötigt wird, zählt asynchrone Flanken.

>> Zb zählerstand 1000 statt den wechsel von 1111 auf 0000.
>Wo kommt in einem Schieberegister ein Zähler vor? Ein Schieberegister
>sind Flipflops hintereinander. Da weiß das Vierte erst nach 3 Takten
>was vom Ersten.
Ja.
Deswegen:
>>Ich denke mir "egal", wenn nur der eine Zähler mitzählt...
>Es geht nicht um "den einen Zähler", sondern darum, dass jedes einzelne
>Flipflop dieses einen Zählers einen falschen Zustand annehmen kann/wird.
>Und das bedeutet: dein Zähler zählt falsch. Stell dir mal vor, ein
>3-Bit-Zähler steht auf 0111. Mit dem nächsten Enable werden also die
>unteren 3 Bits zu 000 und das oberste gesetzt. Wenn aber jetzt das
>oberste Bit den Enable nicht/zu spät bekommt, dann werden die unteren
>auf 000 umschalten, das oberste aber NICHT! Und dann wird der neue
>Zählerstand 0000 statt 1000 sein...
Genau der Fall ist doch durch zwei FFs(2-bit-Schieberegister) 
hintereinander nicht besser geworden: das Auslese-FF vom synchronen 
Prozess hat dann den korrupten Wert des asynchronen Zählers, halt zwei 
Takte später. Es geht mir also nicht um die Metastabilität. Genau das 
verstehe ich nicht.

>> Mit dem ersten schieberegister speichert man doch ggf den metastabilen
>> zustand.
>Beim Frequenzen unter 200MHz ist beim nächsten Takt keines der Flipflops
>mehr in einem ungültigen Zustand. Und vor allem: ein Flipflop KANN
>keinen metastabilen Zustand SPEICHERN!
Ja, ich weiß. Blöd ausgedrückt. Ich meinte den falschen Zählerstand der 
praktisch gerade umschaltet.

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


Lesenswert?

Max schrieb:
> Ich meinte den falschen Zählerstand der praktisch gerade umschaltet.
Du musst natürlich auch so einen Zählerstand über ein "quasistatisches" 
Zwischenregister (am besten per Handshake) übergeben...

Denn sonst ist es ganz einfach: ein jedes einzelne deriner Bits ist 
asynchron zum "restlichen" FPGA und muß daher einsynchronisiert werden. 
Weil aber die Bits zusammengehören, müssen sie erst mal in der einen 
Domäne zusammen zwischengespeichert werden. Und danach kannst du ein 
zusätzliches Signal lossenden, das sagt "da wären wieder mal gültige 
Daten da".

von Max (Gast)


Lesenswert?

Ok, super! Danke Lothar!

Genau mit so einem Handshake kann ich es mir vorstellen, dass alles 
passt.
Wenn das ganze mal lauft, sag ich Bescheid... Wird aber noch dauern bis 
ich richtig anfangen werde. Zuerst noch ein paar kleine Übungsbeispiele, 
damit ich es kapier...
Mahlzeit!

von Max (Gast)


Lesenswert?

Hallo.

Also... lang is es her, aber es geht jetzt alles so wie ich es wollte.
Das Konzept wurde noch umgeändert, aber ich brauchte trotzdem 2 
Clockdomains.

Danke an die lieben "Thread-Freunde" -speziell an Lothar- für Ihre 
Antworten. Lang hat's gedauert bis ich es endlich überrissen habe was 
Ihr mir sagen wolltet.

Beste Grüße, Max

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.