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