Forum: FPGA, VHDL & Co. Einsynchronsieren mit 2 FFs


von Nik N. (neusser)


Lesenswert?

Hallo,

kann mir bitte jemand erklären wie man asynchrone Signale richtig 
einsynchronisiert? (z.B. ein I/O Signal)
Ich kenne bisher diese 2 Varianten :

Beispiel:
                FPGA
                 |
sig_async  -->   |   -> sig_sync
                 |


Variante (1) - meine bisherige Taktik:
sig_sync übernimmt nur einen neuen Wert (bei steigender Taktflanke), 
wenn sig_async für 2 Takte gleich ist.


Variante (2)
Oft habe ich folgendes gelesen (ich glaube u.a. hier im Forum):
sig_async --> FF_1 --> FF_2 -> sig_sync

Was genau bewirken die beiden in Serie geschalteten FFs?

Geht es darum, dass sich FF_1 theoretisch in einem metastabilen Zustand 
befinden kann (Spike auf sig_async zur Taktflanke). Damit würde zwar 
FF_2 u.U. kurzzeitig eine Signaländerung erkennen. Aber da die 
Setup&Hold Zeiten nicht eingehalten werden, liegt an sig_sync ein 
sauberes taktsynchrones Signal (ohne Spike) an.
Ist das richtig oder bin ich total auf dem Holzweg?

Danke für alle Kommentare,
Nik

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


Lesenswert?

> Geht es darum, dass sich FF_1 theoretisch in einem metastabilen
> Zustand befinden kann (Spike auf sig_async zur Taktflanke).
Das muß keineswegs ein Spike sein, sowas passiert dir theoretisch (und 
praktisch) sogar, wenn das Signal ein einziges Mal den Zustand wechselt.
Es reicht einfach aus, wenn die Setup oder die Hold-Zeit verletzt wird.

Offenbar verwendest du das externe Signal im 1. Fall als Reset oder 
Enable für einen Zähler. Allerdings ist es dadurch trotzdem ein 
asynchrones Signal!! (Lass doch mal VHDL-Code zur Variante 1 sehen ;-)

Der eigentliche Witz ist der, dass das asynchrone externe Signal in 
einer umfangreichen State-Machine auf viele FFs geht. Und durch 
unterschiedliche Laufzeiten im FPGA sehen diese FFs teils eine 0 und 
teils eine 1. So kann es passieren, dass die SM falsch 
weiterschaltet/reagiert.

Absolut kampferprobt und z.B. weitverbreitet in Mikrocontrollern 
eigesetzt ist die Variante 2.
1
       input  : in   STD_LOGIC;
2
:
3
signal syncinput : std_logic;
4
signal inputsr   : std_logic_vector(2 downto 0);
5
:
6
   process begin
7
      wait until rising_edge(clk);
8
      inputsr <= inputsr(1 downto 0) & input;
9
   end process;
10
   syncinput <= inputsr(2);
Zudem lässt diese Schieberegisterlösung sich ganz leicht in eine 
Flankenerkennung umbauen/erweitern. Siehe
http://www.lothar-miller.de/s9y/archives/3-Tastenentprellung-mit-Schieberegister.html
Ich bin zu faul das zu kopieren ;-)

von Jan M. (mueschel)


Lesenswert?

@Lothar:
Diese Variante ist auf Xilinx-FPGAs aber in gewisser Weise gefährlich: 
Die Synthese implementiert ein Schieberegister in einer LUT, dadurch 
wird das FF im IO-Buffer nicht benutzt, und man hat keine festen 
setup-to-clock Zeiten, das kann schnell schief gehen, wenn man z.B. zwei 
Signale parallel einlesen will, die dann unterschiedliche Laufzeiten 
haben.
Deswegen sollte man entweder per Constraints inputsr(0) in ein IO-FF 
zwingen oder - häufig die einfachere Lösung - durch zuweisen eines 
Reset-Werts an inputsr erzwingen, dass es in FF umgesetzt wird.

Für das Entprellen von Tasten stellt das natürlich kein Problem dar.

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


Lesenswert?

