SSブログ

部品:AXIストリームレジスタ続き [AXI]

前回、
「値が有効を示す"valid"ももう一本増えます。」
って終わりましたが、いきなり訂正。増えません。

いや、正確には「必要だと思って作り始めたら実はいらなかったので消した」です。
ソースコード見直したらコメント残してましたよ。えらいぞ>過去の自分。でももうちょっとわかりやすく書こうな。
それにしてもまぁ自分の記憶の当てにならないこと。こういう文章書くと見直しになります。

どうせなので増やして設計始めた所から書いてみます。構成としてはこんな感じ。未接続のレジスタの値を制御することになります。
axis_slice.png回路3

状態数を数えます。t_valid, m_ready, m_valid, s_ready, s_validの5本なので32個です。制御対象はt_valid, m_valid, s_ready、データレジスタはt_dataとm_dataです。これらをとりあえず羅列します。あまり頭使ってません。
{t_valid, m_ready, m_valid, s_ready, s_valid} -> {tv,mr,mv,sr,sv}
{t_data, m_data, s_data} -> {td,md,sd}
tvmrmvsrsvtvmvsrtdmd
0 x 0 0 0 0 0 1 never1
0 x 0 0 1 0 0 1 never1
0 x 0 1 0 0 0 1 受信待ち
0 x 0 1 1 0 1 1 sdm_data受信
0 0 1 0 0 0 1 1 never1
0 0 1 0 1 0 1 1 never1
0 0 1 1 0 0 1 1 受信待ち
0 0 1 1 1 1 1 0sd t_data受信。これ以上は受け取れない
0 1 1 0 0 0 0 1 never1
0 1 1 0 1 0 0 1 never1
0 1 1 1 0 0 0 1 m_data送信。空になる
0 1 1 1 1 0 1 1 sdm_data送信と同時に受信
1 x 0 0 0 0 1 1 tdnever12
1 x 0 0 1 0 1 1 tdnever12
1 x 0 1 0 0 1 1 tdnever2
1 x 0 1 1 1 1 0sdtdnever2
1 0 1 0 0 1 1 0 空き待ち
1 0 1 0 1 1 1 0 空き待ち
1 0 1 1 0 illegal
1 0 1 1 1 illegal
1 1 1 0 0 0 1 1 tdm_data送信。t_data送信準備
1 1 1 0 1 0 1 1 tdm_data送信。t_data送信準備
1 1 1 1 0 illegal
1 1 1 1 1 illegal

しばらく眺めます。…この表をそのままcase文にしてもそれはそれで良いかな…無駄なロジックがあるかもしれませんが、今のシリコンからしたら微々たるものとして、もしくはコンパイラががんばるとして「完成」としても良さそうです。物を作ることが目的で最適化が必須とは限りません。さらに、全ての状態を洗い出してるので不定状態がないという安心感も。illegalの所はシミュレーションで$stopさせるとか。

ちゃんと眺めます(笑)
・出力側を見ると、常にt_valid = not s_readyです。これは「t_dataレジスタが埋まってたらもうデータは受け取れない」と読めば当たり前です。ですので、増やしたt_valid信号はいらないのでした。けど思考補助にはなってます。
・t_valid=0もしくはm_valid=0の時、つまりどちらかのレジスタが空いているときに、s_readyを0に(受信拒否)にする理由はありません。この状態も必要ありません(never1の部分)。
・t_valid=1かつm_valid=0の条件、m_dataが空いてるのにt_dataだけにデータが存在するという状態はあり得ないので、この項目は全部消えます(never2の部分)。
・t_valid=1かつm_valid=1、両方のレジスタが埋まってる状態でs_readyを1にするのは違反です(illegalの部分)。s_validが1になったらデータロストを起こします。同時にm_ready=1ならシフトレジスタ動作になってロストしませんが、そのためにはs_readyを組み合わせ回路にする必要があります。

表の不要部分を削除します。
mrmvsrsvmvsrtdmd
x 0 0 x 0 1 リセット状態
x 0 1 0 0 1 受信待ち
x 0 1 1 1 1 sdm_data受信
0 1 1 0 1 1 受信待ち
0 1 1 1 1 0sd t_data受信。これ以上は受け取れない
1 1 1 0 0 1 m_data送信。空になる
1 1 1 1 1 1 sdm_data送信と同時に受信
0 1 0 0 1 0 空き待ち
0 1 0 1 1 0 空き待ち
1 1 0 0 1 1 tdm_data送信。t_data送信準備
1 1 0 1 1 1 tdm_data送信。t_data送信準備

不要とした部分の一つが残ってますが、これをリセット状態とします。
「受信待ち」をリセット状態としても良さそうですが、m_validはともかく、s_readyが1になるのは問題です。全てのモジュールが同時にリセット解除されるという保証が無く、こちらのリセット解除の前に前段のリセットが解除されvalidが1にされた場合、データが失われます。s_readyはリセット中は0で解除後に1にします。
ほか、網掛けの「受信待ち」「空き待ち」は信号が動かないので記述する必要はありません。結果記述する条件は7個となります。
これをHDL化。
module    axis_slice
#(
    parameter  dw = 0        // Data Width
)
(
    // common
    input  wire          c_clk,      // clock
    input  wire          c_rst,      // reset
    // stream-in, sink,  slave
    output wire          s_ready,    // ready
    input  wire          s_valid,    // valid
    input  wire [dw-1:0] s_data ,    // data
    // stream-out, source, master
    input  wire          m_ready,    // ready
    output wire          m_valid,    // valid
    output reg  [dw-1:0] m_data      // data
);
    reg    [dw-1:0] t_data;
    reg    [2:1]    mvsr;
    assign {m_valid,s_ready} = mvsr;

    always @(posedge c_clk) begin
        casex ({c_rst,m_ready,m_valid,s_ready,s_valid})
            5'b1xxxx : begin  mvsr <= 2'b00;                     end
            5'b0x00x : begin  mvsr <= 2'b01;                     end
            5'b0x011 : begin  mvsr <= 2'b11;  m_data <= s_data;  end
            5'b00111 : begin  mvsr <= 2'b10;  t_data <= s_data;  end
            5'b01110 : begin  mvsr <= 2'b01;                     end
            5'b01111 : begin  mvsr <= 2'b11;  m_data <= s_data;  end
            5'b0110x : begin  mvsr <= 2'b11;  m_data <= t_data;  end
        endcase
    end
endmodule
表をそのままcaseにしただけ。
ただし、この記述にするときはちゃんとコメントや文章残しましょう。でないと後から見ると「ナニコレ?」状態になります。if~then~elseで書き直せばソースでもある程度意味がわかる記述になりますが、やっぱりコメントは残しましょう。

詠み人知らずの格言:昨日の自分は別の人。


追記
・c_rstもcase文の条件に入れてしまってます。普通の書き方(if (c_rst) ~ else case ~)にしてもリソース、速度ともに変わらなかったので(ISE S6でテスト)そのままにしてます。条件によっては変わるかも。
・「m_data <= s_data;」の記述を動作に関係ない所(例えば5'b01110のライン)に書くと、データラッチ条件のデコードビットが減って回路が小さく速くなる可能性があります。S6では変わりませんでした。
合成結果見たところ、がっつり最適化してくれてるようです。ありがたや~

追記その2
この回路、意外と入力のファンアウトが多いです。それが原因の問題には今のところ当たったことは無いですが、もし当たったら厄介そうです。
入力もレジスタ化するのは結構難儀なので、当たったときに考えようかと…(笑)

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。