1 //----------------------------------------------------------------------------
2 // Copyright (C) 2001 Authors
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
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.
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.
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
23 //----------------------------------------------------------------------------
25 // *File Name: omsp_dbg.v
27 // *Module Description:
31 // - Olivier Girard, olgirard@gmail.com
33 //----------------------------------------------------------------------------
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"
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
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
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
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
107 //=============================================================================
108 // 1) WIRE & PARAMETER DECLARATION
109 //=============================================================================
111 // Diverse wires and registers
126 wire [15:0] brk0_dout;
129 wire [15:0] brk1_dout;
132 wire [15:0] brk2_dout;
135 wire [15:0] brk3_dout;
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;
147 parameter BRK0_CTL = 6'h08;
148 parameter BRK0_STAT = 6'h09;
149 parameter BRK0_ADDR0 = 6'h0A;
150 parameter BRK0_ADDR1 = 6'h0B;
153 parameter BRK1_CTL = 6'h0C;
154 parameter BRK1_STAT = 6'h0D;
155 parameter BRK1_ADDR0 = 6'h0E;
156 parameter BRK1_ADDR1 = 6'h0F;
159 parameter BRK2_CTL = 6'h10;
160 parameter BRK2_STAT = 6'h11;
161 parameter BRK2_ADDR0 = 6'h12;
162 parameter BRK2_ADDR1 = 6'h13;
165 parameter BRK3_CTL = 6'h14;
166 parameter BRK3_STAT = 6'h15;
167 parameter BRK3_ADDR0 = 6'h16;
168 parameter BRK3_ADDR1 = 6'h17;
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);
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);
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);
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);
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);
206 //============================================================================
207 // 2) REGISTER DECODER
208 //============================================================================
210 // Select Data register during a burst
211 wire [5:0] dbg_addr_in = mem_burst ? MEM_DATA : dbg_addr;
213 // Register address decode
215 always @(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;
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;
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;
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;
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;
249 default: reg_dec = {64{1'b0}};
253 wire reg_write = dbg_wr;
254 wire reg_read = 1'b1;
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}};
261 //=============================================================================
262 // 3) REGISTER: CORE INTERFACE
263 //=============================================================================
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};
274 //-----------------------------------------------------------------------------
276 // Reserved CPU_RST RST_BRK_EN FRZ_BRK_EN SW_BRK_EN ISTEP RUN HALT
277 //-----------------------------------------------------------------------------
280 wire cpu_ctl_wr = reg_wr[CPU_CTL];
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];
286 wire [7:0] cpu_ctl_full = {1'b0, cpu_ctl, 3'b000};
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;
294 //------------------------------------------------------------------------------------
296 // HWBRK3_PND HWBRK2_PND HWBRK1_PND HWBRK0_PND SWBRK_PND PUC_PND Res. HALT_RUN
297 //------------------------------------------------------------------------------------
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];
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);
309 wire [7:0] cpu_stat_full = {brk3_pnd, brk2_pnd, brk1_pnd, brk0_pnd,
310 cpu_stat, 1'b0, dbg_halt_st};
313 //=============================================================================
314 // 4) REGISTER: MEMORY INTERFACE
315 //=============================================================================
318 //-----------------------------------------------------------------------------
320 // Reserved B/W MEM/REG RD/WR START
322 // START : - 0 : Do nothing.
323 // - 1 : Initiate memory transfer.
325 // RD/WR : - 0 : Read access.
326 // - 1 : Write access.
328 // MEM/REG: - 0 : Memory access.
329 // - 1 : CPU Register access.
331 // B/W : - 0 : 16 bit access.
332 // - 1 : 8 bit access (not valid for CPU Registers).
334 //-----------------------------------------------------------------------------
337 wire mem_ctl_wr = reg_wr[MEM_CTL];
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];
343 wire [7:0] mem_ctl_full = {4'b0000, mem_ctl, 1'b0};
346 always @ (posedge mclk or posedge por)
347 if (por) mem_start <= 1'b0;
348 else mem_start <= mem_ctl_wr & dbg_din[0];
350 wire mem_bw = mem_ctl[3];
358 wire mem_data_wr = reg_wr[MEM_DATA];
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]};
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;
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]));
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;
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;
391 wire mem_cnt_wr = reg_wr[MEM_CNT];
393 wire [15:0] mem_cnt_dec = (mem_cnt==16'h0000) ? 16'h0000 :
394 (dbg_mem_acc | dbg_reg_acc) ? 16'hffff : 16'h0000;
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;
402 //=============================================================================
403 // 5) BREAKPOINTS / WATCHPOINTS
404 //=============================================================================
407 // Hardware Breakpoint/Watchpoint Register read select
408 wire [3:0] brk0_reg_rd = {reg_rd[BRK0_ADDR1],
413 // Hardware Breakpoint/Watchpoint Register write select
414 wire [3:0] brk0_reg_wr = {reg_wr[BRK0_ADDR1],
419 omsp_dbg_hwbrk dbg_hwbr_0 (
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
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
443 assign brk0_halt = 1'b0;
444 assign brk0_pnd = 1'b0;
445 assign brk0_dout = 16'h0000;
449 // Hardware Breakpoint/Watchpoint Register read select
450 wire [3:0] brk1_reg_rd = {reg_rd[BRK1_ADDR1],
455 // Hardware Breakpoint/Watchpoint Register write select
456 wire [3:0] brk1_reg_wr = {reg_wr[BRK1_ADDR1],
461 omsp_dbg_hwbrk dbg_hwbr_1 (
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
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
485 assign brk1_halt = 1'b0;
486 assign brk1_pnd = 1'b0;
487 assign brk1_dout = 16'h0000;
491 // Hardware Breakpoint/Watchpoint Register read select
492 wire [3:0] brk2_reg_rd = {reg_rd[BRK2_ADDR1],
497 // Hardware Breakpoint/Watchpoint Register write select
498 wire [3:0] brk2_reg_wr = {reg_wr[BRK2_ADDR1],
503 omsp_dbg_hwbrk dbg_hwbr_2 (
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
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
527 assign brk2_halt = 1'b0;
528 assign brk2_pnd = 1'b0;
529 assign brk2_dout = 16'h0000;
533 // Hardware Breakpoint/Watchpoint Register read select
534 wire [3:0] brk3_reg_rd = {reg_rd[BRK3_ADDR1],
539 // Hardware Breakpoint/Watchpoint Register write select
540 wire [3:0] brk3_reg_wr = {reg_wr[BRK3_ADDR1],
545 omsp_dbg_hwbrk dbg_hwbr_3 (
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
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
569 assign brk3_halt = 1'b0;
570 assign brk3_pnd = 1'b0;
571 assign brk3_dout = 16'h0000;
575 //============================================================================
576 // 6) DATA OUTPUT GENERATION
577 //============================================================================
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]}};
588 wire [15:0] dbg_dout = cpu_id_lo_rd |
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;
608 //============================================================================
610 //============================================================================
613 //--------------------------
614 wire dbg_reset = cpu_ctl[`CPU_RST];
618 //--------------------------
619 wire halt_rst = cpu_ctl[`RST_BRK_EN] & puc;
622 // Freeze peripherals
623 //--------------------------
624 wire dbg_freeze = dbg_halt_st & cpu_ctl[`FRZ_BRK_EN];
628 //--------------------------
629 assign dbg_swbrk = (fe_mdb_in==`DBG_SWBRK_OP) & decode_noirq & cpu_ctl[`SW_BRK_EN];
633 //--------------------------
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};
642 //--------------------------
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;
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;
657 wire dbg_halt_cmd = (halt_flag | halt_flag_set) & ~inc_step[1];
660 //============================================================================
662 //============================================================================
664 // Control Memory bursts
665 //------------------------------
667 wire mem_burst_start = (mem_start & |mem_cnt);
668 wire mem_burst_end = ((dbg_wr | dbg_rd_rdy) & ~|mem_cnt);
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;
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]);
680 // Trigger CPU Register or memory access during a burst
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;
686 // Combine single and burst memory start of sequence
687 wire mem_seq_start = ((mem_start & ~|mem_cnt) | mem_startb);
690 // Memory access state machine
691 //------------------------------
693 reg [1:0] mem_state_nxt;
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;
702 always @(mem_state or mem_seq_start or dbg_halt_st)
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;
713 always @(posedge mclk or posedge por)
714 if (por) mem_state <= M_IDLE;
715 else mem_state <= mem_state_nxt;
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);
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]};
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];
733 assign dbg_mem_en = mem_access & ~mem_ctl[2];
734 assign dbg_mem_rd = dbg_mem_en & ~mem_ctl[1];
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;
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;
747 //=============================================================================
748 // 9) UART COMMUNICATION
749 //=============================================================================
751 omsp_dbg_uart dbg_uart_0 (
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
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
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;
782 //=============================================================================
783 // 10) JTAG COMMUNICATION
784 //=============================================================================
786 JTAG INTERFACE IS NOT SUPPORTED YET
792 `include "openMSP430_undefines.v"