> keine festen setup-to-clock Zeiten, das kann schnell schief gehen,
> wenn man z.B. zwei Signale parallel einlesen will, die dann
> unterschiedliche Laufzeiten haben.
Hmmm, wenn ich parallele Signale einlesen will, brauche ich sowieso eine 
andere Validierungsart. Ich werde mich auch wenn das FF im IO-Treiber 
liegt, nicht darauf verlassen können, das jede Flanke gleichzeitig 
einsynchronisiert wird. I.A. werden also die Daten stabil anliegen, 
anschliessend das Write-Signal deaktiviert werden.

> wird das FF im IO-Buffer nicht benutzt, und man hat
> keine festen setup-to-clock Zeiten,
Richtig, man muß sich nicht unnötig Probleme machen.. ;-)

> oder - häufig die einfachere Lösung - durch zuweisen eines
> Reset-Werts an inputsr erzwingen, dass es in FF umgesetzt wird.
Oder mehrere Bits des SR abfragen. Ich mache für (langsame) asynchrone 
Signale zur Spikeunterdrückung gerne den Vergleich über das ganze 
Schieberegister:
1
   process begin
2
      wait until rising_edge(clk);
3
      inputsr <= inputsr(1 downto 0) & input;
4
      if (inputsr="000") then syncinput <= '0'; end if;
5
      if (inputsr="111") then syncinput <= '1'; end if;
6
   end process;

von Ben Richards (Gast)


Lesenswert?

@ Nik N.
Die erste Variante solltest du schnell wieder vergessen.

>durch zuweisen eines
>Reset-Werts an inputsr erzwingen, dass es in FF umgesetzt wird.
Das ist nicht notwendig. Sobald auf die Zwischenwerte zugegriffen wird, 
werden automatisch FF's verwendet.

von Nik N. (neusser)


Lesenswert?

Hallo,
danke für die ganzen Antworten, aber das muss ich jetzt erstmal 
sortieren.

@L. Miller:
Variante (1) hätte ich bisher immer so implementiert.
1
process(clk)
2
if rising_edge (clk) then
3
  sig_tmp <= sig_async;
4
  if sig_tmp=sig_async then
5
     sig_sync<=sig_async;
6
  else
7
     sig_sync<=sig_sync;
8
  end if;
9
end if;


Variante (3):
Die eine deiner Variante, macht im Prinzip das gleiche, nur ohne 
Latches, oder?
1
process begin
2
      wait until rising_edge(clk);
3
      inputsr <= inputsr(1 downto 0) & input;
4
      if (inputsr="000") then syncinput <= '0'; end if;
5
      if (inputsr="111") then syncinput <= '1'; end if;
6
end process;

Variante (4):
Wenn ich Jan M. richtig verstehe werden hier gar keine seriell 
verschalteten FFs generiert, oder?
1
process begin
2
  wait until rising_edge(clk);
3
  inputsr <= inputsr(1 downto 0) & input;
4
end process;
5
syncinput <= inputsr(2);


Dann meine Fragen:
a) Wie schaut denn dann eine richtige Implementierung von Variante 2 
aus? (sig_async -> FF -> FF ->sig_sync)
2) Was bewirken die beiden FFs dann im Detail?

Mir scheint, es gibt einige verschiedene Varianten dieses Problem zu 
lösen. Die Varianten unterscheiden sich in Details bei der 
Implementierung die ja scheinbar durchaus wichtig sind.

Grüße,
Nik

von ope (Gast)


Lesenswert?

lkmiller:
>> Hmmm, wenn ich parallele Signale einlesen will, brauche ich sowieso eine
andere Validierungsart.

ich hätte einfach dieses über einen vector gelöst, sprich diese 
"single-line-sync"-Lösung parallelisiert. Wie würdest Du es machen?

Grüße
Olaf

von Ben Richards (Gast)


Lesenswert?

>Dann meine Fragen:
>a) Wie schaut denn dann eine richtige Implementierung von Variante 2
>aus? (sig_async -> FF -> FF ->sig_sync)
>2) Was bewirken die beiden FFs dann im Detail?

Sie testen das Signal auf einen stabilen (gültigen) Pegel. Mit einem FF 
würdest du das nur theoretisch hinbekommen. Dazu testet man die 
FF-Ausgänge auf gleiche Pegel.

von Klaus F. (kfalser)


