////////////////////////////////////////////////////////////////////// //// //// //// RxfifoBI.v //// //// //// //// This file is part of the spiMaster opencores effort. //// //// //// //// //// Module Description: //// //// //// //// //// To Do: //// //// //// //// //// Author(s): //// //// - Steve Fielding, sfielding@base2designs.com //// //// //// ////////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2004 Steve Fielding and OPENCORES.ORG //// //// //// //// This source file may be used and distributed without //// //// restriction provided that this copyright statement is not //// //// removed from the file and that any derivative work contains //// //// the original copyright notice and the associated disclaimer. //// //// //// //// This source file is free software; you can redistribute it //// //// and/or modify it under the terms of the GNU Lesser General //// //// Public License as published by the Free Software Foundation; //// //// either version 2.1 of the License, or (at your option) any //// //// later version. //// //// //// //// This source is distributed in the hope that it will be //// //// useful, but WITHOUT ANY WARRANTY; without even the implied //// //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// //// PURPOSE. See the GNU Lesser General Public License for more //// //// details. //// //// //// //// You should have received a copy of the GNU Lesser General //// //// Public License along with this source; if not, download it //// //// from //// //// //// ////////////////////////////////////////////////////////////////////// // `include "timescale.v" `include "spiMaster_defines.v" module RxfifoBI ( address, writeEn, strobe_i, busClk, spiSysClk, rstSyncToBusClk, fifoSelect, fifoDataIn, busDataIn, busDataOut, fifoREn, forceEmptySyncToSpiClk, forceEmptySyncToBusClk, numElementsInFifo ); input [2:0] address; input writeEn; input strobe_i; input busClk; input spiSysClk; input rstSyncToBusClk; input [7:0] fifoDataIn; input [7:0] busDataIn; output [7:0] busDataOut; output fifoREn; output forceEmptySyncToSpiClk; output forceEmptySyncToBusClk; input [15:0] numElementsInFifo; input fifoSelect; wire [2:0] address; wire writeEn; wire strobe_i; wire busClk; wire spiSysClk; wire rstSyncToBusClk; wire [7:0] fifoDataIn; wire [7:0] busDataIn; reg [7:0] busDataOut; reg fifoREn; reg forceEmptySyncToSpiClk; wire forceEmptySyncToBusClk; wire [15:0] numElementsInFifo; wire fifoSelect; reg [5:0] forceEmptyShift; reg forceEmpty; reg forceEmptySyncToUsbClkFirst; //sync write always @(posedge busClk) begin if (writeEn == 1'b1 && fifoSelect == 1'b1 && address == `FIFO_CONTROL_REG && strobe_i == 1'b1 && busDataIn[0] == 1'b1) forceEmpty <= 1'b1; else forceEmpty <= 1'b0; end //generate 'forceEmptySyncToBusClk' //assuming that 'busClk' < 5 * 'spiSysClk'. ie 'busClk' < 240MHz always @(posedge busClk) begin if (rstSyncToBusClk == 1'b1) forceEmptyShift <= 6'b000000; else begin if (forceEmpty == 1'b1) forceEmptyShift <= 6'b111111; else forceEmptyShift <= {1'b0, forceEmptyShift[5:1]}; end end assign forceEmptySyncToBusClk = forceEmptyShift[0]; // double sync across clock domains to generate 'forceEmptySyncToWrClk' always @(posedge spiSysClk) begin forceEmptySyncToUsbClkFirst <= forceEmptySyncToBusClk; forceEmptySyncToSpiClk <= forceEmptySyncToUsbClkFirst; end // async read mux always @(address or fifoDataIn or numElementsInFifo) begin case (address) `FIFO_DATA_REG : busDataOut <= fifoDataIn; `FIFO_DATA_COUNT_MSB : busDataOut <= numElementsInFifo[15:8]; `FIFO_DATA_COUNT_LSB : busDataOut <= numElementsInFifo[7:0]; default: busDataOut <= 8'h00; endcase end //generate fifo read strobe always @(address or writeEn or strobe_i or fifoSelect) begin if (address == `FIFO_DATA_REG && writeEn == 1'b0 && strobe_i == 1'b1 && fifoSelect == 1'b1) fifoREn <= 1'b1; else fifoREn <= 1'b0; end endmodule