www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Werte werden oftmals nicht übernommen


Autor: guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

und das nächste Problem. Ich hab zwei Prozesse am laufen, der eine 
reagiert auf positive, der andere auf negative Flanken. Nun habe ich 
öfter den Fall das ein if-Zweig der Prozesse durchlaufen wird aber nicht 
alle Signale gesetzt werden.

Da ich jetzt keinen Webspace zur verfügung haben, kann ich die ChipScope 
Ergebnisse leider nicht zeigen, versuche aber das Verhalten an einem 
Beispiel klar zu machen.

Beispiel: Im "FALLING_TX.." Prozess wird in "if(LAST_SHIFT_VALUE = '0' 
and DATA_CLK = '1') then ...." gewechselt, allerdings wird lediglich 
"USE_FALLING_VALUE <= '1';" übernommen, "FALLING_VALUE <= SERIAL_IN;" 
hingegen wird nicht ausgeführt. Beim nächsten Einstieg in den if-Zweig 
wird dann auch FALLING_VALUE richtig gesetzt.

Solch ein Verhalten ist sehr oft vorhanden, allerdings nicht immer. Kann 
es sein das es sich nicht verträgt, wenn man Prozesse die auf 
unterschiedliche Flanken reagieren, von einander abhängig macht?

(Asynchroner Reset wird noch ersetzt und Vectoren für die 
Flankenerkennung eingeführt um es übersichtlicher zu gestalten, daher 
bitte auf das wesentliche Bezug nehmen)