Lesenswert?

@Nik

Der ganze Grund für die Geschichte ist, man das Eingangsignal eines FF 
nicht ändern darf, kurz bevor (Setup-Zeit) und kurz nach (Hold Zeit) der 
Taktflanke.
Bei einem Signal von außen, das nichts mit dem Takt im CPLD/FPGA zu tun 
hat, kann man das aber nie garantieren, man muß also damit rechnen dass 
es passiert.
Das Problem ist nun, dass in einer komplexen Schaltung das externe 
Eingangssignal nun auf mehrere FFs gleichzeitig geht (z.B. bei einer 
State Machine). Wenn nun das Signal sich während der Taktflanke ändert, 
kommt es vor, dass einige FF das Signal übernehmen, und andere nicht. 
Das ergibt eine Fehlfunktion der Schaltung.
Weiters kann es passieren, dass ein FF metastabil wird, d.h. der Ausgang 
ist nicht nach der spezifizierten Durchlaufzeit stabil, sondern braucht 
länger, oszilliert usw. Dieser metastabile Zustand wird nach einer 
bestimmten Zeit zur Ruhe, die Dauer des Zustands ist zufallig, der 
Ausgang am FF auch.

Die Abhilfe ist das Synchronisieren : Das externe Signal kommt in das 
FPGA nur über eine einziges FF, dieses kann dann kippen oder nicht. Wenn 
dieses FF metastabil wird, dann betrifft es den Eingang des nächsten FF, 
dieses schaltet aber erst wieder nach der Taktperiode. Das erste FF hat 
also eine ganze Taktperiode Zeit, um den metastabilen  Zustand zu 
verlassen. Bei den heutigen FPGAs ist die Wahrscheinlichkeit, dass das 
erste FF dann noch instabil ist, extrem gering. Nach der klassischen 
Variante schaltet man noch ein FF nach und wiederholt das Spiel. Dann 
werden die Wahrscheinlichkeiten noch kleiner.

Deshalb zu deinen Varianten :
- Die Variante (1) ist unsinnig kompliziert, obwohl sie nicht 
wirkungslos ist.
Das hängt damit zusammen dass das asynchrone Signal über ein gemeinsames 
FF läuft, die Synchronisierung ist einstufig.
- Die Variante (3) ist OK, zusätzlich hast Du ein Tiefpassfilter. Die 
Schaltung hat eine Verzögerung von 3-4 Takten, und setzt voraus das das 
Eingangssignal lansam gegenüber der Taktfrequenz ist.
- Variante (4) erzeugt natürlich seriell verschaltete FFs, wieso auch 
nicht.

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


Angehängte Dateien:

Lesenswert?

1
if rising_edge (clk) then
2
  sig_tmp <= sig_async;
3
  if sig_tmp=sig_async then
4
     sig_sync<=sig_async;
5
  else
6
     sig_sync<=sig_sync;
7
  end if;
8
end if;
Diese Variante geht schief, es wird nur eine FF-Stufe implementiert :-o
Nur das 2. FF ist wirklich zur Synchronisation da (Bild).
Das andere FF und der MUX davor ist nur großes Brimborium.

> Wenn ich Jan M. richtig verstehe werden hier gar keine seriell
> verschalteten FFs generiert, oder?
Doch, aber diese FFs werden (platzsparend) als Schieberegister in eine 
LUT gepackt. Wenn du nur asynchrone Signale (Taster, RS232, ...) 
verarbeitest, ist das keine Einscharänkung. Wenn du aber schnelle 
asynchrone Signale verarbeiten willst, die zueinander in zeitlichem 
Bezug stehen, dann ist es besser, das FF im IOB mitzubenutzen.


> über einen vector gelöst, sprich diese "single-line-sync"-Lösung
> parallelisiert. Wie würdest Du es machen?
Wenn du z.B. 8 Asynchrone Eingänge hast, dann brauchst du (mindestens) 
16 FFs, dass alles hübsch einsynchronisiert ist. Ob du dann schreibst:
1
  Input : in std_logic_vector(7 downto 0);
2
  :
3
  signal ffA : std_logic_vector(7 downto 0);
4
  signal ffB : std_logic_vector(7 downto 0);
