組み込み屋の為のVerilog入門 その5 VALID&READYのハンドシェーク
<はじめに>
最近はXILINXが各コアでAXIバス(ARM社AMBAバス仕様の1つ)を使い始めていることもあって、VALIDとREADYでのハンドシェークを用いることが増えてきた。
この方式に限った話ではないのだが、バスプロトコル関係のハンドシェークがわかりにくいという声を聞く。そこでまずはAXIバスなどで採用されている VALIDとREADYのハンドシェーク方法に絞って、基本的な型を紹介してみようと思う。
<基本形>
まずは基本的な valid と ready でのハンドシェークによるパイプライン演算の1ステージ分の形。
基本は簡単で「自分のステージにデータが無い」、「次のステージがデータを受け入れてくれる」のどちらか一方以上の条件が整っていれば「自分のステージに次のデータを受け入れることが可能」すなわちREADYとなる。
ではREADYで無い場合どうするか。それは処理できないのだから「現状維持」であり、CKE を落とせばよい。
私も昔そうだったが、初心者が難しく考えてへんなコードを書いてしまいがちなので一度整理しておこう。
======================================================= // 基本型 module sample ( // system input wire clk, input wire reset, // slave port input wire [7:0] s_data, input wire s_valid, output wire s_ready, // master port output reg [7:0] m_data, output reg m_valid, input wire m_ready ); // m_valid が0(パイプラインの自ステージが空)か、m_ready が1(次のステージがREADY)の時 wire cke = ~m_valid | m_ready; always @(posedge clk) begin if ( reset ) begin m_data <= 8'bxx; // シミュレーション用にリセットで不定とする m_valid <= 1'b0; // end else begin if ( cke ) begin m_data <= s_data + 1; // 演算を行う m_valid <= s_valid; end end end assign s_ready = cke; endmodule =======================================================
<待ち合わせ>
次に2つの信号の待ち合わせ合成である。2つのデータが両方そろわないと演算ができないケースである。
ここではあえて組み合わせ回路だけで書いている。タイミング収束が問題になった場合の対処方法はまた別途機会があれば書くがまずは基本形。
======================================================= // 待ち合わせ合成 module rendezvous ( // system input wire clk, input wire reset, // slave port 0 input wire [7:0] s0_data, input wire s0_valid, output wire s0_ready, // slave port 1 input wire [7:0] s1_data, input wire s1_valid, output wire s1_ready, // master port output reg [7:0] m_data0, output reg [7:0] m_data1, output reg m_valid, input wire m_ready ); assign s0_ready = s1_valid & m_ready; // お隣と出力先がREADY assign s1_ready = s0_valid & m_ready; // お隣と出力先がREADY assign m_data0 = s0_data; assign m_data1 = s1_data; assign m_valid = s0_valid & s1_valid; endmodule =======================================================
<アービトレーション>
次にアービトレーションである。2つのデータのどちらか一方を調停しながら通す場合である。これもよくあるパターンだがそれほど難しくは無い。
下記は、絶対優先の例であるが、ラウンドロビンなどの方式にする場合も基本は変わらないのでまずはシンプルな例として見てほしい。
======================================================= // アービタ module arbiter ( // system input wire clk, input wire reset, // slave port 0 input wire [7:0] s0_data, input wire s0_valid, output wire s0_ready, // slave port 1 input wire [7:0] s1_data, input wire s1_valid, output wire s1_ready, // master port output reg [7:0] m_data0, output reg [7:0] m_data1, output reg m_valid, input wire m_ready ); assign s0_ready = m_ready; assign s1_ready = ~s0_valid & m_ready; // お隣と出力先がREADY assign m_data = s0_valid ? s0_data : s1_data; assign m_valid = s0_valid | s1_valid; endmodule =======================================================
まずはここまで。
タイミング収束にかかわるREADY系のFFの扱いとか、複数サイクルのデータをまとめる場合とかいろいろ発展パターンがあると思うのでリクエストがあれば考えたいと思う。
この記事を某S氏に捧げるw
« 自宅リフローへの道 初期投資まとめ | トップページ | 組み込み屋の為のVerilog入門 その6 続VALID&READYのハンドシェーク »
「FPGA」カテゴリの記事
- LUT-Networkの蒸留とMobileNet風構成とセマンティックセグメンテーション(2020.03.09)
- LUT-Networkの蒸留(Distillation)について(2019.12.29)
- FPGAでのDNN(Deep Neural Network)の整理(LUT-Netまとめ)(2019.12.15)
- LUT-NetのFPGAリソースについて(2019.12.08)
- MNIST認識のリアルタイム動作環境更新(2019.09.02)
この記事へのコメントは終了しました。
« 自宅リフローへの道 初期投資まとめ | トップページ | 組み込み屋の為のVerilog入門 その6 続VALID&READYのハンドシェーク »
コメント