Line 29... |
Line 29... |
//
|
//
|
// *Author(s):
|
// *Author(s):
|
// - Olivier Girard, olgirard@gmail.com
|
// - Olivier Girard, olgirard@gmail.com
|
//
|
//
|
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
// $Rev: 103 $
|
// $Rev: 106 $
|
// $LastChangedBy: olivier.girard $
|
// $LastChangedBy: olivier.girard $
|
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
|
// $LastChangedDate: 2011-03-25 23:01:03 +0100 (Fri, 25 Mar 2011) $
|
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
`ifdef OMSP_NO_INCLUDE
|
`ifdef OMSP_NO_INCLUDE
|
`else
|
`else
|
`include "openMSP430_defines.v"
|
`include "openMSP430_defines.v"
|
`endif
|
`endif
|
Line 48... |
Line 48... |
dbg_mem_addr, // Debug address for rd/wr access
|
dbg_mem_addr, // Debug address for rd/wr access
|
dbg_mem_dout, // Debug unit data output
|
dbg_mem_dout, // Debug unit data output
|
dbg_mem_en, // Debug unit memory enable
|
dbg_mem_en, // Debug unit memory enable
|
dbg_mem_wr, // Debug unit memory write
|
dbg_mem_wr, // Debug unit memory write
|
dbg_reg_wr, // Debug unit CPU register write
|
dbg_reg_wr, // Debug unit CPU register write
|
dbg_reset, // Reset CPU from debug interface
|
dbg_cpu_reset, // Reset CPU from debug interface
|
dbg_uart_txd, // Debug interface: UART TXD
|
dbg_uart_txd, // Debug interface: UART TXD
|
|
|
// INPUTs
|
// INPUTs
|
|
cpu_en_s, // Enable CPU code execution (synchronous)
|
|
dbg_clk, // Debug unit clock
|
|
dbg_en_s, // Debug interface enable (synchronous)
|
dbg_halt_st, // Halt/Run status from CPU
|
dbg_halt_st, // Halt/Run status from CPU
|
dbg_mem_din, // Debug unit Memory data input
|
dbg_mem_din, // Debug unit Memory data input
|
dbg_reg_din, // Debug unit CPU register data input
|
dbg_reg_din, // Debug unit CPU register data input
|
dbg_uart_rxd, // Debug interface: UART RXD
|
dbg_rst, // Debug unit reset
|
|
dbg_uart_rxd, // Debug interface: UART RXD (asynchronous)
|
decode_noirq, // Frontend decode instruction
|
decode_noirq, // Frontend decode instruction
|
eu_mab, // Execution-Unit Memory address bus
|
eu_mab, // Execution-Unit Memory address bus
|
eu_mb_en, // Execution-Unit Memory bus enable
|
eu_mb_en, // Execution-Unit Memory bus enable
|
eu_mb_wr, // Execution-Unit Memory bus write transfer
|
eu_mb_wr, // Execution-Unit Memory bus write transfer
|
eu_mdb_in, // Memory data bus input
|
eu_mdb_in, // Memory data bus input
|
eu_mdb_out, // Memory data bus output
|
eu_mdb_out, // Memory data bus output
|
exec_done, // Execution completed
|
exec_done, // Execution completed
|
fe_mb_en, // Frontend Memory bus enable
|
fe_mb_en, // Frontend Memory bus enable
|
fe_mdb_in, // Frontend Memory data bus input
|
fe_mdb_in, // Frontend Memory data bus input
|
mclk, // Main system clock
|
|
pc, // Program counter
|
pc, // Program counter
|
por, // Power on reset
|
|
puc // Main system reset
|
puc // Main system reset
|
);
|
);
|
|
|
// OUTPUTs
|
// OUTPUTs
|
//=========
|
//=========
|
Line 80... |
Line 82... |
output [15:0] dbg_mem_addr; // Debug address for rd/wr access
|
output [15:0] dbg_mem_addr; // Debug address for rd/wr access
|
output [15:0] dbg_mem_dout; // Debug unit data output
|
output [15:0] dbg_mem_dout; // Debug unit data output
|
output dbg_mem_en; // Debug unit memory enable
|
output dbg_mem_en; // Debug unit memory enable
|
output [1:0] dbg_mem_wr; // Debug unit memory write
|
output [1:0] dbg_mem_wr; // Debug unit memory write
|
output dbg_reg_wr; // Debug unit CPU register write
|
output dbg_reg_wr; // Debug unit CPU register write
|
output dbg_reset; // Reset CPU from debug interface
|
output dbg_cpu_reset; // Reset CPU from debug interface
|
output dbg_uart_txd; // Debug interface: UART TXD
|
output dbg_uart_txd; // Debug interface: UART TXD
|
|
|
// INPUTs
|
// INPUTs
|
//=========
|
//=========
|
|
input cpu_en_s; // Enable CPU code execution (synchronous)
|
|
input dbg_clk; // Debug unit clock
|
|
input dbg_en_s; // Debug interface enable (synchronous)
|
input dbg_halt_st; // Halt/Run status from CPU
|
input dbg_halt_st; // Halt/Run status from CPU
|
input [15:0] dbg_mem_din; // Debug unit Memory data input
|
input [15:0] dbg_mem_din; // Debug unit Memory data input
|
input [15:0] dbg_reg_din; // Debug unit CPU register data input
|
input [15:0] dbg_reg_din; // Debug unit CPU register data input
|
input dbg_uart_rxd; // Debug interface: UART RXD
|
input dbg_rst; // Debug unit reset
|
|
input dbg_uart_rxd; // Debug interface: UART RXD (asynchronous)
|
input decode_noirq; // Frontend decode instruction
|
input decode_noirq; // Frontend decode instruction
|
input [15:0] eu_mab; // Execution-Unit Memory address bus
|
input [15:0] eu_mab; // Execution-Unit Memory address bus
|
input eu_mb_en; // Execution-Unit Memory bus enable
|
input eu_mb_en; // Execution-Unit Memory bus enable
|
input [1:0] eu_mb_wr; // Execution-Unit Memory bus write transfer
|
input [1:0] eu_mb_wr; // Execution-Unit Memory bus write transfer
|
input [15:0] eu_mdb_in; // Memory data bus input
|
input [15:0] eu_mdb_in; // Memory data bus input
|
input [15:0] eu_mdb_out; // Memory data bus output
|
input [15:0] eu_mdb_out; // Memory data bus output
|
input exec_done; // Execution completed
|
input exec_done; // Execution completed
|
input fe_mb_en; // Frontend Memory bus enable
|
input fe_mb_en; // Frontend Memory bus enable
|
input [15:0] fe_mdb_in; // Frontend Memory data bus input
|
input [15:0] fe_mdb_in; // Frontend Memory data bus input
|
input mclk; // Main system clock
|
|
input [15:0] pc; // Program counter
|
input [15:0] pc; // Program counter
|
input por; // Power on reset
|
|
input puc; // Main system reset
|
input puc; // Main system reset
|
|
|
|
|
//=============================================================================
|
//=============================================================================
|
// 1) WIRE & PARAMETER DECLARATION
|
// 1) WIRE & PARAMETER DECLARATION
|
Line 204... |
Line 208... |
parameter BRK3_ADDR1_D = (64'h1 << BRK3_ADDR1);
|
parameter BRK3_ADDR1_D = (64'h1 << BRK3_ADDR1);
|
`endif
|
`endif
|
|
|
// PUC is localy used as a data.
|
// PUC is localy used as a data.
|
reg [1:0] puc_sync;
|
reg [1:0] puc_sync;
|
always @ (posedge mclk or posedge por)
|
always @ (posedge dbg_clk or posedge dbg_rst)
|
if (por) puc_sync <= 2'b11;
|
if (dbg_rst) puc_sync <= 2'b11;
|
else puc_sync <= {puc_sync[0] , puc};
|
else puc_sync <= {puc_sync[0] , puc};
|
wire puc_s = puc_sync[1];
|
wire puc_s = puc_sync[1];
|
|
|
|
|
//============================================================================
|
//============================================================================
|
Line 286... |
Line 290... |
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
reg [6:3] cpu_ctl;
|
reg [6:3] cpu_ctl;
|
|
|
wire cpu_ctl_wr = reg_wr[CPU_CTL];
|
wire cpu_ctl_wr = reg_wr[CPU_CTL];
|
|
|
always @ (posedge mclk or posedge por)
|
always @ (posedge dbg_clk or posedge dbg_rst)
|
if (por) cpu_ctl <= 4'h0;
|
`ifdef DBG_RST_BRK_EN
|
|
if (dbg_rst) cpu_ctl <= 4'h4;
|
|
`else
|
|
if (dbg_rst) cpu_ctl <= 4'h0;
|
|
`endif
|
else if (cpu_ctl_wr) cpu_ctl <= dbg_din[6:3];
|
else if (cpu_ctl_wr) cpu_ctl <= dbg_din[6:3];
|
|
|
wire [7:0] cpu_ctl_full = {1'b0, cpu_ctl, 3'b000};
|
wire [7:0] cpu_ctl_full = {1'b0, cpu_ctl, 3'b000};
|
|
|
wire halt_cpu = cpu_ctl_wr & dbg_din[`HALT] & ~dbg_halt_st;
|
wire halt_cpu = cpu_ctl_wr & dbg_din[`HALT] & ~dbg_halt_st;
|
Line 308... |
Line 316... |
|
|
wire cpu_stat_wr = reg_wr[CPU_STAT];
|
wire cpu_stat_wr = reg_wr[CPU_STAT];
|
wire [3:2] cpu_stat_set = {dbg_swbrk, puc_s};
|
wire [3:2] cpu_stat_set = {dbg_swbrk, puc_s};
|
wire [3:2] cpu_stat_clr = ~dbg_din[3:2];
|
wire [3:2] cpu_stat_clr = ~dbg_din[3:2];
|
|
|
always @ (posedge mclk or posedge por)
|
always @ (posedge dbg_clk or posedge dbg_rst)
|
if (por) cpu_stat <= 2'b00;
|
if (dbg_rst) cpu_stat <= 2'b00;
|
else if (cpu_stat_wr) cpu_stat <= ((cpu_stat & cpu_stat_clr) | cpu_stat_set);
|
else if (cpu_stat_wr) cpu_stat <= ((cpu_stat & cpu_stat_clr) | cpu_stat_set);
|
else cpu_stat <= (cpu_stat | cpu_stat_set);
|
else cpu_stat <= (cpu_stat | cpu_stat_set);
|
|
|
wire [7:0] cpu_stat_full = {brk3_pnd, brk2_pnd, brk1_pnd, brk0_pnd,
|
wire [7:0] cpu_stat_full = {brk3_pnd, brk2_pnd, brk1_pnd, brk0_pnd,
|
cpu_stat, 1'b0, dbg_halt_st};
|
cpu_stat, 1'b0, dbg_halt_st};
|
Line 343... |
Line 351... |
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
reg [3:1] mem_ctl;
|
reg [3:1] mem_ctl;
|
|
|
wire mem_ctl_wr = reg_wr[MEM_CTL];
|
wire mem_ctl_wr = reg_wr[MEM_CTL];
|
|
|
always @ (posedge mclk or posedge por)
|
always @ (posedge dbg_clk or posedge dbg_rst)
|
if (por) mem_ctl <= 3'h0;
|
if (dbg_rst) mem_ctl <= 3'h0;
|
else if (mem_ctl_wr) mem_ctl <= dbg_din[3:1];
|
else if (mem_ctl_wr) mem_ctl <= dbg_din[3:1];
|
|
|
wire [7:0] mem_ctl_full = {4'b0000, mem_ctl, 1'b0};
|
wire [7:0] mem_ctl_full = {4'b0000, mem_ctl, 1'b0};
|
|
|
reg mem_start;
|
reg mem_start;
|
always @ (posedge mclk or posedge por)
|
always @ (posedge dbg_clk or posedge dbg_rst)
|
if (por) mem_start <= 1'b0;
|
if (dbg_rst) mem_start <= 1'b0;
|
else mem_start <= mem_ctl_wr & dbg_din[0];
|
else mem_start <= mem_ctl_wr & dbg_din[0];
|
|
|
wire mem_bw = mem_ctl[3];
|
wire mem_bw = mem_ctl[3];
|
|
|
// MEM_DATA Register
|
// MEM_DATA Register
|
Line 368... |
Line 376... |
|
|
wire [15:0] dbg_mem_din_bw = ~mem_bw ? dbg_mem_din :
|
wire [15:0] dbg_mem_din_bw = ~mem_bw ? dbg_mem_din :
|
mem_addr[0] ? {8'h00, dbg_mem_din[15:8]} :
|
mem_addr[0] ? {8'h00, dbg_mem_din[15:8]} :
|
{8'h00, dbg_mem_din[7:0]};
|
{8'h00, dbg_mem_din[7:0]};
|
|
|
always @ (posedge mclk or posedge por)
|
always @ (posedge dbg_clk or posedge dbg_rst)
|
if (por) mem_data <= 16'h0000;
|
if (dbg_rst) mem_data <= 16'h0000;
|
else if (mem_data_wr) mem_data <= dbg_din;
|
else if (mem_data_wr) mem_data <= dbg_din;
|
else if (dbg_reg_rd) mem_data <= dbg_reg_din;
|
else if (dbg_reg_rd) mem_data <= dbg_reg_din;
|
else if (dbg_mem_rd_dly) mem_data <= dbg_mem_din_bw;
|
else if (dbg_mem_rd_dly) mem_data <= dbg_mem_din_bw;
|
|
|
|
|
Line 387... |
Line 395... |
|
|
wire [15:0] mem_addr_inc = (mem_cnt==16'h0000) ? 16'h0000 :
|
wire [15:0] mem_addr_inc = (mem_cnt==16'h0000) ? 16'h0000 :
|
(dbg_mem_acc & ~mem_bw) ? 16'h0002 :
|
(dbg_mem_acc & ~mem_bw) ? 16'h0002 :
|
(dbg_mem_acc | dbg_reg_acc) ? 16'h0001 : 16'h0000;
|
(dbg_mem_acc | dbg_reg_acc) ? 16'h0001 : 16'h0000;
|
|
|
always @ (posedge mclk or posedge por)
|
always @ (posedge dbg_clk or posedge dbg_rst)
|
if (por) mem_addr <= 16'h0000;
|
if (dbg_rst) mem_addr <= 16'h0000;
|
else if (mem_addr_wr) mem_addr <= dbg_din;
|
else if (mem_addr_wr) mem_addr <= dbg_din;
|
else mem_addr <= mem_addr + mem_addr_inc;
|
else mem_addr <= mem_addr + mem_addr_inc;
|
|
|
// MEM_CNT Register
|
// MEM_CNT Register
|
//------------------
|
//------------------
|
Line 400... |
Line 408... |
wire mem_cnt_wr = reg_wr[MEM_CNT];
|
wire mem_cnt_wr = reg_wr[MEM_CNT];
|
|
|
wire [15:0] mem_cnt_dec = (mem_cnt==16'h0000) ? 16'h0000 :
|
wire [15:0] mem_cnt_dec = (mem_cnt==16'h0000) ? 16'h0000 :
|
(dbg_mem_acc | dbg_reg_acc) ? 16'hffff : 16'h0000;
|
(dbg_mem_acc | dbg_reg_acc) ? 16'hffff : 16'h0000;
|
|
|
always @ (posedge mclk or posedge por)
|
always @ (posedge dbg_clk or posedge dbg_rst)
|
if (por) mem_cnt <= 16'h0000;
|
if (dbg_rst) mem_cnt <= 16'h0000;
|
else if (mem_cnt_wr) mem_cnt <= dbg_din;
|
else if (mem_cnt_wr) mem_cnt <= dbg_din;
|
else mem_cnt <= mem_cnt + mem_cnt_dec;
|
else mem_cnt <= mem_cnt + mem_cnt_dec;
|
|
|
|
|
//=============================================================================
|
//=============================================================================
|
Line 433... |
Line 441... |
.brk_dout (brk0_dout), // Hardware break/watch-point register data input
|
.brk_dout (brk0_dout), // Hardware break/watch-point register data input
|
|
|
// INPUTs
|
// INPUTs
|
.brk_reg_rd (brk0_reg_rd), // Hardware break/watch-point register read select
|
.brk_reg_rd (brk0_reg_rd), // Hardware break/watch-point register read select
|
.brk_reg_wr (brk0_reg_wr), // Hardware break/watch-point register write select
|
.brk_reg_wr (brk0_reg_wr), // Hardware break/watch-point register write select
|
|
.dbg_clk (dbg_clk), // Debug unit clock
|
.dbg_din (dbg_din), // Debug register data input
|
.dbg_din (dbg_din), // Debug register data input
|
|
.dbg_rst (dbg_rst), // Debug unit reset
|
.eu_mab (eu_mab), // Execution-Unit Memory address bus
|
.eu_mab (eu_mab), // Execution-Unit Memory address bus
|
.eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
|
.eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
|
.eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
|
.eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
|
.eu_mdb_in (eu_mdb_in), // Memory data bus input
|
.eu_mdb_in (eu_mdb_in), // Memory data bus input
|
.eu_mdb_out (eu_mdb_out), // Memory data bus output
|
.eu_mdb_out (eu_mdb_out), // Memory data bus output
|
.exec_done (exec_done), // Execution completed
|
.exec_done (exec_done), // Execution completed
|
.fe_mb_en (fe_mb_en), // Frontend Memory bus enable
|
.fe_mb_en (fe_mb_en), // Frontend Memory bus enable
|
.mclk (mclk), // Main system clock
|
.pc (pc) // Program counter
|
.pc (pc), // Program counter
|
|
.por (por) // Power on reset
|
|
);
|
);
|
|
|
`else
|
`else
|
assign brk0_halt = 1'b0;
|
assign brk0_halt = 1'b0;
|
assign brk0_pnd = 1'b0;
|
assign brk0_pnd = 1'b0;
|
Line 475... |
Line 483... |
.brk_dout (brk1_dout), // Hardware break/watch-point register data input
|
.brk_dout (brk1_dout), // Hardware break/watch-point register data input
|
|
|
// INPUTs
|
// INPUTs
|
.brk_reg_rd (brk1_reg_rd), // Hardware break/watch-point register read select
|
.brk_reg_rd (brk1_reg_rd), // Hardware break/watch-point register read select
|
.brk_reg_wr (brk1_reg_wr), // Hardware break/watch-point register write select
|
.brk_reg_wr (brk1_reg_wr), // Hardware break/watch-point register write select
|
|
.dbg_clk (dbg_clk), // Debug unit clock
|
.dbg_din (dbg_din), // Debug register data input
|
.dbg_din (dbg_din), // Debug register data input
|
|
.dbg_rst (dbg_rst), // Debug unit reset
|
.eu_mab (eu_mab), // Execution-Unit Memory address bus
|
.eu_mab (eu_mab), // Execution-Unit Memory address bus
|
.eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
|
.eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
|
.eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
|
.eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
|
.eu_mdb_in (eu_mdb_in), // Memory data bus input
|
.eu_mdb_in (eu_mdb_in), // Memory data bus input
|
.eu_mdb_out (eu_mdb_out), // Memory data bus output
|
.eu_mdb_out (eu_mdb_out), // Memory data bus output
|
.exec_done (exec_done), // Execution completed
|
.exec_done (exec_done), // Execution completed
|
.fe_mb_en (fe_mb_en), // Frontend Memory bus enable
|
.fe_mb_en (fe_mb_en), // Frontend Memory bus enable
|
.mclk (mclk), // Main system clock
|
.pc (pc) // Program counter
|
.pc (pc), // Program counter
|
|
.por (por) // Power on reset
|
|
);
|
);
|
|
|
`else
|
`else
|
assign brk1_halt = 1'b0;
|
assign brk1_halt = 1'b0;
|
assign brk1_pnd = 1'b0;
|
assign brk1_pnd = 1'b0;
|
Line 517... |
Line 525... |
.brk_dout (brk2_dout), // Hardware break/watch-point register data input
|
.brk_dout (brk2_dout), // Hardware break/watch-point register data input
|
|
|
// INPUTs
|
// INPUTs
|
.brk_reg_rd (brk2_reg_rd), // Hardware break/watch-point register read select
|
.brk_reg_rd (brk2_reg_rd), // Hardware break/watch-point register read select
|
.brk_reg_wr (brk2_reg_wr), // Hardware break/watch-point register write select
|
.brk_reg_wr (brk2_reg_wr), // Hardware break/watch-point register write select
|
|
.dbg_clk (dbg_clk), // Debug unit clock
|
.dbg_din (dbg_din), // Debug register data input
|
.dbg_din (dbg_din), // Debug register data input
|
|
.dbg_rst (dbg_rst), // Debug unit reset
|
.eu_mab (eu_mab), // Execution-Unit Memory address bus
|
.eu_mab (eu_mab), // Execution-Unit Memory address bus
|
.eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
|
.eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
|
.eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
|
.eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
|
.eu_mdb_in (eu_mdb_in), // Memory data bus input
|
.eu_mdb_in (eu_mdb_in), // Memory data bus input
|
.eu_mdb_out (eu_mdb_out), // Memory data bus output
|
.eu_mdb_out (eu_mdb_out), // Memory data bus output
|
.exec_done (exec_done), // Execution completed
|
.exec_done (exec_done), // Execution completed
|
.fe_mb_en (fe_mb_en), // Frontend Memory bus enable
|
.fe_mb_en (fe_mb_en), // Frontend Memory bus enable
|
.mclk (mclk), // Main system clock
|
.pc (pc) // Program counter
|
.pc (pc), // Program counter
|
|
.por (por) // Power on reset
|
|
);
|
);
|
|
|
`else
|
`else
|
assign brk2_halt = 1'b0;
|
assign brk2_halt = 1'b0;
|
assign brk2_pnd = 1'b0;
|
assign brk2_pnd = 1'b0;
|
Line 559... |
Line 567... |
.brk_dout (brk3_dout), // Hardware break/watch-point register data input
|
.brk_dout (brk3_dout), // Hardware break/watch-point register data input
|
|
|
// INPUTs
|
// INPUTs
|
.brk_reg_rd (brk3_reg_rd), // Hardware break/watch-point register read select
|
.brk_reg_rd (brk3_reg_rd), // Hardware break/watch-point register read select
|
.brk_reg_wr (brk3_reg_wr), // Hardware break/watch-point register write select
|
.brk_reg_wr (brk3_reg_wr), // Hardware break/watch-point register write select
|
|
.dbg_clk (dbg_clk), // Debug unit clock
|
.dbg_din (dbg_din), // Debug register data input
|
.dbg_din (dbg_din), // Debug register data input
|
|
.dbg_rst (dbg_rst), // Debug unit reset
|
.eu_mab (eu_mab), // Execution-Unit Memory address bus
|
.eu_mab (eu_mab), // Execution-Unit Memory address bus
|
.eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
|
.eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
|
.eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
|
.eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
|
.eu_mdb_in (eu_mdb_in), // Memory data bus input
|
.eu_mdb_in (eu_mdb_in), // Memory data bus input
|
.eu_mdb_out (eu_mdb_out), // Memory data bus output
|
.eu_mdb_out (eu_mdb_out), // Memory data bus output
|
.exec_done (exec_done), // Execution completed
|
.exec_done (exec_done), // Execution completed
|
.fe_mb_en (fe_mb_en), // Frontend Memory bus enable
|
.fe_mb_en (fe_mb_en), // Frontend Memory bus enable
|
.mclk (mclk), // Main system clock
|
.pc (pc) // Program counter
|
.pc (pc), // Program counter
|
|
.por (por) // Power on reset
|
|
);
|
);
|
|
|
`else
|
`else
|
assign brk3_halt = 1'b0;
|
assign brk3_halt = 1'b0;
|
assign brk3_pnd = 1'b0;
|
assign brk3_pnd = 1'b0;
|
Line 606... |
Line 614... |
brk1_dout |
|
brk1_dout |
|
brk2_dout |
|
brk2_dout |
|
brk3_dout;
|
brk3_dout;
|
|
|
// Tell UART/JTAG interface that the data is ready to be read
|
// Tell UART/JTAG interface that the data is ready to be read
|
always @ (posedge mclk or posedge por)
|
always @ (posedge dbg_clk or posedge dbg_rst)
|
if (por) dbg_rd_rdy <= 1'b0;
|
if (dbg_rst) dbg_rd_rdy <= 1'b0;
|
else if (mem_burst | mem_burst_rd) dbg_rd_rdy <= (dbg_reg_rd | dbg_mem_rd_dly);
|
else if (mem_burst | mem_burst_rd) dbg_rd_rdy <= (dbg_reg_rd | dbg_mem_rd_dly);
|
else dbg_rd_rdy <= dbg_rd;
|
else dbg_rd_rdy <= dbg_rd;
|
|
|
|
|
//============================================================================
|
//============================================================================
|
// 7) CPU CONTROL
|
// 7) CPU CONTROL
|
//============================================================================
|
//============================================================================
|
|
|
// Reset CPU
|
// Reset CPU
|
//--------------------------
|
//--------------------------
|
wire dbg_reset = cpu_ctl[`CPU_RST];
|
wire dbg_cpu_reset = cpu_ctl[`CPU_RST];
|
|
|
|
|
// Break after reset
|
// Break after reset
|
//--------------------------
|
//--------------------------
|
wire halt_rst = cpu_ctl[`RST_BRK_EN] & puc_s;
|
wire halt_rst = cpu_ctl[`RST_BRK_EN] & dbg_en_s & puc_s;
|
|
|
|
|
// Freeze peripherals
|
// Freeze peripherals
|
//--------------------------
|
//--------------------------
|
wire dbg_freeze = dbg_halt_st & cpu_ctl[`FRZ_BRK_EN];
|
wire dbg_freeze = dbg_halt_st & (cpu_ctl[`FRZ_BRK_EN] | ~cpu_en_s);
|
|
|
|
|
// Software break
|
// Software break
|
//--------------------------
|
//--------------------------
|
assign dbg_swbrk = (fe_mdb_in==`DBG_SWBRK_OP) & decode_noirq & cpu_ctl[`SW_BRK_EN];
|
assign dbg_swbrk = (fe_mdb_in==`DBG_SWBRK_OP) & decode_noirq & cpu_ctl[`SW_BRK_EN];
|
|
|
|
|
// Single step
|
// Single step
|
//--------------------------
|
//--------------------------
|
reg [1:0] inc_step;
|
reg [1:0] inc_step;
|
always @(posedge mclk or posedge por)
|
always @(posedge dbg_clk or posedge dbg_rst)
|
if (por) inc_step <= 2'b00;
|
if (dbg_rst) inc_step <= 2'b00;
|
else if (istep) inc_step <= 2'b11;
|
else if (istep) inc_step <= 2'b11;
|
else inc_step <= {inc_step[0], 1'b0};
|
else inc_step <= {inc_step[0], 1'b0};
|
|
|
|
|
// Run / Halt
|
// Run / Halt
|
Line 656... |
Line 664... |
|
|
wire halt_flag_clr = run_cpu | mem_run_cpu;
|
wire halt_flag_clr = run_cpu | mem_run_cpu;
|
wire halt_flag_set = halt_cpu | halt_rst | dbg_swbrk | mem_halt_cpu |
|
wire halt_flag_set = halt_cpu | halt_rst | dbg_swbrk | mem_halt_cpu |
|
brk0_halt | brk1_halt | brk2_halt | brk3_halt;
|
brk0_halt | brk1_halt | brk2_halt | brk3_halt;
|
|
|
always @(posedge mclk or posedge por)
|
always @(posedge dbg_clk or posedge dbg_rst)
|
if (por) halt_flag <= 1'b0;
|
if (dbg_rst) halt_flag <= 1'b0;
|
else if (halt_flag_clr) halt_flag <= 1'b0;
|
else if (halt_flag_clr) halt_flag <= 1'b0;
|
else if (halt_flag_set) halt_flag <= 1'b1;
|
else if (halt_flag_set) halt_flag <= 1'b1;
|
|
|
wire dbg_halt_cmd = (halt_flag | halt_flag_set) & ~inc_step[1];
|
wire dbg_halt_cmd = (halt_flag | halt_flag_set) & ~inc_step[1];
|
|
|
Line 675... |
Line 683... |
|
|
wire mem_burst_start = (mem_start & |mem_cnt);
|
wire mem_burst_start = (mem_start & |mem_cnt);
|
wire mem_burst_end = ((dbg_wr | dbg_rd_rdy) & ~|mem_cnt);
|
wire mem_burst_end = ((dbg_wr | dbg_rd_rdy) & ~|mem_cnt);
|
|
|
// Detect when burst is on going
|
// Detect when burst is on going
|
always @(posedge mclk or posedge por)
|
always @(posedge dbg_clk or posedge dbg_rst)
|
if (por) mem_burst <= 1'b0;
|
if (dbg_rst) mem_burst <= 1'b0;
|
else if (mem_burst_start) mem_burst <= 1'b1;
|
else if (mem_burst_start) mem_burst <= 1'b1;
|
else if (mem_burst_end) mem_burst <= 1'b0;
|
else if (mem_burst_end) mem_burst <= 1'b0;
|
|
|
// Control signals for UART/JTAG interface
|
// Control signals for UART/JTAG interface
|
assign mem_burst_rd = (mem_burst_start & ~mem_ctl[1]);
|
assign mem_burst_rd = (mem_burst_start & ~mem_ctl[1]);
|
assign mem_burst_wr = (mem_burst_start & mem_ctl[1]);
|
assign mem_burst_wr = (mem_burst_start & mem_ctl[1]);
|
|
|
// Trigger CPU Register or memory access during a burst
|
// Trigger CPU Register or memory access during a burst
|
reg mem_startb;
|
reg mem_startb;
|
always @(posedge mclk or posedge por)
|
always @(posedge dbg_clk or posedge dbg_rst)
|
if (por) mem_startb <= 1'b0;
|
if (dbg_rst) mem_startb <= 1'b0;
|
else mem_startb <= (mem_burst & (dbg_wr | dbg_rd)) | mem_burst_rd;
|
else mem_startb <= (mem_burst & (dbg_wr | dbg_rd)) | mem_burst_rd;
|
|
|
// Combine single and burst memory start of sequence
|
// Combine single and burst memory start of sequence
|
wire mem_seq_start = ((mem_start & ~|mem_cnt) | mem_startb);
|
wire mem_seq_start = ((mem_start & ~|mem_cnt) | mem_startb);
|
|
|
Line 717... |
Line 725... |
M_ACCESS : mem_state_nxt = M_IDLE;
|
M_ACCESS : mem_state_nxt = M_IDLE;
|
default : mem_state_nxt = M_IDLE;
|
default : mem_state_nxt = M_IDLE;
|
endcase
|
endcase
|
|
|
// State machine
|
// State machine
|
always @(posedge mclk or posedge por)
|
always @(posedge dbg_clk or posedge dbg_rst)
|
if (por) mem_state <= M_IDLE;
|
if (dbg_rst) mem_state <= M_IDLE;
|
else mem_state <= mem_state_nxt;
|
else mem_state <= mem_state_nxt;
|
|
|
// Utility signals
|
// Utility signals
|
assign mem_halt_cpu = (mem_state==M_IDLE) & (mem_state_nxt==M_SET_BRK);
|
assign mem_halt_cpu = (mem_state==M_IDLE) & (mem_state_nxt==M_SET_BRK);
|
assign mem_run_cpu = (mem_state==M_ACCESS_BRK) & (mem_state_nxt==M_IDLE);
|
assign mem_run_cpu = (mem_state==M_ACCESS_BRK) & (mem_state_nxt==M_IDLE);
|
Line 746... |
Line 754... |
mem_addr[0] ? 2'b10 : 2'b01;
|
mem_addr[0] ? 2'b10 : 2'b01;
|
assign dbg_mem_wr = {2{dbg_mem_en & mem_ctl[1]}} & dbg_mem_wr_msk;
|
assign dbg_mem_wr = {2{dbg_mem_en & mem_ctl[1]}} & dbg_mem_wr_msk;
|
|
|
|
|
// It takes one additional cycle to read from Memory as from registers
|
// It takes one additional cycle to read from Memory as from registers
|
always @(posedge mclk or posedge por)
|
always @(posedge dbg_clk or posedge dbg_rst)
|
if (por) dbg_mem_rd_dly <= 1'b0;
|
if (dbg_rst) dbg_mem_rd_dly <= 1'b0;
|
else dbg_mem_rd_dly <= dbg_mem_rd;
|
else dbg_mem_rd_dly <= dbg_mem_rd;
|
|
|
|
|
//=============================================================================
|
//=============================================================================
|
// 9) UART COMMUNICATION
|
// 9) UART COMMUNICATION
|
Line 765... |
Line 773... |
.dbg_rd (dbg_rd), // Debug register data read
|
.dbg_rd (dbg_rd), // Debug register data read
|
.dbg_uart_txd (dbg_uart_txd), // Debug interface: UART TXD
|
.dbg_uart_txd (dbg_uart_txd), // Debug interface: UART TXD
|
.dbg_wr (dbg_wr), // Debug register data write
|
.dbg_wr (dbg_wr), // Debug register data write
|
|
|
// INPUTs
|
// INPUTs
|
|
.dbg_clk (dbg_clk), // Debug unit clock
|
.dbg_dout (dbg_dout), // Debug register data output
|
.dbg_dout (dbg_dout), // Debug register data output
|
.dbg_rd_rdy (dbg_rd_rdy), // Debug register data is ready for read
|
.dbg_rd_rdy (dbg_rd_rdy), // Debug register data is ready for read
|
|
.dbg_rst (dbg_rst), // Debug unit reset
|
.dbg_uart_rxd (dbg_uart_rxd), // Debug interface: UART RXD
|
.dbg_uart_rxd (dbg_uart_rxd), // Debug interface: UART RXD
|
.mclk (mclk), // Main system clock
|
|
.mem_burst (mem_burst), // Burst on going
|
.mem_burst (mem_burst), // Burst on going
|
.mem_burst_end(mem_burst_end), // End TX/RX burst
|
.mem_burst_end(mem_burst_end), // End TX/RX burst
|
.mem_burst_rd (mem_burst_rd), // Start TX burst
|
.mem_burst_rd (mem_burst_rd), // Start TX burst
|
.mem_burst_wr (mem_burst_wr), // Start RX burst
|
.mem_burst_wr (mem_burst_wr), // Start RX burst
|
.mem_bw (mem_bw), // Burst byte width
|
.mem_bw (mem_bw) // Burst byte width
|
.por (por) // Power on reset
|
|
);
|
);
|
|
|
`else
|
`else
|
assign dbg_addr = 6'h00;
|
assign dbg_addr = 6'h00;
|
assign dbg_din = 16'h0000;
|
assign dbg_din = 16'h0000;
|