論理回路デザイン |
|
// Here is upper module // WIDTH indicates width of data word // DEPTHR indicates radix of depth of fifo fifo #(WIDTH, DEPTHR) fifo_0 ( .iVld (), ........ // Here is lower module module fifo ( iVld, iStall, iData, ........ parameter W = 32; parameter DR = 2; ........ input [W-1:0] iData;
/* **************************** MODULE PREAMBLE ******************************** Copyright (c) 2011, ArchiTek This document constitutes confidential and proprietary information of ArchiTek. All rights reserved. */ // ***************************** MODULE HEADER ********************************* module fifo ( iVld, iStall, iData, oVld, oStall, oData, reset, clk ); // ************************ PARAMETER DECLARATIONS ***************************** // 初期のパラメータ、上位モジュールで再定義のこと parameter W = 32; // Data Length parameter DR = 2; // Depth Radix // FIFOの深さ(2の累乗)を求める parameter D = 1<<DR; // *************************** I/O DECLARATIONS ******************************** // パイプライン入力、言及してきた信号名を合わせるためFullはStallに変更 input iVld; output iStall; input [W-1:0] iData; // パイプライン出力、言及してきた信号名を合わせるためBusy(not Empty)はoVldに変更 output oVld; input oStall; output [W-1:0] oData; // 一般的に必要なリセットとクロック // ユーザーによるソフトリセットを考慮して同期型のリセットを採用 input reset; input clk; // ************************** LOCAL DECLARATIONS ******************************* reg iStall; wire iStallD; reg oVld; wire oVldD; // 入力ポインター、MSBは周期、その他はデータ位置を示す reg [DR:0] iPtr; wire [DR:0] iPtrD; // 出力ポインター、MSBは周期、その他はデータ位置を示す // 入力側の周期情報だけで足りるが、記述簡単のためMSBに周期情報を残す reg [DR:0] oPtr; wire [DR:0] oPtrD; // データ出力はラッチ、なお下記の配列memと同一データを管理する冗長性が存在します reg [W-1:0] oData; // 入出力パルス、EmptyおよびFullの場合は論理的にアサートしない wire iAlloc = iVld & !iStall; wire oAlloc = oVld & !oStall; // FIFOの中身はレジスタで構成、FPGAツールではたいていSRAMへ自動マッピング reg [W-1:0] mem[0:D-1]; // ****************************** MODULE BODY ********************************** // ----------------------------------------------------------------------------- // Data FIFO // FIFOが空の場合は入力データが直接、そうでない場合は次のポインタが示すFIFOを出力FFにラッチ // 事前にFFのD端子信号を用意する方法でデータをラッチ、遅延の移動を参照 always @(posedge clk) if (iAlloc & (iPtr[DR-1:0] == oPtrD[DR-1:0])) oData <= #1 iData; else if (!oStall) oData <= #1 mem[oPtrD[DR-1:0]]; // FIFOにデータを入力、ここはiPtrによる選択のため組み合わせ回路がどうしても挿入される always @(posedge clk) if (iAlloc) mem[iPtr[DR-1:0]] <= #1 iData; // ----------------------------------------------------------------------------- // Data FIFO Pointer // iStallはFull、oVldはBusy(not Empty)に相当 // 事前にFFのD端子信号を用意する方法でデータをラッチ、遅延の移動を参照 // ポインターはインクリメント型でいきなり+2になることはなく、=か!=を用いたピンポイント比較でよい // ただし、FIFOポインタ内をランダムにアクセスする型は大小比較をする必要がある always @(posedge clk) if (reset) begin iStall <= #1 1'b0; oVld <= #1 1'b0; end else begin iStall <= #1 iStallD; oVld <= #1 oVldD; end always @(posedge clk) if (reset) begin iPtr <= #1 {DR+1{1'b0}}; oPtr <= #1 {DR+1{1'b0}}; end else begin iPtr <= #1 iPtrD; oPtr <= #1 oPtrD; end // ポインタがちょうど一周すればFull(これ以上は受け付けることができない) // Fullであっても出ていくデータがあればnot Fullに出来るがタイミングアークが切れなくなる(パス型) assign iStallD = (iPtrD[DR] != oPtrD[DR]) & (iPtrD[DR-1:0] == oPtrD[DR-1:0]); // ポインタが少しでも違えばBusy(not Empty) assign oVldD = (iPtrD != oPtrD); // LintのWarning(Bit長不一致)を消すには、見にくくなるがiAlloc → {{DR-1{1'b0}}, iAlloc} assign iPtrD = iPtr + iAlloc; assign oPtrD = oPtr + oAlloc; // ************************** FUNCTIONS and TASKS ****************************** endmodule // *****************************************************************************
回路デザイン > 設計例 [FIFO] > ここで扱うFIFO 次のページ(Threshold対応FIFO) このページのTOP ▲