Forum: FPGA, VHDL & Co. VHDL timing in GMII auf Spartan6


von René D. (Firma: www.dossmatik.de) (dose)



Lesenswert?

Ich habe das GMII in eine Thread 
Beitrag "Ethernet GMII" mal vorgestellt.

Es wurde bereits in Masterarbeiten eingesetzt.
Auch die aktuellen Diskussionen in einem weiteren Thread haben mich 
bewegt, hier mal wieder weiter zuarbeiten.
Beitrag "Ethernetverbindung FPGA<->PC"

Ich habe einen Effekt, den ich mir nicht so richtig erklären kann, da 
ich auch etwas unwissen mit constrains bin.

Ich habe das SP601 und bekomme  den Code nicht immer zum laufen.
Der Fitter läuft durch. Das ist kein Problem. Ich glaube nicht an einen 
Fehler im VHDL code.
Ich habe aber öfter constrain Verletzungen.

Wenn ich das Bit-file hochlade weden die Pakete von der Hardware auch 
Ethernetpakete gesendet (LED blinkt). Leider kommen die Pakete nicht bei 
Wireshark an.

Ich habe die Files hochgeladen bei denen es läuft.

Wenn ich den TX-fifo mit einem andern CLK betreibe, habe ich so einen 
Fall.
Das wären hier die letzten drei Prozesse auf User_clk und den wclk auf 
User_clk  in ether_top.vhd


Desweiteren stört mich die Zeile:

  PHY_TXC_gtxclk <= not ether_clk;

Das not ist notwendig sonst geht es auch nicht.


Die Implementierung muss sicherer werden. Das UCF file ist sicher nicht 
das Tollste. Es würde mich interessieren, wie es richtiger wäre.

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


Lesenswert?

René D. schrieb:
> Die Implementierung muss sicherer werden.
Dann mach erst mal diese ganzen asynchronen kombinatorischen Resets 
raus:
1
  if counterrx="000" then
2
    countertx<=(others=>'0');
3
    :
4
5
    if state_txout = start then
6
      tx_paket <= '0';
7
      :
Als Beispiel: countertx glitcht garantiert beim zählen. Und was, wenn 
der Zähler beim Übergang von 1 nach 2 oder von 2 nach 3 für ein paar ps 
so aussieht:
1
                    !!            !!!!           
2
counterrx(2)   0    0 0     0     0 0 1     1    1 1      1
3
counterrx(1)   0    0 1     1     0 0 0     0    0 1      1
4
counterrx(0)   1    0 0     1     1 0 0     1    0 0      1
Und das selbe gilt auch für den Automaten state_txout, denn so ein 
Automat ist ja auch nichts anderes als ein komlizierterer Zähler...

Das hier sollte ok sein:
1
  PHY_TXC_gtxclk <= not ether_clk;
Aber zur Sicherheit: immer wieder mal ein Blick in den Timing Report.

Welche Warnungen bekommst du eigentlich für diesen Taktmultiplexer?
1
  ether_clk <= phy_rx_clk when gmii_active = '1' else PHY_TX_CLK;
Und ich bin mir gar nicht so sicher, das es die Timing Constraints da 
drüber schaffen. Du solltest für so eine Taktumschaltung den Taktmanager 
verwenden. Dann bekommst du auch definierte Übergänge onhe Glitches bei 
der Umschaltung.

Und falls es der Takt über den Multiplexer weg schafft (ich traue das 
der Toolchain zu), dann ist es klar, dass du mindestens hier das Timing 
nur selten erreichst:
1
-- Schnipsel aus allen Dateiein zusammenkopiert !!
2
TIMESPEC TS_PHY_RX_CLK = PERIOD "PHY_RX_CLK" 8 ns HIGH 50%;  -- 125MHz
3
4
  ether_clk <= phy_rx_clk ...
5
6
   wclk        => ether_clk,
7
8
    if rising_edge(wclk) then
9
          :
10
          crc32 <= crc(fifo_out, crc32);   
11
12
  function crc (data_in : std_logic_vector (7 downto 0); crc_value : std_logic_vector(31 downto 0)) return std_logic_vector is
13
  begin
14
    crc_out := crc_value;
15
    for k in 0 to 7 loop   --- !! 8 Ebenen tiefe Logik, da muss der Optimierer für 125MHz hart anpacken !!
16
      if crc_out(0) /= data_in(k) then
17
        crc_out := ('0'& crc_out(31 downto 1)) xor X"EDB88320";
18
      else
19
        crc_out := ('0'& crc_out(31 downto 1));
20
      end if;
21
    end loop;
22
    return crc_out;
23
  end crc;
Hast du mal geschaut, was der kritische Pfad ist? Ich vermute, diese CRC 
Berechung ist da vorn mit dabei!
Du solltest versuchen, die CRC in einen Multicycle zu überführen.

von rene (Gast)


Lesenswert?

Hallo Lothar,

ich habe auch stark diesen Prozess in verdacht.
Hier wird von der eine Taktdomäne ein "Impuls" zum senden an die andere 
übergeben.

  process(wclk)
  begin
    if state_txout = start then
      tx_paket <= '0';
    elsif rising_edge(wclk) then
     tx_begin(0)<=send_strobe;
      tx_begin(1)<=tx_begin(0);
      if tx_begin = "01" and tx_en1='0' then
        tx_paket <= '1';
      end if;
     if reset= '1' then
       tx_begin<=(others=>'0');
     end if;
    end if;
  end process;

