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 209

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 202 olivier.gi
//
32 154 olivier.gi
// *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_rst,                           // Debug unit reset
65
    mem_burst,                         // Burst on going
66
    mem_burst_end,                     // End TX/RX burst
67
    mem_burst_rd,                      // Start TX burst
68
    mem_burst_wr,                      // Start RX burst
69
    mem_bw                             // Burst byte width
70
);
71
 
72
// OUTPUTs
73
//=========
74
output        [5:0] dbg_addr;          // Debug register address
75
output       [15:0] dbg_din;           // Debug register data input
76
output              dbg_i2c_sda_out;   // Debug interface: I2C SDA OUT
77
output              dbg_rd;            // Debug register data read
78
output              dbg_wr;            // Debug register data write
79
 
80
// INPUTs
81
//=========
82
input               dbg_clk;           // Debug unit clock
83
input        [15:0] dbg_dout;          // Debug register data output
84
input         [6:0] dbg_i2c_addr;      // Debug interface: I2C ADDRESS
85
input         [6:0] dbg_i2c_broadcast; // Debug interface: I2C Broadcast Address (for multicore systems)
86
input               dbg_i2c_scl;       // Debug interface: I2C SCL
87
input               dbg_i2c_sda_in;    // Debug interface: I2C SDA IN
88
input               dbg_rst;           // Debug unit reset
89
input               mem_burst;         // Burst on going
90
input               mem_burst_end;     // End TX/RX burst
91
input               mem_burst_rd;      // Start TX burst
92
input               mem_burst_wr;      // Start RX burst
93
input               mem_bw;            // Burst byte width
94
 
95
 
96
//=============================================================================
97
// 1) I2C RECEIVE LINE SYNCHRONIZTION & FILTERING
98
//=============================================================================
99
 
100
// Synchronize SCL/SDA inputs
101
//--------------------------------
102
 
103
wire scl_sync_n;
104
omsp_sync_cell sync_cell_i2c_scl (
105
    .data_out  (scl_sync_n),
106
    .data_in   (~dbg_i2c_scl),
107
    .clk       (dbg_clk),
108
    .rst       (dbg_rst)
109
);
110
wire scl_sync = ~scl_sync_n;
111
 
112
wire sda_in_sync_n;
113
omsp_sync_cell sync_cell_i2c_sda (
114
    .data_out  (sda_in_sync_n),
115
    .data_in   (~dbg_i2c_sda_in),
116
    .clk       (dbg_clk),
117
    .rst       (dbg_rst)
118
);
119
wire sda_in_sync = ~sda_in_sync_n;
120
 
121 202 olivier.gi
 
122 154 olivier.gi
// SCL/SDA input buffers
123
//--------------------------------
124
 
125
reg  [1:0] scl_buf;
126
always @ (posedge dbg_clk or posedge dbg_rst)
127
  if (dbg_rst) scl_buf <=  2'h3;
128
  else         scl_buf <=  {scl_buf[0], scl_sync};
129
 
130
reg  [1:0] sda_in_buf;
131
always @ (posedge dbg_clk or posedge dbg_rst)
132
  if (dbg_rst) sda_in_buf <=  2'h3;
133
  else         sda_in_buf <=  {sda_in_buf[0], sda_in_sync};
134
 
135
 
136
// SCL/SDA Majority decision
137
//------------------------------
138
 
139
wire scl         =  (scl_sync      & scl_buf[0])    |
140
                    (scl_sync      & scl_buf[1])    |
141
                    (scl_buf[0]    & scl_buf[1]);
142 202 olivier.gi
 
143 154 olivier.gi
wire sda_in      =  (sda_in_sync   & sda_in_buf[0]) |
144
                    (sda_in_sync   & sda_in_buf[1]) |
145
                    (sda_in_buf[0] & sda_in_buf[1]);
146
 
147
 
148
// SCL/SDA Edge detection
149
//------------------------------
150
 
151
// SDA Edge detection
152
reg        sda_in_dly;
153
always @ (posedge dbg_clk or posedge dbg_rst)
154
  if (dbg_rst) sda_in_dly <=  1'b1;
