Forum: FPGA, VHDL & Co. Problem mit SYNC Stufe - ich bin blind


von Alex (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich habe folgende, eigentlich einfache SYNC Stufe zum einsynchronisieren 
von einem asynchronen Bus.
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
entity sync_stufe is  
6
   port (
7
      clk                : in   std_logic;
8
      nres               : in   std_logic;
9
      en                 : in   std_logic;
10
      analog_in          : in   std_logic_vector(15 downto 0);
11
      analog_sync_out    : out  std_logic_vector(15 downto 0)
12
      );
13
end entity sync_stufe;
14
15
architecture rtl of sync_stufe is
16
17
   signal sync_analog_in : std_logic_vector (31 downto 0);
18
   
19
begin
20
21
   analog_sync_out <= sync_analog_in(31 downto 16);
22
23
   sync_ff : process (clk, nres) is
24
   begin
25
      if (nres = '0') then
26
         analog_sync_out <= (others => '0');
27
         sync_analog_in <= (others => '0');
28
      elsif rising_edge(clk) then
29
         if en = '1' then
30
            sync_analog_in  <= sync_analog_in(15 downto 0) & analog_in;
31
         end if;
32
      end if;
33
   end process;
34
35
end architecture rtl;

Wenn ich mir die Sache nun in der Simulation anschaue, werden nur Nullen 
weiter gegeben, aber immer da, wo eine Eins stehen sollte, kommt ein X.

Was genau mache ich falsch?
Ich sehe in der ganzen Sache eigentlich kein Problem, das shiften von 
den LSBs zu dem MSBs scheint zu gehen... irgendwo danach gehen die 
Einsen verloren.
Ich schaue nun schon mehr als 1h auf das Stückchen Code und finde 
einfach keine Erklärung - bin wohl blind.

Kann mir jemand meinen Fehler aufzeigen und mich aus meiner Denkschleife 
herausholen?

Vielen Dank!
Alex

von Lattice User (Gast)


Lesenswert?

Alex schrieb:
> Ich schaue nun schon mehr als 1h auf das Stückchen Code und finde
> einfach keine Erklärung - bin wohl blind.
>

Oder schaust auf das falsche Stück Code.
Vermutlich wird analog_sync_out irgendwo anders auf 0 gesetzt.


Davon abgesehen, einen Datenbus synchronsiert man nicht so ein, sondern 
mit einem Validsignal.

von Alex (Gast)


Lesenswert?

Hallo und vielen Dank!

Lattice User schrieb:
> Oder schaust auf das falsche Stück Code.
> Vermutlich wird analog_sync_out irgendwo anders auf 0 gesetzt.
Ich habe schon den Weg der Signale verfolgt und nirgens werden diese 
Signale nochmal manipuliert. Sie werden nicht mal abgefragt sondern 
laufen jetzt zu Testzwecken sogar ins Leere.

Lattice User schrieb:
> Davon abgesehen, einen Datenbus synchronsiert man nicht so ein, sondern
> mit einem Validsignal.
Wieso das denn?
Ich synchronisiere diesen analogen Bus genauso ein wie ich mein 
ansynchrones Reset verarbeite. Woher sollte ich dieses Valid nehmen, 
ohne Gegenstelle, die dieses generiert?

Viele Grüße,
Alex

von P. K. (pek)


Lesenswert?

Du hast das Ganze zweimal zugewiesen, einmal concurrent, und ein zweites 
Mal in Deinem Prozess.

Das kannst Du in Modelsim auch ganz einfach rausfinden. Du kopierst in 
der Waveview (dort in der Namen- oder Wertespalte) das Signal und tippst 
in der Commandline:

VSIM> drivers "Signalnamen pasten"

Dann wird er Dich über die Drivers zur aktuellen Simulationszeit 
informieren. Sieht dann zum Veispiel etwa so aus:

VSIM 9>drivers sim:/tb_memwr/dut/wrsdfsm_cur
# Drivers for /tb_memwr/dut/wrsdfsm_cur:
#    idle  : Signal /tb_memwr/dut/wrsdfsm_cur
#      idle : Driver /tb_memwr/dut/seq

von Cihan K. (lazoboy61)


Lesenswert?

Da ist doch Multisource drin:
1
...
2
   analog_sync_out <= sync_analog_in(31 downto 16);
3
4
   sync_ff : process (clk, nres) is
5
   begin
6
      if (nres = '0') then
7
         analog_sync_out <= (others => '0');
8
         sync_analog_in <= (others => '0');
9
      elsif rising_edge(clk) then
10
         if en = '1' then
11
            sync_analog_in  <= sync_analog_in(15 downto 0) & analog_in;
12
         end if;
13
      end if;
14
   end process;
15
...

analog_sync_out wird sowohl in als auch außerhalb eines Prozesses 
gesetzt. Nimm mal am besten das in dem Reset raus!

Cihan

von Lattice User (Gast)


Lesenswert?

Alex schrieb:

>> Davon abgesehen, einen Datenbus synchronsiert man nicht so ein, sondern
>> mit einem Validsignal.
> Wieso das denn?

Du willst erreichen dass der eingelesene Wert immer gültig ist?
Genau das geht so nicht, da sich die Fehler einfach fortpflanzen.

Wenn du kein externes Valid hat, wird es kompliziert aber sich auch 
machbar.
(z.B. intern erzeugen aus Vergleich mehrer aufeinanderfolgender Werte)

von Cihan K. (lazoboy61)


Lesenswert?

Mach die Synchronisation doch am besten über ein Fifo, einfach mit 2 
Clockeingängen. Der Rest geht automatisch. Dann hast du auch ein 
optionales Acknowledge- und Valid-Flag. Da bist du auf der sicheren 
Seite.

Cihan

von Bronco (Gast)


Lesenswert?

Cihan Kalayci schrieb:
> Mach die Synchronisation doch am besten über ein Fifo, einfach mit 2
> Clockeingängen. Der Rest geht automatisch. Dann hast du auch ein
> optionales Acknowledge- und Valid-Flag. Da bist du auf der sicheren
> Seite.

Ja, wenn er für seinen asynchronen Bus ein ClockSignal hätte.

von Klaus (Gast)


Lesenswert?

Bronco schrieb:
> Ja, wenn er für seinen asynchronen Bus ein ClockSignal hätte.

Bei einem asynchronen Bus braucht man aber zumindest ein Enablesignal, 
das einem sagt, wann die Daten gültig sind. Ansonsten gibt es keine 
Möglichkeit die Daten korrekt zu übernehmen, denn man weiß ja nie, ob 
die sich gerade ändern oder nicht.

von Klaus (Gast)


Lesenswert?

Klaus schrieb:
> Bronco schrieb:
>> Ja, wenn er für seinen asynchronen Bus ein ClockSignal hätte.
>
> Bei einem asynchronen Bus braucht man aber zumindest ein Enablesignal,
> das einem sagt, wann die Daten gültig sind. Ansonsten gibt es keine
> Möglichkeit die Daten korrekt zu übernehmen, denn man weiß ja nie, ob
> die sich gerade ändern oder nicht.

Nachtrag: Es sei denn, es gibt spezielle Randbedingungen, wie zum 
Beispiel: Zwischen 2 Datenwörtern bleiben die Daten immer x Takte (vom 
Abtasttakt) stabil. Dann könnte man auf x gleiche Werte prüfen, und die 
Daten nur dann übernehmen.

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.