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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [core/] [rtl/] [verilog/] [omsp_dbg.v] - Blame information for rev 175

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

Line No. Rev Author Line
1 2 olivier.gi
//----------------------------------------------------------------------------
2 117 olivier.gi
// Copyright (C) 2009 , Olivier Girard
3 2 olivier.gi
//
4 117 olivier.gi
// 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 2 olivier.gi
//
16 117 olivier.gi
// 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 2 olivier.gi
//
28
//----------------------------------------------------------------------------
29
//
30 34 olivier.gi
// *File Name: omsp_dbg.v
31 2 olivier.gi
// 
32
// *Module Description:
33
//                       Debug interface
34
//
35
// *Author(s):
36
//              - Olivier Girard,    olgirard@gmail.com
37
//
38
//----------------------------------------------------------------------------
39 17 olivier.gi
// $Rev: 175 $
40
// $LastChangedBy: olivier.girard $
41
// $LastChangedDate: 2013-01-30 22:21:42 +0100 (Wed, 30 Jan 2013) $
42
//----------------------------------------------------------------------------
43 103 olivier.gi
`ifdef OMSP_NO_INCLUDE
44
`else
45 23 olivier.gi
`include "openMSP430_defines.v"
46 103 olivier.gi
`endif
47 2 olivier.gi
 
48 34 olivier.gi
module  omsp_dbg (
49 2 olivier.gi
 
50
// OUTPUTs
51 154 olivier.gi
    dbg_cpu_reset,                     // Reset CPU from debug interface
52
    dbg_freeze,                        // Freeze peripherals
53
    dbg_halt_cmd,                      // Halt CPU command
54
    dbg_i2c_sda_out,                   // Debug interface: I2C SDA OUT
55
    dbg_mem_addr,                      // Debug address for rd/wr access
56
    dbg_mem_dout,                      // Debug unit data output
57
    dbg_mem_en,                        // Debug unit memory enable
58
    dbg_mem_wr,                        // Debug unit memory write
59
    dbg_reg_wr,                        // Debug unit CPU register write
60
    dbg_uart_txd,                      // Debug interface: UART TXD
61 2 olivier.gi
 
62
// INPUTs
63 154 olivier.gi
    cpu_en_s,                          // Enable CPU code execution (synchronous)
64
    cpu_id,                            // CPU ID
65
    cpu_nr_inst,                       // Current oMSP instance number
66
    cpu_nr_total,                      // Total number of oMSP instances-1
67
    dbg_clk,                           // Debug unit clock
68
    dbg_en_s,                          // Debug interface enable (synchronous)
69
    dbg_halt_st,                       // Halt/Run status from CPU
70
    dbg_i2c_addr,                      // Debug interface: I2C Address
71
    dbg_i2c_broadcast,                 // Debug interface: I2C Broadcast Address (for multicore systems)
72
    dbg_i2c_scl,                       // Debug interface: I2C SCL
73
    dbg_i2c_sda_in,                    // Debug interface: I2C SDA IN
74
    dbg_mem_din,                       // Debug unit Memory data input
75
    dbg_reg_din,                       // Debug unit CPU register data input
76
    dbg_rst,                           // Debug unit reset
77
    dbg_uart_rxd,                      // Debug interface: UART RXD (asynchronous)
78
    decode_noirq,                      // Frontend decode instruction
79
    eu_mab,                            // Execution-Unit Memory address bus
80
    eu_mb_en,                          // Execution-Unit Memory bus enable
81
    eu_mb_wr,                          // Execution-Unit Memory bus write transfer
82
    fe_mdb_in,                         // Frontend Memory data bus input
83
    pc,                                // Program counter
84
    puc_pnd_set                        // PUC pending set for the serial debug interface
85 2 olivier.gi
);
86
 
87
// OUTPUTs
88
//=========
89 154 olivier.gi
output              dbg_cpu_reset;     // Reset CPU from debug interface
90
output              dbg_freeze;        // Freeze peripherals
91
output              dbg_halt_cmd;      // Halt CPU command
92
output              dbg_i2c_sda_out;   // Debug interface: I2C SDA OUT
93
output       [15:0] dbg_mem_addr;      // Debug address for rd/wr access
94
output       [15:0] dbg_mem_dout;      // Debug unit data output
95
output              dbg_mem_en;        // Debug unit memory enable
96
output        [1:0] dbg_mem_wr;        // Debug unit memory write
97
output              dbg_reg_wr;        // Debug unit CPU register write
98
output              dbg_uart_txd;      // Debug interface: UART TXD
99 2 olivier.gi
 
100
// INPUTs
101
//=========
102 154 olivier.gi
input               cpu_en_s;          // Enable CPU code execution (synchronous)
103
input        [31:0] cpu_id;            // CPU ID
104
input         [7:0] cpu_nr_inst;       // Current oMSP instance number
105
input         [7:0] cpu_nr_total;      // Total number of oMSP instances-1
106
input               dbg_clk;           // Debug unit clock
107
input               dbg_en_s;          // Debug interface enable (synchronous)
108
input               dbg_halt_st;       // Halt/Run status from CPU
109
input         [6:0] dbg_i2c_addr;      // Debug interface: I2C Address
110
input         [6:0] dbg_i2c_broadcast; // Debug interface: I2C Broadcast Address (for multicore systems)
111
input               dbg_i2c_scl;       // Debug interface: I2C SCL
112
input               dbg_i2c_sda_in;    // Debug interface: I2C SDA IN
113
input        [15:0] dbg_mem_din;       // Debug unit Memory data input
114
input        [15:0] dbg_reg_din;       // Debug unit CPU register data input
115
input               dbg_rst;           // Debug unit reset
116
input               dbg_uart_rxd;      // Debug interface: UART RXD (asynchronous)
117
input               decode_noirq;      // Frontend decode instruction
118
input        [15:0] eu_mab;            // Execution-Unit Memory address bus
119
input               eu_mb_en;          // Execution-Unit Memory bus enable
120
input         [1:0] eu_mb_wr;          // Execution-Unit Memory bus write transfer
121
input        [15:0] fe_mdb_in;         // Frontend Memory data bus input
122
input        [15:0] pc;                // Program counter
123
input               puc_pnd_set;       // PUC pending set for the serial debug interface
124 2 olivier.gi
 
