金曜日, 3月 12, 2010

AMBA AXIのWrapアドレスの計算

前回、AMBA AXIのWrap Boundaryを計算しました。

折角なのでWRAPバーストの場合のアドレスの計算もやってみようと思います。とは言ってもWrap Boundaryが算出できればそれほど難しくはありません。

まず前提条件ですが、AXIのWRAPバーストでは以下の制約があります。


・開始アドレスは転送サイズにアラインメントされていなければならない

・バースト長は2,4,8または16のいずれかでなければならない


なので、前回のBoundaryの計算も含め、ここではこの制約を前提としています。

さて、アドレスを計算するにはアドレスカウンタを作ると思いますがAXIのWRAPバーストの場合、このカウンタは何ビットのものが必要かというと、転送サイズとバースト長の最大値がそれぞれ128Byteと16ビートなので


log2(128*16) = 11ビット


となります。11ビットのライトアドレスカウンタをwaddr_cntとすると次のように書けます。

always @(posedge ACLK or negedge ARESETn) begin
  if (!ARESETn) begin
    waddr_cnt <= 11'd0;
  end
  else begin
    if ( AWVALID && AWREADY ) begin
      if ( WVALID && WREADY )
        waddr_cnt <= AWADDR[10:0] + ( 11'b1 << AWSIZE );
      else
        waddr_cnt <= AWADDR[10:0];
    end
    else if ( WVALID && WREADY ) begin
      waddr_cnt <= waddr_cnt + ( 11'b1 << r_awsize );
    end
  end
end
ここで、r_awsizeはAWSIZEをラッチしたものです。データチャネルがアドレスチャネルよりも先に成立する場合は考慮してません。
そうならないよう、WREADYを制御する(;^_^A
あらかじめ断っておきますが、このコードは実際に検証を行っていませんのでちゃんと動くかどうかわかりません。なんとなくこんな感じで実装できるよというのがわかっていただければ幸いです。
あとはこのアドレスカウンタと前回計算したWrap BoundaryをくっつければWRAPバースト時のアドレスが決まります。こんな感じですね。
assign wrap_waddr = Wrap_Boundary | ( waddr_cnt & ~( { {(Addr_Width-4){1'b1}}, ~r_awlen } << r_awsize ) );
Addr_Widthはアドレスの幅で、r_awlenはAWLENをラッチしたものです。実際は転送サイズは16Byteまでなどといった場合が多いと思うのでカウンタのサイズはもう少し小さくできると思います。

0 件のコメント: