OpenCores
URL https://opencores.org/ocsvn/i2cslave/i2cslave/trunk

Subversion Repositories i2cslave

[/] [i2cslave/] [trunk/] [rtl/] [serialInterface.v] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sfielding
 
2
//////////////////////////////////////////////////////////////////////
3
////                                                              ////
4
//// serialInterface.v                                                 ////
5
////                                                              ////
6
//// This file is part of the i2cSlave opencores effort.
7
//// <http://www.opencores.org/cores//>                           ////
8
////                                                              ////
9
//// Module Description:                                          ////
10
//// Perform all serial to parallel, and parallel
11
//// to serial conversions. Perform device address matching
12
//// Handle arbitrary length I2C reads terminated by NAK
13
//// from host, and arbitrary length I2C writes terminated
14
//// by STOP from host
15
//// The second byte of a I2C write is always interpreted
16
//// as a register address, and becomes the base register address
17
//// for all read and write transactions.
18
//// I2C WRITE:    devAddr, regAddr, data[regAddr], data[regAddr+1], ..... data[regAddr+N]
19
//// I2C READ:    data[regAddr], data[regAddr+1], ..... data[regAddr+N]
20
//// Note that when regAddR reaches 255 it will automatically wrap round to 0
21
////                                                              ////
22
//// To Do:                                                       ////
23
//// 
24
////                                                              ////
25
//// Author(s):                                                   ////
26
//// - Steve Fielding, sfielding@base2designs.com                 ////
27
////                                                              ////
28
//////////////////////////////////////////////////////////////////////
29
////                                                              ////
30
//// Copyright (C) 2008 Steve Fielding and OPENCORES.ORG          ////
31
////                                                              ////
32
//// This source file may be used and distributed without         ////
33
//// restriction provided that this copyright statement is not    ////
34
//// removed from the file and that any derivative work contains  ////
35
//// the original copyright notice and the associated disclaimer. ////
36
////                                                              ////
37
//// This source file is free software; you can redistribute it   ////
38
//// and/or modify it under the terms of the GNU Lesser General   ////
39
//// Public License as published by the Free Software Foundation; ////
40
//// either version 2.1 of the License, or (at your option) any   ////
41
//// later version.                                               ////
42
////                                                              ////
43
//// This source is distributed in the hope that it will be       ////
44
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
45
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
46
//// PURPOSE. See the GNU Lesser General Public License for more  ////
47
//// details.                                                     ////
48
////                                                              ////
49
//// You should have received a copy of the GNU Lesser General    ////
50
//// Public License along with this source; if not, download it   ////
51
//// from <http://www.opencores.org/lgpl.shtml>                   ////
52
////                                                              ////
53
//////////////////////////////////////////////////////////////////////
54
//
55
`include "timescale.v"
56
`include "i2cSlave_define.v"
57
 
58
module serialInterface (clearStartStopDet, clk, dataIn, dataOut, regAddr, rst, scl, sdaIn, sdaOut, startStopDetState, writeEn);
59
input   clk;
60
input   [7:0]dataIn;
61
input   rst;
62
input   scl;
63
input   sdaIn;
64
input   [1:0]startStopDetState;
65
output  clearStartStopDet;
66
output  [7:0]dataOut;
67
output  [7:0]regAddr;
68
output  sdaOut;
69
output  writeEn;
70
 
71
reg     clearStartStopDet, next_clearStartStopDet;
72
wire    clk;
73
wire    [7:0]dataIn;
74
reg     [7:0]dataOut, next_dataOut;
75
reg     [7:0]regAddr, next_regAddr;
76
wire    rst;
77
wire    scl;
78
wire    sdaIn;
79
reg     sdaOut, next_sdaOut;
80
wire    [1:0]startStopDetState;
81
reg     writeEn, next_writeEn;
82
 
83
// diagram signals declarations
84
reg  [2:0]bitCnt, next_bitCnt;
85
reg  [7:0]rxData, next_rxData;
86
reg  [1:0]streamSt, next_streamSt;
87
reg  [7:0]txData, next_txData;
88
 
89
// BINARY ENCODED state machine: SISt
90
// State codes definitions:
91
`define START 4'b0000
92
`define CHK_RD_WR 4'b0001
93
`define READ_RD_LOOP 4'b0010
94
`define READ_WT_HI 4'b0011
95
`define READ_CHK_LOOP_FIN 4'b0100
96
`define READ_WT_LO 4'b0101
97
`define READ_WT_ACK 4'b0110
98
`define WRITE_WT_LO 4'b0111
99
`define WRITE_WT_HI 4'b1000
100
`define WRITE_CHK_LOOP_FIN 4'b1001
101
`define WRITE_LOOP_WT_LO 4'b1010
102
`define WRITE_ST_LOOP 4'b1011
103
`define WRITE_WT_LO2 4'b1100
104
`define WRITE_WT_HI2 4'b1101
105
`define WRITE_CLR_WR 4'b1110
106
`define WRITE_CLR_ST_STOP 4'b1111
107
 
