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

Subversion Repositories openmsp430

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

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

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

powered by: WebSVN 2.1.0

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