木曜日, 3月 25, 2010

AMBA AXIのINCRバーストアドレスの計算

Photo by James Cridland
追記:
INCRバーストでアンアラインド転送の場合を考慮してなかったので、注意点を最後に追記しました。

以前にWRAPバーストアドレスの場合を書いたのですがついでなのでINCRバーストの場合も書いておこうと思います。
というか、むしろこっちの方を先に書いておくべきだったような気が。。。

さて、AXIでは1つのバーストのアドレスが4Kbyteの境界をまたいではいけないという制約があります。
したがって、アドレスのカウンタとしては12bitで十分ということになります。
ということで、INCRバーストのアドレスは次のようになります。

always @(posedge ACLK or negedge ARESETn) begin
  if (!ARESETn) begin
    addr_cnt <= 12'd0;
  end
  else begin
    if ( AWVALID && AWREADY ) begin
      if ( WVALID && WREADY )
        addr_cnt <= AWADDR[11:0] + ( 12'b1 << AWSIZE );
      else
        addr_cnt <= AWADDR[11:0];
    end
    else if ( WVALID && WREADY ) begin
      addr_cnt <= addr_cnt + ( 12'b1 << r_awsize );
    end
  end
end

なんだ、WRAPの場合と同じじゃないか!といわれそうですがその通りです。
なので通常はアドレスカウンタは1つだけ持っておいて、
WRAPバーストの場合は必要な下位のビットだけ使用すれば良いと思います。

もちろん、上位のビットはラッチしといてくださいね。


【追記】アンアラインド転送の場合の注意点
以上の記事を書いている時点では、アンアラインド転送の事を考慮していなかったため、このアドレスカウンタでは不十分な場合があります。
アンアラインドのアドレスをアラインさせるのは以下の方法で行えます。

Aligned_Address = Unaligned_Address & ( {(Addr_Width){1'b1}} << AWSIZE ) 

アドレスカウンタにロードする際にアドレスをアラインメントさせてスタートアドレスを別に記憶しておいてもいいと思いますし、
最初のカウントアップ(または全てのカウントアップ)の時にアラインメントする方法もあります。
もしくはアドレスの計算自体は上記の方法そのままで、出力するときにアラインメントするなど。
方法はいろいろ考えられますが、都合の良い実装方法で行ってください。

ただ実は、スレーブにおいては転送サイズさえ見ておいて、アドレスの下位の部分についてはWSTRBを信用すれば良いので、アドレスがちゃんと転送サイズにアラインメントされていようがいまいが関係なかったりします。

ブリッジなどの場合はアドレスを正しく伝える必要があるかもしれないのでその場合は注意してください。

0 件のコメント: