Forum: FPGA, VHDL & Co. von langsamer in schnellere taktdomain


von luigi (Gast)


Lesenswert?

Hallo Leute,

wir sitzen im Moment vor einem recht schwierigen Problem, zumindest fuer 
uns, und finden keine rechte Loesung dafuer, vllt. kann hier je jemand 
helfen.

Wir wuerden gerne ein Signal, welches z.B. 1 Sekunde lang ist auf einen 
Takt der z.b. nur 0.25s lang ist aufsynchronisieren. Beide Takte (1Hz 
und 4Hz) sind vom gleichen Takt abgeleitet, die Flanken kommen also zur 
gleichen Zeit. Was ich tun moechte ist ein Signal, welches eine Sekunde 
lang anliegt auf 0.25s zu verkuerzen. Sowas sollte doch eigentlich kein 
Problem sein, mir faellt aber dennoch keine Loesung ein, kann mir jemand 
helfen?

Luigi

von Falk S. (falkschilling)


Lesenswert?


von VHDL-Experte (Gast)


Lesenswert?

Um zwischen zwei Taktdomainen dieser Art die Inforamtion auszutauschen 
benötigst Du ein sogenanntes Universal Node Device. Diese als 
U.N.D.-Gatter bezeichneten Blöcke sind u.a. bei Reichelt erhältlich. Man 
legt an die beiden Eingänge die beiden Takte und erhält den gewünschten 
verkürzten Takt.

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


Lesenswert?

luigi schrieb:
> Beide Takte (1Hz und 4Hz) sind vom gleichen Takt abgeleitet, die Flanken
> kommen also zur gleichen Zeit.
Hmmmm. Wenn alle Flanken zur gleichen Zeit kommen, dann ist es der 
gleiche Takt...

> Wir wuerden gerne ein Signal, welches z.B. 1 Sekunde lang ist auf einen
> Takt der z.b. nur 0.25s lang ist aufsynchronisieren. Beide Takte (1Hz
> und 4Hz) sind vom gleichen Takt abgeleitet, die Flanken kommen also zur
> gleichen Zeit.
Kannst du da mal ein Bild von malen?
Und wenn es nicht allzu geheim ist: WAS wollt ihr denn machen?
Nicht: WIE wollt ihr es machen?

Das hört sich nämlich schon anders an:
> Was ich tun moechte ist ein Signal, welches eine Sekunde lang anliegt
> auf 0.25s zu verkuerzen.
Das hört sich für mich nach einem Monoflop an...

von daniel__m (Gast)


Lesenswert?

luigi schrieb:
> Beide Takte (1Hz
> und 4Hz)

sind das wirklich Takte? So langsam?

Eventuell ist das Schlagwort "Flankenerkennung" mit dem 4Hz-Takt 
hilfreich.

von Zeitgeist (Gast)


Lesenswert?

es kommen nie alle Flanken zur selben Zeit! Weg mit dem Gedanken - der 
existiert nur in der Theorie.

Stichwort könnte auch "Überabtastung" sein. Man kann das langsame Signal 
immer in die schnellere einsynchonisieren. Die Frage ist nur, was will 
man damit machen?

von Philip K. (philip_k)


Lesenswert?

Zeitgeist schrieb:
> es kommen nie alle Flanken zur selben Zeit! Weg mit dem Gedanken - der
> existiert nur in der Theorie.

Da hast Du wohl Recht. Aber wenn dem Synthese-Tool die Taktverhältnisse 
bekannt sind, kann man eben so tun als ob...

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


Lesenswert?

Philip K. schrieb:
> Aber wenn dem Synthese-Tool die Taktverhältnisse bekannt sind, kann man
> eben so tun als ob...
Aber nur, wenn das wirklich Takte in einem Taktnetz sind, und nicht 
irgendwas Heruntergeteiltes und Gegatetes...

von luigi (Gast)


Lesenswert?

oh, das ging ja wieder mal schnell, danke schon mal fuer die Kommentare, 
ich denke ich werde es mal etwas genauer erklaeren:
Ich moechte einen I2S Interface bauen (in VHDL), der auf der einen Seite 
die I2S Daten einliest (die Clocks werden dabei von mir erzeugt, durch 
einen Clockteiler), und auf der anderen Seite die 24 bit fuer 
links/rechts ausgibt.

Das ganze system wird mit ungefaehr 25MHz getaktet sein, der datentakt 
ist ein 512tel davon.
Ich habe jetzt also 2 schieberegister welche ich befuelle (1 fuer links/ 
1 fuer rechts), und wenn beide Schieberegister voll sind moechte ich 
einen Impuls der laenge 40ns senden (genau ein 25MHz Takt), die 
schieberegister werden aber mit dem 25MHz/512 Takt befuellt, wie macht 
man soetwas?

es ist eigentlich alles fertig, ausser dem signal welches anzeigt dass 
die daten fertig anliegen.

danke
luigi

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


Lesenswert?

luigi schrieb:
> und wenn beide Schieberegister voll sind moechte ich einen Impuls der
> laenge 40ns senden (genau ein 25MHz Takt),
Nennt sich Clock-Enable und ist gängige Praxis.

> die schieberegister werden aber mit dem 25MHz/512 Takt befuellt, wie
> macht man soetwas?
Man taktet das gesamte System mit 25MHz (frei nach Concn: es kann nur 
einen geben!). Jede geringere Frequenz wird über Teiler erzeugt, die 
Clock-Enables (keinesfalls und niemals aber andere Takte!) generieren.

> es ist eigentlich alles fertig
Dann häng doch einfach mal die VHDL(oder Verilog oder sonstwas)-Datei 
hier an.

von luigi (Gast)


Angehängte Dateien:

Lesenswert?

so, also im Anhang findet Ihr die Dateien. im i2s_in ab Zeile 100 habe 
ich das Problem, dass ich die beiden Prozesse nicht synchronisiert 
bekomme. Ich vermute im Moment mal dass es daran liegt, dass ich die 
beiden Prozesse eben nicht mit unterschiedlichen clocks laufen lassen 
kann, aber wie geht es denn sonst?
falls der Code nicht ausreicht um zu verstehn was ich machen moechte 
kann ich auch noch eine Zeichnung machen.

von berndl (Gast)


Lesenswert?

Zeile 4: Aua!
1
      if rising_edge(sclk_in) then
2
        state_reg <= state_reg;
3
        case state_reg is
4
          when idle =>
5
            ready <= '0';
6
            if falling_edge(lrck_in) then
7
              state_reg <= write_left;
8
            elsif rising_edge(lrck_in) then
9
              state_reg <= write_right;
hmm, was koennte 'state_reg' wohl fuer ein Bauteil sein, das mit 3 
Clocks klarkommt? Schau mal im Datenblatt deines FPGA nach, ob du in 
einem CLB/LE ein passendes FF findest...

von luigi (Gast)


Lesenswert?

hm, ja jetzt wo du mich darauf hinweist wird mir auch klar dass das 
nicht geht, aber das ist leider noch nicht mal das problem welches ich 
meinte.
Dabei kommt aber noch eine Frage auf: warum funktioniert dieses 
Konstrukt in der Simulation mit Questasim?
Es handelt sich hier uebrigens um ein ASIC Design und kein FPGA-Projekt, 
falls das irgendwie wichtig ist.

von Student (Gast)


Lesenswert?

luigi schrieb:
> Es handelt sich hier uebrigens um ein ASIC Design und kein FPGA-Projekt,
> falls das irgendwie wichtig ist.
Das könnte teuer werden, bei dem Wissensstand... :S

von luigi (Gast)


Angehängte Dateien:

Lesenswert?

okay, ich hab das ganze jetzt noch mal neu geschrieben, vllt. wird so 
etwas klarer was ich tun moechte.

wie ihr euch sicherlich schon gedacht habt handelt es sich hier um ein 
uni-projekt, also nichts mit teuer ;)

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


Lesenswert?

1
  stage1 : process (clk, nreset)
2
  begin
3
    if nreset='0' then
4
      q1 <= '0';
5
    else
6
      if rising_edge(clk) then
7
        q1 <= sdata_in;
8
      end if;
9
    end if;
10
  end process stage1;
11
  
12
  stage2 : process (clk, nreset)
13
  begin
14
    if nreset='0' then
15
      q2 <= '0';
16
    else
17
      if rising_edge(clk) then
18
        q2 <= q1;
19
      end if;
20
    end if;
21
  end process stage2;
Das ist es, warum VHDL als "geschwätzig verschrien ist. Ich hätte da 
einfach das hier geschrieben (weil der Reset hier auch in einem ASIC 
absolut vollkommen unnötig ist!):
1
  q1 <= sdata_in when rising_edge(clk);
2
  q2 <= q1 when rising_edge(clk);

Das hier ist übrigens trotz "einsynchronisieren" komplett asynchron, 
weil q2 auf clk eingetaktet, aber mit sclk weitergegeben wird:
1
      if rising_edge(clk) then
2
        q2 <= q1;
3
     :
4
     :     
5
      if rising_edge(sclk) then
