論理回路デザイン |
|
// ----------------------------------------------------------------------------- // Data FIFO 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]]; always @(posedge clk) if (iAlloc) mem[iPtr[DR-1:0]] <= #1 iData;
// ----------------------------------------------------------------------------- // Data FIFO dualSRAM #(W, DR) sram_0 ( .WE (iAlloc), .WA (iPtr[DR-1:0]), .WD (iData), .RE (!oStall), .RA (oPtr[DR-1:0]), .RD (oData), .CK (clk) );
/* **************************** 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 parameter D = 1<<DR; // *************************** I/O DECLARATIONS ******************************** input iVld; output iStall; input [W-1:0] iData; output oVld; input oStall; output [W-1:0] oData; input reset; input clk; // ************************** LOCAL DECLARATIONS ******************************* reg iStall; wire iStallD; reg oVld; wire oVldD; reg [DR:0] iPtr; wire [DR:0] iPtrD; reg [DR:0] oPtr; wire [DR:0] oPtrD; reg [W-1:0] oData; reg [W-1:0] lData; reg ramHD; // SRAMポートを定義、SRAMをモジュール外に置く場合は外部ポートに変更 wire ramWE; wire [DR-1:0] ramWA; wire [W-1:0] ramWD; wire ramRE; wire [DR-1:0] ramRA; wire [W-1:0] ramRD; wire iAlloc = iVld & !iStall; wire oAlloc = oVld & !oStall; // ****************************** MODULE BODY ********************************** // ----------------------------------------------------------------------------- // Data FIFO // FIFOが空の場合は入力データが直接、そうでない場合はポインタの衝突信号を見てラッチ always @(posedge clk) if (iAlloc & (iPtr[DR-1:0] == oPtrD[DR-1:0])) oData <= #1 iData; else if (!oStall) oData <= #1 ramHD ? ramRD : lData; // 入力データを一旦FF受け(衝突時のみ) always @(posedge clk) if (!ramRE) lData <= #1 iData; // ポインタの非衝突を保持 always @(posedge clk) if (reset) ramHD <= #1 1'b0; else ramHD <= #1 ramRE; assign ramWE = iAlloc; assign ramWA = iPtr[DR-1:0]; assign ramWD = iData; // Read Enableが非衝突を示し、衝突時はReadをしない // 衝突はFIFOが空の場合にしか発生しないので、SRAMに格納しなくても取りこぼしはない assign ramRE = !ramWE | (ramWA != ramRA); // ポインタを1つ先行してReadする assign ramRA = oPtrD[DR-1:0] + 1'b1; // 2ポートSRAMをコール、モジュール名は説明のため簡単化 dualSRAM #(W, DR) sram_0 ( .WE (ramWE), .WA (ramWA), .WD (ramWD), .RE (ramRE), .RA (ramRA), .RD (ramRD), .CK (clk) ); // ----------------------------------------------------------------------------- // Data FIFO Pointer // これ以降の記述は従来と変わらず 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 assign iStallD = (iPtrD[DR] != oPtrD[DR]) & (iPtrD[DR-1:0] == oPtrD[DR-1:0]); assign oVldD = (iPtrD != oPtrD); assign iPtrD = iPtr + iAlloc; assign oPtrD = oPtr + oAlloc; // ************************** FUNCTIONS and TASKS ****************************** endmodule // *****************************************************************************
回路デザイン > 設計例 [FIFO] > >SRAMを使用したFIFO 次のページ(非同期FIFO) このページのTOP ▲