diff --git a/hw/snitch/src/snitch.sv b/hw/snitch/src/snitch.sv index 87815c1bc..dd7e66652 100644 --- a/hw/snitch/src/snitch.sv +++ b/hw/snitch/src/snitch.sv @@ -232,6 +232,7 @@ module snitch import snitch_pkg::*; import riscv_instr::*; #( // ----- logic [31:0] csr_rvalue; logic csr_en; + logic csr_dump; localparam logic M = 0; localparam logic S = 1; @@ -2238,7 +2239,8 @@ module snitch import snitch_pkg::*; import riscv_instr::*; #( // CSR logic always_comb begin - csr_rvalue = '0; + csr_rvalue = 1'b0; + csr_dump = 1'b0; illegal_csr = '0; priv_lvl_d = priv_lvl_q; // registers @@ -2468,7 +2470,10 @@ module snitch import snitch_pkg::*; import riscv_instr::*; #( if (!exception) fcsr_d = fcsr_t'(alu_result[9:0]); end else illegal_csr = 1'b1; end - default: csr_rvalue = '0; + default: begin + csr_rvalue = 1'b0; + csr_dump = 1'b1; + end endcase end else illegal_csr = 1'b1; end @@ -2552,6 +2557,17 @@ module snitch import snitch_pkg::*; import riscv_instr::*; #( dcsr_d.prv = dm::priv_lvl_t'(dm::PRIV_LVL_M); end + // pragma translate_off + always_ff @(posedge clk_i or posedge rst_i) begin + // Display CSR write if the CSR does not exist + if (!rst_i && csr_dump && inst_valid_o && inst_ready_i && !stall) begin + // $timeformat(-9, 0, " ns", 0); + $display("[DUMP] %t Core %3d: 0x%3h = 0x%08h, %d, %f", + $time, hart_id_i, inst_data_i[31:20], alu_result, alu_result, $bitstoshortreal(alu_result)); + end + end + // pragma translate_on + snitch_regfile #( .DATA_WIDTH ( 32 ), .NR_READ_PORTS ( 2 ), diff --git a/sw/snRuntime/src/dump.h b/sw/snRuntime/src/dump.h new file mode 100644 index 000000000..8f24cc1b9 --- /dev/null +++ b/sw/snRuntime/src/dump.h @@ -0,0 +1,28 @@ +// Copyright 2020 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Authors: Samuel Riedel, ETH Zurich +// Viviane Potocnik, ETH Zurich + +// Dump a value via CSR +// !!! Careful: This is only supported in simulation and an experimental +// feature. All writes to unimplemented CSR registers will be dumped by Snitch. +// This can be exploited to quickly print measurement values from all cores +// simultaneously without the hassle of printf. To specify multiple metrics, +// different CSRs can be used. The macro will define a function that will then +// always print via the same CSR. E.g., `dump(errors, 8)` will define a function +// with the following signature: `dump_errors(uint32_t val)`, which will print +// the given value via the 8th register. Alternatively, the `write_csr(reg, +// val)` macro can be used directly. + +#define dump_float(name, reg) \ + static __attribute__((always_inline)) inline void dump_##name(float val) { \ + asm volatile("csrw " #reg ", %0" ::"rK"(val)); \ + } + +#define dump_uint(name, reg) \ + static \ + __attribute__((always_inline)) inline void dump_##name(uint32_t val) { \ + asm volatile("csrw " #reg ", %0" ::"rK"(val)); \ + } \ No newline at end of file diff --git a/target/snitch_cluster/sw/runtime/rtl/src/snrt.h b/target/snitch_cluster/sw/runtime/rtl/src/snrt.h index d283d4294..1902c0454 100644 --- a/target/snitch_cluster/sw/runtime/rtl/src/snrt.h +++ b/target/snitch_cluster/sw/runtime/rtl/src/snrt.h @@ -25,6 +25,7 @@ #include "cluster_interrupts.h" #include "dm.h" #include "dma.h" +#include "dump.h" #include "eu.h" #include "kmp.h" #include "omp.h"