Update pulp_riscv_dbg to pulp-platform/riscv-dbg@6bef5d8

Update code from upstream repository https://github.com/pulp-
platform/riscv-dbg to revision
6bef5d80f3559d54cfd0cecd1fa40edb564daa93

* [ling/cleanup] Fix several verilator lint warnings due to sizing
  (Michael Schaffner)
* [lint/cleanup] Break long lines and make literal lengths explicit
  (Michael Schaffner)
* [lint/cleanup] Fix several lint errors / warnings (Michael
  Schaffner)
* [lint/cleanup] Simplify some statements (Michael Schaffner)
* [lint/cleanup] Make params unsingend, correct defaults and uniquify
  (Michael Schaffner)
* [lint/cleanup] Name blocks, align blocking structure (Michael
  Schaffner)
* [lint/cleanup] Change indentation from 4 to 2 spaces per tab
  (Michael Schaffner)
* [lint/cleanup] Fix lint warning in debug_rom, fix indentation
  (Michael Schaffner)

Signed-off-by: Michael Schaffner <msf@opentitan.org>
diff --git a/hw/vendor/patches/pulp_riscv_dbg/0010-ROM-Restore-s0-and-a0-on-debug-exception-entry.patch b/hw/vendor/patches/pulp_riscv_dbg/0001-ROM-Restore-s0-and-a0-on-debug-exception-entry.patch
similarity index 95%
rename from hw/vendor/patches/pulp_riscv_dbg/0010-ROM-Restore-s0-and-a0-on-debug-exception-entry.patch
rename to hw/vendor/patches/pulp_riscv_dbg/0001-ROM-Restore-s0-and-a0-on-debug-exception-entry.patch
index 2a95750..7eae665 100644
--- a/hw/vendor/patches/pulp_riscv_dbg/0010-ROM-Restore-s0-and-a0-on-debug-exception-entry.patch
+++ b/hw/vendor/patches/pulp_riscv_dbg/0001-ROM-Restore-s0-and-a0-on-debug-exception-entry.patch
@@ -1,7 +1,7 @@
-From 79c63578476555dcbd5a700c2166664407676406 Mon Sep 17 00:00:00 2001
+From 4897a1bc9d9e0ac06072d6025b6cdca40332c5a7 Mon Sep 17 00:00:00 2001
 From: Tom Roberts <tomroberts@lowrisc.org>
 Date: Wed, 27 Nov 2019 13:13:34 +0000
-Subject: [PATCH 10/11] [ROM] Restore s0 and a0 on debug exception entry
+Subject: [PATCH 1/4] [ROM] Restore s0 and a0 on debug exception entry
 
 As noted in lowRISC/opentitan#1035 an exception occuring during program
 buffer execution can corrupt the values of core registers (since they might
@@ -98,5 +98,5 @@
      end
    end
 -- 
-2.17.1
+2.24.1.735.g03f4e72817-goog
 
diff --git a/hw/vendor/patches/pulp_riscv_dbg/0001-lint-cleanup-Fix-lint-warning-in-debug_rom-fix-inden.patch b/hw/vendor/patches/pulp_riscv_dbg/0001-lint-cleanup-Fix-lint-warning-in-debug_rom-fix-inden.patch
deleted file mode 100644
index a171fdc..0000000
--- a/hw/vendor/patches/pulp_riscv_dbg/0001-lint-cleanup-Fix-lint-warning-in-debug_rom-fix-inden.patch
+++ /dev/null
@@ -1,168 +0,0 @@
-From dc97d912f2ef11e88dec383be65ea07f36a6514c Mon Sep 17 00:00:00 2001
-From: Michael Schaffner <msf@google.com>
-Date: Thu, 17 Oct 2019 19:01:49 -0700
-Subject: [PATCH 01/11] [lint/cleanup] Fix lint warning in debug_rom, fix
- indentation
-
----
- debug_rom/debug_rom.sv | 75 +++++++++++++++++++++++-------------------
- debug_rom/gen_rom.py   | 39 +++++++++++++---------
- 2 files changed, 64 insertions(+), 50 deletions(-)
-
-diff --git a/debug_rom/debug_rom.sv b/debug_rom/debug_rom.sv
-index 1c6727c..d8e8913 100644
---- a/debug_rom/debug_rom.sv
-+++ b/debug_rom/debug_rom.sv
-@@ -15,44 +15,51 @@
- 
- // Auto-generated code
- module debug_rom (
--   input  logic         clk_i,
--   input  logic         req_i,
--   input  logic [63:0]  addr_i,
--   output logic [63:0]  rdata_o
-+  input  logic         clk_i,
-+  input  logic         req_i,
-+  input  logic [63:0]  addr_i,
-+  output logic [63:0]  rdata_o
- );
--    localparam int RomSize = 19;
- 
--    const logic [RomSize-1:0][63:0] mem = {
--        64'h00000000_7b200073,
--        64'h7b302573_7b202473,
--        64'h10852423_f1402473,
--        64'ha85ff06f_7b302573,
--        64'h7b202473_10052223,
--        64'h00100073_7b302573,
--        64'h10052623_00c51513,
--        64'h00c55513_00000517,
--        64'h7b351073_fd5ff06f,
--        64'hfa041ce3_00247413,
--        64'h40044403_00a40433,
--        64'hf1402473_02041c63,
--        64'h00147413_40044403,
--        64'h00a40433_10852023,
--        64'hf1402473_00c51513,
--        64'h00c55513_00000517,
--        64'h7b351073_7b241073,
--        64'h0ff0000f_04c0006f,
--        64'h07c0006f_00c0006f
--    };
-+  localparam int RomSize = 19;
- 
--    logic [$clog2(RomSize)-1:0] addr_q;
-+  const logic [RomSize-1:0][63:0] mem = {
-+    64'h00000000_7b200073,
-+    64'h7b302573_7b202473,
-+    64'h10852423_f1402473,
-+    64'ha85ff06f_7b302573,
-+    64'h7b202473_10052223,
-+    64'h00100073_7b302573,
-+    64'h10052623_00c51513,
-+    64'h00c55513_00000517,
-+    64'h7b351073_fd5ff06f,
-+    64'hfa041ce3_00247413,
-+    64'h40044403_00a40433,
-+    64'hf1402473_02041c63,
-+    64'h00147413_40044403,
-+    64'h00a40433_10852023,
-+    64'hf1402473_00c51513,
-+    64'h00c55513_00000517,
-+    64'h7b351073_7b241073,
-+    64'h0ff0000f_04c0006f,
-+    64'h07c0006f_00c0006f
-+  };
- 
--    always_ff @(posedge clk_i) begin
--        if (req_i) begin
--            addr_q <= addr_i[$clog2(RomSize)-1+3:3];
--        end
-+  logic [$clog2(RomSize)-1:0] addr_q;
-+
-+  always_ff @(posedge clk_i) begin
-+    if (req_i) begin
-+      addr_q <= addr_i[$clog2(RomSize)-1+3:3];
-+    end
-+  end
-+
-+  // this prevents spurious Xes from propagating into
-+  // the speculative fetch stage of the core
-+  always_comb begin : p_outmux
-+    rdata_o = '0;
-+    if (addr_q < RomSize) begin
-+        rdata_o = mem[addr_q];
-     end
-+  end
- 
--    // this prevents spurious Xes from propagating into
--    // the speculative fetch stage of the core
--    assign rdata_o = (addr_q < RomSize) ? mem[addr_q] : '0;
- endmodule
-diff --git a/debug_rom/gen_rom.py b/debug_rom/gen_rom.py
-index bb2abc3..e701c52 100755
---- a/debug_rom/gen_rom.py
-+++ b/debug_rom/gen_rom.py
-@@ -42,28 +42,35 @@ license = """\
- 
- module = """\
- module $filename (
--   input  logic         clk_i,
--   input  logic         req_i,
--   input  logic [63:0]  addr_i,
--   output logic [63:0]  rdata_o
-+  input  logic         clk_i,
-+  input  logic         req_i,
-+  input  logic [63:0]  addr_i,
-+  output logic [63:0]  rdata_o
- );
--    localparam int RomSize = $size;
- 
--    const logic [RomSize-1:0][63:0] mem = {
-+  localparam int RomSize = $size;
-+
-+  const logic [RomSize-1:0][63:0] mem = {
- $content
--    };
-+  };
- 
--    logic [$$clog2(RomSize)-1:0] addr_q;
-+  logic [$$clog2(RomSize)-1:0] addr_q;
- 
--    always_ff @(posedge clk_i) begin
--        if (req_i) begin
--            addr_q <= addr_i[$$clog2(RomSize)-1+3:3];
--        end
-+  always_ff @(posedge clk_i) begin
-+    if (req_i) begin
-+      addr_q <= addr_i[$$clog2(RomSize)-1+3:3];
-+    end
-+  end
-+
-+  // this prevents spurious Xes from propagating into
-+  // the speculative fetch stage of the core
-+  always_comb begin : p_outmux
-+    rdata_o = '0;
-+    if (addr_q < RomSize) begin
-+        rdata_o = mem[addr_q];
-     end
-+  end
- 
--    // this prevents spurious Xes from propagating into
--    // the speculative fetch stage of the core
--    assign rdata_o = (addr_q < RomSize) ? mem[addr_q] : '0;
- endmodule
- """
- 
-@@ -116,7 +123,7 @@ with open(filename + ".sv", "w") as f:
-     rom_str = ""
-     # process in junks of 64 bit (8 byte)
-     for i in reversed(range(int(len(rom)/8))):
--        rom_str += "        64'h" + "".join(rom[i*8+4:i*8+8][::-1]) + "_" + "".join(rom[i*8:i*8+4][::-1]) + ",\n"
-+        rom_str += "    64'h" + "".join(rom[i*8+4:i*8+8][::-1]) + "_" + "".join(rom[i*8:i*8+4][::-1]) + ",\n"
- 
-     # remove the trailing comma
-     rom_str = rom_str[:-2]
--- 
-2.17.1
-
diff --git a/hw/vendor/patches/pulp_riscv_dbg/0011-abstract-cs-Do-not-execute-invalid-abstract-cmd.patch b/hw/vendor/patches/pulp_riscv_dbg/0002-abstract-cs-Do-not-execute-invalid-abstract-cmd.patch
similarity index 82%
rename from hw/vendor/patches/pulp_riscv_dbg/0011-abstract-cs-Do-not-execute-invalid-abstract-cmd.patch
rename to hw/vendor/patches/pulp_riscv_dbg/0002-abstract-cs-Do-not-execute-invalid-abstract-cmd.patch
index 0bb564b..ca4af5f 100644
--- a/hw/vendor/patches/pulp_riscv_dbg/0011-abstract-cs-Do-not-execute-invalid-abstract-cmd.patch
+++ b/hw/vendor/patches/pulp_riscv_dbg/0002-abstract-cs-Do-not-execute-invalid-abstract-cmd.patch
@@ -1,7 +1,7 @@
-From 75f16162f8739c32d73ec2c38728532d6c494f80 Mon Sep 17 00:00:00 2001
+From d137a450dd02d3653e184e7ff1e3978ba2f56efe Mon Sep 17 00:00:00 2001
 From: Tom Roberts <tomroberts@lowrisc.org>
 Date: Wed, 27 Nov 2019 14:07:28 +0000
-Subject: [PATCH 11/11] [abstract cs] Do not execute invalid abstract cmd
+Subject: [PATCH 2/4] [abstract cs] Do not execute invalid abstract cmd
 
 If the command written is invalid, just set cmderr and do not attempt to
 execute it. This works around some timing issues in OpenOCD.
@@ -23,5 +23,5 @@
            state_d = Go;
          end else if (cmd_valid_i) begin
 -- 
-2.17.1
+2.24.1.735.g03f4e72817-goog
 
diff --git a/hw/vendor/patches/pulp_riscv_dbg/0002-lint-cleanup-Change-indentation-from-4-to-2-spaces-p.patch b/hw/vendor/patches/pulp_riscv_dbg/0002-lint-cleanup-Change-indentation-from-4-to-2-spaces-p.patch
deleted file mode 100644
index 006617c..0000000
--- a/hw/vendor/patches/pulp_riscv_dbg/0002-lint-cleanup-Change-indentation-from-4-to-2-spaces-p.patch
+++ /dev/null
@@ -1,4831 +0,0 @@
-From 2cbdb09aca95a2a8a30077826c5596e0f6843917 Mon Sep 17 00:00:00 2001
-From: Michael Schaffner <msf@google.com>
-Date: Thu, 17 Oct 2019 19:02:22 -0700
-Subject: [PATCH 02/11] [lint/cleanup] Change indentation from 4 to 2 spaces
- per tab
-
-This helps in reducing the amount of overly long lines, which cause lint warnings.
----
- src/dm_csrs.sv      | 1102 +++++++++++++++++++++----------------------
- src/dm_mem.sv       |  890 +++++++++++++++++-----------------
- src/dm_pkg.sv       |  730 ++++++++++++++--------------
- src/dm_sba.sv       |  321 +++++++------
- src/dm_top.sv       |  418 ++++++++--------
- src/dmi_cdc.sv      |   72 +--
- src/dmi_jtag.sv     |  480 +++++++++----------
- src/dmi_jtag_tap.sv |  613 ++++++++++++------------
- 8 files changed, 2309 insertions(+), 2317 deletions(-)
-
-diff --git a/src/dm_csrs.sv b/src/dm_csrs.sv
-index f23ea9d..808a95d 100644
---- a/src/dm_csrs.sv
-+++ b/src/dm_csrs.sv
-@@ -16,591 +16,587 @@
-  */
- 
- module dm_csrs #(
--    parameter int                 NrHarts          = 1,
--    parameter int                 BusWidth         = 32,
--    parameter logic [NrHarts-1:0] SelectableHarts  = 1
-+  parameter int                 NrHarts          = 1,
-+  parameter int                 BusWidth         = 32,
-+  parameter logic [NrHarts-1:0] SelectableHarts  = 1
- ) (
--    input  logic                              clk_i,           // Clock
--    input  logic                              rst_ni,          // Asynchronous reset active low
--    input  logic                              testmode_i,
--    input  logic                              dmi_rst_ni,      // Debug Module Intf reset active-low
--    input  logic                              dmi_req_valid_i,
--    output logic                              dmi_req_ready_o,
--    input  dm::dmi_req_t                      dmi_req_i,
--    // every request needs a response one cycle later
--    output logic                              dmi_resp_valid_o,
--    input  logic                              dmi_resp_ready_i,
--    output dm::dmi_resp_t                     dmi_resp_o,
--    // global ctrl
--    output logic                              ndmreset_o,      // non-debug module reset active-high
--    output logic                              dmactive_o,      // 1 -> debug-module is active,
--                                                               // 0 -> synchronous re-set
--    // hart status
--    input  dm::hartinfo_t [NrHarts-1:0]       hartinfo_i,      // static hartinfo
--    input  logic [NrHarts-1:0]                halted_i,        // hart is halted
--    input  logic [NrHarts-1:0]                unavailable_i,   // e.g.: powered down
--    input  logic [NrHarts-1:0]                resumeack_i,     // hart acknowledged resume request
--    // hart control
--    output logic [19:0]                       hartsel_o,       // hartselect to ctrl module
--    output logic [NrHarts-1:0]                haltreq_o,       // request to halt a hart
--    output logic [NrHarts-1:0]                resumereq_o,     // request hart to resume
--    output logic                              clear_resumeack_o,
--
--    output logic                              cmd_valid_o,       // debugger writing to cmd field
--    output dm::command_t                      cmd_o,             // abstract command
--    input  logic                              cmderror_valid_i,  // an error occured
--    input  dm::cmderr_e                       cmderror_i,        // this error occured
--    input  logic                              cmdbusy_i,         // cmd is currently busy executing
--
--    output logic [dm::ProgBufSize-1:0][31:0]  progbuf_o, // to system bus
--    output logic [dm::DataCount-1:0][31:0]    data_o,
--
--    input  logic [dm::DataCount-1:0][31:0]    data_i,
--    input  logic                              data_valid_i,
--    // system bus access module (SBA)
--    output logic [BusWidth-1:0]               sbaddress_o,
--    input  logic [BusWidth-1:0]               sbaddress_i,
--    output logic                              sbaddress_write_valid_o,
--    // control signals in
--    output logic                              sbreadonaddr_o,
--    output logic                              sbautoincrement_o,
--    output logic [2:0]                        sbaccess_o,
--    // data out
--    output logic                              sbreadondata_o,
--    output logic [BusWidth-1:0]               sbdata_o,
--    output logic                              sbdata_read_valid_o,
--    output logic                              sbdata_write_valid_o,
--    // read data in
--    input  logic [BusWidth-1:0]               sbdata_i,
--    input  logic                              sbdata_valid_i,
--    // control signals
--    input  logic                              sbbusy_i,
--    input  logic                              sberror_valid_i, // bus error occurred
--    input  logic [2:0]                        sberror_i // bus error occurred
-+  input  logic                              clk_i,           // Clock
-+  input  logic                              rst_ni,          // Asynchronous reset active low
-+  input  logic                              testmode_i,
-+  input  logic                              dmi_rst_ni,      // Debug Module Intf reset active-low
-+  input  logic                              dmi_req_valid_i,
-+  output logic                              dmi_req_ready_o,
-+  input  dm::dmi_req_t                      dmi_req_i,
-+  // every request needs a response one cycle later
-+  output logic                              dmi_resp_valid_o,
-+  input  logic                              dmi_resp_ready_i,
-+  output dm::dmi_resp_t                     dmi_resp_o,
-+  // global ctrl
-+  output logic                              ndmreset_o,      // non-debug module reset active-high
-+  output logic                              dmactive_o,      // 1 -> debug-module is active,
-+                                                             // 0 -> synchronous re-set
-+  // hart status
-+  input  dm::hartinfo_t [NrHarts-1:0]       hartinfo_i,      // static hartinfo
-+  input  logic [NrHarts-1:0]                halted_i,        // hart is halted
-+  input  logic [NrHarts-1:0]                unavailable_i,   // e.g.: powered down
-+  input  logic [NrHarts-1:0]                resumeack_i,     // hart acknowledged resume request
-+  // hart control
-+  output logic [19:0]                       hartsel_o,       // hartselect to ctrl module
-+  output logic [NrHarts-1:0]                haltreq_o,       // request to halt a hart
-+  output logic [NrHarts-1:0]                resumereq_o,     // request hart to resume
-+  output logic                              clear_resumeack_o,
-+
-+  output logic                              cmd_valid_o,       // debugger writing to cmd field
-+  output dm::command_t                      cmd_o,             // abstract command
-+  input  logic                              cmderror_valid_i,  // an error occured
-+  input  dm::cmderr_e                       cmderror_i,        // this error occured
-+  input  logic                              cmdbusy_i,         // cmd is currently busy executing
-+
-+  output logic [dm::ProgBufSize-1:0][31:0]  progbuf_o, // to system bus
-+  output logic [dm::DataCount-1:0][31:0]    data_o,
-+
-+  input  logic [dm::DataCount-1:0][31:0]    data_i,
-+  input  logic                              data_valid_i,
-+  // system bus access module (SBA)
-+  output logic [BusWidth-1:0]               sbaddress_o,
-+  input  logic [BusWidth-1:0]               sbaddress_i,
-+  output logic                              sbaddress_write_valid_o,
-+  // control signals in
-+  output logic                              sbreadonaddr_o,
-+  output logic                              sbautoincrement_o,
-+  output logic [2:0]                        sbaccess_o,
-+  // data out
-+  output logic                              sbreadondata_o,
-+  output logic [BusWidth-1:0]               sbdata_o,
-+  output logic                              sbdata_read_valid_o,
-+  output logic                              sbdata_write_valid_o,
-+  // read data in
-+  input  logic [BusWidth-1:0]               sbdata_i,
-+  input  logic                              sbdata_valid_i,
-+  // control signals
-+  input  logic                              sbbusy_i,
-+  input  logic                              sberror_valid_i, // bus error occurred
-+  input  logic [2:0]                        sberror_i // bus error occurred
- );
--    // the amount of bits we need to represent all harts
--    localparam HartSelLen = (NrHarts == 1) ? 1 : $clog2(NrHarts);
--    dm::dtm_op_e dtm_op;
--    assign dtm_op = dm::dtm_op_e'(dmi_req_i.op);
--
--    logic        resp_queue_full;
--    logic        resp_queue_empty;
--    logic        resp_queue_push;
--    logic        resp_queue_pop;
--    logic [31:0] resp_queue_data;
--
--    localparam dm::dm_csr_e DataEnd = dm::dm_csr_e'((dm::Data0 + {4'b0, dm::DataCount}));
--    localparam dm::dm_csr_e ProgBufEnd = dm::dm_csr_e'((dm::ProgBuf0 + {4'b0, dm::ProgBufSize}));
--
--    logic [31:0] haltsum0, haltsum1, haltsum2, haltsum3;
--    logic [((NrHarts-1)/2**5 + 1) * 32 - 1 : 0] halted;
--    logic [(NrHarts-1)/2**5:0][31:0] halted_reshaped0;
--    logic [NrHarts/2**10:0][31:0] halted_reshaped1;
--    logic [NrHarts/2**15:0][31:0] halted_reshaped2;
--    logic [(NrHarts/2**10+1)*32-1:0] halted_flat1;
--    logic [(NrHarts/2**15+1)*32-1:0] halted_flat2;
--    logic [32-1:0] halted_flat3;
--
--    // haltsum0
--    always_comb begin
--        halted              = '0;
--        halted[NrHarts-1:0] = halted_i;
--        halted_reshaped0    = halted;
--        haltsum0            = halted_reshaped0[hartsel_o[19:5]];
-+  // the amount of bits we need to represent all harts
-+  localparam HartSelLen = (NrHarts == 1) ? 1 : $clog2(NrHarts);
-+  dm::dtm_op_e dtm_op;
-+  assign dtm_op = dm::dtm_op_e'(dmi_req_i.op);
-+
-+  logic        resp_queue_full;
-+  logic        resp_queue_empty;
-+  logic        resp_queue_push;
-+  logic        resp_queue_pop;
-+  logic [31:0] resp_queue_data;
-+
-+  localparam dm::dm_csr_e DataEnd = dm::dm_csr_e'((dm::Data0 + {4'b0, dm::DataCount}));
-+  localparam dm::dm_csr_e ProgBufEnd = dm::dm_csr_e'((dm::ProgBuf0 + {4'b0, dm::ProgBufSize}));
-+
-+  logic [31:0] haltsum0, haltsum1, haltsum2, haltsum3;
-+  logic [((NrHarts-1)/2**5 + 1) * 32 - 1 : 0] halted;
-+  logic [(NrHarts-1)/2**5:0][31:0] halted_reshaped0;
-+  logic [NrHarts/2**10:0][31:0] halted_reshaped1;
-+  logic [NrHarts/2**15:0][31:0] halted_reshaped2;
-+  logic [(NrHarts/2**10+1)*32-1:0] halted_flat1;
-+  logic [(NrHarts/2**15+1)*32-1:0] halted_flat2;
-+  logic [32-1:0] halted_flat3;
-+
-+  // haltsum0
-+  always_comb begin
-+    halted              = '0;
-+    halted[NrHarts-1:0] = halted_i;
-+    halted_reshaped0    = halted;
-+    haltsum0            = halted_reshaped0[hartsel_o[19:5]];
-+  end
-+
-+  // haltsum1
-+  always_comb begin : p_reduction1
-+    halted_flat1 = '0;
-+    for (int k=0; k<NrHarts/2**5+1; k++) begin
-+      halted_flat1[k] = |halted_reshaped0[k];
-     end
--    
--    // haltsum1
--    always_comb begin : p_reduction1
--        halted_flat1 = '0;
--        for (int k=0; k<NrHarts/2**5+1; k++) begin
--            halted_flat1[k] = |halted_reshaped0[k];
--        end
--        halted_reshaped1 = halted_flat1;
--        haltsum1         = halted_reshaped1[hartsel_o[19:10]];
-+    halted_reshaped1 = halted_flat1;
-+    haltsum1         = halted_reshaped1[hartsel_o[19:10]];
-+  end
-+  // haltsum2
-+  always_comb begin : p_reduction2
-+    halted_flat2 = '0;
-+    for (int k=0; k<NrHarts/2**10+1; k++) begin
-+      halted_flat2[k] = |halted_reshaped1[k];
-     end
--    // haltsum2
--    always_comb begin : p_reduction2
--        halted_flat2 = '0;
--        for (int k=0; k<NrHarts/2**10+1; k++) begin
--            halted_flat2[k] = |halted_reshaped1[k];
--        end
--        halted_reshaped2 = halted_flat2;
--        haltsum2         = halted_reshaped2[hartsel_o[19:15]];
-+    halted_reshaped2 = halted_flat2;
-+    haltsum2         = halted_reshaped2[hartsel_o[19:15]];
-+  end
-+  // haltsum3
-+  always_comb begin : p_reduction3
-+    halted_flat3 = '0;
-+    for (int k=0; k<NrHarts/2**15+1; k++) begin
-+      halted_flat3[k] = |halted_reshaped2[k];
-     end
--    // haltsum3
--    always_comb begin : p_reduction3
--        halted_flat3 = '0;
--        for (int k=0; k<NrHarts/2**15+1; k++) begin
--            halted_flat3[k] = |halted_reshaped2[k];
-+    haltsum3 = halted_flat3;
-+  end
-+
-+
-+  dm::dmstatus_t      dmstatus;
-+  dm::dmcontrol_t     dmcontrol_d, dmcontrol_q;
-+  dm::abstractcs_t    abstractcs;
-+  dm::cmderr_e        cmderr_d, cmderr_q;
-+  dm::command_t       command_d, command_q;
-+  logic               cmd_valid_d, cmd_valid_q;
-+  dm::abstractauto_t  abstractauto_d, abstractauto_q;
-+  dm::sbcs_t          sbcs_d, sbcs_q;
-+  logic [63:0]        sbaddr_d, sbaddr_q;
-+  logic [63:0]        sbdata_d, sbdata_q;
-+
-+  logic [NrHarts-1:0] havereset_d, havereset_q;
-+  // program buffer
-+  logic [dm::ProgBufSize-1:0][31:0] progbuf_d, progbuf_q;
-+  // because first data address starts at 0x04
-+  logic [({3'b0, dm::DataCount} + dm::Data0 - 1):(dm::Data0)][31:0] data_d, data_q;
-+
-+  logic [HartSelLen-1:0] selected_hart;
-+
-+  // a successful response returns zero
-+  assign dmi_resp_o.resp = dm::DTM_SUCCESS;
-+  assign dmi_resp_valid_o     = ~resp_queue_empty;
-+  assign dmi_req_ready_o      = ~resp_queue_full;
-+  assign resp_queue_push      = dmi_req_valid_i & dmi_req_ready_o;
-+  // SBA
-+  assign sbautoincrement_o = sbcs_q.sbautoincrement;
-+  assign sbreadonaddr_o    = sbcs_q.sbreadonaddr;
-+  assign sbreadondata_o    = sbcs_q.sbreadondata;
-+  assign sbaccess_o        = sbcs_q.sbaccess;
-+  assign sbdata_o          = sbdata_q[BusWidth-1:0];
-+  assign sbaddress_o       = sbaddr_q[BusWidth-1:0];
-+
-+  assign hartsel_o         = {dmcontrol_q.hartselhi, dmcontrol_q.hartsello};
-+
-+  always_comb begin : csr_read_write
-+    // --------------------
-+    // Static Values (R/O)
-+    // --------------------
-+    // dmstatus
-+    dmstatus    = '0;
-+    dmstatus.version = dm::DbgVersion013;
-+    // no authentication implemented
-+    dmstatus.authenticated = 1'b1;
-+    // we do not support halt-on-reset sequence
-+    dmstatus.hasresethaltreq = 1'b0;
-+    // TODO(zarubaf) things need to change here if we implement the array mask
-+    dmstatus.allhavereset = havereset_q[selected_hart];
-+    dmstatus.anyhavereset = havereset_q[selected_hart];
-+
-+    dmstatus.allresumeack = resumeack_i[selected_hart];
-+    dmstatus.anyresumeack = resumeack_i[selected_hart];
-+
-+    dmstatus.allunavail   = unavailable_i[selected_hart];
-+    dmstatus.anyunavail   = unavailable_i[selected_hart];
-+
-+    // as soon as we are out of the legal Hart region tell the debugger
-+    // that there are only non-existent harts
-+    dmstatus.allnonexistent = (hartsel_o > (NrHarts - 1)) ? 1'b1 : 1'b0;
-+    dmstatus.anynonexistent = (hartsel_o > (NrHarts - 1)) ? 1'b1 : 1'b0;
-+
-+    // We are not allowed to be in multiple states at once. This is a to
-+    // make the running/halted and unavailable states exclusive.
-+    dmstatus.allhalted    = halted_i[selected_hart] & ~unavailable_i[selected_hart];
-+    dmstatus.anyhalted    = halted_i[selected_hart] & ~unavailable_i[selected_hart];
-+
-+    dmstatus.allrunning   = ~halted_i[selected_hart] & ~unavailable_i[selected_hart];
-+    dmstatus.anyrunning   = ~halted_i[selected_hart] & ~unavailable_i[selected_hart];
-+
-+    // abstractcs
-+    abstractcs = '0;
-+    abstractcs.datacount = dm::DataCount;
-+    abstractcs.progbufsize = dm::ProgBufSize;
-+    abstractcs.busy = cmdbusy_i;
-+    abstractcs.cmderr = cmderr_q;
-+
-+    // abstractautoexec
-+    abstractauto_d = abstractauto_q;
-+    abstractauto_d.zero0 = '0;
-+
-+    // default assignments
-+    havereset_d = havereset_q;
-+    dmcontrol_d = dmcontrol_q;
-+    cmderr_d    = cmderr_q;
-+    command_d   = command_q;
-+    progbuf_d   = progbuf_q;
-+    data_d      = data_q;
-+    sbcs_d      = sbcs_q;
-+    sbaddr_d    = sbaddress_i;
-+    sbdata_d    = sbdata_q;
-+
-+    resp_queue_data         = 32'b0;
-+    cmd_valid_d             = 1'b0;
-+    sbaddress_write_valid_o = 1'b0;
-+    sbdata_read_valid_o     = 1'b0;
-+    sbdata_write_valid_o    = 1'b0;
-+    clear_resumeack_o       = 1'b0;
-+
-+    // reads
-+    if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_READ) begin
-+      unique case ({1'b0, dmi_req_i.addr}) inside
-+        [(dm::Data0):DataEnd]: begin
-+          if (dm::DataCount > 0) begin
-+            resp_queue_data = data_q[dmi_req_i.addr[4:0]];
-+          end
-+          if (!cmdbusy_i) begin
-+            // check whether we need to re-execute the command (just give a cmd_valid)
-+            cmd_valid_d = abstractauto_q.autoexecdata[dmi_req_i.addr[3:0] -
-+                          int'(dm::Data0)];
-+          end
-+        end
-+        dm::DMControl:    resp_queue_data = dmcontrol_q;
-+        dm::DMStatus:     resp_queue_data = dmstatus;
-+        dm::Hartinfo:     resp_queue_data = hartinfo_i[selected_hart];
-+        dm::AbstractCS:   resp_queue_data = abstractcs;
-+        dm::AbstractAuto: resp_queue_data = abstractauto_q;
-+        // command is read-only
-+        dm::Command:    resp_queue_data = '0;
-+        [(dm::ProgBuf0):ProgBufEnd]: begin
-+          resp_queue_data = progbuf_q[dmi_req_i.addr[4:0]];
-+          if (!cmdbusy_i) begin
-+            // check whether we need to re-execute the command (just give a cmd_valid)
-+            // TODO(zarubaf): check if offset is correct: without it this may assign Xes
-+            cmd_valid_d = abstractauto_q.autoexecprogbuf[dmi_req_i.addr[3:0]+16];
-+          end
-+        end
-+        dm::HaltSum0: resp_queue_data = haltsum0;
-+        dm::HaltSum1: resp_queue_data = haltsum1;
-+        dm::HaltSum2: resp_queue_data = haltsum2;
-+        dm::HaltSum3: resp_queue_data = haltsum3;
-+        dm::SBCS: begin
-+          resp_queue_data = sbcs_q;
-+        end
-+        dm::SBAddress0: begin
-+          // access while the SBA was busy
-+          if (sbbusy_i) begin
-+            sbcs_d.sbbusyerror = 1'b1;
-+          end else begin
-+            resp_queue_data = sbaddr_q[31:0];
-+          end
-+        end
-+        dm::SBAddress1: begin
-+          // access while the SBA was busy
-+          if (sbbusy_i) begin
-+            sbcs_d.sbbusyerror = 1'b1;
-+          end else begin
-+            resp_queue_data = sbaddr_q[63:32];
-+          end
-+      end
-+        dm::SBData0: begin
-+          // access while the SBA was busy
-+          if (sbbusy_i) begin
-+           sbcs_d.sbbusyerror = 1'b1;
-+          end else begin
-+            sbdata_read_valid_o = (sbcs_q.sberror == '0);
-+            resp_queue_data = sbdata_q[31:0];
-+          end
-+        end
-+        dm::SBData1: begin
-+          // access while the SBA was busy
-+          if (sbbusy_i) begin
-+            sbcs_d.sbbusyerror = 1'b1;
-+          end else begin
-+            resp_queue_data = sbdata_q[63:32];
-+          end
-         end
--        haltsum3 = halted_flat3;
-+        default:;
-+      endcase
-     end
- 
--
--    dm::dmstatus_t      dmstatus;
--    dm::dmcontrol_t     dmcontrol_d, dmcontrol_q;
--    dm::abstractcs_t    abstractcs;
--    dm::cmderr_e        cmderr_d, cmderr_q;
--    dm::command_t       command_d, command_q;
--    logic               cmd_valid_d, cmd_valid_q;
--    dm::abstractauto_t  abstractauto_d, abstractauto_q;
--    dm::sbcs_t          sbcs_d, sbcs_q;
--    logic [63:0]        sbaddr_d, sbaddr_q;
--    logic [63:0]        sbdata_d, sbdata_q;
--
--    logic [NrHarts-1:0] havereset_d, havereset_q;
--    // program buffer
--    logic [dm::ProgBufSize-1:0][31:0] progbuf_d, progbuf_q;
--    // because first data address starts at 0x04
--    logic [({3'b0, dm::DataCount} + dm::Data0 - 1):(dm::Data0)][31:0] data_d, data_q;
--
--    logic [HartSelLen-1:0] selected_hart;
--
--    // a successful response returns zero
--    assign dmi_resp_o.resp = dm::DTM_SUCCESS;
--    assign dmi_resp_valid_o     = ~resp_queue_empty;
--    assign dmi_req_ready_o      = ~resp_queue_full;
--    assign resp_queue_push      = dmi_req_valid_i & dmi_req_ready_o;
--    // SBA
--    assign sbautoincrement_o = sbcs_q.sbautoincrement;
--    assign sbreadonaddr_o    = sbcs_q.sbreadonaddr;
--    assign sbreadondata_o    = sbcs_q.sbreadondata;
--    assign sbaccess_o        = sbcs_q.sbaccess;
--    assign sbdata_o          = sbdata_q[BusWidth-1:0];
--    assign sbaddress_o       = sbaddr_q[BusWidth-1:0];
--
--    assign hartsel_o         = {dmcontrol_q.hartselhi, dmcontrol_q.hartsello};
--
--    always_comb begin : csr_read_write
--        // --------------------
--        // Static Values (R/O)
--        // --------------------
--        // dmstatus
--        dmstatus    = '0;
--        dmstatus.version = dm::DbgVersion013;
--        // no authentication implemented
--        dmstatus.authenticated = 1'b1;
--        // we do not support halt-on-reset sequence
--        dmstatus.hasresethaltreq = 1'b0;
--        // TODO(zarubaf) things need to change here if we implement the array mask
--        dmstatus.allhavereset = havereset_q[selected_hart];
--        dmstatus.anyhavereset = havereset_q[selected_hart];
--
--        dmstatus.allresumeack = resumeack_i[selected_hart];
--        dmstatus.anyresumeack = resumeack_i[selected_hart];
--
--        dmstatus.allunavail   = unavailable_i[selected_hart];
--        dmstatus.anyunavail   = unavailable_i[selected_hart];
--
--        // as soon as we are out of the legal Hart region tell the debugger
--        // that there are only non-existent harts
--        dmstatus.allnonexistent = (hartsel_o > (NrHarts - 1)) ? 1'b1 : 1'b0;
--        dmstatus.anynonexistent = (hartsel_o > (NrHarts - 1)) ? 1'b1 : 1'b0;
--
--        // We are not allowed to be in multiple states at once. This is a to
--        // make the running/halted and unavailable states exclusive.
--        dmstatus.allhalted    = halted_i[selected_hart] & ~unavailable_i[selected_hart];
--        dmstatus.anyhalted    = halted_i[selected_hart] & ~unavailable_i[selected_hart];
--
--        dmstatus.allrunning   = ~halted_i[selected_hart] & ~unavailable_i[selected_hart];
--        dmstatus.anyrunning   = ~halted_i[selected_hart] & ~unavailable_i[selected_hart];
--
--        // abstractcs
--        abstractcs = '0;
--        abstractcs.datacount = dm::DataCount;
--        abstractcs.progbufsize = dm::ProgBufSize;
--        abstractcs.busy = cmdbusy_i;
--        abstractcs.cmderr = cmderr_q;
--
--        // abstractautoexec
--        abstractauto_d = abstractauto_q;
--        abstractauto_d.zero0 = '0;
--
--        // default assignments
--        havereset_d = havereset_q;
--        dmcontrol_d = dmcontrol_q;
--        cmderr_d    = cmderr_q;
--        command_d   = command_q;
--        progbuf_d   = progbuf_q;
--        data_d      = data_q;
--        sbcs_d      = sbcs_q;
--        sbaddr_d    = sbaddress_i;
--        sbdata_d    = sbdata_q;
--
--        resp_queue_data         = 32'b0;
--        cmd_valid_d             = 1'b0;
--        sbaddress_write_valid_o = 1'b0;
--        sbdata_read_valid_o     = 1'b0;
--        sbdata_write_valid_o    = 1'b0;
--        clear_resumeack_o       = 1'b0;
--
--        // reads
--        if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_READ) begin
--            unique case ({1'b0, dmi_req_i.addr}) inside
--                [(dm::Data0):DataEnd]: begin
--                    if (dm::DataCount > 0) begin
--                        resp_queue_data = data_q[dmi_req_i.addr[4:0]];
--                    end
--                    if (!cmdbusy_i) begin
--                        // check whether we need to re-execute the command (just give a cmd_valid)
--                        cmd_valid_d = abstractauto_q.autoexecdata[dmi_req_i.addr[3:0] -
--                                      int'(dm::Data0)];
--                    end
--                end
--                dm::DMControl:    resp_queue_data = dmcontrol_q;
--                dm::DMStatus:     resp_queue_data = dmstatus;
--                dm::Hartinfo:     resp_queue_data = hartinfo_i[selected_hart];
--                dm::AbstractCS:   resp_queue_data = abstractcs;
--                dm::AbstractAuto: resp_queue_data = abstractauto_q;
--                // command is read-only
--                dm::Command:    resp_queue_data = '0;
--                [(dm::ProgBuf0):ProgBufEnd]: begin
--                    resp_queue_data = progbuf_q[dmi_req_i.addr[4:0]];
--                    if (!cmdbusy_i) begin
--                        // check whether we need to re-execute the command (just give a cmd_valid)
--                        // TODO(zarubaf): check if offset is correct: without it this may assign Xes
--                        cmd_valid_d = abstractauto_q.autoexecprogbuf[dmi_req_i.addr[3:0]+16];
--                    end
--                end
--                dm::HaltSum0: resp_queue_data = haltsum0;
--                dm::HaltSum1: resp_queue_data = haltsum1;
--                dm::HaltSum2: resp_queue_data = haltsum2;
--                dm::HaltSum3: resp_queue_data = haltsum3;
--                dm::SBCS: begin
--                    resp_queue_data = sbcs_q;
--                end
--                dm::SBAddress0: begin
--                    // access while the SBA was busy
--                    if (sbbusy_i) begin
--                       sbcs_d.sbbusyerror = 1'b1;
--                    end else begin
--                        resp_queue_data = sbaddr_q[31:0];
--                    end
--                end
--                dm::SBAddress1: begin
--                    // access while the SBA was busy
--                    if (sbbusy_i) begin
--                       sbcs_d.sbbusyerror = 1'b1;
--                    end else begin
--                        resp_queue_data = sbaddr_q[63:32];
--                    end
--                end
--                dm::SBData0: begin
--                    // access while the SBA was busy
--                    if (sbbusy_i) begin
--                       sbcs_d.sbbusyerror = 1'b1;
--                    end else begin
--                        sbdata_read_valid_o = (sbcs_q.sberror == '0);
--                        resp_queue_data = sbdata_q[31:0];
--                    end
--                end
--                dm::SBData1: begin
--                    // access while the SBA was busy
--                    if (sbbusy_i) begin
--                       sbcs_d.sbbusyerror = 1'b1;
--                    end else begin
--                        resp_queue_data = sbdata_q[63:32];
--                    end
--                end
--                default:;
--            endcase
-+    // write
-+    if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_WRITE) begin
-+      unique case (dm::dm_csr_e'({1'b0, dmi_req_i.addr})) inside
-+        [(dm::Data0):DataEnd]: begin
-+          // attempts to write them while busy is set does not change their value
-+          if (!cmdbusy_i && dm::DataCount > 0) begin
-+              data_d[dmi_req_i.addr[4:0]] = dmi_req_i.data;
-+              // check whether we need to re-execute the command (just give a cmd_valid)
-+              cmd_valid_d = abstractauto_q.autoexecdata[dmi_req_i.addr[3:0] -
-+                            int'(dm::Data0)];
-+          end
-         end
--
--        // write
--        if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_WRITE) begin
--            unique case (dm::dm_csr_e'({1'b0, dmi_req_i.addr})) inside
--                [(dm::Data0):DataEnd]: begin
--                    // attempts to write them while busy is set does not change their value
--                    if (!cmdbusy_i && dm::DataCount > 0) begin
--                        data_d[dmi_req_i.addr[4:0]] = dmi_req_i.data;
--                        // check whether we need to re-execute the command (just give a cmd_valid)
--                        cmd_valid_d = abstractauto_q.autoexecdata[dmi_req_i.addr[3:0] -
--                                      int'(dm::Data0)];
--                    end
--                end
--                dm::DMControl: begin
--                    automatic dm::dmcontrol_t dmcontrol;
--                    dmcontrol = dm::dmcontrol_t'(dmi_req_i.data);
--                    // clear the havreset of the selected hart
--                    if (dmcontrol.ackhavereset) begin
--                        havereset_d[selected_hart] = 1'b0;
--                    end
--                    dmcontrol_d = dmi_req_i.data;
--                end
--                dm::DMStatus:; // write are ignored to R/O register
--                dm::Hartinfo:; // hartinfo is R/O
--                // only command error is write-able
--                dm::AbstractCS: begin // W1C
--                    // Gets set if an abstract command fails. The bits in this
--                    // field remain set until they are cleared by writing 1 to
--                    // them. No abstract command is started until the value is
--                    // reset to 0.
--                    automatic dm::abstractcs_t a_abstractcs;
--                    a_abstractcs = dm::abstractcs_t'(dmi_req_i.data);
--                    // reads during abstract command execution are not allowed
--                    if (!cmdbusy_i) begin
--                        cmderr_d = dm::cmderr_e'(~a_abstractcs.cmderr & cmderr_q);
--                    end else if (cmderr_q == dm::CmdErrNone) begin
--                        cmderr_d = dm::CmdErrBusy;
--                    end
--
--                end
--                dm::Command: begin
--                    // writes are ignored if a command is already busy
--                    if (!cmdbusy_i) begin
--                        cmd_valid_d = 1'b1;
--                        command_d = dm::command_t'(dmi_req_i.data);
--                    // if there was an attempted to write during a busy execution
--                    // and the cmderror field is zero set the busy error
--                    end else if (cmderr_q == dm::CmdErrNone) begin
--                        cmderr_d = dm::CmdErrBusy;
--                    end
--                end
--                dm::AbstractAuto: begin
--                    // this field can only be written legally when there is no command executing
--                    if (!cmdbusy_i) begin
--                        abstractauto_d                 = 32'b0;
--                        abstractauto_d.autoexecdata    = 12'(dmi_req_i.data[dm::DataCount-1:0]);
--                        abstractauto_d.autoexecprogbuf = 16'(dmi_req_i.data[dm::ProgBufSize-1+16:16]);
--
--                    end else if (cmderr_q == dm::CmdErrNone) begin
--                        cmderr_d = dm::CmdErrBusy;
--                    end
--                end
--                [(dm::ProgBuf0):ProgBufEnd]: begin
--                    // attempts to write them while busy is set does not change their value
--                    if (!cmdbusy_i) begin
--                        progbuf_d[dmi_req_i.addr[4:0]] = dmi_req_i.data;
--                        // check whether we need to re-execute the command (just give a cmd_valid)
--                        // this should probably throw an error if executed during another command
--                        // was busy
--                        // TODO(zarubaf): check if offset is correct - without it this may
--                        // assign Xes
--                        cmd_valid_d = abstractauto_q.autoexecprogbuf[dmi_req_i.addr[3:0]+16];
--                    end
--                end
--                dm::SBCS: begin
--                    // access while the SBA was busy
--                    if (sbbusy_i) begin
--                        sbcs_d.sbbusyerror = 1'b1;
--                    end else begin
--                        automatic dm::sbcs_t sbcs;
--                        sbcs = dm::sbcs_t'(dmi_req_i.data);
--                        sbcs_d = sbcs;
--                        // R/W1C
--                        sbcs_d.sbbusyerror = sbcs_q.sbbusyerror & (~sbcs.sbbusyerror);
--                        sbcs_d.sberror     = sbcs_q.sberror     & (~sbcs.sberror);
--                    end
--                end
--                dm::SBAddress0: begin
--                    // access while the SBA was busy
--                    if (sbbusy_i) begin
--                       sbcs_d.sbbusyerror = 1'b1;
--                    end else begin
--                        sbaddr_d[31:0] = dmi_req_i.data;
--                        sbaddress_write_valid_o = (sbcs_q.sberror == '0);
--                    end
--                end
--                dm::SBAddress1: begin
--                    // access while the SBA was busy
--                    if (sbbusy_i) begin
--                       sbcs_d.sbbusyerror = 1'b1;
--                    end else begin
--                        sbaddr_d[63:32] = dmi_req_i.data;
--                    end
--                end
--                dm::SBData0: begin
--                    // access while the SBA was busy
--                    if (sbbusy_i) begin
--                       sbcs_d.sbbusyerror = 1'b1;
--                    end else begin
--                        sbdata_d[31:0] = dmi_req_i.data;
--                        sbdata_write_valid_o = (sbcs_q.sberror == '0);
--                    end
--                end
--                dm::SBData1: begin
--                    // access while the SBA was busy
--                    if (sbbusy_i) begin
--                       sbcs_d.sbbusyerror = 1'b1;
--                    end else begin
--                        sbdata_d[63:32] = dmi_req_i.data;
--                    end
--                end
--                default:;
--            endcase
-+        dm::DMControl: begin
-+          automatic dm::dmcontrol_t dmcontrol;
-+          dmcontrol = dm::dmcontrol_t'(dmi_req_i.data);
-+          // clear the havreset of the selected hart
-+          if (dmcontrol.ackhavereset) begin
-+              havereset_d[selected_hart] = 1'b0;
-+          end
-+          dmcontrol_d = dmi_req_i.data;
-         end
--        // hart threw a command error and has precedence over bus writes
--        if (cmderror_valid_i) begin
--            cmderr_d = cmderror_i;
-+        dm::DMStatus:; // write are ignored to R/O register
-+        dm::Hartinfo:; // hartinfo is R/O
-+        // only command error is write-able
-+        dm::AbstractCS: begin // W1C
-+          // Gets set if an abstract command fails. The bits in this
-+          // field remain set until they are cleared by writing 1 to
-+          // them. No abstract command is started until the value is
-+          // reset to 0.
-+          automatic dm::abstractcs_t a_abstractcs;
-+          a_abstractcs = dm::abstractcs_t'(dmi_req_i.data);
-+          // reads during abstract command execution are not allowed
-+          if (!cmdbusy_i) begin
-+            cmderr_d = dm::cmderr_e'(~a_abstractcs.cmderr & cmderr_q);
-+          end else if (cmderr_q == dm::CmdErrNone) begin
-+            cmderr_d = dm::CmdErrBusy;
-+          end
-         end
--
--        // update data registers
--        if (data_valid_i)
--            data_d = data_i;
--
--        // set the havereset flag when we did a ndmreset
--        if (ndmreset_o) begin
--            havereset_d = '1;
-+        dm::Command: begin
-+          // writes are ignored if a command is already busy
-+          if (!cmdbusy_i) begin
-+            cmd_valid_d = 1'b1;
-+            command_d = dm::command_t'(dmi_req_i.data);
-+          // if there was an attempted to write during a busy execution
-+          // and the cmderror field is zero set the busy error
-+          end else if (cmderr_q == dm::CmdErrNone) begin
-+            cmderr_d = dm::CmdErrBusy;
-+          end
-         end
--        // -------------
--        // System Bus
--        // -------------
--        // set bus error
--        if (sberror_valid_i) begin
--            sbcs_d.sberror = sberror_i;
-+        dm::AbstractAuto: begin
-+          // this field can only be written legally when there is no command executing
-+          if (!cmdbusy_i) begin
-+            abstractauto_d                 = 32'b0;
-+            abstractauto_d.autoexecdata    = 12'(dmi_req_i.data[dm::DataCount-1:0]);
-+            abstractauto_d.autoexecprogbuf = 16'(dmi_req_i.data[dm::ProgBufSize-1+16:16]);
-+          end else if (cmderr_q == dm::CmdErrNone) begin
-+            cmderr_d = dm::CmdErrBusy;
-+          end
-         end
--        // update read data
--        if (sbdata_valid_i) begin
--            sbdata_d = 64'(sbdata_i);
-+        [(dm::ProgBuf0):ProgBufEnd]: begin
-+          // attempts to write them while busy is set does not change their value
-+          if (!cmdbusy_i) begin
-+            progbuf_d[dmi_req_i.addr[4:0]] = dmi_req_i.data;
-+            // check whether we need to re-execute the command (just give a cmd_valid)
-+            // this should probably throw an error if executed during another command
-+            // was busy
-+            // TODO(zarubaf): check if offset is correct - without it this may
-+            // assign Xes
-+            cmd_valid_d = abstractauto_q.autoexecprogbuf[dmi_req_i.addr[3:0]+16];
-+          end
-         end
--
--        // dmcontrol
--        // TODO(zarubaf) we currently do not implement the hartarry mask
--        dmcontrol_d.hasel           = 1'b0;
--        // we do not support resetting an individual hart
--        dmcontrol_d.hartreset       = 1'b0;
--        dmcontrol_d.setresethaltreq = 1'b0;
--        dmcontrol_d.clrresethaltreq = 1'b0;
--        dmcontrol_d.zero1           = '0;
--        dmcontrol_d.zero0           = '0;
--        // Non-writeable, clear only
--        dmcontrol_d.ackhavereset    = 1'b0;
--        if (!dmcontrol_q.resumereq && dmcontrol_d.resumereq) begin
--            clear_resumeack_o = 1'b1;
-+        dm::SBCS: begin
-+          // access while the SBA was busy
-+          if (sbbusy_i) begin
-+            sbcs_d.sbbusyerror = 1'b1;
-+          end else begin
-+            automatic dm::sbcs_t sbcs;
-+            sbcs = dm::sbcs_t'(dmi_req_i.data);
-+            sbcs_d = sbcs;
-+            // R/W1C
-+            sbcs_d.sbbusyerror = sbcs_q.sbbusyerror & (~sbcs.sbbusyerror);
-+            sbcs_d.sberror     = sbcs_q.sberror     & (~sbcs.sberror);
-+          end
-+        end
-+        dm::SBAddress0: begin
-+          // access while the SBA was busy
-+          if (sbbusy_i) begin
-+            sbcs_d.sbbusyerror = 1'b1;
-+          end else begin
-+            sbaddr_d[31:0] = dmi_req_i.data;
-+            sbaddress_write_valid_o = (sbcs_q.sberror == '0);
-+          end
-+        end
-+        dm::SBAddress1: begin
-+          // access while the SBA was busy
-+          if (sbbusy_i) begin
-+            sbcs_d.sbbusyerror = 1'b1;
-+          end else begin
-+            sbaddr_d[63:32] = dmi_req_i.data;
-+          end
-         end
--        if (dmcontrol_q.resumereq && resumeack_i) begin
--            dmcontrol_d.resumereq = 1'b0;
-+        dm::SBData0: begin
-+          // access while the SBA was busy
-+          if (sbbusy_i) begin
-+            sbcs_d.sbbusyerror = 1'b1;
-+          end else begin
-+            sbdata_d[31:0] = dmi_req_i.data;
-+            sbdata_write_valid_o = (sbcs_q.sberror == '0);
-+          end
-         end
--        // static values for dcsr
--        sbcs_d.sbversion            = 3'b1;
--        sbcs_d.sbbusy               = sbbusy_i;
--        sbcs_d.sbasize              = BusWidth;
--        sbcs_d.sbaccess128          = 1'b0;
--        sbcs_d.sbaccess64           = BusWidth == 64;
--        sbcs_d.sbaccess32           = BusWidth == 32;
--        sbcs_d.sbaccess16           = 1'b0;
--        sbcs_d.sbaccess8            = 1'b0;
--        sbcs_d.sbaccess             = BusWidth == 64 ? 2'd3 : 2'd2;
-+        dm::SBData1: begin
-+          // access while the SBA was busy
-+          if (sbbusy_i) begin
-+           sbcs_d.sbbusyerror = 1'b1;
-+          end else begin
-+            sbdata_d[63:32] = dmi_req_i.data;
-+          end
-+        end
-+        default:;
-+      endcase
-     end
--
--    // output multiplexer
--    always_comb begin
--        selected_hart = hartsel_o[HartSelLen-1:0];
--        // default assignment
--        haltreq_o = '0;
--        resumereq_o = '0;
--        haltreq_o[selected_hart] = dmcontrol_q.haltreq;
--        resumereq_o[selected_hart] = dmcontrol_q.resumereq;
-+    // hart threw a command error and has precedence over bus writes
-+    if (cmderror_valid_i) begin
-+      cmderr_d = cmderror_i;
-     end
- 
--    assign dmactive_o  = dmcontrol_q.dmactive;
--    assign cmd_o       = command_q;
--    assign cmd_valid_o = cmd_valid_q;
--    assign progbuf_o   = progbuf_q;
--    assign data_o      = data_q;
--
--    assign resp_queue_pop = dmi_resp_ready_i & ~resp_queue_empty;
--
--    assign ndmreset_o = dmcontrol_q.ndmreset;
--
--    // response FIFO
--    fifo_v2 #(
--        .dtype            ( logic [31:0]         ),
--        .DEPTH            ( 2                    )
--    ) i_fifo (
--        .clk_i            ( clk_i                ),
--        .rst_ni           ( dmi_rst_ni           ), // reset only when system is re-set
--        .flush_i          ( 1'b0                 ), // we do not need to flush this queue
--        .testmode_i       ( testmode_i           ),
--        .full_o           ( resp_queue_full      ),
--        .empty_o          ( resp_queue_empty     ),
--        .alm_full_o       (                      ),
--        .alm_empty_o      (                      ),
--        .data_i           ( resp_queue_data      ),
--        .push_i           ( resp_queue_push      ),
--        .data_o           ( dmi_resp_o.data      ),
--        .pop_i            ( resp_queue_pop       )
--    );
-+    // update data registers
-+    if (data_valid_i)
-+      data_d = data_i;
- 
--    always_ff @(posedge clk_i or negedge rst_ni) begin
--        // PoR
--        if (!rst_ni) begin
--            dmcontrol_q    <= '0;
--            // this is the only write-able bit during reset
--            cmderr_q       <= dm::CmdErrNone;
--            command_q      <= '0;
--            abstractauto_q <= '0;
--            progbuf_q      <= '0;
--            data_q         <= '0;
--            sbcs_q         <= '0;
--            sbaddr_q       <= '0;
--            sbdata_q       <= '0;
--        end else begin
--            // synchronous re-set of debug module, active-low, except for dmactive
--            if (!dmcontrol_q.dmactive) begin
--                dmcontrol_q.haltreq          <= '0;
--                dmcontrol_q.resumereq        <= '0;
--                dmcontrol_q.hartreset        <= '0;
--                dmcontrol_q.zero1            <= '0;
--                dmcontrol_q.hasel            <= '0;
--                dmcontrol_q.hartsello        <= '0;
--                dmcontrol_q.hartselhi        <= '0;
--                dmcontrol_q.zero0            <= '0;
--                dmcontrol_q.setresethaltreq  <= '0;
--                dmcontrol_q.clrresethaltreq  <= '0;
--                dmcontrol_q.ndmreset         <= '0;
--                // this is the only write-able bit during reset
--                dmcontrol_q.dmactive         <= dmcontrol_d.dmactive;
--                cmderr_q                     <= dm::CmdErrNone;
--                command_q                    <= '0;
--                cmd_valid_q                  <= '0;
--                abstractauto_q               <= '0;
--                progbuf_q                    <= '0;
--                data_q                       <= '0;
--                sbcs_q                       <= '0;
--                sbaddr_q                     <= '0;
--                sbdata_q                     <= '0;
--            end else begin
--                dmcontrol_q                  <= dmcontrol_d;
--                cmderr_q                     <= cmderr_d;
--                command_q                    <= command_d;
--                cmd_valid_q                  <= cmd_valid_d;
--                abstractauto_q               <= abstractauto_d;
--                progbuf_q                    <= progbuf_d;
--                data_q                       <= data_d;
--                sbcs_q                       <= sbcs_d;
--                sbaddr_q                     <= sbaddr_d;
--                sbdata_q                     <= sbdata_d;
--            end
--        end
-+    // set the havereset flag when we did a ndmreset
-+    if (ndmreset_o) begin
-+      havereset_d = '1;
-+    end
-+    // -------------
-+    // System Bus
-+    // -------------
-+    // set bus error
-+    if (sberror_valid_i) begin
-+      sbcs_d.sberror = sberror_i;
-+    end
-+    // update read data
-+    if (sbdata_valid_i) begin
-+      sbdata_d = 64'(sbdata_i);
-+    end
-+
-+    // dmcontrol
-+    // TODO(zarubaf) we currently do not implement the hartarry mask
-+    dmcontrol_d.hasel           = 1'b0;
-+    // we do not support resetting an individual hart
-+    dmcontrol_d.hartreset       = 1'b0;
-+    dmcontrol_d.setresethaltreq = 1'b0;
-+    dmcontrol_d.clrresethaltreq = 1'b0;
-+    dmcontrol_d.zero1           = '0;
-+    dmcontrol_d.zero0           = '0;
-+    // Non-writeable, clear only
-+    dmcontrol_d.ackhavereset    = 1'b0;
-+    if (!dmcontrol_q.resumereq && dmcontrol_d.resumereq) begin
-+      clear_resumeack_o = 1'b1;
-+    end
-+    if (dmcontrol_q.resumereq && resumeack_i) begin
-+      dmcontrol_d.resumereq = 1'b0;
-     end
-+    // static values for dcsr
-+    sbcs_d.sbversion            = 3'b1;
-+    sbcs_d.sbbusy               = sbbusy_i;
-+    sbcs_d.sbasize              = BusWidth;
-+    sbcs_d.sbaccess128          = 1'b0;
-+    sbcs_d.sbaccess64           = BusWidth == 64;
-+    sbcs_d.sbaccess32           = BusWidth == 32;
-+    sbcs_d.sbaccess16           = 1'b0;
-+    sbcs_d.sbaccess8            = 1'b0;
-+    sbcs_d.sbaccess             = BusWidth == 64 ? 2'd3 : 2'd2;
-+  end
-+
-+  // output multiplexer
-+  always_comb begin
-+    selected_hart = hartsel_o[HartSelLen-1:0];
-+    // default assignment
-+    haltreq_o = '0;
-+    resumereq_o = '0;
-+    haltreq_o[selected_hart] = dmcontrol_q.haltreq;
-+    resumereq_o[selected_hart] = dmcontrol_q.resumereq;
-+  end
-+
-+  assign dmactive_o  = dmcontrol_q.dmactive;
-+  assign cmd_o       = command_q;
-+  assign cmd_valid_o = cmd_valid_q;
-+  assign progbuf_o   = progbuf_q;
-+  assign data_o      = data_q;
-+
-+  assign resp_queue_pop = dmi_resp_ready_i & ~resp_queue_empty;
-+
-+  assign ndmreset_o = dmcontrol_q.ndmreset;
-+
-+  // response FIFO
-+  fifo_v2 #(
-+    .dtype            ( logic [31:0]         ),
-+    .DEPTH            ( 2                    )
-+  ) i_fifo (
-+    .clk_i            ( clk_i                ),
-+    .rst_ni           ( dmi_rst_ni           ), // reset only when system is re-set
-+    .flush_i          ( 1'b0                 ), // we do not need to flush this queue
-+    .testmode_i       ( testmode_i           ),
-+    .full_o           ( resp_queue_full      ),
-+    .empty_o          ( resp_queue_empty     ),
-+    .alm_full_o       (                      ),
-+    .alm_empty_o      (                      ),
-+    .data_i           ( resp_queue_data      ),
-+    .push_i           ( resp_queue_push      ),
-+    .data_o           ( dmi_resp_o.data      ),
-+    .pop_i            ( resp_queue_pop       )
-+  );
-+
-+  always_ff @(posedge clk_i or negedge rst_ni) begin
-+    // PoR
-+    if (!rst_ni) begin
-+      dmcontrol_q    <= '0;
-+      // this is the only write-able bit during reset
-+      cmderr_q       <= dm::CmdErrNone;
-+      command_q      <= '0;
-+      abstractauto_q <= '0;
-+      progbuf_q      <= '0;
-+      data_q         <= '0;
-+      sbcs_q         <= '0;
-+      sbaddr_q       <= '0;
-+      sbdata_q       <= '0;
-+    end else begin
-+      // synchronous re-set of debug module, active-low, except for dmactive
-+      if (!dmcontrol_q.dmactive) begin
-+        dmcontrol_q.haltreq          <= '0;
-+        dmcontrol_q.resumereq        <= '0;
-+        dmcontrol_q.hartreset        <= '0;
-+        dmcontrol_q.zero1            <= '0;
-+        dmcontrol_q.hasel            <= '0;
-+        dmcontrol_q.hartsello        <= '0;
-+        dmcontrol_q.hartselhi        <= '0;
-+        dmcontrol_q.zero0            <= '0;
-+        dmcontrol_q.setresethaltreq  <= '0;
-+        dmcontrol_q.clrresethaltreq  <= '0;
-+        dmcontrol_q.ndmreset         <= '0;
-+        // this is the only write-able bit during reset
-+        dmcontrol_q.dmactive         <= dmcontrol_d.dmactive;
-+        cmderr_q                     <= dm::CmdErrNone;
-+        command_q                    <= '0;
-+        cmd_valid_q                  <= '0;
-+        abstractauto_q               <= '0;
-+        progbuf_q                    <= '0;
-+        data_q                       <= '0;
-+        sbcs_q                       <= '0;
-+        sbaddr_q                     <= '0;
-+        sbdata_q                     <= '0;
-+      end else begin
-+        dmcontrol_q                  <= dmcontrol_d;
-+        cmderr_q                     <= cmderr_d;
-+        command_q                    <= command_d;
-+        cmd_valid_q                  <= cmd_valid_d;
-+        abstractauto_q               <= abstractauto_d;
-+        progbuf_q                    <= progbuf_d;
-+        data_q                       <= data_d;
-+        sbcs_q                       <= sbcs_d;
-+        sbaddr_q                     <= sbaddr_d;
-+        sbdata_q                     <= sbdata_d;
-+      end
-+    end
-+  end
- 
- 
--    for (genvar k = 0; k < NrHarts; k++) begin : gen_havereset
--        always_ff @(posedge clk_i or negedge rst_ni) begin
--            if (!rst_ni) begin
--                havereset_q[k] <= 1'b1;
--            end else begin
--                havereset_q[k] <= SelectableHarts[k] ? havereset_d[k] : 1'b0;
--            end
--        end
-+  for (genvar k = 0; k < NrHarts; k++) begin : gen_havereset
-+    always_ff @(posedge clk_i or negedge rst_ni) begin
-+      if (!rst_ni) begin
-+        havereset_q[k] <= 1'b1;
-+      end else begin
-+        havereset_q[k] <= SelectableHarts[k] ? havereset_d[k] : 1'b0;
-+      end
-     end
-+  end
- 
- ///////////////////////////////////////////////////////
- // assertions
- ///////////////////////////////////////////////////////
- 
--
- //pragma translate_off
- `ifndef VERILATOR
--    haltsum: assert property (
--        @(posedge clk_i) disable iff (!rst_ni)
--            (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_READ) |->
--                !({1'b0, dmi_req_i.addr} inside
--                    {dm::HaltSum0, dm::HaltSum1, dm::HaltSum2, dm::HaltSum3}))
--        else $warning("Haltsums have not been properly tested yet.");
-+  haltsum: assert property (
-+      @(posedge clk_i) disable iff (!rst_ni)
-+          (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_READ) |->
-+              !({1'b0, dmi_req_i.addr} inside
-+                  {dm::HaltSum0, dm::HaltSum1, dm::HaltSum2, dm::HaltSum3}))
-+      else $warning("Haltsums have not been properly tested yet.");
- `endif
- //pragma translate_on
- 
--
- endmodule
-diff --git a/src/dm_mem.sv b/src/dm_mem.sv
-index c09126c..1ecc878 100644
---- a/src/dm_mem.sv
-+++ b/src/dm_mem.sv
-@@ -1,470 +1,466 @@
- /* Copyright 2018 ETH Zurich and University of Bologna.
-- * Copyright and related rights are licensed under the Solderpad Hardware
-- * License, Version 0.51 (the “License”); you may not use this file except in
-- * compliance with the License.  You may obtain a copy of the License at
-- * http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-- * or agreed to in writing, software, hardware and materials distributed under
-- * this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
-- * CONDITIONS OF ANY KIND, either express or implied. See the License for the
-- * specific language governing permissions and limitations under the License.
-- *
-- * File:   dm_mem.sv
-- * Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-- * Date:   11.7.2018
-- *
-- * Description: Memory module for execution-based debug clients
-- *
-- */
-+* Copyright and related rights are licensed under the Solderpad Hardware
-+* License, Version 0.51 (the “License”); you may not use this file except in
-+* compliance with the License.  You may obtain a copy of the License at
-+* http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-+* or agreed to in writing, software, hardware and materials distributed under
-+* this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
-+* CONDITIONS OF ANY KIND, either express or implied. See the License for the
-+* specific language governing permissions and limitations under the License.
-+*
-+* File:   dm_mem.sv
-+* Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-+* Date:   11.7.2018
-+*
-+* Description: Memory module for execution-based debug clients
-+*
-+*/
- 
- module dm_mem #(
--    parameter int                 NrHarts          = -1,
--    parameter int                 BusWidth         = -1,
--    parameter logic [NrHarts-1:0] SelectableHarts  = -1
--)(
--    input  logic                             clk_i,       // Clock
--    input  logic                             rst_ni,      // debug module reset
--
--    output logic [NrHarts-1:0]               debug_req_o,
--    input  logic [19:0]                      hartsel_i,
--    // from Ctrl and Status register
--    input  logic [NrHarts-1:0]               haltreq_i,
--    input  logic [NrHarts-1:0]               resumereq_i,
--    input  logic                             clear_resumeack_i,
--
--    // state bits
--    output logic [NrHarts-1:0]               halted_o,    // hart acknowledge halt
--    output logic [NrHarts-1:0]               resuming_o,  // hart is resuming
--
--    input  logic [dm::ProgBufSize-1:0][31:0] progbuf_i,    // program buffer to expose
--
--    input  logic [dm::DataCount-1:0][31:0]   data_i,       // data in
--    output logic [dm::DataCount-1:0][31:0]   data_o,       // data out
--    output logic                             data_valid_o, // data out is valid
--    // abstract command interface
--    input  logic                             cmd_valid_i,
--    input  dm::command_t                     cmd_i,
--    output logic                             cmderror_valid_o,
--    output dm::cmderr_e                      cmderror_o,
--    output logic                             cmdbusy_o,
--    // data interface
--
--    // SRAM interface
--    input  logic                             req_i,
--    input  logic                             we_i,
--    input  logic [BusWidth-1:0]              addr_i,
--    input  logic [BusWidth-1:0]              wdata_i,
--    input  logic [BusWidth/8-1:0]            be_i,
--    output logic [BusWidth-1:0]              rdata_o
-+  parameter int                 NrHarts          = -1,
-+  parameter int                 BusWidth         = -1,
-+  parameter logic [NrHarts-1:0] SelectableHarts  = -1
-+) (
-+  input  logic                             clk_i,       // Clock
-+  input  logic                             rst_ni,      // debug module reset
-+
-+  output logic [NrHarts-1:0]               debug_req_o,
-+  input  logic [19:0]                      hartsel_i,
-+  // from Ctrl and Status register
-+  input  logic [NrHarts-1:0]               haltreq_i,
-+  input  logic [NrHarts-1:0]               resumereq_i,
-+  input  logic                             clear_resumeack_i,
-+
-+  // state bits
-+  output logic [NrHarts-1:0]               halted_o,    // hart acknowledge halt
-+  output logic [NrHarts-1:0]               resuming_o,  // hart is resuming
-+
-+  input  logic [dm::ProgBufSize-1:0][31:0] progbuf_i,    // program buffer to expose
-+
-+  input  logic [dm::DataCount-1:0][31:0]   data_i,       // data in
-+  output logic [dm::DataCount-1:0][31:0]   data_o,       // data out
-+  output logic                             data_valid_o, // data out is valid
-+  // abstract command interface
-+  input  logic                             cmd_valid_i,
-+  input  dm::command_t                     cmd_i,
-+  output logic                             cmderror_valid_o,
-+  output dm::cmderr_e                      cmderror_o,
-+  output logic                             cmdbusy_o,
-+  // data interface
-+
-+  // SRAM interface
-+  input  logic                             req_i,
-+  input  logic                             we_i,
-+  input  logic [BusWidth-1:0]              addr_i,
-+  input  logic [BusWidth-1:0]              wdata_i,
-+  input  logic [BusWidth/8-1:0]            be_i,
-+  output logic [BusWidth-1:0]              rdata_o
- );
- 
--    localparam int HartSelLen = (NrHarts == 1) ? 1 : $clog2(NrHarts);
--    localparam int MaxAar = (BusWidth == 64) ? 4 : 3;
--    localparam DbgAddressBits = 12;
--    localparam logic [DbgAddressBits-1:0] DataBase = (dm::DataAddr);
--    localparam logic [DbgAddressBits-1:0] DataEnd = (dm::DataAddr + 4*dm::DataCount);
--    localparam logic [DbgAddressBits-1:0] ProgBufBase = (dm::DataAddr - 4*dm::ProgBufSize);
--    localparam logic [DbgAddressBits-1:0] ProgBufEnd = (dm::DataAddr - 1);
--    localparam logic [DbgAddressBits-1:0] AbstractCmdBase = (ProgBufBase - 4*10);
--    localparam logic [DbgAddressBits-1:0] AbstractCmdEnd = (ProgBufBase - 1);
--    localparam logic [DbgAddressBits-1:0] WhereTo   = 'h300;
--    localparam logic [DbgAddressBits-1:0] FlagsBase = 'h400;
--    localparam logic [DbgAddressBits-1:0] FlagsEnd  = 'h7FF;
--
--
--    localparam logic [DbgAddressBits-1:0] Halted    = 'h100;
--    localparam logic [DbgAddressBits-1:0] Going     = 'h104;
--    localparam logic [DbgAddressBits-1:0] Resuming  = 'h108;
--    localparam logic [DbgAddressBits-1:0] Exception = 'h10C;
--
--    logic [dm::ProgBufSize/2-1:0][63:0]   progbuf;
--    logic [4:0][63:0]   abstract_cmd;
--    logic [NrHarts-1:0] halted_d, halted_q;
--    logic [NrHarts-1:0] resuming_d, resuming_q;
--    logic               resume, go, going;
--    logic [NrHarts-1:0] halted;
--
--    logic [HartSelLen-1:0] hart_sel;
--    logic exception;
--    logic unsupported_command;
--
--    logic [63:0] rom_rdata;
--    logic [63:0] rdata_d, rdata_q;
--    logic        word_enable32_q;
--
--    // distinguish whether we need to forward data from the ROM or the FSM
--    // latch the address for this
--    logic fwd_rom_d, fwd_rom_q;
--    dm::ac_ar_cmd_t ac_ar;
--
--    // Abstract Command Access Register
--    assign ac_ar       = dm::ac_ar_cmd_t'(cmd_i.control);
--    assign hart_sel    = wdata_i[HartSelLen-1:0];
--    assign debug_req_o = haltreq_i;
--    assign halted_o    = halted_q;
--    assign resuming_o  = resuming_q;
--
--    // reshape progbuf
--    assign progbuf = progbuf_i;
--
--    typedef enum logic [1:0] { Idle, Go, Resume, CmdExecuting } state_e;
--    state_e state_d, state_q;
--
--    // hart ctrl queue
--    always_comb begin
--        cmderror_valid_o = 1'b0;
--        cmderror_o       = dm::CmdErrNone;
--        state_d          = state_q;
--        go               = 1'b0;
--        resume           = 1'b0;
--        cmdbusy_o        = 1'b1;
--
--        case (state_q)
--            Idle: begin
--                cmdbusy_o = 1'b0;
--                if (cmd_valid_i && halted_q[hartsel_i]) begin
--                    // give the go signal
--                    state_d = Go;
--                end else if (cmd_valid_i) begin
--                    // hart must be halted for all requests
--                    cmderror_valid_o = 1'b1;
--                    cmderror_o = dm::CmdErrorHaltResume;
--                end
--                // CSRs want to resume, the request is ignored when the hart is
--                // requested to halt or it didn't clear the resuming_q bit before
--                if (resumereq_i[hartsel_i] && !resuming_q[hartsel_i] &&
--                     !haltreq_i[hartsel_i] &&    halted_q[hartsel_i]) begin
--                    state_d = Resume;
--                end
--            end
--
--            Go: begin
--                // we are already busy here since we scheduled the execution of a program
--                cmdbusy_o = 1'b1;
--                go        = 1'b1;
--                // the thread is now executing the command, track its state
--                if (going)
--                    state_d = CmdExecuting;
--            end
--
--            Resume: begin
--                cmdbusy_o = 1'b1;
--                resume = 1'b1;
--                if (resuming_o[hartsel_i])
--                    state_d = Idle;
--            end
--
--            CmdExecuting: begin
--                cmdbusy_o = 1'b1;
--                go        = 1'b0;
--                // wait until the hart has halted again
--                if (halted[hartsel_i]) begin
--                    state_d = Idle;
--                end
--            end
--        endcase
--
--        // only signal once that cmd is unsupported so that we can clear cmderr
--        // in subsequent writes to abstractcs
--        if (unsupported_command && cmd_valid_i) begin
--            cmderror_valid_o = 1'b1;
--            cmderror_o = dm::CmdErrNotSupported;
-+  localparam int HartSelLen = (NrHarts == 1) ? 1 : $clog2(NrHarts);
-+  localparam int MaxAar = (BusWidth == 64) ? 4 : 3;
-+  localparam DbgAddressBits = 12;
-+  localparam logic [DbgAddressBits-1:0] DataBase = (dm::DataAddr);
-+  localparam logic [DbgAddressBits-1:0] DataEnd = (dm::DataAddr + 4*dm::DataCount);
-+  localparam logic [DbgAddressBits-1:0] ProgBufBase = (dm::DataAddr - 4*dm::ProgBufSize);
-+  localparam logic [DbgAddressBits-1:0] ProgBufEnd = (dm::DataAddr - 1);
-+  localparam logic [DbgAddressBits-1:0] AbstractCmdBase = (ProgBufBase - 4*10);
-+  localparam logic [DbgAddressBits-1:0] AbstractCmdEnd = (ProgBufBase - 1);
-+  localparam logic [DbgAddressBits-1:0] WhereTo   = 'h300;
-+  localparam logic [DbgAddressBits-1:0] FlagsBase = 'h400;
-+  localparam logic [DbgAddressBits-1:0] FlagsEnd  = 'h7FF;
-+
-+
-+  localparam logic [DbgAddressBits-1:0] Halted    = 'h100;
-+  localparam logic [DbgAddressBits-1:0] Going     = 'h104;
-+  localparam logic [DbgAddressBits-1:0] Resuming  = 'h108;
-+  localparam logic [DbgAddressBits-1:0] Exception = 'h10C;
-+
-+  logic [dm::ProgBufSize/2-1:0][63:0]   progbuf;
-+  logic [4:0][63:0]   abstract_cmd;
-+  logic [NrHarts-1:0] halted_d, halted_q;
-+  logic [NrHarts-1:0] resuming_d, resuming_q;
-+  logic               resume, go, going;
-+  logic [NrHarts-1:0] halted;
-+
-+  logic [HartSelLen-1:0] hart_sel;
-+  logic exception;
-+  logic unsupported_command;
-+
-+  logic [63:0] rom_rdata;
-+  logic [63:0] rdata_d, rdata_q;
-+  logic        word_enable32_q;
-+
-+  // distinguish whether we need to forward data from the ROM or the FSM
-+  // latch the address for this
-+  logic fwd_rom_d, fwd_rom_q;
-+  dm::ac_ar_cmd_t ac_ar;
-+
-+  // Abstract Command Access Register
-+  assign ac_ar       = dm::ac_ar_cmd_t'(cmd_i.control);
-+  assign hart_sel    = wdata_i[HartSelLen-1:0];
-+  assign debug_req_o = haltreq_i;
-+  assign halted_o    = halted_q;
-+  assign resuming_o  = resuming_q;
-+
-+  // reshape progbuf
-+  assign progbuf = progbuf_i;
-+
-+  typedef enum logic [1:0] { Idle, Go, Resume, CmdExecuting } state_e;
-+  state_e state_d, state_q;
-+
-+  // hart ctrl queue
-+  always_comb begin
-+    cmderror_valid_o = 1'b0;
-+    cmderror_o       = dm::CmdErrNone;
-+    state_d          = state_q;
-+    go               = 1'b0;
-+    resume           = 1'b0;
-+    cmdbusy_o        = 1'b1;
-+
-+    case (state_q)
-+      Idle: begin
-+        cmdbusy_o = 1'b0;
-+        if (cmd_valid_i && halted_q[hartsel_i]) begin
-+          // give the go signal
-+          state_d = Go;
-+        end else if (cmd_valid_i) begin
-+          // hart must be halted for all requests
-+          cmderror_valid_o = 1'b1;
-+          cmderror_o = dm::CmdErrorHaltResume;
-         end
--
--        if (exception) begin
--            cmderror_valid_o = 1'b1;
--            cmderror_o = dm::CmdErrorException;
--        end
--
--    end
--
--    // read/write logic
--    always_comb begin
--        automatic logic [63:0] data_bits;
--
--        halted_d     = halted_q;
--        resuming_d   = resuming_q;
--        rdata_o      = (BusWidth == 64) ?
--                          (fwd_rom_q ? rom_rdata : rdata_q) :
--                          (word_enable32_q ?
--                              (fwd_rom_q ? rom_rdata[63:32] : rdata_q[63:32]) :
--                              (fwd_rom_q ? rom_rdata[31: 0] : rdata_q[31: 0]));
--        rdata_d      = rdata_q;
--        // convert the data in bits representation
--        data_bits    = data_i;
--        // write data in csr register
--        data_valid_o = 1'b0;
--        exception    = 1'b0;
--        halted       = '0;
--        going        = 1'b0;
--        // The resume ack signal is lowered when the resume request is deasserted
--        if (clear_resumeack_i) begin
--            resuming_d[hartsel_i] = 1'b0;
-+        // CSRs want to resume, the request is ignored when the hart is
-+        // requested to halt or it didn't clear the resuming_q bit before
-+        if (resumereq_i[hartsel_i] && !resuming_q[hartsel_i] &&
-+             !haltreq_i[hartsel_i] &&    halted_q[hartsel_i]) begin
-+          state_d = Resume;
-         end
--        // we've got a new request
--        if (req_i) begin
--            // this is a write
--            if (we_i) begin
--                unique case (addr_i[DbgAddressBits-1:0]) inside
--                    Halted: begin
--                        halted[hart_sel] = 1'b1;
--                        halted_d[hart_sel] = 1'b1;
--                    end
--                    Going: begin
--                        going = 1'b1;
--                    end
--                    Resuming: begin
--                        // clear the halted flag as the hart resumed execution
--                        halted_d[hart_sel] = 1'b0;
--                        // set the resuming flag which needs to be cleared by the debugger
--                        resuming_d[hart_sel] = 1'b1;
--                    end
--                    // an exception occurred during execution
--                    Exception: exception = 1'b1;
--                    // core can write data registers
--                    [(dm::DataAddr):DataEnd]: begin
--                        data_valid_o = 1'b1;
--                        for (int i = 0; i < $bits(be_i); i++) begin
--                            if (be_i[i]) begin
--                                data_bits[i*8+:8] = wdata_i[i*8+:8];
--                            end
--                        end
--                    end
--                    default ;
--                endcase
--
--            // this is a read
--            end else begin
--                unique case (addr_i[DbgAddressBits-1:0]) inside
--                    // variable ROM content
--                    WhereTo: begin
--                        // variable jump to abstract cmd, program_buffer or resume
--                        if (resumereq_i[hart_sel]) begin
--                            rdata_d = {32'b0, dm::jal('0, dm::ResumeAddress[11:0]-WhereTo)};
--                        end
--
--                        // there is a command active so jump there
--                        if (cmdbusy_o) begin
--                            // transfer not set is shortcut to the program buffer if postexec is set
--                            // keep this statement narrow to not catch invalid commands
--                            if (cmd_i.cmdtype == dm::AccessRegister &&
--                                !ac_ar.transfer && ac_ar.postexec) begin
--                                rdata_d = {32'b0, dm::jal('0, ProgBufBase-WhereTo)};
--                            // this is a legit abstract cmd -> execute it
--                            end else begin
--                                rdata_d = {32'b0, dm::jal('0, AbstractCmdBase-WhereTo)};
--                            end
--                        end
--                    end
--
--                    [DataBase:DataEnd]: begin
--                        rdata_d = {
--                                  data_i[(addr_i[DbgAddressBits-1:3] - DataBase[DbgAddressBits-1:3] + 1)],
--                                  data_i[(addr_i[DbgAddressBits-1:3] - DataBase[DbgAddressBits-1:3])]
--                                  };
--                    end
--
--                    [ProgBufBase:ProgBufEnd]: begin
--                        rdata_d = progbuf[(addr_i[DbgAddressBits-1:3] -
--                                      ProgBufBase[DbgAddressBits-1:3])];
--                    end
--
--                    // two slots for abstract command
--                    [AbstractCmdBase:AbstractCmdEnd]: begin
--                        // return the correct address index
--                        rdata_d = abstract_cmd[(addr_i[DbgAddressBits-1:3] -
--                                       AbstractCmdBase[DbgAddressBits-1:3])];
--                    end
--                    // harts are polling for flags here
--                    [FlagsBase:FlagsEnd]: begin
--                        automatic logic [7:0][7:0] rdata;
--                        rdata = '0;
--                        // release the corresponding hart
--                        if (({addr_i[DbgAddressBits-1:3], 3'b0} - FlagsBase[DbgAddressBits-1:0]) ==
--                          {hartsel_i[DbgAddressBits-1:3], 3'b0}) begin
--                            rdata[hartsel_i[2:0]] = {6'b0, resume, go};
--                        end
--                        rdata_d = rdata;
--                    end
--                    default: ;
--                endcase
--            end
-+      end
-+
-+      Go: begin
-+        // we are already busy here since we scheduled the execution of a program
-+        cmdbusy_o = 1'b1;
-+        go        = 1'b1;
-+        // the thread is now executing the command, track its state
-+        if (going)
-+          state_d = CmdExecuting;
-+      end
-+
-+      Resume: begin
-+        cmdbusy_o = 1'b1;
-+        resume = 1'b1;
-+        if (resuming_o[hartsel_i])
-+          state_d = Idle;
-+      end
-+
-+      CmdExecuting: begin
-+        cmdbusy_o = 1'b1;
-+        go        = 1'b0;
-+        // wait until the hart has halted again
-+        if (halted[hartsel_i]) begin
-+          state_d = Idle;
-         end
-+      end
-+    endcase
-+
-+    // only signal once that cmd is unsupported so that we can clear cmderr
-+    // in subsequent writes to abstractcs
-+    if (unsupported_command && cmd_valid_i) begin
-+      cmderror_valid_o = 1'b1;
-+      cmderror_o = dm::CmdErrNotSupported;
-+    end
- 
--        data_o = data_bits;
-+    if (exception) begin
-+      cmderror_valid_o = 1'b1;
-+      cmderror_o = dm::CmdErrorException;
-     end
-+  end
-+
-+  // read/write logic
-+  always_comb begin
-+    automatic logic [63:0] data_bits;
-+
-+    halted_d     = halted_q;
-+    resuming_d   = resuming_q;
-+    rdata_o      = (BusWidth == 64) ?
-+                      (fwd_rom_q ? rom_rdata : rdata_q) :
-+                      (word_enable32_q ?
-+                          (fwd_rom_q ? rom_rdata[63:32] : rdata_q[63:32]) :
-+                          (fwd_rom_q ? rom_rdata[31: 0] : rdata_q[31: 0]));
-+    rdata_d      = rdata_q;
-+    // convert the data in bits representation
-+    data_bits    = data_i;
-+    // write data in csr register
-+    data_valid_o = 1'b0;
-+    exception    = 1'b0;
-+    halted       = '0;
-+    going        = 1'b0;
-+    // The resume ack signal is lowered when the resume request is deasserted
-+    if (clear_resumeack_i) begin
-+      resuming_d[hartsel_i] = 1'b0;
-+    end
-+    // we've got a new request
-+    if (req_i) begin
-+      // this is a write
-+      if (we_i) begin
-+        unique case (addr_i[DbgAddressBits-1:0]) inside
-+          Halted: begin
-+            halted[hart_sel] = 1'b1;
-+            halted_d[hart_sel] = 1'b1;
-+          end
-+          Going: begin
-+            going = 1'b1;
-+          end
-+          Resuming: begin
-+            // clear the halted flag as the hart resumed execution
-+            halted_d[hart_sel] = 1'b0;
-+            // set the resuming flag which needs to be cleared by the debugger
-+            resuming_d[hart_sel] = 1'b1;
-+          end
-+          // an exception occurred during execution
-+          Exception: exception = 1'b1;
-+          // core can write data registers
-+          [(dm::DataAddr):DataEnd]: begin
-+            data_valid_o = 1'b1;
-+            for (int i = 0; i < $bits(be_i); i++) begin
-+              if (be_i[i]) begin
-+                data_bits[i*8+:8] = wdata_i[i*8+:8];
-+              end
-+            end
-+          end
-+          default ;
-+        endcase
- 
--    always_comb begin : abstract_cmd_rom
--        // this abstract command is currently unsupported
--        unsupported_command = 1'b0;
--        // default memory
--        // if ac_ar.transfer is not set then we can take a shortcut to the program buffer
--        abstract_cmd[0][31:0]  = dm::illegal();
--        // load debug module base address into a0, this is shared among all commands
--        abstract_cmd[0][63:32] = dm::auipc(5'd10, '0);
--        abstract_cmd[1][31:0]  = dm::srli(5'd10, 5'd10, 6'd12); // clr lowest 12b -> DM base offset
--        abstract_cmd[1][63:32] = dm::slli(5'd10, 5'd10, 6'd12);
--        abstract_cmd[2][31:0]  = dm::nop();
--        abstract_cmd[2][63:32] = dm::nop();
--        abstract_cmd[3][31:0]  = dm::nop();
--        abstract_cmd[3][63:32] = dm::nop();
--        abstract_cmd[4][31:0]  = dm::csrr(dm::CSR_DSCRATCH1, 5'd10);
--        abstract_cmd[4][63:32] = dm::ebreak();
--
--        // this depends on the command being executed
--        unique case (cmd_i.cmdtype)
--            // --------------------
--            // Access Register
--            // --------------------
--            dm::AccessRegister: begin
--                if (ac_ar.aarsize < MaxAar && ac_ar.transfer && ac_ar.write) begin
--                    // store a0 in dscratch1
--                    abstract_cmd[0][31:0] = dm::csrw(dm::CSR_DSCRATCH1, 5'd10);
--                    // this range is reserved
--                    if (ac_ar.regno[15:14] != '0) begin
--                        abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap
--                        unsupported_command = 1'b1;
--                    // A0 access needs to be handled separately, as we use A0 to load
--                    // the DM address offset need to access DSCRATCH1 in this case
--                    end else if (ac_ar.regno[12] && (!ac_ar.regno[5]) &&
--                                (ac_ar.regno[4:0] == 5'd10)) begin
--                        // store s0 in dscratch
--                        abstract_cmd[2][31:0]  = dm::csrw(dm::CSR_DSCRATCH0, 5'd8);
--                        // load from data register
--                        abstract_cmd[2][63:32] = dm::load(ac_ar.aarsize, 5'd8, 5'd10, dm::DataAddr);
--                        // and store it in the corresponding CSR
--                        abstract_cmd[3][31:0]  = dm::csrw(dm::CSR_DSCRATCH1, 5'd8);
--                        // restore s0 again from dscratch
--                        abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8);
--                    // GPR/FPR access
--                    end else if (ac_ar.regno[12]) begin
--                        // determine whether we want to access the floating point register or not
--                        if (ac_ar.regno[5]) begin
--                            abstract_cmd[2][31:0] =
--                                dm::float_load(ac_ar.aarsize, ac_ar.regno[4:0], 5'd10, dm::DataAddr);
--                        end else begin
--                            abstract_cmd[2][31:0] =
--                                dm::load(ac_ar.aarsize, ac_ar.regno[4:0], 5'd10, dm::DataAddr);
--                        end
--                    // CSR access
--                    end else begin
--                        // data register to CSR
--                        // store s0 in dscratch
--                        abstract_cmd[2][31:0]  = dm::csrw(dm::CSR_DSCRATCH0, 5'd8);
--                        // load from data register
--                        abstract_cmd[2][63:32] = dm::load(ac_ar.aarsize, 5'd8, 5'd10, dm::DataAddr);
--                        // and store it in the corresponding CSR
--                        abstract_cmd[3][31:0]  = dm::csrw(dm::csr_reg_t'(ac_ar.regno[11:0]), 5'd8);
--                        // restore s0 again from dscratch
--                        abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8);
--                    end
--                end else if (ac_ar.aarsize < MaxAar && ac_ar.transfer && !ac_ar.write) begin
--                    // store a0 in dscratch1
--                    abstract_cmd[0][31:0]  = dm::csrw(dm::CSR_DSCRATCH1, 5'd10);
--                    // this range is reserved
--                    if (ac_ar.regno[15:14] != '0) begin
--                        abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap
--                        unsupported_command = 1'b1;
--                    // A0 access needs to be handled separately, as we use A0 to load
--                    // the DM address offset need to access DSCRATCH1 in this case
--                    end else if (ac_ar.regno[12] && (!ac_ar.regno[5]) &&
--                                (ac_ar.regno[4:0] == 5'd10)) begin
--                        // store s0 in dscratch
--                        abstract_cmd[2][31:0]  = dm::csrw(dm::CSR_DSCRATCH0, 5'd8);
--                        // read value from CSR into s0
--                        abstract_cmd[2][63:32] = dm::csrr(dm::CSR_DSCRATCH1, 5'd8);
--                        // and store s0 into data section
--                        abstract_cmd[3][31:0]  = dm::store(ac_ar.aarsize, 5'd8, 5'd10, dm::DataAddr);
--                        // restore s0 again from dscratch
--                        abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8);
--                    // GPR/FPR access
--                    end else if (ac_ar.regno[12]) begin
--                        // determine whether we want to access the floating point register or not
--                        if (ac_ar.regno[5]) begin
--                            abstract_cmd[2][31:0] =
--                                dm::float_store(ac_ar.aarsize, ac_ar.regno[4:0], 5'd10, dm::DataAddr);
--                        end else begin
--                            abstract_cmd[2][31:0] =
--                                dm::store(ac_ar.aarsize, ac_ar.regno[4:0], 5'd10, dm::DataAddr);
--                        end
--                    // CSR access
--                    end else begin
--                        // CSR register to data
--                        // store s0 in dscratch
--                        abstract_cmd[2][31:0]  = dm::csrw(dm::CSR_DSCRATCH0, 5'd8);
--                        // read value from CSR into s0
--                        abstract_cmd[2][63:32] = dm::csrr(dm::csr_reg_t'(ac_ar.regno[11:0]), 5'd8);
--                        // and store s0 into data section
--                        abstract_cmd[3][31:0]  = dm::store(ac_ar.aarsize, 5'd8, 5'd10, dm::DataAddr);
--                        // restore s0 again from dscratch
--                        abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8);
--                    end
--                end else if (ac_ar.aarsize >= MaxAar || ac_ar.aarpostincrement == 1'b1) begin
--                    // this should happend when e.g. ac_ar.aarsize >= MaxAar
--                    // Openocd will try to do an access with aarsize=64 bits
--                    // first before falling back to 32 bits.
--                    abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap
--                    unsupported_command = 1'b1;
--
--                end
--
--                // Check whether we need to execute the program buffer. When we
--                // get an unsupported command we really should abort instead of
--                // still trying to execute the program buffer, makes it easier
--                // for the debugger to recover
--                if (ac_ar.postexec && !unsupported_command) begin
--                    // issue a nop, we will automatically run into the program buffer
--                    abstract_cmd[4][63:32] = dm::nop();
--                end
-+      // this is a read
-+      end else begin
-+        unique case (addr_i[DbgAddressBits-1:0]) inside
-+          // variable ROM content
-+          WhereTo: begin
-+            // variable jump to abstract cmd, program_buffer or resume
-+            if (resumereq_i[hart_sel]) begin
-+              rdata_d = {32'b0, dm::jal('0, dm::ResumeAddress[11:0]-WhereTo)};
-+            end
- 
-+            // there is a command active so jump there
-+            if (cmdbusy_o) begin
-+              // transfer not set is shortcut to the program buffer if postexec is set
-+              // keep this statement narrow to not catch invalid commands
-+              if (cmd_i.cmdtype == dm::AccessRegister &&
-+                  !ac_ar.transfer && ac_ar.postexec) begin
-+                rdata_d = {32'b0, dm::jal('0, ProgBufBase-WhereTo)};
-+              // this is a legit abstract cmd -> execute it
-+              end else begin
-+                rdata_d = {32'b0, dm::jal('0, AbstractCmdBase-WhereTo)};
-+              end
-             end
--            // not supported at the moment
--            // dm::QuickAccess:;
--            // dm::AccessMemory:;
--            default: begin
--                abstract_cmd[0][31:0] = dm::ebreak();
--                unsupported_command = 1'b1;
-+          end
-+
-+          [DataBase:DataEnd]: begin
-+            rdata_d = {
-+                      data_i[(addr_i[DbgAddressBits-1:3] - DataBase[DbgAddressBits-1:3] + 1)],
-+                      data_i[(addr_i[DbgAddressBits-1:3] - DataBase[DbgAddressBits-1:3])]
-+                      };
-+          end
-+
-+          [ProgBufBase:ProgBufEnd]: begin
-+            rdata_d = progbuf[(addr_i[DbgAddressBits-1:3] -
-+                          ProgBufBase[DbgAddressBits-1:3])];
-+          end
-+
-+          // two slots for abstract command
-+          [AbstractCmdBase:AbstractCmdEnd]: begin
-+            // return the correct address index
-+            rdata_d = abstract_cmd[(addr_i[DbgAddressBits-1:3] -
-+                           AbstractCmdBase[DbgAddressBits-1:3])];
-+          end
-+          // harts are polling for flags here
-+          [FlagsBase:FlagsEnd]: begin
-+            automatic logic [7:0][7:0] rdata;
-+            rdata = '0;
-+            // release the corresponding hart
-+            if (({addr_i[DbgAddressBits-1:3], 3'b0} - FlagsBase[DbgAddressBits-1:0]) ==
-+                {hartsel_i[DbgAddressBits-1:3], 3'b0}) begin
-+              rdata[hartsel_i[2:0]] = {6'b0, resume, go};
-             end
-+            rdata_d = rdata;
-+          end
-+          default: ;
-         endcase
-+      end
-     end
- 
--    logic [63:0] rom_addr;
--    assign rom_addr = 64'(addr_i);
--    debug_rom i_debug_rom (
--        .clk_i,
--        .req_i,
--        .addr_i  ( rom_addr  ),
--        .rdata_o ( rom_rdata )
--    );
--
--    // ROM starts at the HaltAddress of the core e.g.: it immediately jumps to
--    // the ROM base address
--    assign fwd_rom_d = (addr_i[DbgAddressBits-1:0] >= dm::HaltAddress[DbgAddressBits-1:0]) ?
--                           1'b1 : 1'b0;
--
--    always_ff @(posedge clk_i or negedge rst_ni) begin
--        if (!rst_ni) begin
--            fwd_rom_q       <= 1'b0;
--            rdata_q         <= '0;
--            state_q         <= Idle;
--            word_enable32_q <= 1'b0;
--        end else begin
--            fwd_rom_q       <= fwd_rom_d;
--            rdata_q         <= rdata_d;
--            state_q         <= state_d;
--            word_enable32_q <= addr_i[2];
--        end
--    end
--
--    for (genvar k = 0; k < NrHarts; k++) begin : gen_halted
--        always_ff @(posedge clk_i or negedge rst_ni) begin
--            if (!rst_ni) begin
--                halted_q[k]   <= 1'b0;
--                resuming_q[k] <= 1'b0;
-+    data_o = data_bits;
-+  end
-+
-+  always_comb begin : abstract_cmd_rom
-+    // this abstract command is currently unsupported
-+    unsupported_command = 1'b0;
-+    // default memory
-+    // if ac_ar.transfer is not set then we can take a shortcut to the program buffer
-+    abstract_cmd[0][31:0]  = dm::illegal();
-+    // load debug module base address into a0, this is shared among all commands
-+    abstract_cmd[0][63:32] = dm::auipc(5'd10, '0);
-+    abstract_cmd[1][31:0]  = dm::srli(5'd10, 5'd10, 6'd12); // clr lowest 12b -> DM base offset
-+    abstract_cmd[1][63:32] = dm::slli(5'd10, 5'd10, 6'd12);
-+    abstract_cmd[2][31:0]  = dm::nop();
-+    abstract_cmd[2][63:32] = dm::nop();
-+    abstract_cmd[3][31:0]  = dm::nop();
-+    abstract_cmd[3][63:32] = dm::nop();
-+    abstract_cmd[4][31:0]  = dm::csrr(dm::CSR_DSCRATCH1, 5'd10);
-+    abstract_cmd[4][63:32] = dm::ebreak();
-+
-+    // this depends on the command being executed
-+    unique case (cmd_i.cmdtype)
-+      // --------------------
-+      // Access Register
-+      // --------------------
-+      dm::AccessRegister: begin
-+        if (ac_ar.aarsize < MaxAar && ac_ar.transfer && ac_ar.write) begin
-+          // store a0 in dscratch1
-+          abstract_cmd[0][31:0] = dm::csrw(dm::CSR_DSCRATCH1, 5'd10);
-+          // this range is reserved
-+          if (ac_ar.regno[15:14] != '0) begin
-+            abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap
-+            unsupported_command = 1'b1;
-+          // A0 access needs to be handled separately, as we use A0 to load
-+          // the DM address offset need to access DSCRATCH1 in this case
-+          end else if (ac_ar.regno[12] && (!ac_ar.regno[5]) &&
-+                      (ac_ar.regno[4:0] == 5'd10)) begin
-+            // store s0 in dscratch
-+            abstract_cmd[2][31:0]  = dm::csrw(dm::CSR_DSCRATCH0, 5'd8);
-+            // load from data register
-+            abstract_cmd[2][63:32] = dm::load(ac_ar.aarsize, 5'd8, 5'd10, dm::DataAddr);
-+            // and store it in the corresponding CSR
-+            abstract_cmd[3][31:0]  = dm::csrw(dm::CSR_DSCRATCH1, 5'd8);
-+            // restore s0 again from dscratch
-+            abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8);
-+          // GPR/FPR access
-+          end else if (ac_ar.regno[12]) begin
-+            // determine whether we want to access the floating point register or not
-+            if (ac_ar.regno[5]) begin
-+              abstract_cmd[2][31:0] =
-+                  dm::float_load(ac_ar.aarsize, ac_ar.regno[4:0], 5'd10, dm::DataAddr);
-+            end else begin
-+              abstract_cmd[2][31:0] =
-+                  dm::load(ac_ar.aarsize, ac_ar.regno[4:0], 5'd10, dm::DataAddr);
-+            end
-+          // CSR access
-+          end else begin
-+            // data register to CSR
-+            // store s0 in dscratch
-+            abstract_cmd[2][31:0]  = dm::csrw(dm::CSR_DSCRATCH0, 5'd8);
-+            // load from data register
-+            abstract_cmd[2][63:32] = dm::load(ac_ar.aarsize, 5'd8, 5'd10, dm::DataAddr);
-+            // and store it in the corresponding CSR
-+            abstract_cmd[3][31:0]  = dm::csrw(dm::csr_reg_t'(ac_ar.regno[11:0]), 5'd8);
-+            // restore s0 again from dscratch
-+            abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8);
-+          end
-+        end else if (ac_ar.aarsize < MaxAar && ac_ar.transfer && !ac_ar.write) begin
-+          // store a0 in dscratch1
-+          abstract_cmd[0][31:0]  = dm::csrw(dm::CSR_DSCRATCH1, 5'd10);
-+          // this range is reserved
-+          if (ac_ar.regno[15:14] != '0) begin
-+            abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap
-+            unsupported_command = 1'b1;
-+          // A0 access needs to be handled separately, as we use A0 to load
-+          // the DM address offset need to access DSCRATCH1 in this case
-+          end else if (ac_ar.regno[12] && (!ac_ar.regno[5]) &&
-+                      (ac_ar.regno[4:0] == 5'd10)) begin
-+            // store s0 in dscratch
-+            abstract_cmd[2][31:0]  = dm::csrw(dm::CSR_DSCRATCH0, 5'd8);
-+            // read value from CSR into s0
-+            abstract_cmd[2][63:32] = dm::csrr(dm::CSR_DSCRATCH1, 5'd8);
-+            // and store s0 into data section
-+            abstract_cmd[3][31:0]  = dm::store(ac_ar.aarsize, 5'd8, 5'd10, dm::DataAddr);
-+            // restore s0 again from dscratch
-+            abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8);
-+          // GPR/FPR access
-+          end else if (ac_ar.regno[12]) begin
-+            // determine whether we want to access the floating point register or not
-+            if (ac_ar.regno[5]) begin
-+              abstract_cmd[2][31:0] =
-+                  dm::float_store(ac_ar.aarsize, ac_ar.regno[4:0], 5'd10, dm::DataAddr);
-             end else begin
--                halted_q[k]   <= SelectableHarts[k] ? halted_d[k]   : 1'b0;
--                resuming_q[k] <= SelectableHarts[k] ? resuming_d[k] : 1'b0;
-+              abstract_cmd[2][31:0] =
-+                  dm::store(ac_ar.aarsize, ac_ar.regno[4:0], 5'd10, dm::DataAddr);
-             end
-+          // CSR access
-+          end else begin
-+            // CSR register to data
-+            // store s0 in dscratch
-+            abstract_cmd[2][31:0]  = dm::csrw(dm::CSR_DSCRATCH0, 5'd8);
-+            // read value from CSR into s0
-+            abstract_cmd[2][63:32] = dm::csrr(dm::csr_reg_t'(ac_ar.regno[11:0]), 5'd8);
-+            // and store s0 into data section
-+            abstract_cmd[3][31:0]  = dm::store(ac_ar.aarsize, 5'd8, 5'd10, dm::DataAddr);
-+            // restore s0 again from dscratch
-+            abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8);
-+          end
-+        end else if (ac_ar.aarsize >= MaxAar || ac_ar.aarpostincrement == 1'b1) begin
-+          // this should happend when e.g. ac_ar.aarsize >= MaxAar
-+          // Openocd will try to do an access with aarsize=64 bits
-+          // first before falling back to 32 bits.
-+          abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap
-+          unsupported_command = 1'b1;
-         end
-+        // Check whether we need to execute the program buffer. When we
-+        // get an unsupported command we really should abort instead of
-+        // still trying to execute the program buffer, makes it easier
-+        // for the debugger to recover
-+        if (ac_ar.postexec && !unsupported_command) begin
-+          // issue a nop, we will automatically run into the program buffer
-+          abstract_cmd[4][63:32] = dm::nop();
-+        end
-+      end
-+      // not supported at the moment
-+      // dm::QuickAccess:;
-+      // dm::AccessMemory:;
-+      default: begin
-+        abstract_cmd[0][31:0] = dm::ebreak();
-+        unsupported_command = 1'b1;
-+      end
-+    endcase
-+  end
-+
-+  logic [63:0] rom_addr;
-+  assign rom_addr = 64'(addr_i);
-+  debug_rom i_debug_rom (
-+    .clk_i,
-+    .req_i,
-+    .addr_i  ( rom_addr  ),
-+    .rdata_o ( rom_rdata )
-+  );
-+
-+  // ROM starts at the HaltAddress of the core e.g.: it immediately jumps to
-+  // the ROM base address
-+  assign fwd_rom_d = (addr_i[DbgAddressBits-1:0] >= dm::HaltAddress[DbgAddressBits-1:0]) ?
-+                     1'b1 : 1'b0;
-+
-+  always_ff @(posedge clk_i or negedge rst_ni) begin
-+    if (!rst_ni) begin
-+      fwd_rom_q       <= 1'b0;
-+      rdata_q         <= '0;
-+      state_q         <= Idle;
-+      word_enable32_q <= 1'b0;
-+    end else begin
-+      fwd_rom_q       <= fwd_rom_d;
-+      rdata_q         <= rdata_d;
-+      state_q         <= state_d;
-+      word_enable32_q <= addr_i[2];
-+    end
-+  end
-+
-+  for (genvar k = 0; k < NrHarts; k++) begin : gen_halted
-+    always_ff @(posedge clk_i or negedge rst_ni) begin
-+      if (!rst_ni) begin
-+        halted_q[k]   <= 1'b0;
-+        resuming_q[k] <= 1'b0;
-+      end else begin
-+        halted_q[k]   <= SelectableHarts[k] ? halted_d[k]   : 1'b0;
-+        resuming_q[k] <= SelectableHarts[k] ? resuming_d[k] : 1'b0;
-+      end
-     end
-+  end
- 
- endmodule
-diff --git a/src/dm_pkg.sv b/src/dm_pkg.sv
-index b2593d6..49e77be 100644
---- a/src/dm_pkg.sv
-+++ b/src/dm_pkg.sv
-@@ -17,370 +17,370 @@
-  */
- 
- package dm;
--    localparam logic [3:0] DbgVersion013 = 4'h2;
--    // size of program buffer in junks of 32-bit words
--    localparam logic [4:0] ProgBufSize   = 5'h8;
--
--    // amount of data count registers implemented
--    localparam logic [3:0] DataCount     = 4'h2;
--
--    // address to which a hart should jump when it was requested to halt
--    localparam logic [63:0] HaltAddress = 64'h800;
--    localparam logic [63:0] ResumeAddress = HaltAddress + 4;
--    localparam logic [63:0] ExceptionAddress = HaltAddress + 8;
--
--    // address where data0-15 is shadowed or if shadowed in a CSR
--    // address of the first CSR used for shadowing the data
--    localparam logic [11:0] DataAddr = 12'h380; // we are aligned with Rocket here
--
--    // debug registers
--    typedef enum logic [7:0] {
--        Data0        = 8'h04,
--        Data1        = 8'h05,
--        Data2        = 8'h06,
--        Data3        = 8'h07,
--        Data4        = 8'h08,
--        Data5        = 8'h09,
--        Data6        = 8'h0A,
--        Data7        = 8'h0B,
--        Data8        = 8'h0C,
--        Data9        = 8'h0D,
--        Data10       = 8'h0E,
--        Data11       = 8'h0F,
--        DMControl    = 8'h10,
--        DMStatus     = 8'h11, // r/o
--        Hartinfo     = 8'h12,
--        HaltSum1     = 8'h13,
--        HAWindowSel  = 8'h14,
--        HAWindow     = 8'h15,
--        AbstractCS   = 8'h16,
--        Command      = 8'h17,
--        AbstractAuto = 8'h18,
--        DevTreeAddr0 = 8'h19,
--        DevTreeAddr1 = 8'h1A,
--        DevTreeAddr2 = 8'h1B,
--        DevTreeAddr3 = 8'h1C,
--        NextDM       = 8'h1D,
--        ProgBuf0     = 8'h20,
--        ProgBuf15    = 8'h2F,
--        AuthData     = 8'h30,
--        HaltSum2     = 8'h34,
--        HaltSum3     = 8'h35,
--        SBAddress3   = 8'h37,
--        SBCS         = 8'h38,
--        SBAddress0   = 8'h39,
--        SBAddress1   = 8'h3A,
--        SBAddress2   = 8'h3B,
--        SBData0      = 8'h3C,
--        SBData1      = 8'h3D,
--        SBData2      = 8'h3E,
--        SBData3      = 8'h3F,
--        HaltSum0     = 8'h40
--    } dm_csr_e;
--
--    // debug causes
--    localparam logic [2:0] CauseBreakpoint = 3'h1;
--    localparam logic [2:0] CauseTrigger    = 3'h2;
--    localparam logic [2:0] CauseRequest    = 3'h3;
--    localparam logic [2:0] CauseSingleStep = 3'h4;
--
--    typedef struct packed {
--        logic [31:23] zero1;
--        logic         impebreak;
--        logic [21:20] zero0;
--        logic         allhavereset;
--        logic         anyhavereset;
--        logic         allresumeack;
--        logic         anyresumeack;
--        logic         allnonexistent;
--        logic         anynonexistent;
--        logic         allunavail;
--        logic         anyunavail;
--        logic         allrunning;
--        logic         anyrunning;
--        logic         allhalted;
--        logic         anyhalted;
--        logic         authenticated;
--        logic         authbusy;
--        logic         hasresethaltreq;
--        logic         devtreevalid;
--        logic [3:0]   version;
--    } dmstatus_t;
--
--    typedef struct packed {
--        logic         haltreq;
--        logic         resumereq;
--        logic         hartreset;
--        logic         ackhavereset;
--        logic         zero1;
--        logic         hasel;
--        logic [25:16] hartsello;
--        logic [15:6]  hartselhi;
--        logic [5:4]   zero0;
--        logic         setresethaltreq;
--        logic         clrresethaltreq;
--        logic         ndmreset;
--        logic         dmactive;
--    } dmcontrol_t;
--
--    typedef struct packed {
--        logic [31:24] zero1;
--        logic [23:20] nscratch;
--        logic [19:17] zero0;
--        logic         dataaccess;
--        logic [15:12] datasize;
--        logic [11:0]  dataaddr;
--    } hartinfo_t;
--
--    typedef enum logic [2:0] {  CmdErrNone, CmdErrBusy, CmdErrNotSupported,
--                                CmdErrorException, CmdErrorHaltResume,
--                                CmdErrorBus, CmdErrorOther = 7
--                             } cmderr_e;
--
--    typedef struct packed {
--        logic [31:29] zero3;
--        logic [28:24] progbufsize;
--        logic [23:13] zero2;
--        logic         busy;
--        logic         zero1;
--        cmderr_e      cmderr;
--        logic [7:4]   zero0;
--        logic [3:0]   datacount;
--    } abstractcs_t;
--
--    typedef enum logic [7:0] {
--                                 AccessRegister = 8'h0,
--                                 QuickAccess    = 8'h1,
--                                 AccessMemory   = 8'h2
--                             } cmd_e;
--
--    typedef struct packed {
--        cmd_e        cmdtype;
--        logic [23:0] control;
--    } command_t;
--
--    typedef struct packed {
--        logic [31:16] autoexecprogbuf;
--        logic [15:12] zero0;
--        logic [11:0]  autoexecdata;
--    } abstractauto_t;
--
--    typedef struct packed {
--        logic         zero1;
--        logic [22:20] aarsize;
--        logic         aarpostincrement;
--        logic         postexec;
--        logic         transfer;
--        logic         write;
--        logic [15:0]  regno;
--    } ac_ar_cmd_t;
--
--    // DTM
--    typedef enum logic [1:0] {
--        DTM_NOP   = 2'h0,
--        DTM_READ  = 2'h1,
--        DTM_WRITE = 2'h2
--    } dtm_op_e;
--
--    typedef struct packed {
--        logic [31:29] sbversion;
--        logic [28:23] zero0;
--        logic         sbbusyerror;
--        logic         sbbusy;
--        logic         sbreadonaddr;
--        logic [19:17] sbaccess;
--        logic         sbautoincrement;
--        logic         sbreadondata;
--        logic [14:12] sberror;
--        logic [11:5]  sbasize;
--        logic         sbaccess128;
--        logic         sbaccess64;
--        logic         sbaccess32;
--        logic         sbaccess16;
--        logic         sbaccess8;
--    } sbcs_t;
--
--    localparam logic[1:0] DTM_SUCCESS = 2'h0;
--
--    typedef struct packed {
--        logic [6:0]  addr;
--        dtm_op_e     op;
--        logic [31:0] data;
--    } dmi_req_t;
--
--    typedef struct packed  {
--        logic [31:0] data;
--        logic [1:0]  resp;
--    } dmi_resp_t;
--
--    // privilege levels
--    typedef enum logic[1:0] {
--      PRIV_LVL_M = 2'b11,
--      PRIV_LVL_S = 2'b01,
--      PRIV_LVL_U = 2'b00
--    } priv_lvl_t;
--
--    // debugregs in core
--    typedef struct packed {
--        logic [31:28]     xdebugver;
--        logic [27:16]     zero2;
--        logic             ebreakm;
--        logic             zero1;
--        logic             ebreaks;
--        logic             ebreaku;
--        logic             stepie;
--        logic             stopcount;
--        logic             stoptime;
--        logic [8:6]       cause;
--        logic             zero0;
--        logic             mprven;
--        logic             nmip;
--        logic             step;
--        priv_lvl_t        prv;
--    } dcsr_t;
--
--    // CSRs
--    typedef enum logic [11:0] {
--        // Floating-Point CSRs
--        CSR_FFLAGS         = 12'h001,
--        CSR_FRM            = 12'h002,
--        CSR_FCSR           = 12'h003,
--        CSR_FTRAN          = 12'h800,
--        // Supervisor Mode CSRs
--        CSR_SSTATUS        = 12'h100,
--        CSR_SIE            = 12'h104,
--        CSR_STVEC          = 12'h105,
--        CSR_SCOUNTEREN     = 12'h106,
--        CSR_SSCRATCH       = 12'h140,
--        CSR_SEPC           = 12'h141,
--        CSR_SCAUSE         = 12'h142,
--        CSR_STVAL          = 12'h143,
--        CSR_SIP            = 12'h144,
--        CSR_SATP           = 12'h180,
--        // Machine Mode CSRs
--        CSR_MSTATUS        = 12'h300,
--        CSR_MISA           = 12'h301,
--        CSR_MEDELEG        = 12'h302,
--        CSR_MIDELEG        = 12'h303,
--        CSR_MIE            = 12'h304,
--        CSR_MTVEC          = 12'h305,
--        CSR_MCOUNTEREN     = 12'h306,
--        CSR_MSCRATCH       = 12'h340,
--        CSR_MEPC           = 12'h341,
--        CSR_MCAUSE         = 12'h342,
--        CSR_MTVAL          = 12'h343,
--        CSR_MIP            = 12'h344,
--        CSR_PMPCFG0        = 12'h3A0,
--        CSR_PMPADDR0       = 12'h3B0,
--        CSR_MVENDORID      = 12'hF11,
--        CSR_MARCHID        = 12'hF12,
--        CSR_MIMPID         = 12'hF13,
--        CSR_MHARTID        = 12'hF14,
--        CSR_MCYCLE         = 12'hB00,
--        CSR_MINSTRET       = 12'hB02,
--        CSR_DCACHE         = 12'h701,
--        CSR_ICACHE         = 12'h700,
--
--        CSR_TSELECT        = 12'h7A0,
--        CSR_TDATA1         = 12'h7A1,
--        CSR_TDATA2         = 12'h7A2,
--        CSR_TDATA3         = 12'h7A3,
--        CSR_TINFO          = 12'h7A4,
--
--        // Debug CSR
--        CSR_DCSR           = 12'h7b0,
--        CSR_DPC            = 12'h7b1,
--        CSR_DSCRATCH0      = 12'h7b2, // optional
--        CSR_DSCRATCH1      = 12'h7b3, // optional
--
--        // Counters and Timers
--        CSR_CYCLE          = 12'hC00,
--        CSR_TIME           = 12'hC01,
--        CSR_INSTRET        = 12'hC02
--    } csr_reg_t;
--
--
--    // Instruction Generation Helpers
--    function automatic logic [31:0] jal (logic[4:0] rd, logic [20:0] imm);
--        // OpCode Jal
--        return {imm[20], imm[10:1], imm[11], imm[19:12], rd, 7'h6f};
--    endfunction
--
--    function automatic logic [31:0] jalr (logic[4:0] rd, logic[4:0] rs1, logic [11:0] offset);
--        // OpCode Jal
--        return {offset[11:0], rs1, 3'b0, rd, 7'h67};
--    endfunction
--
--    function automatic logic [31:0] andi (logic[4:0] rd, logic[4:0] rs1, logic [11:0] imm);
--        // OpCode andi
--        return {imm[11:0], rs1, 3'h7, rd, 7'h13};
--    endfunction
--
--    function automatic logic [31:0] slli (logic[4:0] rd, logic[4:0] rs1, logic [5:0] shamt);
--        // OpCode slli
--        return {6'b0, shamt[5:0], rs1, 3'h1, rd, 7'h13};
--    endfunction
--
--    function automatic logic [31:0] srli (logic[4:0] rd, logic[4:0] rs1, logic [5:0] shamt);
--        // OpCode srli
--        return {6'b0, shamt[5:0], rs1, 3'h5, rd, 7'h13};
--    endfunction
--
--    function automatic logic [31:0] load (logic [2:0] size, logic[4:0] dest, logic[4:0] base, logic [11:0] offset);
--        // OpCode Load
--        return {offset[11:0], base, size, dest, 7'h03};
--    endfunction
--
--    function automatic logic [31:0] auipc (logic[4:0] rd, logic [20:0] imm);
--        // OpCode Auipc
--        return {imm[20], imm[10:1], imm[11], imm[19:12], rd, 7'h17};
--    endfunction
--
--    function automatic logic [31:0] store (logic [2:0] size, logic[4:0] src, logic[4:0] base, logic [11:0] offset);
--        // OpCode Store
--        return {offset[11:5], src, base, size, offset[4:0], 7'h23};
--    endfunction
--
--    function automatic logic [31:0] float_load (logic [2:0] size, logic[4:0] dest, logic[4:0] base, logic [11:0] offset);
--        // OpCode Load
--        return {offset[11:0], base, size, dest, 7'b00_001_11};
--    endfunction
--
--    function automatic logic [31:0] float_store (logic [2:0] size, logic[4:0] src, logic[4:0] base, logic [11:0] offset);
--        // OpCode Store
--        return {offset[11:5], src, base, size, offset[4:0], 7'b01_001_11};
--    endfunction
--
--    function automatic logic [31:0] csrw (csr_reg_t csr, logic[4:0] rs1);
--        // CSRRW, rd, OpCode System
--        return {csr, rs1, 3'h1, 5'h0, 7'h73};
--    endfunction
--
--    function automatic logic [31:0] csrr (csr_reg_t csr, logic [4:0] dest);
--        // rs1, CSRRS, rd, OpCode System
--        return {csr, 5'h0, 3'h2, dest, 7'h73};
--    endfunction
--
--    function automatic logic [31:0] branch(logic [4:0] src2, logic [4:0] src1, logic [2:0] funct3, logic [11:0] offset);
--        // OpCode Branch
--        return {offset[11], offset[9:4], src2, src1, funct3, offset[3:0], offset[10], 7'b11_000_11};
--    endfunction
--
--    function automatic logic [31:0] ebreak ();
--        return 32'h00100073;
--    endfunction
--
--    function automatic logic [31:0] wfi ();
--        return 32'h10500073;
--    endfunction
--
--    function automatic logic [31:0] nop ();
--        return 32'h00000013;
--    endfunction
--
--    function automatic logic [31:0] illegal ();
--        return 32'h00000000;
--    endfunction
--
-+  localparam logic [3:0] DbgVersion013 = 4'h2;
-+  // size of program buffer in junks of 32-bit words
-+  localparam logic [4:0] ProgBufSize   = 5'h8;
-+
-+  // amount of data count registers implemented
-+  localparam logic [3:0] DataCount     = 4'h2;
-+
-+  // address to which a hart should jump when it was requested to halt
-+  localparam logic [63:0] HaltAddress = 64'h800;
-+  localparam logic [63:0] ResumeAddress = HaltAddress + 4;
-+  localparam logic [63:0] ExceptionAddress = HaltAddress + 8;
-+
-+  // address where data0-15 is shadowed or if shadowed in a CSR
-+  // address of the first CSR used for shadowing the data
-+  localparam logic [11:0] DataAddr = 12'h380; // we are aligned with Rocket here
-+
-+  // debug registers
-+  typedef enum logic [7:0] {
-+    Data0        = 8'h04,
-+    Data1        = 8'h05,
-+    Data2        = 8'h06,
-+    Data3        = 8'h07,
-+    Data4        = 8'h08,
-+    Data5        = 8'h09,
-+    Data6        = 8'h0A,
-+    Data7        = 8'h0B,
-+    Data8        = 8'h0C,
-+    Data9        = 8'h0D,
-+    Data10       = 8'h0E,
-+    Data11       = 8'h0F,
-+    DMControl    = 8'h10,
-+    DMStatus     = 8'h11, // r/o
-+    Hartinfo     = 8'h12,
-+    HaltSum1     = 8'h13,
-+    HAWindowSel  = 8'h14,
-+    HAWindow     = 8'h15,
-+    AbstractCS   = 8'h16,
-+    Command      = 8'h17,
-+    AbstractAuto = 8'h18,
-+    DevTreeAddr0 = 8'h19,
-+    DevTreeAddr1 = 8'h1A,
-+    DevTreeAddr2 = 8'h1B,
-+    DevTreeAddr3 = 8'h1C,
-+    NextDM       = 8'h1D,
-+    ProgBuf0     = 8'h20,
-+    ProgBuf15    = 8'h2F,
-+    AuthData     = 8'h30,
-+    HaltSum2     = 8'h34,
-+    HaltSum3     = 8'h35,
-+    SBAddress3   = 8'h37,
-+    SBCS         = 8'h38,
-+    SBAddress0   = 8'h39,
-+    SBAddress1   = 8'h3A,
-+    SBAddress2   = 8'h3B,
-+    SBData0      = 8'h3C,
-+    SBData1      = 8'h3D,
-+    SBData2      = 8'h3E,
-+    SBData3      = 8'h3F,
-+    HaltSum0     = 8'h40
-+  } dm_csr_e;
-+
-+  // debug causes
-+  localparam logic [2:0] CauseBreakpoint = 3'h1;
-+  localparam logic [2:0] CauseTrigger    = 3'h2;
-+  localparam logic [2:0] CauseRequest    = 3'h3;
-+  localparam logic [2:0] CauseSingleStep = 3'h4;
-+
-+  typedef struct packed {
-+    logic [31:23] zero1;
-+    logic         impebreak;
-+    logic [21:20] zero0;
-+    logic         allhavereset;
-+    logic         anyhavereset;
-+    logic         allresumeack;
-+    logic         anyresumeack;
-+    logic         allnonexistent;
-+    logic         anynonexistent;
-+    logic         allunavail;
-+    logic         anyunavail;
-+    logic         allrunning;
-+    logic         anyrunning;
-+    logic         allhalted;
-+    logic         anyhalted;
-+    logic         authenticated;
-+    logic         authbusy;
-+    logic         hasresethaltreq;
-+    logic         devtreevalid;
-+    logic [3:0]   version;
-+  } dmstatus_t;
-+
-+  typedef struct packed {
-+    logic         haltreq;
-+    logic         resumereq;
-+    logic         hartreset;
-+    logic         ackhavereset;
-+    logic         zero1;
-+    logic         hasel;
-+    logic [25:16] hartsello;
-+    logic [15:6]  hartselhi;
-+    logic [5:4]   zero0;
-+    logic         setresethaltreq;
-+    logic         clrresethaltreq;
-+    logic         ndmreset;
-+    logic         dmactive;
-+  } dmcontrol_t;
-+
-+  typedef struct packed {
-+    logic [31:24] zero1;
-+    logic [23:20] nscratch;
-+    logic [19:17] zero0;
-+    logic         dataaccess;
-+    logic [15:12] datasize;
-+    logic [11:0]  dataaddr;
-+  } hartinfo_t;
-+
-+  typedef enum logic [2:0] {
-+    CmdErrNone, CmdErrBusy, CmdErrNotSupported,
-+    CmdErrorException, CmdErrorHaltResume,
-+    CmdErrorBus, CmdErrorOther = 7
-+  } cmderr_e;
-+
-+  typedef struct packed {
-+    logic [31:29] zero3;
-+    logic [28:24] progbufsize;
-+    logic [23:13] zero2;
-+    logic         busy;
-+    logic         zero1;
-+    cmderr_e      cmderr;
-+    logic [7:4]   zero0;
-+    logic [3:0]   datacount;
-+  } abstractcs_t;
-+
-+  typedef enum logic [7:0] {
-+    AccessRegister = 8'h0,
-+    QuickAccess    = 8'h1,
-+    AccessMemory   = 8'h2
-+  } cmd_e;
-+
-+  typedef struct packed {
-+    cmd_e        cmdtype;
-+    logic [23:0] control;
-+  } command_t;
-+
-+  typedef struct packed {
-+    logic [31:16] autoexecprogbuf;
-+    logic [15:12] zero0;
-+    logic [11:0]  autoexecdata;
-+  } abstractauto_t;
-+
-+  typedef struct packed {
-+    logic         zero1;
-+    logic [22:20] aarsize;
-+    logic         aarpostincrement;
-+    logic         postexec;
-+    logic         transfer;
-+    logic         write;
-+    logic [15:0]  regno;
-+  } ac_ar_cmd_t;
-+
-+  // DTM
-+  typedef enum logic [1:0] {
-+    DTM_NOP   = 2'h0,
-+    DTM_READ  = 2'h1,
-+    DTM_WRITE = 2'h2
-+  } dtm_op_e;
-+
-+  typedef struct packed {
-+    logic [31:29] sbversion;
-+    logic [28:23] zero0;
-+    logic         sbbusyerror;
-+    logic         sbbusy;
-+    logic         sbreadonaddr;
-+    logic [19:17] sbaccess;
-+    logic         sbautoincrement;
-+    logic         sbreadondata;
-+    logic [14:12] sberror;
-+    logic [11:5]  sbasize;
-+    logic         sbaccess128;
-+    logic         sbaccess64;
-+    logic         sbaccess32;
-+    logic         sbaccess16;
-+    logic         sbaccess8;
-+  } sbcs_t;
-+
-+  localparam logic[1:0] DTM_SUCCESS = 2'h0;
-+
-+  typedef struct packed {
-+    logic [6:0]  addr;
-+    dtm_op_e     op;
-+    logic [31:0] data;
-+  } dmi_req_t;
-+
-+  typedef struct packed  {
-+    logic [31:0] data;
-+    logic [1:0]  resp;
-+  } dmi_resp_t;
-+
-+  // privilege levels
-+  typedef enum logic[1:0] {
-+    PRIV_LVL_M = 2'b11,
-+    PRIV_LVL_S = 2'b01,
-+    PRIV_LVL_U = 2'b00
-+  } priv_lvl_t;
-+
-+  // debugregs in core
-+  typedef struct packed {
-+    logic [31:28]     xdebugver;
-+    logic [27:16]     zero2;
-+    logic             ebreakm;
-+    logic             zero1;
-+    logic             ebreaks;
-+    logic             ebreaku;
-+    logic             stepie;
-+    logic             stopcount;
-+    logic             stoptime;
-+    logic [8:6]       cause;
-+    logic             zero0;
-+    logic             mprven;
-+    logic             nmip;
-+    logic             step;
-+    priv_lvl_t        prv;
-+  } dcsr_t;
-+
-+  // CSRs
-+  typedef enum logic [11:0] {
-+    // Floating-Point CSRs
-+    CSR_FFLAGS         = 12'h001,
-+    CSR_FRM            = 12'h002,
-+    CSR_FCSR           = 12'h003,
-+    CSR_FTRAN          = 12'h800,
-+    // Supervisor Mode CSRs
-+    CSR_SSTATUS        = 12'h100,
-+    CSR_SIE            = 12'h104,
-+    CSR_STVEC          = 12'h105,
-+    CSR_SCOUNTEREN     = 12'h106,
-+    CSR_SSCRATCH       = 12'h140,
-+    CSR_SEPC           = 12'h141,
-+    CSR_SCAUSE         = 12'h142,
-+    CSR_STVAL          = 12'h143,
-+    CSR_SIP            = 12'h144,
-+    CSR_SATP           = 12'h180,
-+    // Machine Mode CSRs
-+    CSR_MSTATUS        = 12'h300,
-+    CSR_MISA           = 12'h301,
-+    CSR_MEDELEG        = 12'h302,
-+    CSR_MIDELEG        = 12'h303,
-+    CSR_MIE            = 12'h304,
-+    CSR_MTVEC          = 12'h305,
-+    CSR_MCOUNTEREN     = 12'h306,
-+    CSR_MSCRATCH       = 12'h340,
-+    CSR_MEPC           = 12'h341,
-+    CSR_MCAUSE         = 12'h342,
-+    CSR_MTVAL          = 12'h343,
-+    CSR_MIP            = 12'h344,
-+    CSR_PMPCFG0        = 12'h3A0,
-+    CSR_PMPADDR0       = 12'h3B0,
-+    CSR_MVENDORID      = 12'hF11,
-+    CSR_MARCHID        = 12'hF12,
-+    CSR_MIMPID         = 12'hF13,
-+    CSR_MHARTID        = 12'hF14,
-+    CSR_MCYCLE         = 12'hB00,
-+    CSR_MINSTRET       = 12'hB02,
-+    CSR_DCACHE         = 12'h701,
-+    CSR_ICACHE         = 12'h700,
-+
-+    CSR_TSELECT        = 12'h7A0,
-+    CSR_TDATA1         = 12'h7A1,
-+    CSR_TDATA2         = 12'h7A2,
-+    CSR_TDATA3         = 12'h7A3,
-+    CSR_TINFO          = 12'h7A4,
-+
-+    // Debug CSR
-+    CSR_DCSR           = 12'h7b0,
-+    CSR_DPC            = 12'h7b1,
-+    CSR_DSCRATCH0      = 12'h7b2, // optional
-+    CSR_DSCRATCH1      = 12'h7b3, // optional
-+
-+    // Counters and Timers
-+    CSR_CYCLE          = 12'hC00,
-+    CSR_TIME           = 12'hC01,
-+    CSR_INSTRET        = 12'hC02
-+  } csr_reg_t;
-+
-+
-+  // Instruction Generation Helpers
-+  function automatic logic [31:0] jal (logic[4:0] rd, logic [20:0] imm);
-+    // OpCode Jal
-+    return {imm[20], imm[10:1], imm[11], imm[19:12], rd, 7'h6f};
-+  endfunction
-+
-+  function automatic logic [31:0] jalr (logic[4:0] rd, logic[4:0] rs1, logic [11:0] offset);
-+    // OpCode Jal
-+    return {offset[11:0], rs1, 3'b0, rd, 7'h67};
-+  endfunction
-+
-+  function automatic logic [31:0] andi (logic[4:0] rd, logic[4:0] rs1, logic [11:0] imm);
-+    // OpCode andi
-+    return {imm[11:0], rs1, 3'h7, rd, 7'h13};
-+  endfunction
-+
-+  function automatic logic [31:0] slli (logic[4:0] rd, logic[4:0] rs1, logic [5:0] shamt);
-+    // OpCode slli
-+    return {6'b0, shamt[5:0], rs1, 3'h1, rd, 7'h13};
-+  endfunction
-+
-+  function automatic logic [31:0] srli (logic[4:0] rd, logic[4:0] rs1, logic [5:0] shamt);
-+    // OpCode srli
-+    return {6'b0, shamt[5:0], rs1, 3'h5, rd, 7'h13};
-+  endfunction
-+
-+  function automatic logic [31:0] load (logic [2:0] size, logic[4:0] dest, logic[4:0] base, logic [11:0] offset);
-+    // OpCode Load
-+    return {offset[11:0], base, size, dest, 7'h03};
-+  endfunction
-+
-+  function automatic logic [31:0] auipc (logic[4:0] rd, logic [20:0] imm);
-+    // OpCode Auipc
-+    return {imm[20], imm[10:1], imm[11], imm[19:12], rd, 7'h17};
-+  endfunction
-+
-+  function automatic logic [31:0] store (logic [2:0] size, logic[4:0] src, logic[4:0] base, logic [11:0] offset);
-+    // OpCode Store
-+    return {offset[11:5], src, base, size, offset[4:0], 7'h23};
-+  endfunction
-+
-+  function automatic logic [31:0] float_load (logic [2:0] size, logic[4:0] dest, logic[4:0] base, logic [11:0] offset);
-+    // OpCode Load
-+    return {offset[11:0], base, size, dest, 7'b00_001_11};
-+  endfunction
-+
-+  function automatic logic [31:0] float_store (logic [2:0] size, logic[4:0] src, logic[4:0] base, logic [11:0] offset);
-+    // OpCode Store
-+    return {offset[11:5], src, base, size, offset[4:0], 7'b01_001_11};
-+  endfunction
-+
-+  function automatic logic [31:0] csrw (csr_reg_t csr, logic[4:0] rs1);
-+    // CSRRW, rd, OpCode System
-+    return {csr, rs1, 3'h1, 5'h0, 7'h73};
-+  endfunction
-+
-+  function automatic logic [31:0] csrr (csr_reg_t csr, logic [4:0] dest);
-+    // rs1, CSRRS, rd, OpCode System
-+    return {csr, 5'h0, 3'h2, dest, 7'h73};
-+  endfunction
-+
-+  function automatic logic [31:0] branch(logic [4:0] src2, logic [4:0] src1, logic [2:0] funct3, logic [11:0] offset);
-+    // OpCode Branch
-+    return {offset[11], offset[9:4], src2, src1, funct3, offset[3:0], offset[10], 7'b11_000_11};
-+  endfunction
-+
-+  function automatic logic [31:0] ebreak ();
-+    return 32'h00100073;
-+  endfunction
-+
-+  function automatic logic [31:0] wfi ();
-+    return 32'h10500073;
-+  endfunction
-+
-+  function automatic logic [31:0] nop ();
-+    return 32'h00000013;
-+  endfunction
-+
-+  function automatic logic [31:0] illegal ();
-+    return 32'h00000000;
-+  endfunction
- 
- endpackage
-diff --git a/src/dm_sba.sv b/src/dm_sba.sv
-index f85aa75..fa9d401 100644
---- a/src/dm_sba.sv
-+++ b/src/dm_sba.sv
-@@ -1,173 +1,172 @@
- /* Copyright 2018 ETH Zurich and University of Bologna.
-- * Copyright and related rights are licensed under the Solderpad Hardware
-- * License, Version 0.51 (the “License”); you may not use this file except in
-- * compliance with the License.  You may obtain a copy of the License at
-- * http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-- * or agreed to in writing, software, hardware and materials distributed under
-- * this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
-- * CONDITIONS OF ANY KIND, either express or implied. See the License for the
-- * specific language governing permissions and limitations under the License.
-- *
-- * File:   dm_sba.sv
-- * Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-- * Date:   1.8.2018
-- *
-- * Description: System Bus Access Module
-- *
-- */
-+* Copyright and related rights are licensed under the Solderpad Hardware
-+* License, Version 0.51 (the “License”); you may not use this file except in
-+* compliance with the License.  You may obtain a copy of the License at
-+* http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-+* or agreed to in writing, software, hardware and materials distributed under
-+* this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
-+* CONDITIONS OF ANY KIND, either express or implied. See the License for the
-+* specific language governing permissions and limitations under the License.
-+*
-+* File:   dm_sba.sv
-+* Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-+* Date:   1.8.2018
-+*
-+* Description: System Bus Access Module
-+*
-+*/
- module dm_sba #(
--    parameter int BusWidth = -1
-+  parameter int BusWidth = -1
- ) (
--    input  logic                   clk_i,       // Clock
--    input  logic                   rst_ni,
--    input  logic                   dmactive_i,  // synchronous reset active low
--
--    output logic                   master_req_o,
--    output logic [BusWidth-1:0]    master_add_o,
--    output logic                   master_we_o,
--    output logic [BusWidth-1:0]    master_wdata_o,
--    output logic [BusWidth/8-1:0]  master_be_o,
--    input  logic                   master_gnt_i,
--    input  logic                   master_r_valid_i,
--    input  logic [BusWidth-1:0]    master_r_rdata_i,
--
--    input  logic [BusWidth-1:0]    sbaddress_i,
--    input  logic                   sbaddress_write_valid_i,
--    // control signals in
--    input  logic                   sbreadonaddr_i,
--    output logic [BusWidth-1:0]    sbaddress_o,
--    input  logic                   sbautoincrement_i,
--    input  logic [2:0]             sbaccess_i,
--    // data in
--    input  logic                   sbreadondata_i,
--    input  logic [BusWidth-1:0]    sbdata_i,
--    input  logic                   sbdata_read_valid_i,
--    input  logic                   sbdata_write_valid_i,
--    // read data out
--    output logic [BusWidth-1:0]    sbdata_o,
--    output logic                   sbdata_valid_o,
--    // control signals
--    output logic                   sbbusy_o,
--    output logic                   sberror_valid_o, // bus error occurred
--    output logic [2:0]             sberror_o // bus error occurred
-+  input  logic                   clk_i,       // Clock
-+  input  logic                   rst_ni,
-+  input  logic                   dmactive_i,  // synchronous reset active low
-+
-+  output logic                   master_req_o,
-+  output logic [BusWidth-1:0]    master_add_o,
-+  output logic                   master_we_o,
-+  output logic [BusWidth-1:0]    master_wdata_o,
-+  output logic [BusWidth/8-1:0]  master_be_o,
-+  input  logic                   master_gnt_i,
-+  input  logic                   master_r_valid_i,
-+  input  logic [BusWidth-1:0]    master_r_rdata_i,
-+
-+  input  logic [BusWidth-1:0]    sbaddress_i,
-+  input  logic                   sbaddress_write_valid_i,
-+  // control signals in
-+  input  logic                   sbreadonaddr_i,
-+  output logic [BusWidth-1:0]    sbaddress_o,
-+  input  logic                   sbautoincrement_i,
-+  input  logic [2:0]             sbaccess_i,
-+  // data in
-+  input  logic                   sbreadondata_i,
-+  input  logic [BusWidth-1:0]    sbdata_i,
-+  input  logic                   sbdata_read_valid_i,
-+  input  logic                   sbdata_write_valid_i,
-+  // read data out
-+  output logic [BusWidth-1:0]    sbdata_o,
-+  output logic                   sbdata_valid_o,
-+  // control signals
-+  output logic                   sbbusy_o,
-+  output logic                   sberror_valid_o, // bus error occurred
-+  output logic [2:0]             sberror_o // bus error occurred
- );
- 
--    typedef enum logic [2:0] { Idle, Read, Write, WaitRead, WaitWrite } state_e;
--    state_e state_d, state_q;
--
--    logic [BusWidth-1:0]   address;
--    logic                  req;
--    logic                  gnt;
--    logic                  we;
--    logic [BusWidth/8-1:0] be;
--
--    assign sbbusy_o = (state_q != Idle) ? 1'b1 : 1'b0;
--
--    always_comb begin
--        req     = 1'b0;
--        address = sbaddress_i;
--        we      = 1'b0;
--        be      = '0;
--
--        sberror_o       = '0;
--        sberror_valid_o = 1'b0;
--        sbaddress_o     = sbaddress_i;
--
--        state_d = state_q;
--
--        case (state_q)
--            Idle: begin
--                // debugger requested a read
--                if (sbaddress_write_valid_i && sbreadonaddr_i)  state_d = Read;
--                // debugger requested a write
--                if (sbdata_write_valid_i) state_d = Write;
--                // perform another read
--                if (sbdata_read_valid_i && sbreadondata_i) state_d = Read;
--            end
--
--            Read: begin
--                req = 1'b1;
--                if (gnt) state_d = WaitRead;
--            end
--
--            Write: begin
--                req = 1'b1;
--                we  = 1'b1;
--                // generate byte enable mask
--                case (sbaccess_i)
--                    3'b000: begin
--                        if (BusWidth == 64) be[ sbaddress_i[2:0]] = '1;
--                        else                be[ sbaddress_i[1:0]] = '1;
--                    end
--                    3'b001: begin
--                        if (BusWidth == 64) be[{sbaddress_i[2:1], 1'b0} +: 2] = '1;
--                        else                be[{sbaddress_i[1:1], 1'b0} +: 2] = '1;
--                    end
--                    3'b010: begin
--                        if (BusWidth == 64) be[{sbaddress_i[2:2], 2'b0} +: 4] = '1;
--                        else                be = '1;
--                    end
--                    3'b011: be = '1;
--                    default:;
--                endcase
--                if (gnt) state_d = WaitWrite;
--            end
--
--            WaitRead: begin
--                if (sbdata_valid_o) begin
--                    state_d = Idle;
--                    // auto-increment address
--                    if (sbautoincrement_i) sbaddress_o = sbaddress_i + (1'b1 << sbaccess_i);
--                end
--            end
--
--            WaitWrite: begin
--                if (sbdata_valid_o) begin
--                    state_d = Idle;
--                    // auto-increment address
--                    if (sbautoincrement_i) sbaddress_o = sbaddress_i + (1'b1 << sbaccess_i);
--                end
--            end
--
--            default:;
-+  typedef enum logic [2:0] { Idle, Read, Write, WaitRead, WaitWrite } state_e;
-+  state_e state_d, state_q;
-+
-+  logic [BusWidth-1:0]   address;
-+  logic                  req;
-+  logic                  gnt;
-+  logic                  we;
-+  logic [BusWidth/8-1:0] be;
-+
-+  assign sbbusy_o = (state_q != Idle) ? 1'b1 : 1'b0;
-+
-+  always_comb begin
-+    req     = 1'b0;
-+    address = sbaddress_i;
-+    we      = 1'b0;
-+    be      = '0;
-+
-+    sberror_o       = '0;
-+    sberror_valid_o = 1'b0;
-+    sbaddress_o     = sbaddress_i;
-+
-+    state_d = state_q;
-+
-+    case (state_q)
-+      Idle: begin
-+        // debugger requested a read
-+        if (sbaddress_write_valid_i && sbreadonaddr_i)  state_d = Read;
-+        // debugger requested a write
-+        if (sbdata_write_valid_i) state_d = Write;
-+        // perform another read
-+        if (sbdata_read_valid_i && sbreadondata_i) state_d = Read;
-+      end
-+
-+      Read: begin
-+        req = 1'b1;
-+        if (gnt) state_d = WaitRead;
-+      end
-+
-+      Write: begin
-+        req = 1'b1;
-+        we  = 1'b1;
-+        // generate byte enable mask
-+        case (sbaccess_i)
-+          3'b000: begin
-+            if (BusWidth == 64) be[ sbaddress_i[2:0]] = '1;
-+            else                be[ sbaddress_i[1:0]] = '1;
-+          end
-+          3'b001: begin
-+            if (BusWidth == 64) be[{sbaddress_i[2:1], 1'b0} +: 2] = '1;
-+            else                be[{sbaddress_i[1:1], 1'b0} +: 2] = '1;
-+          end
-+          3'b010: begin
-+            if (BusWidth == 64) be[{sbaddress_i[2:2], 2'b0} +: 4] = '1;
-+            else                be = '1;
-+          end
-+          3'b011: be = '1;
-+          default:;
-         endcase
--
--        // handle error case
--        if (sbaccess_i > 3 && state_q != Idle) begin
--            req             = 1'b0;
--            state_d         = Idle;
--            sberror_valid_o = 1'b1;
--            sberror_o       = 3'd3;
-+        if (gnt) state_d = WaitWrite;
-+      end
-+
-+      WaitRead: begin
-+        if (sbdata_valid_o) begin
-+          state_d = Idle;
-+          // auto-increment address
-+          if (sbautoincrement_i) sbaddress_o = sbaddress_i + (1'b1 << sbaccess_i);
-         end
--        // further error handling should go here ...
--    end
-+      end
- 
--    always_ff @(posedge clk_i or negedge rst_ni) begin
--        if (!rst_ni) begin
--            state_q <= Idle;
--        end else begin
--            state_q <= state_d;
-+      WaitWrite: begin
-+        if (sbdata_valid_o) begin
-+          state_d = Idle;
-+          // auto-increment address
-+          if (sbautoincrement_i) sbaddress_o = sbaddress_i + (1'b1 << sbaccess_i);
-         end
--    end
-+      end
- 
--    assign master_req_o    = req;
--    assign master_add_o    = address[BusWidth-1:0];
--    assign master_we_o     = we;
--    assign master_wdata_o  = sbdata_i[BusWidth-1:0];
--    assign master_be_o     = be[BusWidth/8-1:0];
--    assign gnt             = master_gnt_i;
--    assign sbdata_valid_o  = master_r_valid_i;
--    assign sbdata_o        = master_r_rdata_i[BusWidth-1:0];
--
--
--    //pragma translate_off
--    `ifndef VERILATOR
--        // maybe bump severity to $error if not handled at runtime
--        dm_sba_access_size: assert property(@(posedge clk_i) disable iff (dmactive_i !== 1'b0)
--            (state_d != Idle) |-> (sbaccess_i < 4))
--        else
--            $warning ("accesses > 8 byte not supported at the moment");
--    `endif
--    //pragma translate_on
-+      default:;
-+    endcase
-+
-+    // handle error case
-+    if (sbaccess_i > 3 && state_q != Idle) begin
-+      req             = 1'b0;
-+      state_d         = Idle;
-+      sberror_valid_o = 1'b1;
-+      sberror_o       = 3'd3;
-+    end
-+    // further error handling should go here ...
-+  end
-+
-+  always_ff @(posedge clk_i or negedge rst_ni) begin
-+    if (!rst_ni) begin
-+      state_q <= Idle;
-+    end else begin
-+      state_q <= state_d;
-+    end
-+  end
-+
-+  assign master_req_o    = req;
-+  assign master_add_o    = address[BusWidth-1:0];
-+  assign master_we_o     = we;
-+  assign master_wdata_o  = sbdata_i[BusWidth-1:0];
-+  assign master_be_o     = be[BusWidth/8-1:0];
-+  assign gnt             = master_gnt_i;
-+  assign sbdata_valid_o  = master_r_valid_i;
-+  assign sbdata_o        = master_r_rdata_i[BusWidth-1:0];
-+
-+
-+  //pragma translate_off
-+  `ifndef VERILATOR
-+    // maybe bump severity to $error if not handled at runtime
-+    dm_sba_access_size: assert property(@(posedge clk_i) disable iff (dmactive_i !== 1'b0)
-+        (state_d != Idle) |-> (sbaccess_i < 4))
-+            else $warning ("accesses > 8 byte not supported at the moment");
-+  `endif
-+  //pragma translate_on
- 
- endmodule
-diff --git a/src/dm_top.sv b/src/dm_top.sv
-index ad20535..03ac112 100644
---- a/src/dm_top.sv
-+++ b/src/dm_top.sv
-@@ -1,222 +1,222 @@
- /* Copyright 2018 ETH Zurich and University of Bologna.
-- * Copyright and related rights are licensed under the Solderpad Hardware
-- * License, Version 0.51 (the “License”); you may not use this file except in
-- * compliance with the License.  You may obtain a copy of the License at
-- * http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-- * or agreed to in writing, software, hardware and materials distributed under
-- * this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
-- * CONDITIONS OF ANY KIND, either express or implied. See the License for the
-- * specific language governing permissions and limitations under the License.
-- *
-- * File:   dm_top.sv
-- * Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-- * Date:   30.6.2018
-- *
-- * Description: Top-level of debug module (DM). This is an AXI-Slave.
-- *              DTM protocol is equal to SiFives debug protocol to leverage
-- *              SW infrastructure re-use. As of version 0.13
-- */
-+* Copyright and related rights are licensed under the Solderpad Hardware
-+* License, Version 0.51 (the “License”); you may not use this file except in
-+* compliance with the License.  You may obtain a copy of the License at
-+* http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-+* or agreed to in writing, software, hardware and materials distributed under
-+* this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
-+* CONDITIONS OF ANY KIND, either express or implied. See the License for the
-+* specific language governing permissions and limitations under the License.
-+*
-+* File:   dm_top.sv
-+* Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-+* Date:   30.6.2018
-+*
-+* Description: Top-level of debug module (DM). This is an AXI-Slave.
-+*              DTM protocol is equal to SiFives debug protocol to leverage
-+*              SW infrastructure re-use. As of version 0.13
-+*/
- 
- module dm_top #(
--    parameter int                 NrHarts          = 1,
--    parameter int                 BusWidth         = 32,
--    parameter logic [NrHarts-1:0] SelectableHarts  = 1  // Bitmask to select physically available harts for systems
--                                                        // that don't use hart numbers in a contiguous fashion.
-+  parameter int                 NrHarts          = 1,
-+  parameter int                 BusWidth         = 32,
-+  parameter logic [NrHarts-1:0] SelectableHarts  = 1  // Bitmask to select physically available harts for systems
-+                                                      // that don't use hart numbers in a contiguous fashion.
- 
- ) (
--    input  logic                  clk_i,       // clock
--    input  logic                  rst_ni,      // asynchronous reset active low, connect PoR here, not the system reset
--    input  logic                  testmode_i,
--    output logic                  ndmreset_o,  // non-debug module reset
--    output logic                  dmactive_o,  // debug module is active
--    output logic [NrHarts-1:0]    debug_req_o, // async debug request
--    input  logic [NrHarts-1:0]    unavailable_i, // communicate whether the hart is unavailable (e.g.: power down)
--    dm::hartinfo_t [NrHarts-1:0]  hartinfo_i,
--
--    input  logic                  slave_req_i,
--    input  logic                  slave_we_i,
--    input  logic [BusWidth-1:0]   slave_addr_i,
--    input  logic [BusWidth/8-1:0] slave_be_i,
--    input  logic [BusWidth-1:0]   slave_wdata_i,
--    output logic [BusWidth-1:0]   slave_rdata_o,
--
--    output logic                  master_req_o,
--    output logic [BusWidth-1:0]   master_add_o,
--    output logic                  master_we_o,
--    output logic [BusWidth-1:0]   master_wdata_o,
--    output logic [BusWidth/8-1:0] master_be_o,
--    input  logic                  master_gnt_i,
--    input  logic                  master_r_valid_i,
--    input  logic [BusWidth-1:0]   master_r_rdata_i,
--
--    // Connection to DTM - compatible to RocketChip Debug Module
--    input  logic                  dmi_rst_ni,
--    input  logic                  dmi_req_valid_i,
--    output logic                  dmi_req_ready_o,
--    input  dm::dmi_req_t          dmi_req_i,
--
--    output logic                  dmi_resp_valid_o,
--    input  logic                  dmi_resp_ready_i,
--    output dm::dmi_resp_t         dmi_resp_o
-+  input  logic                  clk_i,       // clock
-+  input  logic                  rst_ni,      // asynchronous reset active low, connect PoR here, not the system reset
-+  input  logic                  testmode_i,
-+  output logic                  ndmreset_o,  // non-debug module reset
-+  output logic                  dmactive_o,  // debug module is active
-+  output logic [NrHarts-1:0]    debug_req_o, // async debug request
-+  input  logic [NrHarts-1:0]    unavailable_i, // communicate whether the hart is unavailable (e.g.: power down)
-+  dm::hartinfo_t [NrHarts-1:0]  hartinfo_i,
-+
-+  input  logic                  slave_req_i,
-+  input  logic                  slave_we_i,
-+  input  logic [BusWidth-1:0]   slave_addr_i,
-+  input  logic [BusWidth/8-1:0] slave_be_i,
-+  input  logic [BusWidth-1:0]   slave_wdata_i,
-+  output logic [BusWidth-1:0]   slave_rdata_o,
-+
-+  output logic                  master_req_o,
-+  output logic [BusWidth-1:0]   master_add_o,
-+  output logic                  master_we_o,
-+  output logic [BusWidth-1:0]   master_wdata_o,
-+  output logic [BusWidth/8-1:0] master_be_o,
-+  input  logic                  master_gnt_i,
-+  input  logic                  master_r_valid_i,
-+  input  logic [BusWidth-1:0]   master_r_rdata_i,
-+
-+  // Connection to DTM - compatible to RocketChip Debug Module
-+  input  logic                  dmi_rst_ni,
-+  input  logic                  dmi_req_valid_i,
-+  output logic                  dmi_req_ready_o,
-+  input  dm::dmi_req_t          dmi_req_i,
-+
-+  output logic                  dmi_resp_valid_o,
-+  input  logic                  dmi_resp_ready_i,
-+  output dm::dmi_resp_t         dmi_resp_o
- );
- 
--    // Debug CSRs
--    logic [NrHarts-1:0]               halted;
--    // logic [NrHarts-1:0]               running;
--    logic [NrHarts-1:0]               resumeack;
--    logic [NrHarts-1:0]               haltreq;
--    logic [NrHarts-1:0]               resumereq;
--    logic                             clear_resumeack;
--    logic                             cmd_valid;
--    dm::command_t                     cmd;
--
--    logic                             cmderror_valid;
--    dm::cmderr_e                      cmderror;
--    logic                             cmdbusy;
--    logic [dm::ProgBufSize-1:0][31:0] progbuf;
--    logic [dm::DataCount-1:0][31:0]   data_csrs_mem;
--    logic [dm::DataCount-1:0][31:0]   data_mem_csrs;
--    logic                             data_valid;
--    logic [19:0]                      hartsel;
--    // System Bus Access Module
--    logic [BusWidth-1:0]              sbaddress_csrs_sba;
--    logic [BusWidth-1:0]              sbaddress_sba_csrs;
--    logic                             sbaddress_write_valid;
--    logic                             sbreadonaddr;
--    logic                             sbautoincrement;
--    logic [2:0]                       sbaccess;
--    logic                             sbreadondata;
--    logic [BusWidth-1:0]              sbdata_write;
--    logic                             sbdata_read_valid;
--    logic                             sbdata_write_valid;
--    logic [BusWidth-1:0]              sbdata_read;
--    logic                             sbdata_valid;
--    logic                             sbbusy;
--    logic                             sberror_valid;
--    logic [2:0]                       sberror;
--
--
--    dm_csrs #(
--        .NrHarts(NrHarts),
--        .BusWidth(BusWidth),
--        .SelectableHarts(SelectableHarts)
--    ) i_dm_csrs (
--        .clk_i                   ( clk_i                 ),
--        .rst_ni                  ( rst_ni                ),
--        .testmode_i              ( testmode_i            ),
--        .dmi_rst_ni,
--        .dmi_req_valid_i,
--        .dmi_req_ready_o,
--        .dmi_req_i,
--        .dmi_resp_valid_o,
--        .dmi_resp_ready_i,
--        .dmi_resp_o,
--        .ndmreset_o              ( ndmreset_o            ),
--        .dmactive_o              ( dmactive_o            ),
--        .hartsel_o               ( hartsel               ),
--        .hartinfo_i              ( hartinfo_i            ),
--        .halted_i                ( halted                ),
--        .unavailable_i,
--        .resumeack_i             ( resumeack             ),
--        .haltreq_o               ( haltreq               ),
--        .resumereq_o             ( resumereq             ),
--        .clear_resumeack_o       ( clear_resumeack       ),
--        .cmd_valid_o             ( cmd_valid             ),
--        .cmd_o                   ( cmd                   ),
--        .cmderror_valid_i        ( cmderror_valid        ),
--        .cmderror_i              ( cmderror              ),
--        .cmdbusy_i               ( cmdbusy               ),
--        .progbuf_o               ( progbuf               ),
--        .data_i                  ( data_mem_csrs         ),
--        .data_valid_i            ( data_valid            ),
--        .data_o                  ( data_csrs_mem         ),
--        .sbaddress_o             ( sbaddress_csrs_sba    ),
--        .sbaddress_i             ( sbaddress_sba_csrs    ),
--        .sbaddress_write_valid_o ( sbaddress_write_valid ),
--        .sbreadonaddr_o          ( sbreadonaddr          ),
--        .sbautoincrement_o       ( sbautoincrement       ),
--        .sbaccess_o              ( sbaccess              ),
--        .sbreadondata_o          ( sbreadondata          ),
--        .sbdata_o                ( sbdata_write          ),
--        .sbdata_read_valid_o     ( sbdata_read_valid     ),
--        .sbdata_write_valid_o    ( sbdata_write_valid    ),
--        .sbdata_i                ( sbdata_read           ),
--        .sbdata_valid_i          ( sbdata_valid          ),
--        .sbbusy_i                ( sbbusy                ),
--        .sberror_valid_i         ( sberror_valid         ),
--        .sberror_i               ( sberror               )
--    );
--
--    dm_sba #(
--        .BusWidth(BusWidth)
--    ) i_dm_sba (
--        .clk_i                   ( clk_i                 ),
--        .rst_ni                  ( rst_ni                ),
--        .dmactive_i              ( dmactive_o            ),
--
--        .master_req_o            ( master_req_o          ),
--        .master_add_o            ( master_add_o          ),
--        .master_we_o             ( master_we_o           ),
--        .master_wdata_o          ( master_wdata_o        ),
--        .master_be_o             ( master_be_o           ),
--        .master_gnt_i            ( master_gnt_i          ),
--        .master_r_valid_i        ( master_r_valid_i      ),
--        .master_r_rdata_i        ( master_r_rdata_i      ),
--
--        .sbaddress_i             ( sbaddress_csrs_sba    ),
--        .sbaddress_o             ( sbaddress_sba_csrs    ),
--        .sbaddress_write_valid_i ( sbaddress_write_valid ),
--        .sbreadonaddr_i          ( sbreadonaddr          ),
--        .sbautoincrement_i       ( sbautoincrement       ),
--        .sbaccess_i              ( sbaccess              ),
--        .sbreadondata_i          ( sbreadondata          ),
--        .sbdata_i                ( sbdata_write          ),
--        .sbdata_read_valid_i     ( sbdata_read_valid     ),
--        .sbdata_write_valid_i    ( sbdata_write_valid    ),
--        .sbdata_o                ( sbdata_read           ),
--        .sbdata_valid_o          ( sbdata_valid          ),
--        .sbbusy_o                ( sbbusy                ),
--        .sberror_valid_o         ( sberror_valid         ),
--        .sberror_o               ( sberror               )
--    );
--
--    dm_mem #(
--        .NrHarts(NrHarts),
--        .BusWidth(BusWidth),
--        .SelectableHarts(SelectableHarts)
--    ) i_dm_mem (
--        .clk_i                   ( clk_i                 ),
--        .rst_ni                  ( rst_ni                ),
--        .debug_req_o             ( debug_req_o           ),
--        .hartsel_i               ( hartsel               ),
--        .haltreq_i               ( haltreq               ),
--        .resumereq_i             ( resumereq             ),
--        .clear_resumeack_i       ( clear_resumeack       ),
--        .halted_o                ( halted                ),
--        .resuming_o              ( resumeack             ),
--        .cmd_valid_i             ( cmd_valid             ),
--        .cmd_i                   ( cmd                   ),
--        .cmderror_valid_o        ( cmderror_valid        ),
--        .cmderror_o              ( cmderror              ),
--        .cmdbusy_o               ( cmdbusy               ),
--        .progbuf_i               ( progbuf               ),
--        .data_i                  ( data_csrs_mem         ),
--        .data_o                  ( data_mem_csrs         ),
--        .data_valid_o            ( data_valid            ),
--        .req_i                   ( slave_req_i           ),
--        .we_i                    ( slave_we_i            ),
--        .addr_i                  ( slave_addr_i          ),
--        .wdata_i                 ( slave_wdata_i         ),
--        .be_i                    ( slave_be_i            ),
--        .rdata_o                 ( slave_rdata_o         )
--    );
-+  // Debug CSRs
-+  logic [NrHarts-1:0]               halted;
-+  // logic [NrHarts-1:0]               running;
-+  logic [NrHarts-1:0]               resumeack;
-+  logic [NrHarts-1:0]               haltreq;
-+  logic [NrHarts-1:0]               resumereq;
-+  logic                             clear_resumeack;
-+  logic                             cmd_valid;
-+  dm::command_t                     cmd;
-+
-+  logic                             cmderror_valid;
-+  dm::cmderr_e                      cmderror;
-+  logic                             cmdbusy;
-+  logic [dm::ProgBufSize-1:0][31:0] progbuf;
-+  logic [dm::DataCount-1:0][31:0]   data_csrs_mem;
-+  logic [dm::DataCount-1:0][31:0]   data_mem_csrs;
-+  logic                             data_valid;
-+  logic [19:0]                      hartsel;
-+  // System Bus Access Module
-+  logic [BusWidth-1:0]              sbaddress_csrs_sba;
-+  logic [BusWidth-1:0]              sbaddress_sba_csrs;
-+  logic                             sbaddress_write_valid;
-+  logic                             sbreadonaddr;
-+  logic                             sbautoincrement;
-+  logic [2:0]                       sbaccess;
-+  logic                             sbreadondata;
-+  logic [BusWidth-1:0]              sbdata_write;
-+  logic                             sbdata_read_valid;
-+  logic                             sbdata_write_valid;
-+  logic [BusWidth-1:0]              sbdata_read;
-+  logic                             sbdata_valid;
-+  logic                             sbbusy;
-+  logic                             sberror_valid;
-+  logic [2:0]                       sberror;
-+
-+
-+  dm_csrs #(
-+    .NrHarts(NrHarts),
-+    .BusWidth(BusWidth),
-+    .SelectableHarts(SelectableHarts)
-+  ) i_dm_csrs (
-+    .clk_i                   ( clk_i                 ),
-+    .rst_ni                  ( rst_ni                ),
-+    .testmode_i              ( testmode_i            ),
-+    .dmi_rst_ni,
-+    .dmi_req_valid_i,
-+    .dmi_req_ready_o,
-+    .dmi_req_i,
-+    .dmi_resp_valid_o,
-+    .dmi_resp_ready_i,
-+    .dmi_resp_o,
-+    .ndmreset_o              ( ndmreset_o            ),
-+    .dmactive_o              ( dmactive_o            ),
-+    .hartsel_o               ( hartsel               ),
-+    .hartinfo_i              ( hartinfo_i            ),
-+    .halted_i                ( halted                ),
-+    .unavailable_i,
-+    .resumeack_i             ( resumeack             ),
-+    .haltreq_o               ( haltreq               ),
-+    .resumereq_o             ( resumereq             ),
-+    .clear_resumeack_o       ( clear_resumeack       ),
-+    .cmd_valid_o             ( cmd_valid             ),
-+    .cmd_o                   ( cmd                   ),
-+    .cmderror_valid_i        ( cmderror_valid        ),
-+    .cmderror_i              ( cmderror              ),
-+    .cmdbusy_i               ( cmdbusy               ),
-+    .progbuf_o               ( progbuf               ),
-+    .data_i                  ( data_mem_csrs         ),
-+    .data_valid_i            ( data_valid            ),
-+    .data_o                  ( data_csrs_mem         ),
-+    .sbaddress_o             ( sbaddress_csrs_sba    ),
-+    .sbaddress_i             ( sbaddress_sba_csrs    ),
-+    .sbaddress_write_valid_o ( sbaddress_write_valid ),
-+    .sbreadonaddr_o          ( sbreadonaddr          ),
-+    .sbautoincrement_o       ( sbautoincrement       ),
-+    .sbaccess_o              ( sbaccess              ),
-+    .sbreadondata_o          ( sbreadondata          ),
-+    .sbdata_o                ( sbdata_write          ),
-+    .sbdata_read_valid_o     ( sbdata_read_valid     ),
-+    .sbdata_write_valid_o    ( sbdata_write_valid    ),
-+    .sbdata_i                ( sbdata_read           ),
-+    .sbdata_valid_i          ( sbdata_valid          ),
-+    .sbbusy_i                ( sbbusy                ),
-+    .sberror_valid_i         ( sberror_valid         ),
-+    .sberror_i               ( sberror               )
-+  );
-+
-+  dm_sba #(
-+    .BusWidth(BusWidth)
-+  ) i_dm_sba (
-+    .clk_i                   ( clk_i                 ),
-+    .rst_ni                  ( rst_ni                ),
-+    .dmactive_i              ( dmactive_o            ),
-+
-+    .master_req_o            ( master_req_o          ),
-+    .master_add_o            ( master_add_o          ),
-+    .master_we_o             ( master_we_o           ),
-+    .master_wdata_o          ( master_wdata_o        ),
-+    .master_be_o             ( master_be_o           ),
-+    .master_gnt_i            ( master_gnt_i          ),
-+    .master_r_valid_i        ( master_r_valid_i      ),
-+    .master_r_rdata_i        ( master_r_rdata_i      ),
-+
-+    .sbaddress_i             ( sbaddress_csrs_sba    ),
-+    .sbaddress_o             ( sbaddress_sba_csrs    ),
-+    .sbaddress_write_valid_i ( sbaddress_write_valid ),
-+    .sbreadonaddr_i          ( sbreadonaddr          ),
-+    .sbautoincrement_i       ( sbautoincrement       ),
-+    .sbaccess_i              ( sbaccess              ),
-+    .sbreadondata_i          ( sbreadondata          ),
-+    .sbdata_i                ( sbdata_write          ),
-+    .sbdata_read_valid_i     ( sbdata_read_valid     ),
-+    .sbdata_write_valid_i    ( sbdata_write_valid    ),
-+    .sbdata_o                ( sbdata_read           ),
-+    .sbdata_valid_o          ( sbdata_valid          ),
-+    .sbbusy_o                ( sbbusy                ),
-+    .sberror_valid_o         ( sberror_valid         ),
-+    .sberror_o               ( sberror               )
-+  );
-+
-+  dm_mem #(
-+    .NrHarts(NrHarts),
-+    .BusWidth(BusWidth),
-+    .SelectableHarts(SelectableHarts)
-+  ) i_dm_mem (
-+    .clk_i                   ( clk_i                 ),
-+    .rst_ni                  ( rst_ni                ),
-+    .debug_req_o             ( debug_req_o           ),
-+    .hartsel_i               ( hartsel               ),
-+    .haltreq_i               ( haltreq               ),
-+    .resumereq_i             ( resumereq             ),
-+    .clear_resumeack_i       ( clear_resumeack       ),
-+    .halted_o                ( halted                ),
-+    .resuming_o              ( resumeack             ),
-+    .cmd_valid_i             ( cmd_valid             ),
-+    .cmd_i                   ( cmd                   ),
-+    .cmderror_valid_o        ( cmderror_valid        ),
-+    .cmderror_o              ( cmderror              ),
-+    .cmdbusy_o               ( cmdbusy               ),
-+    .progbuf_i               ( progbuf               ),
-+    .data_i                  ( data_csrs_mem         ),
-+    .data_o                  ( data_mem_csrs         ),
-+    .data_valid_o            ( data_valid            ),
-+    .req_i                   ( slave_req_i           ),
-+    .we_i                    ( slave_we_i            ),
-+    .addr_i                  ( slave_addr_i          ),
-+    .wdata_i                 ( slave_wdata_i         ),
-+    .be_i                    ( slave_be_i            ),
-+    .rdata_o                 ( slave_rdata_o         )
-+  );
- 
- 
- `ifndef VERILATOR
--    initial begin
--        assert (BusWidth == 32 || BusWidth == 64)
--            else $fatal(1, "DM needs a bus width of either 32 or 64 bits");
--    end
-+  initial begin
-+    assert (BusWidth == 32 || BusWidth == 64)
-+        else $fatal(1, "DM needs a bus width of either 32 or 64 bits");
-+  end
- `endif
- 
- endmodule
-diff --git a/src/dmi_cdc.sv b/src/dmi_cdc.sv
-index 98b15a8..ba856df 100644
---- a/src/dmi_cdc.sv
-+++ b/src/dmi_cdc.sv
-@@ -1,46 +1,46 @@
- /* Copyright 2018 ETH Zurich and University of Bologna.
-- * Copyright and related rights are licensed under the Solderpad Hardware
-- * License, Version 0.51 (the “License”); you may not use this file except in
-- * compliance with the License.  You may obtain a copy of the License at
-- * http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-- * or agreed to in writing, software, hardware and materials distributed under
-- * this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
-- * CONDITIONS OF ANY KIND, either express or implied. See the License for the
-- * specific language governing permissions and limitations under the License.
-- *
-- * File:   axi_riscv_debug_module.sv
-- * Author: Andreas Traber <atraber@iis.ee.ethz.ch>
-- * Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-- *
-- * Description: Clock domain crossings for JTAG to DMI very heavily based
-- *              on previous work by Andreas Traber for the PULP project.
-- *              This is mainly a wrapper around the existing CDCs.
-- */
-+* Copyright and related rights are licensed under the Solderpad Hardware
-+* License, Version 0.51 (the “License”); you may not use this file except in
-+* compliance with the License.  You may obtain a copy of the License at
-+* http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-+* or agreed to in writing, software, hardware and materials distributed under
-+* this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
-+* CONDITIONS OF ANY KIND, either express or implied. See the License for the
-+* specific language governing permissions and limitations under the License.
-+*
-+* File:   axi_riscv_debug_module.sv
-+* Author: Andreas Traber <atraber@iis.ee.ethz.ch>
-+* Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-+*
-+* Description: Clock domain crossings for JTAG to DMI very heavily based
-+*              on previous work by Andreas Traber for the PULP project.
-+*              This is mainly a wrapper around the existing CDCs.
-+*/
- module dmi_cdc (
--    // JTAG side (master side)
--    input  logic             tck_i,
--    input  logic             trst_ni,
-+  // JTAG side (master side)
-+  input  logic             tck_i,
-+  input  logic             trst_ni,
- 
--    input  dm::dmi_req_t     jtag_dmi_req_i,
--    output logic             jtag_dmi_ready_o,
--    input  logic             jtag_dmi_valid_i,
-+  input  dm::dmi_req_t     jtag_dmi_req_i,
-+  output logic             jtag_dmi_ready_o,
-+  input  logic             jtag_dmi_valid_i,
- 
--    output dm::dmi_resp_t    jtag_dmi_resp_o,
--    output logic             jtag_dmi_valid_o,
--    input  logic             jtag_dmi_ready_i,
-+  output dm::dmi_resp_t    jtag_dmi_resp_o,
-+  output logic             jtag_dmi_valid_o,
-+  input  logic             jtag_dmi_ready_i,
- 
--    // core side (slave side)
--    input  logic             clk_i,
--    input  logic             rst_ni,
-+  // core side (slave side)
-+  input  logic             clk_i,
-+  input  logic             rst_ni,
- 
--    output dm::dmi_req_t     core_dmi_req_o,
--    output logic             core_dmi_valid_o,
--    input  logic             core_dmi_ready_i,
-+  output dm::dmi_req_t     core_dmi_req_o,
-+  output logic             core_dmi_valid_o,
-+  input  logic             core_dmi_ready_i,
- 
--    input dm::dmi_resp_t     core_dmi_resp_i,
--    output logic             core_dmi_ready_o,
--    input  logic             core_dmi_valid_i
--  );
-+  input dm::dmi_resp_t     core_dmi_resp_i,
-+  output logic             core_dmi_ready_o,
-+  input  logic             core_dmi_valid_i
-+);
- 
-   cdc_2phase #(.T(dm::dmi_req_t)) i_cdc_req (
-     .src_rst_ni  ( trst_ni          ),
-diff --git a/src/dmi_jtag.sv b/src/dmi_jtag.sv
-index f177551..083ed59 100644
---- a/src/dmi_jtag.sv
-+++ b/src/dmi_jtag.sv
-@@ -1,262 +1,262 @@
- /* Copyright 2018 ETH Zurich and University of Bologna.
-- * Copyright and related rights are licensed under the Solderpad Hardware
-- * License, Version 0.51 (the “License”); you may not use this file except in
-- * compliance with the License.  You may obtain a copy of the License at
-- * http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-- * or agreed to in writing, software, hardware and materials distributed under
-- * this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
-- * CONDITIONS OF ANY KIND, either express or implied. See the License for the
-- * specific language governing permissions and limitations under the License.
-- *
-- * File:   axi_riscv_debug_module.sv
-- * Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-- * Date:   19.7.2018
-- *
-- * Description: JTAG DMI (debug module interface)
-- *
-- */
-+* Copyright and related rights are licensed under the Solderpad Hardware
-+* License, Version 0.51 (the “License”); you may not use this file except in
-+* compliance with the License.  You may obtain a copy of the License at
-+* http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
-+* or agreed to in writing, software, hardware and materials distributed under
-+* this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
-+* CONDITIONS OF ANY KIND, either express or implied. See the License for the
-+* specific language governing permissions and limitations under the License.
-+*
-+* File:   axi_riscv_debug_module.sv
-+* Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-+* Date:   19.7.2018
-+*
-+* Description: JTAG DMI (debug module interface)
-+*
-+*/
- 
- module dmi_jtag #(
--    parameter logic [31:0] IdcodeValue = 32'h00000001
-+  parameter logic [31:0] IdcodeValue = 32'h00000001
- ) (
--    input  logic         clk_i,      // DMI Clock
--    input  logic         rst_ni,     // Asynchronous reset active low
--    input  logic         testmode_i,
--
--    output logic         dmi_rst_no, // hard reset
--    output dm::dmi_req_t dmi_req_o,
--    output logic         dmi_req_valid_o,
--    input  logic         dmi_req_ready_i,
--
--    input dm::dmi_resp_t dmi_resp_i,
--    output logic         dmi_resp_ready_o,
--    input  logic         dmi_resp_valid_i,
--
--    input  logic         tck_i,    // JTAG test clock pad
--    input  logic         tms_i,    // JTAG test mode select pad
--    input  logic         trst_ni,  // JTAG test reset pad
--    input  logic         td_i,     // JTAG test data input pad
--    output logic         td_o,     // JTAG test data output pad
--    output logic         tdo_oe_o  // Data out output enable
-+  input  logic         clk_i,      // DMI Clock
-+  input  logic         rst_ni,     // Asynchronous reset active low
-+  input  logic         testmode_i,
-+
-+  output logic         dmi_rst_no, // hard reset
-+  output dm::dmi_req_t dmi_req_o,
-+  output logic         dmi_req_valid_o,
-+  input  logic         dmi_req_ready_i,
-+
-+  input dm::dmi_resp_t dmi_resp_i,
-+  output logic         dmi_resp_ready_o,
-+  input  logic         dmi_resp_valid_i,
-+
-+  input  logic         tck_i,    // JTAG test clock pad
-+  input  logic         tms_i,    // JTAG test mode select pad
-+  input  logic         trst_ni,  // JTAG test reset pad
-+  input  logic         td_i,     // JTAG test data input pad
-+  output logic         td_o,     // JTAG test data output pad
-+  output logic         tdo_oe_o  // Data out output enable
- );
--    assign       dmi_rst_no = rst_ni;
--
--    logic        test_logic_reset;
--    logic        shift_dr;
--    logic        update_dr;
--    logic        capture_dr;
--    logic        dmi_access;
--    logic        dtmcs_select;
--    logic        dmi_reset;
--    logic        dmi_tdi;
--    logic        dmi_tdo;
--
--    dm::dmi_req_t  dmi_req;
--    logic          dmi_req_ready;
--    logic          dmi_req_valid;
--
--    dm::dmi_resp_t dmi_resp;
--    logic          dmi_resp_valid;
--    logic          dmi_resp_ready;
--
--    typedef struct packed {
--        logic [6:0]  address;
--        logic [31:0] data;
--        logic [1:0]  op;
--    } dmi_t;
--
--    typedef enum logic [1:0] {
--                                DMINoError = 2'h0, DMIReservedError = 2'h1,
--                                DMIOPFailed = 2'h2, DMIBusy = 2'h3
--                             } dmi_error_e;
--
--    typedef enum logic [2:0] { Idle, Read, WaitReadValid, Write, WaitWriteValid } state_e;
--    state_e state_d, state_q;
--
--    logic [$bits(dmi_t)-1:0] dr_d, dr_q;
--    logic [6:0] address_d, address_q;
--    logic [31:0] data_d, data_q;
--
--    dmi_t  dmi;
--    assign dmi          = dmi_t'(dr_q);
--    assign dmi_req.addr = address_q;
--    assign dmi_req.data = data_q;
--    assign dmi_req.op   = (state_q == Write) ? dm::DTM_WRITE : dm::DTM_READ;
--    // we'will always be ready to accept the data we requested
--    assign dmi_resp_ready = 1'b1;
--
--    logic error_dmi_busy;
--    dmi_error_e error_d, error_q;
--
--    always_comb begin
--        error_dmi_busy = 1'b0;
--        // default assignments
--        state_d   = state_q;
--        address_d = address_q;
--        data_d    = data_q;
--        error_d   = error_q;
--
--        dmi_req_valid = 1'b0;
--
--        case (state_q)
--            Idle: begin
--                // make sure that no error is sticky
--                if (dmi_access && update_dr && (error_q == DMINoError)) begin
--                    // save address and value
--                    address_d = dmi.address;
--                    data_d = dmi.data;
--                    if (dm::dtm_op_e'(dmi.op) == dm::DTM_READ) begin
--                        state_d = Read;
--                    end else if (dm::dtm_op_e'(dmi.op) == dm::DTM_WRITE) begin
--                        state_d = Write;
--                    end
--                    // else this is a nop and we can stay here
--                end
--            end
--
--            Read: begin
--                dmi_req_valid = 1'b1;
--                if (dmi_req_ready) begin
--                    state_d = WaitReadValid;
--                end
--            end
--
--            WaitReadValid: begin
--                // load data into register and shift out
--                if (dmi_resp_valid) begin
--                    data_d = dmi_resp.data;
--                    state_d = Idle;
--                end
--            end
--
--            Write: begin
--                dmi_req_valid = 1'b1;
--                // got a valid answer go back to idle
--                if (dmi_req_ready) begin
--                    state_d = Idle;
--                end
--            end
--
--            default: begin
--                // just wait for idle here
--                if (dmi_resp_valid) begin
--                    state_d = Idle;
--                end
--            end
--        endcase
--
--        // update_dr means we got another request but we didn't finish
--        // the one in progress, this state is sticky
--        if (update_dr && state_q != Idle) begin
--            error_dmi_busy = 1'b1;
-+  assign       dmi_rst_no = rst_ni;
-+
-+  logic        test_logic_reset;
-+  logic        shift_dr;
-+  logic        update_dr;
-+  logic        capture_dr;
-+  logic        dmi_access;
-+  logic        dtmcs_select;
-+  logic        dmi_reset;
-+  logic        dmi_tdi;
-+  logic        dmi_tdo;
-+
-+  dm::dmi_req_t  dmi_req;
-+  logic          dmi_req_ready;
-+  logic          dmi_req_valid;
-+
-+  dm::dmi_resp_t dmi_resp;
-+  logic          dmi_resp_valid;
-+  logic          dmi_resp_ready;
-+
-+  typedef struct packed {
-+    logic [6:0]  address;
-+    logic [31:0] data;
-+    logic [1:0]  op;
-+  } dmi_t;
-+
-+  typedef enum logic [1:0] {
-+    DMINoError = 2'h0, DMIReservedError = 2'h1,
-+    DMIOPFailed = 2'h2, DMIBusy = 2'h3
-+  } dmi_error_e;
-+
-+  typedef enum logic [2:0] { Idle, Read, WaitReadValid, Write, WaitWriteValid } state_e;
-+  state_e state_d, state_q;
-+
-+  logic [$bits(dmi_t)-1:0] dr_d, dr_q;
-+  logic [6:0] address_d, address_q;
-+  logic [31:0] data_d, data_q;
-+
-+  dmi_t  dmi;
-+  assign dmi          = dmi_t'(dr_q);
-+  assign dmi_req.addr = address_q;
-+  assign dmi_req.data = data_q;
-+  assign dmi_req.op   = (state_q == Write) ? dm::DTM_WRITE : dm::DTM_READ;
-+  // we'will always be ready to accept the data we requested
-+  assign dmi_resp_ready = 1'b1;
-+
-+  logic error_dmi_busy;
-+  dmi_error_e error_d, error_q;
-+
-+  always_comb begin
-+    error_dmi_busy = 1'b0;
-+    // default assignments
-+    state_d   = state_q;
-+    address_d = address_q;
-+    data_d    = data_q;
-+    error_d   = error_q;
-+
-+    dmi_req_valid = 1'b0;
-+
-+    case (state_q)
-+      Idle: begin
-+        // make sure that no error is sticky
-+        if (dmi_access && update_dr && (error_q == DMINoError)) begin
-+          // save address and value
-+          address_d = dmi.address;
-+          data_d = dmi.data;
-+          if (dm::dtm_op_e'(dmi.op) == dm::DTM_READ) begin
-+            state_d = Read;
-+          end else if (dm::dtm_op_e'(dmi.op) == dm::DTM_WRITE) begin
-+            state_d = Write;
-+          end
-+          // else this is a nop and we can stay here
-         end
-+      end
- 
--        // if capture_dr goes high while we are in the read state
--        // or in the corresponding wait state we are not giving back a valid word
--        // -> throw an error
--        if (capture_dr && state_q inside {Read, WaitReadValid}) begin
--            error_dmi_busy = 1'b1;
-+      Read: begin
-+        dmi_req_valid = 1'b1;
-+        if (dmi_req_ready) begin
-+          state_d = WaitReadValid;
-         end
-+      end
- 
--        if (error_dmi_busy) begin
--            error_d = DMIBusy;
-+      WaitReadValid: begin
-+        // load data into register and shift out
-+        if (dmi_resp_valid) begin
-+          data_d = dmi_resp.data;
-+          state_d = Idle;
-         end
--        // clear sticky error flag
--        if (dmi_reset && dtmcs_select) begin
--            error_d = DMINoError;
--        end
--    end
-+      end
- 
--    // shift register
--    assign dmi_tdo = dr_q[0];
--
--    always_comb begin
--        dr_d    = dr_q;
--
--        if (capture_dr) begin
--            if (dmi_access) begin
--                if (error_q == DMINoError && !error_dmi_busy) begin
--                    dr_d = {address_q, data_q, DMINoError};
--                // DMI was busy, report an error
--                end else if (error_q == DMIBusy || error_dmi_busy) begin
--                    dr_d = {address_q, data_q, DMIBusy};
--                end
--            end
-+      Write: begin
-+        dmi_req_valid = 1'b1;
-+        // got a valid answer go back to idle
-+        if (dmi_req_ready) begin
-+          state_d = Idle;
-         end
-+      end
- 
--        if (shift_dr) begin
--            if (dmi_access) dr_d = {dmi_tdi, dr_q[$bits(dr_q)-1:1]};
-+      default: begin
-+        // just wait for idle here
-+        if (dmi_resp_valid) begin
-+          state_d = Idle;
-         end
-+      end
-+    endcase
- 
--        if (test_logic_reset) begin
--            dr_d = '0;
--        end
-+    // update_dr means we got another request but we didn't finish
-+    // the one in progress, this state is sticky
-+    if (update_dr && state_q != Idle) begin
-+      error_dmi_busy = 1'b1;
-+    end
-+
-+    // if capture_dr goes high while we are in the read state
-+    // or in the corresponding wait state we are not giving back a valid word
-+    // -> throw an error
-+    if (capture_dr && state_q inside {Read, WaitReadValid}) begin
-+      error_dmi_busy = 1'b1;
-+    end
-+
-+    if (error_dmi_busy) begin
-+      error_d = DMIBusy;
-     end
-+    // clear sticky error flag
-+    if (dmi_reset && dtmcs_select) begin
-+      error_d = DMINoError;
-+    end
-+  end
-+
-+  // shift register
-+  assign dmi_tdo = dr_q[0];
- 
--    always_ff @(posedge tck_i or negedge trst_ni) begin
--        if (!trst_ni) begin
--            dr_q      <= '0;
--            state_q   <= Idle;
--            address_q <= '0;
--            data_q    <= '0;
--            error_q   <= DMINoError;
--        end else begin
--            dr_q      <= dr_d;
--            state_q   <= state_d;
--            address_q <= address_d;
--            data_q    <= data_d;
--            error_q   <= error_d;
-+  always_comb begin
-+    dr_d    = dr_q;
-+
-+    if (capture_dr) begin
-+      if (dmi_access) begin
-+        if (error_q == DMINoError && !error_dmi_busy) begin
-+          dr_d = {address_q, data_q, DMINoError};
-+        // DMI was busy, report an error
-+        end else if (error_q == DMIBusy || error_dmi_busy) begin
-+          dr_d = {address_q, data_q, DMIBusy};
-         end
-+      end
-     end
- 
--    // ---------
--    // TAP
--    // ---------
--    dmi_jtag_tap #(
--        .IrLength (5),
--        .IdcodeValue(IdcodeValue)
--    ) i_dmi_jtag_tap (
--        .tck_i,
--        .tms_i,
--        .trst_ni,
--        .td_i,
--        .td_o,
--        .tdo_oe_o,
--        .testmode_i         ( testmode_i       ),
--        .test_logic_reset_o ( test_logic_reset ),
--        .shift_dr_o         ( shift_dr         ),
--        .update_dr_o        ( update_dr        ),
--        .capture_dr_o       ( capture_dr       ),
--        .dmi_access_o       ( dmi_access       ),
--        .dtmcs_select_o     ( dtmcs_select     ),
--        .dmi_reset_o        ( dmi_reset        ),
--        .dmi_error_i        ( error_q          ),
--        .dmi_tdi_o          ( dmi_tdi          ),
--        .dmi_tdo_i          ( dmi_tdo          )
--    );
--
--    // ---------
--    // CDC
--    // ---------
--    dmi_cdc i_dmi_cdc (
--        // JTAG side (master side)
--        .tck_i,
--        .trst_ni,
--        .jtag_dmi_req_i    ( dmi_req          ),
--        .jtag_dmi_ready_o  ( dmi_req_ready    ),
--        .jtag_dmi_valid_i  ( dmi_req_valid    ),
--        .jtag_dmi_resp_o   ( dmi_resp         ),
--        .jtag_dmi_valid_o  ( dmi_resp_valid   ),
--        .jtag_dmi_ready_i  ( dmi_resp_ready   ),
--        // core side
--        .clk_i,
--        .rst_ni,
--        .core_dmi_req_o    ( dmi_req_o        ),
--        .core_dmi_valid_o  ( dmi_req_valid_o  ),
--        .core_dmi_ready_i  ( dmi_req_ready_i  ),
--        .core_dmi_resp_i   ( dmi_resp_i       ),
--        .core_dmi_ready_o  ( dmi_resp_ready_o ),
--        .core_dmi_valid_i  ( dmi_resp_valid_i )
--    );
-+    if (shift_dr) begin
-+      if (dmi_access) dr_d = {dmi_tdi, dr_q[$bits(dr_q)-1:1]};
-+    end
-+
-+    if (test_logic_reset) begin
-+      dr_d = '0;
-+    end
-+  end
-+
-+  always_ff @(posedge tck_i or negedge trst_ni) begin
-+    if (!trst_ni) begin
-+      dr_q      <= '0;
-+      state_q   <= Idle;
-+      address_q <= '0;
-+      data_q    <= '0;
-+      error_q   <= DMINoError;
-+    end else begin
-+      dr_q      <= dr_d;
-+      state_q   <= state_d;
-+      address_q <= address_d;
-+      data_q    <= data_d;
-+      error_q   <= error_d;
-+    end
-+  end
-+
-+  // ---------
-+  // TAP
-+  // ---------
-+  dmi_jtag_tap #(
-+    .IrLength (5),
-+    .IdcodeValue(IdcodeValue)
-+  ) i_dmi_jtag_tap (
-+    .tck_i,
-+    .tms_i,
-+    .trst_ni,
-+    .td_i,
-+    .td_o,
-+    .tdo_oe_o,
-+    .testmode_i         ( testmode_i       ),
-+    .test_logic_reset_o ( test_logic_reset ),
-+    .shift_dr_o         ( shift_dr         ),
-+    .update_dr_o        ( update_dr        ),
-+    .capture_dr_o       ( capture_dr       ),
-+    .dmi_access_o       ( dmi_access       ),
-+    .dtmcs_select_o     ( dtmcs_select     ),
-+    .dmi_reset_o        ( dmi_reset        ),
-+    .dmi_error_i        ( error_q          ),
-+    .dmi_tdi_o          ( dmi_tdi          ),
-+    .dmi_tdo_i          ( dmi_tdo          )
-+  );
-+
-+  // ---------
-+  // CDC
-+  // ---------
-+  dmi_cdc i_dmi_cdc (
-+    // JTAG side (master side)
-+    .tck_i,
-+    .trst_ni,
-+    .jtag_dmi_req_i    ( dmi_req          ),
-+    .jtag_dmi_ready_o  ( dmi_req_ready    ),
-+    .jtag_dmi_valid_i  ( dmi_req_valid    ),
-+    .jtag_dmi_resp_o   ( dmi_resp         ),
-+    .jtag_dmi_valid_o  ( dmi_resp_valid   ),
-+    .jtag_dmi_ready_i  ( dmi_resp_ready   ),
-+    // core side
-+    .clk_i,
-+    .rst_ni,
-+    .core_dmi_req_o    ( dmi_req_o        ),
-+    .core_dmi_valid_o  ( dmi_req_valid_o  ),
-+    .core_dmi_ready_i  ( dmi_req_ready_i  ),
-+    .core_dmi_resp_i   ( dmi_resp_i       ),
-+    .core_dmi_ready_o  ( dmi_resp_ready_o ),
-+    .core_dmi_valid_i  ( dmi_resp_valid_i )
-+  );
- 
- endmodule
-diff --git a/src/dmi_jtag_tap.sv b/src/dmi_jtag_tap.sv
-index cab01ca..19d876f 100644
---- a/src/dmi_jtag_tap.sv
-+++ b/src/dmi_jtag_tap.sv
-@@ -17,327 +17,328 @@
-  */
- 
- module dmi_jtag_tap #(
--    parameter int IrLength = 5,
--    // JTAG IDCODE Value
--    parameter logic [31:0] IdcodeValue = 32'h00000001
--    // xxxx             version
--    // xxxxxxxxxxxxxxxx part number
--    // xxxxxxxxxxx      manufacturer id
--    // 1                required by standard
--)(
--    input  logic        tck_i,    // JTAG test clock pad
--    input  logic        tms_i,    // JTAG test mode select pad
--    input  logic        trst_ni,  // JTAG test reset pad
--    input  logic        td_i,     // JTAG test data input pad
--    output logic        td_o,     // JTAG test data output pad
--    output logic        tdo_oe_o, // Data out output enable
--    input  logic        testmode_i,
--    output logic        test_logic_reset_o,
--    output logic        shift_dr_o,
--    output logic        update_dr_o,
--    output logic        capture_dr_o,
--
--    // we want to access DMI register
--    output logic        dmi_access_o,
--    // JTAG is interested in writing the DTM CSR register
--    output logic        dtmcs_select_o,
--    // clear error state
--    output logic        dmi_reset_o,
--    input  logic [1:0]  dmi_error_i,
--    // test data to submodule
--    output logic        dmi_tdi_o,
--    // test data in from submodule
--    input  logic        dmi_tdo_i
--
-+  parameter int IrLength = 5,
-+  // JTAG IDCODE Value
-+  parameter logic [31:0] IdcodeValue = 32'h00000001
-+  // xxxx             version
-+  // xxxxxxxxxxxxxxxx part number
-+  // xxxxxxxxxxx      manufacturer id
-+  // 1                required by standard
-+) (
-+  input  logic        tck_i,    // JTAG test clock pad
-+  input  logic        tms_i,    // JTAG test mode select pad
-+  input  logic        trst_ni,  // JTAG test reset pad
-+  input  logic        td_i,     // JTAG test data input pad
-+  output logic        td_o,     // JTAG test data output pad
-+  output logic        tdo_oe_o, // Data out output enable
-+  input  logic        testmode_i,
-+  output logic        test_logic_reset_o,
-+  output logic        shift_dr_o,
-+  output logic        update_dr_o,
-+  output logic        capture_dr_o,
-+
-+  // we want to access DMI register
-+  output logic        dmi_access_o,
-+  // JTAG is interested in writing the DTM CSR register
-+  output logic        dtmcs_select_o,
-+  // clear error state
-+  output logic        dmi_reset_o,
-+  input  logic [1:0]  dmi_error_i,
-+  // test data to submodule
-+  output logic        dmi_tdi_o,
-+  // test data in from submodule
-+  input  logic        dmi_tdo_i
- );
- 
--    // to submodule
--    assign dmi_tdi_o = td_i;
--
--    typedef enum logic [3:0] { TestLogicReset, RunTestIdle, SelectDrScan,
--                     CaptureDr, ShiftDr, Exit1Dr, PauseDr, Exit2Dr,
--                     UpdateDr, SelectIrScan, CaptureIr, ShiftIr,
--                     Exit1Ir, PauseIr, Exit2Ir, UpdateIr } tap_state_e;
--    tap_state_e tap_state_q, tap_state_d;
--
--    typedef enum logic [IrLength-1:0] {
--        BYPASS0   = 'h0,
--        IDCODE    = 'h1,
--        DTMCSR    = 'h10,
--        DMIACCESS = 'h11,
--        BYPASS1   = 'h1f
--    } ir_reg_e;
--
--    typedef struct packed {
--        logic [31:18] zero1;
--        logic         dmihardreset;
--        logic         dmireset;
--        logic         zero0;
--        logic [14:12] idle;
--        logic [11:10] dmistat;
--        logic [9:4]   abits;
--        logic [3:0]   version;
--    } dtmcs_t;
--
--    // ----------------
--    // IR logic
--    // ----------------
--    logic [IrLength-1:0]  jtag_ir_shift_d, jtag_ir_shift_q; // shift register
--    ir_reg_e              jtag_ir_d, jtag_ir_q; // IR register -> this gets captured from shift register upon update_ir
--    logic capture_ir, shift_ir, pause_ir, update_ir;
--
--    always_comb begin
--        jtag_ir_shift_d = jtag_ir_shift_q;
--        jtag_ir_d       = jtag_ir_q;
--
--        // IR shift register
--        if (shift_ir) begin
--            jtag_ir_shift_d = {td_i, jtag_ir_shift_q[IrLength-1:1]};
--        end
--
--        // capture IR register
--        if (capture_ir) begin
--            jtag_ir_shift_d =  'b0101;
--        end
--
--        // update IR register
--        if (update_ir) begin
--            jtag_ir_d = ir_reg_e'(jtag_ir_shift_q);
--        end
--
--        // synchronous test-logic reset
--        if (test_logic_reset_o) begin
--            jtag_ir_shift_d = '0;
--            jtag_ir_d       = IDCODE;
--        end
-+  // to submodule
-+  assign dmi_tdi_o = td_i;
-+
-+  typedef enum logic [3:0] {
-+    TestLogicReset, RunTestIdle, SelectDrScan,
-+    CaptureDr, ShiftDr, Exit1Dr, PauseDr, Exit2Dr,
-+    UpdateDr, SelectIrScan, CaptureIr, ShiftIr,
-+    Exit1Ir, PauseIr, Exit2Ir, UpdateIr
-+  } tap_state_e;
-+
-+  tap_state_e tap_state_q, tap_state_d;
-+
-+  typedef enum logic [IrLength-1:0] {
-+    BYPASS0   = 'h0,
-+    IDCODE    = 'h1,
-+    DTMCSR    = 'h10,
-+    DMIACCESS = 'h11,
-+    BYPASS1   = 'h1f
-+  } ir_reg_e;
-+
-+  typedef struct packed {
-+    logic [31:18] zero1;
-+    logic         dmihardreset;
-+    logic         dmireset;
-+    logic         zero0;
-+    logic [14:12] idle;
-+    logic [11:10] dmistat;
-+    logic [9:4]   abits;
-+    logic [3:0]   version;
-+  } dtmcs_t;
-+
-+  // ----------------
-+  // IR logic
-+  // ----------------
-+  logic [IrLength-1:0]  jtag_ir_shift_d, jtag_ir_shift_q; // shift register
-+  ir_reg_e              jtag_ir_d, jtag_ir_q; // IR register -> this gets captured from shift register upon update_ir
-+  logic capture_ir, shift_ir, pause_ir, update_ir;
-+
-+  always_comb begin
-+    jtag_ir_shift_d = jtag_ir_shift_q;
-+    jtag_ir_d       = jtag_ir_q;
-+
-+    // IR shift register
-+    if (shift_ir) begin
-+      jtag_ir_shift_d = {td_i, jtag_ir_shift_q[IrLength-1:1]};
-     end
- 
--    always_ff @(posedge tck_i, negedge trst_ni) begin
--        if (!trst_ni) begin
--            jtag_ir_shift_q <= '0;
--            jtag_ir_q       <= IDCODE;
--        end else begin
--            jtag_ir_shift_q <= jtag_ir_shift_d;
--            jtag_ir_q       <= jtag_ir_d;
--        end
-+    // capture IR register
-+    if (capture_ir) begin
-+      jtag_ir_shift_d =  'b0101;
-     end
- 
--    // ----------------
--    // TAP DR Regs
--    // ----------------
--    // - Bypass
--    // - IDCODE
--    // - DTM CS
--    logic [31:0] idcode_d, idcode_q;
--    logic        idcode_select;
--    logic        bypass_select;
--    dtmcs_t      dtmcs_d, dtmcs_q;
--    logic        bypass_d, bypass_q;  // this is a 1-bit register
--
--    assign dmi_reset_o = dtmcs_q.dmireset;
--
--    always_comb begin
--        idcode_d = idcode_q;
--        bypass_d = bypass_q;
--        dtmcs_d  = dtmcs_q;
--
--        if (capture_dr_o) begin
--            if (idcode_select) idcode_d = IdcodeValue;
--            if (bypass_select) bypass_d = 1'b0;
--            if (dtmcs_select_o) begin
--                dtmcs_d  = '{
--                                zero1        : '0,
--                                dmihardreset : 1'b0,
--                                dmireset     : 1'b0,
--                                zero0        : '0,
--                                idle         : 'd1,         // 1: Enter Run-Test/Idle and leave it immediately
--                                dmistat      : dmi_error_i, // 0: No error, 1: Op failed, 2: too fast
--                                abits        : 'd7, // The size of address in dmi
--                                version      : 'd1  // Version described in spec version 0.13 (and later?)
--                            };
--            end
--        end
--
--        if (shift_dr_o) begin
--            if (idcode_select)  idcode_d = {td_i, idcode_q[31:1]};
--            if (bypass_select)  bypass_d = td_i;
--            if (dtmcs_select_o) dtmcs_d  = {td_i, dtmcs_q[31:1]};
--        end
--
--        if (test_logic_reset_o) begin
--            idcode_d = IdcodeValue;
--            bypass_d = 1'b0;
--        end
-+    // update IR register
-+    if (update_ir) begin
-+      jtag_ir_d = ir_reg_e'(jtag_ir_shift_q);
-     end
- 
--    // ----------------
--    // Data reg select
--    // ----------------
--    always_comb begin
--        dmi_access_o   = 1'b0;
--        dtmcs_select_o = 1'b0;
--        idcode_select  = 1'b0;
--        bypass_select  = 1'b0;
--        case (jtag_ir_q)
--            BYPASS0:   bypass_select  = 1'b1;
--            IDCODE:    idcode_select  = 1'b1;
--            DTMCSR:    dtmcs_select_o = 1'b1;
--            DMIACCESS: dmi_access_o   = 1'b1;
--            BYPASS1:   bypass_select  = 1'b1;
--            default:   bypass_select  = 1'b1;
--        endcase
-+    // synchronous test-logic reset
-+    if (test_logic_reset_o) begin
-+      jtag_ir_shift_d = '0;
-+      jtag_ir_d       = IDCODE;
-+    end
-+  end
-+
-+  always_ff @(posedge tck_i, negedge trst_ni) begin
-+    if (!trst_ni) begin
-+      jtag_ir_shift_q <= '0;
-+      jtag_ir_q       <= IDCODE;
-+    end else begin
-+      jtag_ir_shift_q <= jtag_ir_shift_d;
-+      jtag_ir_q       <= jtag_ir_d;
-+    end
-+  end
-+
-+  // ----------------
-+  // TAP DR Regs
-+  // ----------------
-+  // - Bypass
-+  // - IDCODE
-+  // - DTM CS
-+  logic [31:0] idcode_d, idcode_q;
-+  logic        idcode_select;
-+  logic        bypass_select;
-+  dtmcs_t      dtmcs_d, dtmcs_q;
-+  logic        bypass_d, bypass_q;  // this is a 1-bit register
-+
-+  assign dmi_reset_o = dtmcs_q.dmireset;
-+
-+  always_comb begin
-+    idcode_d = idcode_q;
-+    bypass_d = bypass_q;
-+    dtmcs_d  = dtmcs_q;
-+
-+    if (capture_dr_o) begin
-+      if (idcode_select) idcode_d = IdcodeValue;
-+      if (bypass_select) bypass_d = 1'b0;
-+      if (dtmcs_select_o) begin
-+        dtmcs_d  = '{
-+                      zero1        : '0,
-+                      dmihardreset : 1'b0,
-+                      dmireset     : 1'b0,
-+                      zero0        : '0,
-+                      idle         : 'd1,         // 1: Enter Run-Test/Idle and leave it immediately
-+                      dmistat      : dmi_error_i, // 0: No error, 1: Op failed, 2: too fast
-+                      abits        : 'd7, // The size of address in dmi
-+                      version      : 'd1  // Version described in spec version 0.13 (and later?)
-+                    };
-+      end
-     end
- 
--    // ----------------
--    // Output select
--    // ----------------
--    logic tdo_mux;
--
--    always_comb begin
--        // we are shifting out the IR register
--        if (shift_ir) begin
--            tdo_mux = jtag_ir_shift_q[0];
--        // here we are shifting the DR register
--        end else begin
--          case (jtag_ir_q)    // synthesis parallel_case
--            IDCODE:         tdo_mux = idcode_q[0];     // Reading ID code
--            DTMCSR:         tdo_mux = dtmcs_q[0];
--            DMIACCESS:      tdo_mux = dmi_tdo_i;       // Read from DMI TDO
--            default:        tdo_mux = bypass_q;      // BYPASS instruction
--          endcase
--        end
--
-+    if (shift_dr_o) begin
-+      if (idcode_select)  idcode_d = {td_i, idcode_q[31:1]};
-+      if (bypass_select)  bypass_d = td_i;
-+      if (dtmcs_select_o) dtmcs_d  = {td_i, dtmcs_q[31:1]};
-     end
- 
--    // DFT
--    logic tck_n, tck_ni;
--
--    cluster_clock_inverter i_tck_inv (
--        .clk_i ( tck_i  ),
--        .clk_o ( tck_ni )
--    );
--
--    pulp_clock_mux2 i_dft_tck_mux (
--        .clk0_i    ( tck_ni     ),
--        .clk1_i    ( tck_i      ), // bypass the inverted clock for testing
--        .clk_sel_i ( testmode_i ),
--        .clk_o     ( tck_n      )
--    );
--
--    // TDO changes state at negative edge of TCK
--    always_ff @(posedge tck_n, negedge trst_ni) begin
--        if (!trst_ni) begin
--            td_o     <= 1'b0;
--            tdo_oe_o <= 1'b0;
--        end else begin
--            td_o     <= tdo_mux;
--            tdo_oe_o <= (shift_ir | shift_dr_o);
--        end
-+    if (test_logic_reset_o) begin
-+      idcode_d = IdcodeValue;
-+      bypass_d = 1'b0;
-     end
--    // ----------------
--    // TAP FSM
--    // ----------------
--    // Determination of next state; purely combinatorial
--    always_comb begin
--        test_logic_reset_o = 1'b0;
--
--        capture_dr_o       = 1'b0;
--        shift_dr_o         = 1'b0;
--        update_dr_o        = 1'b0;
--
--        capture_ir         = 1'b0;
--        shift_ir           = 1'b0;
--        pause_ir           = 1'b0;
--        update_ir          = 1'b0;
--
--        case (tap_state_q)
--            TestLogicReset: begin
--                tap_state_d = (tms_i) ? TestLogicReset : RunTestIdle;
--                test_logic_reset_o = 1'b1;
--            end
--            RunTestIdle: begin
--                tap_state_d = (tms_i) ? SelectDrScan : RunTestIdle;
--            end
--            // DR Path
--            SelectDrScan: begin
--                tap_state_d = (tms_i) ? SelectIrScan : CaptureDr;
--            end
--            CaptureDr: begin
--                capture_dr_o = 1'b1;
--                tap_state_d = (tms_i) ? Exit1Dr : ShiftDr;
--            end
--            ShiftDr: begin
--                shift_dr_o = 1'b1;
--                tap_state_d = (tms_i) ? Exit1Dr : ShiftDr;
--            end
--            Exit1Dr: begin
--                tap_state_d = (tms_i) ? UpdateDr : PauseDr;
--            end
--            PauseDr: begin
--                tap_state_d = (tms_i) ? Exit2Dr : PauseDr;
--            end
--            Exit2Dr: begin
--                tap_state_d = (tms_i) ? UpdateDr : ShiftDr;
--            end
--            UpdateDr: begin
--                update_dr_o = 1'b1;
--                tap_state_d = (tms_i) ? SelectDrScan : RunTestIdle;
--            end
--            // IR Path
--            SelectIrScan: begin
--                tap_state_d = (tms_i) ? TestLogicReset : CaptureIr;
--            end
--            // In this controller state, the shift register bank in the
--            // Instruction Register parallel loads a pattern of fixed values on
--            // the rising edge of TCK. The last two significant bits must always
--            // be "01".
--            CaptureIr: begin
--                capture_ir = 1'b1;
--                tap_state_d = (tms_i) ? Exit1Ir : ShiftIr;
--            end
--            // In this controller state, the instruction register gets connected
--            // between TDI and TDO, and the captured pattern gets shifted on
--            // each rising edge of TCK. The instruction available on the TDI
--            // pin is also shifted in to the instruction register.
--            ShiftIr: begin
--                shift_ir = 1'b1;
--                tap_state_d = (tms_i) ? Exit1Ir : ShiftIr;
--            end
--            Exit1Ir: begin
--                tap_state_d = (tms_i) ? UpdateIr : PauseIr;
--            end
--            PauseIr: begin
--                pause_ir = 1'b1;
--                tap_state_d = (tms_i) ? Exit2Ir : PauseIr;
--            end
--            Exit2Ir: begin
--                tap_state_d = (tms_i) ? UpdateIr : ShiftIr;
--            end
--            // In this controller state, the instruction in the instruction
--            // shift register is latched to the latch bank of the Instruction
--            // Register on every falling edge of TCK. This instruction becomes
--            // the current instruction once it is latched.
--            UpdateIr: begin
--                update_ir = 1'b1;
--                tap_state_d = (tms_i) ? SelectDrScan : RunTestIdle;
--            end
--            default: tap_state_d = TestLogicReset;  // can't actually happen
-+  end
-+
-+  // ----------------
-+  // Data reg select
-+  // ----------------
-+  always_comb begin
-+    dmi_access_o   = 1'b0;
-+    dtmcs_select_o = 1'b0;
-+    idcode_select  = 1'b0;
-+    bypass_select  = 1'b0;
-+    case (jtag_ir_q)
-+      BYPASS0:   bypass_select  = 1'b1;
-+      IDCODE:    idcode_select  = 1'b1;
-+      DTMCSR:    dtmcs_select_o = 1'b1;
-+      DMIACCESS: dmi_access_o   = 1'b1;
-+      BYPASS1:   bypass_select  = 1'b1;
-+      default:   bypass_select  = 1'b1;
-+    endcase
-+  end
-+
-+  // ----------------
-+  // Output select
-+  // ----------------
-+  logic tdo_mux;
-+
-+  always_comb begin
-+    // we are shifting out the IR register
-+    if (shift_ir) begin
-+      tdo_mux = jtag_ir_shift_q[0];
-+    // here we are shifting the DR register
-+    end else begin
-+      case (jtag_ir_q)    // synthesis parallel_case
-+        IDCODE:         tdo_mux = idcode_q[0];     // Reading ID code
-+        DTMCSR:         tdo_mux = dtmcs_q[0];
-+        DMIACCESS:      tdo_mux = dmi_tdo_i;       // Read from DMI TDO
-+        default:        tdo_mux = bypass_q;      // BYPASS instruction
-       endcase
-     end
--
--    always_ff @(posedge tck_i or negedge trst_ni) begin
--        if (!trst_ni) begin
--            tap_state_q <= RunTestIdle;
--            idcode_q    <= IdcodeValue;
--            bypass_q    <= 1'b0;
--            dtmcs_q     <= '0;
--        end else begin
--            tap_state_q <= tap_state_d;
--            idcode_q    <= idcode_d;
--            bypass_q    <= bypass_d;
--            dtmcs_q     <= dtmcs_d;
--        end
-+  end
-+
-+  // DFT
-+  logic tck_n, tck_ni;
-+
-+  cluster_clock_inverter i_tck_inv (
-+    .clk_i ( tck_i  ),
-+    .clk_o ( tck_ni )
-+  );
-+
-+  pulp_clock_mux2 i_dft_tck_mux (
-+    .clk0_i    ( tck_ni     ),
-+    .clk1_i    ( tck_i      ), // bypass the inverted clock for testing
-+    .clk_sel_i ( testmode_i ),
-+    .clk_o     ( tck_n      )
-+  );
-+
-+  // TDO changes state at negative edge of TCK
-+  always_ff @(posedge tck_n, negedge trst_ni) begin
-+    if (!trst_ni) begin
-+      td_o     <= 1'b0;
-+      tdo_oe_o <= 1'b0;
-+    end else begin
-+      td_o     <= tdo_mux;
-+      tdo_oe_o <= (shift_ir | shift_dr_o);
-     end
--
-+  end
-+  // ----------------
-+  // TAP FSM
-+  // ----------------
-+  // Determination of next state; purely combinatorial
-+  always_comb begin
-+    test_logic_reset_o = 1'b0;
-+
-+    capture_dr_o       = 1'b0;
-+    shift_dr_o         = 1'b0;
-+    update_dr_o        = 1'b0;
-+
-+    capture_ir         = 1'b0;
-+    shift_ir           = 1'b0;
-+    pause_ir           = 1'b0;
-+    update_ir          = 1'b0;
-+
-+    case (tap_state_q)
-+      TestLogicReset: begin
-+        tap_state_d = (tms_i) ? TestLogicReset : RunTestIdle;
-+        test_logic_reset_o = 1'b1;
-+      end
-+      RunTestIdle: begin
-+        tap_state_d = (tms_i) ? SelectDrScan : RunTestIdle;
-+      end
-+      // DR Path
-+      SelectDrScan: begin
-+        tap_state_d = (tms_i) ? SelectIrScan : CaptureDr;
-+      end
-+      CaptureDr: begin
-+        capture_dr_o = 1'b1;
-+        tap_state_d = (tms_i) ? Exit1Dr : ShiftDr;
-+      end
-+      ShiftDr: begin
-+        shift_dr_o = 1'b1;
-+        tap_state_d = (tms_i) ? Exit1Dr : ShiftDr;
-+      end
-+      Exit1Dr: begin
-+        tap_state_d = (tms_i) ? UpdateDr : PauseDr;
-+      end
-+      PauseDr: begin
-+        tap_state_d = (tms_i) ? Exit2Dr : PauseDr;
-+      end
-+      Exit2Dr: begin
-+        tap_state_d = (tms_i) ? UpdateDr : ShiftDr;
-+      end
-+      UpdateDr: begin
-+        update_dr_o = 1'b1;
-+        tap_state_d = (tms_i) ? SelectDrScan : RunTestIdle;
-+      end
-+      // IR Path
-+      SelectIrScan: begin
-+        tap_state_d = (tms_i) ? TestLogicReset : CaptureIr;
-+      end
-+      // In this controller state, the shift register bank in the
-+      // Instruction Register parallel loads a pattern of fixed values on
-+      // the rising edge of TCK. The last two significant bits must always
-+      // be "01".
-+      CaptureIr: begin
-+        capture_ir = 1'b1;
-+        tap_state_d = (tms_i) ? Exit1Ir : ShiftIr;
-+      end
-+      // In this controller state, the instruction register gets connected
-+      // between TDI and TDO, and the captured pattern gets shifted on
-+      // each rising edge of TCK. The instruction available on the TDI
-+      // pin is also shifted in to the instruction register.
-+      ShiftIr: begin
-+        shift_ir = 1'b1;
-+        tap_state_d = (tms_i) ? Exit1Ir : ShiftIr;
-+      end
-+      Exit1Ir: begin
-+            tap_state_d = (tms_i) ? UpdateIr : PauseIr;
-+      end
-+      PauseIr: begin
-+        pause_ir = 1'b1;
-+        tap_state_d = (tms_i) ? Exit2Ir : PauseIr;
-+      end
-+      Exit2Ir: begin
-+        tap_state_d = (tms_i) ? UpdateIr : ShiftIr;
-+      end
-+      // In this controller state, the instruction in the instruction
-+      // shift register is latched to the latch bank of the Instruction
-+      // Register on every falling edge of TCK. This instruction becomes
-+      // the current instruction once it is latched.
-+      UpdateIr: begin
-+        update_ir = 1'b1;
-+        tap_state_d = (tms_i) ? SelectDrScan : RunTestIdle;
-+      end
-+      default: tap_state_d = TestLogicReset;  // can't actually happen
-+    endcase
-+  end
-+
-+
-+  always_ff @(posedge tck_i or negedge trst_ni) begin
-+    if (!trst_ni) begin
-+      tap_state_q <= RunTestIdle;
-+      idcode_q    <= IdcodeValue;
-+      bypass_q    <= 1'b0;
-+      dtmcs_q     <= '0;
-+    end else begin
-+      tap_state_q <= tap_state_d;
-+      idcode_q    <= idcode_d;
-+      bypass_q    <= bypass_d;
-+      dtmcs_q     <= dtmcs_d;
-+    end
-+  end
- 
- endmodule
--- 
-2.17.1
-
diff --git a/hw/vendor/patches/pulp_riscv_dbg/0003-Make-sure-all-case-statements-are-unique-and-have-a-.patch b/hw/vendor/patches/pulp_riscv_dbg/0003-Make-sure-all-case-statements-are-unique-and-have-a-.patch
new file mode 100644
index 0000000..6bbf96b
--- /dev/null
+++ b/hw/vendor/patches/pulp_riscv_dbg/0003-Make-sure-all-case-statements-are-unique-and-have-a-.patch
@@ -0,0 +1,133 @@
+From db50a1c140933c4c7769a5632b89410b9cb4d1b0 Mon Sep 17 00:00:00 2001
+From: Michael Schaffner <msf@google.com>
+Date: Mon, 16 Dec 2019 18:33:18 -0800
+Subject: [PATCH 3/4] Make sure all case statements are unique and have a
+ default
+
+---
+ src/dm_mem.sv       |  4 +++-
+ src/dm_sba.sv       |  8 ++++----
+ src/dmi_jtag.sv     |  2 +-
+ src/dmi_jtag_tap.sv | 10 ++++------
+ 4 files changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/src/dm_mem.sv b/src/dm_mem.sv
+index 49daa38..938e883 100644
+--- a/src/dm_mem.sv
++++ b/src/dm_mem.sv
+@@ -137,7 +137,7 @@ module dm_mem #(
+     resume           = 1'b0;
+     cmdbusy_o        = 1'b1;
+ 
+-    case (state_q)
++    unique case (state_q)
+       Idle: begin
+         cmdbusy_o = 1'b0;
+         if (cmd_valid_i && halted_q_aligned[hartsel] && !unsupported_command) begin
+@@ -182,6 +182,8 @@ module dm_mem #(
+           state_d = Idle;
+         end
+       end
++
++      default: ;
+     endcase
+ 
+     // only signal once that cmd is unsupported so that we can clear cmderr
+diff --git a/src/dm_sba.sv b/src/dm_sba.sv
+index 43a6dad..f605088 100644
+--- a/src/dm_sba.sv
++++ b/src/dm_sba.sv
+@@ -77,7 +77,7 @@ module dm_sba #(
+ 
+     state_d = state_q;
+ 
+-    case (state_q)
++    unique case (state_q)
+       Idle: begin
+         // debugger requested a read
+         if (sbaddress_write_valid_i && sbreadonaddr_i)  state_d = Read;
+@@ -96,7 +96,7 @@ module dm_sba #(
+         req = 1'b1;
+         we  = 1'b1;
+         // generate byte enable mask
+-        case (sbaccess_i)
++        unique case (sbaccess_i)
+           3'b000: begin
+             be[be_idx] = '1;
+           end
+@@ -108,7 +108,7 @@ module dm_sba #(
+             else                    be = '1;
+           end
+           3'b011: be = '1;
+-          default:;
++          default: ;
+         endcase
+         if (gnt) state_d = WaitWrite;
+       end
+@@ -129,7 +129,7 @@ module dm_sba #(
+         end
+       end
+ 
+-      default:;
++      default: state_d = Idle; // catch parasitic state
+     endcase
+ 
+     // handle error case
+diff --git a/src/dmi_jtag.sv b/src/dmi_jtag.sv
+index 60e67f4..2039e25 100644
+--- a/src/dmi_jtag.sv
++++ b/src/dmi_jtag.sv
+@@ -98,7 +98,7 @@ module dmi_jtag #(
+ 
+     dmi_req_valid = 1'b0;
+ 
+-    case (state_q)
++    unique case (state_q)
+       Idle: begin
+         // make sure that no error is sticky
+         if (dmi_access && update_dr && (error_q == DMINoError)) begin
+diff --git a/src/dmi_jtag_tap.sv b/src/dmi_jtag_tap.sv
+index f8b282a..3d11145 100644
+--- a/src/dmi_jtag_tap.sv
++++ b/src/dmi_jtag_tap.sv
+@@ -183,7 +183,7 @@ module dmi_jtag_tap #(
+     dtmcs_select_o = 1'b0;
+     idcode_select  = 1'b0;
+     bypass_select  = 1'b0;
+-    case (jtag_ir_q)
++    unique case (jtag_ir_q)
+       BYPASS0:   bypass_select  = 1'b1;
+       IDCODE:    idcode_select  = 1'b1;
+       DTMCSR:    dtmcs_select_o = 1'b1;
+@@ -204,7 +204,7 @@ module dmi_jtag_tap #(
+       tdo_mux = jtag_ir_shift_q[0];
+     // here we are shifting the DR register
+     end else begin
+-      case (jtag_ir_q)    // synthesis parallel_case
++      unique case (jtag_ir_q)
+         IDCODE:         tdo_mux = idcode_q[0];     // Reading ID code
+         DTMCSR:         tdo_mux = dtmcs_q.version[0];
+         DMIACCESS:      tdo_mux = dmi_tdo_i;       // Read from DMI TDO
+@@ -257,9 +257,7 @@ module dmi_jtag_tap #(
+     // pause_ir           = 1'b0; unused
+     update_ir          = 1'b0;
+ 
+-    // note that tap_state_d does not have a default assignment since the
+-    // case statement is full
+-    case (tap_state_q)
++    unique case (tap_state_q)
+       TestLogicReset: begin
+         tap_state_d = (tms_i) ? TestLogicReset : RunTestIdle;
+         test_logic_reset_o = 1'b1;
+@@ -330,7 +328,7 @@ module dmi_jtag_tap #(
+         update_ir = 1'b1;
+         tap_state_d = (tms_i) ? SelectDrScan : RunTestIdle;
+       end
+-      default: ; // can't actually happen
++      default: ; // can't actually happen since case is full
+     endcase
+   end
+ 
+-- 
+2.24.1.735.g03f4e72817-goog
+
diff --git a/hw/vendor/patches/pulp_riscv_dbg/0003-lint-cleanup-Name-blocks-align-blocking-structure.patch b/hw/vendor/patches/pulp_riscv_dbg/0003-lint-cleanup-Name-blocks-align-blocking-structure.patch
deleted file mode 100644
index 9c6c43b..0000000
--- a/hw/vendor/patches/pulp_riscv_dbg/0003-lint-cleanup-Name-blocks-align-blocking-structure.patch
+++ /dev/null
@@ -1,315 +0,0 @@
-From 393329b704d63a6fa150e9d4eb54c81dec7edae3 Mon Sep 17 00:00:00 2001
-From: Michael Schaffner <msf@google.com>
-Date: Thu, 17 Oct 2019 15:52:49 -0700
-Subject: [PATCH 03/11] [lint/cleanup] Name blocks, align blocking structure
-
----
- src/dm_csrs.sv      |  9 +++++----
- src/dm_mem.sv       | 16 +++++++++-------
- src/dm_pkg.sv       |  2 +-
- src/dm_sba.sv       |  6 +++---
- src/dm_top.sv       |  2 +-
- src/dmi_cdc.sv      |  3 ++-
- src/dmi_jtag.sv     | 10 ++++++----
- src/dmi_jtag_tap.sv | 21 +++++++++++----------
- 8 files changed, 38 insertions(+), 31 deletions(-)
-
-diff --git a/src/dm_csrs.sv b/src/dm_csrs.sv
-index 808a95d..3253173 100644
---- a/src/dm_csrs.sv
-+++ b/src/dm_csrs.sv
-@@ -102,7 +102,7 @@ module dm_csrs #(
-   logic [32-1:0] halted_flat3;
- 
-   // haltsum0
--  always_comb begin
-+  always_comb begin : p_haltsum0
-     halted              = '0;
-     halted[NrHarts-1:0] = halted_i;
-     halted_reshaped0    = halted;
-@@ -433,8 +433,9 @@ module dm_csrs #(
-     end
- 
-     // update data registers
--    if (data_valid_i)
-+    if (data_valid_i) begin
-       data_d = data_i;
-+    end
- 
-     // set the havereset flag when we did a ndmreset
-     if (ndmreset_o) begin
-@@ -482,7 +483,7 @@ module dm_csrs #(
-   end
- 
-   // output multiplexer
--  always_comb begin
-+  always_comb begin : p_outmux
-     selected_hart = hartsel_o[HartSelLen-1:0];
-     // default assignment
-     haltreq_o = '0;
-@@ -599,4 +600,4 @@ module dm_csrs #(
- `endif
- //pragma translate_on
- 
--endmodule
-+endmodule : dm_csrs
-diff --git a/src/dm_mem.sv b/src/dm_mem.sv
-index 1ecc878..12057f3 100644
---- a/src/dm_mem.sv
-+++ b/src/dm_mem.sv
-@@ -110,7 +110,7 @@ module dm_mem #(
-   state_e state_d, state_q;
- 
-   // hart ctrl queue
--  always_comb begin
-+  always_comb begin : p_hart_ctrl_queue
-     cmderror_valid_o = 1'b0;
-     cmderror_o       = dm::CmdErrNone;
-     state_d          = state_q;
-@@ -142,15 +142,17 @@ module dm_mem #(
-         cmdbusy_o = 1'b1;
-         go        = 1'b1;
-         // the thread is now executing the command, track its state
--        if (going)
-+        if (going) begin
-           state_d = CmdExecuting;
-+        end
-       end
- 
-       Resume: begin
-         cmdbusy_o = 1'b1;
-         resume = 1'b1;
--        if (resuming_o[hartsel_i])
-+        if (resuming_o[hartsel_i]) begin
-           state_d = Idle;
-+        end
-       end
- 
-       CmdExecuting: begin
-@@ -177,7 +179,7 @@ module dm_mem #(
-   end
- 
-   // read/write logic
--  always_comb begin
-+  always_comb begin : p_rw_logic
-     automatic logic [63:0] data_bits;
- 
-     halted_d     = halted_q;
-@@ -292,7 +294,7 @@ module dm_mem #(
-     data_o = data_bits;
-   end
- 
--  always_comb begin : abstract_cmd_rom
-+  always_comb begin : p_abstract_cmd_rom
-     // this abstract command is currently unsupported
-     unsupported_command = 1'b0;
-     // default memory
-@@ -437,7 +439,7 @@ module dm_mem #(
-   assign fwd_rom_d = (addr_i[DbgAddressBits-1:0] >= dm::HaltAddress[DbgAddressBits-1:0]) ?
-                      1'b1 : 1'b0;
- 
--  always_ff @(posedge clk_i or negedge rst_ni) begin
-+  always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
-     if (!rst_ni) begin
-       fwd_rom_q       <= 1'b0;
-       rdata_q         <= '0;
-@@ -463,4 +465,4 @@ module dm_mem #(
-     end
-   end
- 
--endmodule
-+endmodule : dm_mem
-diff --git a/src/dm_pkg.sv b/src/dm_pkg.sv
-index 49e77be..341e9ab 100644
---- a/src/dm_pkg.sv
-+++ b/src/dm_pkg.sv
-@@ -383,4 +383,4 @@ package dm;
-     return 32'h00000000;
-   endfunction
- 
--endpackage
-+endpackage : dm
-diff --git a/src/dm_sba.sv b/src/dm_sba.sv
-index fa9d401..12b1951 100644
---- a/src/dm_sba.sv
-+++ b/src/dm_sba.sv
-@@ -63,7 +63,7 @@ module dm_sba #(
- 
-   assign sbbusy_o = (state_q != Idle) ? 1'b1 : 1'b0;
- 
--  always_comb begin
-+  always_comb begin : p_fsm
-     req     = 1'b0;
-     address = sbaddress_i;
-     we      = 1'b0;
-@@ -142,7 +142,7 @@ module dm_sba #(
-     // further error handling should go here ...
-   end
- 
--  always_ff @(posedge clk_i or negedge rst_ni) begin
-+  always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
-     if (!rst_ni) begin
-       state_q <= Idle;
-     end else begin
-@@ -169,4 +169,4 @@ module dm_sba #(
-   `endif
-   //pragma translate_on
- 
--endmodule
-+endmodule : dm_sba
-diff --git a/src/dm_top.sv b/src/dm_top.sv
-index 03ac112..6c7fa49 100644
---- a/src/dm_top.sv
-+++ b/src/dm_top.sv
-@@ -219,4 +219,4 @@ module dm_top #(
-   end
- `endif
- 
--endmodule
-+endmodule : dm_top
-diff --git a/src/dmi_cdc.sv b/src/dmi_cdc.sv
-index ba856df..4665c91 100644
---- a/src/dmi_cdc.sv
-+++ b/src/dmi_cdc.sv
-@@ -69,4 +69,5 @@ module dmi_cdc (
-     .dst_valid_o ( jtag_dmi_valid_o ),
-     .dst_ready_i ( jtag_dmi_ready_i )
-   );
--endmodule
-+
-+endmodule : dmi_cdc
-diff --git a/src/dmi_jtag.sv b/src/dmi_jtag.sv
-index 083ed59..5642dc1 100644
---- a/src/dmi_jtag.sv
-+++ b/src/dmi_jtag.sv
-@@ -88,7 +88,7 @@ module dmi_jtag #(
-   logic error_dmi_busy;
-   dmi_error_e error_d, error_q;
- 
--  always_comb begin
-+  always_comb begin : p_fsm
-     error_dmi_busy = 1'b0;
-     // default assignments
-     state_d   = state_q;
-@@ -170,7 +170,7 @@ module dmi_jtag #(
-   // shift register
-   assign dmi_tdo = dr_q[0];
- 
--  always_comb begin
-+  always_comb begin : p_shift
-     dr_d    = dr_q;
- 
-     if (capture_dr) begin
-@@ -185,7 +185,9 @@ module dmi_jtag #(
-     end
- 
-     if (shift_dr) begin
--      if (dmi_access) dr_d = {dmi_tdi, dr_q[$bits(dr_q)-1:1]};
-+      if (dmi_access) begin
-+        dr_d = {dmi_tdi, dr_q[$bits(dr_q)-1:1]};
-+      end
-     end
- 
-     if (test_logic_reset) begin
-@@ -259,4 +261,4 @@ module dmi_jtag #(
-     .core_dmi_valid_i  ( dmi_resp_valid_i )
-   );
- 
--endmodule
-+endmodule : dmi_jtag
-diff --git a/src/dmi_jtag_tap.sv b/src/dmi_jtag_tap.sv
-index 19d876f..bd447f6 100644
---- a/src/dmi_jtag_tap.sv
-+++ b/src/dmi_jtag_tap.sv
-@@ -88,7 +88,7 @@ module dmi_jtag_tap #(
-   ir_reg_e              jtag_ir_d, jtag_ir_q; // IR register -> this gets captured from shift register upon update_ir
-   logic capture_ir, shift_ir, pause_ir, update_ir;
- 
--  always_comb begin
-+  always_comb begin : p_jtag
-     jtag_ir_shift_d = jtag_ir_shift_q;
-     jtag_ir_d       = jtag_ir_q;
- 
-@@ -114,7 +114,7 @@ module dmi_jtag_tap #(
-     end
-   end
- 
--  always_ff @(posedge tck_i, negedge trst_ni) begin
-+  always_ff @(posedge tck_i, negedge trst_ni) begin : p_jtag_ir_reg
-     if (!trst_ni) begin
-       jtag_ir_shift_q <= '0;
-       jtag_ir_q       <= IDCODE;
-@@ -138,7 +138,7 @@ module dmi_jtag_tap #(
- 
-   assign dmi_reset_o = dtmcs_q.dmireset;
- 
--  always_comb begin
-+  always_comb begin : p_tap_dr
-     idcode_d = idcode_q;
-     bypass_d = bypass_q;
-     dtmcs_d  = dtmcs_q;
-@@ -175,7 +175,7 @@ module dmi_jtag_tap #(
-   // ----------------
-   // Data reg select
-   // ----------------
--  always_comb begin
-+  always_comb begin : p_data_reg_sel
-     dmi_access_o   = 1'b0;
-     dtmcs_select_o = 1'b0;
-     idcode_select  = 1'b0;
-@@ -195,7 +195,7 @@ module dmi_jtag_tap #(
-   // ----------------
-   logic tdo_mux;
- 
--  always_comb begin
-+  always_comb begin : p_out_sel
-     // we are shifting out the IR register
-     if (shift_ir) begin
-       tdo_mux = jtag_ir_shift_q[0];
-@@ -210,7 +210,9 @@ module dmi_jtag_tap #(
-     end
-   end
- 
-+  // ----------------
-   // DFT
-+  // ----------------
-   logic tck_n, tck_ni;
- 
-   cluster_clock_inverter i_tck_inv (
-@@ -226,7 +228,7 @@ module dmi_jtag_tap #(
-   );
- 
-   // TDO changes state at negative edge of TCK
--  always_ff @(posedge tck_n, negedge trst_ni) begin
-+  always_ff @(posedge tck_n, negedge trst_ni) begin : p_tdo_regs
-     if (!trst_ni) begin
-       td_o     <= 1'b0;
-       tdo_oe_o <= 1'b0;
-@@ -239,7 +241,7 @@ module dmi_jtag_tap #(
-   // TAP FSM
-   // ----------------
-   // Determination of next state; purely combinatorial
--  always_comb begin
-+  always_comb begin : p_tap_fsm
-     test_logic_reset_o = 1'b0;
- 
-     capture_dr_o       = 1'b0;
-@@ -326,8 +328,7 @@ module dmi_jtag_tap #(
-     endcase
-   end
- 
--
--  always_ff @(posedge tck_i or negedge trst_ni) begin
-+  always_ff @(posedge tck_i or negedge trst_ni) begin : p_regs
-     if (!trst_ni) begin
-       tap_state_q <= RunTestIdle;
-       idcode_q    <= IdcodeValue;
-@@ -341,4 +342,4 @@ module dmi_jtag_tap #(
-     end
-   end
- 
--endmodule
-+endmodule : dmi_jtag_tap
--- 
-2.17.1
-
diff --git a/hw/vendor/patches/pulp_riscv_dbg/0009-Use-lowrisc-instead-of-PULP-primitives.patch b/hw/vendor/patches/pulp_riscv_dbg/0004-Use-lowrisc-instead-of-PULP-primitives.patch
similarity index 97%
rename from hw/vendor/patches/pulp_riscv_dbg/0009-Use-lowrisc-instead-of-PULP-primitives.patch
rename to hw/vendor/patches/pulp_riscv_dbg/0004-Use-lowrisc-instead-of-PULP-primitives.patch
index 883cf8f..571c70b 100644
--- a/hw/vendor/patches/pulp_riscv_dbg/0009-Use-lowrisc-instead-of-PULP-primitives.patch
+++ b/hw/vendor/patches/pulp_riscv_dbg/0004-Use-lowrisc-instead-of-PULP-primitives.patch
@@ -1,7 +1,7 @@
-From 6a037bd7e07ba9e1aa0445ab53b845ee74ceecc2 Mon Sep 17 00:00:00 2001
+From 2179b843c1a753642d803918170c21d6e74b9beb Mon Sep 17 00:00:00 2001
 From: Philipp Wagner <phw@lowrisc.org>
 Date: Fri, 22 Feb 2019 14:48:46 +0000
-Subject: [PATCH 09/11] Use lowrisc instead of PULP primitives
+Subject: [PATCH 4/4] Use lowrisc instead of PULP primitives
 
 ---
  src/dm_csrs.sv      | 42 +++++++++++++++-------------------
@@ -159,7 +159,7 @@
  
  endmodule : dmi_cdc
 diff --git a/src/dmi_jtag_tap.sv b/src/dmi_jtag_tap.sv
-index f8b282a..9771cd9 100644
+index 3d11145..ca6b824 100644
 --- a/src/dmi_jtag_tap.sv
 +++ b/src/dmi_jtag_tap.sv
 @@ -216,18 +216,14 @@ module dmi_jtag_tap #(
@@ -190,5 +190,5 @@
  
    // TDO changes state at negative edge of TCK
 -- 
-2.17.1
+2.24.1.735.g03f4e72817-goog
 
diff --git a/hw/vendor/patches/pulp_riscv_dbg/0004-lint-cleanup-Make-params-unsingend-correct-defaults-.patch b/hw/vendor/patches/pulp_riscv_dbg/0004-lint-cleanup-Make-params-unsingend-correct-defaults-.patch
deleted file mode 100644
index a3ca25b..0000000
--- a/hw/vendor/patches/pulp_riscv_dbg/0004-lint-cleanup-Make-params-unsingend-correct-defaults-.patch
+++ /dev/null
@@ -1,271 +0,0 @@
-From 0b5428a2047c27f5abdae04d0da99893c695693b Mon Sep 17 00:00:00 2001
-From: Michael Schaffner <msf@google.com>
-Date: Fri, 18 Oct 2019 10:31:56 -0700
-Subject: [PATCH 04/11] [lint/cleanup] Make params unsingend, correct defaults
- and uniquify
-
----
- src/dm_csrs.sv      | 14 ++++----
- src/dm_mem.sv       | 80 +++++++++++++++++++++++----------------------
- src/dm_sba.sv       |  2 +-
- src/dm_top.sv       | 10 +++---
- src/dmi_jtag_tap.sv |  2 +-
- 5 files changed, 55 insertions(+), 53 deletions(-)
-
-diff --git a/src/dm_csrs.sv b/src/dm_csrs.sv
-index 3253173..ffa45ba 100644
---- a/src/dm_csrs.sv
-+++ b/src/dm_csrs.sv
-@@ -16,9 +16,9 @@
-  */
- 
- module dm_csrs #(
--  parameter int                 NrHarts          = 1,
--  parameter int                 BusWidth         = 32,
--  parameter logic [NrHarts-1:0] SelectableHarts  = 1
-+  parameter int unsigned        NrHarts          = 1,
-+  parameter int unsigned        BusWidth         = 32,
-+  parameter logic [NrHarts-1:0] SelectableHarts  = {NrHarts{1'b1}}
- ) (
-   input  logic                              clk_i,           // Clock
-   input  logic                              rst_ni,          // Asynchronous reset active low
-@@ -79,7 +79,7 @@ module dm_csrs #(
-   input  logic [2:0]                        sberror_i // bus error occurred
- );
-   // the amount of bits we need to represent all harts
--  localparam HartSelLen = (NrHarts == 1) ? 1 : $clog2(NrHarts);
-+  localparam int unsigned HartSelLen = (NrHarts == 1) ? 1 : $clog2(NrHarts);
-   dm::dtm_op_e dtm_op;
-   assign dtm_op = dm::dtm_op_e'(dmi_req_i.op);
- 
-@@ -112,7 +112,7 @@ module dm_csrs #(
-   // haltsum1
-   always_comb begin : p_reduction1
-     halted_flat1 = '0;
--    for (int k=0; k<NrHarts/2**5+1; k++) begin
-+    for (int unsigned k=0; k<NrHarts/2**5+1; k++) begin
-       halted_flat1[k] = |halted_reshaped0[k];
-     end
-     halted_reshaped1 = halted_flat1;
-@@ -121,7 +121,7 @@ module dm_csrs #(
-   // haltsum2
-   always_comb begin : p_reduction2
-     halted_flat2 = '0;
--    for (int k=0; k<NrHarts/2**10+1; k++) begin
-+    for (int unsigned k=0; k<NrHarts/2**10+1; k++) begin
-       halted_flat2[k] = |halted_reshaped1[k];
-     end
-     halted_reshaped2 = halted_flat2;
-@@ -130,7 +130,7 @@ module dm_csrs #(
-   // haltsum3
-   always_comb begin : p_reduction3
-     halted_flat3 = '0;
--    for (int k=0; k<NrHarts/2**15+1; k++) begin
-+    for (int unsigned k=0; k<NrHarts/2**15+1; k++) begin
-       halted_flat3[k] = |halted_reshaped2[k];
-     end
-     haltsum3 = halted_flat3;
-diff --git a/src/dm_mem.sv b/src/dm_mem.sv
-index 12057f3..9de08d4 100644
---- a/src/dm_mem.sv
-+++ b/src/dm_mem.sv
-@@ -17,9 +17,9 @@
- */
- 
- module dm_mem #(
--  parameter int                 NrHarts          = -1,
--  parameter int                 BusWidth         = -1,
--  parameter logic [NrHarts-1:0] SelectableHarts  = -1
-+  parameter int unsigned        NrHarts          =  1,
-+  parameter int unsigned        BusWidth         = 32,
-+  parameter logic [NrHarts-1:0] SelectableHarts  = {NrHarts{1'b1}}
- ) (
-   input  logic                             clk_i,       // Clock
-   input  logic                             rst_ni,      // debug module reset
-@@ -57,24 +57,26 @@ module dm_mem #(
-   output logic [BusWidth-1:0]              rdata_o
- );
- 
--  localparam int HartSelLen = (NrHarts == 1) ? 1 : $clog2(NrHarts);
--  localparam int MaxAar = (BusWidth == 64) ? 4 : 3;
--  localparam DbgAddressBits = 12;
--  localparam logic [DbgAddressBits-1:0] DataBase = (dm::DataAddr);
--  localparam logic [DbgAddressBits-1:0] DataEnd = (dm::DataAddr + 4*dm::DataCount);
--  localparam logic [DbgAddressBits-1:0] ProgBufBase = (dm::DataAddr - 4*dm::ProgBufSize);
--  localparam logic [DbgAddressBits-1:0] ProgBufEnd = (dm::DataAddr - 1);
--  localparam logic [DbgAddressBits-1:0] AbstractCmdBase = (ProgBufBase - 4*10);
--  localparam logic [DbgAddressBits-1:0] AbstractCmdEnd = (ProgBufBase - 1);
--  localparam logic [DbgAddressBits-1:0] WhereTo   = 'h300;
--  localparam logic [DbgAddressBits-1:0] FlagsBase = 'h400;
--  localparam logic [DbgAddressBits-1:0] FlagsEnd  = 'h7FF;
--
--
--  localparam logic [DbgAddressBits-1:0] Halted    = 'h100;
--  localparam logic [DbgAddressBits-1:0] Going     = 'h104;
--  localparam logic [DbgAddressBits-1:0] Resuming  = 'h108;
--  localparam logic [DbgAddressBits-1:0] Exception = 'h10C;
-+  localparam int unsigned DbgAddressBits = 12;
-+  localparam int unsigned HartSelLen     = (NrHarts == 1) ? 1 : $clog2(NrHarts);
-+  localparam int unsigned NrHartsAligned = 2**HartSelLen;
-+  localparam int unsigned MaxAar         = (BusWidth == 64) ? 4 : 3;
-+
-+  localparam logic [DbgAddressBits-1:0] DataBaseAddr        = (dm::DataAddr);
-+  localparam logic [DbgAddressBits-1:0] DataEndAddr         = (dm::DataAddr + 4*dm::DataCount);
-+  localparam logic [DbgAddressBits-1:0] ProgBufBaseAddr     = (dm::DataAddr - 4*dm::ProgBufSize);
-+  localparam logic [DbgAddressBits-1:0] ProgBufEndAddr      = (dm::DataAddr - 1);
-+  localparam logic [DbgAddressBits-1:0] AbstractCmdBaseAddr = (ProgBufBaseAddr - 4*10);
-+  localparam logic [DbgAddressBits-1:0] AbstractCmdEndAddr  = (ProgBufBaseAddr - 1);
-+
-+  localparam logic [DbgAddressBits-1:0] WhereToAddr   = 'h300;
-+  localparam logic [DbgAddressBits-1:0] FlagsBaseAddr = 'h400;
-+  localparam logic [DbgAddressBits-1:0] FlagsEndAddr  = 'h7FF;
-+
-+  localparam logic [DbgAddressBits-1:0] HaltedAddr    = 'h100;
-+  localparam logic [DbgAddressBits-1:0] GoingAddr     = 'h104;
-+  localparam logic [DbgAddressBits-1:0] ResumingAddr  = 'h108;
-+  localparam logic [DbgAddressBits-1:0] ExceptionAddr = 'h10C;
- 
-   logic [dm::ProgBufSize/2-1:0][63:0]   progbuf;
-   logic [4:0][63:0]   abstract_cmd;
-@@ -206,23 +208,23 @@ module dm_mem #(
-       // this is a write
-       if (we_i) begin
-         unique case (addr_i[DbgAddressBits-1:0]) inside
--          Halted: begin
-+          HaltedAddr: begin
-             halted[hart_sel] = 1'b1;
-             halted_d[hart_sel] = 1'b1;
-           end
--          Going: begin
-+          GoingAddr: begin
-             going = 1'b1;
-           end
--          Resuming: begin
-+          ResumingAddr: begin
-             // clear the halted flag as the hart resumed execution
-             halted_d[hart_sel] = 1'b0;
-             // set the resuming flag which needs to be cleared by the debugger
-             resuming_d[hart_sel] = 1'b1;
-           end
-           // an exception occurred during execution
--          Exception: exception = 1'b1;
-+          ExceptionAddr: exception = 1'b1;
-           // core can write data registers
--          [(dm::DataAddr):DataEnd]: begin
-+          [(dm::DataAddr):DataEndAddr]: begin
-             data_valid_o = 1'b1;
-             for (int i = 0; i < $bits(be_i); i++) begin
-               if (be_i[i]) begin
-@@ -237,10 +239,10 @@ module dm_mem #(
-       end else begin
-         unique case (addr_i[DbgAddressBits-1:0]) inside
-           // variable ROM content
--          WhereTo: begin
-+          WhereToAddr: begin
-             // variable jump to abstract cmd, program_buffer or resume
-             if (resumereq_i[hart_sel]) begin
--              rdata_d = {32'b0, dm::jal('0, dm::ResumeAddress[11:0]-WhereTo)};
-+              rdata_d = {32'b0, dm::jal('0, dm::ResumeAddress[11:0]-WhereToAddr)};
-             end
- 
-             // there is a command active so jump there
-@@ -249,38 +251,38 @@ module dm_mem #(
-               // keep this statement narrow to not catch invalid commands
-               if (cmd_i.cmdtype == dm::AccessRegister &&
-                   !ac_ar.transfer && ac_ar.postexec) begin
--                rdata_d = {32'b0, dm::jal('0, ProgBufBase-WhereTo)};
-+                rdata_d = {32'b0, dm::jal('0, ProgBufBaseAddr-WhereToAddr)};
-               // this is a legit abstract cmd -> execute it
-               end else begin
--                rdata_d = {32'b0, dm::jal('0, AbstractCmdBase-WhereTo)};
-+                rdata_d = {32'b0, dm::jal('0, AbstractCmdBaseAddr-WhereToAddr)};
-               end
-             end
-           end
- 
--          [DataBase:DataEnd]: begin
-+          [DataBaseAddr:DataEndAddr]: begin
-             rdata_d = {
--                      data_i[(addr_i[DbgAddressBits-1:3] - DataBase[DbgAddressBits-1:3] + 1)],
--                      data_i[(addr_i[DbgAddressBits-1:3] - DataBase[DbgAddressBits-1:3])]
-+                      data_i[(addr_i[DbgAddressBits-1:3] - DataBaseAddr[DbgAddressBits-1:3] + 1)],
-+                      data_i[(addr_i[DbgAddressBits-1:3] - DataBaseAddr[DbgAddressBits-1:3])]
-                       };
-           end
- 
--          [ProgBufBase:ProgBufEnd]: begin
-+          [ProgBufBaseAddr:ProgBufEndAddr]: begin
-             rdata_d = progbuf[(addr_i[DbgAddressBits-1:3] -
--                          ProgBufBase[DbgAddressBits-1:3])];
-+                          ProgBufBaseAddr[DbgAddressBits-1:3])];
-           end
- 
-           // two slots for abstract command
--          [AbstractCmdBase:AbstractCmdEnd]: begin
-+          [AbstractCmdBaseAddr:AbstractCmdEndAddr]: begin
-             // return the correct address index
-             rdata_d = abstract_cmd[(addr_i[DbgAddressBits-1:3] -
--                           AbstractCmdBase[DbgAddressBits-1:3])];
-+                           AbstractCmdBaseAddr[DbgAddressBits-1:3])];
-           end
-           // harts are polling for flags here
--          [FlagsBase:FlagsEnd]: begin
-+          [FlagsBaseAddr:FlagsEndAddr]: begin
-             automatic logic [7:0][7:0] rdata;
-             rdata = '0;
-             // release the corresponding hart
--            if (({addr_i[DbgAddressBits-1:3], 3'b0} - FlagsBase[DbgAddressBits-1:0]) ==
-+            if (({addr_i[DbgAddressBits-1:3], 3'b0} - FlagsBaseAddr[DbgAddressBits-1:0]) ==
-                 {hartsel_i[DbgAddressBits-1:3], 3'b0}) begin
-               rdata[hartsel_i[2:0]] = {6'b0, resume, go};
-             end
-diff --git a/src/dm_sba.sv b/src/dm_sba.sv
-index 12b1951..c143ba1 100644
---- a/src/dm_sba.sv
-+++ b/src/dm_sba.sv
-@@ -16,7 +16,7 @@
- *
- */
- module dm_sba #(
--  parameter int BusWidth = -1
-+  parameter int unsigned BusWidth = 32
- ) (
-   input  logic                   clk_i,       // Clock
-   input  logic                   rst_ni,
-diff --git a/src/dm_top.sv b/src/dm_top.sv
-index 6c7fa49..dd06a23 100644
---- a/src/dm_top.sv
-+++ b/src/dm_top.sv
-@@ -18,11 +18,11 @@
- */
- 
- module dm_top #(
--  parameter int                 NrHarts          = 1,
--  parameter int                 BusWidth         = 32,
--  parameter logic [NrHarts-1:0] SelectableHarts  = 1  // Bitmask to select physically available harts for systems
--                                                      // that don't use hart numbers in a contiguous fashion.
--
-+  parameter int unsigned        NrHarts          = 1,
-+  parameter int unsigned        BusWidth         = 32,
-+  // Bitmask to select physically available harts for systems
-+  // that don't use hart numbers in a contiguous fashion.
-+  parameter logic [NrHarts-1:0] SelectableHarts  = {NrHarts{1'b1}}
- ) (
-   input  logic                  clk_i,       // clock
-   input  logic                  rst_ni,      // asynchronous reset active low, connect PoR here, not the system reset
-diff --git a/src/dmi_jtag_tap.sv b/src/dmi_jtag_tap.sv
-index bd447f6..c39fc43 100644
---- a/src/dmi_jtag_tap.sv
-+++ b/src/dmi_jtag_tap.sv
-@@ -17,7 +17,7 @@
-  */
- 
- module dmi_jtag_tap #(
--  parameter int IrLength = 5,
-+  parameter int unsigned IrLength = 5,
-   // JTAG IDCODE Value
-   parameter logic [31:0] IdcodeValue = 32'h00000001
-   // xxxx             version
--- 
-2.17.1
-
diff --git a/hw/vendor/patches/pulp_riscv_dbg/0005-lint-cleanup-Simplify-some-statements.patch b/hw/vendor/patches/pulp_riscv_dbg/0005-lint-cleanup-Simplify-some-statements.patch
deleted file mode 100644
index 65ca615..0000000
--- a/hw/vendor/patches/pulp_riscv_dbg/0005-lint-cleanup-Simplify-some-statements.patch
+++ /dev/null
@@ -1,209 +0,0 @@
-From 2d91bb21434ee8b66eed93e5a9c52b29defdc525 Mon Sep 17 00:00:00 2001
-From: Michael Schaffner <msf@google.com>
-Date: Thu, 17 Oct 2019 18:07:55 -0700
-Subject: [PATCH 05/11] [lint/cleanup] Simplify some statements
-
----
- src/dm_csrs.sv | 17 ++++-------------
- src/dm_mem.sv  | 34 ++++++++++++++++++----------------
- src/dm_sba.sv  |  2 +-
- src/dm_top.sv  | 38 +++++++++++++++++++-------------------
- 4 files changed, 42 insertions(+), 49 deletions(-)
-
-diff --git a/src/dm_csrs.sv b/src/dm_csrs.sv
-index ffa45ba..a6b1c6d 100644
---- a/src/dm_csrs.sv
-+++ b/src/dm_csrs.sv
-@@ -194,8 +194,8 @@ module dm_csrs #(
- 
-     // as soon as we are out of the legal Hart region tell the debugger
-     // that there are only non-existent harts
--    dmstatus.allnonexistent = (hartsel_o > (NrHarts - 1)) ? 1'b1 : 1'b0;
--    dmstatus.anynonexistent = (hartsel_o > (NrHarts - 1)) ? 1'b1 : 1'b0;
-+    dmstatus.allnonexistent = logic'(hartsel_o > (NrHarts - 1));
-+    dmstatus.anynonexistent = logic'(hartsel_o > (NrHarts - 1));
- 
-     // We are not allowed to be in multiple states at once. This is a to
-     // make the running/halted and unavailable states exclusive.
-@@ -534,7 +534,9 @@ module dm_csrs #(
-       sbcs_q         <= '0;
-       sbaddr_q       <= '0;
-       sbdata_q       <= '0;
-+      havereset_q    <= '1;
-     end else begin
-+      havereset_q    <= SelectableHarts & havereset_d;
-       // synchronous re-set of debug module, active-low, except for dmactive
-       if (!dmcontrol_q.dmactive) begin
-         dmcontrol_q.haltreq          <= '0;
-@@ -574,17 +576,6 @@ module dm_csrs #(
-     end
-   end
- 
--
--  for (genvar k = 0; k < NrHarts; k++) begin : gen_havereset
--    always_ff @(posedge clk_i or negedge rst_ni) begin
--      if (!rst_ni) begin
--        havereset_q[k] <= 1'b1;
--      end else begin
--        havereset_q[k] <= SelectableHarts[k] ? havereset_d[k] : 1'b0;
--      end
--    end
--  end
--
- ///////////////////////////////////////////////////////
- // assertions
- ///////////////////////////////////////////////////////
-diff --git a/src/dm_mem.sv b/src/dm_mem.sv
-index 9de08d4..bba5234 100644
---- a/src/dm_mem.sv
-+++ b/src/dm_mem.sv
-@@ -180,17 +180,22 @@ module dm_mem #(
-     end
-   end
- 
-+  // word mux for 32bit and 64bit buses
-+  logic [63:0] word_mux;
-+  assign word_mux = (fwd_rom_q) ? rom_rdata : rdata_q;
-+
-+  if (BusWidth == 64) begin : gen_word_mux64
-+    assign rdata_o = word_mux;
-+  end else begin : gen_word_mux32
-+    assign rdata_o = (word_enable32_q) ? word_mux[32 +: 32] : word_mux[0 +: 32];
-+  end
-+
-   // read/write logic
-   always_comb begin : p_rw_logic
-     automatic logic [63:0] data_bits;
- 
-     halted_d     = halted_q;
-     resuming_d   = resuming_q;
--    rdata_o      = (BusWidth == 64) ?
--                      (fwd_rom_q ? rom_rdata : rdata_q) :
--                      (word_enable32_q ?
--                          (fwd_rom_q ? rom_rdata[63:32] : rdata_q[63:32]) :
--                          (fwd_rom_q ? rom_rdata[31: 0] : rdata_q[31: 0]));
-     rdata_d      = rdata_q;
-     // convert the data in bits representation
-     data_bits    = data_i;
-@@ -438,8 +443,7 @@ module dm_mem #(
- 
-   // ROM starts at the HaltAddress of the core e.g.: it immediately jumps to
-   // the ROM base address
--  assign fwd_rom_d = (addr_i[DbgAddressBits-1:0] >= dm::HaltAddress[DbgAddressBits-1:0]) ?
--                     1'b1 : 1'b0;
-+  assign fwd_rom_d = logic'(addr_i[DbgAddressBits-1:0] >= dm::HaltAddress[DbgAddressBits-1:0]);
- 
-   always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
-     if (!rst_ni) begin
-@@ -455,15 +459,13 @@ module dm_mem #(
-     end
-   end
- 
--  for (genvar k = 0; k < NrHarts; k++) begin : gen_halted
--    always_ff @(posedge clk_i or negedge rst_ni) begin
--      if (!rst_ni) begin
--        halted_q[k]   <= 1'b0;
--        resuming_q[k] <= 1'b0;
--      end else begin
--        halted_q[k]   <= SelectableHarts[k] ? halted_d[k]   : 1'b0;
--        resuming_q[k] <= SelectableHarts[k] ? resuming_d[k] : 1'b0;
--      end
-+  always_ff @(posedge clk_i or negedge rst_ni) begin
-+    if (!rst_ni) begin
-+      halted_q   <= 1'b0;
-+      resuming_q <= 1'b0;
-+    end else begin
-+      halted_q   <= SelectableHarts & halted_d;
-+      resuming_q <= SelectableHarts & resuming_d;
-     end
-   end
- 
-diff --git a/src/dm_sba.sv b/src/dm_sba.sv
-index c143ba1..9fb445e 100644
---- a/src/dm_sba.sv
-+++ b/src/dm_sba.sv
-@@ -61,7 +61,7 @@ module dm_sba #(
-   logic                  we;
-   logic [BusWidth/8-1:0] be;
- 
--  assign sbbusy_o = (state_q != Idle) ? 1'b1 : 1'b0;
-+  assign sbbusy_o = logic'(state_q != Idle);
- 
-   always_comb begin : p_fsm
-     req     = 1'b0;
-diff --git a/src/dm_top.sv b/src/dm_top.sv
-index dd06a23..e375101 100644
---- a/src/dm_top.sv
-+++ b/src/dm_top.sv
-@@ -101,9 +101,9 @@ module dm_top #(
-     .BusWidth(BusWidth),
-     .SelectableHarts(SelectableHarts)
-   ) i_dm_csrs (
--    .clk_i                   ( clk_i                 ),
--    .rst_ni                  ( rst_ni                ),
--    .testmode_i              ( testmode_i            ),
-+    .clk_i,
-+    .rst_ni,
-+    .testmode_i,
-     .dmi_rst_ni,
-     .dmi_req_valid_i,
-     .dmi_req_ready_o,
-@@ -111,10 +111,10 @@ module dm_top #(
-     .dmi_resp_valid_o,
-     .dmi_resp_ready_i,
-     .dmi_resp_o,
--    .ndmreset_o              ( ndmreset_o            ),
--    .dmactive_o              ( dmactive_o            ),
-+    .ndmreset_o,
-+    .dmactive_o,
-     .hartsel_o               ( hartsel               ),
--    .hartinfo_i              ( hartinfo_i            ),
-+    .hartinfo_i,
-     .halted_i                ( halted                ),
-     .unavailable_i,
-     .resumeack_i             ( resumeack             ),
-@@ -150,18 +150,18 @@ module dm_top #(
-   dm_sba #(
-     .BusWidth(BusWidth)
-   ) i_dm_sba (
--    .clk_i                   ( clk_i                 ),
--    .rst_ni                  ( rst_ni                ),
-+    .clk_i,
-+    .rst_ni,
-     .dmactive_i              ( dmactive_o            ),
- 
--    .master_req_o            ( master_req_o          ),
--    .master_add_o            ( master_add_o          ),
--    .master_we_o             ( master_we_o           ),
--    .master_wdata_o          ( master_wdata_o        ),
--    .master_be_o             ( master_be_o           ),
--    .master_gnt_i            ( master_gnt_i          ),
--    .master_r_valid_i        ( master_r_valid_i      ),
--    .master_r_rdata_i        ( master_r_rdata_i      ),
-+    .master_req_o,
-+    .master_add_o,
-+    .master_we_o,
-+    .master_wdata_o,
-+    .master_be_o,
-+    .master_gnt_i,
-+    .master_r_valid_i,
-+    .master_r_rdata_i,
- 
-     .sbaddress_i             ( sbaddress_csrs_sba    ),
-     .sbaddress_o             ( sbaddress_sba_csrs    ),
-@@ -185,9 +185,9 @@ module dm_top #(
-     .BusWidth(BusWidth),
-     .SelectableHarts(SelectableHarts)
-   ) i_dm_mem (
--    .clk_i                   ( clk_i                 ),
--    .rst_ni                  ( rst_ni                ),
--    .debug_req_o             ( debug_req_o           ),
-+    .clk_i,
-+    .rst_ni,
-+    .debug_req_o,
-     .hartsel_i               ( hartsel               ),
-     .haltreq_i               ( haltreq               ),
-     .resumereq_i             ( resumereq             ),
--- 
-2.17.1
-
diff --git a/hw/vendor/patches/pulp_riscv_dbg/0006-lint-cleanup-Fix-several-lint-errors-warnings.patch b/hw/vendor/patches/pulp_riscv_dbg/0006-lint-cleanup-Fix-several-lint-errors-warnings.patch
deleted file mode 100644
index 787efdb..0000000
--- a/hw/vendor/patches/pulp_riscv_dbg/0006-lint-cleanup-Fix-several-lint-errors-warnings.patch
+++ /dev/null
@@ -1,736 +0,0 @@
-From c1d4cdedb11f185e967fda782b1b18093bf1f5ab Mon Sep 17 00:00:00 2001
-From: Michael Schaffner <msf@google.com>
-Date: Thu, 17 Oct 2019 18:12:59 -0700
-Subject: [PATCH 06/11] [lint/cleanup] Fix several lint errors / warnings
-
-This fixes several lint errors and warnings, most of which are related to
-array indexing operations that are out of range.
----
- src/dm_csrs.sv      | 158 +++++++++++++++++++++++++++++---------------
- src/dm_mem.sv       |  95 ++++++++++++++++----------
- src/dmi_jtag.sv     |   4 +-
- src/dmi_jtag_tap.sv |  30 +++++----
- 4 files changed, 182 insertions(+), 105 deletions(-)
-
-diff --git a/src/dm_csrs.sv b/src/dm_csrs.sv
-index a6b1c6d..54cbc1a 100644
---- a/src/dm_csrs.sv
-+++ b/src/dm_csrs.sv
-@@ -80,6 +80,8 @@ module dm_csrs #(
- );
-   // the amount of bits we need to represent all harts
-   localparam int unsigned HartSelLen = (NrHarts == 1) ? 1 : $clog2(NrHarts);
-+  localparam int unsigned NrHartsAligned = 2**HartSelLen;
-+
-   dm::dtm_op_e dtm_op;
-   assign dtm_op = dm::dtm_op_e'(dmi_req_i.op);
- 
-@@ -102,35 +104,56 @@ module dm_csrs #(
-   logic [32-1:0] halted_flat3;
- 
-   // haltsum0
-+  logic [14:0] hartsel_idx0;
-   always_comb begin : p_haltsum0
-     halted              = '0;
-+    haltsum0            = '0;
-+    hartsel_idx0        = hartsel_o[19:5];
-     halted[NrHarts-1:0] = halted_i;
-     halted_reshaped0    = halted;
--    haltsum0            = halted_reshaped0[hartsel_o[19:5]];
-+    if (hartsel_idx0 < (NrHarts-1)/2**5+1) begin
-+      haltsum0 = halted_reshaped0[hartsel_idx0];
-+    end
-   end
- 
-   // haltsum1
-+  logic [9:0] hartsel_idx1;
-   always_comb begin : p_reduction1
-     halted_flat1 = '0;
--    for (int unsigned k=0; k<NrHarts/2**5+1; k++) begin
-+    haltsum1     = '0;
-+    hartsel_idx1 = hartsel_o[19:10];
-+
-+    for (int unsigned k = 0; k < NrHarts/2**5+1; k++) begin
-       halted_flat1[k] = |halted_reshaped0[k];
-     end
-     halted_reshaped1 = halted_flat1;
--    haltsum1         = halted_reshaped1[hartsel_o[19:10]];
-+
-+    if (hartsel_idx1 < (NrHarts/2**10+1)) begin
-+      haltsum1 = halted_reshaped1[hartsel_idx1];
-+    end
-   end
-+
-   // haltsum2
-+  logic [4:0] hartsel_idx2;
-   always_comb begin : p_reduction2
-     halted_flat2 = '0;
--    for (int unsigned k=0; k<NrHarts/2**10+1; k++) begin
-+    haltsum2     = '0;
-+    hartsel_idx2 = hartsel_o[19:15];
-+
-+    for (int unsigned k = 0; k < NrHarts/2**10+1; k++) begin
-       halted_flat2[k] = |halted_reshaped1[k];
-     end
-     halted_reshaped2 = halted_flat2;
--    haltsum2         = halted_reshaped2[hartsel_o[19:15]];
-+
-+    if (hartsel_idx2 < (NrHarts/2**15+1)) begin
-+      haltsum2         = halted_reshaped2[hartsel_idx2];
-+    end
-   end
-+
-   // haltsum3
-   always_comb begin : p_reduction3
-     halted_flat3 = '0;
--    for (int unsigned k=0; k<NrHarts/2**15+1; k++) begin
-+    for (int unsigned k = 0; k < NrHarts/2**15+1; k++) begin
-       halted_flat3[k] = |halted_reshaped2[k];
-     end
-     haltsum3 = halted_flat3;
-@@ -151,8 +174,7 @@ module dm_csrs #(
-   logic [NrHarts-1:0] havereset_d, havereset_q;
-   // program buffer
-   logic [dm::ProgBufSize-1:0][31:0] progbuf_d, progbuf_q;
--  // because first data address starts at 0x04
--  logic [({3'b0, dm::DataCount} + dm::Data0 - 1):(dm::Data0)][31:0] data_d, data_q;
-+  logic [dm::DataCount-1:0][31:0] data_d, data_q;
- 
-   logic [HartSelLen-1:0] selected_hart;
- 
-@@ -171,6 +193,27 @@ module dm_csrs #(
- 
-   assign hartsel_o         = {dmcontrol_q.hartselhi, dmcontrol_q.hartsello};
- 
-+  // needed to avoid lint warnings
-+  logic [NrHartsAligned-1:0] havereset_d_aligned, havereset_q_aligned,
-+                             resumeack_aligned, unavailable_aligned,
-+                             halted_aligned;
-+  assign resumeack_aligned   = NrHartsAligned'(resumeack_i);
-+  assign unavailable_aligned = NrHartsAligned'(unavailable_i);
-+  assign halted_aligned      = NrHartsAligned'(halted_i);
-+
-+  assign havereset_d         = NrHarts'(havereset_d_aligned);
-+  assign havereset_q_aligned = NrHartsAligned'(havereset_q);
-+
-+  dm::hartinfo_t [NrHartsAligned-1:0] hartinfo_aligned;
-+  always_comb begin : p_hartinfo_align
-+    hartinfo_aligned = '0;
-+    hartinfo_aligned[NrHarts-1:0] = hartinfo_i;
-+  end
-+
-+  // helper variables
-+  dm::sbcs_t sbcs;
-+  dm::dmcontrol_t dmcontrol;
-+  dm::abstractcs_t a_abstractcs;
-   always_comb begin : csr_read_write
-     // --------------------
-     // Static Values (R/O)
-@@ -183,14 +226,14 @@ module dm_csrs #(
-     // we do not support halt-on-reset sequence
-     dmstatus.hasresethaltreq = 1'b0;
-     // TODO(zarubaf) things need to change here if we implement the array mask
--    dmstatus.allhavereset = havereset_q[selected_hart];
--    dmstatus.anyhavereset = havereset_q[selected_hart];
-+    dmstatus.allhavereset = havereset_q_aligned[selected_hart];
-+    dmstatus.anyhavereset = havereset_q_aligned[selected_hart];
- 
--    dmstatus.allresumeack = resumeack_i[selected_hart];
--    dmstatus.anyresumeack = resumeack_i[selected_hart];
-+    dmstatus.allresumeack = resumeack_aligned[selected_hart];
-+    dmstatus.anyresumeack = resumeack_aligned[selected_hart];
- 
--    dmstatus.allunavail   = unavailable_i[selected_hart];
--    dmstatus.anyunavail   = unavailable_i[selected_hart];
-+    dmstatus.allunavail   = unavailable_aligned[selected_hart];
-+    dmstatus.anyunavail   = unavailable_aligned[selected_hart];
- 
-     // as soon as we are out of the legal Hart region tell the debugger
-     // that there are only non-existent harts
-@@ -199,11 +242,11 @@ module dm_csrs #(
- 
-     // We are not allowed to be in multiple states at once. This is a to
-     // make the running/halted and unavailable states exclusive.
--    dmstatus.allhalted    = halted_i[selected_hart] & ~unavailable_i[selected_hart];
--    dmstatus.anyhalted    = halted_i[selected_hart] & ~unavailable_i[selected_hart];
-+    dmstatus.allhalted    = halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
-+    dmstatus.anyhalted    = halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
- 
--    dmstatus.allrunning   = ~halted_i[selected_hart] & ~unavailable_i[selected_hart];
--    dmstatus.anyrunning   = ~halted_i[selected_hart] & ~unavailable_i[selected_hart];
-+    dmstatus.allrunning   = ~halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
-+    dmstatus.anyrunning   = ~halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
- 
-     // abstractcs
-     abstractcs = '0;
-@@ -217,15 +260,15 @@ module dm_csrs #(
-     abstractauto_d.zero0 = '0;
- 
-     // default assignments
--    havereset_d = havereset_q;
--    dmcontrol_d = dmcontrol_q;
--    cmderr_d    = cmderr_q;
--    command_d   = command_q;
--    progbuf_d   = progbuf_q;
--    data_d      = data_q;
--    sbcs_d      = sbcs_q;
--    sbaddr_d    = sbaddress_i;
--    sbdata_d    = sbdata_q;
-+    havereset_d_aligned = NrHartsAligned'(havereset_q);
-+    dmcontrol_d         = dmcontrol_q;
-+    cmderr_d            = cmderr_q;
-+    command_d           = command_q;
-+    progbuf_d           = progbuf_q;
-+    data_d              = data_q;
-+    sbcs_d              = sbcs_q;
-+    sbaddr_d            = 64'(sbaddress_i);
-+    sbdata_d            = sbdata_q;
- 
-     resp_queue_data         = 32'b0;
-     cmd_valid_d             = 1'b0;
-@@ -234,13 +277,19 @@ module dm_csrs #(
-     sbdata_write_valid_o    = 1'b0;
-     clear_resumeack_o       = 1'b0;
- 
-+    // helper variables
-+    sbcs         = '0;
-+    dmcontrol    = '0;
-+    a_abstractcs = '0;
-+
-+    // localparam int unsigned DataCountAlign = $clog2(dm::DataCount);
-     // reads
-     if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_READ) begin
-       unique case ({1'b0, dmi_req_i.addr}) inside
-         [(dm::Data0):DataEnd]: begin
--          if (dm::DataCount > 0) begin
--            resp_queue_data = data_q[dmi_req_i.addr[4:0]];
--          end
-+          // logic [$clog2(dm::DataCount)-1:0] resp_queue_idx;
-+          // resp_queue_idx = dmi_req_i.addr[4:0] - int'(dm::Data0);
-+          resp_queue_data = data_q[dmi_req_i.addr[4:0] - int'(dm::Data0)];
-           if (!cmdbusy_i) begin
-             // check whether we need to re-execute the command (just give a cmd_valid)
-             cmd_valid_d = abstractauto_q.autoexecdata[dmi_req_i.addr[3:0] -
-@@ -249,13 +298,13 @@ module dm_csrs #(
-         end
-         dm::DMControl:    resp_queue_data = dmcontrol_q;
-         dm::DMStatus:     resp_queue_data = dmstatus;
--        dm::Hartinfo:     resp_queue_data = hartinfo_i[selected_hart];
-+        dm::Hartinfo:     resp_queue_data = hartinfo_aligned[selected_hart];
-         dm::AbstractCS:   resp_queue_data = abstractcs;
-         dm::AbstractAuto: resp_queue_data = abstractauto_q;
-         // command is read-only
-         dm::Command:    resp_queue_data = '0;
-         [(dm::ProgBuf0):ProgBufEnd]: begin
--          resp_queue_data = progbuf_q[dmi_req_i.addr[4:0]];
-+          resp_queue_data = progbuf_q[dmi_req_i.addr[$clog2(dm::ProgBufSize)-1:0]];
-           if (!cmdbusy_i) begin
-             // check whether we need to re-execute the command (just give a cmd_valid)
-             // TODO(zarubaf): check if offset is correct: without it this may assign Xes
-@@ -284,11 +333,11 @@ module dm_csrs #(
-           end else begin
-             resp_queue_data = sbaddr_q[63:32];
-           end
--      end
-+        end
-         dm::SBData0: begin
-           // access while the SBA was busy
-           if (sbbusy_i) begin
--           sbcs_d.sbbusyerror = 1'b1;
-+            sbcs_d.sbbusyerror = 1'b1;
-           end else begin
-             sbdata_read_valid_o = (sbcs_q.sberror == '0);
-             resp_queue_data = sbdata_q[31:0];
-@@ -312,18 +361,16 @@ module dm_csrs #(
-         [(dm::Data0):DataEnd]: begin
-           // attempts to write them while busy is set does not change their value
-           if (!cmdbusy_i && dm::DataCount > 0) begin
--              data_d[dmi_req_i.addr[4:0]] = dmi_req_i.data;
--              // check whether we need to re-execute the command (just give a cmd_valid)
--              cmd_valid_d = abstractauto_q.autoexecdata[dmi_req_i.addr[3:0] -
--                            int'(dm::Data0)];
-+            data_d[dmi_req_i.addr[$clog2(dm::DataCount)-1:0]] = dmi_req_i.data;
-+            // check whether we need to re-execute the command (just give a cmd_valid)
-+            cmd_valid_d = abstractauto_q.autoexecdata[dmi_req_i.addr[3:0] - int'(dm::Data0)];
-           end
-         end
-         dm::DMControl: begin
--          automatic dm::dmcontrol_t dmcontrol;
-           dmcontrol = dm::dmcontrol_t'(dmi_req_i.data);
-           // clear the havreset of the selected hart
-           if (dmcontrol.ackhavereset) begin
--              havereset_d[selected_hart] = 1'b0;
-+            havereset_d_aligned[selected_hart] = 1'b0;
-           end
-           dmcontrol_d = dmi_req_i.data;
-         end
-@@ -335,7 +382,6 @@ module dm_csrs #(
-           // field remain set until they are cleared by writing 1 to
-           // them. No abstract command is started until the value is
-           // reset to 0.
--          automatic dm::abstractcs_t a_abstractcs;
-           a_abstractcs = dm::abstractcs_t'(dmi_req_i.data);
-           // reads during abstract command execution are not allowed
-           if (!cmdbusy_i) begin
-@@ -368,7 +414,7 @@ module dm_csrs #(
-         [(dm::ProgBuf0):ProgBufEnd]: begin
-           // attempts to write them while busy is set does not change their value
-           if (!cmdbusy_i) begin
--            progbuf_d[dmi_req_i.addr[4:0]] = dmi_req_i.data;
-+            progbuf_d[dmi_req_i.addr[$clog2(dm::ProgBufSize)-1:0]] = dmi_req_i.data;
-             // check whether we need to re-execute the command (just give a cmd_valid)
-             // this should probably throw an error if executed during another command
-             // was busy
-@@ -382,7 +428,6 @@ module dm_csrs #(
-           if (sbbusy_i) begin
-             sbcs_d.sbbusyerror = 1'b1;
-           end else begin
--            automatic dm::sbcs_t sbcs;
-             sbcs = dm::sbcs_t'(dmi_req_i.data);
-             sbcs_d = sbcs;
-             // R/W1C
-@@ -410,7 +455,7 @@ module dm_csrs #(
-         dm::SBData0: begin
-           // access while the SBA was busy
-           if (sbbusy_i) begin
--            sbcs_d.sbbusyerror = 1'b1;
-+           sbcs_d.sbbusyerror = 1'b1;
-           end else begin
-             sbdata_d[31:0] = dmi_req_i.data;
-             sbdata_write_valid_o = (sbcs_q.sberror == '0);
-@@ -439,7 +484,7 @@ module dm_csrs #(
- 
-     // set the havereset flag when we did a ndmreset
-     if (ndmreset_o) begin
--      havereset_d = '1;
-+      havereset_d_aligned[NrHarts-1:0] = '1;
-     end
-     // -------------
-     // System Bus
-@@ -488,8 +533,10 @@ module dm_csrs #(
-     // default assignment
-     haltreq_o = '0;
-     resumereq_o = '0;
--    haltreq_o[selected_hart] = dmcontrol_q.haltreq;
--    resumereq_o[selected_hart] = dmcontrol_q.resumereq;
-+    if (selected_hart < NrHarts) begin
-+      haltreq_o[selected_hart]   = dmcontrol_q.haltreq;
-+      resumereq_o[selected_hart] = dmcontrol_q.resumereq;
-+    end
-   end
- 
-   assign dmactive_o  = dmcontrol_q.dmactive;
-@@ -521,7 +568,7 @@ module dm_csrs #(
-     .pop_i            ( resp_queue_pop       )
-   );
- 
--  always_ff @(posedge clk_i or negedge rst_ni) begin
-+  always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
-     // PoR
-     if (!rst_ni) begin
-       dmcontrol_q    <= '0;
-@@ -542,6 +589,7 @@ module dm_csrs #(
-         dmcontrol_q.haltreq          <= '0;
-         dmcontrol_q.resumereq        <= '0;
-         dmcontrol_q.hartreset        <= '0;
-+        dmcontrol_q.ackhavereset     <= '0;
-         dmcontrol_q.zero1            <= '0;
-         dmcontrol_q.hasel            <= '0;
-         dmcontrol_q.hartsello        <= '0;
-@@ -576,19 +624,19 @@ module dm_csrs #(
-     end
-   end
- 
--///////////////////////////////////////////////////////
--// assertions
--///////////////////////////////////////////////////////
-+  ///////////////////////////////////////////////////////
-+  // assertions
-+  ///////////////////////////////////////////////////////
- 
--//pragma translate_off
--`ifndef VERILATOR
-+  //pragma translate_off
-+  `ifndef VERILATOR
-   haltsum: assert property (
-       @(posedge clk_i) disable iff (!rst_ni)
-           (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_READ) |->
-               !({1'b0, dmi_req_i.addr} inside
-                   {dm::HaltSum0, dm::HaltSum1, dm::HaltSum2, dm::HaltSum3}))
-       else $warning("Haltsums have not been properly tested yet.");
--`endif
--//pragma translate_on
-+  `endif
-+  //pragma translate_on
- 
- endmodule : dm_csrs
-diff --git a/src/dm_mem.sv b/src/dm_mem.sv
-index bba5234..c6d4059 100644
---- a/src/dm_mem.sv
-+++ b/src/dm_mem.sv
-@@ -56,7 +56,6 @@ module dm_mem #(
-   input  logic [BusWidth/8-1:0]            be_i,
-   output logic [BusWidth-1:0]              rdata_o
- );
--
-   localparam int unsigned DbgAddressBits = 12;
-   localparam int unsigned HartSelLen     = (NrHarts == 1) ? 1 : $clog2(NrHarts);
-   localparam int unsigned NrHartsAligned = 2**HartSelLen;
-@@ -79,13 +78,11 @@ module dm_mem #(
-   localparam logic [DbgAddressBits-1:0] ExceptionAddr = 'h10C;
- 
-   logic [dm::ProgBufSize/2-1:0][63:0]   progbuf;
--  logic [4:0][63:0]   abstract_cmd;
-+  logic [7:0][63:0]   abstract_cmd;
-   logic [NrHarts-1:0] halted_d, halted_q;
-   logic [NrHarts-1:0] resuming_d, resuming_q;
-   logic               resume, go, going;
--  logic [NrHarts-1:0] halted;
- 
--  logic [HartSelLen-1:0] hart_sel;
-   logic exception;
-   logic unsupported_command;
- 
-@@ -93,6 +90,27 @@ module dm_mem #(
-   logic [63:0] rdata_d, rdata_q;
-   logic        word_enable32_q;
- 
-+  // this is needed to avoid lint warnings related to array indexing
-+  // resize hartsel to valid range
-+  logic [HartSelLen-1:0] hartsel, wdata_hartsel;
-+
-+  assign hartsel       = hartsel_i[HartSelLen-1:0];
-+  assign wdata_hartsel = wdata_i[HartSelLen-1:0];
-+
-+  logic [NrHartsAligned-1:0] resumereq_aligned, haltreq_aligned,
-+                             halted_d_aligned, halted_q_aligned,
-+                             halted_aligned, resumereq_wdata_aligned,
-+                             resuming_d_aligned, resuming_q_aligned;
-+
-+  assign resumereq_aligned       = NrHartsAligned'(resumereq_i);
-+  assign haltreq_aligned         = NrHartsAligned'(haltreq_i);
-+  assign resumereq_wdata_aligned = NrHartsAligned'(resumereq_i);
-+
-+  assign halted_q_aligned        = NrHartsAligned'(halted_q);
-+  assign halted_d                = NrHarts'(halted_d_aligned);
-+  assign resuming_q_aligned      = NrHartsAligned'(resuming_q);
-+  assign resuming_d              = NrHarts'(resuming_d_aligned);
-+
-   // distinguish whether we need to forward data from the ROM or the FSM
-   // latch the address for this
-   logic fwd_rom_d, fwd_rom_q;
-@@ -100,7 +118,6 @@ module dm_mem #(
- 
-   // Abstract Command Access Register
-   assign ac_ar       = dm::ac_ar_cmd_t'(cmd_i.control);
--  assign hart_sel    = wdata_i[HartSelLen-1:0];
-   assign debug_req_o = haltreq_i;
-   assign halted_o    = halted_q;
-   assign resuming_o  = resuming_q;
-@@ -123,7 +140,7 @@ module dm_mem #(
-     case (state_q)
-       Idle: begin
-         cmdbusy_o = 1'b0;
--        if (cmd_valid_i && halted_q[hartsel_i]) begin
-+        if (cmd_valid_i && halted_q_aligned[hartsel]) begin
-           // give the go signal
-           state_d = Go;
-         end else if (cmd_valid_i) begin
-@@ -133,8 +150,8 @@ module dm_mem #(
-         end
-         // CSRs want to resume, the request is ignored when the hart is
-         // requested to halt or it didn't clear the resuming_q bit before
--        if (resumereq_i[hartsel_i] && !resuming_q[hartsel_i] &&
--             !haltreq_i[hartsel_i] &&    halted_q[hartsel_i]) begin
-+        if (resumereq_aligned[hartsel] && !resuming_q_aligned[hartsel] &&
-+            !haltreq_aligned[hartsel] && halted_q_aligned[hartsel]) begin
-           state_d = Resume;
-         end
-       end
-@@ -145,14 +162,14 @@ module dm_mem #(
-         go        = 1'b1;
-         // the thread is now executing the command, track its state
-         if (going) begin
--          state_d = CmdExecuting;
-+            state_d = CmdExecuting;
-         end
-       end
- 
-       Resume: begin
-         cmdbusy_o = 1'b1;
-         resume = 1'b1;
--        if (resuming_o[hartsel_i]) begin
-+        if (resuming_q_aligned[hartsel]) begin
-           state_d = Idle;
-         end
-       end
-@@ -161,7 +178,7 @@ module dm_mem #(
-         cmdbusy_o = 1'b1;
-         go        = 1'b0;
-         // wait until the hart has halted again
--        if (halted[hartsel_i]) begin
-+        if (halted_aligned[hartsel]) begin
-           state_d = Idle;
-         end
-       end
-@@ -191,22 +208,26 @@ module dm_mem #(
-   end
- 
-   // read/write logic
-+  logic [63:0] data_bits;
-+  logic [7:0][7:0] rdata;
-   always_comb begin : p_rw_logic
--    automatic logic [63:0] data_bits;
- 
--    halted_d     = halted_q;
--    resuming_d   = resuming_q;
--    rdata_d      = rdata_q;
-+    halted_d_aligned   = NrHartsAligned'(halted_q);
-+    resuming_d_aligned = NrHartsAligned'(resuming_q);
-+    rdata_d        = rdata_q;
-     // convert the data in bits representation
--    data_bits    = data_i;
-+    data_bits      = data_i;
-+    rdata          = '0;
-+
-     // write data in csr register
--    data_valid_o = 1'b0;
--    exception    = 1'b0;
--    halted       = '0;
--    going        = 1'b0;
-+    data_valid_o   = 1'b0;
-+    exception      = 1'b0;
-+    halted_aligned     = '0;
-+    going          = 1'b0;
-+
-     // The resume ack signal is lowered when the resume request is deasserted
-     if (clear_resumeack_i) begin
--      resuming_d[hartsel_i] = 1'b0;
-+      resuming_d_aligned[hartsel] = 1'b0;
-     end
-     // we've got a new request
-     if (req_i) begin
-@@ -214,17 +235,17 @@ module dm_mem #(
-       if (we_i) begin
-         unique case (addr_i[DbgAddressBits-1:0]) inside
-           HaltedAddr: begin
--            halted[hart_sel] = 1'b1;
--            halted_d[hart_sel] = 1'b1;
-+            halted_aligned[wdata_hartsel] = 1'b1;
-+            halted_d_aligned[wdata_hartsel] = 1'b1;
-           end
-           GoingAddr: begin
-             going = 1'b1;
-           end
-           ResumingAddr: begin
-             // clear the halted flag as the hart resumed execution
--            halted_d[hart_sel] = 1'b0;
-+            halted_d_aligned[wdata_hartsel] = 1'b0;
-             // set the resuming flag which needs to be cleared by the debugger
--            resuming_d[hart_sel] = 1'b1;
-+            resuming_d_aligned[wdata_hartsel] = 1'b1;
-           end
-           // an exception occurred during execution
-           ExceptionAddr: exception = 1'b1;
-@@ -246,7 +267,7 @@ module dm_mem #(
-           // variable ROM content
-           WhereToAddr: begin
-             // variable jump to abstract cmd, program_buffer or resume
--            if (resumereq_i[hart_sel]) begin
-+            if (resumereq_wdata_aligned[wdata_hartsel]) begin
-               rdata_d = {32'b0, dm::jal('0, dm::ResumeAddress[11:0]-WhereToAddr)};
-             end
- 
-@@ -266,30 +287,30 @@ module dm_mem #(
- 
-           [DataBaseAddr:DataEndAddr]: begin
-             rdata_d = {
--                      data_i[(addr_i[DbgAddressBits-1:3] - DataBaseAddr[DbgAddressBits-1:3] + 1)],
--                      data_i[(addr_i[DbgAddressBits-1:3] - DataBaseAddr[DbgAddressBits-1:3])]
-+                      data_i[$clog2(dm::ProgBufSize)'(addr_i[DbgAddressBits-1:3] -
-+                          DataBaseAddr[DbgAddressBits-1:3] + 1)],
-+                      data_i[$clog2(dm::ProgBufSize)'(addr_i[DbgAddressBits-1:3] -
-+                          DataBaseAddr[DbgAddressBits-1:3])]
-                       };
-           end
- 
-           [ProgBufBaseAddr:ProgBufEndAddr]: begin
--            rdata_d = progbuf[(addr_i[DbgAddressBits-1:3] -
-+            rdata_d = progbuf[$clog2(dm::ProgBufSize)'(addr_i[DbgAddressBits-1:3] -
-                           ProgBufBaseAddr[DbgAddressBits-1:3])];
-           end
- 
-           // two slots for abstract command
-           [AbstractCmdBaseAddr:AbstractCmdEndAddr]: begin
-             // return the correct address index
--            rdata_d = abstract_cmd[(addr_i[DbgAddressBits-1:3] -
-+            rdata_d = abstract_cmd[3'(addr_i[DbgAddressBits-1:3] -
-                            AbstractCmdBaseAddr[DbgAddressBits-1:3])];
-           end
-           // harts are polling for flags here
-           [FlagsBaseAddr:FlagsEndAddr]: begin
--            automatic logic [7:0][7:0] rdata;
--            rdata = '0;
-             // release the corresponding hart
-             if (({addr_i[DbgAddressBits-1:3], 3'b0} - FlagsBaseAddr[DbgAddressBits-1:0]) ==
--                {hartsel_i[DbgAddressBits-1:3], 3'b0}) begin
--              rdata[hartsel_i[2:0]] = {6'b0, resume, go};
-+              (DbgAddressBits'(hartsel) & {{(DbgAddressBits-3){1'b1}}, 3'b0})) begin
-+              rdata[DbgAddressBits'(hartsel) & 3'b111] = {6'b0, resume, go};
-             end
-             rdata_d = rdata;
-           end
-@@ -317,6 +338,7 @@ module dm_mem #(
-     abstract_cmd[3][63:32] = dm::nop();
-     abstract_cmd[4][31:0]  = dm::csrr(dm::CSR_DSCRATCH1, 5'd10);
-     abstract_cmd[4][63:32] = dm::ebreak();
-+    abstract_cmd[7:5]      = '0;
- 
-     // this depends on the command being executed
-     unique case (cmd_i.cmdtype)
-@@ -370,8 +392,8 @@ module dm_mem #(
-           abstract_cmd[0][31:0]  = dm::csrw(dm::CSR_DSCRATCH1, 5'd10);
-           // this range is reserved
-           if (ac_ar.regno[15:14] != '0) begin
--            abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap
--            unsupported_command = 1'b1;
-+              abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap
-+              unsupported_command = 1'b1;
-           // A0 access needs to be handled separately, as we use A0 to load
-           // the DM address offset need to access DSCRATCH1 in this case
-           end else if (ac_ar.regno[12] && (!ac_ar.regno[5]) &&
-@@ -413,6 +435,7 @@ module dm_mem #(
-           abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap
-           unsupported_command = 1'b1;
-         end
-+
-         // Check whether we need to execute the program buffer. When we
-         // get an unsupported command we really should abort instead of
-         // still trying to execute the program buffer, makes it easier
-diff --git a/src/dmi_jtag.sv b/src/dmi_jtag.sv
-index 5642dc1..60e67f4 100644
---- a/src/dmi_jtag.sv
-+++ b/src/dmi_jtag.sv
-@@ -195,7 +195,7 @@ module dmi_jtag #(
-     end
-   end
- 
--  always_ff @(posedge tck_i or negedge trst_ni) begin
-+  always_ff @(posedge tck_i or negedge trst_ni) begin : p_regs
-     if (!trst_ni) begin
-       dr_q      <= '0;
-       state_q   <= Idle;
-@@ -224,7 +224,7 @@ module dmi_jtag #(
-     .td_i,
-     .td_o,
-     .tdo_oe_o,
--    .testmode_i         ( testmode_i       ),
-+    .testmode_i,
-     .test_logic_reset_o ( test_logic_reset ),
-     .shift_dr_o         ( shift_dr         ),
-     .update_dr_o        ( update_dr        ),
-diff --git a/src/dmi_jtag_tap.sv b/src/dmi_jtag_tap.sv
-index c39fc43..a6fd191 100644
---- a/src/dmi_jtag_tap.sv
-+++ b/src/dmi_jtag_tap.sv
-@@ -84,9 +84,12 @@ module dmi_jtag_tap #(
-   // ----------------
-   // IR logic
-   // ----------------
--  logic [IrLength-1:0]  jtag_ir_shift_d, jtag_ir_shift_q; // shift register
--  ir_reg_e              jtag_ir_d, jtag_ir_q; // IR register -> this gets captured from shift register upon update_ir
--  logic capture_ir, shift_ir, pause_ir, update_ir;
-+
-+  // shift register
-+  logic [IrLength-1:0]  jtag_ir_shift_d, jtag_ir_shift_q;
-+  // IR register -> this gets captured from shift register upon update_ir
-+  ir_reg_e              jtag_ir_d, jtag_ir_q;
-+  logic capture_ir, shift_ir, update_ir; // pause_ir
- 
-   always_comb begin : p_jtag
-     jtag_ir_shift_d = jtag_ir_shift_q;
-@@ -138,7 +141,7 @@ module dmi_jtag_tap #(
- 
-   assign dmi_reset_o = dtmcs_q.dmireset;
- 
--  always_comb begin : p_tap_dr
-+  always_comb begin
-     idcode_d = idcode_q;
-     bypass_d = bypass_q;
-     dtmcs_d  = dtmcs_q;
-@@ -152,7 +155,7 @@ module dmi_jtag_tap #(
-                       dmihardreset : 1'b0,
-                       dmireset     : 1'b0,
-                       zero0        : '0,
--                      idle         : 'd1,         // 1: Enter Run-Test/Idle and leave it immediately
-+                      idle         : 'd1, // 1: Enter Run-Test/Idle and leave it immediately
-                       dmistat      : dmi_error_i, // 0: No error, 1: Op failed, 2: too fast
-                       abits        : 'd7, // The size of address in dmi
-                       version      : 'd1  // Version described in spec version 0.13 (and later?)
-@@ -161,9 +164,9 @@ module dmi_jtag_tap #(
-     end
- 
-     if (shift_dr_o) begin
--      if (idcode_select)  idcode_d = {td_i, idcode_q[31:1]};
-+      if (idcode_select)  idcode_d = {td_i, 31'(idcode_q >> 1)};
-       if (bypass_select)  bypass_d = td_i;
--      if (dtmcs_select_o) dtmcs_d  = {td_i, dtmcs_q[31:1]};
-+      if (dtmcs_select_o) dtmcs_d  = {td_i, 31'(dtmcs_q >> 1)};
-     end
- 
-     if (test_logic_reset_o) begin
-@@ -203,7 +206,7 @@ module dmi_jtag_tap #(
-     end else begin
-       case (jtag_ir_q)    // synthesis parallel_case
-         IDCODE:         tdo_mux = idcode_q[0];     // Reading ID code
--        DTMCSR:         tdo_mux = dtmcs_q[0];
-+        DTMCSR:         tdo_mux = dtmcs_q.version[0];
-         DMIACCESS:      tdo_mux = dmi_tdo_i;       // Read from DMI TDO
-         default:        tdo_mux = bypass_q;      // BYPASS instruction
-       endcase
-@@ -242,6 +245,7 @@ module dmi_jtag_tap #(
-   // ----------------
-   // Determination of next state; purely combinatorial
-   always_comb begin : p_tap_fsm
-+
-     test_logic_reset_o = 1'b0;
- 
-     capture_dr_o       = 1'b0;
-@@ -250,9 +254,11 @@ module dmi_jtag_tap #(
- 
-     capture_ir         = 1'b0;
-     shift_ir           = 1'b0;
--    pause_ir           = 1'b0;
-+    // pause_ir           = 1'b0; unused
-     update_ir          = 1'b0;
- 
-+    // note that tap_state_d does not have a default assignment since the
-+    // case statement is full
-     case (tap_state_q)
-       TestLogicReset: begin
-         tap_state_d = (tms_i) ? TestLogicReset : RunTestIdle;
-@@ -307,10 +313,10 @@ module dmi_jtag_tap #(
-         tap_state_d = (tms_i) ? Exit1Ir : ShiftIr;
-       end
-       Exit1Ir: begin
--            tap_state_d = (tms_i) ? UpdateIr : PauseIr;
-+        tap_state_d = (tms_i) ? UpdateIr : PauseIr;
-       end
-       PauseIr: begin
--        pause_ir = 1'b1;
-+        // pause_ir = 1'b1; // unused
-         tap_state_d = (tms_i) ? Exit2Ir : PauseIr;
-       end
-       Exit2Ir: begin
-@@ -324,7 +330,7 @@ module dmi_jtag_tap #(
-         update_ir = 1'b1;
-         tap_state_d = (tms_i) ? SelectDrScan : RunTestIdle;
-       end
--      default: tap_state_d = TestLogicReset;  // can't actually happen
-+      default: ; // can't actually happen
-     endcase
-   end
- 
--- 
-2.17.1
-
diff --git a/hw/vendor/patches/pulp_riscv_dbg/0007-lint-cleanup-Break-long-lines-and-make-literal-lengt.patch b/hw/vendor/patches/pulp_riscv_dbg/0007-lint-cleanup-Break-long-lines-and-make-literal-lengt.patch
deleted file mode 100644
index f07294e..0000000
--- a/hw/vendor/patches/pulp_riscv_dbg/0007-lint-cleanup-Break-long-lines-and-make-literal-lengt.patch
+++ /dev/null
@@ -1,207 +0,0 @@
-From 4b293663f9e4353cf58077c6a6f7107e3210915d Mon Sep 17 00:00:00 2001
-From: Michael Schaffner <msf@google.com>
-Date: Thu, 17 Oct 2019 18:35:46 -0700
-Subject: [PATCH 07/11] [lint/cleanup] Break long lines and make literal
- lengths explicit
-
-Overly long lines and unsized literals generate several lint warnings, and this
-commit fixes these.
----
- src/dm_csrs.sv      |  6 ++---
- src/dm_pkg.sv       | 56 +++++++++++++++++++++++++++++++++------------
- src/dm_sba.sv       | 12 +++++-----
- src/dmi_jtag_tap.sv |  8 +++----
- 4 files changed, 55 insertions(+), 27 deletions(-)
-
-diff --git a/src/dm_csrs.sv b/src/dm_csrs.sv
-index 54cbc1a..cac7509 100644
---- a/src/dm_csrs.sv
-+++ b/src/dm_csrs.sv
-@@ -520,11 +520,11 @@ module dm_csrs #(
-     sbcs_d.sbbusy               = sbbusy_i;
-     sbcs_d.sbasize              = BusWidth;
-     sbcs_d.sbaccess128          = 1'b0;
--    sbcs_d.sbaccess64           = BusWidth == 64;
--    sbcs_d.sbaccess32           = BusWidth == 32;
-+    sbcs_d.sbaccess64           = logic'(BusWidth == 32'd64);
-+    sbcs_d.sbaccess32           = logic'(BusWidth == 32'd32);
-     sbcs_d.sbaccess16           = 1'b0;
-     sbcs_d.sbaccess8            = 1'b0;
--    sbcs_d.sbaccess             = BusWidth == 64 ? 2'd3 : 2'd2;
-+    sbcs_d.sbaccess             = (BusWidth == 32'd64) ? 2'd3 : 2'd2;
-   end
- 
-   // output multiplexer
-diff --git a/src/dm_pkg.sv b/src/dm_pkg.sv
-index 341e9ab..de75c3e 100644
---- a/src/dm_pkg.sv
-+++ b/src/dm_pkg.sv
-@@ -302,69 +302,97 @@ package dm;
- 
- 
-   // Instruction Generation Helpers
--  function automatic logic [31:0] jal (logic[4:0] rd, logic [20:0] imm);
-+  function automatic logic [31:0] jal (logic [4:0]  rd,
-+                                       logic [20:0] imm);
-     // OpCode Jal
-     return {imm[20], imm[10:1], imm[11], imm[19:12], rd, 7'h6f};
-   endfunction
- 
--  function automatic logic [31:0] jalr (logic[4:0] rd, logic[4:0] rs1, logic [11:0] offset);
-+  function automatic logic [31:0] jalr (logic [4:0]  rd,
-+                                        logic [4:0]  rs1,
-+                                        logic [11:0] offset);
-     // OpCode Jal
-     return {offset[11:0], rs1, 3'b0, rd, 7'h67};
-   endfunction
- 
--  function automatic logic [31:0] andi (logic[4:0] rd, logic[4:0] rs1, logic [11:0] imm);
-+  function automatic logic [31:0] andi (logic [4:0]  rd,
-+                                        logic [4:0]  rs1,
-+                                        logic [11:0] imm);
-     // OpCode andi
-     return {imm[11:0], rs1, 3'h7, rd, 7'h13};
-   endfunction
- 
--  function automatic logic [31:0] slli (logic[4:0] rd, logic[4:0] rs1, logic [5:0] shamt);
-+  function automatic logic [31:0] slli (logic [4:0] rd,
-+                                        logic [4:0] rs1,
-+                                        logic [5:0] shamt);
-     // OpCode slli
-     return {6'b0, shamt[5:0], rs1, 3'h1, rd, 7'h13};
-   endfunction
- 
--  function automatic logic [31:0] srli (logic[4:0] rd, logic[4:0] rs1, logic [5:0] shamt);
-+  function automatic logic [31:0] srli (logic [4:0] rd,
-+                                        logic [4:0] rs1,
-+                                        logic [5:0] shamt);
-     // OpCode srli
-     return {6'b0, shamt[5:0], rs1, 3'h5, rd, 7'h13};
-   endfunction
- 
--  function automatic logic [31:0] load (logic [2:0] size, logic[4:0] dest, logic[4:0] base, logic [11:0] offset);
-+  function automatic logic [31:0] load (logic [2:0]  size,
-+                                        logic [4:0]  dest,
-+                                        logic [4:0]  base,
-+                                        logic [11:0] offset);
-     // OpCode Load
-     return {offset[11:0], base, size, dest, 7'h03};
-   endfunction
- 
--  function automatic logic [31:0] auipc (logic[4:0] rd, logic [20:0] imm);
-+  function automatic logic [31:0] auipc (logic [4:0]  rd,
-+                                         logic [20:0] imm);
-     // OpCode Auipc
-     return {imm[20], imm[10:1], imm[11], imm[19:12], rd, 7'h17};
-   endfunction
- 
--  function automatic logic [31:0] store (logic [2:0] size, logic[4:0] src, logic[4:0] base, logic [11:0] offset);
-+  function automatic logic [31:0] store (logic [2:0]  size,
-+                                         logic [4:0]  src,
-+                                         logic [4:0]  base,
-+                                         logic [11:0] offset);
-     // OpCode Store
-     return {offset[11:5], src, base, size, offset[4:0], 7'h23};
-   endfunction
- 
--  function automatic logic [31:0] float_load (logic [2:0] size, logic[4:0] dest, logic[4:0] base, logic [11:0] offset);
-+  function automatic logic [31:0] float_load (logic [2:0]  size,
-+                                              logic [4:0]  dest,
-+                                              logic [4:0]  base,
-+                                              logic [11:0] offset);
-     // OpCode Load
-     return {offset[11:0], base, size, dest, 7'b00_001_11};
-   endfunction
- 
--  function automatic logic [31:0] float_store (logic [2:0] size, logic[4:0] src, logic[4:0] base, logic [11:0] offset);
-+  function automatic logic [31:0] float_store (logic [2:0]  size,
-+                                               logic [4:0]  src,
-+                                               logic [4:0]  base,
-+                                               logic [11:0] offset);
-     // OpCode Store
-     return {offset[11:5], src, base, size, offset[4:0], 7'b01_001_11};
-   endfunction
- 
--  function automatic logic [31:0] csrw (csr_reg_t csr, logic[4:0] rs1);
-+  function automatic logic [31:0] csrw (csr_reg_t   csr,
-+                                        logic [4:0] rs1);
-     // CSRRW, rd, OpCode System
-     return {csr, rs1, 3'h1, 5'h0, 7'h73};
-   endfunction
- 
--  function automatic logic [31:0] csrr (csr_reg_t csr, logic [4:0] dest);
-+  function automatic logic [31:0] csrr (csr_reg_t   csr,
-+                                        logic [4:0] dest);
-     // rs1, CSRRS, rd, OpCode System
-     return {csr, 5'h0, 3'h2, dest, 7'h73};
-   endfunction
- 
--  function automatic logic [31:0] branch(logic [4:0] src2, logic [4:0] src1, logic [2:0] funct3, logic [11:0] offset);
-+  function automatic logic [31:0] branch(logic [4:0]  src2,
-+                                         logic [4:0]  src1,
-+                                         logic [2:0]  funct3,
-+                                         logic [11:0] offset);
-     // OpCode Branch
--    return {offset[11], offset[9:4], src2, src1, funct3, offset[3:0], offset[10], 7'b11_000_11};
-+    return {offset[11], offset[9:4], src2, src1, funct3,
-+        offset[3:0], offset[10], 7'b11_000_11};
-   endfunction
- 
-   function automatic logic [31:0] ebreak ();
-diff --git a/src/dm_sba.sv b/src/dm_sba.sv
-index 9fb445e..fa08d3f 100644
---- a/src/dm_sba.sv
-+++ b/src/dm_sba.sv
-@@ -96,16 +96,16 @@ module dm_sba #(
-         // generate byte enable mask
-         case (sbaccess_i)
-           3'b000: begin
--            if (BusWidth == 64) be[ sbaddress_i[2:0]] = '1;
--            else                be[ sbaddress_i[1:0]] = '1;
-+            if (BusWidth == 32'd64) be[ sbaddress_i[2:0]] = '1;
-+            else                    be[ sbaddress_i[1:0]] = '1;
-           end
-           3'b001: begin
--            if (BusWidth == 64) be[{sbaddress_i[2:1], 1'b0} +: 2] = '1;
--            else                be[{sbaddress_i[1:1], 1'b0} +: 2] = '1;
-+            if (BusWidth == 32'd64) be[{sbaddress_i[2:1], 1'b0} +: 2] = '1;
-+            else                    be[{sbaddress_i[1:1], 1'b0} +: 2] = '1;
-           end
-           3'b010: begin
--            if (BusWidth == 64) be[{sbaddress_i[2:2], 2'b0} +: 4] = '1;
--            else                be = '1;
-+            if (BusWidth == 32'd64) be[{sbaddress_i[2:2], 2'b0} +: 4] = '1;
-+            else                    be = '1;
-           end
-           3'b011: be = '1;
-           default:;
-diff --git a/src/dmi_jtag_tap.sv b/src/dmi_jtag_tap.sv
-index a6fd191..f8b282a 100644
---- a/src/dmi_jtag_tap.sv
-+++ b/src/dmi_jtag_tap.sv
-@@ -102,7 +102,7 @@ module dmi_jtag_tap #(
- 
-     // capture IR register
-     if (capture_ir) begin
--      jtag_ir_shift_d =  'b0101;
-+      jtag_ir_shift_d =  IrLength'(4'b0101);
-     end
- 
-     // update IR register
-@@ -155,10 +155,10 @@ module dmi_jtag_tap #(
-                       dmihardreset : 1'b0,
-                       dmireset     : 1'b0,
-                       zero0        : '0,
--                      idle         : 'd1, // 1: Enter Run-Test/Idle and leave it immediately
-+                      idle         : 3'd1, // 1: Enter Run-Test/Idle and leave it immediately
-                       dmistat      : dmi_error_i, // 0: No error, 1: Op failed, 2: too fast
--                      abits        : 'd7, // The size of address in dmi
--                      version      : 'd1  // Version described in spec version 0.13 (and later?)
-+                      abits        : 6'd7, // The size of address in dmi
-+                      version      : 4'd1  // Version described in spec version 0.13 (and later?)
-                     };
-       end
-     end
--- 
-2.17.1
-
diff --git a/hw/vendor/patches/pulp_riscv_dbg/0008-ling-cleanup-Fix-several-verilator-lint-warnings-due.patch b/hw/vendor/patches/pulp_riscv_dbg/0008-ling-cleanup-Fix-several-verilator-lint-warnings-due.patch
deleted file mode 100644
index a9271f2..0000000
--- a/hw/vendor/patches/pulp_riscv_dbg/0008-ling-cleanup-Fix-several-verilator-lint-warnings-due.patch
+++ /dev/null
@@ -1,333 +0,0 @@
-From dcad45beb85df7b1154d68a7e10dc9e7f88249fa Mon Sep 17 00:00:00 2001
-From: Michael Schaffner <msf@google.com>
-Date: Fri, 18 Oct 2019 11:03:19 -0700
-Subject: [PATCH 08/11] [ling/cleanup] Fix several verilator lint warnings due
- to sizing
-
----
- debug_rom/debug_rom.sv |  4 ++--
- debug_rom/gen_rom.py   |  4 ++--
- src/dm_csrs.sv         | 39 ++++++++++++++++++++++-----------------
- src/dm_mem.sv          | 16 ++++++++--------
- src/dm_sba.sv          | 24 ++++++++++++------------
- 5 files changed, 46 insertions(+), 41 deletions(-)
-
-diff --git a/debug_rom/debug_rom.sv b/debug_rom/debug_rom.sv
-index d8e8913..2723816 100644
---- a/debug_rom/debug_rom.sv
-+++ b/debug_rom/debug_rom.sv
-@@ -21,7 +21,7 @@ module debug_rom (
-   output logic [63:0]  rdata_o
- );
- 
--  localparam int RomSize = 19;
-+  localparam int unsigned RomSize = 19;
- 
-   const logic [RomSize-1:0][63:0] mem = {
-     64'h00000000_7b200073,
-@@ -57,7 +57,7 @@ module debug_rom (
-   // the speculative fetch stage of the core
-   always_comb begin : p_outmux
-     rdata_o = '0;
--    if (addr_q < RomSize) begin
-+    if (addr_q < $clog2(RomSize)'(RomSize)) begin
-         rdata_o = mem[addr_q];
-     end
-   end
-diff --git a/debug_rom/gen_rom.py b/debug_rom/gen_rom.py
-index e701c52..338abbb 100755
---- a/debug_rom/gen_rom.py
-+++ b/debug_rom/gen_rom.py
-@@ -48,7 +48,7 @@ module $filename (
-   output logic [63:0]  rdata_o
- );
- 
--  localparam int RomSize = $size;
-+  localparam int unsigned RomSize = $size;
- 
-   const logic [RomSize-1:0][63:0] mem = {
- $content
-@@ -66,7 +66,7 @@ $content
-   // the speculative fetch stage of the core
-   always_comb begin : p_outmux
-     rdata_o = '0;
--    if (addr_q < RomSize) begin
-+    if (addr_q < $clog2(RomSize)'(RomSize)) begin
-         rdata_o = mem[addr_q];
-     end
-   end
-diff --git a/src/dm_csrs.sv b/src/dm_csrs.sv
-index cac7509..807bb19 100644
---- a/src/dm_csrs.sv
-+++ b/src/dm_csrs.sv
-@@ -111,7 +111,7 @@ module dm_csrs #(
-     hartsel_idx0        = hartsel_o[19:5];
-     halted[NrHarts-1:0] = halted_i;
-     halted_reshaped0    = halted;
--    if (hartsel_idx0 < (NrHarts-1)/2**5+1) begin
-+    if (hartsel_idx0 < 15'((NrHarts-1)/2**5+1)) begin
-       haltsum0 = halted_reshaped0[hartsel_idx0];
-     end
-   end
-@@ -128,7 +128,7 @@ module dm_csrs #(
-     end
-     halted_reshaped1 = halted_flat1;
- 
--    if (hartsel_idx1 < (NrHarts/2**10+1)) begin
-+    if (hartsel_idx1 < 10'((NrHarts/2**10+1))) begin
-       haltsum1 = halted_reshaped1[hartsel_idx1];
-     end
-   end
-@@ -145,7 +145,7 @@ module dm_csrs #(
-     end
-     halted_reshaped2 = halted_flat2;
- 
--    if (hartsel_idx2 < (NrHarts/2**15+1)) begin
-+    if (hartsel_idx2 < 5'((NrHarts/2**15+1))) begin
-       haltsum2         = halted_reshaped2[hartsel_idx2];
-     end
-   end
-@@ -214,6 +214,7 @@ module dm_csrs #(
-   dm::sbcs_t sbcs;
-   dm::dmcontrol_t dmcontrol;
-   dm::abstractcs_t a_abstractcs;
-+  logic [4:0] autoexecdata_idx;
-   always_comb begin : csr_read_write
-     // --------------------
-     // Static Values (R/O)
-@@ -237,8 +238,8 @@ module dm_csrs #(
- 
-     // as soon as we are out of the legal Hart region tell the debugger
-     // that there are only non-existent harts
--    dmstatus.allnonexistent = logic'(hartsel_o > (NrHarts - 1));
--    dmstatus.anynonexistent = logic'(hartsel_o > (NrHarts - 1));
-+    dmstatus.allnonexistent = logic'(32'(hartsel_o) > (NrHarts - 1));
-+    dmstatus.anynonexistent = logic'(32'(hartsel_o) > (NrHarts - 1));
- 
-     // We are not allowed to be in multiple states at once. This is a to
-     // make the running/halted and unavailable states exclusive.
-@@ -282,6 +283,8 @@ module dm_csrs #(
-     dmcontrol    = '0;
-     a_abstractcs = '0;
- 
-+    autoexecdata_idx    = dmi_req_i.addr[4:0] - 5'(dm::Data0);
-+
-     // localparam int unsigned DataCountAlign = $clog2(dm::DataCount);
-     // reads
-     if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_READ) begin
-@@ -289,11 +292,12 @@ module dm_csrs #(
-         [(dm::Data0):DataEnd]: begin
-           // logic [$clog2(dm::DataCount)-1:0] resp_queue_idx;
-           // resp_queue_idx = dmi_req_i.addr[4:0] - int'(dm::Data0);
--          resp_queue_data = data_q[dmi_req_i.addr[4:0] - int'(dm::Data0)];
-+          resp_queue_data = data_q[$clog2(dm::DataCount)'(autoexecdata_idx)];
-           if (!cmdbusy_i) begin
-             // check whether we need to re-execute the command (just give a cmd_valid)
--            cmd_valid_d = abstractauto_q.autoexecdata[dmi_req_i.addr[3:0] -
--                          int'(dm::Data0)];
-+            if (autoexecdata_idx < $bits(abstractauto_q.autoexecdata)) begin
-+              cmd_valid_d = abstractauto_q.autoexecdata[autoexecdata_idx];
-+            end
-           end
-         end
-         dm::DMControl:    resp_queue_data = dmcontrol_q;
-@@ -307,8 +311,8 @@ module dm_csrs #(
-           resp_queue_data = progbuf_q[dmi_req_i.addr[$clog2(dm::ProgBufSize)-1:0]];
-           if (!cmdbusy_i) begin
-             // check whether we need to re-execute the command (just give a cmd_valid)
--            // TODO(zarubaf): check if offset is correct: without it this may assign Xes
--            cmd_valid_d = abstractauto_q.autoexecprogbuf[dmi_req_i.addr[3:0]+16];
-+            // range of autoexecprogbuf is 31:16
-+            cmd_valid_d = abstractauto_q.autoexecprogbuf[{1'b1, dmi_req_i.addr[3:0]}];
-           end
-         end
-         dm::HaltSum0: resp_queue_data = haltsum0;
-@@ -363,7 +367,9 @@ module dm_csrs #(
-           if (!cmdbusy_i && dm::DataCount > 0) begin
-             data_d[dmi_req_i.addr[$clog2(dm::DataCount)-1:0]] = dmi_req_i.data;
-             // check whether we need to re-execute the command (just give a cmd_valid)
--            cmd_valid_d = abstractauto_q.autoexecdata[dmi_req_i.addr[3:0] - int'(dm::Data0)];
-+            if (autoexecdata_idx < $bits(abstractauto_q.autoexecdata)) begin
-+              cmd_valid_d = abstractauto_q.autoexecdata[autoexecdata_idx];
-+            end
-           end
-         end
-         dm::DMControl: begin
-@@ -418,9 +424,8 @@ module dm_csrs #(
-             // check whether we need to re-execute the command (just give a cmd_valid)
-             // this should probably throw an error if executed during another command
-             // was busy
--            // TODO(zarubaf): check if offset is correct - without it this may
--            // assign Xes
--            cmd_valid_d = abstractauto_q.autoexecprogbuf[dmi_req_i.addr[3:0]+16];
-+            // range of autoexecprogbuf is 31:16
-+            cmd_valid_d = abstractauto_q.autoexecprogbuf[{1'b1, dmi_req_i.addr[3:0]}];
-           end
-         end
-         dm::SBCS: begin
-@@ -518,13 +523,13 @@ module dm_csrs #(
-     // static values for dcsr
-     sbcs_d.sbversion            = 3'b1;
-     sbcs_d.sbbusy               = sbbusy_i;
--    sbcs_d.sbasize              = BusWidth;
-+    sbcs_d.sbasize              = $bits(sbcs_d.sbasize)'(BusWidth);
-     sbcs_d.sbaccess128          = 1'b0;
-     sbcs_d.sbaccess64           = logic'(BusWidth == 32'd64);
-     sbcs_d.sbaccess32           = logic'(BusWidth == 32'd32);
-     sbcs_d.sbaccess16           = 1'b0;
-     sbcs_d.sbaccess8            = 1'b0;
--    sbcs_d.sbaccess             = (BusWidth == 32'd64) ? 2'd3 : 2'd2;
-+    sbcs_d.sbaccess             = (BusWidth == 32'd64) ? 3'd3 : 3'd2;
-   end
- 
-   // output multiplexer
-@@ -533,7 +538,7 @@ module dm_csrs #(
-     // default assignment
-     haltreq_o = '0;
-     resumereq_o = '0;
--    if (selected_hart < NrHarts) begin
-+    if (selected_hart < HartSelLen'(NrHarts)) begin
-       haltreq_o[selected_hart]   = dmcontrol_q.haltreq;
-       resumereq_o[selected_hart] = dmcontrol_q.resumereq;
-     end
-diff --git a/src/dm_mem.sv b/src/dm_mem.sv
-index c6d4059..5c361fc 100644
---- a/src/dm_mem.sv
-+++ b/src/dm_mem.sv
-@@ -268,7 +268,7 @@ module dm_mem #(
-           WhereToAddr: begin
-             // variable jump to abstract cmd, program_buffer or resume
-             if (resumereq_wdata_aligned[wdata_hartsel]) begin
--              rdata_d = {32'b0, dm::jal('0, dm::ResumeAddress[11:0]-WhereToAddr)};
-+              rdata_d = {32'b0, dm::jal('0, 21'(dm::ResumeAddress[11:0])-21'(WhereToAddr))};
-             end
- 
-             // there is a command active so jump there
-@@ -277,10 +277,10 @@ module dm_mem #(
-               // keep this statement narrow to not catch invalid commands
-               if (cmd_i.cmdtype == dm::AccessRegister &&
-                   !ac_ar.transfer && ac_ar.postexec) begin
--                rdata_d = {32'b0, dm::jal('0, ProgBufBaseAddr-WhereToAddr)};
-+                rdata_d = {32'b0, dm::jal('0, 21'(ProgBufBaseAddr)-21'(WhereToAddr))};
-               // this is a legit abstract cmd -> execute it
-               end else begin
--                rdata_d = {32'b0, dm::jal('0, AbstractCmdBaseAddr-WhereToAddr)};
-+                rdata_d = {32'b0, dm::jal('0, 21'(AbstractCmdBaseAddr)-21'(WhereToAddr))};
-               end
-             end
-           end
-@@ -288,7 +288,7 @@ module dm_mem #(
-           [DataBaseAddr:DataEndAddr]: begin
-             rdata_d = {
-                       data_i[$clog2(dm::ProgBufSize)'(addr_i[DbgAddressBits-1:3] -
--                          DataBaseAddr[DbgAddressBits-1:3] + 1)],
-+                          DataBaseAddr[DbgAddressBits-1:3] + 1'b1)],
-                       data_i[$clog2(dm::ProgBufSize)'(addr_i[DbgAddressBits-1:3] -
-                           DataBaseAddr[DbgAddressBits-1:3])]
-                       };
-@@ -310,7 +310,7 @@ module dm_mem #(
-             // release the corresponding hart
-             if (({addr_i[DbgAddressBits-1:3], 3'b0} - FlagsBaseAddr[DbgAddressBits-1:0]) ==
-               (DbgAddressBits'(hartsel) & {{(DbgAddressBits-3){1'b1}}, 3'b0})) begin
--              rdata[DbgAddressBits'(hartsel) & 3'b111] = {6'b0, resume, go};
-+              rdata[DbgAddressBits'(hartsel) & DbgAddressBits'(3'b111)] = {6'b0, resume, go};
-             end
-             rdata_d = rdata;
-           end
-@@ -346,7 +346,7 @@ module dm_mem #(
-       // Access Register
-       // --------------------
-       dm::AccessRegister: begin
--        if (ac_ar.aarsize < MaxAar && ac_ar.transfer && ac_ar.write) begin
-+        if (32'(ac_ar.aarsize) < MaxAar && ac_ar.transfer && ac_ar.write) begin
-           // store a0 in dscratch1
-           abstract_cmd[0][31:0] = dm::csrw(dm::CSR_DSCRATCH1, 5'd10);
-           // this range is reserved
-@@ -387,7 +387,7 @@ module dm_mem #(
-             // restore s0 again from dscratch
-             abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8);
-           end
--        end else if (ac_ar.aarsize < MaxAar && ac_ar.transfer && !ac_ar.write) begin
-+        end else if (32'(ac_ar.aarsize) < MaxAar && ac_ar.transfer && !ac_ar.write) begin
-           // store a0 in dscratch1
-           abstract_cmd[0][31:0]  = dm::csrw(dm::CSR_DSCRATCH1, 5'd10);
-           // this range is reserved
-@@ -428,7 +428,7 @@ module dm_mem #(
-             // restore s0 again from dscratch
-             abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8);
-           end
--        end else if (ac_ar.aarsize >= MaxAar || ac_ar.aarpostincrement == 1'b1) begin
-+        end else if (32'(ac_ar.aarsize) >= MaxAar || ac_ar.aarpostincrement == 1'b1) begin
-           // this should happend when e.g. ac_ar.aarsize >= MaxAar
-           // Openocd will try to do an access with aarsize=64 bits
-           // first before falling back to 32 bits.
-diff --git a/src/dm_sba.sv b/src/dm_sba.sv
-index fa08d3f..43a6dad 100644
---- a/src/dm_sba.sv
-+++ b/src/dm_sba.sv
-@@ -55,11 +55,12 @@ module dm_sba #(
-   typedef enum logic [2:0] { Idle, Read, Write, WaitRead, WaitWrite } state_e;
-   state_e state_d, state_q;
- 
--  logic [BusWidth-1:0]   address;
--  logic                  req;
--  logic                  gnt;
--  logic                  we;
--  logic [BusWidth/8-1:0] be;
-+  logic [BusWidth-1:0]           address;
-+  logic                          req;
-+  logic                          gnt;
-+  logic                          we;
-+  logic [BusWidth/8-1:0]         be;
-+  logic [$clog2(BusWidth/8)-1:0] be_idx;
- 
-   assign sbbusy_o = logic'(state_q != Idle);
- 
-@@ -68,6 +69,7 @@ module dm_sba #(
-     address = sbaddress_i;
-     we      = 1'b0;
-     be      = '0;
-+    be_idx  = sbaddress_i[$clog2(BusWidth/8)-1:0];
- 
-     sberror_o       = '0;
-     sberror_valid_o = 1'b0;
-@@ -96,15 +98,13 @@ module dm_sba #(
-         // generate byte enable mask
-         case (sbaccess_i)
-           3'b000: begin
--            if (BusWidth == 32'd64) be[ sbaddress_i[2:0]] = '1;
--            else                    be[ sbaddress_i[1:0]] = '1;
-+            be[be_idx] = '1;
-           end
-           3'b001: begin
--            if (BusWidth == 32'd64) be[{sbaddress_i[2:1], 1'b0} +: 2] = '1;
--            else                    be[{sbaddress_i[1:1], 1'b0} +: 2] = '1;
-+            be[int'({be_idx[$high(be_idx):1], 1'b0}) +: 2] = '1;
-           end
-           3'b010: begin
--            if (BusWidth == 32'd64) be[{sbaddress_i[2:2], 2'b0} +: 4] = '1;
-+            if (BusWidth == 32'd64) be[int'({be_idx[$high(be_idx)], 2'b0}) +: 4] = '1;
-             else                    be = '1;
-           end
-           3'b011: be = '1;
-@@ -117,7 +117,7 @@ module dm_sba #(
-         if (sbdata_valid_o) begin
-           state_d = Idle;
-           // auto-increment address
--          if (sbautoincrement_i) sbaddress_o = sbaddress_i + (1'b1 << sbaccess_i);
-+          if (sbautoincrement_i) sbaddress_o = sbaddress_i + (32'b1 << sbaccess_i);
-         end
-       end
- 
-@@ -125,7 +125,7 @@ module dm_sba #(
-         if (sbdata_valid_o) begin
-           state_d = Idle;
-           // auto-increment address
--          if (sbautoincrement_i) sbaddress_o = sbaddress_i + (1'b1 << sbaccess_i);
-+          if (sbautoincrement_i) sbaddress_o = sbaddress_i + (32'b1 << sbaccess_i);
-         end
-       end
- 
--- 
-2.17.1
-
diff --git a/hw/vendor/pulp_riscv_dbg.lock.hjson b/hw/vendor/pulp_riscv_dbg.lock.hjson
index d838c5b..e823e06 100644
--- a/hw/vendor/pulp_riscv_dbg.lock.hjson
+++ b/hw/vendor/pulp_riscv_dbg.lock.hjson
@@ -9,6 +9,6 @@
   upstream:
   {
     url: https://github.com/pulp-platform/riscv-dbg
-    rev: 811b2d707795a5044d63a68f747b2f9cd29d3a88
+    rev: 6bef5d80f3559d54cfd0cecd1fa40edb564daa93
   }
 }
diff --git a/hw/vendor/pulp_riscv_dbg/src/dm_mem.sv b/hw/vendor/pulp_riscv_dbg/src/dm_mem.sv
index 49daa38..938e883 100644
--- a/hw/vendor/pulp_riscv_dbg/src/dm_mem.sv
+++ b/hw/vendor/pulp_riscv_dbg/src/dm_mem.sv
@@ -137,7 +137,7 @@
     resume           = 1'b0;
     cmdbusy_o        = 1'b1;
 
-    case (state_q)
+    unique case (state_q)
       Idle: begin
         cmdbusy_o = 1'b0;
         if (cmd_valid_i && halted_q_aligned[hartsel] && !unsupported_command) begin
@@ -182,6 +182,8 @@
           state_d = Idle;
         end
       end
+
+      default: ;
     endcase
 
     // only signal once that cmd is unsupported so that we can clear cmderr
diff --git a/hw/vendor/pulp_riscv_dbg/src/dm_sba.sv b/hw/vendor/pulp_riscv_dbg/src/dm_sba.sv
index 43a6dad..f605088 100644
--- a/hw/vendor/pulp_riscv_dbg/src/dm_sba.sv
+++ b/hw/vendor/pulp_riscv_dbg/src/dm_sba.sv
@@ -77,7 +77,7 @@
 
     state_d = state_q;
 
-    case (state_q)
+    unique case (state_q)
       Idle: begin
         // debugger requested a read
         if (sbaddress_write_valid_i && sbreadonaddr_i)  state_d = Read;
@@ -96,7 +96,7 @@
         req = 1'b1;
         we  = 1'b1;
         // generate byte enable mask
-        case (sbaccess_i)
+        unique case (sbaccess_i)
           3'b000: begin
             be[be_idx] = '1;
           end
@@ -108,7 +108,7 @@
             else                    be = '1;
           end
           3'b011: be = '1;
-          default:;
+          default: ;
         endcase
         if (gnt) state_d = WaitWrite;
       end
@@ -129,7 +129,7 @@
         end
       end
 
-      default:;
+      default: state_d = Idle; // catch parasitic state
     endcase
 
     // handle error case
diff --git a/hw/vendor/pulp_riscv_dbg/src/dmi_jtag.sv b/hw/vendor/pulp_riscv_dbg/src/dmi_jtag.sv
index 60e67f4..2039e25 100644
--- a/hw/vendor/pulp_riscv_dbg/src/dmi_jtag.sv
+++ b/hw/vendor/pulp_riscv_dbg/src/dmi_jtag.sv
@@ -98,7 +98,7 @@
 
     dmi_req_valid = 1'b0;
 
-    case (state_q)
+    unique case (state_q)
       Idle: begin
         // make sure that no error is sticky
         if (dmi_access && update_dr && (error_q == DMINoError)) begin
diff --git a/hw/vendor/pulp_riscv_dbg/src/dmi_jtag_tap.sv b/hw/vendor/pulp_riscv_dbg/src/dmi_jtag_tap.sv
index 9771cd9..ca6b824 100644
--- a/hw/vendor/pulp_riscv_dbg/src/dmi_jtag_tap.sv
+++ b/hw/vendor/pulp_riscv_dbg/src/dmi_jtag_tap.sv
@@ -183,7 +183,7 @@
     dtmcs_select_o = 1'b0;
     idcode_select  = 1'b0;
     bypass_select  = 1'b0;
-    case (jtag_ir_q)
+    unique case (jtag_ir_q)
       BYPASS0:   bypass_select  = 1'b1;
       IDCODE:    idcode_select  = 1'b1;
       DTMCSR:    dtmcs_select_o = 1'b1;
@@ -204,7 +204,7 @@
       tdo_mux = jtag_ir_shift_q[0];
     // here we are shifting the DR register
     end else begin
-      case (jtag_ir_q)    // synthesis parallel_case
+      unique case (jtag_ir_q)
         IDCODE:         tdo_mux = idcode_q[0];     // Reading ID code
         DTMCSR:         tdo_mux = dtmcs_q.version[0];
         DMIACCESS:      tdo_mux = dmi_tdo_i;       // Read from DMI TDO
@@ -253,9 +253,7 @@
     // pause_ir           = 1'b0; unused
     update_ir          = 1'b0;
 
-    // note that tap_state_d does not have a default assignment since the
-    // case statement is full
-    case (tap_state_q)
+    unique case (tap_state_q)
       TestLogicReset: begin
         tap_state_d = (tms_i) ? TestLogicReset : RunTestIdle;
         test_logic_reset_o = 1'b1;
@@ -326,7 +324,7 @@
         update_ir = 1'b1;
         tap_state_d = (tms_i) ? SelectDrScan : RunTestIdle;
       end
-      default: ; // can't actually happen
+      default: ; // can't actually happen since case is full
     endcase
   end