// (C) Tomonori Izumi , Aug. 2012. All rigts reserved. // いずみ研 valid/wait インターフェース サンプル回路 // 受け取ったら2段のパイプライン計算をして次に渡す // バースト(休止サイクル無し)動作が可能 // レジスタ出力:入力にFIFO(容量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 [15:0] data1_reg, data2_reg, data3_reg; reg valid1_reg, valid2_reg, valid3_reg; wire valid0,valid1,valid2,valid3; wire wait0,wait1,wait2,wait3; reg [15:0] fifo_reg[1:0]; reg [0:0] fifo_wp_reg, fifo_rp_reg; reg [1:0] fifo_cnt_reg; reg fifo_full_reg, fifo_empty_reg; assign valid0=~fifo_empty_reg; assign valid1=valid1_reg; assign valid2=valid2_reg; assign valid3=valid3_reg; assign wait0=wait1&valid1_reg; // 渋滞先読み assign wait1=wait2&valid2_reg; // 渋滞先読み assign wait2=wait3&valid3_reg; // 渋滞先読み assign wait3=owait; assign iwait=fifo_full_reg; // レジスタ出力(ここで筒抜けパスを切る) assign ovalid=valid3; assign odata=data3_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 // [PIPELINE STAGE1] FIFO always @(posedge clk or negedge xrst) begin if (!xrst) begin fifo_cnt_reg<=0; fifo_wp_reg<=0; fifo_rp_reg<=0; fifo_full_reg<=0; fifo_empty_reg<=1; end else begin if (ivalid&!iwait) begin // 受取成立 fifo_reg[fifo_wp_reg]<=idata; fifo_wp_reg<=fifo_wp_reg+1; if (!valid0|wait0) begin // 送出不成立(増加) fifo_cnt_reg<=fifo_cnt_reg+1; fifo_empty_reg<=0; fifo_full_reg<=(fifo_cnt_reg==1)?1:0; //次サイクルでfullか end end if (valid0&!wait0) begin // 送出成立 fifo_reg[fifo_rp_reg]<=16'hffff; // デバグ用(実際は不要) fifo_rp_reg<=fifo_rp_reg+1; if (!ivalid|iwait) begin // 受取不成立(減少) fifo_cnt_reg<=fifo_cnt_reg-1; fifo_full_reg<=0; fifo_empty_reg<=(fifo_cnt_reg==1)?1:0; //次サイクルでemptyか end end end end // [PIPELINE STAGE2] Receive from FIFO always @(posedge clk or negedge xrst) begin if (!xrst) begin data1_reg<=16'hffff; valid1_reg<=0; end else if (valid0&!wait0) begin // 受取成立 data1_reg<=fifo_reg[fifo_rp_reg]; valid1_reg<=1; end else if (valid1&!wait1) begin // 受取不成立かつ送出成立 data1_reg<=16'hffff; // デバグ用(実際は不要) valid1_reg<=0; end end // [PIPELINE STAGE3] Calculation 1 always @(posedge clk or negedge xrst) begin if (!xrst) begin data2_reg<=16'hffff; valid2_reg<=0; end else if (valid1&!wait1) begin // 受取成立 data2_reg<=calc1(data1_reg); // 1段目の計算 valid2_reg<=1; end else if (valid2&!wait2) begin // 受取不成立かつ送出成立 data2_reg<=16'hffff; // デバグ用(実際は不要) valid2_reg<=0; end end // [PIPELINE STAGE4] Calculation 2 always @(posedge clk or negedge xrst) begin if (!xrst) begin data3_reg<=16'hffff; valid3_reg<=0; end else if (valid2&!wait2) begin // 受取成立 data3_reg<=calc2(data2_reg); // 2段目の計算 valid3_reg<=1; end else if (valid3&!wait3) begin // 受取不成立かつ送出成立 data3_reg<=16'hffff; // デバグ用(実際は不要) valid3_reg<=0; end end endmodule