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

Subversion Repositories openmsp430

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

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

powered by: WebSVN 2.1.0

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