2016-11-22 3 views
-1

Ich versuche den I2S Transmitter in Verilog zu implementieren. Das Datenblatt dafür ist: https://www.sparkfun.com/datasheets/BreakoutBoards/I2SBUS.pdfI2S Transmitter Verilog Implementierung funktioniert nicht

Ich schrieb den Code, aber meine SD-Linie ist 1 Takt verzögert, wenn ich es teste. Kann jemand meine Implementierung überprüfen?

module Transmiter(
    input signed [23:0] DLeft, input signed [23:0] DRight, input WS, input CLK, 
    output reg SD 
    ); 

    wire PL; 
    reg Q1,Q2; 
    reg [23:0] shift_reg; 
    reg [23:0] Tdata; 


    assign PL = Q1^Q2; 



    always @(posedge CLK) 
    begin 
     Q1 <= WS; 
     Q2 <= Q1; 
    end 


    always @(Q1) begin 
     if (Q1) 
     begin 
     Tdata <= DRight; 
     end 
     else 
      begin 
      Tdata <= DLeft; 
      end 
    end 



    always @(negedge CLK) 
     begin 

      if(PL) 
      begin 
       shift_reg <= Tdata; 
      end 
      else begin 

      SD <= shift_reg[23]; 
      shift_reg <= {shift_reg[22:0],1'b0}; 
      end 
     end 


endmodule 

EDIT: Hier ist ein Bild der Wellenform image

PRüFSTAND Code:

module Transmitter_tb(

    ); 


    reg CLK, WS; 
    reg [23:0] dataL; 
    reg [23:0] dataR; 

    wire SDout; 



    Transmiter UT(dataL, dataR, WS, CLK, SDout); 

    initial begin 
    dataL = 24'hF0F0FF; #2; 
    dataR = 24'h0000F0; #2; 

    end 



    always begin 
    CLK=0; #20; 
    CLK=1; #20; 
    end; 

     always begin 
    WS=0; #1000; 
    WS=1; #1000; 
    end; 





endmodule 
+0

Bitte fügen Sie weitere Details hinzu - Ihre Testbench-Code, Ihre Wellenform, wo Sie SD verzögert sehen, und wo genau ist das Problem? – noobuntu

+0

'immer @ (Q1)' sollte 'immer @ (Q1 oder DRight oder DLeft) 'nicht sicher sein, wenn das das Problem ist. – Hida

+0

@Hida DRight und DLeft sind konstante Werte, ich bin auf der Suche nach der Veränderung in Q1. Basierend auf Q1 wird entweder R oder L in Tdata geladen – user1775297

Antwort

1

Ihr negedge Block enthält ein if-else Konstrukt und wird immer nur eine berechnen oder die andere auf einem einzigen Uhrenkante. SD wird daher den Wert nicht ändern, wenn PL hoch ist.

Außerdem verwenden Sie in Ihrem Code nicht blockierende Zuordnungen (<=). Dies bedeutet in etwa, dass Änderungen erst am Ende des Always-Blocks ausgewertet werden. Also selbst wenn SD <= shift_reg[23] nach shift_reg <= Tdata wird es nicht den neuen Wert in shift_reg[23] übernehmen aber den vorherigen Wert verwenden. Wenn Sie möchten, dass SD sofort geändert wird, wenn shift_reg[23] ändert, müssen Sie dies kombinatorisch tun.

sollte diese Arbeit:

always @(negedge CLK) 
    begin 

     if(PL) 
     begin 
      shift_reg <= Tdata; 
     end 
     else 
      shift_reg <= {shift_reg[22:0],1'b0}; 
    end 
    assign SD = shift_reg[23]; 

Arbeitsbeispiel: https://www.edaplayground.com/x/4bPv

Auf einer Seite zur Kenntnis davon überzeugt, ich bin immer noch nicht, dass DRight und DLeft tatsächlich Konstanten sind, kann ich sehen, dass sie in Ihrem TB aber es macht keinen Sinn, dass die Daten für Ihr I2S konstant sind. Ihr aktuelles Konstrukt wird wahrscheinlich ein Latch (anstelle eines MUX) erzeugen, und wir wollen diese im Allgemeinen nicht in unserem Design.

+0

Wenn ich sage, dass DRight und DLeft konstant sind, meine ich, dass meine if-else-Anweisung im Code nicht von ihnen abhängt. Weil ich einfach eins von ihnen zu einem tempdata Standort auf dem Wert von Q1 kopiere. Im Allgemeinen, ja, DRight und DLeft werden sich ändern, aber ich werde sie nicht an einen temporären Speicherort kopieren, wenn sie sich ändern, nur wenn Q1 sich ändert. Q1 wählt entweder DRight oder DLeft. verschoben werden. – user1775297

+0

Dieser Fix hat funktioniert, und ich verstehe, was Sie jetzt meinen. Ich musste auch den WS-Taktzyklus auf 960ns ändern. Aber alles funktioniert jetzt. Vielen Dank. – user1775297

0

Sie sollten Ihre Nutzung der Blockierung im Vergleich zu nicht-blockierende Aussagen aufzuräumen:

Verwenden Sie nicht blockierende assigments „< =“, in getakteten Aussagen Bedeutung.

Verwenden Sie in kombinatorischen (nicht getakteten) Anweisungen immer blockierende Aufgaben, dh "=".

Dies ist eine branchenweite Empfehlung, keine persönliche Meinung. Sie können diese Empfehlung viele Orte finden, siehe zum Beispiel:

http://web.mit.edu/6.111/www/f2007/handouts/L06.pdf

Die sensitivtity Liste (wie erwähnt durch @Hida) Probleme verursachen kann auch unvollständig ist.

Versuchen Sie, diese beiden Dinge zu korrigieren, und sehen Sie, ob es mehr wie erwartet funktioniert.

Beachten Sie auch, dass Sie Q1 (neben anderen Signalen) verwenden, um Ihr PL-Signal zu generieren. Wenn der WS-Eingang nicht synchron mit Ihrer lokalen Uhr ist (wie ich annehme, ist es nicht), müssen Sie einen weiteren Flop setzen (d. H. Zwei in Reihe), bevor Sie mit der Ausgabe beginnen, um Metastabilitätsprobleme zu vermeiden. Aber Sie werden das in einer RTL-Simulation nicht sehen.

Verwandte Themen