5
  :
6
  process begin 
7
    wait until rising_edge(clk);
8
    ffA <= Input;
9
    ffB <= ffA;
10
  end process;
oder
1
  InputZ : in std_logic;
2
  InputY : in std_logic;
3
  InputX : in std_logic;
4
  InputW : in std_logic;
5
  :
6
  signal srZ : std_logic_vector(1 downto 0);
7
  signal srY : std_logic_vector(1 downto 0);
8
  :
9
  process begin 
10
    wait until rising_edge(clk);
11
    srZ <= srZ(0)&Input0;
12
    srY <= srY(1)&Input0;
13
    srX <= srX(2)&Input0;
14
    :
15
  end process;
das ist "nur" eine Frage, was schöner aussieht. Wenn alle Signale 
voneinander unabhängig sind, ist Variante 2 schöner. Wenn es ein Bus 
ist, eher Variante 1.
Aber bei einem parallelen Bus ist es wie gesagt oft sinnvoll, eine 
andere Validierungs-Art zum einsynchronisieren zu verwenden.

von ope (Gast)


Lesenswert?

jetzt aber: und welche? hast Du dazu auch ein Bsp.?

Grüße
Olaf

von Klaus F. (kfalser)


Lesenswert?

Einen Bus asynchron zu einem FPGA zu führen ist eh meistens eine 
schlechte Idee, kommt aber leider vor, habe ich auch schon gemacht.
Es geht dabei nur darum, die Daten zu einem Zeitpunkt abzutakten an dem 
diese stabil sind.
Dazu hat jeder Bus ein einzelnes Signal (RD, WR oder eine anderes 
Strobe), welches dies signalisiert.
Dieses eine Signal wird synchronisert und auf den bestimmten Pegel 
gewartet. Da die Synchronisierung vielleicht eine Zeitverzögerung 
erzeugt, können die Daten am Bus schon vorbei sein. In diesem Fall muß 
man diese durch zusätzliche FF Ketten der Datensignale ausgleichen.

von Thomas R. (Firma: abaxor engineering) (abaxor)


Lesenswert?

Jan M. wrote:
> @Lothar:
> Diese Variante ist auf Xilinx-FPGAs aber in gewisser Weise gefährlich:
> Die Synthese implementiert ein Schieberegister in einer LUT, dadurch
> wird das FF im IO-Buffer nicht benutzt,

So allgemein kann man das nicht sagen. Ein SRL16 hat nur zwei Ausgänge, 
darum ist es für eine seriell-parallel-Wandlung mit mehr als zwei 
parallen Ausgängen nicht geeignet. Hier wird es wohl verwendet werden.


Tom

von Jan M. (mueschel)


Lesenswert?

@Thomas:
Ja, alles was von der einfachen Beschreibung "vorne rein, hinten raus" 
abweicht kann nicht in Schieberegister gepackt werden - Deswegen auch 
mein Vorschlag mit den Resets; jeder andere parallele Zugriff auf 
mehrere Bits funktioniert natuerlich auch oder man zwingt die Synthese 
durch Attribute oder Constraints dazu, die FF zu behalten oder IO-FF zu 
benutzen - es gibt viele Moeglichkeiten, aber die einfachste und 
direkteste beinhaltet diese Falle, deswegen meine "Warnung".

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


Lesenswert?

>> Aber bei einem parallelen Bus ist es wie gesagt oft sinnvoll, eine
>> andere Validierungs-Art zum einsynchronisieren zu verwenden.
> jetzt aber: und welche? hast Du dazu auch ein Bsp.?
Klaus Falser hat es schon geschreiben: es gibt für parallele Busse 
üblicherweise ein zusätzliches Steuersignal, das anzeigt, wenn die Daten 
gültig (und stabil) sind. Nur dieses eine Signal muß synchronisiert 
werden, dann sind die Setup-Zeiten für die entsprechenden FFs erfüllt.

Ich würde sogar noch weitergehen, und z.B. ein Write-Signal als lokalen 
Takt die Daten einlesen lassen, und anschliessend mit den gespeicherten 
Daten weiterarbeiten.
1
   daten : in STD_LOGIC_VECTOR(7 downto 0);
