2016-11-22 5 views
-1

VerilogでI2Sトランスミッタを実装しようとしています。それのためのデータシートは:https://www.sparkfun.com/datasheets/BreakoutBoards/I2SBUS.pdfI2SトランスミッタVerilogの実装が動作しない

私はコードを書いたが、私のSDラインは、私がテストすると1クロックサイクル遅れている。 私の実装をチェックできる人はいますか?

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:

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

詳細を追加してください - あなたのテストベンチコード、SDが遅れている波形、正確にどこに問題があるのでしょうか? – noobuntu

+0

'常に@(Q1)'は '常に@(Q1またはDRightまたはDLeft)'でなければなりません。 – Hida

+0

@Hida DRightとDLeftは一定の値ですが、私はQ1の変更を探しています。 Q1に基づいて、RまたはLのいずれかがTdataにロードされます – user1775297

答えて

1

あなたnegedgeブロックがif-else構造が含まれているとしか、単一の上、どちらか一方を計算します:ここで波形image

テストベンチCODEのイメージがありますクロックエッジ。したがってPLが高い場合、SDは値を変更しません。

さらに、コードにノンブロッキング割り当て(<=)を使用しています。これは、大まかには、変更がalwaysブロックの最後まで評価されないことを意味します。したがって、shift_reg <= Tdataの後にSD <= shift_reg[23]を指定しても、shift_reg[23]の新しい値は使用されませんが、以前の値が使用されます。 が変更されたときにすぐにSDを変更したい場合は、これを組み合わせて行う必要があります。

これは動作するはずです:

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]; 

の作業例:サイドノートでhttps://www.edaplayground.com/x/4bPv

を私はまだDRightDLeftが実際定数であることを納得していないよ、私は彼らがあなたのTBであることがわかりますI2Sのデータは一定ではありません。あなたの現在の構成はおそらく(MUXの代わりに)ラッチを生成するでしょう、我々は一般的に私たちの設計にそれらを望んでいません。

+0

DRightとDLeftが一定であると言えば、コード内のif-else文がそれらに依存しないことを意味します。私はQ1の値に基づいて、どちらか一方をtempdataの場所に単純にコピーしているためです。一般的には、DRightとDLeftは変更されますが、Q1が変更された場合にのみ、変更時にそれらを一時的な場所にコピーしていません。 Q1はDRightとDLeftのいずれかを選択します。シフトアウトされる。 – user1775297

+0

この修正はうまくいきました。今何を意味しているのか理解しています。 WSクロックサイクルを960nsに変更する必要もありました。しかし、すべてが今働く。ありがとうございました。 – user1775297

0

あなたは、非ブロッキング文対ブロックの使用をクリーンアップする必要があります

は常にクロックドステートメントでは、「< =」を意味、非ブロックassigmentsを使用しています。

combinational(非クロック)ステートメントでは常に "="を意味するブロックアシメントを使用してください。

これは業界全体の推奨事項であり、個人的な意見ではありません。

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

(@Hidaで指摘したように)不完全であることsensitivtityリストにも問題を引き起こすことがあります。あなたは、インスタンスを参照、この勧告に多くの場所を見つけることができます。

これら2つの問題を修正し、期待どおりに動作するかどうかを確認してください。

また、Q1(他の信号の中でも)を使用してPL信号を生成しています。 WS入力があなたのローカルクロックと同期していない場合(そうでないと仮定して)、メタスタビリティ問題を避けるために、出力を使用する前にもう1つのフロップ(直列2つ)を入れる必要があります。しかし、RTLシミュレーションではこれを見ることはできません。

関連する問題