6
        if right_enable = '1' then
7
          right_reg <= right_reg(23 downto 0) & q2;  -- Holla die Waldfee
Das gibt dann zwischendurch wüstes Rauschen oder Knacken in der 
Tonübertragung...

Mach es mit dem Takt doch einfach so wie der Highlander:
Es kann  nur einen geben!
Und I2S kann mit seinen maximal 6MBit/s locker mit den 25MHz verwaltet 
werden...

Oder du könntest doch einfach den Empfang komplett synchron zum sclk 
abhandeln, und dann die empfangenen Ton-Daten an die andere Taktdomäne 
übergeben (so würde ich das machen).
1
  use ieee.numeric_std.all;
2
  use ieee.std_logic_unsigned.all;
Oh nein, nicht schon wieder...
Siehe den Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"

von Christoph Z. (christophz)


Lesenswert?

luigi schrieb:
> wie ihr euch sicherlich schon gedacht habt handelt es sich hier um ein
> uni-projekt, also nichts mit teuer ;)

Doch, für uns Steuerzahler :-)

Bringt ja weder dir noch der Uni was, wenn du einen ASIC hast, der nicht 
das macht, was er soll.

luigi schrieb:
> Dabei kommt aber noch eine Frage auf: warum funktioniert dieses
> Konstrukt in der Simulation mit Questasim?

Weil die Syntax korrekt ist. Dein Simulator hat Ahnung von VHDL aber 
nicht von ASICs.

Wenn du ein bisschen Zeit zum Austesten hast, kannst du ja mal eine 
Post-Map Simulation machen (Also das Ergebnis des Synthesizers und des 
Technologie-Mappers simulieren). Dann siehst du auch im Simulator, was 
von deinem Konstrukt übrig geblieben ist.

von luigi (Gast)


Lesenswert?

Lothar Miller schrieb:
> Oder du könntest doch einfach den Empfang komplett synchron zum sclk
> abhandeln, und dann die empfangenen Ton-Daten an die andere Taktdomäne
> übergeben (so würde ich das machen).

ja das wollte ich ja genau so machen, nur wie synce ich das dann zu den 
25MHz?

Als Ausgangsinterface haben wir die 2*24bit Daten für links/rechts 
spezifiziert und dieses take_data signal, welches halt fuer einen Takt 
(von clk, also 40ns) auf high geht. in diesem Takt holt das naechste 
Modul dann die Daten ab und verarbeitet diese.

die Anfangsidee war jetzt die Schieberegister mit der SCLK zu feeden und 
wenn diese voll sind das take_data signal (aber eben nur mit 40ns 
laenge) zu erzeugen und die schieberegister zu resetten.
Von der Sache her scheitert es in meiner Vorstellung der Hardware jetzt 
vor allem daran dass ich nicht weiß wie ich diesen kurzen impuls aus dem 
langen SCLK-Impuls erzeuge, und zwar auch noch taktsynchron zur clk.

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


Lesenswert?

luigi schrieb:
> ja das wollte ich so machen, nur wie synce ich das dann zu den 25MHz?
Ist doch einfach, du hast ja pro Wort mindestens 24 Bit des langsamen 
sclk Zeit zur Übergabe in die schnelle Domain (und damit mindestens 96 
Takte deines clk). Ich würde für die Übergabe sogar einfach den 
WordSelect des I2C Signal einsynchronisieren, dann eine Flankenerkennung 
draufsetzen und damit dann das abgespeicherte Wort nach clk übernehmen.

luigi schrieb:
> die Anfangsidee war jetzt die Schieberegister mit der SCLK zu feeden und
> wenn diese voll sind das take_data signal (aber eben nur mit 40ns
> laenge) zu erzeugen und die schieberegister zu resetten.
Nimm zwei Schieberegister: eines für Links, das andere für Rechts. Und 
immer der Kanal, der gerade nicht übertragen wird, wird in die clk 
Domäne übernommen. Denn dann ändern sich dessen Daten ja gerade nicht...

: Bearbeitet durch Moderator
von luigi (Gast)


Lesenswert?

2 schieberegister habe ich schon (fuer links und rechts), die Daten 
muessen aber gleichzeitig zum naechsten modul uebertragen werden, was 
aber auch kein problem ist da jede Uebertragung 32 sclk-Takte lang ist, 
aber nur waehrend der ersten 24 Takte liegen auch daten an (sind halt 
nur 24bit), da hat man danach also genug Zeit die Daten zu uebertragen 
und die beide schieberegister zu resetten.
Ob die Schieberegister voll sind erkenne ich an dem left/right_full 
signal welches ins 25. bit der Schieberegister geschoben wird.

