// (C) Tomonori Izumi , Aug. 2012. All rigts reserved. // いずみ研 valid/wait インターフェース サンプル回路 // マルチサイクル演算の例 // 受け取ったら2クロック計算して次に渡す // わかりやすさ優先の実装 // 状態、サイクルの無駄あり module ifsmpl (xrst,clk, idata,ivalid,iwait, odata,ovalid,owait); input xrst,clk; input [15:0] idata; input ivalid; output iwait; output [15:0] odata; output ovalid; input owait; reg iwait_reg; reg [15:0] odata_reg; reg ovalid_reg; reg [2:0] state; parameter STATE_RECEIVE0 = 3'b000; parameter STATE_RECEIVE = 3'b001; parameter STATE_CALC1 = 3'b010; parameter STATE_CALC2 = 3'b011; parameter STATE_TRANSMIT0 = 3'b100; parameter STATE_TRANSMIT = 3'b101; reg [15:0] data; assign iwait=iwait_reg; assign ovalid=ovalid_reg; assign odata=odata_reg; // 何らかの計算1 function [15:0] calc1; input [15:0] data; begin calc1=data; // 「何もしない」という計算 end endfunction // 何らかの計算2 function [15:0] calc2; input [15:0] data; begin calc2=data; // 「何もしない」という計算 end endfunction // メインステートマシン always @(posedge clk or negedge xrst) begin if (!xrst) begin state<=STATE_RECEIVE; // iwait=0 で開始するので受信状態から開始 iwait_reg<=0; ovalid_reg<=0; odata_reg<=16'hffff; data<=16'hffff; end else begin case (state) STATE_RECEIVE0: begin iwait_reg<=0; // 受信可(次のサイクルで反映) state<=STATE_RECEIVE; end STATE_RECEIVE: begin if (ivalid&!iwait) begin data<=idata; // データ受信 iwait_reg<=1; // 次から受信不可 state<=STATE_CALC1; end end STATE_CALC1: begin data<=calc1(data); state<=STATE_CALC2; end STATE_CALC2: begin data<=calc2(data); state<=STATE_TRANSMIT0; end STATE_TRANSMIT0: begin odata_reg<=data; // 送信データ ovalid_reg<=1; // 送信可(次のサイクルで反映) state<=STATE_TRANSMIT; end STATE_TRANSMIT: begin if (ovalid&!owait) begin odata_reg<=16'hffff; // デバグ用(実際は不要) ovalid_reg<=0; // 次から送信不可 state<=STATE_RECEIVE0; end end endcase end end endmodule // ifsmpl