155
  else         sda_in_dly <=  sda_in;
156
 
157
wire sda_in_fe   =  sda_in_dly & ~sda_in;
158
wire sda_in_re   = ~sda_in_dly &  sda_in;
159
wire sda_in_edge =  sda_in_dly ^  sda_in;
160
 
161
// SCL Edge detection
162
reg        scl_dly;
163
always @ (posedge dbg_clk or posedge dbg_rst)
164
  if (dbg_rst) scl_dly <=  1'b1;
165
  else         scl_dly <=  scl;
166
 
167
wire scl_fe      =  scl_dly    & ~scl;
168
wire scl_re      = ~scl_dly    &  scl;
169
wire scl_edge    =  scl_dly    ^  scl;
170
 
171
 
172
// Delayed SCL Rising-Edge for SDA data sampling
173
reg  [1:0] scl_re_dly;
174
always @ (posedge dbg_clk or posedge dbg_rst)
175
  if (dbg_rst) scl_re_dly <=  2'b00;
176
  else         scl_re_dly <=  {scl_re_dly[0], scl_re};
177
 
178
wire scl_sample  =  scl_re_dly[1];
179
 
180 202 olivier.gi
 
181 154 olivier.gi
//=============================================================================
182
// 2) I2C START & STOP CONDITION DETECTION
183
//=============================================================================
184
 
185
//-----------------
186
// Start condition
187
//-----------------
188
 
189
wire start_detect = sda_in_fe & scl;
190
 
191
//-----------------
192
// Stop condition
193
//-----------------
194
 
195
 wire stop_detect = sda_in_re & scl;
196 202 olivier.gi
 
197 154 olivier.gi
//-----------------
198
// I2C Slave Active
199
//-----------------
200
// The I2C logic will be activated whenever a start condition
201
// is detected and will be disactivated if the slave address
202
// doesn't match or if a stop condition is detected.
203
 
204
wire i2c_addr_not_valid;
205
 
206
reg  i2c_active_seq;
207
always @ (posedge dbg_clk or posedge dbg_rst)
208
  if (dbg_rst)                                 i2c_active_seq <= 1'b0;
209
  else if (start_detect)                       i2c_active_seq <= 1'b1;
210
  else if (stop_detect || i2c_addr_not_valid)  i2c_active_seq <= 1'b0;
211
 
212
wire i2c_active =  i2c_active_seq & ~stop_detect;
213
wire i2c_init   = ~i2c_active     |  start_detect;
214
 
215 202 olivier.gi
 
216 154 olivier.gi
//=============================================================================
217
// 3) I2C STATE MACHINE
218
//=============================================================================
219
 
220
// State register/wires
221
reg   [2:0] i2c_state;
222
reg   [2:0] i2c_state_nxt;
223
 
224
// Utility signals
225
reg   [8:0] shift_buf;
226
wire        shift_rx_done;
227
wire        shift_tx_done;
228
reg         dbg_rd;
229 202 olivier.gi
 
230 154 olivier.gi
// State machine definition
231
parameter   RX_ADDR      =  3'h0;
232
parameter   RX_ADDR_ACK  =  3'h1;
233
parameter   RX_DATA      =  3'h2;
234
parameter   RX_DATA_ACK  =  3'h3;
235
parameter   TX_DATA      =  3'h4;
236
parameter   TX_DATA_ACK  =  3'h5;
237
 
238
// State transition
239
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)
240
  case (i2c_state)
241
    RX_ADDR     : i2c_state_nxt =   i2c_init           ?  RX_ADDR      :
242
                                   ~shift_rx_done      ?  RX_ADDR      :
243
                                    i2c_addr_not_valid ?  RX_ADDR      :
244
                                                          RX_ADDR_ACK;
245
 
246
    RX_ADDR_ACK : i2c_state_nxt =   i2c_init           ?  RX_ADDR      :
247
                                   ~scl_fe             ?  RX_ADDR_ACK  :
248
                                    shift_buf[0]       ?  TX_DATA      :