der ablauf ist also folgender: lrck geht low, die flanke erkenne ich und 
starte mein ganzes system. von da an wird dann das linke schieberegister 
mit sclk getaktet und bekommt die daten rein bis left_full high ist.
ab jetzt wird gewartet bis lrck high geht, dann wird das rechte 
schieberegister befuellt.
dann sind left_full und right_full beide high, es kann also das 
take_data signal erzeugt werden, und genau hier weiss ich nicht weiter. 
wie erzeuge ich denn dieses signal so dass es nur 40ns breit wird?
nachdem das take_data signal dann high war werden die schieberegister 
resettet und alles beginnt von vorn, aber dieses take_data signal zu 
erzeugen, da komme ich einfach nicht drauf wie das sinnvoll gehen soll, 
das muss doch irgendwie zu machen sein?

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


Lesenswert?

luigi schrieb:
> 2 schieberegister habe ich schon (fuer links und rechts), die Daten
> muessen aber gleichzeitig zum naechsten modul uebertragen werden, was
> aber auch kein problem ist da jede Uebertragung 32 sclk-Takte lang ist,
> aber nur waehrend der ersten 24 Takte liegen auch daten an (sind halt
> nur 24bit), da hat man danach also genug Zeit die Daten zu uebertragen
> und die beide schieberegister zu resetten.
Ich behaupte: man braucht da kein Schieberegister irgendwann 
zurücksetzen. Es müssen nur die jeweils bis dahin empfangenen Daten zum 
richtigen Zeitpunkt richtig weitergegeben werden.

luigi schrieb:
> der ablauf ist also folgender: lrck geht low, die flanke erkenne ich und
> starte mein ganzes system. von da an wird dann das linke schieberegister
> mit sclk getaktet und bekommt die daten rein bis left_full high ist.
> ab jetzt wird gewartet bis lrck high geht, dann wird das rechte
> schieberegister befuellt.
> dann sind left_full und right_full beide high, es kann also das
> take_data signal erzeugt werden, und genau hier weiss ich nicht weiter.
> wie erzeuge ich denn dieses signal so dass es nur 40ns breit wird?
> nachdem das take_data signal dann high war werden die schieberegister
> resettet und alles beginnt von vorn, aber dieses take_data signal zu
> erzeugen, da komme ich einfach nicht drauf wie das sinnvoll gehen soll,
> das muss doch irgendwie zu machen sein?
Irgendein Großbuchstabe hätte diesen Text besser lesbar gemacht...

> lrck
Schon das ist falsch: es gibt keinen Rechts-Links-Clock im I2S 
Protokoll, sondern es gibt nur den Schiebetakt slck. Im 
Wikipedia-Artikel ist statt lrck der passendere Namen verwendet: ws für 
Word-Select. Und so ist es auch: die Daten werden mit den sclk 
eingetaktet, und mit dem ws wird ausgewählt, welches der beiden 
Schieberegister gerade aktualisiert wird.

: Bearbeitet durch Moderator
von pks (Gast)


Lesenswert?

Lothar Miller schrieb:
> Oh nein, nicht schon wieder...
> Siehe den Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"

Du wirst aber auch nicht müde...;-)

Ich muss ja gestehen, dass obwohl ich den Beitrag kenne, ich das Teil 
seit Jahren weiter verwende. Probleme sind mir daraus noch nie 
entstanden...

von Christoph Z. (christophz)


Lesenswert?

luigi schrieb:
> Von der Sache her scheitert es in meiner Vorstellung der Hardware jetzt
> vor allem daran dass ich nicht weiß wie ich diesen kurzen impuls aus dem
> langen SCLK-Impuls erzeuge, und zwar auch noch taktsynchron zur clk.

Synchronisierer mit Flankenerkennung, wie hier beschrieben:
http://www.doulos.com/knowhow/fpga/synchronisation/

von pks (Gast)


Lesenswert?

So zum Beispiel:
1
entity EDGE_DETECT is
2
  generic(
3
    -- Number signals to check
4
    G_NUM_SIG : integer;
5
    -- Input not clock synchronous
6
    G_ASYNC   : boolean := false
7
    );
8
  port(
9
    CLK       : in  std_logic;
10
    -- Input signal
11
    I_SIGNALS : in  std_logic_vector(G_NUM_SIG-1 downto 0);
12
    -- Edge detection output
13
    O_RISE    : out std_logic_vector(G_NUM_SIG-1 downto 0);
14
    O_fall    : out std_logic_vector(G_NUM_SIG-1 downto 0)
15
    );
