![]() |
10 |
BSVによるAXIモジュールの設計 |
Claude Codeがbsc環境を持てるということで、AXIのコードを書いて貰いました。今まではChatレベルではAIの想像でコードを書いていました。従ってコードベースの多いPython等は100%一発動作しましたが、逆に少ないBSVではSyntax errorも頻発していました。
AXI4-Lite ハンドシェイク チュートリアル
ブロック図を示します。

スレーブは AxiRegs.bsv、32bit レジスタ4本を 0x00、0x04、0x08、0x0C に持つ Full 版です。テストベンチ TbTut.bsv はマスタ側の信号を1本ずつレジスタで直接駆動し、スレーブの応答を Wire で観測します。トランザクタも FIFO も使いません。何を見て何を出すかを、文の並びがそのまま示すためです。
波形は bsc が生成した Verilog を iverilog で走らせた verilog.vcd から取り、1サイクルは 10 単位です。上から、場面番号、CLK、書き込みアドレスチャネル AW、書き込みデータチャネル W、書き込み応答チャネル B、読み出しアドレスチャネル AR、読み出しデータチャネル R、そしてマスタが記録した値とスレーブのレジスタです。
0. 規則はこれだけ
AXI4-Lite の5チャネルは全て同じ握手で動きます。送り手が valid を立て、受け手が ready を立て、両方が立っているクロックの立ち上がりで1件が渡ります。送り手は valid を立てたら ready が来るまで下ろしてはならず、その間データを変えてはいけません。valid を ready に依存させてはいけません。ready は valid を見て決めて構いません。チャネルは互いに独立で、AW と W の成立順に決まりはなく、B は AW と W の両方が成立した後にだけ出ます。
送り手を StmtFSM で書くときの型は次のとおりです。
function Stmt putAW (Addr a) = seq
action awvalid <= True; awaddr <= a; endaction // 次のサイクルからバスに出る
while (!awready) noAction; // ready が立つサイクルまで待つ
awvalid <= False; // 立ったその同じサイクルに下ろす
endseq;
while を抜けた同じサイクルに次の文が実行されるので(つまり最初からawready==Trueならwhileは0サイクル)、valid は ready を見たサイクルだけ立ち、転送はちょうど1件になります。await (awready) と書くと次の文が1サイクル遅れて valid が2サイクル残り、二重転送になります。この差は測って確かめました。
受け手側は ready を立てたまま valid を待ちます。
function Stmt getB = seq
while (!bvalid) noAction; // bready は立てたまま
bRespReg <= bresp; // 成立したサイクルに応答を読む
endseq;
これもwhile を抜けた同じサイクルに次の文が実行されます(つまり最初からbvalid==Trueならwhileは0サイクル)。