125
 
126
//=============================================================================
127
// 1)  WIRE & PARAMETER DECLARATION
128
//=============================================================================
129
 
130
// Diverse wires and registers
131
wire  [5:0] dbg_addr;
132
wire [15:0] dbg_din;
133
wire        dbg_wr;
134
reg         mem_burst;
135
wire        dbg_reg_rd;
136
wire        dbg_mem_rd;
137
reg         dbg_mem_rd_dly;
138
wire        dbg_swbrk;
139
wire        dbg_rd;
140
reg         dbg_rd_rdy;
141
wire        mem_burst_rd;
142
wire        mem_burst_wr;
143
wire        brk0_halt;
144
wire        brk0_pnd;
145
wire [15:0] brk0_dout;
146
wire        brk1_halt;
147
wire        brk1_pnd;
148
wire [15:0] brk1_dout;
149
wire        brk2_halt;
150
wire        brk2_pnd;
151
wire [15:0] brk2_dout;
152
wire        brk3_halt;
153
wire        brk3_pnd;
154
wire [15:0] brk3_dout;
155
 
156 134 olivier.gi
// Number of registers
157 154 olivier.gi
parameter           NR_REG       = 25;
158 134 olivier.gi
 
159 2 olivier.gi
// Register addresses
160
parameter           CPU_ID_LO    = 6'h00;
161
parameter           CPU_ID_HI    = 6'h01;
162
parameter           CPU_CTL      = 6'h02;
163
parameter           CPU_STAT     = 6'h03;
164
parameter           MEM_CTL      = 6'h04;
165
parameter           MEM_ADDR     = 6'h05;
166
parameter           MEM_DATA     = 6'h06;
167
parameter           MEM_CNT      = 6'h07;
168
`ifdef DBG_HWBRK_0
169
parameter           BRK0_CTL     = 6'h08;
170
parameter           BRK0_STAT    = 6'h09;
171
parameter           BRK0_ADDR0   = 6'h0A;
172
parameter           BRK0_ADDR1   = 6'h0B;
173
`endif
174
`ifdef DBG_HWBRK_1
175
parameter           BRK1_CTL     = 6'h0C;
176
parameter           BRK1_STAT    = 6'h0D;
177
parameter           BRK1_ADDR0   = 6'h0E;
178
parameter           BRK1_ADDR1   = 6'h0F;
179
`endif
180
`ifdef DBG_HWBRK_2
181
parameter           BRK2_CTL     = 6'h10;
182
parameter           BRK2_STAT    = 6'h11;
183
parameter           BRK2_ADDR0   = 6'h12;
184
parameter           BRK2_ADDR1   = 6'h13;
185
`endif
186
`ifdef DBG_HWBRK_3
187
parameter           BRK3_CTL     = 6'h14;
188
parameter           BRK3_STAT    = 6'h15;
189
parameter           BRK3_ADDR0   = 6'h16;
190
parameter           BRK3_ADDR1   = 6'h17;
191
`endif
192 154 olivier.gi
parameter           CPU_NR       = 6'h18;
193 2 olivier.gi
 