16
end entity EDGE_DETECT;
17
18
architecture rtl of EDGE_DETECT is
19
20
  signal S_CHECK_D0 : std_logic_vector(G_NUM_SIG-1 downto 0);
21
  signal S_CHECK_D1 : std_logic_vector(G_NUM_SIG-1 downto 0);
22
23
begin
24
25
  -- Asynchronous case
26
  GEN_ASYNC : if (G_ASYNC) generate
27
28
    B_ASYNC : block is
29
      signal S_I_SIGNALS : std_logic_vector(G_NUM_SIG-1 downto 0);
30
    begin  -- block B_ASYNC
31
      -- Purpose: Input register pipe
32
      P_REG : process (CLK)
33
      begin  -- process P_REG
34
        if (rising_edge(CLK)) then
35
          S_I_SIGNALS <= I_SIGNALS;
36
          S_CHECK_D0  <= S_I_SIGNALS;
37
          S_CHECK_D1  <= S_CHECK_D0;
38
        end if;
39
      end process P_REG;
40
    end block B_ASYNC;
41
    
42
  end generate GEN_ASYNC;
43
44
  -- Synchronous case
45
  GEN_SYNC : if (not G_ASYNC) generate
46
47
    -- Purpose: Input register
48
    P_REG : process (CLK)
49
    begin  -- process P_REG
50
      if (rising_edge(CLK)) then
51
        S_CHECK_D1 <= I_SIGNALS;
52
      end if;
53
    end process P_REG;
54
55
    S_CHECK_D0 <= I_SIGNALS;
56
    
57
  end generate GEN_SYNC;
58
59
  -- Combinational process
60
  -- Purpose:  Edge detection
61
  P_DETECT : process (S_CHECK_D0, S_CHECK_D1)
62
  begin  -- process P_DETECT
63
    for i in 0 to G_NUM_SIG-1 loop
64
      O_RISE(i) <= S_CHECK_D0(i) and not S_CHECK_D1(i);
65
      O_FALL(i) <= not S_CHECK_D0(i) and S_CHECK_D1(i);
66
    end loop;  -- i
67
  end process P_DETECT;
68
69
end architecture rtl;

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


Angehängte Dateien:

Lesenswert?

pks schrieb:
> Du wirst aber auch nicht müde...;-)
Frag nicht...
> Ich muss ja gestehen, dass obwohl ich den Beitrag kenne, ich das Teil
> seit Jahren weiter verwende. Probleme sind mir daraus noch nie
> entstanden...
Klar geht das gut, solange du nicht zusätzlich auch die numeric_std 
mit einbindest. Das ist der Kasus Knaxus... ;-)

Christoph Z. schrieb:
> Synchronisierer mit Flankenerkennung
Das ist hier nicht das Problem...

@luigi:
Ich habe da mal was geschrieben und behaupte, das läuft (ich habe es 
aber noch nicht ausprobiert oder simulaiert). Du kannst es auf jeden 
Fall als Gedankenskizze nehmen. Man könnte noch ein paar FF sparen, wenn 
man die unnötige Registrierung des garantiert stabilen Wortes 
herausnimmt.

pks schrieb:
> So zum Beispiel: ...
Ja, das wird luigi jetzt entweder a) weiterbringen oder b) ihm 
wenigstens das Fürchten lehren... ;-)

Ich mache das Einsynchronisieren und die folgende Flankenerkennung so:
http://www.lothar-miller.de/s9y/categories/18-Flankenerkennung
Ich denke, da kapiert man recht schnell worum es geht. Und wie man das 
dann generisch beschreiben kann, das kann jeder für sich alleine 
herausfinden.

: Bearbeitet durch Moderator
von Christoph Z. (christophz)


Lesenswert?

Lothar Miller schrieb:
> Christoph Z. schrieb:
>> Synchronisierer mit Flankenerkennung
> Das ist hier nicht das Problem...

War auch mehr für die Vollständigkeit. Damit Luigi trotzdem weiss, wie 
man ein Flag synchronisiert, damit es in der Zieldomäne nur eine 
Taktperiode kurz ist.
Wir sind hier ja alle gleicher Meinung, dass sein Problem gar nicht 
vorhanden ist, wenn die vorgeschlagenen Lösungen realisiert werden.

von pks (Gast)


Lesenswert?

Lothar Miller schrieb:
> pks schrieb:
>> So zum Beispiel: ...
> Ja, das wird luigi jetzt entweder a) weiterbringen oder b) ihm
> wenigstens das Fürchten lehren... ;-)

Was soll denn das jetzt heißen? :-)

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.