////////////////////////////////////////////////////////////////////// //// //// //// readWriteSPIWireData.v //// //// //// //// This file is part of the spiMaster opencores effort. //// //// //// //// //// Module Description: //// //// parameterized dual clock domain fifo. //// fifo depth is restricted to 2^ADDR_WIDTH //// No protection against over runs and under runs. //// //// //// //// 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 readWriteSPIWireData (clk, clkDelay, rst, rxDataOut, rxDataRdySet, spiClkOut, spiDataIn, spiDataOut, txDataEmpty, txDataFull, txDataFullClr, txDataIn); input clk; input [7:0]clkDelay; input rst; input spiDataIn; input txDataFull; input [7:0]txDataIn; output [7:0]rxDataOut; output rxDataRdySet; output spiClkOut; output spiDataOut; output txDataEmpty; output txDataFullClr; wire clk; wire [7:0]clkDelay; wire rst; reg [7:0]rxDataOut, next_rxDataOut; reg rxDataRdySet, next_rxDataRdySet; reg spiClkOut, next_spiClkOut; wire spiDataIn; reg spiDataOut, next_spiDataOut; reg txDataEmpty, next_txDataEmpty; wire txDataFull; reg txDataFullClr, next_txDataFullClr; wire [7:0]txDataIn; // diagram signals declarations reg [3:0]bitCnt, next_bitCnt; reg [7:0]clkDelayCnt, next_clkDelayCnt; reg [7:0]rxDataShiftReg, next_rxDataShiftReg; reg [7:0]txDataShiftReg, next_txDataShiftReg; // BINARY ENCODED state machine: rwSPISt // State codes definitions: `define WT_TX_DATA 2'b00 `define CLK_HI 2'b01 `define CLK_LO 2'b10 `define ST_RW_WIRE 2'b11 reg [1:0]CurrState_rwSPISt, NextState_rwSPISt; // Diagram actions (continuous assignments allowed only: assign ...) // diagram ACTION // Machine: rwSPISt // NextState logic (combinatorial) always @ (txDataFull or txDataIn or clkDelayCnt or clkDelay or txDataShiftReg or bitCnt or rxDataShiftReg or spiDataIn or rxDataRdySet or txDataEmpty or txDataFullClr or spiClkOut or spiDataOut or rxDataOut or CurrState_rwSPISt) begin NextState_rwSPISt <= CurrState_rwSPISt; // Set default values for outputs and signals next_rxDataRdySet <= rxDataRdySet; next_txDataEmpty <= txDataEmpty; next_txDataShiftReg <= txDataShiftReg; next_rxDataShiftReg <= rxDataShiftReg; next_bitCnt <= bitCnt; next_clkDelayCnt <= clkDelayCnt; next_txDataFullClr <= txDataFullClr; next_spiClkOut <= spiClkOut; next_spiDataOut <= spiDataOut; next_rxDataOut <= rxDataOut; case (CurrState_rwSPISt) // synopsys parallel_case full_case `WT_TX_DATA: begin next_rxDataRdySet <= 1'b0; next_txDataEmpty <= 1'b1; if (txDataFull == 1'b1) begin NextState_rwSPISt <= `CLK_HI; next_txDataShiftReg <= txDataIn; next_rxDataShiftReg <= 8'h00; next_bitCnt <= 4'h0; next_clkDelayCnt <= 8'h00; next_txDataFullClr <= 1'b1; next_txDataEmpty <= 1'b0; end end `CLK_HI: begin next_clkDelayCnt <= clkDelayCnt + 1'b1; next_txDataFullClr <= 1'b0; next_rxDataRdySet <= 1'b0; if (clkDelayCnt == clkDelay) begin NextState_rwSPISt <= `CLK_LO; next_spiClkOut <= 1'b0; next_spiDataOut <= txDataShiftReg[7]; next_txDataShiftReg <= {txDataShiftReg[6:0], 1'b0}; next_clkDelayCnt <= 8'h00; end end `CLK_LO: begin next_clkDelayCnt <= clkDelayCnt + 1'b1; if ((bitCnt == 4'h8) && (txDataFull == 1'b1)) begin NextState_rwSPISt <= `CLK_HI; next_rxDataRdySet <= 1'b1; next_rxDataOut <= rxDataShiftReg; next_txDataShiftReg <= txDataIn; next_bitCnt <= 3'b000; next_clkDelayCnt <= 8'h00; next_txDataFullClr <= 1'b1; end else if (bitCnt == 4'h8) begin NextState_rwSPISt <= `WT_TX_DATA; next_rxDataRdySet <= 1'b1; next_rxDataOut <= rxDataShiftReg; end else if (clkDelayCnt == clkDelay) begin NextState_rwSPISt <= `CLK_HI; next_spiClkOut <= 1'b1; next_bitCnt <= bitCnt + 1'b1; next_clkDelayCnt <= 8'h00; next_rxDataShiftReg <= {rxDataShiftReg[6:0], spiDataIn}; end end `ST_RW_WIRE: begin next_bitCnt <= 4'h0; next_clkDelayCnt <= 8'h00; next_txDataFullClr <= 1'b0; next_rxDataRdySet <= 1'b0; next_txDataShiftReg <= 8'h00; next_rxDataShiftReg <= 8'h00; next_rxDataOut <= 8'h00; next_spiDataOut <= 1'b0; next_spiClkOut <= 1'b0; next_txDataEmpty <= 1'b0; NextState_rwSPISt <= `WT_TX_DATA; end endcase end // Current State Logic (sequential) always @ (posedge clk) begin if (rst == 1'b1) CurrState_rwSPISt <= `ST_RW_WIRE; else CurrState_rwSPISt <= NextState_rwSPISt; end // Registered outputs logic always @ (posedge clk) begin if (rst == 1'b1) begin rxDataRdySet <= 1'b0; txDataEmpty <= 1'b0; txDataFullClr <= 1'b0; spiClkOut <= 1'b0; spiDataOut <= 1'b0; rxDataOut <= 8'h00; txDataShiftReg <= 8'h00; rxDataShiftReg <= 8'h00; bitCnt <= 4'h0; clkDelayCnt <= 8'h00; end else begin rxDataRdySet <= next_rxDataRdySet; txDataEmpty <= next_txDataEmpty; txDataFullClr <= next_txDataFullClr; spiClkOut <= next_spiClkOut; spiDataOut <= next_spiDataOut; rxDataOut <= next_rxDataOut; txDataShiftReg <= next_txDataShiftReg; rxDataShiftReg <= next_rxDataShiftReg; bitCnt <= next_bitCnt; clkDelayCnt <= next_clkDelayCnt; end end endmodule