2
   write : in STD_LOGIC; -- fallende Flanke --> Daten gültig
3
   clk   : in STD_LOGIC;
4
  :
5
  :
6
   dasync : STD_LOGIC_VECTOR(7 downto 0);
7
   dsync : STD_LOGIC_VECTOR(7 downto 0);
8
   wrsr : STD_LOGIC_VECTOR(2 downto 0);
9
  :
10
  :
11
   process begin
12
      -- Daten von extern mit write-Impuls übernehmen
13
      wait until falling_edge(write);  
14
      dasync <= daten;
15
   end process;
16
17
   process begin
18
      -- gespeicherte Daten synchron weitergeben.
19
      wait until rising_edge(clk);
20
      wrsr <= wrsr(1 downto 0) & wr; -- Schieberegister
21
      if(wrsr="100") then -- fallende Flanke
22
         dsync <= dasync;
23
      end if;
24
   end process;
Dabei sollte der FPGA-Takt natürlcih so schnell sein, dass nicht beim 
Synchronisieren schon der nächste Schreibzyklus beendet wird.

von Alter Hase (Gast)


Lesenswert?

>Diese Variante ist auf Xilinx-FPGAs aber in gewisser Weise gefährlich:
>Die Synthese implementiert ein Schieberegister in einer LUT, dadurch
>wird das FF im IO-Buffer nicht benutzt, und man hat keine festen
>setup-to-clock Zeiten, das kann schnell schief gehen, wenn man z.B. zwei
>Signale parallel einlesen will, die dann unterschiedliche Laufzeiten
>haben.

Ist das nicht bei asynchronen Signalen egal? Das FF ist zwar zum 
Nulltarif, aber es stört das einsynchronisieren nicht. "Parallele" 
Signale bekommst du mit Synchronisierstufen eh nicht sauber eingetaktet, 
braucht es schon eine Fifo.

von ope (Gast)


Lesenswert?

das Shift register sollte bestimmt das write Signal verwenden, also:
1
.
2
.
3
.
4
process begin
5
   -- gespeicherte Daten synchron weitergeben.
6
   wait until rising_edge(clk);
7
   wrsr <= wrsr(1 downto 0) & write; -- Schieberegister
8
   if(wrsr="100") then -- fallende Flanke
9
      dsync <= dasync;
10
   end if;
11
end process;

Korrekt?

Grüße
Olaf

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


Lesenswert?

> Korrekt?
Ja.

von Nik N. (neusser)


Angehängte Dateien:

Lesenswert?

Hallo,

jetzt sind ja noch einige Beiträge zusammen gekommen.
Alles zum Thema Bussynchronisieren würde ich später gerne in einem 
anderen Thread diskutieren damit dieser hier nicht zu unübersichtlich 
wird

@Klaus Falser: Danke für das Wie und Warum. Das ist jetzt klar!

Im Prinzip gibt es dann verschiedene Wege um eine 2- oder mehrstufige FF 
Stufe zu beschreiben. Man muss nur überprüfen ob die Synthese auch 
tatsächlich 2 FFs generiert und nicht nur eine wie bei meiner Variante 1
Richtig?


>> Wenn ich Jan M. richtig verstehe werden hier gar keine seriell
>> verschalteten FFs generiert, oder?
>Doch, aber diese FFs werden (platzsparend) als Schieberegister in eine
>LUT gepackt.

Die genauen Unterschiede oder Hintergründe zwischen der Variante mit 2 
FFs oder einem Schieberegister (LUT)  ist aber immer noch nicht ganz 
klar.
1
signal sig_tmp1 : STD_LOGIC;
2
signal sig_tmp2 : STD_LOGIC_VECTOR(1 downto 0);
3
4
----------------------------------------
5
-- 2 FFs
6
----------------------------------------
7
process(CLK)
8
begin
9
   if rising_edge(CLK) then
10
      sig_tmp1 <=sig_async1;
11
      sig_sync1<=sig_tmp1;
12
   end if;
13
end process;
14
15
16
----------------------------------------
17
-- Schieberegister
18
----------------------------------------
19
process(CLK)
20
begin
21
   if rising_edge(CLK) then
22
      sig_tmp2 <= sig_tmp2(0) & sig_async2;