108
reg [3:0]CurrState_SISt, NextState_SISt;
109
 
110
// Diagram actions (continuous assignments allowed only: assign ...)
111
// diagram ACTION
112
 
113
 
114
// Machine: SISt
115
 
116
// NextState logic (combinatorial)
117
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)
118
begin
119
  NextState_SISt <= CurrState_SISt;
120
  // Set default values for outputs and signals
121
  next_streamSt <= streamSt;
122
  next_txData <= txData;
123
  next_rxData <= rxData;
124
  next_sdaOut <= sdaOut;
125
  next_writeEn <= writeEn;
126
  next_dataOut <= dataOut;
127
  next_bitCnt <= bitCnt;
128
  next_clearStartStopDet <= clearStartStopDet;
129
  next_regAddr <= regAddr;
130
  case (CurrState_SISt)  // synopsys parallel_case full_case
131
    `START:
132
    begin
133
      next_streamSt <= `STREAM_IDLE;
134
      next_txData <= 8'h00;
135
      next_rxData <= 8'h00;
136
      next_sdaOut <= 1'b1;
137
      next_writeEn <= 1'b0;
138
      next_dataOut <= 8'h00;
139
      next_bitCnt <= 3'b000;
140
      next_clearStartStopDet <= 1'b0;
141
      NextState_SISt <= `CHK_RD_WR;
142
    end
143
    `CHK_RD_WR:
144
    begin
