When DEBUG_WEDGE is defined, expose the last committed and next in the reorder buffer PC and corresponding instruction via DMI registers, since even when the core is wedged and we can't read GPRs etc we can still interact with the debug module itself. Hopefully this proves useful for debugging wedges.
533 lines
18 KiB
Plaintext
533 lines
18 KiB
Plaintext
// Copyright (c) 2017-2019 Bluespec, Inc. All Rights Reserved.
|
|
|
|
package DM_Common;
|
|
|
|
// ================================================================
|
|
// This package has non-implementation-specific definitions, i.e.,
|
|
// just encodes things in the spec.
|
|
|
|
// ================================================================
|
|
// BSV library imports
|
|
|
|
// None
|
|
|
|
// ================================================================
|
|
// Project imports
|
|
|
|
// None
|
|
|
|
// ================================================================
|
|
// Debug Module Interface (DMI) addresses and data.
|
|
// Note: data is always 32b, whether the connected CPU is RV32, RV64 or RV128.
|
|
|
|
typedef Bit #(7) DM_Addr;
|
|
|
|
DM_Addr max_DM_Addr = 'h7F;
|
|
|
|
typedef Bit #(32) DM_Word;
|
|
|
|
// ================================================================
|
|
// Debug Module address map
|
|
|
|
// ----------------
|
|
// Run Control
|
|
|
|
DM_Addr dm_addr_dmcontrol = 'h10;
|
|
DM_Addr dm_addr_dmstatus = 'h11;
|
|
DM_Addr dm_addr_hartinfo = 'h12;
|
|
DM_Addr dm_addr_haltsum = 'h13;
|
|
DM_Addr dm_addr_hawindowsel = 'h14;
|
|
DM_Addr dm_addr_hawindow = 'h15;
|
|
DM_Addr dm_addr_devtreeaddr0 = 'h19;
|
|
DM_Addr dm_addr_authdata = 'h30;
|
|
DM_Addr dm_addr_haltregion0 = 'h40;
|
|
DM_Addr dm_addr_haltregion31 = 'h5F;
|
|
|
|
DM_Addr dm_addr_verbosity = 'h60; // Non-standard (not in spec)
|
|
|
|
// ----------------
|
|
// Abstract commands (read/write RISC-V registers and RISC-V CSRs)
|
|
|
|
DM_Addr dm_addr_abstractcs = 'h16;
|
|
DM_Addr dm_addr_command = 'h17;
|
|
|
|
DM_Addr dm_addr_data0 = 'h04;
|
|
DM_Addr dm_addr_data1 = 'h05;
|
|
DM_Addr dm_addr_data2 = 'h06;
|
|
DM_Addr dm_addr_data3 = 'h07;
|
|
DM_Addr dm_addr_data4 = 'h08;
|
|
DM_Addr dm_addr_data5 = 'h09;
|
|
DM_Addr dm_addr_data6 = 'h0a;
|
|
DM_Addr dm_addr_data7 = 'h0b;
|
|
DM_Addr dm_addr_data8 = 'h0c;
|
|
DM_Addr dm_addr_data9 = 'h0d;
|
|
DM_Addr dm_addr_data10 = 'h0d;
|
|
DM_Addr dm_addr_data11 = 'h0f;
|
|
|
|
DM_Addr dm_addr_abstractauto = 'h18;
|
|
DM_Addr dm_addr_progbuf0 = 'h20;
|
|
|
|
// ----------------
|
|
// System Bus access (read/write RISC-V memory/devices)
|
|
|
|
DM_Addr dm_addr_sbcs = 'h38;
|
|
DM_Addr dm_addr_sbaddress0 = 'h39;
|
|
DM_Addr dm_addr_sbaddress1 = 'h3a;
|
|
DM_Addr dm_addr_sbaddress2 = 'h3b;
|
|
DM_Addr dm_addr_sbdata0 = 'h3c;
|
|
DM_Addr dm_addr_sbdata1 = 'h3d;
|
|
DM_Addr dm_addr_sbdata2 = 'h3e;
|
|
DM_Addr dm_addr_sbdata3 = 'h3f;
|
|
|
|
// ----------------
|
|
// Custom registers
|
|
|
|
DM_Addr dm_addr_custom0 = 'h70;
|
|
DM_Addr dm_addr_custom1 = 'h71;
|
|
DM_Addr dm_addr_custom2 = 'h72;
|
|
DM_Addr dm_addr_custom3 = 'h73;
|
|
DM_Addr dm_addr_custom4 = 'h74;
|
|
DM_Addr dm_addr_custom5 = 'h75;
|
|
DM_Addr dm_addr_custom6 = 'h76;
|
|
DM_Addr dm_addr_custom7 = 'h77;
|
|
DM_Addr dm_addr_custom8 = 'h78;
|
|
DM_Addr dm_addr_custom9 = 'h79;
|
|
DM_Addr dm_addr_custom10 = 'h7a;
|
|
DM_Addr dm_addr_custom11 = 'h7b;
|
|
DM_Addr dm_addr_custom12 = 'h7c;
|
|
DM_Addr dm_addr_custom13 = 'h7d;
|
|
DM_Addr dm_addr_custom14 = 'h7e;
|
|
DM_Addr dm_addr_custom15 = 'h7f;
|
|
|
|
// ================================================================
|
|
|
|
function Fmt fshow_dm_addr (DM_Addr dm_addr);
|
|
return case (dm_addr)
|
|
// Run Control
|
|
dm_addr_dmcontrol: $format ("dm_addr_dmcontrol");
|
|
dm_addr_dmstatus: $format ("dm_addr_dmstatus");
|
|
dm_addr_hartinfo: $format ("dm_addr_hartinfo");
|
|
dm_addr_haltsum: $format ("dm_addr_haltsum");
|
|
dm_addr_hawindowsel: $format ("dm_addr_hawindowsel");
|
|
dm_addr_hawindow: $format ("dm_addr_hawindow");
|
|
dm_addr_devtreeaddr0: $format ("dm_addr_devtreeaddr0");
|
|
dm_addr_authdata: $format ("dm_addr_authdata");
|
|
dm_addr_haltregion0: $format ("dm_addr_haltregion0");
|
|
dm_addr_haltregion31: $format ("dm_addr_haltregion31");
|
|
dm_addr_verbosity: $format ("dm_addr_verbosity");
|
|
|
|
// Abstract Commands
|
|
dm_addr_abstractcs: $format ("dm_addr_abstractcs");
|
|
dm_addr_command: $format ("dm_addr_command");
|
|
dm_addr_data0: $format ("dm_addr_data0");
|
|
dm_addr_data1: $format ("dm_addr_data1");
|
|
dm_addr_data2: $format ("dm_addr_data2");
|
|
dm_addr_data3: $format ("dm_addr_data3");
|
|
dm_addr_data4: $format ("dm_addr_data4");
|
|
dm_addr_data5: $format ("dm_addr_data5");
|
|
dm_addr_data6: $format ("dm_addr_data6");
|
|
dm_addr_data7: $format ("dm_addr_data7");
|
|
dm_addr_data8: $format ("dm_addr_data8");
|
|
dm_addr_data9: $format ("dm_addr_data9");
|
|
dm_addr_data10: $format ("dm_addr_data10");
|
|
dm_addr_data11: $format ("dm_addr_data11");
|
|
dm_addr_abstractauto: $format ("dm_addr_abstractauto");
|
|
dm_addr_progbuf0: $format ("dm_addr_progbuf0");
|
|
|
|
// System Bus
|
|
dm_addr_sbcs: $format ("dm_addr_sbcs");
|
|
dm_addr_sbaddress0: $format ("dm_addr_sbaddress0");
|
|
dm_addr_sbaddress1: $format ("dm_addr_sbaddress1");
|
|
dm_addr_sbaddress2: $format ("dm_addr_sbaddress2");
|
|
dm_addr_sbdata0: $format ("dm_addr_sbdata0");
|
|
dm_addr_sbdata1: $format ("dm_addr_sbdata1");
|
|
dm_addr_sbdata2: $format ("dm_addr_sbdata2");
|
|
dm_addr_sbdata3: $format ("dm_addr_sbdata3");
|
|
|
|
default: $format ("<Unknown dm_abstract_command dm_addr 0x%0h>", dm_addr);
|
|
endcase;
|
|
endfunction
|
|
|
|
// ================================================================
|
|
// Run Control DM register fields
|
|
|
|
// ----------------------------------------------------------------
|
|
// 'dmcontrol' register
|
|
|
|
function DM_Word fn_mk_dmcontrol (Bool haltreq,
|
|
Bool resumereq,
|
|
Bool hartreset,
|
|
Bool hasel,
|
|
Bit #(10) hartsel,
|
|
Bool ndmreset,
|
|
Bool dmactive);
|
|
return {pack (haltreq),
|
|
pack (resumereq),
|
|
pack (hartreset),
|
|
2'b0,
|
|
pack (hasel),
|
|
hartsel,
|
|
14'b0,
|
|
pack (ndmreset),
|
|
pack (dmactive)};
|
|
endfunction
|
|
|
|
function Bool fn_dmcontrol_haltreq (DM_Word dm_word);
|
|
return unpack (dm_word [31]);
|
|
endfunction
|
|
|
|
function Bool fn_dmcontrol_resumereq (DM_Word dm_word);
|
|
return unpack (dm_word [30]);
|
|
endfunction
|
|
|
|
function Bool fn_dmcontrol_hartreset (DM_Word dm_word);
|
|
return unpack (dm_word [29]);
|
|
endfunction
|
|
|
|
function Bool fn_dmcontrol_hasel (DM_Word dm_word);
|
|
return unpack (dm_word [26]);
|
|
endfunction
|
|
|
|
function Bit #(10) fn_dmcontrol_hartsel (DM_Word dm_word);
|
|
return dm_word [25:16];
|
|
endfunction
|
|
|
|
function Bool fn_dmcontrol_ndmreset (DM_Word dm_word);
|
|
return unpack (dm_word [1]);
|
|
endfunction
|
|
|
|
function Bool fn_dmcontrol_dmactive (DM_Word dm_word);
|
|
return unpack (dm_word [0]);
|
|
endfunction
|
|
|
|
// ----------------------------------------------------------------
|
|
// 'dmstatus' register
|
|
|
|
function Bool fn_dmstatus_allresumeack (DM_Word x);
|
|
return unpack (x [17]);
|
|
endfunction
|
|
|
|
function Bool fn_dmstatus_anyresumeack (DM_Word x);
|
|
return unpack (x [16]);
|
|
endfunction
|
|
|
|
function Bool fn_dmstatus_allnonexistent (DM_Word x);
|
|
return unpack (x [15]);
|
|
endfunction
|
|
|
|
function Bool fn_dmstatus_anynonexistent (DM_Word x);
|
|
return unpack (x [14]);
|
|
endfunction
|
|
|
|
function Bool fn_dmstatus_allunavail (DM_Word x);
|
|
return unpack (x [13]);
|
|
endfunction
|
|
|
|
function Bool fn_dmstatus_anyunavail (DM_Word x);
|
|
return unpack (x [12]);
|
|
endfunction
|
|
|
|
function Bool fn_dmstatus_allrunning (DM_Word x);
|
|
return unpack (x [11]);
|
|
endfunction
|
|
|
|
function Bool fn_dmstatus_anyrunning (DM_Word x);
|
|
return unpack (x [10]);
|
|
endfunction
|
|
|
|
function Bool fn_dmstatus_allhalted (DM_Word x);
|
|
return unpack (x [9]);
|
|
endfunction
|
|
|
|
function Bool fn_dmstatus_anyhalted (DM_Word x);
|
|
return unpack (x [8]);
|
|
endfunction
|
|
|
|
function Bool fn_dmstatus_authenticated (DM_Word x);
|
|
return unpack (x [7]);
|
|
endfunction
|
|
|
|
function Bool fn_dmstatus_authbusy (DM_Word x);
|
|
return unpack (x [6]);
|
|
endfunction
|
|
|
|
function Bool fn_dmstatus_devtreevalid (DM_Word x);
|
|
return unpack (x [4]);
|
|
endfunction
|
|
|
|
function Bit #(4) fn_dmstatus_version (DM_Word x);
|
|
return unpack (x [3:0]);
|
|
endfunction
|
|
|
|
function Fmt fshow_dmstatus (DM_Word x);
|
|
Fmt fmt_version = ( (x[3:0] == 0)
|
|
? $format ("v.none")
|
|
: ( (x[3:0] == 1)
|
|
? $format ("v0.11")
|
|
: ( (x[3:0] == 2)
|
|
? $format ("v0.13")
|
|
: $format ("v??"))));
|
|
|
|
return ( $format ("(all/any) ")
|
|
+ $format ("resumeack %0d/%0d ", x[17], x[16])
|
|
+ $format ("nonexistent %0d/%0d ", x[15], x[14])
|
|
+ $format ("unavail %0d/%0d ", x[13], x[12])
|
|
+ $format ("running %0d/%0d ", x[11], x[10])
|
|
+ $format ("halted %0d/%0d ", x[9], x[8])
|
|
+ $format ("authenticated %0d ", x[7])
|
|
+ $format ("authbusy %0d ", x[6])
|
|
+ $format ("devtreevalid %0d ", x[4])
|
|
+ fmt_version);
|
|
endfunction
|
|
|
|
// ================================================================
|
|
// Abstract Command register fields
|
|
|
|
// ----------------------------------------------------------------
|
|
// 'dm_abstractcs' register
|
|
|
|
typedef enum {DM_ABSTRACTCS_CMDERR_NONE, // 0
|
|
DM_ABSTRACTCS_CMDERR_BUSY, // 1
|
|
DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED, // 2
|
|
DM_ABSTRACTCS_CMDERR_EXCEPTION, // 3
|
|
DM_ABSTRACTCS_CMDERR_HALT_RESUME, // 4
|
|
DM_ABSTRACTCS_CMDERR_UNDEF5, // 5
|
|
DM_ABSTRACTCS_CMDERR_UNDEF6, // 6
|
|
DM_ABSTRACTCS_CMDERR_OTHER // 7
|
|
} DM_abstractcs_cmderr
|
|
deriving (Bits, Eq, FShow);
|
|
|
|
// The following is used in writes, to clear cmderr
|
|
DM_abstractcs_cmderr dm_cmderr_w1c = DM_ABSTRACTCS_CMDERR_OTHER;
|
|
|
|
function DM_Word fn_mk_abstractcs (DM_abstractcs_cmderr cmderr);
|
|
return { 0, pack (cmderr), 8'h0 };
|
|
endfunction
|
|
|
|
function Bit #(5) fn_abstractcs_progsize (DM_Word dm_word);
|
|
return unpack (dm_word [28:24]);
|
|
endfunction
|
|
|
|
function Bool fn_abstractcs_busy (DM_Word dm_word);
|
|
return unpack (dm_word [12]);
|
|
endfunction
|
|
|
|
function DM_abstractcs_cmderr fn_abstractcs_cmderr (DM_Word dm_word);
|
|
return unpack (dm_word [10:8]);
|
|
endfunction
|
|
|
|
function Bit #(5) fn_abstractcs_datacount (DM_Word dm_word);
|
|
return unpack (dm_word [4:0]);
|
|
endfunction
|
|
|
|
// ----------------------------------------------------------------
|
|
// 'command' register
|
|
|
|
typedef enum {DM_COMMAND_CMDTYPE_ACCESS_REG,
|
|
DM_COMMAND_CMDTYPE_QUICK_ACCESS
|
|
} DM_command_cmdtype
|
|
deriving (Bits, Eq, FShow);
|
|
|
|
typedef enum {DM_COMMAND_ACCESS_REG_SIZE_UNDEF0, // 0
|
|
DM_COMMAND_ACCESS_REG_SIZE_UNDEF1, // 1
|
|
DM_COMMAND_ACCESS_REG_SIZE_LOWER32, // 2
|
|
DM_COMMAND_ACCESS_REG_SIZE_LOWER64, // 3
|
|
DM_COMMAND_ACCESS_REG_SIZE_LOWER128, // 4
|
|
DM_COMMAND_ACCESS_REG_SIZE_UNDEF5, // 5
|
|
DM_COMMAND_ACCESS_REG_SIZE_UNDEF6, // 6
|
|
DM_COMMAND_ACCESS_REG_SIZE_UNDEF7 // 7
|
|
} DM_command_access_reg_size
|
|
deriving (Bits, Eq, FShow);
|
|
|
|
Integer dm_command_access_reg_regno_csr_0 = 'h0000;
|
|
Integer dm_command_access_reg_regno_csr_FFF = 'h0FFF;
|
|
Integer dm_command_access_reg_regno_gpr_0 = 'h1000;
|
|
Integer dm_command_access_reg_regno_gpr_1F = 'h101F;
|
|
Integer dm_command_access_reg_regno_fpr_0 = 'h1020;
|
|
Integer dm_command_access_reg_regno_fpr_1F = 'h103F;
|
|
|
|
function DM_Word fn_mk_command_access_reg (DM_command_access_reg_size size,
|
|
Bool postexec,
|
|
Bool transfer,
|
|
Bool write,
|
|
Bit #(16) regno);
|
|
Bit #(8) b8_cmdtype = zeroExtend (pack (DM_COMMAND_CMDTYPE_ACCESS_REG));
|
|
Bit #(3) b3_size = pack (size);
|
|
return {b8_cmdtype,
|
|
1'b0,
|
|
b3_size,
|
|
1'b0,
|
|
pack (postexec),
|
|
pack (transfer),
|
|
pack (write),
|
|
regno};
|
|
endfunction
|
|
|
|
function DM_command_cmdtype fn_command_cmdtype (DM_Word dm_word);
|
|
return unpack (truncate (dm_word [31:24]));
|
|
endfunction
|
|
|
|
function DM_command_access_reg_size fn_command_access_reg_size (DM_Word dm_word);
|
|
return unpack (dm_word [22:20]);
|
|
endfunction
|
|
|
|
function Bool fn_command_access_reg_postexec (DM_Word dm_word);
|
|
return unpack (dm_word [18]);
|
|
endfunction
|
|
|
|
function Bool fn_command_access_reg_transfer (DM_Word dm_word);
|
|
return unpack (dm_word [17]);
|
|
endfunction
|
|
|
|
function Bool fn_command_access_reg_write (DM_Word dm_word);
|
|
return unpack (dm_word [16]);
|
|
endfunction
|
|
|
|
function Bit #(16) fn_command_access_reg_regno (DM_Word dm_word);
|
|
return dm_word [15:0];
|
|
endfunction
|
|
|
|
// ================================================================
|
|
// System Bus Access DM register fields
|
|
|
|
// ----------------------------------------------------------------
|
|
// 'dm_sbcs' register
|
|
|
|
typedef enum {DM_SBACCESS_8_BIT,
|
|
DM_SBACCESS_16_BIT,
|
|
DM_SBACCESS_32_BIT,
|
|
DM_SBACCESS_64_BIT,
|
|
DM_SBACCESS_128_BIT
|
|
} DM_sbaccess
|
|
deriving (Bits, Eq, FShow);
|
|
|
|
function Integer fn_sbaccess_to_addr_incr (DM_sbaccess sbaccess);
|
|
case (sbaccess)
|
|
DM_SBACCESS_8_BIT: return 1;
|
|
DM_SBACCESS_16_BIT: return 2;
|
|
DM_SBACCESS_32_BIT: return 4;
|
|
DM_SBACCESS_64_BIT: return 8;
|
|
DM_SBACCESS_128_BIT: return 16;
|
|
endcase
|
|
endfunction
|
|
|
|
typedef enum {DM_SBERROR_NONE, // 0
|
|
DM_SBERROR_TIMEOUT, // 1
|
|
DM_SBERROR_BADADDR, // 2
|
|
DM_SBERROR_OTHER, // 3
|
|
DM_SBERROR_BUSY_STALE, // 4
|
|
DM_SBERROR_UNDEF5, // 5
|
|
DM_SBERROR_UNDEF6, // 6
|
|
DM_SBERROR_UNDEF7_W1C // 7, used in writes, to clear sberror
|
|
} DM_sberror
|
|
deriving (Bits, Eq, FShow);
|
|
|
|
// Constructor
|
|
|
|
function DM_Word fn_mk_sbcs_val (Bit #(3) sbversion,
|
|
Bool sbbusyerror,
|
|
Bool sbbusy,
|
|
Bool sbreadonaddr,
|
|
DM_sbaccess sbaccess,
|
|
Bool sbautoincrement,
|
|
Bool sbreadondata,
|
|
DM_sberror sberror,
|
|
Bit #(7) sbasize,
|
|
Bit #(1) sbaccess128,
|
|
Bit #(1) sbaccess64,
|
|
Bit #(1) sbaccess32,
|
|
Bit #(1) sbaccess16,
|
|
Bit #(1) sbaccess8);
|
|
return {sbversion,
|
|
6'b0,
|
|
pack (sbbusyerror),
|
|
pack (sbbusy),
|
|
pack (sbreadonaddr),
|
|
pack (sbaccess),
|
|
pack (sbautoincrement),
|
|
pack (sbreadondata),
|
|
pack (sberror),
|
|
sbasize,
|
|
sbaccess128,
|
|
sbaccess64,
|
|
sbaccess32,
|
|
sbaccess16,
|
|
sbaccess8};
|
|
endfunction
|
|
|
|
// Selectors
|
|
|
|
function Bit #(3) fn_sbcs_sbversion (DM_Word dm_word); return unpack (dm_word [31:29]); endfunction
|
|
function Bool fn_sbcs_sbbusyerror (DM_Word dm_word); return unpack (dm_word [22]); endfunction
|
|
function Bool fn_sbcs_sbbusy (DM_Word dm_word); return unpack (dm_word [21]); endfunction
|
|
function Bool fn_sbcs_sbreadonaddr (DM_Word dm_word); return unpack (dm_word [20]); endfunction
|
|
function DM_sbaccess fn_sbcs_sbaccess (DM_Word dm_word); return unpack (dm_word [19:17]); endfunction
|
|
function Bool fn_sbcs_sbautoincrement (DM_Word dm_word); return unpack (dm_word [16]); endfunction
|
|
function Bool fn_sbcs_sbreadondata (DM_Word dm_word); return unpack (dm_word [15]); endfunction
|
|
function DM_sberror fn_sbcs_sberror (DM_Word dm_word); return unpack (dm_word [14:12]); endfunction
|
|
function Bit #(7) fn_sbcs_sbasize (DM_Word dm_word); return dm_word [11:5]; endfunction
|
|
function Bool fn_sbcs_sbaccess128 (DM_Word dm_word); return unpack (dm_word [4]); endfunction
|
|
function Bool fn_sbcs_sbaccess64 (DM_Word dm_word); return unpack (dm_word [3]); endfunction
|
|
function Bool fn_sbcs_sbaccess32 (DM_Word dm_word); return unpack (dm_word [2]); endfunction
|
|
function Bool fn_sbcs_sbaccess16 (DM_Word dm_word); return unpack (dm_word [1]); endfunction
|
|
function Bool fn_sbcs_sbaccess8 (DM_Word dm_word); return unpack (dm_word [0]); endfunction
|
|
|
|
// Debugging
|
|
|
|
function Fmt fshow_sbcs (DM_Word dm_word);
|
|
return ( $format ("SBCS{")
|
|
+ $format ("sbversion %0d", fn_sbcs_sbversion (dm_word))
|
|
+ $format (" sbbusyerror %0d", fn_sbcs_sbbusyerror (dm_word))
|
|
+ $format (" sbbusy %0d", fn_sbcs_sbbusy (dm_word))
|
|
+ $format (" sbreadonaddr ") + fshow (fn_sbcs_sbreadonaddr (dm_word))
|
|
+ $format (" sbaccess ") + fshow (fn_sbcs_sbaccess (dm_word))
|
|
+ $format (" sbautoincrement ") + fshow (fn_sbcs_sbautoincrement (dm_word))
|
|
+ $format (" sbreadondata ") + fshow (fn_sbcs_sbreadondata (dm_word))
|
|
+ $format (" sberror ") + fshow (fn_sbcs_sberror (dm_word))
|
|
+ $format (" sbasize %0d", fn_sbcs_sbasize (dm_word))
|
|
+ $format (" sbaccess")
|
|
+ ((fn_sbcs_sbaccess128 (dm_word)) ? $format ("_128") : $format ("x"))
|
|
+ ((fn_sbcs_sbaccess64 (dm_word)) ? $format ("_64") : $format ("x"))
|
|
+ ((fn_sbcs_sbaccess32 (dm_word)) ? $format ("_32") : $format ("x"))
|
|
+ ((fn_sbcs_sbaccess16 (dm_word)) ? $format ("_16") : $format ("x"))
|
|
+ ((fn_sbcs_sbaccess8 (dm_word)) ? $format ("_8") : $format ("x"))
|
|
+ $format ("}"));
|
|
endfunction
|
|
|
|
// ================================================================
|
|
// DCSR 'cause' field values
|
|
|
|
typedef enum {DCSR_CAUSE_RESERVED0,
|
|
DCSR_CAUSE_EBREAK,
|
|
DCSR_CAUSE_TRIGGER,
|
|
DCSR_CAUSE_HALTREQ,
|
|
DCSR_CAUSE_STEP,
|
|
DCSR_CAUSE_RESERVED5,
|
|
DCSR_CAUSE_RESERVED6,
|
|
DCSR_CAUSE_RESERVED7
|
|
} DCSR_Cause
|
|
deriving (Bits, Eq, FShow);
|
|
|
|
// ================================================================
|
|
// Sub-interface of the Debug Module facing the remote debugger (e.g. GDB)
|
|
|
|
interface DMI;
|
|
method Action read_addr (DM_Addr dm_addr);
|
|
method ActionValue #(DM_Word) read_data;
|
|
method Action write (DM_Addr dm_addr, DM_Word dm_word);
|
|
endinterface
|
|
|
|
// A dummy interface to tie off DMI if it is not used.
|
|
|
|
DMI dummy_DMI_ifc = interface DMI;
|
|
method Action read_addr (DM_Addr dm_addr) = noAction;
|
|
method ActionValue #(DM_Word) read_data = actionvalue
|
|
return 0;
|
|
endactionvalue;
|
|
method Action write (DM_Addr dm_addr, DM_Word dm_word) = noAction;
|
|
endinterface;
|
|
|
|
// ================================================================
|
|
|
|
endpackage
|