249
                                                          RX_DATA;
250
 
251
    RX_DATA     : i2c_state_nxt =   i2c_init           ?  RX_ADDR      :
252
                                   ~shift_rx_done      ?  RX_DATA      :
253
                                                          RX_DATA_ACK;
254
 
255
    RX_DATA_ACK : i2c_state_nxt =   i2c_init           ?  RX_ADDR      :
256
                                   ~scl_fe             ?  RX_DATA_ACK  :
257
                                                          RX_DATA;
258
 
259
    TX_DATA     : i2c_state_nxt =   i2c_init           ?  RX_ADDR      :
260
                                   ~shift_tx_done      ?  TX_DATA      :
261
                                                          TX_DATA_ACK;
262
 
263
    TX_DATA_ACK : i2c_state_nxt =   i2c_init           ?  RX_ADDR      :
264
                                   ~scl_fe             ?  TX_DATA_ACK  :
265
                                   ~sda_in             ?  TX_DATA      :
266
                                                          RX_ADDR;
267
  // pragma coverage off
268
    default     : i2c_state_nxt =                         RX_ADDR;
269
  // pragma coverage on
270
  endcase
271 202 olivier.gi
 
272 154 olivier.gi
// State machine
273
always @(posedge dbg_clk or posedge dbg_rst)
274
  if (dbg_rst)       i2c_state <= RX_ADDR;
275
  else               i2c_state <= i2c_state_nxt;
276
 
277
 
278
//=============================================================================
279
// 4) I2C SHIFT REGISTER (FOR RECEIVING & TRANSMITING)
280
//=============================================================================
281
 
282
wire       shift_rx_en       = ((i2c_state==RX_ADDR) | (i2c_state    ==RX_DATA) | (i2c_state    ==RX_DATA_ACK));
283
wire       shift_tx_en       =                         (i2c_state    ==TX_DATA) | (i2c_state    ==TX_DATA_ACK);
284
wire       shift_tx_en_pre   =                         (i2c_state_nxt==TX_DATA) | (i2c_state_nxt==TX_DATA_ACK);
285
 
