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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [core/] [rtl/] [verilog/] [omsp_dbg_i2c.v] - Blame information for rev 154

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 154 olivier.gi
//----------------------------------------------------------------------------
2
// Copyright (C) 2009 , Olivier Girard
3
//
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions
6
// are met:
7
//     * Redistributions of source code must retain the above copyright
8
//       notice, this list of conditions and the following disclaimer.
9
//     * Redistributions in binary form must reproduce the above copyright
10
//       notice, this list of conditions and the following disclaimer in the
11
//       documentation and/or other materials provided with the distribution.
12
//     * Neither the name of the authors nor the names of its contributors
13
//       may be used to endorse or promote products derived from this software
14
//       without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26
// THE POSSIBILITY OF SUCH DAMAGE
27
//
28
//----------------------------------------------------------------------------
29
//
30
// *File Name: omsp_dbg_i2c.v
31
// 
32
// *Module Description:
33
//                       Debug I2C Slave communication interface
34
//
35
// *Author(s):
36
//              - Olivier Girard,    olgirard@gmail.com
37
//
38
//----------------------------------------------------------------------------
39
// $Rev: 103 $
40
// $LastChangedBy: olivier.girard $
41
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
42
//----------------------------------------------------------------------------
43
`ifdef OMSP_NO_INCLUDE
44
`else
45
`include "openMSP430_defines.v"
46
`endif
47
 
48
module  omsp_dbg_i2c (
49
 
50
// OUTPUTs
51
    dbg_addr,                          // Debug register address
52
    dbg_din,                           // Debug register data input
53
    dbg_i2c_sda_out,                   // Debug interface: I2C SDA OUT
54
    dbg_rd,                            // Debug register data read
55
    dbg_wr,                            // Debug register data write
56
 
57
// INPUTs
58
    dbg_clk,                           // Debug unit clock
59
    dbg_dout,                          // Debug register data output
60
    dbg_i2c_addr,                      // Debug interface: I2C ADDRESS
61
    dbg_i2c_broadcast,                 // Debug interface: I2C Broadcast Address (for multicore systems)
62
    dbg_i2c_scl,                       // Debug interface: I2C SCL
63
    dbg_i2c_sda_in,                    // Debug interface: I2C SDA IN
64
    dbg_rd_rdy,                        // Debug register data is ready for read
65
    dbg_rst,                           // Debug unit reset
66
    mem_burst,                         // Burst on going
67
    mem_burst_end,                     // End TX/RX burst
68
    mem_burst_rd,                      // Start TX burst
69
    mem_burst_wr,                      // Start RX burst
70
    mem_bw                             // Burst byte width
71
);
72
 
73
// OUTPUTs
74
//=========
75
output        [5:0] dbg_addr;          // Debug register address
76
output       [15:0] dbg_din;           // Debug register data input
77
output              dbg_i2c_sda_out;   // Debug interface: I2C SDA OUT
78
output              dbg_rd;            // Debug register data read
79
output              dbg_wr;            // Debug register data write
80
 
81
// INPUTs
82
//=========
83
input               dbg_clk;           // Debug unit clock
84
input        [15:0] dbg_dout;          // Debug register data output
85
input         [6:0] dbg_i2c_addr;      // Debug interface: I2C ADDRESS
86
input         [6:0] dbg_i2c_broadcast; // Debug interface: I2C Broadcast Address (for multicore systems)
87
input               dbg_i2c_scl;       // Debug interface: I2C SCL
88
input               dbg_i2c_sda_in;    // Debug interface: I2C SDA IN
89
input               dbg_rd_rdy;        // Debug register data is ready for read
90
input               dbg_rst;           // Debug unit reset
91
input               mem_burst;         // Burst on going
92
input               mem_burst_end;     // End TX/RX burst
93
input               mem_burst_rd;      // Start TX burst
94
input               mem_burst_wr;      // Start RX burst
95
input               mem_bw;            // Burst byte width
96
 
97
 
98
//=============================================================================
99
// 1) I2C RECEIVE LINE SYNCHRONIZTION & FILTERING
100
//=============================================================================
101
 
102
// Synchronize SCL/SDA inputs
103
//--------------------------------
104
 