145
      if (streamSt == `STREAM_READ)
146
      begin
147
        NextState_SISt <= `READ_RD_LOOP;
148
        next_txData <= dataIn;
149
        next_regAddr <= regAddr + 1'b1;
150
        next_bitCnt <= 3'b001;
151
      end
152
      else
153
      begin
154
        NextState_SISt <= `WRITE_WT_HI;
155
        next_rxData <= 8'h00;
156
      end
157
    end
158
    `READ_RD_LOOP:
159
    begin
160
      if (scl == 1'b0)
161
      begin
162
        NextState_SISt <= `READ_WT_HI;
163
        next_sdaOut <= txData [7];
164
        next_txData <= {txData [6:0], 1'b0};
165
      end
166
    end
167
    `READ_WT_HI:
168
    begin
169
      if (scl == 1'b1)
170
      begin
171
        NextState_SISt <= `READ_CHK_LOOP_FIN;
172
      end
173
    end
174
    `READ_CHK_LOOP_FIN:
175
    begin
176
      if (bitCnt == 3'b000)
177
      begin
178
        NextState_SISt <= `READ_WT_LO;
179
      end
180
      else
181
      begin
182
        NextState_SISt <= `READ_RD_LOOP;
183
        next_bitCnt <= bitCnt + 1'b1;
184
      end
185
    end
186
    `READ_WT_LO:
187
    begin
188
      if (scl == 1'b0)
189
      begin
190
        NextState_SISt <= `READ_WT_ACK;
191
        next_sdaOut <= 1'b1;
192
      end
193
    end
194
    `READ_WT_ACK:
195
    begin
196
      if (scl == 1'b1)
197
      begin
198
        NextState_SISt <= `CHK_RD_WR;
199
        if (sdaIn == `I2C_NAK)
200
        next_streamSt <= `STREAM_IDLE;
201
      end
202
    end
203
    `WRITE_WT_LO:
204
    begin
205
      if ((scl == 1'b0) && (startStopDetState == `STOP_DET ||
206
        (streamSt == `STREAM_IDLE && startStopDetState == `NULL_DET)))
207
      begin
208
        NextState_SISt <= `WRITE_CLR_ST_STOP;
209
        case (startStopDetState)
210
        `NULL_DET:
211
        next_bitCnt <= bitCnt + 1'b1;
212
        `START_DET: begin
213
        next_streamSt <= `STREAM_IDLE;
214
        next_rxData <= 8'h00;
215
        end
216
        default: ;
217
        endcase
218
        next_streamSt <= `STREAM_IDLE;
219
        next_clearStartStopDet <= 1'b1;
220
      end
221
      else if (scl == 1'b0)
222
      begin
223
        NextState_SISt <= `WRITE_ST_LOOP;
224
        case (startStopDetState)
225
        `NULL_DET:
226
        next_bitCnt <= bitCnt + 1'b1;
227
        `START_DET: begin
228
        next_streamSt <= `STREAM_IDLE;
229
        next_rxData <= 8'h00;
230
        end
231
        default: ;
232
        endcase
233
      end
234
    end
235
    `WRITE_WT_HI:
236
    begin
237
      if (scl == 1'b1)
238
      begin
239
        NextState_SISt <= `WRITE_WT_LO;
240
        next_rxData <= {rxData [6:0], sdaIn};
241
        next_bitCnt <= 3'b000;
242
      end
243
    end
244
    `WRITE_CHK_LOOP_FIN:
245
    begin
246
      if (bitCnt == 3'b111)
247
      begin
248
        NextState_SISt <= `WRITE_CLR_WR;
249
        next_sdaOut <= `I2C_ACK;
250
        case (streamSt)
251
        `STREAM_IDLE: begin
252
        if (rxData[7:1] == `I2C_ADDRESS &&
253
        startStopDetState == `START_DET) begin
254
        if (rxData[0] == 1'b1)
255
        next_streamSt <= `STREAM_READ;
256
        else
257
        next_streamSt <= `STREAM_WRITE_ADDR;
258
        end
259
        else
260
        next_sdaOut <= `I2C_NAK;
261
        end
262
        `STREAM_WRITE_ADDR: begin
263
        next_streamSt <= `STREAM_WRITE_DATA;
264
        next_regAddr <= rxData;
265
        end
266
        `STREAM_WRITE_DATA: begin
267
        next_dataOut <= rxData;
268
        next_writeEn <= 1'b1;
269
        end
270
        default:
271
        next_streamSt <= streamSt;
272
        endcase
273
      end
274
      else
275
      begin
276
        NextState_SISt <= `WRITE_ST_LOOP;
277
        next_bitCnt <= bitCnt + 1'b1;
278
      end
279
    end
280
    `WRITE_LOOP_WT_LO:
281
    begin
282
      if (scl == 1'b0)
283
      begin
284
        NextState_SISt <= `WRITE_CHK_LOOP_FIN;
285
      end
286
    end
287
    `WRITE_ST_LOOP:
288
    begin
289
      if (scl == 1'b1)
290
      begin
291
        NextState_SISt <= `WRITE_LOOP_WT_LO;
292
        next_rxData <= {rxData [6:0], sdaIn};
293
      end
294
    end
295
    `WRITE_WT_LO2:
296
    begin
297
      if (scl == 1'b0)
298
      begin
299
        NextState_SISt <= `CHK_RD_WR;
300
        next_sdaOut <= 1'b1;
301
      end
302
    end
303
    `WRITE_WT_HI2:
304
    begin
305
      next_clearStartStopDet <= 1'b0;
306
      if (scl == 1'b1)
307
      begin
308
        NextState_SISt <= `WRITE_WT_LO2;
309
      end
310
    end
311
    `WRITE_CLR_WR:
312
    begin
313
      if (writeEn == 1'b1)
314
      next_regAddr <= regAddr + 1'b1;
315
      next_writeEn <= 1'b0;
316
      next_clearStartStopDet <= 1'b1;
317
      NextState_SISt <= `WRITE_WT_HI2;
318
    end
319
    `WRITE_CLR_ST_STOP:
320
    begin
321
      next_clearStartStopDet <= 1'b0;
322
      NextState_SISt <= `CHK_RD_WR;
323
    end
324
  endcase
325
end
326
 
327
// Current State Logic (sequential)
328
always @ (posedge clk)
329
begin
330
  if (rst == 1'b1)
331
    CurrState_SISt <= `START;
332
  else
333
    CurrState_SISt <= NextState_SISt;
334
end
335
 
336
// Registered outputs logic
337
always @ (posedge clk)
338
begin
339
  if (rst == 1'b1)
340
  begin
341
    sdaOut <= 1'b1;
342
    writeEn <= 1'b0;
343
    dataOut <= 8'h00;
344
    clearStartStopDet <= 1'b0;
345
    // regAddr <=     // Initialization in the reset state or default value required!!
346
    streamSt <= `STREAM_IDLE;
347
    txData <= 8'h00;
348
    rxData <= 8'h00;
349
    bitCnt <= 3'b000;
350
  end
351
  else
352
  begin
353
    sdaOut <= next_sdaOut;
354
    writeEn <= next_writeEn;
355
    dataOut <= next_dataOut;
356
    clearStartStopDet <= next_clearStartStopDet;
357
    regAddr <= next_regAddr;
358
    streamSt <= next_streamSt;
359
    txData <= next_txData;
360
    rxData <= next_rxData;
361
    bitCnt <= next_bitCnt;
362
  end
363
end
364
 
365
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.