286
assign     shift_rx_done     = shift_rx_en & scl_fe & shift_buf[8];
287
assign     shift_tx_done     = shift_tx_en & scl_fe & (shift_buf==9'h100);
288
 
289
wire       shift_buf_rx_init = i2c_init | ((i2c_state==RX_ADDR_ACK) & scl_fe & ~shift_buf[0]) |
290
                                          ((i2c_state==RX_DATA_ACK) & scl_fe);
291
wire       shift_buf_rx_en   = shift_rx_en     & scl_sample;
292
 
293
wire       shift_buf_tx_init =            ((i2c_state==RX_ADDR_ACK) & scl_re &  shift_buf[0]) |
294
                                          ((i2c_state==TX_DATA_ACK) & scl_re);
295
wire       shift_buf_tx_en   = shift_tx_en_pre & scl_fe & (shift_buf!=9'h100);
296
 
297
wire [7:0] shift_tx_val;
298 202 olivier.gi
 
299
wire [8:0] shift_buf_nxt     = shift_buf_rx_init  ? 9'h001                   : // RX Init
300
                               shift_buf_tx_init  ? {shift_tx_val,   1'b1}   : // TX Init
301 154 olivier.gi
                               shift_buf_rx_en    ? {shift_buf[7:0], sda_in} : // RX Shift
302
                               shift_buf_tx_en    ? {shift_buf[7:0], 1'b0}   : // TX Shift
303
                                                     shift_buf[8:0];           // Hold
304
 
305
always @ (posedge dbg_clk or posedge dbg_rst)
306
  if (dbg_rst) shift_buf <= 9'h001;
307
  else         shift_buf <= shift_buf_nxt;
308
 
309
// Detect when the received I2C device address is not valid
310
assign i2c_addr_not_valid =  (i2c_state == RX_ADDR) && shift_rx_done && (
311
`ifdef DBG_I2C_BROADCAST
312
                              (shift_buf[7:1] != dbg_i2c_broadcast[6:0]) &&
313
`endif
314
                              (shift_buf[7:1] != dbg_i2c_addr[6:0]));
315 202 olivier.gi
`ifdef DBG_I2C_BROADCAST
316
`else
317
wire [6:0] UNUSED_dbg_i2c_broadcast = dbg_i2c_broadcast;
318
`endif
319 154 olivier.gi
 
320
// Utility signals
321 202 olivier.gi
wire        shift_rx_data_done = shift_rx_done & (i2c_state==RX_DATA);
322
wire        shift_tx_data_done = shift_tx_done;
323 154 olivier.gi
 
324
 
325
//=============================================================================
326
// 5) I2C TRANSMIT BUFFER
327
//=============================================================================
328
 
329
reg dbg_i2c_sda_out;
330
 
331
always @ (posedge dbg_clk or posedge dbg_rst)
332
  if (dbg_rst)     dbg_i2c_sda_out <= 1'b1;
333
  else if (scl_fe) dbg_i2c_sda_out <= ~((i2c_state_nxt==RX_ADDR_ACK) ||
334
                                        (i2c_state_nxt==RX_DATA_ACK) ||
335
                                       (shift_buf_tx_en & ~shift_buf[8]));
336 202 olivier.gi
 
337
 
338 154 olivier.gi
//=============================================================================
339
// 6) DEBUG INTERFACE STATE MACHINE
340
//=============================================================================
341
 
342
// State register/wires
343
reg   [2:0] dbg_state;
344
reg   [2:0] dbg_state_nxt;
345
 
346
// Utility signals
347
reg         dbg_bw;
348
 
349
// State machine definition
350
parameter  RX_CMD     = 3'h0;
351
parameter  RX_BYTE_LO = 3'h1;
352
parameter  RX_BYTE_HI = 3'h2;
353
parameter  TX_BYTE_LO = 3'h3;
354
parameter  TX_BYTE_HI = 3'h4;
355
 
356
// State transition
357
always @(dbg_state    or shift_rx_data_done or shift_tx_data_done or shift_buf     or dbg_bw or
358
         mem_burst_wr or mem_burst_rd       or mem_burst          or mem_burst_end or mem_bw)
359
  case (dbg_state)
360
    RX_CMD     : dbg_state_nxt =  mem_burst_wr                ? RX_BYTE_LO  :
361
                                  mem_burst_rd                ? TX_BYTE_LO  :
362
                                  ~shift_rx_data_done         ? RX_CMD      :
363
                                   shift_buf[7]               ? RX_BYTE_LO  :
364
                                                                TX_BYTE_LO;
365
 
366
    RX_BYTE_LO : dbg_state_nxt = (mem_burst &  mem_burst_end) ? RX_CMD      :
367
                                  ~shift_rx_data_done         ? RX_BYTE_LO  :
368
                                 (mem_burst & ~mem_burst_end) ?
369
                                 (mem_bw                      ? RX_BYTE_LO  :
370
                                                                RX_BYTE_HI) :
371
                                  dbg_bw                      ? RX_CMD      :
372
                                                                RX_BYTE_HI;
373
 
374
    RX_BYTE_HI : dbg_state_nxt =  ~shift_rx_data_done         ? RX_BYTE_HI  :
375
                                 (mem_burst & ~mem_burst_end) ? RX_BYTE_LO  :
376
                                                                RX_CMD;
377
 
378
    TX_BYTE_LO : dbg_state_nxt =  ~shift_tx_data_done         ? TX_BYTE_LO  :
379
                                 ( mem_burst &  mem_bw)       ? TX_BYTE_LO  :
380
                                 ( mem_burst & ~mem_bw)       ? TX_BYTE_HI  :
381
                                  ~dbg_bw                     ? TX_BYTE_HI  :
382
                                                                RX_CMD;
383
 
384
    TX_BYTE_HI : dbg_state_nxt =  ~shift_tx_data_done         ? TX_BYTE_HI  :
385
                                   mem_burst                  ? TX_BYTE_LO  :
386
                                                                RX_CMD;
387
 
388
  // pragma coverage off
389
    default    : dbg_state_nxt =                                RX_CMD;
390
  // pragma coverage on
391
  endcase
392 202 olivier.gi
 
393 154 olivier.gi
// State machine
394
always @(posedge dbg_clk or posedge dbg_rst)
395
  if (dbg_rst) dbg_state <= RX_CMD;
396
  else         dbg_state <= dbg_state_nxt;
397
 
398
// Utility signals
399
wire cmd_valid   = (dbg_state==RX_CMD)     & shift_rx_data_done;
400
wire rx_lo_valid = (dbg_state==RX_BYTE_LO) & shift_rx_data_done;
401
wire rx_hi_valid = (dbg_state==RX_BYTE_HI) & shift_rx_data_done;
402
 
403
 
404
//=============================================================================
405
// 7) REGISTER READ/WRITE ACCESS
406
//=============================================================================
407
 
408
parameter MEM_DATA = 6'h06;
409
 
410
// Debug register address & bit width
411
reg [5:0] dbg_addr;
412
always @ (posedge dbg_clk or posedge dbg_rst)
413
  if (dbg_rst)
414
    begin
415
       dbg_bw   <= 1'b0;
416
       dbg_addr <= 6'h00;
417
    end
418
  else if (cmd_valid)
419
    begin
420
       dbg_bw   <= shift_buf[6];
421
       dbg_addr <= shift_buf[5:0];
422
    end
423
  else if (mem_burst)
424
    begin
425
       dbg_bw   <= mem_bw;
426
       dbg_addr <= MEM_DATA;
427
    end
428
 
429
 
430
// Debug register data input
431
reg [7:0] dbg_din_lo;
432
always @ (posedge dbg_clk or posedge dbg_rst)
433
  if (dbg_rst)          dbg_din_lo <= 8'h00;
434
  else if (rx_lo_valid) dbg_din_lo <= shift_buf[7:0];
435
 
436
reg [7:0] dbg_din_hi;
437
always @ (posedge dbg_clk or posedge dbg_rst)
438
  if (dbg_rst)          dbg_din_hi <= 8'h00;
439
  else if (rx_lo_valid) dbg_din_hi <= 8'h00;
440
  else if (rx_hi_valid) dbg_din_hi <= shift_buf[7:0];
441 202 olivier.gi
 
442 154 olivier.gi
assign dbg_din = {dbg_din_hi, dbg_din_lo};
443
 
444
 
445
// Debug register data write command
446
reg  dbg_wr;
447
always @ (posedge dbg_clk or posedge dbg_rst)
448
  if (dbg_rst) dbg_wr <= 1'b0;
449
  else         dbg_wr <= (mem_burst &  mem_bw) ? rx_lo_valid :
450
                         (mem_burst & ~mem_bw) ? rx_hi_valid :
451
                         dbg_bw                ? rx_lo_valid :
452
                                                 rx_hi_valid;
453
 
454
 
455
// Debug register data read command
456
always @ (posedge dbg_clk or posedge dbg_rst)
457
  if (dbg_rst) dbg_rd <= 1'b0;
458
  else         dbg_rd <= (mem_burst &  mem_bw) ? (shift_tx_data_done & (dbg_state==TX_BYTE_LO)) :
459 202 olivier.gi
                         (mem_burst & ~mem_bw) ? (shift_tx_data_done & (dbg_state==TX_BYTE_HI)) :
460 154 olivier.gi
                         cmd_valid             ?  ~shift_buf[7]                                 :
461
                                                  1'b0;
462
 
463
 
464 202 olivier.gi
// Debug register data read value
465 154 olivier.gi
assign shift_tx_val = (dbg_state==TX_BYTE_HI) ? dbg_dout[15:8] :
466
                                                dbg_dout[7:0];
467
 
468
endmodule
469 188 olivier.gi
 
470
`ifdef OMSP_NO_INCLUDE
471
`else
472
`include "openMSP430_undefines.v"
473
`endif

powered by: WebSVN 2.1.0

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