23
   end if;
24
end process;
25
sig_sync2 <= sig_tmp2(1);

Die synthetisierte FF Stufe ist klar. Aber was bei der LUT Version 
passiert, verstehe ich nicht ganz. Das LUT arbeitet doch genauso 
clocksynchron, richtig? (Siehe Anhang)

Danke für eure Antworten,
Nik

von Jan M. (mueschel)


Lesenswert?

>Die synthetisierte FF Stufe ist klar. Aber was bei der LUT Version
>passiert, verstehe ich nicht ganz. Das LUT arbeitet doch genauso
>clocksynchron, richtig?

Der Unterschied ist die Lage im FPGA: Direkt am Input befindet sich ein 
spezielles FF fuer genau den Zweck, hereinkommende Signale zu 
synchronisieren. Die LUT muss aber irgendwo in der restlichen Logik des 
FPGAs untergebracht werden, so dass die Signallaufzeiten vom Pin zu 
dieser LUT stark schwanken koennen je nach Design.

(Bei Tastern ist das natuerlich voellig unerheblich, bei schnellen 
Signalen die synchron zu irgendeinem Takt von aussen sind, kann das aber 
grosse Probleme verursachen)

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


Lesenswert?

> Das LUT arbeitet doch genauso clocksynchron, richtig? (Siehe Anhang)
In diesem Bild siehst du nicht, wie die FFs tatsächlich realisiert 
werden. Was dur in diesem Plan siehst, ist nur, was die Synthese aus 
deiner Beschreibung gemacht hat.
Abhängig von den Einstellungen in Translate und P&R können daraus 
einzelne FFs werden oder das Ganze könnte in eine LUT gepackt werden und 
zudem das FF im IOB verwendet werden oder nicht.

> bei schnellen Signalen die synchron zu irgendeinem Takt von aussen sind,
> kann das aber grosse Probleme verursachen
Und dann sind Timing-Constraints unabdingbar...


BTW:
> Das LUT
die Look-Up-Tabelle --> die LUT

von Klaus F. (kfalser)


Lesenswert?

Die Diskussion über LUT, SRL und FF ist unsinnig und verwirrt nur.
Wichtig ist, dass eine Kette von 2 oder mehrern FFs erzeugt wird.

Das 1. FF in ein IOB zu legen, könnte höchstens den Vorteil haben, dass 
diese vielleicht in Bezug auf Metastabilität optimiert sind, aber das 
ist eine Hypothese.

Es geht bei dieser Diskussion ja über asynchrone Signale von außen. 
Irgendwelche Timing-Constraints sind deshalb komplett unsinnig. Damit 
will man je erreichen, dass 2 oder mehrere verschieden Pfade in den 
Laufzeiten übereinstimmen.
Aufgrund der Metastabilität kann man aber 2 Signale NIEMALS parallel 
eintakten, weil es ganau die Eigenschaft der Metastabiliät ist, dass der 
Ausgang des FFs kippen kann oder nicht. Es kann deshalb immer vorkommen, 
dass ein Port das jeweilige Eingangsignal einen Takt früher sieht als 
der andere.

von Nik N. (neusser)


Lesenswert?

Ok,

bei der direkten FF Beschreibung werden also defintiv 2 FF erzeugt.
1
process(CLK)
2
begin
3
   if rising_edge(CLK) then
4
      sig_tmp1 <=sig_async1;
5
      sig_sync1<=sig_tmp1;
6
   end if;
7
end process;

bei der Beschreibung mittels Schieberegister können entweder FF oder 
LUTs Verwendung finden.
1
process(CLK)
2
begin
3
   if rising_edge(CLK) then
4
      sig_tmp2 <= sig_tmp2(0) & sig_async2;
5
   end if;
6
end process;
7
sig_sync2 <= sig_tmp2(1);



Kann man dann folgendes Fazit unter das Thema ziehen:

1) Die Problematik (Warum und Weshalb) hat Klaus Falser sehr schön 
erklärt (24.02.2009 09:42)
2) Meine Variante 1 erzeugt nur eine 1-stufige Synchronisierung, was 
nicht ausreichend ist
3) Zur Synchronisierung werden mindestens 2 FF benötigt. Beide 
Beschreibungen (siehe dieser Beitrag) mit 2FF oder Schieberegister sind 
in Ordnung