105
wire scl_sync_n;
106
omsp_sync_cell sync_cell_i2c_scl (
107
    .data_out  (scl_sync_n),
108
    .data_in   (~dbg_i2c_scl),
109
    .clk       (dbg_clk),
110
    .rst       (dbg_rst)
111
);
112
wire scl_sync = ~scl_sync_n;
113
 
114
wire sda_in_sync_n;
115
omsp_sync_cell sync_cell_i2c_sda (
116
    .data_out  (sda_in_sync_n),
117
    .data_in   (~dbg_i2c_sda_in),
118
    .clk       (dbg_clk),
119
    .rst       (dbg_rst)
120
);
121
wire sda_in_sync = ~sda_in_sync_n;
122
 
123
 
124
// SCL/SDA input buffers
125
//--------------------------------
126
 
127
reg  [1:0] scl_buf;
128
always @ (posedge dbg_clk or posedge dbg_rst)
129
  if (dbg_rst) scl_buf <=  2'h3;
130
  else         scl_buf <=  {scl_buf[0], scl_sync};
131
 
132
reg  [1:0] sda_in_buf;
133
always @ (posedge dbg_clk or posedge dbg_rst)
134
  if (dbg_rst) sda_in_buf <=  2'h3;
135
  else         sda_in_buf <=  {sda_in_buf[0], sda_in_sync};
136
 
137
 
138
// SCL/SDA Majority decision
139
//------------------------------
140
 
141
wire scl         =  (scl_sync      & scl_buf[0])    |
142
                    (scl_sync      & scl_buf[1])    |
143
                    (scl_buf[0]    & scl_buf[1]);
144
 
145
wire sda_in      =  (sda_in_sync   & sda_in_buf[0]) |
146
                    (sda_in_sync   & sda_in_buf[1]) |
147
                    (sda_in_buf[0] & sda_in_buf[1]);
148
 
149
 
150
// SCL/SDA Edge detection
151
//------------------------------
152
 
153
// SDA Edge detection
154
reg        sda_in_dly;
155
always @ (posedge dbg_clk or posedge dbg_rst)
156
  if (dbg_rst) sda_in_dly <=  1'b1;
157
  else         sda_in_dly <=  sda_in;
158
 
159
wire sda_in_fe   =  sda_in_dly & ~sda_in;
160
wire sda_in_re   = ~sda_in_dly &  sda_in;
161
wire sda_in_edge =  sda_in_dly ^  sda_in;
162
 
163
// SCL Edge detection
164
reg        scl_dly;
165
always @ (posedge dbg_clk or posedge dbg_rst)
166
  if (dbg_rst) scl_dly <=  1'b1;
167
  else         scl_dly <=  scl;
168
 
169
wire scl_fe      =  scl_dly    & ~scl;
170
wire scl_re      = ~scl_dly    &  scl;
171
wire scl_edge    =  scl_dly    ^  scl;
172
 
173
 
174
// Delayed SCL Rising-Edge for SDA data sampling
175
reg  [1:0] scl_re_dly;
176
always @ (posedge dbg_clk or posedge dbg_rst)
177
  if (dbg_rst) scl_re_dly <=  2'b00;
178
  else         scl_re_dly <=  {scl_re_dly[0], scl_re};
179
 
180
wire scl_sample  =  scl_re_dly[1];
181
 
182
 
183
//=============================================================================
184
// 2) I2C START & STOP CONDITION DETECTION
185
//=============================================================================
186
 
187
//-----------------
188
// Start condition
189
//-----------------
190
 
191
wire start_detect = sda_in_fe & scl;
192
 
193
//-----------------
194
// Stop condition
195
//-----------------
196
 
197
 wire stop_detect = sda_in_re & scl;
198
 
199
//-----------------
200
// I2C Slave Active
201
//-----------------
202
// The I2C logic will be activated whenever a start condition
203
// is detected and will be disactivated if the slave address
204
// doesn't match or if a stop condition is detected.
205
 
206
wire i2c_addr_not_valid;
207
 
208
reg  i2c_active_seq;
209
always @ (posedge dbg_clk or posedge dbg_rst)
210
  if (dbg_rst)                                 i2c_active_seq <= 1'b0;
211
  else if (start_detect)                       i2c_active_seq <= 1'b1;
212
  else if (stop_detect || i2c_addr_not_valid)  i2c_active_seq <= 1'b0;
213
 
214
wire i2c_active =  i2c_active_seq & ~stop_detect;
215
wire i2c_init   = ~i2c_active     |  start_detect;
216
 
