123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
-
- //////////////////////////////////////////////////////////////////////
- //// ////
- //// serialInterface.v ////
- //// ////
- //// This file is part of the i2cSlave opencores effort.
- //// <http://www.opencores.org/cores//> ////
- //// ////
- //// Module Description: ////
- //// Perform all serial to parallel, and parallel
- //// to serial conversions. Perform device address matching
- //// Handle arbitrary length I2C reads terminated by NAK
- //// from host, and arbitrary length I2C writes terminated
- //// by STOP from host
- //// The second byte of a I2C write is always interpreted
- //// as a register address, and becomes the base register address
- //// for all read and write transactions.
- //// I2C WRITE: devAddr, regAddr, data[regAddr], data[regAddr+1], ..... data[regAddr+N]
- //// I2C READ: data[regAddr], data[regAddr+1], ..... data[regAddr+N]
- //// Note that when regAddR reaches 255 it will automatically wrap round to 0
- //// ////
- //// To Do: ////
- ////
- //// ////
- //// Author(s): ////
- //// - Steve Fielding, sfielding@base2designs.com ////
- //// ////
- //////////////////////////////////////////////////////////////////////
- //// ////
- //// Copyright (C) 2008 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 <http://www.opencores.org/lgpl.shtml> ////
- //// ////
- //////////////////////////////////////////////////////////////////////
- //
- `include "timescale.v"
- `include "i2cSlave_define.v"
-
- module serialInterface (clearStartStopDet, clk, dataIn, dataOut, regAddr, rst, scl, sdaIn, sdaOut, startStopDetState, writeEn);
- input clk;
- input [7:0]dataIn;
- input rst;
- input scl;
- input sdaIn;
- input [1:0]startStopDetState;
- output clearStartStopDet;
- output [7:0]dataOut;
- output [15:0]regAddr;
- output sdaOut;
- output writeEn;
-
- reg clearStartStopDet, next_clearStartStopDet;
- wire clk;
- wire [7:0]dataIn;
- reg [7:0]dataOut, next_dataOut;
- reg [15:0]regAddr, next_regAddr;
- reg regAddr_hiByte = 1'b0; //high and low byte of regAddr
- wire rst;
- wire scl;
- wire sdaIn;
- reg sdaOut, next_sdaOut;
- wire [1:0]startStopDetState;
- reg writeEn, next_writeEn;
-
- // diagram signals declarations
- reg [2:0]bitCnt, next_bitCnt;
- reg [7:0]rxData, next_rxData;
- reg [1:0]streamSt, next_streamSt;
- reg [7:0]txData, next_txData;
-
- // BINARY ENCODED state machine: SISt
- // State codes definitions:
- `define START 4'b0000
- `define CHK_RD_WR 4'b0001
- `define READ_RD_LOOP 4'b0010
- `define READ_WT_HI 4'b0011
- `define READ_CHK_LOOP_FIN 4'b0100
- `define READ_WT_LO 4'b0101
- `define READ_WT_ACK 4'b0110
- `define WRITE_WT_LO 4'b0111
- `define WRITE_WT_HI 4'b1000
- `define WRITE_CHK_LOOP_FIN 4'b1001
- `define WRITE_LOOP_WT_LO 4'b1010
- `define WRITE_ST_LOOP 4'b1011
- `define WRITE_WT_LO2 4'b1100
- `define WRITE_WT_HI2 4'b1101
- `define WRITE_CLR_WR 4'b1110
- `define WRITE_CLR_ST_STOP 4'b1111
-
- reg [3:0]CurrState_SISt, NextState_SISt;
-
- // Diagram actions (continuous assignments allowed only: assign ...)
- // diagram ACTION
-
-
- // Machine: SISt
-
- // NextState logic (combinatorial)
- always @ (startStopDetState or streamSt or scl or txData or bitCnt or rxData or sdaIn or regAddr or dataIn or sdaOut or writeEn or dataOut or clearStartStopDet or CurrState_SISt)
- begin
- NextState_SISt <= CurrState_SISt;
- // Set default values for outputs and signals
- next_streamSt <= streamSt;
- next_txData <= txData;
- next_rxData <= rxData;
- next_sdaOut <= sdaOut;
- next_writeEn <= writeEn;
- next_dataOut <= dataOut;
- next_bitCnt <= bitCnt;
- next_clearStartStopDet <= clearStartStopDet;
- next_regAddr <= regAddr;
- case (CurrState_SISt) // synopsys parallel_case full_case
- `START:
- begin
- next_streamSt <= `STREAM_IDLE;
- next_txData <= 8'h00;
- next_rxData <= 8'h00;
- next_sdaOut <= 1'b1;
- next_writeEn <= 1'b0;
- next_dataOut <= 8'h00;
- next_bitCnt <= 3'b000;
- next_clearStartStopDet <= 1'b0;
- NextState_SISt <= `CHK_RD_WR;
- end
- `CHK_RD_WR:
- begin
- if (streamSt == `STREAM_READ)
- begin
- NextState_SISt <= `READ_RD_LOOP;
- next_txData <= dataIn;
- next_regAddr <= regAddr + 1'b1;
- next_bitCnt <= 3'b001;
- end
- else
- begin
- NextState_SISt <= `WRITE_WT_HI;
- next_rxData <= 8'h00;
- end
- end
- `READ_RD_LOOP:
- begin
- if (scl == 1'b0)
- begin
- NextState_SISt <= `READ_WT_HI;
- next_sdaOut <= txData [7];
- next_txData <= {txData [6:0], 1'b0};
- end
- end
- `READ_WT_HI:
- begin
- if (scl == 1'b1)
- begin
- NextState_SISt <= `READ_CHK_LOOP_FIN;
- end
- end
- `READ_CHK_LOOP_FIN:
- begin
- if (bitCnt == 3'b000)
- begin
- NextState_SISt <= `READ_WT_LO;
- end
- else
- begin
- NextState_SISt <= `READ_RD_LOOP;
- next_bitCnt <= bitCnt + 1'b1;
- end
- end
- `READ_WT_LO:
- begin
- if (scl == 1'b0)
- begin
- NextState_SISt <= `READ_WT_ACK;
- next_sdaOut <= 1'b1;
- end
- end
- `READ_WT_ACK:
- begin
- if (scl == 1'b1)
- begin
- NextState_SISt <= `CHK_RD_WR;
- if (sdaIn == `I2C_NAK)
- next_streamSt <= `STREAM_IDLE;
- end
- end
- `WRITE_WT_LO:
- begin
- if ((scl == 1'b0) && (startStopDetState == `STOP_DET ||
- (streamSt == `STREAM_IDLE && startStopDetState == `NULL_DET)))
- begin
- NextState_SISt <= `WRITE_CLR_ST_STOP;
- case (startStopDetState)
- `NULL_DET:
- next_bitCnt <= bitCnt + 1'b1;
- `START_DET: begin
- next_streamSt <= `STREAM_IDLE;
- next_rxData <= 8'h00;
- end
- default: ;
- endcase
- next_streamSt <= `STREAM_IDLE;
- next_clearStartStopDet <= 1'b1;
- end
- else if (scl == 1'b0)
- begin
- NextState_SISt <= `WRITE_ST_LOOP;
- case (startStopDetState)
- `NULL_DET:
- next_bitCnt <= bitCnt + 1'b1;
- `START_DET: begin
- next_streamSt <= `STREAM_IDLE;
- next_rxData <= 8'h00;
- end
- default: ;
- endcase
- end
- end
- `WRITE_WT_HI:
- begin
- if (scl == 1'b1)
- begin
- NextState_SISt <= `WRITE_WT_LO;
- next_rxData <= {rxData [6:0], sdaIn};
- next_bitCnt <= 3'b000;
- end
- end
- `WRITE_CHK_LOOP_FIN:
- begin
- if (bitCnt == 3'b111)
- begin
- NextState_SISt <= `WRITE_CLR_WR;
- next_sdaOut <= `I2C_ACK;
- case (streamSt)
- `STREAM_IDLE: begin
- if (rxData[7:1] == `I2C_ADDRESS && startStopDetState == `START_DET) begin
- if (rxData[0] == 1'b1)
- next_streamSt <= `STREAM_READ;
- else
- next_streamSt <= `STREAM_WRITE_ADDR;
- end
- else
- next_sdaOut <= `I2C_NAK;
- end
- `STREAM_WRITE_ADDR: begin
- if(regAddr_hiByte == 0) begin
- next_regAddr[15:8] <= rxData;
- regAddr_hiByte <= 1;
- end
- else begin
- next_streamSt <= `STREAM_WRITE_DATA;
- next_regAddr[7:0] <= rxData;
- regAddr_hiByte <= 0;
- end
- end
- `STREAM_WRITE_DATA: begin
- next_dataOut <= rxData;
- next_writeEn <= 1'b1;
- end
- default:
- next_streamSt <= streamSt;
- endcase
- end
- else
- begin
- NextState_SISt <= `WRITE_ST_LOOP;
- next_bitCnt <= bitCnt + 1'b1;
- end
- end
- `WRITE_LOOP_WT_LO:
- begin
- if (scl == 1'b0)
- begin
- NextState_SISt <= `WRITE_CHK_LOOP_FIN;
- end
- end
- `WRITE_ST_LOOP:
- begin
- if (scl == 1'b1)
- begin
- NextState_SISt <= `WRITE_LOOP_WT_LO;
- next_rxData <= {rxData [6:0], sdaIn};
- end
- end
- `WRITE_WT_LO2:
- begin
- if (scl == 1'b0)
- begin
- NextState_SISt <= `CHK_RD_WR;
- next_sdaOut <= 1'b1;
- end
- end
- `WRITE_WT_HI2:
- begin
- next_clearStartStopDet <= 1'b0;
- if (scl == 1'b1)
- begin
- NextState_SISt <= `WRITE_WT_LO2;
- end
- end
- `WRITE_CLR_WR:
- begin
- if (writeEn == 1'b1)
- next_regAddr <= regAddr + 1'b1;
- next_writeEn <= 1'b0;
- next_clearStartStopDet <= 1'b1;
- NextState_SISt <= `WRITE_WT_HI2;
- end
- `WRITE_CLR_ST_STOP:
- begin
- next_clearStartStopDet <= 1'b0;
- NextState_SISt <= `CHK_RD_WR;
- end
- endcase
- end
-
- // Current State Logic (sequential)
- always @ (posedge clk)
- begin
- if (rst == 1'b1)
- CurrState_SISt <= `START;
- else
- CurrState_SISt <= NextState_SISt;
- end
-
- // Registered outputs logic
- always @ (posedge clk)
- begin
- if (rst == 1'b1)
- begin
- sdaOut <= 1'b1;
- writeEn <= 1'b0;
- dataOut <= 8'h00;
- clearStartStopDet <= 1'b0;
- // regAddr <= // Initialization in the reset state or default value required!!
- streamSt <= `STREAM_IDLE;
- txData <= 8'h00;
- rxData <= 8'h00;
- bitCnt <= 3'b000;
- end
- else
- begin
- sdaOut <= next_sdaOut;
- writeEn <= next_writeEn;
- dataOut <= next_dataOut;
- clearStartStopDet <= next_clearStartStopDet;
- regAddr <= next_regAddr;
- streamSt <= next_streamSt;
- txData <= next_txData;
- rxData <= next_rxData;
- bitCnt <= next_bitCnt;
- end
- end
-
- endmodule
|