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

Subversion Repositories openmsp430

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

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

powered by: WebSVN 2.1.0

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