From cf431ee49133d577c6025fb99dcedda80fcb0ea3 Mon Sep 17 00:00:00 2001 From: Florian Zaruba Date: Sat, 30 Jun 2018 18:51:23 -0700 Subject: [PATCH] :construction: Add debug CSRs to DM --- Makefile | 3 +- src/debug/axi_riscv_dm.sv | 11 +++- src/debug/debug_csrs.sv | 114 ++++++++++++++++++++++++++++++++++++++ src/debug/dm_pkg.sv | 11 ++++ 4 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 src/debug/debug_csrs.sv diff --git a/Makefile b/Makefile index 3a18f94fb..ebeba5800 100755 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ test_pkg := $(wildcard tb/test/*/*sequence_pkg.sv*) $(wildcard tb/test/*/*_pkg.s dpi := $(wildcard tb/dpi/*) # this list contains the standalone components src := $(wildcard src/*.sv) $(wildcard tb/common/*.sv) $(wildcard src/axi2per/*.sv) $(wildcard src/axi_slice/*.sv) \ - $(wildcard src/axi_node/*.sv) $(wildcard src/axi_mem_if/src/*.sv) + $(wildcard src/axi_node/*.sv) $(wildcard src/axi_mem_if/src/*.sv) $(filter-out src/debug/dm_pkg.sv, $(wildcard src/debug/*.sv)) # look for testbenches tbs := tb/alu_tb.sv tb/core_tb.sv tb/dcache_arbiter_tb.sv tb/store_queue_tb.sv tb/scoreboard_tb.sv tb/fifo_tb.sv @@ -175,6 +175,7 @@ $(tests): build # User Verilator verilate: $(verilator) $(ariane_pkg) $(filter-out src/ariane_regfile.sv, $(wildcard src/*.sv)) $(wildcard src/axi_slice/*.sv) \ + $(filter-out src/debug/dm_pkg.sv, $(wildcard src/debug/*.sv)) \ src/util/cluster_clock_gating.sv src/util/behav_sram.sv src/axi_mem_if/src/axi2mem.sv tb/agents/axi_if/axi_if.sv \ --unroll-count 256 -Wno-fatal -Werror-PINMISSING -LDFLAGS "-lfesvr" -CFLAGS "-std=c++11" -Wall --cc --trace \ $(list_incdir) --top-module ariane_wrapped --exe tb/ariane_tb.cpp tb/simmem.cpp diff --git a/src/debug/axi_riscv_dm.sv b/src/debug/axi_riscv_dm.sv index c337f1d11..d1b2ffc78 100644 --- a/src/debug/axi_riscv_dm.sv +++ b/src/debug/axi_riscv_dm.sv @@ -14,14 +14,16 @@ * * 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. + * SW infrastructure re-use. As of version 0.13 */ -module axi_riscv_dm ( +module axi_riscv_dm #( + parameter int NrHarts = -1 +)( input logic clk_i, // clock input logic rst_ni, // asynchronous reset active low output logic ndmreset_o, // non-debug module reset - AXI_BUS.Slave axi_slave // bus slave + AXI_BUS.Slave axi_slave, // bus slave // Connection to DTM - compatible to RocketChip Debug Module input logic debug_req_valid, output logic debug_req_ready, @@ -35,4 +37,7 @@ module axi_riscv_dm ( output logic [31:0] debug_resp_bits_data ); + // Debug CSRs + + endmodule diff --git a/src/debug/debug_csrs.sv b/src/debug/debug_csrs.sv new file mode 100644 index 000000000..fe1e45cb4 --- /dev/null +++ b/src/debug/debug_csrs.sv @@ -0,0 +1,114 @@ +/* Copyright 2018 ETH Zurich and University of Bologna. + * Copyright and related rights are licensed under the Solderpad Hardware + * License, Version 0.51 (the “License”); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law + * or agreed to in writing, software, hardware and materials distributed under + * this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * File: axi_riscv_debug_module.sv + * Author: Florian Zaruba + * Date: 30.6.2018 + * + * Description: Debug CSRs. Communication over Debug Transport Module (DTM) + */ + +module debug_csrs #( + parameter int NrHarts = -1 +)( + input logic clk_i, // Clock + input logic rst_ni, // Asynchronous reset active low + input logic debug_req_valid, + output logic debug_req_ready, + input logic [ 6:0] debug_req_bits_addr, + input logic [ 1:0] debug_req_bits_op, // 0 = nop, 1 = read, 2 = write + input logic [31:0] debug_req_bits_data, + // every request needs a response one cycle later + output logic debug_resp_valid, + input logic debug_resp_ready, + output logic [ 1:0] debug_resp_bits_resp, + output logic [31:0] debug_resp_bits_data, + // hart communication + input logic [NrHarts-1:0] halted_i, // hart is halted + input logic [NrHarts-1:0] running_i, // hart is running + input logic [NrHarts-1:0] unavailable_i // e.g.: powered down + +); + // the amount of bits we need to represent all harts + localparam NrHartBits = (NrHarts == 1) ? 1 : $clog2(NrHarts); + + logic resp_queue_full; + logic resp_queue_empty; + logic resp_queue_push; + logic [31:0] resp_queue_data; + + dm::dmstatus_t dmstatus; + dm::dmcontrol_t dmcontrol_d, dmcontrol_q; + + // a successful response returns zero + assign debug_resp_bits_resp = DTM_SUCCESS; + assign debug_resp_valid = ~resp_queue_empty; + assign debug_req_ready = ~resp_queue_full; + assign resp_queue_push = debug_req_valid & debug_req_ready; + + always_comb begin : csr_read_write + // default assignments + dmstatus = '0; + dmstatus.version = DbgVersion013; + // no authentication implemented + dmstatus.authenticated = 1'b1; + + dmcontrol_d = dmcontrol_q; + // we only allow 1024 harts + dmcontrol_d.hartselhi = '0; + // determine how how many harts we actually want to select + dmcontrol_d.hartsello[9:NrHartBits] = '0; + + resp_queue_data = 32'0; + + if (debug_req_valid && debug_req_bits_op == DTM_READ) begin + unique case ({1'b0, debug_req_bits_addr}) + default:; + endcase + end + + if (debug_req_valid && debug_req_bits_op == DTM_WRITE) begin + unique case ({1'b0, debug_req_bits_addr}) + default:; + endcase + end + end + + // response FIFO + fifo #( + .dtype(logic [31:0]), + .DEPTH(2) + ) i_fifo ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .flush_i ( 1'b0 ), // we do not need to flush this queue + .full_o ( resp_queue_full ), + .empty_o ( resp_queue_empty ), + .single_element_o ( ), + .data_i ( resp_queue_data ), + .push_i ( resp_queue_push ), + .data_o ( debug_resp_bits_data ), + .pop_i ( debug_resp_ready ) + ); + + always_ff @(posedge clk_i or negedge rst_ni) begin : proc_ + if(~rst_ni) begin + dmcontrol_q <= '0; + end else begin + dmcontrol_q <= dmcontrol_d; + end + end + + `ifndef SYNTHESIS + initial begin + assert (NR_HARTS == 1024) else $error ("A maxium of 1024 harts is allowed."); + end + `endif +endmodule diff --git a/src/debug/dm_pkg.sv b/src/debug/dm_pkg.sv index 93555c763..8cd6e04c6 100644 --- a/src/debug/dm_pkg.sv +++ b/src/debug/dm_pkg.sv @@ -17,6 +17,7 @@ */ package dm; + localparam logic [3:0] DbgVersion013 = 4'h2; // debug registers localparam logic [7:0] Data0 = 8'h04; // up to Data11 @@ -35,6 +36,9 @@ package dm; localparam logic [7:0] DevTreeAddr3 = 8'h1C; localparam logic [7:0] NextDM = 8'h1D; localparam logic [7:0] ProgBuf0 = 8'h20; + localparam logic [7:0] ProgBuf1 = 8'h21; + localparam logic [7:0] ProgBuf2 = 8'h22; + localparam logic [7:0] ProgBuf3 = 8'h23; // up to ProgBuf15 localparam logic [7:0] AuthData = 8'h30; localparam logic [7:0] HaltSum2 = 8'h34; @@ -146,4 +150,11 @@ package dm; logic prv; } dcsr_t; + // DTM + localparam logic[1:0] DTM_NOP = 2'h0; + localparam logic[1:0] DTM_READ = 2'h1; + localparam logic[1:0] DTM_WRITE = 2'h2; + + localparam logic[1:0] DTM_SUCCESS = 2'h0; + endpackage