diff --git a/hw/vendor/cheriot-debug-module.lock.hjson b/hw/vendor/cheriot-debug-module.lock.hjson index 9a6b4a62..bf82af83 100644 --- a/hw/vendor/cheriot-debug-module.lock.hjson +++ b/hw/vendor/cheriot-debug-module.lock.hjson @@ -8,7 +8,7 @@ { upstream: { - url: https://github.com/SamuelRiedel/riscv-dbg.git - rev: c2991e163a21c2142fba79d316fdb5423e3503e2 + url: https://github.com/CHERIoT-Platform/cheriot-dbg-module.git + rev: 845f74ce6deb8e811f695c8dab1e6b4ba9cf2fbd } } diff --git a/hw/vendor/cheriot-debug-module.vendor.hjson b/hw/vendor/cheriot-debug-module.vendor.hjson index 92823092..afaf0550 100644 --- a/hw/vendor/cheriot-debug-module.vendor.hjson +++ b/hw/vendor/cheriot-debug-module.vendor.hjson @@ -6,7 +6,7 @@ target_dir: "cheriot_debug_module", patch_dir: "patches/cheriot_debug_module", upstream: { - url: "https://github.com/SamuelRiedel/riscv-dbg.git", - rev: "cheriot-rebased", + url: "https://github.com/CHERIoT-Platform/cheriot-dbg-module.git", + rev: "main", } } diff --git a/hw/vendor/cheriot_debug_module/.gitignore b/hw/vendor/cheriot_debug_module/.gitignore deleted file mode 100644 index c95e8c8f..00000000 --- a/hw/vendor/cheriot_debug_module/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.bender/ -Bender.lock diff --git a/hw/vendor/cheriot_debug_module/.travis.yml b/hw/vendor/cheriot_debug_module/.travis.yml deleted file mode 100644 index 7d8bce59..00000000 --- a/hw/vendor/cheriot_debug_module/.travis.yml +++ /dev/null @@ -1,85 +0,0 @@ -language: cpp -# run on new infrastructure -dist: xenial -sudo: false -cache: - apt: true - directories: - $RISCV - $VERILATOR_ROOT - timeout: 1000 - -# required packages to install -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - gcc-7 - - g++-7 - - gperf - - autoconf - - automake - - autotools-dev - - libmpc-dev - - libmpfr-dev - - libgmp-dev - - gawk - - build-essential - - bison - - flex - - texinfo - - python-pexpect - - libusb-1.0-0-dev - - default-jdk - - zlib1g-dev - - valgrind -env: - global: - - RISCV="/home/travis/riscv_install" - - VERILATOR_ROOT="/home/travis/verilator-4.018" - - -before_install: - - export CXX=g++-7 CC=gcc-7 - # setup dependent paths - - export PATH=$RISCV/bin:$VERILATOR_ROOT/bin:$PATH - - export LIBRARY_PATH=$RISCV/lib - - export LD_LIBRARY_PATH=$RISCV/lib - - export C_INCLUDE_PATH=$RISCV/include:$VERILATOR_ROOT/share/verilator/include - - export CPLUS_INCLUDE_PATH=$RISCV/include:$VERILATOR_ROOT/share/verilator/include - - export PKG_CONFIG_PATH=$VERILATOR_ROOT/share/pkgconfig - # number of parallel jobs to use for make commands and simulation - - export NUM_JOBS=4 - - ci/make-tmp.sh - - git submodule update --init --recursive - -stages: - - download - - compile1 - - compile2 - - test - -jobs: - include: - - stage: download - name: download pulp gcc - script: - - ci/download-pulp-gcc.sh - - - stage: compile2 - name: build verilator - script: - - ci/install-verilator.sh - - stage: compile2 - name: build openocd - script: - - ci/get-openocd.sh - - - stage: test - name: run openocd debug module tests - script: - - ci/veri-run-openocd-compliance.sh - -# extra time during long builds -install: travis_wait diff --git a/hw/vendor/cheriot_debug_module/Bender.yml b/hw/vendor/cheriot_debug_module/Bender.yml index d6b90900..7178d565 100644 --- a/hw/vendor/cheriot_debug_module/Bender.yml +++ b/hw/vendor/cheriot_debug_module/Bender.yml @@ -10,7 +10,7 @@ package: dependencies: tech_cells_generic: { git: "https://github.com/pulp-platform/tech_cells_generic.git", version: 0.2.3 } - common_cells: {git: "https://github.com/pulp-platform/common_cells.git", version: 1.24.0} + common_cells: {git: https://github.com/pulp-platform/common_cells.git, version: 1.21.0} sources: files: diff --git a/hw/vendor/cheriot_debug_module/CHANGELOG.md b/hw/vendor/cheriot_debug_module/CHANGELOG.md index 99dab605..91ad2d5d 100644 --- a/hw/vendor/cheriot_debug_module/CHANGELOG.md +++ b/hw/vendor/cheriot_debug_module/CHANGELOG.md @@ -4,60 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## Unreleased - -## [0.8.1] - 2023-10-01 -### Changed -- debug_rom: Add rst - -## [0.8.0] - 2023-04-05 -### Fixed -- dm_csrs: Fix W1C behavior of `sberror` (#155) [@andreaskurth](https://github.com/andreaskurth) -- gen_rom.py: Port to python3 (#152) [@andreaskurth](https://github.com/andreaskurth) - -### Added -- `xprop_off` to Xprop-incompatible processes (#151) [@andreaskurth](https://github.com/andreaskurth) - -## [0.7.0] - 2022-11-02 -### Fixed -- 64-bit unaligned accesses (#145) [@creinwar](https://github.com/creinwar) -- Various minor testbench fixes (#146) - -### Changed -- Halted, Resume and Exception addresses are now aligned to 8 bytes - -## [0.6.0] - 2022-10-11 -### Fixed -- Testbench build (#141, #142) -- remote_bitbang tb build for newer GCC versions (#133) [@epsilon537](https://github.com/noytzach) -- 32-bit access to abstract data (#27) [@Silabs-ArjanB](https://github.com/Silabs-ArjanB) -- `dm_mem`: Clear state of hart upon ndmreset (#140) [@andreaskurth](https://github.com/andreaskurth) -- `dmi_jtag_tap`: Bring all state to initial value in test-logic-reset (#139) [@andreaskurth](https://github.com/andreaskurth) -- Fix DMI response when command or SBA are busy (#138) [@andreaskurth](https://github.com/andreaskurth) - -### Changed -- Add expontential backoff to read_dmi in tb (#134) [@colluca](https://github.com/colluca) - -## [0.5.1] - 2022-04-12 -### Fixed -- Fixed dmi_bscane_tap top-level signals - -## [0.5.0] - 2022-04-04 +## [Unreleased] ### Added -- Add sbaccess8 and sbaccess16 support (#106) [@noytzach](https://github.com/noytzach) -- Implement SBA bad address error (#12) [@msfchaffner](https://github.com/msfschaffner) -- Added random reset tests to dmi testbench. ### Changed -- Implement `dmihardreset` functionaliy in `dtmcs` register. -- `dmi_rst_ni` of `dm_top` is now a synchronous signal. However, `dmi_rst_no` of - `dmi_jtag` is glitch-free and asserted during all forms (functional or POR) of - resets. ### Fixed -- Fixed documentation (csr) -- Fixed reset value of sbcs register (#127) [@msfchaffner](https://github.com/msfschaffner) -- Fixed various ascent lint warnings [@msfchaffner](https://github.com/msfschaffner) -- Implement proper CDC flushing behavior on functional resets and JTAG resets (asynchronous or TestLogicReset driven). -- Fix JTAG non-compliance in TestLogicReset state (IR should reset to IDCODE). ## [0.4.1] - 2021-05-04 ### Added diff --git a/hw/vendor/cheriot_debug_module/ci/veri-run-openocd-compliance.sh b/hw/vendor/cheriot_debug_module/ci/veri-run-openocd-compliance.sh new file mode 100755 index 00000000..09b58925 --- /dev/null +++ b/hw/vendor/cheriot_debug_module/ci/veri-run-openocd-compliance.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +set -e + +ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) + +if [ -z "${RISCV}" ] +then + echo "RISCV is empty" + exit 1 +fi + + +veri_out=$(mktemp) +openocd_out=openocd.log + +make -C "${ROOT}"/tb veri-run |& tee "${veri_out}"& +# record veri pid/pgid to kill it if it survives this script +veri_pid=$! +veri_pgid=$(ps -o pgid= ${veri_pid} | grep -o [0-9]*) + +# block until we get "Listening on port" so that we are safe to connect openocd +coproc grep -m 1 "Listening on port" +tail -f -n0 "${veri_out}" --pid "$COPROC_PID" >&"${COPROC[1]}" + +echo "Starting openocd" +"${RISCV}"/bin/openocd -f "${ROOT}"/tb/dm_compliance_test.cfg |& tee "${openocd_out}" + +if grep -q "ALL TESTS PASSED" "${openocd_out}"; then + exit 0 +fi +exit 1 + diff --git a/hw/vendor/cheriot_debug_module/debug_rom/Makefile b/hw/vendor/cheriot_debug_module/debug_rom/Makefile index f8f6b8fa..228bab1c 100644 --- a/hw/vendor/cheriot_debug_module/debug_rom/Makefile +++ b/hw/vendor/cheriot_debug_module/debug_rom/Makefile @@ -1,7 +1,7 @@ # See LICENSE.SiFive for license details -# Conversion to CHERIoT Ibex ISA from RISC-V -# Copyright SCI Semiconductor 2025 +## Conversion to CHERIoT Ibex ISA from RISC-V +## Copyright SCI Semiconductor 2025 debug_rom = debug_rom.sv debug_rom.dump @@ -10,7 +10,7 @@ OBJCOPY=${CHERIOT_LLVM_ROOT}/llvm-objcopy OBJDUMP=${CHERIOT_LLVM_ROOT}/llvm-objdump LD=${CHERIOT_LLVM_ROOT}/ld.lld -PYTHON?=python3 +PYTHON?=python all: $(debug_rom) diff --git a/hw/vendor/cheriot_debug_module/debug_rom/debug_rom.S b/hw/vendor/cheriot_debug_module/debug_rom/debug_rom.S index abc50034..1630c4cc 100644 --- a/hw/vendor/cheriot_debug_module/debug_rom/debug_rom.S +++ b/hw/vendor/cheriot_debug_module/debug_rom/debug_rom.S @@ -9,9 +9,9 @@ // # define SND_SCRATCH 1 // These are implementation-specific addresses in the Debug Module #define HALTED 0x100 -#define GOING 0x108 -#define RESUMING 0x110 -#define EXCEPTION 0x118 +#define GOING 0x104 +#define RESUMING 0x108 +#define EXCEPTION 0x10C // Region of memory where each hart has 1 // byte to read. diff --git a/hw/vendor/cheriot_debug_module/debug_rom/debug_rom.dump b/hw/vendor/cheriot_debug_module/debug_rom/debug_rom.dump index 8a65d92a..fe66e5be 100644 --- a/hw/vendor/cheriot_debug_module/debug_rom/debug_rom.dump +++ b/hw/vendor/cheriot_debug_module/debug_rom/debug_rom.dump @@ -38,20 +38,20 @@ Disassembly of section .text: 854: 17 05 00 00 auipcc ca0, 0 858: 13 55 c5 00 srli a0, a0, 12 85c: 13 15 c5 00 slli a0, a0, 12 - 860: 23 2c 05 10 csw zero, 280(ca0) + 860: 23 26 05 10 csw zero, 268(ca0) 864: 5b 05 a0 03 cspecialr ca0, 26 868: 5b 04 90 03 cspecialr cs0, 25 86c: 73 00 10 00 ebreak 00000870 : - 870: 23 24 05 10 csw zero, 264(ca0) + 870: 23 22 05 10 csw zero, 260(ca0) 874: 5b 05 a0 03 cspecialr ca0, 26 878: 5b 04 90 03 cspecialr cs0, 25 87c: 6f f0 5f a8 j 0x300 00000880 <_resume>: 880: 73 24 40 f1 csrr s0, mhartid - 884: 23 28 85 10 csw s0, 272(ca0) + 884: 23 24 85 10 csw s0, 264(ca0) 888: 5b 05 a0 03 cspecialr ca0, 26 88c: 5b 04 90 03 cspecialr cs0, 25 890: 73 00 20 7b dret diff --git a/hw/vendor/cheriot_debug_module/debug_rom/debug_rom.h b/hw/vendor/cheriot_debug_module/debug_rom/debug_rom.h index f94bafce..bba459b8 100644 --- a/hw/vendor/cheriot_debug_module/debug_rom/debug_rom.h +++ b/hw/vendor/cheriot_debug_module/debug_rom/debug_rom.h @@ -27,16 +27,16 @@ uint32_t reset_vec[reset_vec_size] = { 0x00000517, 0x00c55513, 0x00c51513, - 0x10052c23, + 0x10052623, 0x03a0055b, 0x0390045b, 0x00100073, - 0x10052423, + 0x10052223, 0x03a0055b, 0x0390045b, 0xa85ff06f, 0xf1402473, - 0x10852823, + 0x10852423, 0x03a0055b, 0x0390045b, 0x7b200073, diff --git a/hw/vendor/cheriot_debug_module/debug_rom/debug_rom.sv b/hw/vendor/cheriot_debug_module/debug_rom/debug_rom.sv index ed3c1250..f2e70d73 100644 --- a/hw/vendor/cheriot_debug_module/debug_rom/debug_rom.sv +++ b/hw/vendor/cheriot_debug_module/debug_rom/debug_rom.sv @@ -20,7 +20,6 @@ // Auto-generated code module debug_rom ( input logic clk_i, - input logic rst_ni, input logic req_i, input logic [63:0] addr_i, output logic [63:0] rdata_o @@ -32,11 +31,11 @@ module debug_rom ( assign mem = { 64'h00000000_7b200073, 64'h0390045b_03a0055b, - 64'h10852823_f1402473, + 64'h10852423_f1402473, 64'ha85ff06f_0390045b, - 64'h03a0055b_10052423, + 64'h03a0055b_10052223, 64'h00100073_0390045b, - 64'h03a0055b_10052c23, + 64'h03a0055b_10052623, 64'h00c51513_00c55513, 64'h00000517_fd5ff06f, 64'hfa041ce3_00247413, @@ -51,15 +50,11 @@ module debug_rom ( 64'h07c0006f_00c0006f }; - logic [$clog2(RomSize)-1:0] addr_d, addr_q; + logic [$clog2(RomSize)-1:0] addr_q; - assign addr_d = req_i ? addr_i[$clog2(RomSize)-1+3:3] : addr_q; - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - addr_q <= '0; - end else begin - addr_q <= addr_d; + always_ff @(posedge clk_i) begin + if (req_i) begin + addr_q <= addr_i[$clog2(RomSize)-1+3:3]; end end @@ -68,7 +63,7 @@ module debug_rom ( always_comb begin : p_outmux rdata_o = '0; if (addr_q < $clog2(RomSize)'(RomSize)) begin - rdata_o = mem[addr_q]; + rdata_o = mem[addr_q]; end end diff --git a/hw/vendor/cheriot_debug_module/debug_rom/debug_rom_one_scratch.h b/hw/vendor/cheriot_debug_module/debug_rom/debug_rom_one_scratch.h index d4539714..625d66a0 100644 --- a/hw/vendor/cheriot_debug_module/debug_rom/debug_rom_one_scratch.h +++ b/hw/vendor/cheriot_debug_module/debug_rom/debug_rom_one_scratch.h @@ -1,14 +1,11 @@ // Auto-generated code -const int reset_vec_size = 28; +const int reset_vec_size = 26; uint32_t reset_vec[reset_vec_size] = { - 0x0180006f, - 0x00000013, - 0x0580006f, - 0x00000013, - 0x0380006f, - 0x00000013, + 0x00c0006f, + 0x0500006f, + 0x0340006f, 0x0ff0000f, 0x7b241073, 0xf1402473, @@ -19,16 +16,17 @@ uint32_t reset_vec[reset_vec_size] = { 0xf1402473, 0x40044403, 0x00247413, - 0xfc0414e3, + 0xfc0418e3, 0xfddff06f, - 0x10002c23, + 0x10002623, 0x7b202473, 0x00100073, - 0x10002423, + 0x10002223, 0x7b202473, - 0xaa5ff06f, + 0xab1ff06f, 0xf1402473, - 0x10802823, + 0x10802423, 0x7b202473, - 0x7b200073 + 0x7b200073, + 0x00000000 }; diff --git a/hw/vendor/cheriot_debug_module/debug_rom/debug_rom_one_scratch.sv b/hw/vendor/cheriot_debug_module/debug_rom/debug_rom_one_scratch.sv deleted file mode 100644 index 3cd2d9e2..00000000 --- a/hw/vendor/cheriot_debug_module/debug_rom/debug_rom_one_scratch.sv +++ /dev/null @@ -1,66 +0,0 @@ -/* 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: $filename.v - * - * Description: Auto-generated bootrom - */ - -// Auto-generated code -module debug_rom_one_scratch ( - input logic clk_i, - input logic rst_ni, - input logic req_i, - input logic [63:0] addr_i, - output logic [63:0] rdata_o -); - - localparam int unsigned RomSize = 14; - - logic [RomSize-1:0][63:0] mem; - assign mem = { - 64'h7b200073_7b202473, - 64'h10802823_f1402473, - 64'haa5ff06f_7b202473, - 64'h10002423_00100073, - 64'h7b202473_10002c23, - 64'hfddff06f_fc0414e3, - 64'h00247413_40044403, - 64'hf1402473_02041263, - 64'h00147413_40044403, - 64'h10802023_f1402473, - 64'h7b241073_0ff0000f, - 64'h00000013_0380006f, - 64'h00000013_0580006f, - 64'h00000013_0180006f - }; - - logic [$clog2(RomSize)-1:0] addr_d, addr_q; - - assign addr_d = req_i ? addr_i[$clog2(RomSize)-1+3:3] : addr_q; - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - addr_q <= '0; - end else begin - addr_q <= addr_d; - 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 < $clog2(RomSize)'(RomSize)) begin - rdata_o = mem[addr_q]; - end - end - -endmodule diff --git a/hw/vendor/cheriot_debug_module/debug_rom/gen_rom.py b/hw/vendor/cheriot_debug_module/debug_rom/gen_rom.py index a9dafe63..7f0ac666 100755 --- a/hw/vendor/cheriot_debug_module/debug_rom/gen_rom.py +++ b/hw/vendor/cheriot_debug_module/debug_rom/gen_rom.py @@ -22,11 +22,7 @@ filename = os.path.splitext(file)[0] license = """\ -/* - * Conversion to CHERIoT Ibex ISA from RISC-V - * Copyright SCI Semiconductor 2025 - * - * Copyright 2018 ETH Zurich and University of Bologna. +/* 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 @@ -47,7 +43,6 @@ module = """\ module $filename ( input logic clk_i, - input logic rst_ni, input logic req_i, input logic [63:0] addr_i, output logic [63:0] rdata_o @@ -60,15 +55,11 @@ $content }; - logic [$$clog2(RomSize)-1:0] addr_d, addr_q; - - assign addr_d = req_i ? addr_i[$$clog2(RomSize)-1+3:3] : addr_q; + logic [$$clog2(RomSize)-1:0] addr_q; - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - addr_q <= '0; - end else begin - addr_q <= addr_d; + always_ff @(posedge clk_i) begin + if (req_i) begin + addr_q <= addr_i[$$clog2(RomSize)-1+3:3]; end end @@ -77,7 +68,7 @@ always_comb begin : p_outmux rdata_o = '0; if (addr_q < $$clog2(RomSize)'(RomSize)) begin - rdata_o = mem[addr_q]; + rdata_o = mem[addr_q]; end end @@ -97,9 +88,10 @@ def read_bin(): with open(filename + ".img", 'rb') as f: - rom = bytes.hex(f.read()) + rom = binascii.hexlify(f.read()).decode("utf-8") rom = list(map(''.join, zip(rom[::2], rom[1::2]))) + # align to 64 bit align = (int((len(list(rom)) + 7) / 8 )) * 8; diff --git a/hw/vendor/cheriot_debug_module/doc/debug-system.md b/hw/vendor/cheriot_debug_module/doc/debug-system.md index 5fbfbe18..b025f89f 100644 --- a/hw/vendor/cheriot_debug_module/doc/debug-system.md +++ b/hw/vendor/cheriot_debug_module/doc/debug-system.md @@ -439,9 +439,9 @@ Address | Description --------------- | ------------------------------------------------------------------------------------------------------------------------------------------ 0x0 to 0x0ff | _unused_ 0x100 | Halted. Write to this address to acknowledge that the core is halted. -0x108 | Going. Write to this address to acknowledge that the core is executing. -0x110 | Resuming. Write to this address to acknowledge that the core is resuming non-debug operation. -0x118 | Exception. An exception was triggered while the core was in debug mode. +0x104 | Going. Write to this address to acknowledge that the core is executing. +0x108 | Resuming. Write to this address to acknowledge that the core is resuming non-debug operation. +0x10c | Exception. An exception was triggered while the core was in debug mode. 0x300 | WhereTo 0x338 to 0x35f | AbstractCmd 0x360 to 0x37f | Program Buffer (8 words) @@ -449,8 +449,8 @@ Address | Description 0x400 to 0x7ff | Flags 0x800 to 0x1000 | Debug ROM 0x800 | HaltAddress. Entry point into the Debug Module. The core must jump to this address when it was requested to halt. -0x808 | ResumeAddress. Entry point into the Debug Module. Jumping to this address instructs the debug module to bring the core out of debug mode and back into normal operation mode. -0x810 | ExceptionAddress. Entry point into the Debug Module. The core must jump to this address when it receives an exception while being in debug mode. +0x804 | ResumeAddress. Entry point into the Debug Module. Jumping to this address instructs the debug module to bring the core out of debug mode and back into normal operation mode. +0x808 | ExceptionAddress. Entry point into the Debug Module. The core must jump to this address when it receives an exception while being in debug mode. (Note: The debug memory addressing scheme is adopted from the Rocket Chip Generator.) @@ -485,6 +485,7 @@ default the IR register is 5 bits long, but the implementation is parameterized. ) ( ``` - `DTMCSR`: RISC-V specific control and status register of the JTAG DMI. + Currently `dmihardreset` is not implemented. - `DMIACCESS`: Access the debug module's register. - `abits+33:34`: Address - `33:2`: Data diff --git a/hw/vendor/cheriot_debug_module/src/dm_csrs.sv b/hw/vendor/cheriot_debug_module/src/dm_csrs.sv index a800141b..943738cc 100644 --- a/hw/vendor/cheriot_debug_module/src/dm_csrs.sv +++ b/hw/vendor/cheriot_debug_module/src/dm_csrs.sv @@ -22,10 +22,8 @@ module dm_csrs #( ) ( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low - input logic [31:0] next_dm_addr_i, // Static next_dm word address. input logic testmode_i, - input logic dmi_rst_ni, // sync. DTM reset, - // active-low + 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, @@ -35,7 +33,6 @@ module dm_csrs #( output dm::dmi_resp_t dmi_resp_o, // global ctrl output logic ndmreset_o, // non-debug module reset active-high - input logic ndmreset_ack_i, // non-debug module reset ack pulse output logic dmactive_o, // 1 -> debug-module is active, // 0 -> synchronous re-set // hart status @@ -89,6 +86,8 @@ module dm_csrs #( dm::dtm_op_e dtm_op; assign dtm_op = dm::dtm_op_e'(dmi_req_i.op); + logic [31:0] resp_queue_data; + localparam dm::dm_csr_e DataEnd = dm::dm_csr_e'(dm::Data0 + {4'h0, dm::DataCount} - 8'h1); localparam dm::dm_csr_e ProgBufEnd = dm::dm_csr_e'(dm::ProgBuf0 + {4'h0, dm::ProgBufSize} - 8'h1); @@ -176,8 +175,8 @@ module dm_csrs #( logic [HartSelLen-1:0] selected_hart; - dm::dmi_resp_t resp_queue_inp; - + // a successful response returns zero + assign dmi_resp_o.resp = dm::DTM_SUCCESS; // SBA assign sbautoincrement_o = sbcs_q.sbautoincrement; assign sbreadonaddr_o = sbcs_q.sbreadonaddr; @@ -213,14 +212,11 @@ module dm_csrs #( // Get the data index, i.e. 0 for dm::Data0 up to 11 for dm::Data11 assign dm_csr_addr = dm::dm_csr_e'({1'b0, dmi_req_i.addr}); - logic unused_addr_bits; - assign unused_addr_bits = ^dmi_req_i.addr[31:$bits(dm_csr_addr)]; - // Xilinx Vivado 2020.1 does not allow subtraction of two enums; do the subtraction with logic // types instead. assign autoexecdata_idx = 4'({dm_csr_addr} - {dm::Data0}); - always_comb (*xprop_off *) begin : csr_read_write + always_comb begin : csr_read_write // -------------------- // Static Values (R/O) // -------------------- @@ -276,8 +272,7 @@ module dm_csrs #( sbaddr_d = 64'(sbaddress_i); sbdata_d = sbdata_q; - resp_queue_inp.data = 32'h0; - resp_queue_inp.resp = dm::DTM_SUCCESS; + resp_queue_data = 32'h0; cmd_valid_d = 1'b0; sbaddress_write_valid_o = 1'b0; sbdata_read_valid_o = 1'b0; @@ -292,70 +287,62 @@ module dm_csrs #( if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_READ) begin unique case (dm_csr_addr) inside [(dm::Data0):DataEnd]: begin - resp_queue_inp.data = data_q[$clog2(dm::DataCount)'(autoexecdata_idx)]; + 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[autoexecdata_idx]; // An abstract command was executing while one of the data registers was read - end else begin - resp_queue_inp.resp = dm::DTM_BUSY; - if (cmderr_q == dm::CmdErrNone) begin - cmderr_d = dm::CmdErrBusy; - end + end else if (cmderr_q == dm::CmdErrNone) begin + cmderr_d = dm::CmdErrBusy; end end - dm::DMControl: resp_queue_inp.data = dmcontrol_q; - dm::DMStatus: resp_queue_inp.data = dmstatus; - dm::Hartinfo: resp_queue_inp.data = hartinfo_aligned[selected_hart]; - dm::AbstractCS: resp_queue_inp.data = abstractcs; - dm::AbstractAuto: resp_queue_inp.data = abstractauto_q; - dm::Command: resp_queue_inp.data = '0; - dm::NextDM: resp_queue_inp.data = next_dm_addr_i; + dm::DMControl: resp_queue_data = dmcontrol_q; + dm::DMStatus: resp_queue_data = dmstatus; + 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_inp.data = progbuf_q[dmi_req_i.addr[$clog2(dm::ProgBufSize)-1: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) // range of autoexecprogbuf is 31:16 cmd_valid_d = abstractauto_q.autoexecprogbuf[{1'b1, dmi_req_i.addr[3:0]}]; // An abstract command was executing while one of the progbuf registers was read - end else begin - resp_queue_inp.resp = dm::DTM_BUSY; - if (cmderr_q == dm::CmdErrNone) begin - cmderr_d = dm::CmdErrBusy; - end + end else if (cmderr_q == dm::CmdErrNone) begin + cmderr_d = dm::CmdErrBusy; end end - dm::HaltSum0: resp_queue_inp.data = haltsum0; - dm::HaltSum1: resp_queue_inp.data = haltsum1; - dm::HaltSum2: resp_queue_inp.data = haltsum2; - dm::HaltSum3: resp_queue_inp.data = haltsum3; + 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_inp.data = sbcs_q; + resp_queue_data = sbcs_q; end dm::SBAddress0: begin - resp_queue_inp.data = sbaddr_q[31:0]; + resp_queue_data = sbaddr_q[31:0]; end dm::SBAddress1: begin - resp_queue_inp.data = sbaddr_q[63:32]; + resp_queue_data = sbaddr_q[63:32]; end dm::SBData0: begin // access while the SBA was busy if (sbbusy_i || sbcs_q.sbbusyerror) begin sbcs_d.sbbusyerror = 1'b1; - resp_queue_inp.resp = dm::DTM_BUSY; end else begin sbdata_read_valid_o = (sbcs_q.sberror == '0); - resp_queue_inp.data = sbdata_q[31:0]; + resp_queue_data = sbdata_q[31:0]; end end dm::SBData1: begin // access while the SBA was busy if (sbbusy_i || sbcs_q.sbbusyerror) begin sbcs_d.sbbusyerror = 1'b1; - resp_queue_inp.resp = dm::DTM_BUSY; end else begin - resp_queue_inp.data = sbdata_q[63:32]; + resp_queue_data = sbdata_q[63:32]; end end default:; @@ -373,11 +360,8 @@ module dm_csrs #( // check whether we need to re-execute the command (just give a cmd_valid) cmd_valid_d = abstractauto_q.autoexecdata[autoexecdata_idx]; //An abstract command was executing while one of the data registers was written - end else begin - resp_queue_inp.resp = dm::DTM_BUSY; - if (cmderr_q == dm::CmdErrNone) begin - cmderr_d = dm::CmdErrBusy; - end + end else if (cmderr_q == dm::CmdErrNone) begin + cmderr_d = dm::CmdErrBusy; end end end @@ -400,11 +384,8 @@ module dm_csrs #( // reads during abstract command execution are not allowed if (!cmdbusy_i) begin cmderr_d = dm::cmderr_e'(~a_abstractcs.cmderr & cmderr_q); - end else begin - resp_queue_inp.resp = dm::DTM_BUSY; - if (cmderr_q == dm::CmdErrNone) begin - cmderr_d = dm::CmdErrBusy; - end + end else if (cmderr_q == dm::CmdErrNone) begin + cmderr_d = dm::CmdErrBusy; end end dm::Command: begin @@ -414,25 +395,18 @@ module dm_csrs #( 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 begin - resp_queue_inp.resp = dm::DTM_BUSY; - if (cmderr_q == dm::CmdErrNone) begin - cmderr_d = dm::CmdErrBusy; - end + end else if (cmderr_q == dm::CmdErrNone) begin + cmderr_d = dm::CmdErrBusy; end end - dm::NextDM:; // nextdm is R/O dm::AbstractAuto: begin // this field can only be written legally when there is no command executing if (!cmdbusy_i) begin abstractauto_d = 32'h0; 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 begin - resp_queue_inp.resp = dm::DTM_BUSY; - if (cmderr_q == dm::CmdErrNone) begin - cmderr_d = dm::CmdErrBusy; - end + end else if (cmderr_q == dm::CmdErrNone) begin + cmderr_d = dm::CmdErrBusy; end end [(dm::ProgBuf0):ProgBufEnd]: begin @@ -445,31 +419,26 @@ module dm_csrs #( // range of autoexecprogbuf is 31:16 cmd_valid_d = abstractauto_q.autoexecprogbuf[{1'b1, dmi_req_i.addr[3:0]}]; //An abstract command was executing while one of the progbuf registers was written - end else begin - resp_queue_inp.resp = dm::DTM_BUSY; - if (cmderr_q == dm::CmdErrNone) begin - cmderr_d = dm::CmdErrBusy; - end + end else if (cmderr_q == dm::CmdErrNone) begin + cmderr_d = dm::CmdErrBusy; end end dm::SBCS: begin // access while the SBA was busy if (sbbusy_i) begin sbcs_d.sbbusyerror = 1'b1; - resp_queue_inp.resp = dm::DTM_BUSY; end else begin 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.sberror) ? 3'b0 : sbcs_q.sberror; + sbcs_d.sberror = sbcs_q.sberror & (~sbcs.sberror); end end dm::SBAddress0: begin // access while the SBA was busy if (sbbusy_i || sbcs_q.sbbusyerror) begin sbcs_d.sbbusyerror = 1'b1; - resp_queue_inp.resp = dm::DTM_BUSY; end else begin sbaddr_d[31:0] = dmi_req_i.data; sbaddress_write_valid_o = (sbcs_q.sberror == '0); @@ -479,7 +448,6 @@ module dm_csrs #( // access while the SBA was busy if (sbbusy_i || sbcs_q.sbbusyerror) begin sbcs_d.sbbusyerror = 1'b1; - resp_queue_inp.resp = dm::DTM_BUSY; end else begin sbaddr_d[63:32] = dmi_req_i.data; end @@ -488,7 +456,6 @@ module dm_csrs #( // access while the SBA was busy if (sbbusy_i || sbcs_q.sbbusyerror) begin sbcs_d.sbbusyerror = 1'b1; - resp_queue_inp.resp = dm::DTM_BUSY; end else begin sbdata_d[31:0] = dmi_req_i.data; sbdata_write_valid_o = (sbcs_q.sberror == '0); @@ -498,7 +465,6 @@ module dm_csrs #( // access while the SBA was busy if (sbbusy_i || sbcs_q.sbbusyerror) begin sbcs_d.sbbusyerror = 1'b1; - resp_queue_inp.resp = dm::DTM_BUSY; end else begin sbdata_d[63:32] = dmi_req_i.data; end @@ -516,8 +482,8 @@ module dm_csrs #( data_d = data_i; end - // set the havereset flag when the ndmreset completed - if (ndmreset_ack_i) begin + // set the havereset flag when we did a ndmreset + if (ndmreset_o) begin havereset_d_aligned[NrHarts-1:0] = '1; end // ------------- @@ -549,18 +515,16 @@ module dm_csrs #( if (dmcontrol_q.resumereq && resumeack_i) begin dmcontrol_d.resumereq = 1'b0; end - // WARL behavior of hartsel, depending on NrHarts. - // If NrHarts = 1 this is just masked to all-zeros. - {dmcontrol_d.hartselhi, dmcontrol_d.hartsello} &= (2**$clog2(NrHarts))-1; // static values for dcsr sbcs_d.sbversion = 3'd1; sbcs_d.sbbusy = sbbusy_i; sbcs_d.sbasize = $bits(sbcs_d.sbasize)'(BusWidth); - sbcs_d.sbaccess128 = logic'(BusWidth >= 32'd128); - sbcs_d.sbaccess64 = logic'(BusWidth >= 32'd64); - sbcs_d.sbaccess32 = logic'(BusWidth >= 32'd32); - sbcs_d.sbaccess16 = logic'(BusWidth >= 32'd16); - sbcs_d.sbaccess8 = logic'(BusWidth >= 32'd8); + 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) ? 3'd3 : 3'd2; end // output multiplexer @@ -588,17 +552,17 @@ module dm_csrs #( // response FIFO prim_fifo_sync #( - .Width ($bits(dmi_resp_o)), + .Width (32), .Pass (1'b0), .Depth (2) ) i_fifo ( .clk_i ( clk_i ), .rst_ni ( dmi_rst_ni ), // reset only when system is re-set .clr_i ( 1'b0 ), - .wdata_i ( resp_queue_inp ), + .wdata_i ( resp_queue_data ), .wvalid_i( dmi_req_valid_i ), .wready_o( dmi_req_ready_o ), - .rdata_o ( dmi_resp_o ), + .rdata_o ( dmi_resp_o.data ), .rvalid_o( dmi_resp_valid_o ), .rready_i( dmi_resp_ready_i ), .full_o ( ), // Unused @@ -617,7 +581,7 @@ module dm_csrs #( abstractauto_q <= '0; progbuf_q <= '0; data_q <= '0; - sbcs_q <= '{default: '0, sbaccess: 3'd2}; + sbcs_q <= '0; sbaddr_q <= '0; sbdata_q <= '0; havereset_q <= '1; @@ -645,7 +609,7 @@ module dm_csrs #( abstractauto_q <= '0; progbuf_q <= '0; data_q <= '0; - sbcs_q <= '{default: '0, sbaccess: 3'd2}; + sbcs_q <= '0; sbaddr_q <= '0; sbdata_q <= '0; end else begin diff --git a/hw/vendor/cheriot_debug_module/src/dm_mem.sv b/hw/vendor/cheriot_debug_module/src/dm_mem.sv index f1a7ce2d..8462c86c 100644 --- a/hw/vendor/cheriot_debug_module/src/dm_mem.sv +++ b/hw/vendor/cheriot_debug_module/src/dm_mem.sv @@ -24,14 +24,13 @@ module dm_mem #( parameter int unsigned NrHarts = 1, parameter int unsigned BusWidth = 32, parameter logic [NrHarts-1:0] SelectableHarts = {NrHarts{1'b1}}, - parameter int unsigned DmBaseAddress = '0, - localparam int unsigned BeWidth = BusWidth/8 + parameter int unsigned DmBaseAddress = '0 ) ( input logic clk_i, // Clock input logic rst_ni, // debug module reset + input logic ndmreset_i, output logic [NrHarts-1:0] debug_req_o, - input logic ndmreset_i, input logic [19:0] hartsel_i, // from Ctrl and Status register input logic [NrHarts-1:0] haltreq_i, @@ -60,9 +59,8 @@ module dm_mem #( input logic we_i, input logic [BusWidth-1:0] addr_i, input logic [BusWidth-1:0] wdata_i, - input logic [BeWidth-1:0] be_i, - output logic [BusWidth-1:0] rdata_o, - output logic err_o + 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); @@ -84,19 +82,11 @@ module dm_mem #( localparam logic [DbgAddressBits-1:0] FlagsEndAddr = 'h7FF; localparam logic [DbgAddressBits-1:0] HaltedAddr = 'h100; - localparam logic [DbgAddressBits-1:0] GoingAddr = 'h108; - localparam logic [DbgAddressBits-1:0] ResumingAddr = 'h110; - localparam logic [DbgAddressBits-1:0] ExceptionAddr = 'h118; - - localparam logic [DbgAddressBits-1:0] RomBaseAddr = dm::HaltAddress; - // The size is arbitrarily set to 0x800, so as to make the dm_space exactly 0x900 long. This is - // more than eough to cover the 19 x 64bit = 0x98 bytes currenty allocated in the debug ROM. - localparam logic [DbgAddressBits-1:0] RomEndAddr = dm::HaltAddress + 'h7FF; - // Prog buff size after repacking the 32bit array into a 64bit array. - localparam int unsigned ProgBuf64Size = dm::ProgBufSize / 2; - localparam int unsigned ProgBuf64AddrSize = $clog2(ProgBuf64Size); - - logic [ProgBuf64Size-1:0][63:0] progbuf; + 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 [7:0][63:0] abstract_cmd; logic [NrHarts-1:0] halted_d, halted_q; logic [NrHarts-1:0] resuming_d, resuming_q; @@ -216,13 +206,6 @@ module dm_mem #( cmderror_valid_o = 1'b1; cmderror_o = dm::CmdErrorException; end - - if (ndmreset_i) begin - // Clear state of hart and its control signals when it is being reset. - state_d = Idle; - go = 1'b0; - resume = 1'b0; - end end // word mux for 32bit and 64bit buses @@ -236,16 +219,16 @@ module dm_mem #( end // read/write logic - logic [dm::DataCount-1:0][31:0] data_bits; + logic [63:0] data_bits; logic [7:0][7:0] rdata; - always_comb (* xprop_off *) begin : p_rw_logic + always_comb begin : p_rw_logic 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; rdata = '0; - fwd_rom_d = 1'b0; // write data in csr register data_valid_o = 1'b0; @@ -280,24 +263,13 @@ module dm_mem #( // core can write data registers [DataBaseAddr:DataEndAddr]: begin data_valid_o = 1'b1; - for (int unsigned dc = 0; dc < dm::DataCount; dc++) begin - if ((addr_i[DbgAddressBits-1:2] - DataBaseAddr[DbgAddressBits-1:2]) == dc) begin - for (int unsigned i = 0; i < $bits(be_i); i++) begin - if (be_i[i]) begin - if (i>3) begin // for upper 32bit data write (only used for BusWidth == 64) - // ensure we write to an implemented data register - if (dc < (dm::DataCount - 1)) begin - data_bits[dc+1][(i-4)*8+:8] = wdata_i[i*8+:8]; - end - end else begin // for lower 32bit data write - data_bits[dc][i*8+:8] = wdata_i[i*8+:8]; - end - end - end + 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: ; + default ; endcase // this is a read @@ -326,17 +298,16 @@ module dm_mem #( [DataBaseAddr:DataEndAddr]: begin rdata_d = { - data_i[$clog2(dm::DataCount)'(((addr_i[DbgAddressBits-1:3] - - DataBaseAddr[DbgAddressBits-1:3]) << 1) - + 1'b1)], - data_i[$clog2(dm::DataCount)'(((addr_i[DbgAddressBits-1:3] - - DataBaseAddr[DbgAddressBits-1:3]) << 1))] + data_i[$clog2(dm::ProgBufSize)'(addr_i[DbgAddressBits-1:3] - + DataBaseAddr[DbgAddressBits-1:3] + 1'b1)], + data_i[$clog2(dm::ProgBufSize)'(addr_i[DbgAddressBits-1:3] - + DataBaseAddr[DbgAddressBits-1:3])] }; end [ProgBufBaseAddr:ProgBufEndAddr]: begin - rdata_d = progbuf[ProgBuf64AddrSize'(addr_i[DbgAddressBits-1:3] - - ProgBufBaseAddr[DbgAddressBits-1:3])]; + rdata_d = progbuf[$clog2(dm::ProgBufSize)'(addr_i[DbgAddressBits-1:3] - + ProgBufBaseAddr[DbgAddressBits-1:3])]; end // two slots for abstract command @@ -354,73 +325,14 @@ module dm_mem #( end rdata_d = rdata; end - // Access has to be forwarded to the ROM. The ROM starts at the HaltAddress of the core - // e.g.: it immediately jumps to the ROM base address. - [RomBaseAddr:RomEndAddr]: begin - fwd_rom_d = 1'b1; - end default: ; endcase end end - if (ndmreset_i) begin - // When harts are reset, they are neither halted nor resuming. - halted_d_aligned = '0; - resuming_d_aligned = '0; - end - data_o = data_bits; end - // This flags subword writes that are shorter than the defined width of the register. - // Other writes are ignored. - function automatic logic gen_wr_err(logic we, logic [BeWidth-1:0] be, logic [BeWidth-1:0] mask); - return we && (|(~be & mask)); - endfunction - - // Relevant bus error cases - // - access unmapped address - // - write a CSR with unaligned address, e.g. `a_address[1:0] != 0` - // - write a CSR less than its width, e.g. when CSR is 2 bytes wide, only write 1 byte - // - write a RO (read-only) memory - localparam logic[BeWidth-1:0] FullRegMask = {BeWidth{1'b1}}; - localparam logic[BeWidth-1:0] OneBitMask = BeWidth'(1'b1); - localparam logic[BeWidth-1:0] HartSelMask = BeWidth'(2**HartSelLen-1); - logic err_d, err_q; - always_comb begin - err_d = 1'b0; - if (req_i) begin - unique case (addr_i[DbgAddressBits-1:0]) inside - WhereToAddr: err_d = gen_wr_err(we_i, be_i, FullRegMask); - HaltedAddr: err_d = gen_wr_err(we_i, be_i, HartSelMask); - GoingAddr: err_d = gen_wr_err(we_i, be_i, OneBitMask); - ResumingAddr: err_d = gen_wr_err(we_i, be_i, HartSelMask); - ExceptionAddr: err_d = gen_wr_err(we_i, be_i, OneBitMask); - [DataBaseAddr:DataEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); - [ProgBufBaseAddr:ProgBufEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); - [AbstractCmdBaseAddr:AbstractCmdEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); - [FlagsBaseAddr:FlagsEndAddr]: err_d = gen_wr_err(we_i, be_i, FullRegMask); - [RomBaseAddr:RomEndAddr]: err_d = we_i; // Writing ROM area always errors. - default: err_d = 1'b1; - endcase - // Unaligned accesses - if (addr_i[$clog2(BeWidth)-1:0] != '0) begin - err_d = 1'b1; - end - end - end - - always_ff @(posedge clk_i or negedge rst_ni) begin : p_err_reg - if (!rst_ni) begin - err_q <= 1'b0; - end else begin - err_q <= err_d; - end - end - - assign err_o = err_q; - always_comb begin : p_abstract_cmd_rom // this abstract command is currently unsupported unsupported_command = 1'b0; @@ -569,7 +481,6 @@ module dm_mem #( if (HasSndScratch) begin : gen_rom_snd_scratch debug_rom i_debug_rom ( .clk_i, - .rst_ni, .req_i, .addr_i ( rom_addr ), .rdata_o ( rom_rdata ) @@ -580,13 +491,16 @@ module dm_mem #( // be saved. debug_rom_one_scratch i_debug_rom ( .clk_i, - .rst_ni, .req_i, .addr_i ( rom_addr ), .rdata_o ( rom_rdata ) ); end + // ROM starts at the HaltAddress of the core e.g.: it immediately jumps to + // the ROM base address + 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 fwd_rom_q <= 1'b0; diff --git a/hw/vendor/cheriot_debug_module/src/dm_obi_top.sv b/hw/vendor/cheriot_debug_module/src/dm_obi_top.sv index aa0b4f0f..b1906ec7 100644 --- a/hw/vendor/cheriot_debug_module/src/dm_obi_top.sv +++ b/hw/vendor/cheriot_debug_module/src/dm_obi_top.sv @@ -101,10 +101,8 @@ module dm_obi_top #( 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_rvalid_i, // Renamed according to OBI spec - input logic master_err_i, - input logic master_other_err_i, // *other_err_i has priority over *err_i - input logic [BusWidth-1:0] master_rdata_i, // Renamed according to OBI spec + input logic master_rvalid_i, // Renamed according to OBI spec + input logic [BusWidth-1:0] master_rdata_i, // Renamed according to OBI spec // Connection to DTM - compatible to RocketChip Debug Module input logic dmi_rst_ni, @@ -151,8 +149,6 @@ module dm_obi_top #( .master_be_o ( master_be_o ), .master_gnt_i ( master_gnt_i ), .master_r_valid_i ( master_rvalid_i ), // Renamed according to OBI spec - .master_r_err_i ( master_err_i ), - .master_r_other_err_i ( master_other_err_i ), // *other_err_i has priority over *err_i .master_r_rdata_i ( master_rdata_i ), // Renamed according to OBI spec .dmi_rst_ni ( dmi_rst_ni ), diff --git a/hw/vendor/cheriot_debug_module/src/dm_pkg.sv b/hw/vendor/cheriot_debug_module/src/dm_pkg.sv index 9a00bf46..094cf0a1 100644 --- a/hw/vendor/cheriot_debug_module/src/dm_pkg.sv +++ b/hw/vendor/cheriot_debug_module/src/dm_pkg.sv @@ -30,8 +30,8 @@ package dm; // 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 + 8; - localparam logic [63:0] ExceptionAddress = HaltAddress + 16; + 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 @@ -201,12 +201,6 @@ package dm; DTM_WRITE = 2'h2 } dtm_op_e; - typedef enum logic [1:0] { - DTM_SUCCESS = 2'h0, - DTM_ERR = 2'h2, - DTM_BUSY = 2'h3 - } dtm_op_status_e; - typedef struct packed { logic [31:29] sbversion; logic [28:23] zero0; @@ -225,8 +219,10 @@ package dm; logic sbaccess8; } sbcs_t; + localparam logic [1:0] DTM_SUCCESS = 2'h0; + typedef struct packed { - logic [31:0] addr; + logic [6:0] addr; dtm_op_e op; logic [31:0] data; } dmi_req_t; diff --git a/hw/vendor/cheriot_debug_module/src/dm_sba.sv b/hw/vendor/cheriot_debug_module/src/dm_sba.sv index a9f0bde3..6cd0bfb4 100644 --- a/hw/vendor/cheriot_debug_module/src/dm_sba.sv +++ b/hw/vendor/cheriot_debug_module/src/dm_sba.sv @@ -31,8 +31,6 @@ module dm_sba #( output logic [BusWidth/8-1:0] master_be_o, input logic master_gnt_i, input logic master_r_valid_i, - input logic master_r_err_i, - input logic master_r_other_err_i, // *other_err_i has priority over *err_i input logic [BusWidth-1:0] master_r_rdata_i, input logic [BusWidth-1:0] sbaddress_i, @@ -56,7 +54,6 @@ module dm_sba #( output logic [2:0] sberror_o // bus error occurred ); - localparam int BeIdxWidth = $clog2(BusWidth/8); dm::sba_state_e state_d, state_q; logic [BusWidth-1:0] address; @@ -65,7 +62,7 @@ module dm_sba #( logic we; logic [BusWidth/8-1:0] be; logic [BusWidth/8-1:0] be_mask; - logic [BeIdxWidth-1:0] be_idx; + logic [$clog2(BusWidth/8)-1:0] be_idx; assign sbbusy_o = logic'(state_q != dm::Idle); @@ -89,26 +86,16 @@ module dm_sba #( endcase end - logic [BusWidth-1:0] sbaccess_mask; - assign sbaccess_mask = {BusWidth{1'b1}} << sbaccess_i; - - logic addr_incr_en; - logic [BusWidth-1:0] addr_incr; - assign addr_incr = (addr_incr_en) ? (BusWidth'(1'b1) << sbaccess_i) : '0; - assign sbaddress_o = sbaddress_i + addr_incr; - - always_comb begin : p_fsm req = 1'b0; address = sbaddress_i; we = 1'b0; be = '0; - be_idx = sbaddress_i[BeIdxWidth-1:0]; + be_idx = sbaddress_i[$clog2(BusWidth/8)-1:0]; sberror_o = '0; sberror_valid_o = 1'b0; - - addr_incr_en = 1'b0; + sbaddress_o = sbaddress_i; state_d = state_q; @@ -139,16 +126,7 @@ module dm_sba #( if (sbdata_valid_o) begin state_d = dm::Idle; // auto-increment address - addr_incr_en = sbautoincrement_i; - // check whether an "other" error has been encountered. - if (master_r_other_err_i) begin - sberror_valid_o = 1'b1; - sberror_o = 3'd7; - // check whether there was a bus error (== bad address). - end else if (master_r_err_i) begin - sberror_valid_o = 1'b1; - sberror_o = 3'd2; - end + if (sbautoincrement_i) sbaddress_o = sbaddress_i + (32'h1 << sbaccess_i); end end @@ -156,16 +134,7 @@ module dm_sba #( if (sbdata_valid_o) begin state_d = dm::Idle; // auto-increment address - addr_incr_en = sbautoincrement_i; - // check whether an "other" error has been encountered. - if (master_r_other_err_i) begin - sberror_valid_o = 1'b1; - sberror_o = 3'd7; - // check whether there was a bus error (== bad address). - end else if (master_r_err_i) begin - sberror_valid_o = 1'b1; - sberror_o = 3'd2; - end + if (sbautoincrement_i) sbaddress_o = sbaddress_i + (32'h1 << sbaccess_i); end end @@ -173,19 +142,11 @@ module dm_sba #( endcase // handle error case - if (32'(sbaccess_i) > BeIdxWidth && state_q != dm::Idle) begin - req = 1'b0; - state_d = dm::Idle; - sberror_valid_o = 1'b1; - sberror_o = 3'd4; // unsupported size was requested - end - - //if sbaccess_i lsbs of address are not 0 - report misalignment error - if (|(sbaddress_i & ~sbaccess_mask) && state_q != dm::Idle) begin + if (sbaccess_i > 3 && state_q != dm::Idle) begin req = 1'b0; state_d = dm::Idle; sberror_valid_o = 1'b1; - sberror_o = 3'd3; // alignment error + sberror_o = 3'd3; end // further error handling should go here ... end @@ -198,15 +159,13 @@ module dm_sba #( end end - logic [BeIdxWidth-1:0] be_idx_masked; - assign be_idx_masked = be_idx & BeIdxWidth'(sbaccess_mask); 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] << (8 * be_idx_masked); + 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] >> (8 * be_idx_masked); + assign sbdata_o = master_r_rdata_i[BusWidth-1:0]; endmodule : dm_sba diff --git a/hw/vendor/cheriot_debug_module/src/dm_top.sv b/hw/vendor/cheriot_debug_module/src/dm_top.sv index 87b480aa..a92faeeb 100644 --- a/hw/vendor/cheriot_debug_module/src/dm_top.sv +++ b/hw/vendor/cheriot_debug_module/src/dm_top.sv @@ -122,7 +122,6 @@ module dm_top #( ) i_dm_csrs ( .clk_i, .rst_ni, - .next_dm_addr_i, .testmode_i, .dmi_rst_ni, .dmi_req_valid_i, @@ -132,7 +131,6 @@ module dm_top #( .dmi_resp_ready_i, .dmi_resp_o, .ndmreset_o ( ndmreset ), - .ndmreset_ack_i ( ndmreset_ack_i ), .dmactive_o, .hartsel_o ( hartsel ), .hartinfo_i, @@ -183,8 +181,6 @@ module dm_top #( .master_be_o, .master_gnt_i, .master_r_valid_i, - .master_r_err_i, - .master_r_other_err_i, .master_r_rdata_i, .sbaddress_i ( sbaddress_csrs_sba ), @@ -234,8 +230,7 @@ module dm_top #( .addr_i ( slave_addr_i ), .wdata_i ( slave_wdata_i ), .be_i ( slave_be_i ), - .rdata_o ( slave_rdata_o ), - .err_o ( slave_err_o ) + .rdata_o ( slave_rdata_o ) ); endmodule : dm_top diff --git a/hw/vendor/cheriot_debug_module/src/dmi_bscane_tap.sv b/hw/vendor/cheriot_debug_module/src/dmi_bscane_tap.sv index 5fe5d86e..b1c12a85 100644 --- a/hw/vendor/cheriot_debug_module/src/dmi_bscane_tap.sv +++ b/hw/vendor/cheriot_debug_module/src/dmi_bscane_tap.sv @@ -32,7 +32,7 @@ module dmi_jtag_tap #( input logic testmode_i, output logic tck_o, - output logic dmi_clear_o, + output logic trst_no, output logic update_o, output logic capture_o, output logic shift_o, @@ -44,12 +44,16 @@ module dmi_jtag_tap #( input logic dmi_tdo_i ); + /// DTMCS Register + logic trst; + assign trst_no = ~trst; + BSCANE2 #( .JTAG_CHAIN (3) ) i_tap_dtmcs ( .CAPTURE (capture_o), .DRCK (), - .RESET (dmi_clear_o), + .RESET (trst), .RUNTEST (), .SEL (dtmcs_select_o), .SHIFT (shift_o), diff --git a/hw/vendor/cheriot_debug_module/src/dmi_cdc.sv b/hw/vendor/cheriot_debug_module/src/dmi_cdc.sv index e31ae88b..7dd550e0 100644 --- a/hw/vendor/cheriot_debug_module/src/dmi_cdc.sv +++ b/hw/vendor/cheriot_debug_module/src/dmi_cdc.sv @@ -17,19 +17,13 @@ * This is mainly a wrapper around the existing CDCs. */ module dmi_cdc ( - // Test controls - input logic testmode_i, - input logic test_rst_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 logic jtag_dmi_cdc_clear_i, // Synchronous clear signal. - // Triggers reset sequencing - // accross CDC output dm::dmi_resp_t jtag_dmi_resp_o, output logic jtag_dmi_valid_o, @@ -39,7 +33,6 @@ module dmi_cdc ( input logic clk_i, input logic rst_ni, - output logic core_dmi_rst_no, output dm::dmi_req_t core_dmi_req_o, output logic core_dmi_valid_o, input logic core_dmi_ready_i, @@ -49,75 +42,40 @@ module dmi_cdc ( input logic core_dmi_valid_i ); - - logic jtag_combined_rstn; - always_ff @(posedge tck_i or negedge trst_ni) begin - if (!trst_ni) begin - jtag_combined_rstn <= '0; - end else if (jtag_dmi_cdc_clear_i) begin - jtag_combined_rstn <= '0; - end else begin - jtag_combined_rstn <= 1'b1; - end - end - - logic combined_rstn_premux; - prim_flop_2sync #( - .Width(1), - .ResetValue(0) - ) u_combined_rstn_sync ( - .clk_i, - .rst_ni(rst_ni), - .d_i(jtag_combined_rstn), - .q_o(combined_rstn_premux) - ); - - logic combined_rstn; - prim_clock_mux2 #( - .NoFpgaBufG(1'b1) - ) u_rst_mux ( - .clk0_i(combined_rstn_premux), - .clk1_i(test_rst_ni), - .sel_i(testmode_i), - .clk_o(combined_rstn) - ); + // TODO: Make it clean for synthesis. prim_fifo_async_simple #( - .Width($bits(dm::dmi_req_t)), - // Use the RZ protocol so that the two sides can be reset independently without getting - // out of sync due to EVEN/ODD states. - .EnRzHs(1) + .Width ( $bits(dm::dmi_req_t) ), + .EnRzHs ( 1 ) ) i_cdc_req ( - .clk_wr_i (tck_i), - .rst_wr_ni(trst_ni), - .wvalid_i (jtag_dmi_valid_i), - .wready_o (jtag_dmi_ready_o), - .wdata_i (jtag_dmi_req_i), - .clk_rd_i (clk_i), - .rst_rd_ni(combined_rstn), - .rvalid_o (core_dmi_valid_o), - .rready_i (core_dmi_ready_i), - .rdata_o (core_dmi_req_o) + .clk_wr_i ( tck_i ), + .rst_wr_ni ( trst_ni ), + .wvalid_i ( jtag_dmi_valid_i ), + .wready_o ( jtag_dmi_ready_o ), // wrclk + .wdata_i ( jtag_dmi_req_i ), + + .clk_rd_i ( clk_i ), + .rst_rd_ni ( rst_ni ), + .rvalid_o ( core_dmi_valid_o ), + .rready_i ( core_dmi_ready_i ), + .rdata_o ( core_dmi_req_o ) ); prim_fifo_async_simple #( - .Width($bits(dm::dmi_resp_t)), - // Use the RZ protocol so that the two sides can be reset independently without getting - // out of sync due to EVEN/ODD states. - .EnRzHs(1) + .Width ( $bits(dm::dmi_resp_t) ), + .EnRzHs ( 1 ) ) i_cdc_resp ( - .clk_wr_i (clk_i), - .rst_wr_ni(combined_rstn), - .wvalid_i (core_dmi_valid_i), - .wready_o (core_dmi_ready_o), - .wdata_i (core_dmi_resp_i), - .clk_rd_i (tck_i), - .rst_rd_ni(trst_ni), - .rvalid_o (jtag_dmi_valid_o), - .rready_i (jtag_dmi_ready_i), - .rdata_o (jtag_dmi_resp_o) - ); + .clk_wr_i ( clk_i ), + .rst_wr_ni ( rst_ni ), + .wvalid_i ( core_dmi_valid_i ), + .wready_o ( core_dmi_ready_o ), // wrclk + .wdata_i ( core_dmi_resp_i ), - assign core_dmi_rst_no = combined_rstn; + .clk_rd_i ( tck_i ), + .rst_rd_ni ( trst_ni ), + .rvalid_o ( jtag_dmi_valid_o ), + .rready_i ( jtag_dmi_ready_i ), + .rdata_o ( jtag_dmi_resp_o ) + ); endmodule : dmi_cdc diff --git a/hw/vendor/cheriot_debug_module/src/dmi_jtag.sv b/hw/vendor/cheriot_debug_module/src/dmi_jtag.sv index b82bde12..70ee7769 100644 --- a/hw/vendor/cheriot_debug_module/src/dmi_jtag.sv +++ b/hw/vendor/cheriot_debug_module/src/dmi_jtag.sv @@ -17,17 +17,13 @@ */ module dmi_jtag #( - parameter logic [31:0] IdcodeValue = 32'h00000DB3, - parameter int unsigned NumDmiWordAbits = 16 // Number of DMI address bits (7 - 32) + 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, - input logic test_rst_ni, - // active-low glitch free reset signal. Is asserted - // (clk_i) whenever the dmi_jtag is reset. - output logic dmi_rst_no, + 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, @@ -51,25 +47,22 @@ module dmi_jtag #( dmi_error_e error_d, error_q; logic tck; - logic jtag_dmi_clear; // Synchronous reset of DMI triggered by TestLogicReset in - // jtag TAP - logic dmi_clear; // Functional (warm) reset of the entire DMI + logic trst_n; logic update; logic capture; logic shift; logic tdi; - logic dtmcs_select; - dm::dtmcs_t dtmcs_d, dtmcs_q; - - assign dmi_clear = jtag_dmi_clear || (dtmcs_select && update && dtmcs_q.dmihardreset); - // ------------------------------- // Debug Module Control and Status // ------------------------------- + logic dtmcs_select; + + dm::dtmcs_t dtmcs_d, dtmcs_q; always_comb begin - dtmcs_d = dtmcs_q; + dtmcs_d = dtmcs_q; + if (capture) begin if (dtmcs_select) begin dtmcs_d = '{ @@ -79,7 +72,7 @@ module dmi_jtag #( zero0 : '0, idle : 3'd1, // 1: Enter Run-Test/Idle and leave it immediately dmistat : error_q, // 0: No error, 2: Op failed, 3: too fast - abits : 6'(NumDmiWordAbits), // The size of address in dmi + abits : 6'd7, // The size of address in dmi version : 4'd1 // Version described in spec version 0.13 (and later?) }; end @@ -90,8 +83,8 @@ module dmi_jtag #( end end - always_ff @(posedge tck or negedge trst_ni) begin - if (!trst_ni) begin + always_ff @(posedge tck or negedge trst_n) begin + if (!trst_n) begin dtmcs_q <= '0; end else begin dtmcs_q <= dtmcs_d; @@ -101,6 +94,9 @@ module dmi_jtag #( // ---------------------------- // DMI (Debug Module Interface) // ---------------------------- + // TODO(zarubaf): Might need to be connected to the `dtmcs_q.dmihardreset` + // signal. + assign dmi_rst_no = rst_ni; logic dmi_select; logic dmi_tdo; @@ -114,7 +110,7 @@ module dmi_jtag #( logic dmi_resp_ready; typedef struct packed { - logic [NumDmiWordAbits-1:0] address; + logic [6:0] address; logic [31:0] data; logic [1:0] op; } dmi_t; @@ -123,23 +119,21 @@ module dmi_jtag #( state_e state_d, state_q; logic [$bits(dmi_t)-1:0] dr_d, dr_q; - logic [NumDmiWordAbits-1:0] address_d, address_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 = $bits(dmi_req.addr)'(address_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; - logic error_dmi_op_failed; always_comb begin : p_fsm error_dmi_busy = 1'b0; - error_dmi_op_failed = 1'b0; // default assignments state_d = state_q; address_d = address_q; @@ -148,111 +142,79 @@ module dmi_jtag #( dmi_req_valid = 1'b0; - if (dmi_clear) begin - state_d = Idle; - data_d = '0; - error_d = DMINoError; - address_d = '0; - end else begin - unique case (state_q) - Idle: begin - // make sure that no error is sticky - if (dmi_select && update && (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; + unique case (state_q) + Idle: begin + // make sure that no error is sticky + if (dmi_select && update && (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 - WaitReadValid: begin - // load data into register and shift out - if (dmi_resp_valid) begin - unique case (dmi_resp.resp) - dm::DTM_SUCCESS: begin - data_d = dmi_resp.data; - end - dm::DTM_ERR: begin - data_d = 32'hDEAD_BEEF; - error_dmi_op_failed = 1'b1; - end - dm::DTM_BUSY: begin - data_d = 32'hB051_B051; - error_dmi_busy = 1'b1; - end - default: begin - data_d = 32'hBAAD_C0DE; - end - endcase - state_d = Idle; - end + Read: begin + dmi_req_valid = 1'b1; + if (dmi_req_ready) begin + state_d = WaitReadValid; end + end - Write: begin - dmi_req_valid = 1'b1; - // request sent, wait for response before going back to idle - if (dmi_req_ready) begin - state_d = WaitWriteValid; - 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 - WaitWriteValid: begin - // got a valid answer go back to idle - if (dmi_resp_valid) begin - unique case (dmi_resp.resp) - dm::DTM_ERR: error_dmi_op_failed = 1'b1; - dm::DTM_BUSY: error_dmi_busy = 1'b1; - default: ; - endcase - state_d = Idle; - end + Write: begin + dmi_req_valid = 1'b1; + // request sent, wait for response before going back to idle + if (dmi_req_ready) begin + state_d = WaitWriteValid; end + end - default: begin - // just wait for idle here - if (dmi_resp_valid) begin - state_d = Idle; - end + WaitWriteValid: begin + // got a valid answer go back to idle + if (dmi_resp_valid) begin + state_d = Idle; end - endcase - - // update means we got another request but we didn't finish - // the one in progress, this state is sticky - if (update && state_q != Idle) begin - error_dmi_busy = 1'b1; end - // if capture 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 && state_q inside {Read, WaitReadValid}) begin - error_dmi_busy = 1'b1; + default: begin + // just wait for idle here + if (dmi_resp_valid) begin + state_d = Idle; + end end + endcase - if (error_dmi_busy && error_q == DMINoError) begin - error_d = DMIBusy; - end + // update means we got another request but we didn't finish + // the one in progress, this state is sticky + if (update && state_q != Idle) begin + error_dmi_busy = 1'b1; + end - if (error_dmi_op_failed && error_q == DMINoError) begin - error_d = DMIOPFailed; - end + // if capture 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 && state_q inside {Read, WaitReadValid}) begin + error_dmi_busy = 1'b1; + end - // clear sticky error flag - if (update && dtmcs_q.dmireset && dtmcs_select) begin - error_d = DMINoError; - end + if (error_dmi_busy) begin + error_d = DMIBusy; + end + // clear sticky error flag + if (update && dtmcs_q.dmireset && dtmcs_select) begin + error_d = DMINoError; end end @@ -261,30 +223,27 @@ module dmi_jtag #( always_comb begin : p_shift dr_d = dr_q; - if (dmi_clear) begin - dr_d = '0; - end else begin - if (capture) begin - if (dmi_select) 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 + + if (capture) begin + if (dmi_select) 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 - if (shift) begin - if (dmi_select) begin - dr_d = {tdi, dr_q[$bits(dr_q)-1:1]}; - end + if (shift) begin + if (dmi_select) begin + dr_d = {tdi, dr_q[$bits(dr_q)-1:1]}; end end end - always_ff @(posedge tck or negedge trst_ni) begin - if (!trst_ni) begin + always_ff @(posedge tck or negedge trst_n) begin + if (!trst_n) begin dr_q <= '0; state_q <= Idle; address_q <= '0; @@ -314,7 +273,7 @@ module dmi_jtag #( .tdo_oe_o, .testmode_i, .tck_o ( tck ), - .dmi_clear_o ( jtag_dmi_clear ), + .trst_no ( trst_n ), .update_o ( update ), .capture_o ( capture ), .shift_o ( shift ), @@ -329,29 +288,24 @@ module dmi_jtag #( // CDC // --------- dmi_cdc i_dmi_cdc ( - // Test controls - .testmode_i, - .test_rst_ni, // JTAG side (master side) - .tck_i ( tck ), - .trst_ni ( trst_ni ), - .jtag_dmi_cdc_clear_i ( dmi_clear ), - .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 ), + .tck_i ( tck ), + .trst_ni ( trst_n ), + .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_rst_no ( dmi_rst_no ), - .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 ) + .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 : dmi_jtag diff --git a/hw/vendor/cheriot_debug_module/src/dmi_jtag_tap.sv b/hw/vendor/cheriot_debug_module/src/dmi_jtag_tap.sv index b198c2f6..c665cbc7 100644 --- a/hw/vendor/cheriot_debug_module/src/dmi_jtag_tap.sv +++ b/hw/vendor/cheriot_debug_module/src/dmi_jtag_tap.sv @@ -34,8 +34,7 @@ module dmi_jtag_tap #( input logic testmode_i, // JTAG is interested in writing the DTM CSR register output logic tck_o, - // Synchronous reset of the dmi module triggered by JTAG TAP - output logic dmi_clear_o, + output logic trst_no, output logic update_o, output logic capture_o, output logic shift_o, @@ -313,11 +312,10 @@ module dmi_jtag_tap #( // Pass through JTAG signals to debug custom DR logic. // In case of a single TAP those are just feed-through. assign tck_o = tck_i; + assign trst_no = !test_logic_reset; assign tdi_o = td_i; assign update_o = update_dr; assign shift_o = shift_dr; assign capture_o = capture_dr; - assign dmi_clear_o = test_logic_reset; - endmodule : dmi_jtag_tap diff --git a/hw/vendor/cheriot_debug_module/src_files.yml b/hw/vendor/cheriot_debug_module/src_files.yml deleted file mode 100644 index 12d02046..00000000 --- a/hw/vendor/cheriot_debug_module/src_files.yml +++ /dev/null @@ -1,14 +0,0 @@ -riscv-dbg: - files: [ - src/dm_pkg.sv, - debug_rom/debug_rom.sv, - debug_rom/debug_rom_one_scratch.sv, - src/dm_csrs.sv, - src/dm_mem.sv, - src/dm_top.sv, - src/dm_obi_top.sv, - src/dmi_cdc.sv, - src/dmi_jtag.sv, - src/dmi_jtag_tap.sv, - src/dm_sba.sv, - ] diff --git a/hw/vendor/cheriot_debug_module/tb/.clang-format b/hw/vendor/cheriot_debug_module/tb/.clang-format deleted file mode 100644 index ab4772e0..00000000 --- a/hw/vendor/cheriot_debug_module/tb/.clang-format +++ /dev/null @@ -1,35 +0,0 @@ ---- -BasedOnStyle: LLVM -IndentWidth: 4 -UseTab: Never -BreakBeforeBraces: Linux -AlwaysBreakBeforeMultilineStrings: true -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -AllowShortFunctionsOnASingleLine: false -IndentCaseLabels: false -AlignEscapedNewlinesLeft: false -AlignTrailingComments: true -AlignOperands: true -AllowAllParametersOfDeclarationOnNextLine: false -AlignAfterOpenBracket: true -SpaceAfterCStyleCast: false -MaxEmptyLinesToKeep: 2 -BreakBeforeBinaryOperators: NonAssignment -BreakStringLiterals: false -SortIncludes: false -ContinuationIndentWidth: 4 -ColumnLimit: 80 -IndentPPDirectives: AfterHash -BinPackArguments: true -BinPackParameters: true -ForEachMacros: - - 'TAILQ_FOREACH' - - 'TAILQ_FOREACH_REVERSE' -BreakBeforeBinaryOperators: None -MaxEmptyLinesToKeep: 1 -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: false -AlignConsecutiveAssignments: true -... diff --git a/hw/vendor/cheriot_debug_module/tb/Makefile b/hw/vendor/cheriot_debug_module/tb/Makefile index cd5bdfc7..b6a3b293 100644 --- a/hw/vendor/cheriot_debug_module/tb/Makefile +++ b/hw/vendor/cheriot_debug_module/tb/Makefile @@ -16,46 +16,43 @@ # Author: Robert Balas (balasr@iis.ee.ethz.ch) # Description: All in one. Uses parts of picorv32's makefile. -# minimum tool versions supported -MIN_VSIM_VERSION = "questa-2020.1" -MIN_VCS_VERSION = "vcs-2020.12" - MAKE = make CTAGS = ctags # vsim configuration +VVERSION = "10.7b" -VLIB = vlib +VLIB = vlib-$(VVERSION) VWORK = work -VLOG = vlog +VLOG = vlog-$(VVERSION) VLOG_FLAGS = -pedanticerrors -suppress 2577 -suppress 2583 -VLOG_LOG = vloggy +VLOG_LOG = vloggy -VOPT = vopt +VOPT = vopt-$(VVERSION) VOPT_FLAGS = -debugdb -fsmdebug -pedanticerrors #=mnprft -VSIM = vsim -VSIM_HOME = -VSIM_FLAGS = # user defined +VSIM = vsim-$(VVERSION) +VSIM_HOME = /usr/pack/modelsim-$(VVERSION)-kgf/questasim +VSIM_FLAGS = # user defined ALL_VSIM_FLAGS = $(VSIM_FLAGS) -sv_lib remote_bitbang/librbs_vsim VSIM_DEBUG_FLAGS = -debugdb -VSIM_GUI_FLAGS = -gui -debugdb -VSIM_SCRIPT_BATCH = vsim_batch.tcl -VSIM_SCRIPT_GUI = vsim_gui.tcl +VSIM_GUI_FLAGS = -gui -debugdb +VSIM_SCRIPT_BATCH = vsim_batch.tcl +VSIM_SCRIPT_GUI = vsim_gui.tcl -VCS = vcs -VCS_HOME = -VCS_FLAGS = -SIMV_FLAGS = +VCS = vcs-2017.03-kgf vcs +VCS_HOME = /usr/pack/vcs-2017.03-kgf +VCS_FLAGS = +SIMV_FLAGS = # verilator configuration VERILATOR = verilator -VERI_FLAGS = -VERI_COMPILE_FLAGS = -VERI_TRACE = -VERI_DIR = cobj_dir -VERI_CFLAGS = -O2 +VERI_FLAGS = +VERI_COMPILE_FLAGS = +VERI_TRACE = +VERI_DIR = cobj_dir +VERI_CFLAGS = -O2 # RTL source files RTLSRC_TB_PKG := @@ -70,13 +67,13 @@ RTLSRC_TB := boot_rom.sv \ tb_test_env.sv \ tb_top.sv -RTLSRC_VERI_TB := boot_rom.sv \ +RTLSRC_VERI_TB := boot_rom.sv \ dp_ram.sv \ mm_ram.sv \ SimJTAG.sv \ tb_top_verilator.sv -RTLSRC_INCDIR := riscv/rtl/include common_cells/include +RTLSRC_INCDIR := riscv/rtl/include RTLSRC_FPNEW_PKG := fpnew/src/fpnew_pkg.sv RTLSRC_RISCV_PKG += $(addprefix riscv/rtl/include/,\ @@ -84,10 +81,7 @@ RTLSRC_RISCV_PKG += $(addprefix riscv/rtl/include/,\ ../../bhv/include/cv32e40p_tracer_pkg.sv) RTLSRC_DM_PKG += ../src/dm_pkg.sv -RTLSRC_COMMON_PKG := common_cells/src/cdc_reset_ctrlr_pkg.sv - -RTLSRC_PKG = $(RTLSRC_FPNEW_PKG) dm_tb_pkg.sv $(RTLSRC_RISCV_PKG) \ - $(RTLSRC_DM_PKG) $(RTLSRC_COMMON_PKG) +RTLSRC_PKG = $(RTLSRC_FPNEW_PKG) dm_tb_pkg.sv $(RTLSRC_RISCV_PKG) $(RTLSRC_DM_PKG) RTLSRC_RISCV := $(addprefix riscv/rtl/,\ ../bhv/cv32e40p_sim_clock_gate.sv \ ../bhv/cv32e40p_tracer.sv \ @@ -115,15 +109,13 @@ RTLSRC_RISCV := $(addprefix riscv/rtl/,\ cv32e40p_prefetch_controller.sv \ cv32e40p_sleep_unit.sv \ cv32e40p_core.sv) -RTLSRC_COMMON := $(addprefix common_cells/src/,\ - spill_register_flushable.sv spill_register.sv \ - cdc_2phase.sv cdc_2phase_clearable.sv \ - cdc_reset_ctrlr.sv cdc_4phase.sv \ - deprecated/fifo_v2.sv fifo_v3.sv \ - rstgen.sv rstgen_bypass.sv sync.sv) +RTLSRC_COMMON := $(addprefix common_cells/src/,\ + cdc_2phase.sv fifo_v2.sv fifo_v3.sv\ + rstgen.sv rstgen_bypass.sv) RTLSRC_TECH := $(addprefix tech_cells_generic/src/,\ - rtl/tc_clk.sv) -RTLSRC_DEBUG := ../debug_rom/debug_rom.sv + cluster_clock_inverter.sv pulp_clock_mux2.sv\ + cluster_clock_gating.sv) +RTLSRC_DEBUG := ../debug_rom/debug_rom.sv RTLSRC_DEBUG += $(addprefix ../src/,\ dm_csrs.sv dmi_cdc.sv dmi_jtag.sv \ dmi_jtag_tap.sv dm_mem.sv \ @@ -132,12 +124,12 @@ RTLSRC_DEBUG += $(addprefix ../src/,\ RTLSRC += $(RTLSRC_RISCV) $(RTLSRC_COMMON) $(RTLSRC_TECH) $(RTLSRC_DEBUG) # versions for this tb -CV32E40P_SHA = f9d63290eea738cb0a6fbf1e77bbd18555015a03 -FPU_SHA = v0.6.1 -COMMON_SHA = v1.24.0 -TECH_SHA = v0.2.3 +CV32E40P_SHA = f9d63290eea738cb0a6fbf1e77bbd18555015a03 +FPU_SHA = v0.6.1 +COMMON_SHA = 337f54a7cdfdad78b124cbdd2a627db3e0939141 +TECH_SHA = b35652608124b7ea813818b14a00ca76edd7599d -RAM_START_ADDR = 0x1c000000 +RAM_START_ADDR = 0x1c000000 # TODO: clean this up RTLSRC_VLOG_TB_TOP := $(basename $(notdir $(RTLSRC_TB_TOP))) @@ -165,7 +157,7 @@ vlib: .lib-rtl # rebuild if we change some sourcefile .build-rtl: .lib-rtl $(RTLSRC_PKG) $(RTLSRC) $(RTLSRC_TB_PKG) $(RTLSRC_TB) - $(VLOG) -work $(VWORK) $(addprefix +incdir+,$(RTLSRC_INCDIR)) $(VLOG_FLAGS) \ + $(VLOG) -work $(VWORK) +incdir+$(RTLSRC_INCDIR) $(VLOG_FLAGS) \ $(RTLSRC_PKG) $(RTLSRC) $(RTLSRC_TB_PKG) $(RTLSRC_TB) touch .build-rtl @@ -180,10 +172,10 @@ vsim-all: .opt-rtl vcsify: $(RTLSRC_PKG) $(RTLSRC) $(RTLSRC_TB_PKG) $(RTLSRC_TB) remote_bitbang/librbs_vcs.so $(VCS) +vc -sverilog -race=all -ignore unique_checks -full64 \ - -timescale=1ns/1ps -assert svaext \ - -CC "$(if $(VCS_HOME),-I$(VCS_HOME)/include,) -O3 -march=native" $(VCS_FLAGS) \ + -timescale=1ns/1ps \ + -CC "-I$(VCS_HOME)/include -O3 -march=native" $(VCS_FLAGS) \ $(RTLSRC_PKG) $(RTLSRC) $(RTLSRC_TB_PKG) $(RTLSRC_TB) \ - $(addprefix +incdir+,$(RTLSRC_INCDIR)) + +incdir+$(RTLSRC_INCDIR) vcs-clean: rm -rf simv* *.daidir *.vpd *.db csrc ucli.key vc_hdrs.h @@ -207,8 +199,8 @@ verilate: testbench_verilator testbench_verilator: $(RTLSRC_VERI_TB) $(RTLSRC_PKG) $(RTLSRC) \ remote_bitbang/librbs_veri.so $(VERILATOR) --cc --sv --exe $(VERI_TRACE) \ - --Wno-lint --Wno-UNOPTFLAT --Wno-BLKANDNBLK --Wno-COMBDLY \ - --Wno-MODDUP $(addprefix +incdir+,$(RTLSRC_INCDIR)) --top-module \ + --Wno-lint --Wno-UNOPTFLAT --Wno-BLKANDNBLK \ + --Wno-MODDUP +incdir+$(RTLSRC_INCDIR) --top-module \ tb_top_verilator --Mdir $(VERI_DIR) \ -CFLAGS "-std=gnu++11 $(VERI_CFLAGS)" $(VERI_COMPILE_FLAGS) \ $(RTLSRC_PKG) $(RTLSRC_VERI_TB) $(RTLSRC) \ @@ -241,19 +233,19 @@ $(RTLSRC_RISCV_PKG) $(RTLSRC_RISCV): cd riscv/ && git checkout $(CV32E40P_SHA) # openocd server -remote_bitbang/librbs_veri.so: INCLUDE_DIRS =./ +remote_bitbang/librbs_veri.so: INCLUDE_DIRS =./ $(VSIM_HOME)/include remote_bitbang/librbs_veri.so: $(MAKE) -C remote_bitbang all mv remote_bitbang/librbs.so $@ +remote_bitbang/librbs_vsim.so: INCLUDE_DIRS =./ $(VSIM_HOME)/include remote_bitbang/librbs_vsim.so: -remote_bitbang/librbs_vsim.so: - $(MAKE) -C remote_bitbang all INCLUDE_DIRS="./ $(if $(VSIM_HOME),$(VSIM_HOME)/include,)" + $(MAKE) -C remote_bitbang all mv remote_bitbang/librbs.so $@ +remote_bitbang/librbs_vcs.so: INCLUDE_DIRS =./ $(VCS_HOME)/include remote_bitbang/librbs_vcs.so: -remote_bitbang/librbs_vcs.so: - $(MAKE) -C remote_bitbang all INCLUDE_DIRS="./ $(if $(VCS_HOME),$(VCS_HOME)/include,)" + $(MAKE) -C remote_bitbang all mv remote_bitbang/librbs.so $@ rbs-clean: @@ -305,13 +297,6 @@ veri-run: verilate prog/test.hex ./testbench_verilator $(VERI_FLAGS) \ "+firmware=prog/test.hex" -# run openocd testbench -# Use OPENOCD to point to openocd binary -# Use OPENOCD_SCRIPT to point to test script -.PHONY: test-openocd -test-openocd: - ./veri-run-openocd.py - .PHONY: vsim-run vsim-run: vsim-all prog/test.hex vsim-run: ALL_VSIM_FLAGS += "+firmware=prog/test.hex" diff --git a/hw/vendor/cheriot_debug_module/tb/jtag_dmi/jtag_test.sv b/hw/vendor/cheriot_debug_module/tb/jtag_dmi/jtag_test.sv index d043358a..7872d5c6 100644 --- a/hw/vendor/cheriot_debug_module/tb/jtag_dmi/jtag_test.sv +++ b/hw/vendor/cheriot_debug_module/tb/jtag_dmi/jtag_test.sv @@ -33,7 +33,6 @@ package jtag_test; jtag.trst_n <= #TA 0; repeat (2) clock(); jtag.trst_n <= #TA 1; - this.ir_select = 'h1; clock(); endtask @@ -43,9 +42,6 @@ package jtag_test; repeat (6) clock(); jtag.tms <= #TA 0; clock(); - // After softreset the IR should be reset to IDCODE so we have to mirror - // this in our internal state. - this.ir_select = 'h1; endtask // Set IR, but only if it needs to be set. @@ -87,16 +83,15 @@ package jtag_test; jtag.tms <= #TA 0; endtask - // Assumes JTAG FSM is already in shift DR state task readwrite_bits(output logic rdata [$], input logic wdata [$], input logic tms_last); for (int i = 0; i < wdata.size(); i++) begin jtag.tdi <= #TA wdata[i]; - if (i == (wdata.size() - 1)) jtag.tms <= #TA tms_last; // tms_last ? exit1 DR : shift DR + if (i == (wdata.size() - 1)) jtag.tms <= #TA tms_last; cycle_start(); rdata[i] = jtag.tdo; cycle_end(); end - jtag.tms <= #TA 0; // tms_last ? pause DR : shift DR + jtag.tms <= #TA 0; endtask task wait_idle(int cycles); @@ -182,11 +177,6 @@ package jtag_test; data = dm::dtmcs_t'({<<{read_data}}); endtask - task reset_dmi(); - logic [31:0] dmireset = 1 << 16; - write_dtmcs(dmireset); - endtask - task write_dmi(input dm::dm_csr_e address, input logic [31:0] data); logic write_data [DMIWidth]; logic [DMIWidth-1:0] write_data_packed = {address, data, dm::DTM_WRITE}; @@ -197,111 +187,29 @@ package jtag_test; jtag.update_dr(1'b0); endtask - task read_dmi(input dm::dm_csr_e address, output logic [31:0] data, input int wait_cycles = 10, - output dm::dtm_op_status_e op); + task read_dmi(input dm::dm_csr_e address, output logic [31:0] data, input int wait_cycles = 10); logic read_data [DMIWidth], write_data [DMIWidth]; logic [DMIWidth-1:0] data_out = 0; automatic logic [DMIWidth-1:0] write_data_packed = {address, 32'b0, dm::DTM_READ}; {<<{write_data}} = write_data_packed; jtag.set_ir(DMIACCESS); - // send read command jtag.shift_dr(); + // send read command jtag.write_bits(write_data, 1'b1); jtag.update_dr(1'b0); jtag.wait_idle(wait_cycles); - // shift out read data jtag.shift_dr(); + // shift out read data write_data_packed = {address, 32'b0, dm::DTM_NOP}; {<<{write_data}} = write_data_packed; jtag.readwrite_bits(read_data, write_data, 1'b1); - jtag.update_dr(1'b0); + // I am pretty sure this should be `update_dr` here. + // jtag.update_dr(1'b0); + jtag.shift_dr(); data_out = {<<{read_data}}; - op = dm::dtm_op_status_e'(data_out[1:0]); data = data_out[33:2]; endtask - // Repeatedly read DMI until we get a valid response. - // The delay between Update-DR and Capture-DR of - // successive operations is automatically adjusted through - // an exponential backoff scheme. - // Note: read operations which have side-effects (e.g. - // reading SBData0) should not use this function - task read_dmi_exp_backoff(input dm::dm_csr_e address, output logic [31:0] data); - logic read_data [DMIWidth], write_data [DMIWidth]; - logic [DMIWidth-1:0] write_data_packed; - logic [DMIWidth-1:0] data_out = 0; - dm::dtm_op_status_e op = dm::DTM_SUCCESS; - int trial_idx = 0; - int wait_cycles = 8; - - do begin - if (trial_idx != 0) begin - // Not entered upon first iteration, resets the - // sticky error state if previous read was unsuccessful - reset_dmi(); - end - read_dmi(address, data, wait_cycles, op); - wait_cycles *= 2; - trial_idx++; - end while (op == dm::DTM_BUSY); - endtask - - task sba_read_double(input logic [31:0] address, output logic [63:0] data); - // Attempt the access sequence. Two timing violations may - // occur: - // 1) an operation is attempted while a DMI request is still - // in progress; - // 2) a SB read is attempted while a read is still in progress - // or a SB access is attempted while one is in progress - // In either case the whole sequence must be re-attempted with - // increased delays. - // Case 1) is intercepted when the op returned by a read is == DTM_BUSY, - // the sequence can be interrupted early and the delay to be adjusted is - // that between the update phase and the capture phase of a successive op. - // Case 2) is intercepted at the end of the sequence by reading the - // SBCS register, and checking sbbusyerror. In this case the delay to be - // adjusted is that before the SBData read operations. - dm::dtm_op_status_e op; - automatic int dmi_wait_cycles = 2; - automatic int sba_wait_cycles = 2; - automatic dm::sbcs_t sbcs = '{sbreadonaddr: 1, sbaccess: 3, default: '0}; - dm::sbcs_t read_sbcs; - // Check address is 64b aligned - assert (address[2:0] == '0) else $error("[JTAG] 64b-unaligned accesses not supported"); - // Start SBA sequence attempts - while (1) begin - automatic bit failed = 0; - write_dmi(dm::SBCS, sbcs); - write_dmi(dm::SBAddress0, address); - wait_idle(sba_wait_cycles); - read_dmi(dm::SBData1, data[63:32], dmi_wait_cycles, op); - // Skip second read if we already have a DTM busy error - // else we can override op - if (op != dm::DTM_BUSY) begin - read_dmi(dm::SBData0, data[31:0], dmi_wait_cycles, op); - end - // If we had a DTM_BUSY error, increase dmi_wait_cycles and clear error - if (op == dm::DTM_BUSY) begin - dmi_wait_cycles *= 2; - failed = 1'b1; - reset_dmi(); - end - // Test sbbusyerror and wait for sbbusy == 0 - // Error is cleared in next iteration when writing SBCS - do begin - sbcs.sbbusyerror = 1'b0; - read_dmi_exp_backoff(dm::SBCS, read_sbcs); - if (read_sbcs.sbbusyerror) begin - sbcs.sbbusyerror = 1'b1; // set 1 to clear - sba_wait_cycles *= 2; - failed = 1'b1; - end - if (read_sbcs.sbbusy) wait_idle(sba_wait_cycles); - end while (read_sbcs.sbbusy); - // Exit loop if sequence was successful - if (!failed) break; - end - endtask endclass endpackage diff --git a/hw/vendor/cheriot_debug_module/tb/jtag_dmi/tb_jtag_dmi.sv b/hw/vendor/cheriot_debug_module/tb/jtag_dmi/tb_jtag_dmi.sv index 1d64a01e..1e0cdd82 100644 --- a/hw/vendor/cheriot_debug_module/tb/jtag_dmi/tb_jtag_dmi.sv +++ b/hw/vendor/cheriot_debug_module/tb/jtag_dmi/tb_jtag_dmi.sv @@ -242,30 +242,6 @@ module tb_jtag_dmi; riscv_dbg.read_dmi(dm::dm_csr_e'(transaction.addr), rdata); rsp_mbx.put(rdata); end - // Randomly reset the dmi using either hard jtag trst_ni, JTAG - // TestLogicReset or the dtmcs.dmihardreset bit. - if ($urandom_range(0,100) < 5) begin - riscv_dbg.wait_idle(30); - case ($urandom_range(0,3)) - 0: begin - $info("Resetting JTAG DMI using asynchronous JTAG reset signal..."); - riscv_dbg.reset_master(); - end - - 1: begin - $info("Resetting JTAG DMI using JTAG softreset (TestLogicReset TAP state)."); - riscv_dbg.jtag.soft_reset(); - end - - 2: begin - dm::dtmcs_t dtmcs_value; - dtmcs_value = '0; - dtmcs_value.dmihardreset = 1; - $info("Resetting JTAG DMI using DMI dtmcs registers' dmihardreset control bit."); - riscv_dbg.write_dtmcs(dtmcs_value); - end - endcase - end end #1000; $finish(); @@ -285,10 +261,8 @@ module tb_jtag_dmi; req_mbx.get(req); rsp_mbx.get(rsp); nr_transactions++; - assert(req.addr == req_mon.addr) else - $error("Invalid dmi request. Got address %0x instead of %0x.", req_mon.addr, req.addr); - assert(req.op == req_mon.op) else - $error("Invalid dmi request. Got op %0x instead of %0x.", req_mon.op, req.op);; + assert(req.addr == req_mon.addr); + assert(req.op == req_mon.op); if (req.op == dm::DTM_READ) begin assert(rsp_mon.data == rsp); end else begin diff --git a/hw/vendor/cheriot_debug_module/tb/remote_bitbang/remote_bitbang.c b/hw/vendor/cheriot_debug_module/tb/remote_bitbang/remote_bitbang.c index 196d0f8a..e77c00dd 100644 --- a/hw/vendor/cheriot_debug_module/tb/remote_bitbang/remote_bitbang.c +++ b/hw/vendor/cheriot_debug_module/tb/remote_bitbang/remote_bitbang.c @@ -13,24 +13,6 @@ #include "remote_bitbang.h" -//Public globals, declared in remote_bitbang.h - -int rbs_err; - -unsigned char tck; -unsigned char tms; -unsigned char tdi; -unsigned char trstn; -unsigned char tdo; -unsigned char quit; - -int socket_fd; -int client_fd; - -//static const ssize_t buf_size = 64 * 1024; -char recv_buf[64 * 1024]; -ssize_t recv_start, recv_end; - int rbs_init(uint16_t port) { socket_fd = 0; @@ -133,12 +115,7 @@ void rbs_tick(unsigned char *jtag_tck, unsigned char *jtag_tms, void rbs_reset() { - trstn = 0; -} - -void rbs_set() -{ - trstn = 1; + // trstn = 0; } void rbs_set_pins(char _tck, char _tms, char _tdi) @@ -193,23 +170,24 @@ void rbs_execute_command() case 'r': if (VERBOSE) fprintf(stderr, "r-reset\n"); - rbs_set(); //r-reset command deasserts TRST. See: openocd/blob/master/doc/manual/jtag/drivers/remote_bitbang.txt - break; + rbs_reset(); + break; // This is wrong. 'r' has other bits that indicated TRST and + // SRST. case 's': if (VERBOSE) fprintf(stderr, "s-reset\n"); - rbs_set(); //s-reset command deasserts TRST. See: openocd/blob/master/doc/manual/jtag/drivers/remote_bitbang.txt - break; + rbs_reset(); + break; // This is wrong. case 't': if (VERBOSE) fprintf(stderr, "t-reset\n"); - rbs_reset(); //t-reset command asserts TRST. See: openocd/blob/master/doc/manual/jtag/drivers/remote_bitbang.txt - break; + rbs_reset(); + break; // This is wrong. case 'u': if (VERBOSE) fprintf(stderr, "u-reset\n"); - rbs_reset(); //u-reset command asserts TRST. See: openocd/blob/master/doc/manual/jtag/drivers/remote_bitbang.txt - break; + rbs_reset(); + break; // This is wrong. case '0': if (VERBOSE) fprintf(stderr, "Write 0 0 0\n"); diff --git a/hw/vendor/cheriot_debug_module/tb/remote_bitbang/remote_bitbang.h b/hw/vendor/cheriot_debug_module/tb/remote_bitbang/remote_bitbang.h index f1e261bd..460819e2 100644 --- a/hw/vendor/cheriot_debug_module/tb/remote_bitbang/remote_bitbang.h +++ b/hw/vendor/cheriot_debug_module/tb/remote_bitbang/remote_bitbang.h @@ -8,21 +8,21 @@ #define VERBOSE 0 -extern int rbs_err; +int rbs_err; -extern unsigned char tck; -extern unsigned char tms; -extern unsigned char tdi; -extern unsigned char trstn; -extern unsigned char tdo; -extern unsigned char quit; +unsigned char tck; +unsigned char tms; +unsigned char tdi; +unsigned char trstn; +unsigned char tdo; +unsigned char quit; -extern int socket_fd; -extern int client_fd; +int socket_fd; +int client_fd; -//static const ssize_t buf_size = 64 * 1024; -extern char recv_buf[64 * 1024]; -extern ssize_t recv_start, recv_end; +static const ssize_t buf_size = 64 * 1024; +char recv_buf[64 * 1024]; +ssize_t recv_start, recv_end; // Create a new server, listening for connections from localhost on the given // port. @@ -44,8 +44,8 @@ void rbs_accept(); // simulation to run. void rbs_execute_command(); -void rbs_reset(); //Assert TRST -void rbs_set(); //Deassert TRST +// Reset. Currently does nothing. +void rbs_reset(); void rbs_set_pins(char _tck, char _tms, char _tdi); diff --git a/hw/vendor/cheriot_debug_module/tb/tb_test_env.sv b/hw/vendor/cheriot_debug_module/tb/tb_test_env.sv index 9ac8f28a..5d443014 100644 --- a/hw/vendor/cheriot_debug_module/tb/tb_test_env.sv +++ b/hw/vendor/cheriot_debug_module/tb/tb_test_env.sv @@ -245,7 +245,6 @@ module tb_test_env #( .clk_i ( clk_i ), .rst_ni ( rst_ni ), - .next_dm_addr_i ( '0 ), .testmode_i ( 1'b0 ), .ndmreset_o ( ndmreset ), .dmactive_o ( ), // active debug session TODO @@ -259,7 +258,6 @@ module tb_test_env #( .slave_be_i ( dm_be ), .slave_wdata_i ( dm_wdata ), .slave_rdata_o ( dm_rdata ), - .slave_err_o ( ), .master_req_o ( sb_req ), .master_add_o ( sb_addr ), @@ -268,8 +266,6 @@ module tb_test_env #( .master_be_o ( sb_be ), .master_gnt_i ( sb_gnt ), .master_r_valid_i ( sb_rvalid ), - .master_r_err_i ( 1'b0 ), - .master_r_other_err_i ( 1'b0 ), .master_r_rdata_i ( sb_rdata ), .dmi_rst_ni ( rst_ni ), diff --git a/hw/vendor/cheriot_debug_module/tb/veri-run-openocd.py b/hw/vendor/cheriot_debug_module/tb/veri-run-openocd.py deleted file mode 100755 index a5d7a455..00000000 --- a/hw/vendor/cheriot_debug_module/tb/veri-run-openocd.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/python3 -"""Launch riscv-dbg testbench and connect to openocd""" - -import sys -from subprocess import Popen -from subprocess import PIPE, STDOUT -from os import getenv -import shlex - -if __name__ == '__main__': - veri_proc = Popen(shlex.split('make veri-run'), - stdin=PIPE, stdout=PIPE, stderr=STDOUT, - universal_newlines=True) - for line in veri_proc.stdout: - print(line, end='') - if 'Listening on port' in line: - print('Starting OpenOCD') - break - elif 'failed to bind socket' in line: - print("Try 'killall testbench_verilator'", file=sys.stderr) - exit(1) - - # try a few paths where openocd could be - openocd = getenv('OPENOCD') - if not openocd: - openocd = getenv('RISCV') - if openocd: - openocd += '/bin/openocd' - if not openocd: - openocd = 'openocd' - - openocd_script = getenv('OPENOCD_SCRIPT') - if not openocd_script: - openocd_script = 'dm_compliance_test.cfg' - - print("Using '" + openocd) - openocd_proc = Popen(shlex.split(openocd + ' -f ' + openocd_script), - stdin=PIPE, stdout=PIPE, stderr=STDOUT, - universal_newlines=True) - print('Launched OpenOCD') - - ret = 1 - for line in openocd_proc.stdout: - print(line, end='') - if 'ALL TESTS PASSED' in line: - ret = 0 - - # Our spawned processes should have terminated by now. If not, we have to go after - # them with the hammer (openocd likes to ignore sigterms when it gets stuck) - if not openocd_proc.poll(): - openocd_proc.kill() - - if not veri_proc.poll(): - veri_proc.kill() - - exit(ret) diff --git a/hw/vendor/lowrisc_ip/ip/rv_dm/rtl/rv_dm.sv b/hw/vendor/lowrisc_ip/ip/rv_dm/rtl/rv_dm.sv index 3f0c6c24..828050b1 100644 --- a/hw/vendor/lowrisc_ip/ip/rv_dm/rtl/rv_dm.sv +++ b/hw/vendor/lowrisc_ip/ip/rv_dm/rtl/rv_dm.sv @@ -473,13 +473,11 @@ module rv_dm // JTAG TAP dmi_jtag #( - .IdcodeValue (IdcodeValue), - .NumDmiWordAbits(7) + .IdcodeValue (IdcodeValue) ) dap ( .clk_i (clk_i), .rst_ni (rst_ni), .testmode_i (testmode), - .test_rst_ni (scan_rst_ni), .dmi_rst_no (dmi_rst_n), .dmi_req_o (dmi_req), diff --git a/hw/vendor/patches/cheriot_debug_module/0001-Fix-SCISemi-debug-module-s-core-file.patch b/hw/vendor/patches/cheriot_debug_module/0001-Fix-scisemi_ip_riscv_dbg.core-file-for-xcelium-and-v.patch similarity index 70% rename from hw/vendor/patches/cheriot_debug_module/0001-Fix-SCISemi-debug-module-s-core-file.patch rename to hw/vendor/patches/cheriot_debug_module/0001-Fix-scisemi_ip_riscv_dbg.core-file-for-xcelium-and-v.patch index abc3d0ea..f122ee4d 100644 --- a/hw/vendor/patches/cheriot_debug_module/0001-Fix-SCISemi-debug-module-s-core-file.patch +++ b/hw/vendor/patches/cheriot_debug_module/0001-Fix-scisemi_ip_riscv_dbg.core-file-for-xcelium-and-v.patch @@ -1,17 +1,17 @@ -From bc2412e135706c14814b20d8f898812119d8d0aa Mon Sep 17 00:00:00 2001 +From 496c8eed91878b92455cba587484720e13919b98 Mon Sep 17 00:00:00 2001 From: Samuel Riedel -Date: Fri, 21 Mar 2025 10:38:05 +0000 -Subject: [PATCH 1/2] Fix SCISemi debug module's core file +Date: Tue, 1 Apr 2025 08:29:37 +0000 +Subject: [PATCH 1/2] Fix `scisemi_ip_riscv_dbg.core` file for xcelium and vcs --- - scisemi_ip_riscv_dbg.core | 18 +++--------------- - 1 file changed, 3 insertions(+), 15 deletions(-) + scisemi_ip_riscv_dbg.core | 17 ++--------------- + 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/scisemi_ip_riscv_dbg.core b/scisemi_ip_riscv_dbg.core -index 138e911..a773af2 100644 +index 138e911..becc53b 100644 --- a/scisemi_ip_riscv_dbg.core +++ b/scisemi_ip_riscv_dbg.core -@@ -19,24 +19,12 @@ filesets: +@@ -19,24 +19,11 @@ filesets: - src/dm_mem.sv - src/dmi_cdc.sv - src/dmi_jtag.sv @@ -30,7 +30,6 @@ index 138e911..a773af2 100644 - - src/dmi_jtag_tap.sv + - "!tool_vivado ? (src/dmi_jtag_tap.sv)" + - "tool_vivado ? (src/dmi_bscane_tap.sv)" -+ - src/dm_top.sv file_type: systemVerilogSource targets: diff --git a/hw/vendor/patches/cheriot_debug_module/0002-Add-dm_top-file-back-to-debug-module.patch b/hw/vendor/patches/cheriot_debug_module/0002-Add-dm_top-file-back-to-debug-module.patch new file mode 100644 index 00000000..46962403 --- /dev/null +++ b/hw/vendor/patches/cheriot_debug_module/0002-Add-dm_top-file-back-to-debug-module.patch @@ -0,0 +1,268 @@ +From a6063bcf6aec9f568ee6c66f19f8ff8e34eb4bef Mon Sep 17 00:00:00 2001 +From: Samuel Riedel +Date: Tue, 1 Apr 2025 08:45:45 +0000 +Subject: [PATCH 2/2] Add `dm_top` file back to debug module + +--- + scisemi_ip_riscv_dbg.core | 1 + + src/dm_top.sv | 236 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 237 insertions(+) + create mode 100644 hw/vendor/cheriot_debug_module/src/dm_top.sv + +diff --git a/scisemi_ip_riscv_dbg.core b/scisemi_ip_riscv_dbg.core +index becc53b..a773af2 100644 +--- a/scisemi_ip_riscv_dbg.core ++++ b/scisemi_ip_riscv_dbg.core +@@ -21,6 +21,7 @@ filesets: + - src/dmi_jtag.sv + - "!tool_vivado ? (src/dmi_jtag_tap.sv)" + - "tool_vivado ? (src/dmi_bscane_tap.sv)" ++ - src/dm_top.sv + file_type: systemVerilogSource + + targets: +diff --git a/src/dm_top.sv b/src/dm_top.sv +new file mode 100644 +index 0000000..a92faee +--- /dev/null ++++ b/src/dm_top.sv +@@ -0,0 +1,236 @@ ++/* 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 ++* 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 unsigned NrHarts = 1, ++ parameter int unsigned BusWidth = 32, ++ parameter int unsigned DmBaseAddress = 'h1000, // default to non-zero page ++ // 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}}, ++ // toggle new behavior to drive master_be_o during a read ++ parameter bit ReadByteEnable = 1 ++) ( ++ input logic clk_i, // clock ++ // asynchronous reset active low, connect PoR here, not the system reset ++ input logic rst_ni, ++ // Subsequent debug modules can be chained by setting the nextdm register value to the offset of ++ // the next debug module. The RISC-V debug spec mandates that the first debug module located at ++ // 0x0, and that the last debug module in the chain sets the nextdm register to 0x0. The nextdm ++ // register is a word address and not a byte address. This value is passed in as a static signal ++ // so that it becomes possible to assign this value with chiplet tie-offs or straps, if needed. ++ input logic [31:0] next_dm_addr_i, ++ input logic testmode_i, ++ output logic ndmreset_o, // non-debug module reset ++ input logic ndmreset_ack_i, // non-debug module reset acknowledgement pulse ++ output logic dmactive_o, // debug module is active ++ output logic [NrHarts-1:0] debug_req_o, // async debug request ++ // communicate whether the hart is unavailable (e.g.: power down) ++ input logic [NrHarts-1:0] unavailable_i, ++ input 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 slave_err_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 master_r_err_i, ++ input logic master_r_other_err_i, // *other_err_i has priority over *err_i ++ input logic [BusWidth-1:0] master_r_rdata_i, ++ ++ // Connection to DTM - compatible to RocketChip Debug Module ++ input logic dmi_rst_ni, // Synchronous clear request from ++ // the DTM to clear the DMI response ++ // FIFO. ++ 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 ndmreset; ++ 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; ++ ++ assign ndmreset_o = ndmreset; ++ ++ dm_csrs #( ++ .NrHarts(NrHarts), ++ .BusWidth(BusWidth), ++ .SelectableHarts(SelectableHarts) ++ ) i_dm_csrs ( ++ .clk_i, ++ .rst_ni, ++ .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 ), ++ .dmactive_o, ++ .hartsel_o ( hartsel ), ++ .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), ++ .ReadByteEnable(ReadByteEnable) ++ ) i_dm_sba ( ++ .clk_i, ++ .rst_ni, ++ .dmactive_i ( dmactive_o ), ++ ++ .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 ), ++ .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), ++ .DmBaseAddress(DmBaseAddress) ++ ) i_dm_mem ( ++ .clk_i, ++ .rst_ni, ++ .debug_req_o, ++ .ndmreset_i ( ndmreset ), ++ .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 ) ++ ); ++ ++endmodule : dm_top +-- +2.34.1 + diff --git a/hw/vendor/patches/cheriot_debug_module/0002-Regenerate-the-debug-ROM.patch b/hw/vendor/patches/cheriot_debug_module/0002-Regenerate-the-debug-ROM.patch deleted file mode 100644 index 0a317330..00000000 --- a/hw/vendor/patches/cheriot_debug_module/0002-Regenerate-the-debug-ROM.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 6611bc11420597d5ba5dfe4bdcfa396d1f522153 Mon Sep 17 00:00:00 2001 -From: Samuel Riedel -Date: Thu, 20 Mar 2025 21:39:11 +0000 -Subject: [PATCH 2/2] Regenerate the debug ROM - ---- - debug_rom/Makefile | 4 ++-- - debug_rom/debug_rom.dump | 10 +++++----- - debug_rom/debug_rom.h | 10 +++++----- - debug_rom/debug_rom.sv | 8 ++++---- - debug_rom/gen_rom.py | 6 +++++- - 5 files changed, 21 insertions(+), 17 deletions(-) - -diff --git a/debug_rom/Makefile b/debug_rom/Makefile -index 3ea9da8..f8f6b8f 100644 ---- a/debug_rom/Makefile -+++ b/debug_rom/Makefile -@@ -1,7 +1,7 @@ - # See LICENSE.SiFive for license details - --// Conversion to CHERIoT Ibex ISA from RISC-V --// Copyright SCI Semiconductor 2025 -+# Conversion to CHERIoT Ibex ISA from RISC-V -+# Copyright SCI Semiconductor 2025 - - debug_rom = debug_rom.sv debug_rom.dump - -diff --git a/debug_rom/debug_rom.dump b/debug_rom/debug_rom.dump -index a227224..8a65d92 100644 ---- a/debug_rom/debug_rom.dump -+++ b/debug_rom/debug_rom.dump -@@ -38,20 +38,20 @@ Disassembly of section .text: - 854: 17 05 00 00 auipcc ca0, 0 - 858: 13 55 c5 00 srli a0, a0, 12 - 85c: 13 15 c5 00 slli a0, a0, 12 -- 860: 23 26 05 10 csw zero, 268(ca0) -+ 860: 23 2c 05 10 csw zero, 280(ca0) - 864: 5b 05 a0 03 cspecialr ca0, 26 - 868: 5b 04 90 03 cspecialr cs0, 25 -- 86c: 73 00 10 00 ebreak -+ 86c: 73 00 10 00 ebreak - - 00000870 : -- 870: 23 22 05 10 csw zero, 260(ca0) -+ 870: 23 24 05 10 csw zero, 264(ca0) - 874: 5b 05 a0 03 cspecialr ca0, 26 - 878: 5b 04 90 03 cspecialr cs0, 25 - 87c: 6f f0 5f a8 j 0x300 - - 00000880 <_resume>: - 880: 73 24 40 f1 csrr s0, mhartid -- 884: 23 24 85 10 csw s0, 264(ca0) -+ 884: 23 28 85 10 csw s0, 272(ca0) - 888: 5b 05 a0 03 cspecialr ca0, 26 - 88c: 5b 04 90 03 cspecialr cs0, 25 -- 890: 73 00 20 7b dret -+ 890: 73 00 20 7b dret -diff --git a/debug_rom/debug_rom.h b/debug_rom/debug_rom.h -index 5950d84..f94bafc 100644 ---- a/debug_rom/debug_rom.h -+++ b/debug_rom/debug_rom.h -@@ -1,6 +1,6 @@ - // Auto-generated code - --const int reset_vec_size = 40; -+const int reset_vec_size = 38; - - uint32_t reset_vec[reset_vec_size] = { - 0x00c0006f, -@@ -22,21 +22,21 @@ uint32_t reset_vec[reset_vec_size] = { - 0x00a40433, - 0x40044403, - 0x00247413, -- 0xfa0418e3, -+ 0xfa041ce3, - 0xfd5ff06f, - 0x00000517, - 0x00c55513, - 0x00c51513, -- 0x10052623, -+ 0x10052c23, - 0x03a0055b, - 0x0390045b, - 0x00100073, -- 0x10052223, -+ 0x10052423, - 0x03a0055b, - 0x0390045b, - 0xa85ff06f, - 0xf1402473, -- 0x10852423, -+ 0x10852823, - 0x03a0055b, - 0x0390045b, - 0x7b200073, -diff --git a/debug_rom/debug_rom.sv b/debug_rom/debug_rom.sv -index ab42f40..ed3c125 100644 ---- a/debug_rom/debug_rom.sv -+++ b/debug_rom/debug_rom.sv -@@ -1,4 +1,4 @@ --/* -+/* - * Conversion to CHERIoT Ibex ISA from RISC-V - * Copyright SCI Semiconductor 2025 - * -@@ -32,11 +32,11 @@ module debug_rom ( - assign mem = { - 64'h00000000_7b200073, - 64'h0390045b_03a0055b, -- 64'h10852423_f1402473, -+ 64'h10852823_f1402473, - 64'ha85ff06f_0390045b, -- 64'h03a0055b_10052223, -+ 64'h03a0055b_10052423, - 64'h00100073_0390045b, -- 64'h03a0055b_10052623, -+ 64'h03a0055b_10052c23, - 64'h00c51513_00c55513, - 64'h00000517_fd5ff06f, - 64'hfa041ce3_00247413, -diff --git a/debug_rom/gen_rom.py b/debug_rom/gen_rom.py -index 54387a1..a9dafe6 100755 ---- a/debug_rom/gen_rom.py -+++ b/debug_rom/gen_rom.py -@@ -22,7 +22,11 @@ if not os.path.isfile(file): - filename = os.path.splitext(file)[0] - - license = """\ --/* Copyright 2018 ETH Zurich and University of Bologna. -+/* -+ * Conversion to CHERIoT Ibex ISA from RISC-V -+ * Copyright SCI Semiconductor 2025 -+ * -+ * 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 --- -2.34.1 -