von Boris (Gast)


Lesenswert?

Zum synchronisieren eines std_logic sind beide Wege richtig...

Aber wie willst du es machen wenn du ein std_logic_vector 
synchronisieren willst? Dann bräuchtest du für die Version mit dem 
Schieberegister ein Zweidimensionales;) => Für die Synchronisation eines 
std_logic_vectors nehme ich deine erste Version (natürlich entsprechend 
angepasst).

Hier mal schnell skizziert (will keine neue Diskussion anfangen - nur 
falls das jemand liest der einen Vector synchronisieren will):

Port signal : std_logic_vector
signal signal_1 : std_logic_vector
signal signal_2 : std_logic_vector

process(CLK)
begin
   if rising_edge(CLK) then
      signal_1 <=sigal;
      signal_2<=signal_1;
   end if;
end process;

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


Lesenswert?

> bei der direkten FF Beschreibung werden also defintiv 2 FF erzeugt.
Nein, wenn keine der Zwischenstufen (sig_tmp1) verwendet wird, kommt das 
in eine LUT. So schlau sind die Tools ;-)

von Panzer H. (panzer1)


Lesenswert?

Boris wrote:
> Port signal : std_logic_vector
> signal signal_1 : std_logic_vector
> signal signal_2 : std_logic_vector
>
> process(CLK)
> begin
>    if rising_edge(CLK) then
>       signal_1 <=sigal;
>       signal_2<=signal_1;
>    end if;
> end process;

Gefährlich, weil ja wegen unterschiedlicher Signallaufzeiten, die 
Signale teilweise um einen Takt verzögert ausgegeben werden. Besser: 
Handshake...
Andere Ideen??

von lkmiller (Gast)


Lesenswert?

> Gefährlich, weil ja wegen unterschiedlicher Signallaufzeiten, die
> Signale teilweise um einen Takt verzögert ausgegeben werden.
Ich wollte damit nicht einen parallelen Bus synchron in das FPGA 
bekommen. Das klappt so niemals!
Ich wollte nur z.B. 8 paralell angeschlossene Taster einsynchronisieren. 
Und muß durch die Vektor-Schreibweise nicht jede Strippe einzeln in die 
Hand nehmen. Jedes dieser Eingangssignale ist also asynchron sowohl zum 
Takt wie auch zu den anderen Signalen.

von Nik N. (neusser)


Lesenswert?

Hallo,

damit dieser Thread nicht zu unübersichtilch wird, habe ich die 
Beitraege die das Synchronisieren von STD_LOGIC_VECTORen bzw. parallelen 
Bussignalen betreffen in einen neuen Thread gepackt:
Beitrag "Einsynchronisieren von STD_LOGIC_VECTORen"

Weitere Kommentare zu diesem Thread hier, sind natürlich noch weiterhin 
sehr willkommen.

gruß,
Nik

von Alter Hase (Gast)


Lesenswert?

>Das 1. FF in ein IOB zu legen, könnte höchstens den Vorteil haben, dass
>diese vielleicht in Bezug auf Metastabilität optimiert sind, aber das
>ist eine Hypothese.


Hab ich doch mal für einen V5-3 die Setup/Holdzeiten am IIO-FF und am 
SRL nachgeschaut:

SRL    1.03/0.26   ns
IO-FF  0.39/-0.12  ns


Damit ist für das SRL der "böse Teil" der Taktperiode länger.

MfG

von Jonas (Gast)


Lesenswert?

Für was steht denn eigentlich SRL ?

von Alter Hase (Gast)


Lesenswert?

> Für was steht denn eigentlich SRL ?

Wenn man die LookUpTable (LUT) in Xilinx-FPGA's in dem Modus 
Schieberegister (Shift Register) verwendet, nennt Xilinx das SRL16 Macro 
(vor Virtex5). wofür das L steht ist unbekannt (vielleicht length 16 
(um, verwechslungen mit SR als Set/Reset FlipFlop zu vermeiden?)). Beim 
V6 mit breiteren LUT wird das Schieberegister dann auch tiefer als 16.

MfG, AH

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.