FALLING_TX_CLK_SYNC : process(CLK_SYS, RST)
begin  
   if(RST = '1') then
      LAST_FALLING_VALUE <= '1';  
   elsif(CLK_SYS'event and CLK_SYS = '0') then
      if(LAST_SHIFT_VALUE = '0' and DATA_CLK = '1') then
         USE_FALLING_VALUE <= '1';
         FALLING_VALUE <= SERIAL_IN;
      else
         USE_FALLING_VALUE <= '0';
      end if;
         LAST_FALLING_VALUE <= DATA_CLK;
      end if;  
end process;

RISING_TX_CLK_SYNC : process(CLK_SYS, RST)
begin  
   if(RST = '1') then
      SHIFT_EN <= '0';
      LAST_SHIFT_VALUE <= '1';    
   elsif(CLK_SYS'event and CLK_SYS = '1') then
      if(LAST_FALLING_VALUE = '0' and DATA_CLK = '1') then
         SHIFT_EN <= '1';
         SHIFT_VALUE <= SERIAL_IN;
      elsif(USE_FALLING_VALUE = '1') then
         SHIFT_VALUE <= FALLING_VALUE;
         SHIFT_EN <= '1';
      else
         SHIFT_EN <= '0';
      end if;
         LAST_SHIFT_VALUE <= DATA_CLK;
      end if;
end process;


Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
guest schrieb:
> Solch ein Verhalten ist sehr oft vorhanden, allerdings nicht immer.
Das deutet auf unzureichendes Einsynchronisieren von externen 
(asynchronen) Signalen hin...

> Kann es sein das es sich nicht verträgt, wenn man Prozesse die auf
> unterschiedliche Flanken reagieren, von einander abhängig macht?
Es ist infach nur unschön. Denn damit verdoppelst du implizit die 
Taktfrequenz deines Designs...

> Ich hab zwei Prozesse am laufen, der eine
> reagiert auf positive, der andere auf negative Flanken.
Wozu?
Welche Frequenz hat dein SYS_CLK?
Welche der DATA_CLK?


BTW: von diesen ganzen großgeschriebenen Namen kriegt man ja die Krätze 
ans Auge... :-/

Autor: guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das deutet auf unzureichendes Einsynchronisieren von externen
> (asynchronen) Signalen hin...

Ich habe im Modul nur zwei externe (asynchrone Signale), zum einen 
DATA_CLK, zum anderen SERIAL_IN. Liegt hier "LAST_SHIFT_VALUE = '0' and 
DATA_CLK = '1'" schon ein dickes Problem? Also wenn ich DATA_CLK direkt 
nutze ohne es vorher zu speichern um anschließend andere FF's mit dem 
Wert zu beschreiben?


> Wozu?
> Welche Frequenz hat dein SYS_CLK?
> Welche der DATA_CLK?

SYS_CLK = 16 Mhz
DATA_CLK im ungünstigsten Fall 8 Mhz wodurch ich nicht mehr sicher mit 
der SYS_CLK die DATA_CLK eintakten kann. Daher möchte ich zu jeder 
Flanke (steigend und fallend) den aktuell anliegenden DATA_CLK Wert 
abgreifen.


> BTW: von diesen ganzen großgeschriebenen Namen kriegt man ja die Krätze
> ans Auge... :-/

Naja das wurde im Reichardt/Schwarz (Du kennst es) so empfohlen. 
Allerdings mit der ungefähren Begründung "Es hat sich so 
eingebürgert..", wenn ich mich recht erinnere.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
guest schrieb:
> SYS_CLK = 16 Mhz
> DATA_CLK im ungünstigsten Fall 8 Mhz
Wenn du ein FPGA hast: nimm einen DCM und mach aus den 16MHz erst mal 
eine höhere Frequenz. Das macht dir das Leben unglaublich 
einfach(er)....

> DATA_CLK im ungünstigsten Fall 8 Mhz wodurch ich nicht mehr sicher mit
> der SYS_CLK die DATA_CLK eintakten kann.
Da hast du also eine synchrone externe Schnittstelle (evtl. sogar SPI?), 
die dir Daten sendet? Dann lass doch den Empfänger asynchron mit lokalem 
Takt (Schieberegister mit DATA_CLK) laufen und übernehme dann das 
empfangene Wort synchron nach SYS_CLK...

Autor: guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also es existieren zwei Module die synchron Daten austauschen können. 
Der Übertragungstakt wird vom Sendemodul erzeugt, und gibt somit auch 
die Mindestfrequenz für den Empfänger vor.

Wie meinst du das mit dem asynchronen Schieberegister? Ich kann ja nicht 
einfach " if(rising_edge(DATA_CLK)) then A <= A(X downto Y)& SERIAL_IN 
end if; " nutzen?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
guest schrieb:
> Wie meinst du das mit dem asynchronen Schieberegister? Ich kann ja nicht
> einfach " if(rising_edge(DATA_CLK)) then A <= A(X downto Y)& SERIAL_IN
> end if; " nutzen?
Doch, genau so würde ich das in deinem Fall machen. Nur brauchst du dann 
noch ein Signal, das sagt, wann ein Datenwort fertig übertragen ist 
(beim SPI ist das der Chip-Select)...

Du kannst natürlich auch einfach nach x Bit das bis dahin empfangene 
Wort in ein Schattenregister/Pufferregister schreiben und das dann über 
die Taktdomänengrnze wegschleusen...

Autor: guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie willst du denn garantieren, dass das Schieberegister auch syncron 
schaltet und nicht aufgrund von ungünstigem Routing einige Speicher das 
DATA_CLK Signal eher bekommen als andere? Oder gibt es die Möglichkeit 
externe Signale auf ein Taktnetz zu leiten??

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
guest schrieb:
> Wie willst du denn garantieren, dass das Schieberegister auch syncron
> schaltet und nicht aufgrund von ungünstigem Routing einige Speicher das
> DATA_CLK Signal eher bekommen als andere?
Das Vertrauen in die Technik garantiert mir das... ;-)

> Oder gibt es die Möglichkeit externe Signale auf ein Taktnetz zu leiten??
Abhängig vom FPGA ginge das, aber das war bisher noch nie nötig...
Die paar FFs, die an diesem Takt angeschlossen sind, lassen sich mit den 
lokalen Routing-Ressourcen problemlos verdrahten.

Autor: guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das Vertrauen in die Technik garantiert mir das... ;-)

