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 件のコメント:
コメントを投稿