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


von guest (Gast)


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)

1
FALLING_TX_CLK_SYNC : process(CLK_SYS, RST)
2
begin  
3
   if(RST = '1') then
4
      LAST_FALLING_VALUE <= '1';  
5
   elsif(CLK_SYS'event and CLK_SYS = '0') then
6
      if(LAST_SHIFT_VALUE = '0' and DATA_CLK = '1') then
7
         USE_FALLING_VALUE <= '1';
8
         FALLING_VALUE <= SERIAL_IN;
9
      else
10
         USE_FALLING_VALUE <= '0';
11
      end if;
12
         LAST_FALLING_VALUE <= DATA_CLK;
13
      end if;  
14
end process;
15
16
RISING_TX_CLK_SYNC : process(CLK_SYS, RST)
17
begin  
18
   if(RST = '1') then
19
      SHIFT_EN <= '0';
20
      LAST_SHIFT_VALUE <= '1';    
21
   elsif(CLK_SYS'event and CLK_SYS = '1') then
22
      if(LAST_FALLING_VALUE = '0' and DATA_CLK = '1') then
23
         SHIFT_EN <= '1';
24
         SHIFT_VALUE <= SERIAL_IN;
25
      elsif(USE_FALLING_VALUE = '1') then
26
         SHIFT_VALUE <= FALLING_VALUE;
27
         SHIFT_EN <= '1';
28
      else
29
         SHIFT_EN <= '0';
30
      end if;
31
         LAST_SHIFT_VALUE <= DATA_CLK;
32
      end if;
33
end process;

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


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... :-/

von guest (Gast)


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.

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


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...

von guest (Gast)


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?

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


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...

von guest (Gast)


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??

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


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.

von guest (Gast)


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??

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


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...

von guest (Gast)


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.
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
5
entity toplevel is
6
  port(  BTN1 : in std_logic;
7
    RST : in std_logic;
8
    LED1 : out std_logic);
9
end toplevel;
10
11
12
architecture Behavioral of toplevel is
13
    signal TMP : std_logic;
14
begin
15
  
16
  p1 : process(BTN1, RST)
17
  begin
18
      if(RST = '1') then
19
         TMP <= '1';
20
      elsif(BTN1'event and BTN1 = '1') then
21
          TMP <= '0';
22
      end if;
23
  end process;
24
  LED1 <= TMP;
25
  
26
end Behavioral;

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


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:
1
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.

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.