217
 
218
//=============================================================================
219
// 3) I2C STATE MACHINE
220
//=============================================================================
221
 
222
// State register/wires
223
reg   [2:0] i2c_state;
224
reg   [2:0] i2c_state_nxt;
225
 
226
// Utility signals
227
reg   [8:0] shift_buf;
228
wire        shift_rx_done;
229
wire        shift_tx_done;
230
reg         dbg_rd;
231
 
232
// State machine definition
233
parameter   RX_ADDR      =  3'h0;
234
parameter   RX_ADDR_ACK  =  3'h1;
235
parameter   RX_DATA      =  3'h2;
236
parameter   RX_DATA_ACK  =  3'h3;
237
parameter   TX_DATA      =  3'h4;
238
parameter   TX_DATA_ACK  =  3'h5;
239
 
240
// State transition
241
always @(i2c_state or i2c_init or shift_rx_done or i2c_addr_not_valid or shift_tx_done or scl_fe or shift_buf or sda_in)
242
  case (i2c_state)
243
    RX_ADDR     : i2c_state_nxt =   i2c_init           ?  RX_ADDR      :
244
                                   ~shift_rx_done      ?  RX_ADDR      :
245
                                    i2c_addr_not_valid ?  RX_ADDR      :
246
                                                          RX_ADDR_ACK;
247
 
248
    RX_ADDR_ACK : i2c_state_nxt =   i2c_init           ?  RX_ADDR      :
249
                                   ~scl_fe             ?  RX_ADDR_ACK  :
250
                                    shift_buf[0]       ?  TX_DATA      :
251
                                                          RX_DATA;
252
 
253
    RX_DATA     : i2c_state_nxt =   i2c_init           ?  RX_ADDR      :
254
                                   ~shift_rx_done      ?  RX_DATA      :
255
                                                          RX_DATA_ACK;
256
 
257
    RX_DATA_ACK : i2c_state_nxt =   i2c_init           ?  RX_ADDR      :
258
                                   ~scl_fe             ?  RX_DATA_ACK  :
259
                                                          RX_DATA;
260
 
261
    TX_DATA     : i2c_state_nxt =   i2c_init           ?  RX_ADDR      :
262
                                   ~shift_tx_done      ?  TX_DATA      :
263
                                                          TX_DATA_ACK;
264
 
265
    TX_DATA_ACK : i2c_state_nxt =   i2c_init           ?  RX_ADDR      :
266
                                   ~scl_fe             ?  TX_DATA_ACK  :
267
                                   ~sda_in             ?  TX_DATA      :
268
                                                          RX_ADDR;
269
  // pragma coverage off
270
    default     : i2c_state_nxt =                         RX_ADDR;
271
  // pragma coverage on
272
  endcase
273
 
274
// State machine
275
always @(posedge dbg_clk or posedge dbg_rst)
276
  if (dbg_rst)       i2c_state <= RX_ADDR;
277
  else               i2c_state <= i2c_state_nxt;
278
 
279
 
280
//=============================================================================
281
// 4) I2C SHIFT REGISTER (FOR RECEIVING & TRANSMITING)
282
//=============================================================================
283
 
284
wire       shift_rx_en       = ((i2c_state==RX_ADDR) | (i2c_state    ==RX_DATA) | (i2c_state    ==RX_DATA_ACK));
285
wire       shift_tx_en       =                         (i2c_state    ==TX_DATA) | (i2c_state    ==TX_DATA_ACK);
286
wire       shift_tx_en_pre   =                         (i2c_state_nxt==TX_DATA) | (i2c_state_nxt==TX_DATA_ACK);
287
 
