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