Ja das fehlt bei mir noch im großen Maße.. Wie realisiert ISE denn einen
std_logic_vector(7 downto 0) ?? Werden da einfach 8 FF miteinader 
verkettet? Wenn das so ist, woher weiß man das die länge der 
Signalleitung von DATA_CLK zu den einzelnen FF des Registers gleich lang 
sind?

Das es funktioniert kann ich mir vorstellen wenn die FF, räumlich 
gesehen, nebeneinander liegen. Aber ob das immer gegeben ist, grade wenn 
es voll wird auf dem FPGA... wer kann das sicherstellen??

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
guest schrieb:
> Wie realisiert ISE denn einen std_logic_vector(7 downto 0) ??
> Werden da einfach 8 FF miteinader verkettet?
Nur, wenn ein Takt beteiligt ist...

> Wenn das so ist, woher weiß man das die länge der Signalleitung von
> DATA_CLK zu den einzelnen FF des Registers gleich lang sind?
Sagen wir das mal so: die Länge ist ausreichend kurz und vor allem 
hinreichend gleich... ;-)
Ich habe da mal einen Ringoszillator mit S3 gebastelt, in dem etliche 
LUTs hintereinander geschaltet werden:
http://www.lothar-miller.de/s9y/categories/29-Ringoszillator
Dazwischen liegt dann noch die Verdrahtung der LUTs, die ja für den 
lokalen Takt auch verwendet werden wird. Und das Zeit zwischen zwei 
LUT-Ausgängen ist rechnerisch etwa 1/(50MHz*2*8) = 1/800MHz = 1,25ns. 
Davon abgezogen die Laufzeit durch die LUT laut DB 0,6ns ergibt ein 
Routig-Delay von 0,6ns.

Probiers einfach aus... ;-)

guest schrieb:
> Das es funktioniert kann ich mir vorstellen wenn die FF, räumlich
> gesehen, nebeneinander liegen. Aber ob das immer gegeben ist, grade wenn
> es voll wird auf dem FPGA... wer kann das sicherstellen??
Du könntest es über (Timing- oder Place-)Constraints fordern...

Autor: guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, technisch mag es funktionieren, sauber ist es aber nicht oder 
versteh ich das jetzt falsch?

Es ist ein paar Wochen her (Der erste Kontakt mit Hardware), da hatte 
ich den unten stehenden Code gepostet wo ich folgenden Error erhielt:

"The IO component <BTN1> is placed at site <PAD278>. This will not allow 
the use of the fast path between the IO and the Clock buffer. If this
sub optimal condition is acceptable for this design, you may use the 
CLOCK_DEDICATED_ROUTE constraint in the .ucf file...."

Das Wundermittel war damals "NET "BTN1" CLOCK_DEDICATED_ROUTE = FALSE;"
um trotzdem was ans laufen zu bekommen.

Da gabs dann von dir was auf die Finger, dass man das so nicht macht, 
sondern mit clock enable zu lösen hat. Ich seh da quasi keinen 
Unterschied zum jetzigen Problem, d.h. ein externes Signal dient als clk 
für beliebige FF's.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


entity toplevel is
  port(  BTN1 : in std_logic;
    RST : in std_logic;
    LED1 : out std_logic);
end toplevel;


architecture Behavioral of toplevel is
    signal TMP : std_logic;
begin
  
  p1 : process(BTN1, RST)
  begin
      if(RST = '1') then
         TMP <= '1';
      elsif(BTN1'event and BTN1 = '1') then
          TMP <= '0';
      end if;
  end process;
  LED1 <= TMP;
  
end Behavioral;


Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
guest schrieb:
> Da gabs dann von dir was auf die Finger, dass man das so nicht macht,
> sondern mit clock enable zu lösen hat.
Der Name BTN deutet auf einen (mechanischen) Taster incl. Prellen... 
hin. Das ist keine geeignete Taktquelle.

Wenn du aber einen digitalen Takt hast, relativiert sich das Ganze auf 
die Frage:
If this sub optimal condition is acceptable for this design
Und wenn du sagen kannst: "Ja, das ist mir bewusst und ich kann die 
resultierenden Laufzeitverzögerungen akzeptieren", dann spricht nichts 
gegen eine solche Lösung.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.