https://www.update-gadget.com/blog/2020/09/24/implement-axi-stream-write1/
の続きです。AXI Stream masterの実装をします。昨日は、コードのテンプレを用意したので、中身を作っていく。
作りたいAXI Stream masterは、次のようなタイミングチャートになります。wavedramで作成しました。
master側の動作は、slave側のREADYがHighになったら、DATAをインクリメントする。16回転送したら最後に、lastを立てて終了する。stateは、master側の内部変数で、状態を管理している。大文字が外部の信号で、小文字が内部信号になる。
最初にstateの実装になります。READYがHighになったらSTATE_OUT状態になって、転送回数(stream_counter)が15回になったらSTREAM_END状態になるようにする。
always @( posedge M_AXIS_ACLK ) begin
if (M_AXIS_ARESETN) begin
if (state == STATE_IDLE) begin
if (M_AXIS_TREADY == 1'b1) begin
state <= STATE_OUT;
end
end else if (state == STATE_OUT) begin
if (stream_counter == 32'h0000_000f) begin
state <= STATE_END;
end
end
end
end
状態遷移ができたら状態とslaveからのREADYで&を取ってVALID信号を作っている。また、内部のvalid状態として使用する。
assign M_AXIS_TVALID = M_AXIS_TREADY & (state == STATE_OUT) ;
転送するデータは、VALIDが立っている時にインクエイメントしているデータを転送する。
assign M_AXIS_TDATA = stream_out;
always @( posedge M_AXIS_ACLK ) begin
if (M_AXIS_ARESETN) begin
if (M_AXIS_TVALID == 1'b1) begin
stream_out <= stream_out + 1;
end
end
end
転送終了を示すLASTは転送回数(stream_counter)を見て制御している。
always @( posedge M_AXIS_ACLK ) begin
if (M_AXIS_ARESETN) begin
if (stream_counter == 32'h0000_000e) begin
axis_tlast = 1'b1;
end else if (stream_counter == 32'h0000_000f) begin
axis_tlast = 1'b0;
end
end
end
まだ、本物のSlaveと接続したいないが、想定通り動作するか、シミュレータを実行した。いろいろ不具合を修正して、最初のタイミングチャートと同じ結果を得ることができたと思う。