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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [fpga/] [xilinx_diligent_s3board/] [rtl/] [verilog/] [openmsp430/] [omsp_dbg.v] - Blame information for rev 111

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

powered by: WebSVN 2.1.0

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