Wenn die Domäne, es kappiert hat, setzt sie den Impuls zurück. Un das 
muss asynchron passieren, da beide mit unter schiedlichen Takt laufen.


Der CRC war nie das Problem.

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


Lesenswert?

rene schrieb:
> Un das muss asynchron passieren, da beide mit unter schiedlichen Takt
> laufen.
Asynchron und unterschiedlicher Takt, das wird sicher Probleme machen 
und niemals stabil laufen.

Du kannst noch ausprobieren, im die state_txout FSM als OneHot zu 
codieren, dann hast du wenigstens keine Glitches mehr... (aber irgendwie 
hat das eine starke Tendenz Richtung Murks)

von rene (Gast)


Lesenswert?

Ich habe einen FiFo der der zwischen den beiden Taktdomains.

Ich sehe gerade die CRC32 wird mit dem falschen Takt getrieben.
Das könnte mein Hauptproblem sein.

von ingenieur (Gast)


Lesenswert?

Mach das asynchrone Resetzeugs komplett raus

Der CRC32 für Ethernet ist im opencores gut gelöst und realisert, zum 
nachschauen

Was du auch noch machen muss: die Polarität und Phase des Taktes zum PHY 
checken. Da ging bei mir viel in die Hose.

von Christian R. (supachris)


Lesenswert?

Da war doch was mit 90° verschobenem Takt am Marvell Phy, oder? Und nimm 
für die Taktumschaltung, falls die wirklich nötig ist, einen Clock Mux. 
Und erzeuge alle Takte mit den MMCMs, per Inverter negieren ist recht 
böse.

von Schlumpf (Gast)


Lesenswert?

rene schrieb:
> Un das
> muss asynchron passieren, da beide mit unter schiedlichen Takt laufen.

Ohne mir deinen Code angeschaut zu haben, folgendes Statement:
Wenn du sowas machst, dann musst du mehrere Dinge sicherstellen
1.) Das Steuersignal der Quell-Domäne darf nur 1 Bit breit sein, denn 
dann ist sichergestellt, dass es zu jeder Zeit in sich selbst konsistent 
ist. Also entweder "1" oder "0".

2.) In der Ziel-Domain muss dieses Signal wie ein asynchrones Signal 
behandelt werden. Es muss also via Register auf den Takt der Zieldomain 
einsynchronisiert werden, bevor es weiterverwendet wird.

Gibt es mehrere Signale, die in einer gewissen zeitlichen Abfolge an der 
Ziel-Domain ankommen müssen, dann musst du aufpassen, dass die Signale 
nicht nur an der Quelle diese Reihenfolge einhalten, sondern dass diese 
Reihenfolge durch unterschiedliche Laufzeiten von Quelle zum Ziel nicht 
zunichte gemacht wird. Hier helfen dann "MAX_DELAY"-Constraints o.Ä.

Wie gesagt, ich habe deinen Code nicht angeschaut, aber du kannst ihn ja 
selber mal überprüfen, ob du irgendwo ne Schweinerei bei den 
Domain-Übergängen drin hast

von Trundle Trollkönig (Gast)


Lesenswert?

kurzer Einwurf,

ich kann leider nur verilog aber ich sehe du hast, die Demo-Board-Datein 
als Basis genommen, das hab ich damals auch gemacht und die sind auch 
funktionstüchtig. Ohne dein Code gelesen zu haben, weil ich vhdl nicht 
mehr kann, hört sich das Problem für mich sehr bekannt an. Das mit dem 
leicht verschobenen Takt von TX-Data[7:0] und TXCLK (125 Mhz 
Refenrenz-Clock zum Phy) kriegst du am besten hin wenn du, das letzte 
Ausgangsregister der TX-Daten in die IO-Buffer verlegst ((* IOB="TRUE" 
*) ) und die TXCLK mittels ODDR und 180 ° verschobenen Takt (bezüglich 
der TX-Register) erzeugst. Dann hast du centeraligned die Daten... 
Danach hatte ich keine Probleme mehr mit Instabilitäten und du siehst 
dann auch deine Packet in Wireshark. Ich denke nicht das die 
CRC-Berechnung das Problem ist. Basis meiner CRC-Berechnung ist auch das 
Verilog-pendant der SP601 Demo-files und das hat bisher immer korrekt 
funktioniert, wenn man es mit den richtigen Daten gefüttert hat.

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

> Du kannst noch ausprobieren, im die state_txout FSM als OneHot zu
> codieren, dann hast du wenigstens keine Glitches mehr... (aber irgendwie
> hat das eine starke Tendenz Richtung Murks)


>Ohne mir deinen Code angeschaut zu haben, folgendes Statement:
>Wenn du sowas machst, dann musst du mehrere Dinge sicherstellen
>1.) Das Steuersignal der Quell-Domäne darf nur 1 Bit breit sein, denn
>dann ist sichergestellt, dass es zu jeder Zeit in sich selbst konsistent
>ist. Also entweder "1" oder "0".


Ich habe als asynchronen Reset ein Signal, damit entgehe ich der Gefahr 
der Glitches bei der Änderung des Zustandsautomaten.

von René D. (Firma: www.dossmatik.de) (dose)


Angehängte Dateien:

Lesenswert?

Christian R. schrieb:
> Da war doch was mit 90° verschobenem Takt am Marvell Phy, oder?

Sehe eigentlich keinen 90° Takt.

: Bearbeitet durch User
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.