288
assign     shift_rx_done     = shift_rx_en & scl_fe & shift_buf[8];
289
assign     shift_tx_done     = shift_tx_en & scl_fe & (shift_buf==9'h100);
290
 
291
wire       shift_buf_rx_init = i2c_init | ((i2c_state==RX_ADDR_ACK) & scl_fe & ~shift_buf[0]) |
292
                                          ((i2c_state==RX_DATA_ACK) & scl_fe);
293
wire       shift_buf_rx_en   = shift_rx_en     & scl_sample;
294
 
295
wire       shift_buf_tx_init =            ((i2c_state==RX_ADDR_ACK) & scl_re &  shift_buf[0]) |
296
                                          ((i2c_state==TX_DATA_ACK) & scl_re);
297
wire       shift_buf_tx_en   = shift_tx_en_pre & scl_fe & (shift_buf!=9'h100);
298
 
299
wire [7:0] shift_tx_val;
300
 
301
wire [8:0] shift_buf_nxt     = shift_buf_rx_init  ? 9'h001                   : // RX Init 
302
                               shift_buf_tx_init  ? {shift_tx_val,   1'b1}   : // TX Init 
303
                               shift_buf_rx_en    ? {shift_buf[7:0], sda_in} : // RX Shift
304
                               shift_buf_tx_en    ? {shift_buf[7:0], 1'b0}   : // TX Shift
305
                                                     shift_buf[8:0];           // Hold
306
 
307
always @ (posedge dbg_clk or posedge dbg_rst)
308
  if (dbg_rst) shift_buf <= 9'h001;
309
  else         shift_buf <= shift_buf_nxt;
310
 
311
// Detect when the received I2C device address is not valid
312
assign i2c_addr_not_valid =  (i2c_state == RX_ADDR) && shift_rx_done && (
313
`ifdef DBG_I2C_BROADCAST
314
                              (shift_buf[7:1] != dbg_i2c_broadcast[6:0]) &&
315
`endif
316
                              (shift_buf[7:1] != dbg_i2c_addr[6:0]));
317
 
318
// Utility signals
319
wire        shift_rx_data_done = shift_rx_done & (i2c_state==RX_DATA);
320
wire        shift_tx_data_done = shift_tx_done;
321
 
322
 
323
//=============================================================================
324
// 5) I2C TRANSMIT BUFFER
325
//=============================================================================
326
 
327
reg dbg_i2c_sda_out;
328
 
329
always @ (posedge dbg_clk or posedge dbg_rst)
330
  if (dbg_rst)     dbg_i2c_sda_out <= 1'b1;
331
  else if (scl_fe) dbg_i2c_sda_out <= ~((i2c_state_nxt==RX_ADDR_ACK) ||
332
                                        (i2c_state_nxt==RX_DATA_ACK) ||
333
                                       (shift_buf_tx_en & ~shift_buf[8]));
334
 
335
 
336
//=============================================================================
337
// 6) DEBUG INTERFACE STATE MACHINE
338
//=============================================================================
339
 
340
// State register/wires
341
reg   [2:0] dbg_state;
342
reg   [2:0] dbg_state_nxt;
343
 
344
// Utility signals
345
reg         dbg_bw;
346
 
347
// State machine definition
348
parameter  RX_CMD     = 3'h0;
349
parameter  RX_BYTE_LO = 3'h1;
350
parameter  RX_BYTE_HI = 3'h2;
351
parameter  TX_BYTE_LO = 3'h3;
352
parameter  TX_BYTE_HI = 3'h4;
353
 
354
// State transition
355
always @(dbg_state    or shift_rx_data_done or shift_tx_data_done or shift_buf     or dbg_bw or
356
         mem_burst_wr or mem_burst_rd       or mem_burst          or mem_burst_end or mem_bw)
357
  case (dbg_state)
358
    RX_CMD     : dbg_state_nxt =  mem_burst_wr                ? RX_BYTE_LO  :
359
                                  mem_burst_rd                ? TX_BYTE_LO  :
360
                                  ~shift_rx_data_done         ? RX_CMD      :
361
                                   shift_buf[7]               ? RX_BYTE_LO  :
362
                                                                TX_BYTE_LO;
363
 
364
    RX_BYTE_LO : dbg_state_nxt = (mem_burst &  mem_burst_end) ? RX_CMD      :
365
                                  ~shift_rx_data_done         ? RX_BYTE_LO  :
366
                                 (mem_burst & ~mem_burst_end) ?
367
                                 (mem_bw                      ? RX_BYTE_LO  :
368
                                                                RX_BYTE_HI) :
369
                                  dbg_bw                      ? RX_CMD      :
370
                                                                RX_BYTE_HI;
371
 
372
    RX_BYTE_HI : dbg_state_nxt =  ~shift_rx_data_done         ? RX_BYTE_HI  :
373
                                 (mem_burst & ~mem_burst_end) ? RX_BYTE_LO  :
374
                                                                RX_CMD;
375
 
376
    TX_BYTE_LO : dbg_state_nxt =  ~shift_tx_data_done         ? TX_BYTE_LO  :
377
                                 ( mem_burst &  mem_bw)       ? TX_BYTE_LO  :
378
                                 ( mem_burst & ~mem_bw)       ? TX_BYTE_HI  :
379
                                  ~dbg_bw                     ? TX_BYTE_HI  :
380
                                                                RX_CMD;
381
 
382
    TX_BYTE_HI : dbg_state_nxt =  ~shift_tx_data_done         ? TX_BYTE_HI  :
383
                                   mem_burst                  ? TX_BYTE_LO  :
384
                                                                RX_CMD;
385
 
386
  // pragma coverage off
387
    default    : dbg_state_nxt =                                RX_CMD;
388
  // pragma coverage on
389
  endcase
390
 
391
// State machine
392
always @(posedge dbg_clk or posedge dbg_rst)
393
  if (dbg_rst) dbg_state <= RX_CMD;
394
  else         dbg_state <= dbg_state_nxt;
395
 
396
// Utility signals
397
wire cmd_valid   = (dbg_state==RX_CMD)     & shift_rx_data_done;
398
wire rx_lo_valid = (dbg_state==RX_BYTE_LO) & shift_rx_data_done;
399
wire rx_hi_valid = (dbg_state==RX_BYTE_HI) & shift_rx_data_done;
400
 
401
 
402
//=============================================================================
403
// 7) REGISTER READ/WRITE ACCESS
404
//=============================================================================
405
 
406
parameter MEM_DATA = 6'h06;
407
 
408
// Debug register address & bit width
409
reg [5:0] dbg_addr;
410
always @ (posedge dbg_clk or posedge dbg_rst)
411
  if (dbg_rst)
412
    begin
413
       dbg_bw   <= 1'b0;
414
       dbg_addr <= 6'h00;
415
    end
416
  else if (cmd_valid)
417
    begin
418
       dbg_bw   <= shift_buf[6];
419
       dbg_addr <= shift_buf[5:0];
420
    end
421
  else if (mem_burst)
422
    begin
423
       dbg_bw   <= mem_bw;
424
       dbg_addr <= MEM_DATA;
425
    end
426
 
427
 
428
// Debug register data input
429
reg [7:0] dbg_din_lo;
430
always @ (posedge dbg_clk or posedge dbg_rst)
431
  if (dbg_rst)          dbg_din_lo <= 8'h00;
432
  else if (rx_lo_valid) dbg_din_lo <= shift_buf[7:0];
433
 
434
reg [7:0] dbg_din_hi;
435
always @ (posedge dbg_clk or posedge dbg_rst)
436
  if (dbg_rst)          dbg_din_hi <= 8'h00;
437
  else if (rx_lo_valid) dbg_din_hi <= 8'h00;
438
  else if (rx_hi_valid) dbg_din_hi <= shift_buf[7:0];
439
 
440
assign dbg_din = {dbg_din_hi, dbg_din_lo};
441
 
442
 
443
// Debug register data write command
444
reg  dbg_wr;
445
always @ (posedge dbg_clk or posedge dbg_rst)
446
  if (dbg_rst) dbg_wr <= 1'b0;
447
  else         dbg_wr <= (mem_burst &  mem_bw) ? rx_lo_valid :
448
                         (mem_burst & ~mem_bw) ? rx_hi_valid :
449
                         dbg_bw                ? rx_lo_valid :
450
                                                 rx_hi_valid;
451
 
452
 
453
// Debug register data read command
454
always @ (posedge dbg_clk or posedge dbg_rst)
455
  if (dbg_rst) dbg_rd <= 1'b0;
456
  else         dbg_rd <= (mem_burst &  mem_bw) ? (shift_tx_data_done & (dbg_state==TX_BYTE_LO)) :
457
                         (mem_burst & ~mem_bw) ? (shift_tx_data_done & (dbg_state==TX_BYTE_HI)) :
458
                         cmd_valid             ?  ~shift_buf[7]                                 :
459
                                                  1'b0;
460
 
461
 
462
// Debug register data read value 
463
assign shift_tx_val = (dbg_state==TX_BYTE_HI) ? dbg_dout[15:8] :
464
                                                dbg_dout[7:0];
465
 
466
endmodule

powered by: WebSVN 2.1.0

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