194
// Register one-hot decoder
195 134 olivier.gi
parameter           BASE_D       = {{NR_REG-1{1'b0}}, 1'b1};
196
parameter           CPU_ID_LO_D  = (BASE_D << CPU_ID_LO);
197
parameter           CPU_ID_HI_D  = (BASE_D << CPU_ID_HI);
198
parameter           CPU_CTL_D    = (BASE_D << CPU_CTL);
199
parameter           CPU_STAT_D   = (BASE_D << CPU_STAT);
200
parameter           MEM_CTL_D    = (BASE_D << MEM_CTL);
201
parameter           MEM_ADDR_D   = (BASE_D << MEM_ADDR);
202
parameter           MEM_DATA_D   = (BASE_D << MEM_DATA);
203
parameter           MEM_CNT_D    = (BASE_D << MEM_CNT);
204 2 olivier.gi
`ifdef DBG_HWBRK_0
205 134 olivier.gi
parameter           BRK0_CTL_D   = (BASE_D << BRK0_CTL);
206
parameter           BRK0_STAT_D  = (BASE_D << BRK0_STAT);
207
parameter           BRK0_ADDR0_D = (BASE_D << BRK0_ADDR0);
208
parameter           BRK0_ADDR1_D = (BASE_D << BRK0_ADDR1);
209 2 olivier.gi
`endif
210
`ifdef DBG_HWBRK_1
211 134 olivier.gi
parameter           BRK1_CTL_D   = (BASE_D << BRK1_CTL);
212
parameter           BRK1_STAT_D  = (BASE_D << BRK1_STAT);
213
parameter           BRK1_ADDR0_D = (BASE_D << BRK1_ADDR0);
214
parameter           BRK1_ADDR1_D = (BASE_D << BRK1_ADDR1);
215 2 olivier.gi
`endif
216
`ifdef DBG_HWBRK_2
217 134 olivier.gi
parameter           BRK2_CTL_D   = (BASE_D << BRK2_CTL);
218
parameter           BRK2_STAT_D  = (BASE_D << BRK2_STAT);
219
parameter           BRK2_ADDR0_D = (BASE_D << BRK2_ADDR0);
220
parameter           BRK2_ADDR1_D = (BASE_D << BRK2_ADDR1);
221 2 olivier.gi
`endif
222
`ifdef DBG_HWBRK_3
223 134 olivier.gi
parameter           BRK3_CTL_D   = (BASE_D << BRK3_CTL);
224
parameter           BRK3_STAT_D  = (BASE_D << BRK3_STAT);
225
parameter           BRK3_ADDR0_D = (BASE_D << BRK3_ADDR0);
226
parameter           BRK3_ADDR1_D = (BASE_D << BRK3_ADDR1);
227 2 olivier.gi
`endif
228 154 olivier.gi
parameter           CPU_NR_D     = (BASE_D << CPU_NR);
229 2 olivier.gi
 
230 84 olivier.gi
 
231 2 olivier.gi
//============================================================================
232
// 2)  REGISTER DECODER
233
//============================================================================
234
 
235
// Select Data register during a burst
236
wire  [5:0] dbg_addr_in = mem_burst ? MEM_DATA : dbg_addr;
237
 
238
// Register address decode
239 134 olivier.gi
reg  [NR_REG-1:0]  reg_dec;
240 2 olivier.gi
always @(dbg_addr_in)
241
  case (dbg_addr_in)
242
    CPU_ID_LO :  reg_dec  =  CPU_ID_LO_D;
243
    CPU_ID_HI :  reg_dec  =  CPU_ID_HI_D;
244
    CPU_CTL   :  reg_dec  =  CPU_CTL_D;
245
    CPU_STAT  :  reg_dec  =  CPU_STAT_D;
246
    MEM_CTL   :  reg_dec  =  MEM_CTL_D;
247
    MEM_ADDR  :  reg_dec  =  MEM_ADDR_D;
248
    MEM_DATA  :  reg_dec  =  MEM_DATA_D;
249
    MEM_CNT   :  reg_dec  =  MEM_CNT_D;
250
`ifdef DBG_HWBRK_0
251
    BRK0_CTL  :  reg_dec  =  BRK0_CTL_D;
252
    BRK0_STAT :  reg_dec  =  BRK0_STAT_D;
253
    BRK0_ADDR0:  reg_dec  =  BRK0_ADDR0_D;
254
    BRK0_ADDR1:  reg_dec  =  BRK0_ADDR1_D;
255
`endif
256
`ifdef DBG_HWBRK_1
257
    BRK1_CTL  :  reg_dec  =  BRK1_CTL_D;
258
    BRK1_STAT :  reg_dec  =  BRK1_STAT_D;
259
    BRK1_ADDR0:  reg_dec  =  BRK1_ADDR0_D;
260
    BRK1_ADDR1:  reg_dec  =  BRK1_ADDR1_D;
261
`endif
262
`ifdef DBG_HWBRK_2
263
    BRK2_CTL  :  reg_dec  =  BRK2_CTL_D;
264
    BRK2_STAT :  reg_dec  =  BRK2_STAT_D;
265
    BRK2_ADDR0:  reg_dec  =  BRK2_ADDR0_D;
266
    BRK2_ADDR1:  reg_dec  =  BRK2_ADDR1_D;
267
`endif
268
`ifdef DBG_HWBRK_3
269
    BRK3_CTL  :  reg_dec  =  BRK3_CTL_D;
270
    BRK3_STAT :  reg_dec  =  BRK3_STAT_D;
271
    BRK3_ADDR0:  reg_dec  =  BRK3_ADDR0_D;
272
    BRK3_ADDR1:  reg_dec  =  BRK3_ADDR1_D;
273
`endif
274 154 olivier.gi
    CPU_NR    :  reg_dec  =  CPU_NR_D;
275 134 olivier.gi
  // pragma coverage off
276
    default:     reg_dec  =  {NR_REG{1'b0}};
277
  // pragma coverage on
278 2 olivier.gi
  endcase
279
 
280
// Read/Write probes
281 134 olivier.gi
wire               reg_write =  dbg_wr;
282
wire               reg_read  =  1'b1;
283 2 olivier.gi
 
284
// Read/Write vectors
285 134 olivier.gi
wire  [NR_REG-1:0] reg_wr    = reg_dec & {NR_REG{reg_write}};
286
wire  [NR_REG-1:0] reg_rd    = reg_dec & {NR_REG{reg_read}};
287 2 olivier.gi
 
288
 
289
//=============================================================================
290
// 3)  REGISTER: CORE INTERFACE
291
//=============================================================================
292
 
293
// CPU_ID Register
294
//-----------------   
295 111 olivier.gi
//              -------------------------------------------------------------------
296
// CPU_ID_LO:  | 15  14  13  12  11  10  9  |  8  7  6  5  4  |  3   |   2  1  0   |
297
//             |----------------------------+-----------------+------+-------------|
298
//             |        PER_SPACE           |   USER_VERSION  | ASIC | CPU_VERSION |
299
//              --------------------------------------------------------------------
300
// CPU_ID_HI:  |   15  14  13  12  11  10   |   9  8  7  6  5  4  3  2  1   |   0  |
301
//             |----------------------------+-------------------------------+------|
302
//             |         PMEM_SIZE          |            DMEM_SIZE          |  MPY |
303
//              -------------------------------------------------------------------
304 2 olivier.gi
 
305 134 olivier.gi
// This register is assigned in the SFR module
306 2 olivier.gi
 
307
 
308 154 olivier.gi
// CPU_NR Register
309
//-----------------
310
//    -------------------------------------------------------------------
311
//   | 15  14  13  12  11  10   9   8  |  7   6   5   4   3   2   1   0  |
312
//   |---------------------------------+---------------------------------|
313
//   |            CPU_TOTAL_NR         |           CPU_INST_NR           |
314
//    -------------------------------------------------------------------
315
 
316
wire [15:0] cpu_nr = {cpu_nr_total, cpu_nr_inst};
317
 
318
 
319 2 olivier.gi
// CPU_CTL Register
320
//-----------------------------------------------------------------------------
321
//       7         6          5          4           3        2     1    0
322
//   Reserved   CPU_RST  RST_BRK_EN  FRZ_BRK_EN  SW_BRK_EN  ISTEP  RUN  HALT
323
//-----------------------------------------------------------------------------
324
reg   [6:3] cpu_ctl;
325
 
326
wire        cpu_ctl_wr = reg_wr[CPU_CTL];
327
 
328 106 olivier.gi
always @ (posedge dbg_clk or posedge dbg_rst)
329
`ifdef DBG_RST_BRK_EN
330 134 olivier.gi
  if (dbg_rst)         cpu_ctl <=  4'h6;
331 106 olivier.gi
`else
332 134 olivier.gi
  if (dbg_rst)         cpu_ctl <=  4'h2;
333 106 olivier.gi
`endif
334 2 olivier.gi
  else if (cpu_ctl_wr) cpu_ctl <=  dbg_din[6:3];
335
 
336
wire  [7:0] cpu_ctl_full = {1'b0, cpu_ctl, 3'b000};
337
 
338
wire        halt_cpu = cpu_ctl_wr & dbg_din[`HALT]  & ~dbg_halt_st;
339
wire        run_cpu  = cpu_ctl_wr & dbg_din[`RUN]   &  dbg_halt_st;
340
wire        istep    = cpu_ctl_wr & dbg_din[`ISTEP] &  dbg_halt_st;
341
 
342
 
343
// CPU_STAT Register
344
//------------------------------------------------------------------------------------
345
//      7           6          5           4           3         2      1       0
346
// HWBRK3_PND  HWBRK2_PND  HWBRK1_PND  HWBRK0_PND  SWBRK_PND  PUC_PND  Res.  HALT_RUN
347
//------------------------------------------------------------------------------------
348
reg   [3:2] cpu_stat;
349
 
350
wire        cpu_stat_wr  = reg_wr[CPU_STAT];
351 134 olivier.gi
wire  [3:2] cpu_stat_set = {dbg_swbrk, puc_pnd_set};
352 2 olivier.gi
wire  [3:2] cpu_stat_clr = ~dbg_din[3:2];
353
 
354 106 olivier.gi
always @ (posedge dbg_clk or posedge dbg_rst)
355
  if (dbg_rst)          cpu_stat <=  2'b00;
356 2 olivier.gi
  else if (cpu_stat_wr) cpu_stat <= ((cpu_stat & cpu_stat_clr) | cpu_stat_set);
357
  else                  cpu_stat <=  (cpu_stat                 | cpu_stat_set);
358
 
359
wire  [7:0] cpu_stat_full = {brk3_pnd, brk2_pnd, brk1_pnd, brk0_pnd,
360
                             cpu_stat, 1'b0, dbg_halt_st};
361
 
362
 
363
//=============================================================================
364
// 4)  REGISTER: MEMORY INTERFACE
365
//=============================================================================
366
 
367
// MEM_CTL Register
368
//-----------------------------------------------------------------------------
369
//       7     6     5     4          3        2         1       0
370
//            Reserved               B/W    MEM/REG    RD/WR   START
371
//
372
// START  :  -  0 : Do nothing.
373
//           -  1 : Initiate memory transfer.
374
//
375
// RD/WR  :  -  0 : Read access.
376
//           -  1 : Write access.
377
//
378
// MEM/REG:  -  0 : Memory access.
379
//           -  1 : CPU Register access.
380
//
381
// B/W    :  -  0 : 16 bit access.
382
//           -  1 :  8 bit access (not valid for CPU Registers).
383
//
384
//-----------------------------------------------------------------------------
385
reg   [3:1] mem_ctl;
386
 
387
wire        mem_ctl_wr = reg_wr[MEM_CTL];
388
 
389 106 olivier.gi
always @ (posedge dbg_clk or posedge dbg_rst)
390
  if (dbg_rst)         mem_ctl <=  3'h0;
391 2 olivier.gi
  else if (mem_ctl_wr) mem_ctl <=  dbg_din[3:1];
392
 
393
wire  [7:0] mem_ctl_full  = {4'b0000, mem_ctl, 1'b0};
394
 
395
reg         mem_start;
396 106 olivier.gi
always @ (posedge dbg_clk or posedge dbg_rst)
397
  if (dbg_rst)  mem_start <=  1'b0;
398
  else          mem_start <=  mem_ctl_wr & dbg_din[0];
399 2 olivier.gi
 
400
wire        mem_bw    = mem_ctl[3];
401
 
402
// MEM_DATA Register
403
//------------------   
404
reg  [15:0] mem_data;
405
reg  [15:0] mem_addr;
406
wire        mem_access;
407
 
408
wire        mem_data_wr = reg_wr[MEM_DATA];
409
 
410
wire [15:0] dbg_mem_din_bw = ~mem_bw      ? dbg_mem_din                :
411
                              mem_addr[0] ? {8'h00, dbg_mem_din[15:8]} :
412
                                            {8'h00, dbg_mem_din[7:0]};
413
 
414 106 olivier.gi
always @ (posedge dbg_clk or posedge dbg_rst)
415
  if (dbg_rst)             mem_data <=  16'h0000;
416 2 olivier.gi
  else if (mem_data_wr)    mem_data <=  dbg_din;
417
  else if (dbg_reg_rd)     mem_data <=  dbg_reg_din;
418
  else if (dbg_mem_rd_dly) mem_data <=  dbg_mem_din_bw;
419
 
420
 
421
// MEM_ADDR Register
422
//------------------   
423
reg  [15:0] mem_cnt;
424
 
425
wire        mem_addr_wr  = reg_wr[MEM_ADDR];
426
wire        dbg_mem_acc  = (|dbg_mem_wr | (dbg_rd_rdy & ~mem_ctl[2]));
427
wire        dbg_reg_acc  = ( dbg_reg_wr | (dbg_rd_rdy &  mem_ctl[2]));
428
 
429 175 olivier.gi
wire [15:0] mem_addr_inc = (mem_cnt==16'h0000)                       ? 16'h0000 :
430
                           (mem_burst &  dbg_mem_acc & ~mem_bw)      ? 16'h0002 :
431
                           (mem_burst & (dbg_mem_acc | dbg_reg_acc)) ? 16'h0001 : 16'h0000;
432 2 olivier.gi
 
433 106 olivier.gi
always @ (posedge dbg_clk or posedge dbg_rst)
434
  if (dbg_rst)          mem_addr <=  16'h0000;
435 2 olivier.gi
  else if (mem_addr_wr) mem_addr <=  dbg_din;
436
  else                  mem_addr <=  mem_addr + mem_addr_inc;
437
 
438
// MEM_CNT Register
439
//------------------   
440
 
441
wire        mem_cnt_wr  = reg_wr[MEM_CNT];
442
 
443 149 olivier.gi
wire [15:0] mem_cnt_dec = (mem_cnt==16'h0000)                       ? 16'h0000 :
444
                          (mem_burst & (dbg_mem_acc | dbg_reg_acc)) ? 16'hffff : 16'h0000;
445 2 olivier.gi
 
446 106 olivier.gi
always @ (posedge dbg_clk or posedge dbg_rst)
447
  if (dbg_rst)         mem_cnt <=  16'h0000;
448 2 olivier.gi
  else if (mem_cnt_wr) mem_cnt <=  dbg_din;
449
  else                 mem_cnt <=  mem_cnt + mem_cnt_dec;
450
 
451
 
452
//=============================================================================
453
// 5)  BREAKPOINTS / WATCHPOINTS
454
//=============================================================================
455
 
456
`ifdef DBG_HWBRK_0
457
// Hardware Breakpoint/Watchpoint Register read select
458
wire [3:0] brk0_reg_rd = {reg_rd[BRK0_ADDR1],
459
                          reg_rd[BRK0_ADDR0],
460
                          reg_rd[BRK0_STAT],
461
                          reg_rd[BRK0_CTL]};
462
 
463
// Hardware Breakpoint/Watchpoint Register write select
464
wire [3:0] brk0_reg_wr = {reg_wr[BRK0_ADDR1],
465
                          reg_wr[BRK0_ADDR0],
466
                          reg_wr[BRK0_STAT],
467
                          reg_wr[BRK0_CTL]};
468
 
469 34 olivier.gi
omsp_dbg_hwbrk dbg_hwbr_0 (
470 2 olivier.gi
 
471
// OUTPUTs
472 175 olivier.gi
    .brk_halt     (brk0_halt),    // Hardware breakpoint command
473
    .brk_pnd      (brk0_pnd),     // Hardware break/watch-point pending
474
    .brk_dout     (brk0_dout),    // Hardware break/watch-point register data input
475 2 olivier.gi
 
476
// INPUTs
477 175 olivier.gi
    .brk_reg_rd   (brk0_reg_rd),  // Hardware break/watch-point register read select
478
    .brk_reg_wr   (brk0_reg_wr),  // Hardware break/watch-point register write select
479
    .dbg_clk      (dbg_clk),      // Debug unit clock
480
    .dbg_din      (dbg_din),      // Debug register data input
481
    .dbg_rst      (dbg_rst),      // Debug unit reset
482
    .decode_noirq (decode_noirq), // Frontend decode instruction
483
    .eu_mab       (eu_mab),       // Execution-Unit Memory address bus
484
    .eu_mb_en     (eu_mb_en),     // Execution-Unit Memory bus enable
485
    .eu_mb_wr     (eu_mb_wr),     // Execution-Unit Memory bus write transfer
486
    .pc           (pc)            // Program counter
487 2 olivier.gi
);
488
 
489
`else
490
assign brk0_halt =  1'b0;
491
assign brk0_pnd  =  1'b0;
492
assign brk0_dout = 16'h0000;
493
`endif
494
 
495
`ifdef DBG_HWBRK_1
496
// Hardware Breakpoint/Watchpoint Register read select
497
wire [3:0] brk1_reg_rd = {reg_rd[BRK1_ADDR1],
498
                          reg_rd[BRK1_ADDR0],
499
                          reg_rd[BRK1_STAT],
500
                          reg_rd[BRK1_CTL]};
501
 
502
// Hardware Breakpoint/Watchpoint Register write select
503
wire [3:0] brk1_reg_wr = {reg_wr[BRK1_ADDR1],
504
                          reg_wr[BRK1_ADDR0],
505
                          reg_wr[BRK1_STAT],
506
                          reg_wr[BRK1_CTL]};
507
 
508 34 olivier.gi
omsp_dbg_hwbrk dbg_hwbr_1 (
509 2 olivier.gi
 
510
// OUTPUTs
511 175 olivier.gi
    .brk_halt     (brk1_halt),    // Hardware breakpoint command
512
    .brk_pnd      (brk1_pnd),     // Hardware break/watch-point pending
513
    .brk_dout     (brk1_dout),    // Hardware break/watch-point register data input
514 2 olivier.gi
 
515
// INPUTs
516 175 olivier.gi
    .brk_reg_rd   (brk1_reg_rd),  // Hardware break/watch-point register read select
517
    .brk_reg_wr   (brk1_reg_wr),  // Hardware break/watch-point register write select
518
    .dbg_clk      (dbg_clk),      // Debug unit clock
519
    .dbg_din      (dbg_din),      // Debug register data input
520
    .dbg_rst      (dbg_rst),      // Debug unit reset
521
    .decode_noirq (decode_noirq), // Frontend decode instruction
522
    .eu_mab       (eu_mab),       // Execution-Unit Memory address bus
523
    .eu_mb_en     (eu_mb_en),     // Execution-Unit Memory bus enable
524
    .eu_mb_wr     (eu_mb_wr),     // Execution-Unit Memory bus write transfer
525
    .pc           (pc)            // Program counter
526 2 olivier.gi
);
527
 
528
`else
529
assign brk1_halt =  1'b0;
530
assign brk1_pnd  =  1'b0;
531
assign brk1_dout = 16'h0000;
532
`endif
533
 
534
 `ifdef DBG_HWBRK_2
535
// Hardware Breakpoint/Watchpoint Register read select
536
wire [3:0] brk2_reg_rd = {reg_rd[BRK2_ADDR1],
537
                          reg_rd[BRK2_ADDR0],
538
                          reg_rd[BRK2_STAT],
539
                          reg_rd[BRK2_CTL]};
540
 
541
// Hardware Breakpoint/Watchpoint Register write select
542
wire [3:0] brk2_reg_wr = {reg_wr[BRK2_ADDR1],
543
                          reg_wr[BRK2_ADDR0],
544
                          reg_wr[BRK2_STAT],
545
                          reg_wr[BRK2_CTL]};
546
 
547 34 olivier.gi
omsp_dbg_hwbrk dbg_hwbr_2 (
548 2 olivier.gi
 
549
// OUTPUTs
550 175 olivier.gi
    .brk_halt     (brk2_halt),    // Hardware breakpoint command
551
    .brk_pnd      (brk2_pnd),     // Hardware break/watch-point pending
552
    .brk_dout     (brk2_dout),    // Hardware break/watch-point register data input
553 2 olivier.gi
 
554
// INPUTs
555 175 olivier.gi
    .brk_reg_rd   (brk2_reg_rd),  // Hardware break/watch-point register read select
556
    .brk_reg_wr   (brk2_reg_wr),  // Hardware break/watch-point register write select
557
    .dbg_clk      (dbg_clk),      // Debug unit clock
558
    .dbg_din      (dbg_din),      // Debug register data input
559
    .dbg_rst      (dbg_rst),      // Debug unit reset
560
    .decode_noirq (decode_noirq), // Frontend decode instruction
561
    .eu_mab       (eu_mab),       // Execution-Unit Memory address bus
562
    .eu_mb_en     (eu_mb_en),     // Execution-Unit Memory bus enable
563
    .eu_mb_wr     (eu_mb_wr),     // Execution-Unit Memory bus write transfer
564
    .pc           (pc)            // Program counter
565 2 olivier.gi
);
566
 
567
`else
568
assign brk2_halt =  1'b0;
569
assign brk2_pnd  =  1'b0;
570
assign brk2_dout = 16'h0000;
571
`endif
572
 
573
`ifdef DBG_HWBRK_3
574
// Hardware Breakpoint/Watchpoint Register read select
575
wire [3:0] brk3_reg_rd = {reg_rd[BRK3_ADDR1],
576
                          reg_rd[BRK3_ADDR0],
577
                          reg_rd[BRK3_STAT],
578
                          reg_rd[BRK3_CTL]};
579
 
580
// Hardware Breakpoint/Watchpoint Register write select
581
wire [3:0] brk3_reg_wr = {reg_wr[BRK3_ADDR1],
582
                          reg_wr[BRK3_ADDR0],
583
                          reg_wr[BRK3_STAT],
584
                          reg_wr[BRK3_CTL]};
585
 
586 34 olivier.gi
omsp_dbg_hwbrk dbg_hwbr_3 (
587 2 olivier.gi
 
588
// OUTPUTs
589 175 olivier.gi
    .brk_halt     (brk3_halt),    // Hardware breakpoint command
590
    .brk_pnd      (brk3_pnd),     // Hardware break/watch-point pending
591
    .brk_dout     (brk3_dout),    // Hardware break/watch-point register data input
592 2 olivier.gi
 
593
// INPUTs
594 175 olivier.gi
    .brk_reg_rd   (brk3_reg_rd),  // Hardware break/watch-point register read select
595
    .brk_reg_wr   (brk3_reg_wr),  // Hardware break/watch-point register write select
596
    .dbg_clk      (dbg_clk),      // Debug unit clock
597
    .dbg_din      (dbg_din),      // Debug register data input
598
    .dbg_rst      (dbg_rst),      // Debug unit reset
599
    .decode_noirq (decode_noirq), // Frontend decode instruction
600
    .eu_mab       (eu_mab),       // Execution-Unit Memory address bus
601
    .eu_mb_en     (eu_mb_en),     // Execution-Unit Memory bus enable
602
    .eu_mb_wr     (eu_mb_wr),     // Execution-Unit Memory bus write transfer
603
    .pc           (pc)            // Program counter
604 2 olivier.gi
);
605
 
606
`else
607
assign brk3_halt =  1'b0;
608
assign brk3_pnd  =  1'b0;
609
assign brk3_dout = 16'h0000;
610
`endif
611
 
612
 
613
//============================================================================
614
// 6) DATA OUTPUT GENERATION
615
//============================================================================
616
 
617
wire [15:0] cpu_id_lo_rd = cpu_id[15:0]           & {16{reg_rd[CPU_ID_LO]}};
618
wire [15:0] cpu_id_hi_rd = cpu_id[31:16]          & {16{reg_rd[CPU_ID_HI]}};
619
wire [15:0] cpu_ctl_rd   = {8'h00, cpu_ctl_full}  & {16{reg_rd[CPU_CTL]}};
620
wire [15:0] cpu_stat_rd  = {8'h00, cpu_stat_full} & {16{reg_rd[CPU_STAT]}};
621
wire [15:0] mem_ctl_rd   = {8'h00, mem_ctl_full}  & {16{reg_rd[MEM_CTL]}};
622
wire [15:0] mem_data_rd  = mem_data               & {16{reg_rd[MEM_DATA]}};
623
wire [15:0] mem_addr_rd  = mem_addr               & {16{reg_rd[MEM_ADDR]}};
624
wire [15:0] mem_cnt_rd   = mem_cnt                & {16{reg_rd[MEM_CNT]}};
625 154 olivier.gi
wire [15:0] cpu_nr_rd    = cpu_nr                 & {16{reg_rd[CPU_NR]}};
626 2 olivier.gi
 
627
wire [15:0] dbg_dout = cpu_id_lo_rd |
628
                       cpu_id_hi_rd |
629
                       cpu_ctl_rd   |
630
                       cpu_stat_rd  |
631
                       mem_ctl_rd   |
632
                       mem_data_rd  |
633
                       mem_addr_rd  |
634
                       mem_cnt_rd   |
635
                       brk0_dout    |
636
                       brk1_dout    |
637
                       brk2_dout    |
638 154 olivier.gi
                       brk3_dout    |
639
                       cpu_nr_rd;
640 2 olivier.gi
 
641 154 olivier.gi
// Tell UART/I2C interface that the data is ready to be read
642 106 olivier.gi
always @ (posedge dbg_clk or posedge dbg_rst)
643
  if (dbg_rst)                       dbg_rd_rdy  <=  1'b0;
644 2 olivier.gi
  else if (mem_burst | mem_burst_rd) dbg_rd_rdy  <= (dbg_reg_rd | dbg_mem_rd_dly);
645
  else                               dbg_rd_rdy  <=  dbg_rd;
646
 
647
 
648
//============================================================================
649
// 7) CPU CONTROL
650
//============================================================================
651
 
652
// Reset CPU
653
//--------------------------
654 106 olivier.gi
wire dbg_cpu_reset  = cpu_ctl[`CPU_RST];
655 2 olivier.gi
 
656
 
657
// Break after reset
658
//--------------------------
659 134 olivier.gi
wire halt_rst = cpu_ctl[`RST_BRK_EN] & dbg_en_s & puc_pnd_set;
660 2 olivier.gi
 
661
 
662
// Freeze peripherals
663
//--------------------------
664 106 olivier.gi
wire dbg_freeze = dbg_halt_st & (cpu_ctl[`FRZ_BRK_EN] | ~cpu_en_s);
665 2 olivier.gi
 
666 106 olivier.gi
 
667 2 olivier.gi
// Software break
668
//--------------------------
669 53 olivier.gi
assign dbg_swbrk = (fe_mdb_in==`DBG_SWBRK_OP) & decode_noirq & cpu_ctl[`SW_BRK_EN];
670 2 olivier.gi
 
671
 
672
// Single step
673
//--------------------------
674
reg [1:0] inc_step;
675 106 olivier.gi
always @(posedge dbg_clk or posedge dbg_rst)
676
  if (dbg_rst)    inc_step <= 2'b00;
677 2 olivier.gi
  else if (istep) inc_step <= 2'b11;
678
  else            inc_step <= {inc_step[0], 1'b0};
679
 
680
 
681
// Run / Halt
682
//--------------------------
683
reg   halt_flag;
684
 
685
wire  mem_halt_cpu;
686
wire  mem_run_cpu;
687
 
688
wire  halt_flag_clr = run_cpu   | mem_run_cpu;
689
wire  halt_flag_set = halt_cpu  | halt_rst  | dbg_swbrk | mem_halt_cpu |
690
                      brk0_halt | brk1_halt | brk2_halt | brk3_halt;
691
 
692 106 olivier.gi
always @(posedge dbg_clk or posedge dbg_rst)
693
  if (dbg_rst)            halt_flag <= 1'b0;
694 2 olivier.gi
  else if (halt_flag_clr) halt_flag <= 1'b0;
695
  else if (halt_flag_set) halt_flag <= 1'b1;
696
 
697
wire dbg_halt_cmd = (halt_flag | halt_flag_set) & ~inc_step[1];
698
 
699
 
700
//============================================================================
701
// 8) MEMORY CONTROL
702
//============================================================================
703
 
704
// Control Memory bursts
705
//------------------------------
706
 
707
wire mem_burst_start = (mem_start             &  |mem_cnt);
708
wire mem_burst_end   = ((dbg_wr | dbg_rd_rdy) & ~|mem_cnt);
709
 
710
// Detect when burst is on going
711 106 olivier.gi
always @(posedge dbg_clk or posedge dbg_rst)
712
  if (dbg_rst)              mem_burst <= 1'b0;
713 2 olivier.gi
  else if (mem_burst_start) mem_burst <= 1'b1;
714
  else if (mem_burst_end)   mem_burst <= 1'b0;
715
 
716 154 olivier.gi
// Control signals for UART/I2C interface
717 2 olivier.gi
assign mem_burst_rd = (mem_burst_start & ~mem_ctl[1]);
718
assign mem_burst_wr = (mem_burst_start &  mem_ctl[1]);
719
 
720
// Trigger CPU Register or memory access during a burst
721
reg        mem_startb;
722 106 olivier.gi
always @(posedge dbg_clk or posedge dbg_rst)
723
  if (dbg_rst) mem_startb <= 1'b0;
724
  else         mem_startb <= (mem_burst & (dbg_wr | dbg_rd)) | mem_burst_rd;
725 2 olivier.gi
 
726
// Combine single and burst memory start of sequence
727
wire       mem_seq_start = ((mem_start & ~|mem_cnt) | mem_startb);
728
 
729
 
730
// Memory access state machine
731
//------------------------------
732
reg  [1:0] mem_state;
733
reg  [1:0] mem_state_nxt;
734
 
735
// State machine definition
736
parameter  M_IDLE       = 2'h0;
737
parameter  M_SET_BRK    = 2'h1;
738
parameter  M_ACCESS_BRK = 2'h2;
739
parameter  M_ACCESS     = 2'h3;
740
 
741
// State transition
742
always @(mem_state or mem_seq_start or dbg_halt_st)
743
  case (mem_state)
744
    M_IDLE       : mem_state_nxt = ~mem_seq_start ? M_IDLE       :
745
                                    dbg_halt_st   ? M_ACCESS     : M_SET_BRK;
746
    M_SET_BRK    : mem_state_nxt =  dbg_halt_st   ? M_ACCESS_BRK : M_SET_BRK;
747
    M_ACCESS_BRK : mem_state_nxt =  M_IDLE;
748
    M_ACCESS     : mem_state_nxt =  M_IDLE;
749 134 olivier.gi
  // pragma coverage off
750 2 olivier.gi
    default      : mem_state_nxt =  M_IDLE;
751 134 olivier.gi
  // pragma coverage on
752 2 olivier.gi
  endcase
753
 
754
// State machine
755 106 olivier.gi
always @(posedge dbg_clk or posedge dbg_rst)
756
  if (dbg_rst) mem_state <= M_IDLE;
757
  else         mem_state <= mem_state_nxt;
758 2 olivier.gi
 
759
// Utility signals
760
assign mem_halt_cpu = (mem_state==M_IDLE)       & (mem_state_nxt==M_SET_BRK);
761
assign mem_run_cpu  = (mem_state==M_ACCESS_BRK) & (mem_state_nxt==M_IDLE);
762
assign mem_access   = (mem_state==M_ACCESS)     | (mem_state==M_ACCESS_BRK);
763
 
764
 
765
// Interface to CPU Registers and Memory bacbkone
766
//------------------------------------------------
767
assign      dbg_mem_addr   =  mem_addr;
768
assign      dbg_mem_dout   = ~mem_bw      ? mem_data               :
769
                              mem_addr[0] ? {mem_data[7:0], 8'h00} :
770
                                            {8'h00, mem_data[7:0]};
771
 
772
assign      dbg_reg_wr     = mem_access &  mem_ctl[1] &  mem_ctl[2];
773
assign      dbg_reg_rd     = mem_access & ~mem_ctl[1] &  mem_ctl[2];
774
 
775
assign      dbg_mem_en     = mem_access & ~mem_ctl[2];
776
assign      dbg_mem_rd     = dbg_mem_en & ~mem_ctl[1];
777
 
778
wire  [1:0] dbg_mem_wr_msk = ~mem_bw      ? 2'b11 :
779
                              mem_addr[0] ? 2'b10 : 2'b01;
780
assign      dbg_mem_wr     = {2{dbg_mem_en & mem_ctl[1]}} & dbg_mem_wr_msk;
781
 
782
 
783
// It takes one additional cycle to read from Memory as from registers
784 106 olivier.gi
always @(posedge dbg_clk or posedge dbg_rst)
785
  if (dbg_rst) dbg_mem_rd_dly <= 1'b0;
786
  else         dbg_mem_rd_dly <= dbg_mem_rd;
787 2 olivier.gi
 
788
 
789
//=============================================================================
790
// 9)  UART COMMUNICATION
791
//=============================================================================
792
`ifdef DBG_UART
793 34 olivier.gi
omsp_dbg_uart dbg_uart_0 (
794 2 olivier.gi
 
795
// OUTPUTs
796 154 olivier.gi
    .dbg_addr         (dbg_addr),         // Debug register address
797
    .dbg_din          (dbg_din),          // Debug register data input
798
    .dbg_rd           (dbg_rd),           // Debug register data read
799
    .dbg_uart_txd     (dbg_uart_txd),     // Debug interface: UART TXD
800
    .dbg_wr           (dbg_wr),           // Debug register data write
801 2 olivier.gi
 
802
// INPUTs
803 154 olivier.gi
    .dbg_clk          (dbg_clk),          // Debug unit clock
804
    .dbg_dout         (dbg_dout),         // Debug register data output
805
    .dbg_rd_rdy       (dbg_rd_rdy),       // Debug register data is ready for read
806
    .dbg_rst          (dbg_rst),          // Debug unit reset
807
    .dbg_uart_rxd     (dbg_uart_rxd),     // Debug interface: UART RXD
808
    .mem_burst        (mem_burst),        // Burst on going
809
    .mem_burst_end    (mem_burst_end),    // End TX/RX burst
810
    .mem_burst_rd     (mem_burst_rd),     // Start TX burst
811
    .mem_burst_wr     (mem_burst_wr),     // Start RX burst
812
    .mem_bw           (mem_bw)            // Burst byte width
813 2 olivier.gi
);
814
 
815
`else
816 154 olivier.gi
    assign dbg_uart_txd    =  1'b1;
817
  `ifdef DBG_I2C
818
  `else
819
    assign dbg_addr        =  6'h00;
820
    assign dbg_din         = 16'h0000;
821
    assign dbg_rd          =  1'b0;
822
    assign dbg_wr          =  1'b0;
823
  `endif
824 2 olivier.gi
`endif
825
 
826
//=============================================================================
827 154 olivier.gi
// 10)  I2C COMMUNICATION
828 2 olivier.gi
//=============================================================================
829 154 olivier.gi
`ifdef DBG_I2C
830
omsp_dbg_i2c dbg_i2c_0 (
831
 
832
// OUTPUTs
833
    .dbg_addr          (dbg_addr),          // Debug register address
834
    .dbg_din           (dbg_din),           // Debug register data input
835
    .dbg_i2c_sda_out   (dbg_i2c_sda_out),   // Debug interface: I2C SDA OUT
836
    .dbg_rd            (dbg_rd),            // Debug register data read
837
    .dbg_wr            (dbg_wr),            // Debug register data write
838
 
839
// INPUTs
840
    .dbg_clk           (dbg_clk),           // Debug unit clock
841
    .dbg_dout          (dbg_dout),          // Debug register data output
842
    .dbg_i2c_addr      (dbg_i2c_addr),      // Debug interface: I2C Address
843
    .dbg_i2c_broadcast (dbg_i2c_broadcast), // Debug interface: I2C Broadcast Address (for multicore systems)
844
    .dbg_i2c_scl       (dbg_i2c_scl),       // Debug interface: I2C SCL
845
    .dbg_i2c_sda_in    (dbg_i2c_sda_in),    // Debug interface: I2C SDA IN
846
    .dbg_rd_rdy        (dbg_rd_rdy),        // Debug register data is ready for read
847
    .dbg_rst           (dbg_rst),           // Debug unit reset
848
    .mem_burst         (mem_burst),         // Burst on going
849
    .mem_burst_end     (mem_burst_end),     // End TX/RX burst
850
    .mem_burst_rd      (mem_burst_rd),      // Start TX burst
851
    .mem_burst_wr      (mem_burst_wr),      // Start RX burst
852
    .mem_bw            (mem_bw)             // Burst byte width
853
);
854
 
855 2 olivier.gi
`else
856 154 olivier.gi
    assign dbg_i2c_sda_out =  1'b1;
857 2 olivier.gi
`endif
858
 
859 154 olivier.gi
endmodule // omsp_dbg
860 2 olivier.gi
 
861 103 olivier.gi
`ifdef OMSP_NO_INCLUDE
862
`else
863 33 olivier.gi
`include "openMSP430_undefines.v"
864 103 olivier.gi
`endif

powered by: WebSVN 2.1.0

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