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