diff --git a/config/shared/debug.vh b/config/shared/debug.vh index 8a9c9c2ff..bee590f70 100755 --- a/config/shared/debug.vh +++ b/config/shared/debug.vh @@ -1,30 +1,20 @@ -/////////////////////////////////////////// -// debug.vh -// +/////////////////////////////////////////// debug.vh // Written: matthew.n.otto@okstate.edu // Created: 15 March 2024 -// // Purpose: debug port definitions -// // A component of the CORE-V-WALLY configurable RISC-V project. // https://github.com/openhwgroup/cvw -// // Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University -// // SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You // may obtain a copy of the License at -// // https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// 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 +// Unless required by applicable law or agreed to in writing, any work distributed under the +// 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. -//////////////////////////////////////////////////////////////////////////////////////////////// - +////////////////////////////////////////////////////////////////////////////////////////////// // DMI op field constants `define OP_NOP 2'b00 `define OP_READ 2'b01 @@ -139,253 +129,81 @@ `define AAR64 3 `define AAR128 4 -// Register Numbers (regno) +// Register Numbers (regno) // (Table 3.3) // 0x0000 – 0x0fff | CSRs. The “PC” can be accessed here through dpc. // 0x1000 – 0x101f | GPRs // 0x1020 – 0x103f | Floating point registers // 0xc000 – 0xffff | Reserved for non-standard extensions and internal use. -// privileged/csr/csrm -`define MISA_REGNO 16'h0301 // XLEN P.ZICSR_SUPPORTED (Read Only) // wallypipelinedcore `define TRAPM_REGNO 16'hC000 // 1'b P.ZICSR_SUPPORTED (Read Only) // src/ifu -`define DPC_REGNO 16'h07B1 // BOZO: Alias to PCM until DPC CSR is added `define PCM_REGNO 16'hC001 // XLEN P.ZICSR_SUPPORTED | P.BPRED_SUPPORTED `define INSTRM_REGNO 16'hC002 // 32'b P.ZICSR_SUPPORTED | P.A_SUPPORTED // ieu/controller `define MEMRWM_REGNO 16'hC003 // 2'b -`define INSTRVALIDM_REGNO 16'hC004 // 1'b +`define INSTRVALIDM_REGNO 16'hC004 // 1'b // ieu/datapath `define WRITEDATAM_REGNO 16'hC005 // XLEN // lsu `define IEUADRM_REGNO 16'hC006 // XLEN `define READDATAM_REGNO 16'hC007 // LLEN (Read Only) -// src/ieu/datapath -`define CSR_USTATUS 16'h0000 -`define CSR_UIE 16'h0004 -`define CSR_UTVEC 16'h0005 -`define CSR_USCRATCH 16'h0040 -`define CSR_UEPC 16'h0041 -`define CSR_UCAUSE 16'h0042 -`define CSR_UTVAL 16'h0043 -`define CSR_UIP 16'h0044 -`define CSR_FFLAGS 16'h0001 -`define CSR_FRM 16'h0002 -`define CSR_FCSR 16'h0003 -`define CSR_CYCLE 16'h0C00 -`define CSR_TIME 16'h0C01 -`define CSR_INSTRET 16'h0C02 -`define CSR_HPMCOUNTER3 16'h0C03 -`define CSR_HPMCOUNTER4 16'h0C04 -`define CSR_HPMCOUNTER5 16'h0C05 -`define CSR_HPMCOUNTER6 16'h0C06 -`define CSR_HPMCOUNTER7 16'h0C07 -`define CSR_HPMCOUNTER8 16'h0C08 -`define CSR_HPMCOUNTER9 16'h0C09 -`define CSR_HPMCOUNTER10 16'h0C0A -`define CSR_HPMCOUNTER11 16'h0C0B -`define CSR_HPMCOUNTER12 16'h0C0C -`define CSR_HPMCOUNTER13 16'h0C0D -`define CSR_HPMCOUNTER14 16'h0C0E -`define CSR_HPMCOUNTER15 16'h0C0F -`define CSR_HPMCOUNTER16 16'h0C10 -`define CSR_HPMCOUNTER17 16'h0C11 -`define CSR_HPMCOUNTER18 16'h0C12 -`define CSR_HPMCOUNTER19 16'h0C13 -`define CSR_HPMCOUNTER20 16'h0C14 -`define CSR_HPMCOUNTER21 16'h0C15 -`define CSR_HPMCOUNTER22 16'h0C16 -`define CSR_HPMCOUNTER23 16'h0C17 -`define CSR_HPMCOUNTER24 16'h0C18 -`define CSR_HPMCOUNTER25 16'h0C19 -`define CSR_HPMCOUNTER26 16'h0C1A -`define CSR_HPMCOUNTER27 16'h0C1B -`define CSR_HPMCOUNTER28 16'h0C1C -`define CSR_HPMCOUNTER29 16'h0C1D -`define CSR_HPMCOUNTER30 16'h0C1E -`define CSR_HPMCOUNTER31 16'h0C1F -`define CSR_CYCLEH 16'h0C80 -`define CSR_TIMEH 16'h0C81 -`define CSR_INSTRETH 16'h0C82 -`define CSR_HPMCOUNTER3H 16'h0C83 -`define CSR_HPMCOUNTER4H 16'h0C84 -`define CSR_HPMCOUNTER5H 16'h0C85 -`define CSR_HPMCOUNTER6H 16'h0C86 -`define CSR_HPMCOUNTER7H 16'h0C87 -`define CSR_HPMCOUNTER8H 16'h0C88 -`define CSR_HPMCOUNTER9H 16'h0C89 -`define CSR_HPMCOUNTER10H 16'h0C8A -`define CSR_HPMCOUNTER11H 16'h0C8B -`define CSR_HPMCOUNTER12H 16'h0C8C -`define CSR_HPMCOUNTER13H 16'h0C8D -`define CSR_HPMCOUNTER14H 16'h0C8E -`define CSR_HPMCOUNTER15H 16'h0C8F -`define CSR_HPMCOUNTER16H 16'h0C90 -`define CSR_HPMCOUNTER17H 16'h0C91 -`define CSR_HPMCOUNTER18H 16'h0C92 -`define CSR_HPMCOUNTER19H 16'h0C93 -`define CSR_HPMCOUNTER20H 16'h0C94 -`define CSR_HPMCOUNTER21H 16'h0C95 -`define CSR_HPMCOUNTER22H 16'h0C96 -`define CSR_HPMCOUNTER23H 16'h0C97 -`define CSR_HPMCOUNTER24H 16'h0C98 -`define CSR_HPMCOUNTER25H 16'h0C99 -`define CSR_HPMCOUNTER26H 16'h0C9A -`define CSR_HPMCOUNTER27H 16'h0C9B -`define CSR_HPMCOUNTER28H 16'h0C9C -`define CSR_HPMCOUNTER29H 16'h0C9D -`define CSR_HPMCOUNTER30H 16'h0C9E -`define CSR_HPMCOUNTER31H 16'h0C9F -`define CSR_SSTATUS 16'h0100 -`define CSR_SEDELEG 16'h0102 -`define CSR_SIDELEG 16'h0103 -`define CSR_SIE 16'h0104 -`define CSR_STVEC 16'h0105 -`define CSR_SCOUNTEREN 16'h0106 -`define CSR_SSCRATCH 16'h0140 -`define CSR_SEPC 16'h0141 -`define CSR_SCAUSE 16'h0142 -`define CSR_STVAL 16'h0143 -`define CSR_SIP 16'h0144 -`define CSR_SATP 16'h0180 -`define CSR_MVENDORID 16'h0F11 -`define CSR_MARCHID 16'h0F12 -`define CSR_MIMPID 16'h0F13 -`define CSR_MHARTID 16'h0F14 -`define CSR_MSTATUS 16'h0300 -`define CSR_MISA 16'h0301 -`define CSR_MEDELEG 16'h0302 -`define CSR_MIDELEG 16'h0303 -`define CSR_MIE 16'h0304 -`define CSR_MTVEC 16'h0305 -`define CSR_MCOUNTEREN 16'h0306 -`define CSR_MSCRATCH 16'h0340 -`define CSR_MEPC 16'h0341 -`define CSR_MCAUSE 16'h0342 -`define CSR_MTVAL 16'h0343 -`define CSR_MIP 16'h0344 -`define CSR_PMPCFG0 16'h03A0 -`define CSR_PMPCFG1 16'h03A1 -`define CSR_PMPCFG2 16'h03A2 -`define CSR_PMPCFG3 16'h03A3 -`define CSR_PMPADDR0 16'h03B0 -`define CSR_PMPADDR1 16'h03B1 -`define CSR_PMPADDR2 16'h03B2 -`define CSR_PMPADDR3 16'h03B3 -`define CSR_PMPADDR4 16'h03B4 -`define CSR_PMPADDR5 16'h03B5 -`define CSR_PMPADDR6 16'h03B6 -`define CSR_PMPADDR7 16'h03B7 -`define CSR_PMPADDR8 16'h03B8 -`define CSR_PMPADDR9 16'h03B9 -`define CSR_PMPADDR10 16'h03BA -`define CSR_PMPADDR11 16'h03BB -`define CSR_PMPADDR12 16'h03BC -`define CSR_PMPADDR13 16'h03BD -`define CSR_PMPADDR14 16'h03BE -`define CSR_PMPADDR15 16'h03BF -`define CSR_MCYCLE 16'h0B00 -`define CSR_MINSTRET 16'h0B02 -`define CSR_MHPMCOUNTER3 16'h0B03 -`define CSR_MHPMCOUNTER4 16'h0B04 -`define CSR_MHPMCOUNTER5 16'h0B05 -`define CSR_MHPMCOUNTER6 16'h0B06 -`define CSR_MHPMCOUNTER7 16'h0B07 -`define CSR_MHPMCOUNTER8 16'h0B08 -`define CSR_MHPMCOUNTER9 16'h0B09 -`define CSR_MHPMCOUNTER10 16'h0B0A -`define CSR_MHPMCOUNTER11 16'h0B0B -`define CSR_MHPMCOUNTER12 16'h0B0C -`define CSR_MHPMCOUNTER13 16'h0B0D -`define CSR_MHPMCOUNTER14 16'h0B0E -`define CSR_MHPMCOUNTER15 16'h0B0F -`define CSR_MHPMCOUNTER16 16'h0B10 -`define CSR_MHPMCOUNTER17 16'h0B11 -`define CSR_MHPMCOUNTER18 16'h0B12 -`define CSR_MHPMCOUNTER19 16'h0B13 -`define CSR_MHPMCOUNTER20 16'h0B14 -`define CSR_MHPMCOUNTER21 16'h0B15 -`define CSR_MHPMCOUNTER22 16'h0B16 -`define CSR_MHPMCOUNTER23 16'h0B17 -`define CSR_MHPMCOUNTER24 16'h0B18 -`define CSR_MHPMCOUNTER25 16'h0B19 -`define CSR_MHPMCOUNTER26 16'h0B1A -`define CSR_MHPMCOUNTER27 16'h0B1B -`define CSR_MHPMCOUNTER28 16'h0B1C -`define CSR_MHPMCOUNTER29 16'h0B1D -`define CSR_MHPMCOUNTER30 16'h0B1E -`define CSR_MHPMCOUNTER31 16'h0B1F -`define CSR_MCYCLEH 16'h0B80 -`define CSR_MINSTRETH 16'h0B82 -`define CSR_MHPMCOUNTER3H 16'h0B83 -`define CSR_MHPMCOUNTER4H 16'h0B84 -`define CSR_MHPMCOUNTER5H 16'h0B85 -`define CSR_MHPMCOUNTER6H 16'h0B86 -`define CSR_MHPMCOUNTER7H 16'h0B87 -`define CSR_MHPMCOUNTER8H 16'h0B88 -`define CSR_MHPMCOUNTER9H 16'h0B89 -`define CSR_MHPMCOUNTER10H 16'h0B8A -`define CSR_MHPMCOUNTER11H 16'h0B8B -`define CSR_MHPMCOUNTER12H 16'h0B8C -`define CSR_MHPMCOUNTER13H 16'h0B8D -`define CSR_MHPMCOUNTER14H 16'h0B8E -`define CSR_MHPMCOUNTER15H 16'h0B8F -`define CSR_MHPMCOUNTER16H 16'h0B90 -`define CSR_MHPMCOUNTER17H 16'h0B91 -`define CSR_MHPMCOUNTER18H 16'h0B92 -`define CSR_MHPMCOUNTER19H 16'h0B93 -`define CSR_MHPMCOUNTER20H 16'h0B94 -`define CSR_MHPMCOUNTER21H 16'h0B95 -`define CSR_MHPMCOUNTER22H 16'h0B96 -`define CSR_MHPMCOUNTER23H 16'h0B97 -`define CSR_MHPMCOUNTER24H 16'h0B98 -`define CSR_MHPMCOUNTER25H 16'h0B99 -`define CSR_MHPMCOUNTER26H 16'h0B9A -`define CSR_MHPMCOUNTER27H 16'h0B9B -`define CSR_MHPMCOUNTER28H 16'h0B9C -`define CSR_MHPMCOUNTER29H 16'h0B9D -`define CSR_MHPMCOUNTER30H 16'h0B9E -`define CSR_MHPMCOUNTER31H 16'h0B9F -`define CSR_MHPMEVENT3 16'h0323 -`define CSR_MHPMEVENT4 16'h0324 -`define CSR_MHPMEVENT5 16'h0325 -`define CSR_MHPMEVENT6 16'h0326 -`define CSR_MHPMEVENT7 16'h0327 -`define CSR_MHPMEVENT8 16'h0328 -`define CSR_MHPMEVENT9 16'h0329 -`define CSR_MHPMEVENT10 16'h032A -`define CSR_MHPMEVENT11 16'h032B -`define CSR_MHPMEVENT12 16'h032C -`define CSR_MHPMEVENT13 16'h032D -`define CSR_MHPMEVENT14 16'h032E -`define CSR_MHPMEVENT15 16'h032F -`define CSR_MHPMEVENT16 16'h0330 -`define CSR_MHPMEVENT17 16'h0331 -`define CSR_MHPMEVENT18 16'h0332 -`define CSR_MHPMEVENT19 16'h0333 -`define CSR_MHPMEVENT20 16'h0334 -`define CSR_MHPMEVENT21 16'h0335 -`define CSR_MHPMEVENT22 16'h0336 -`define CSR_MHPMEVENT23 16'h0337 -`define CSR_MHPMEVENT24 16'h0338 -`define CSR_MHPMEVENT25 16'h0339 -`define CSR_MHPMEVENT26 16'h033A -`define CSR_MHPMEVENT27 16'h033B -`define CSR_MHPMEVENT28 16'h033C -`define CSR_MHPMEVENT29 16'h033D -`define CSR_MHPMEVENT30 16'h033E -`define CSR_MHPMEVENT31 16'h033F -`define CSR_TSELECT 16'h07A0 -`define CSR_TDATA1 16'h07A1 -`define CSR_TDATA2 16'h07A2 -`define CSR_TDATA3 16'h07A3 -`define CSR_DCSR 16'h07B0 -`define CSR_DPC 16'h07B1 -`define CSR_DSCRATCH 16'h07B2 +// CSR +// privileged/csru +`define FFLAGS_REGNO 16'h0001 +`define FRM_REGNO 16'h0002 +`define FCSR_REGNO 16'h0003 +// privileged/csrm +`define MSTATUS_REGNO 16'h0300 +`define MISA_REGNO 16'h0301 +`define MEDELEG_REGNO 16'h0302 +`define MIDELEG_REGNO 16'h0303 +`define MIE_REGNO 16'h0304 +`define MTVEC_REGNO 16'h0305 +`define MCOUNTEREN_REGNO 16'h0306 + +`define MENVCFG_REGNO 16'h030A + +`define MSTATUSH_REGNO 16'h0310 + +`define MENVCFGH_REGNO 16'h031A + +`define MCOUNTINHIBIT_REGNO 16'h0320 + +`define MSCRATCH_REGNO 16'h0340 +`define MEPC_REGNO 16'h0341 +`define MCAUSE_REGNO 16'h0342 +`define MTVAL_REGNO 16'h0343 +`define MIP_REGNO 16'h0344 + +`define PMPCFG0_REGNO 16'h03A0 +//range +`define PMPCFGF_REGNO 16'h03AF +`define PMPADDR0_REGNO 16'h03B0// P.PA_BITS +//range +`define PMPADDRF_REGNO 16'h03EF + +`define TSELECT_REGNO 16'h07A0 +`define TDATA1_REGNO 16'h07A1 +`define TDATA2_REGNO 16'h07A2 +`define TDATA3_REGNO 16'h07A3 + +`define DCSR_REGNO 16'h07B0 +`define DPC_REGNO 16'h07B1 + +`define MVENDORID_REGNO 16'h0F11 +`define MARCHID_REGNO 16'h0F12 +`define MIMPID_REGNO 16'h0F13 +`define MHARTID_REGNO 16'h0F14 +`define MCONFIGPTR_REGNO 16'h0F15 + + + + +// src/ieu/datapath `define X0_REGNO 16'h1000 `define X1_REGNO 16'h1001 `define X2_REGNO 16'h1002 diff --git a/src/debug/dm.sv b/src/debug/dm.sv index d07eaeec9..c5de29a53 100644 --- a/src/debug/dm.sv +++ b/src/debug/dm.sv @@ -41,20 +41,19 @@ module dm import cvw::*; #(parameter cvw_t P) ( output logic DebugStall, // Scan Chain - output logic ScanEn, - input logic ScanIn, - output logic ScanOut, - output logic GPRSel, - output logic FPRSel, - output logic [4:0] RegAddr, - output logic DebugCapture, - output logic DebugRegUpdate, - output logic GPRScanEn, - input logic GPRScanIn, - output logic GPRScanOut, - output logic FPRScanEn, - input logic FPRScanIn, - output logic FPRScanOut + output logic DebugScanEn, // puts scannable flops into scan mode + input logic DebugScanIn, // (misc) scan chain data in + input logic GPRScanIn, // (GPR) scan chain data in + input logic FPRScanIn, // (FPR) scan chain data in + input logic CSRScanIn, // (CSR) scan chain data in + output logic DebugScanOut, // scan chain data out + output logic MiscSel, // selects general scan chain + output logic GPRSel, // selects GPR scan chain + output logic FPRSel, // selects FPR scan chain + output logic CSRSel, // selects CSR scan chain + output logic [11:0] RegAddr, // address for scanable regfiles (GPR, FPR, CSR) + output logic DebugCapture, // latches values into scan register before scanning out + output logic DebugRegUpdate // writes values from scan register after scanning in ); `include "debug.vh" @@ -112,6 +111,7 @@ module dm import cvw::*; #(parameter cvw_t P) ( logic RegReadOnly; // Current RegNo points to a readonly register logic GPRegNo; // Requested RegNo is a GPR logic FPRegNo; // Requested RegNo is a FPR + logic CSRegNo; // Requested RegNo is a CSR logic StoreScanChain; // Store current value of ScanReg into DataX logic WriteMsgReg; // Write to DataX logic WriteScanReg; // Insert data from DataX into ScanReg @@ -407,32 +407,25 @@ module dm import cvw::*; #(parameter cvw_t P) ( end assign Busy = ~(AcState == AC_IDLE); + + // Scan Chain + assign DebugScanEn = (AcState == AC_SCAN); assign DebugCapture = (AcState == AC_CAPTURE); assign DebugRegUpdate = (AcState == AC_UPDATE); - // Scan Chain + assign MiscSel = ~(CSRegNo | GPRegNo | FPRegNo) & (AcState != AC_IDLE); + assign CSRSel = CSRegNo & (AcState != AC_IDLE); assign GPRSel = GPRegNo & (AcState != AC_IDLE); assign FPRSel = FPRegNo & (AcState != AC_IDLE); + assign DebugScanOut = ScanReg[0]; + always_comb begin - {ScanOut,GPRScanOut,FPRScanOut} = 0; - {ScanEn,GPRScanEn,FPRScanEn} = 0; - case ({GPRSel, FPRSel}) - 2'b10 : begin - ScanReg[P.LLEN] = GPRScanIn; - GPRScanOut = ScanReg[0]; - GPRScanEn = (AcState == AC_SCAN); - end - 2'b01 : begin - ScanReg[P.LLEN] = FPRScanIn; - FPRScanOut = ScanReg[0]; - FPRScanEn = (AcState == AC_SCAN); - end - 2'b00 : begin - ScanReg[P.LLEN] = ScanIn; - ScanOut = ScanReg[0]; - ScanEn = (AcState == AC_SCAN); - end + case ({CSRSel, GPRSel, FPRSel}) + 3'b100 : ScanReg[P.LLEN] = CSRScanIn; + 3'b010 : ScanReg[P.LLEN] = GPRScanIn; + 3'b001 : ScanReg[P.LLEN] = FPRScanIn; + default : ScanReg[P.LLEN] = DebugScanIn; endcase end @@ -470,6 +463,6 @@ module dm import cvw::*; #(parameter cvw_t P) ( flopenr #(32) data3reg (.clk, .reset(rst), .en(StoreScanChain | WriteMsgReg & (ReqAddress == `DATA3)), .d(Data3Wr), .q(Data3)); end - rad #(P) regnodecode(.AarSize(ReqData[`AARSIZE]),.Regno(ReqData[`REGNO]),.GPRegNo,.FPRegNo,.ScanChainLen,.ShiftCount,.InvalidRegNo,.RegReadOnly,.RegAddr,.ARMask); + rad #(P) regnodecode(.AarSize(ReqData[`AARSIZE]),.Regno(ReqData[`REGNO]),.CSRegNo,.GPRegNo,.FPRegNo,.ScanChainLen,.ShiftCount,.InvalidRegNo,.RegReadOnly,.RegAddr,.ARMask); endmodule diff --git a/src/debug/rad.sv b/src/debug/rad.sv index b572c2ca9..9edc985ea 100644 --- a/src/debug/rad.sv +++ b/src/debug/rad.sv @@ -4,7 +4,8 @@ // Written: matthew.n.otto@okstate.edu // Created: 28 April 2024 // -// Purpose: Calculates the numbers of shifts required to access target register on the debug scan chain +// Purpose: Decodes the register address and generates various control signals +// required to access target register on the debug scan chain // // A component of the CORE-V-WALLY configurable RISC-V project. // https://github.com/openhwgroup/cvw @@ -30,11 +31,12 @@ module rad import cvw::*; #(parameter cvw_t P) ( input logic [15:0] Regno, output logic GPRegNo, output logic FPRegNo, + output logic CSRegNo, output logic [9:0] ScanChainLen, output logic [9:0] ShiftCount, output logic InvalidRegNo, output logic RegReadOnly, - output logic [4:0] RegAddr, + output logic [11:0] RegAddr, output logic [P.LLEN-1:0] ARMask ); `include "debug.vh" @@ -52,8 +54,6 @@ module rad import cvw::*; #(parameter cvw_t P) ( + MISALEN + TRAPMLEN + PCMLEN + INSTRMLEN + MEMRWMLEN + INSTRVALIDMLEN + WRITEDATAMLEN + IEUADRMLEN + READDATAMLEN; - localparam GPRCHAINLEN = P.XLEN; - localparam FPRCHAINLEN = P.FLEN; localparam MISA_IDX = MISALEN; localparam TRAPM_IDX = MISA_IDX + TRAPMLEN; @@ -67,8 +67,8 @@ module rad import cvw::*; #(parameter cvw_t P) ( logic [P.LLEN:0] Mask; - assign RegAddr = Regno[4:0]; - assign ScanChainLen = GPRegNo ? GPRCHAINLEN : FPRegNo ? FPRCHAINLEN : SCANCHAINLEN; + assign RegAddr = Regno[11:0]; + assign ScanChainLen = (CSRegNo | GPRegNo) ? P.XLEN : FPRegNo ? P.FLEN : SCANCHAINLEN; // Register decoder always_comb begin @@ -77,6 +77,35 @@ module rad import cvw::*; #(parameter cvw_t P) ( GPRegNo = 0; FPRegNo = 0; case (Regno) inside + [`USTATUS_REGNO:`UTVEC_REGNO], + [`USCRATCH_REGNO:`UIP_REGNO], + `SSTATUS_REGNO, + [`SEDELEG_REGNO:`SCOUNTEREN_REGNO], + [`SSCRATCH_REGNO:`SIP_REGNO], + `SATP_REGNO, + [`MSTATUS_REGNO:`MCOUNTEREN_REGNO], + [`MHPMEVENT3_REGNO:`MIP_REGNO], + [`PMPCFG0_REGNO:`PMPCFG3_REGNO], + [`PMPADDR0_REGNO:`PMPADDR15_REGNO], + [`TSELECT_REGNO:`TDATA3_REGNO], + [`DCSR_REGNO:`DPC_REGNO], + `MCYCLE_REGNO, + [`MINSTRET_REGNO:`MHPMCOUNTER31_REGNO], + `MCYCLEH_REGNO, + [`MINSTRETH_REGNO:`MHPMCOUNTER31H_REGNO] : begin + ShiftCount = P.XLEN - 1; + CSRegNo = 1; + RegReadOnly = 1; // TODO: eventually DCSR (any maybe others) will be RW + end + + [`CYCLE_REGNO:`HPMCOUNTER31_REGNO], + [`CYCLEH_REGNO:`HPMCOUNTER31H_REGNO], + [`MVENDORID_REGNO:`MHARTID_REGNO] : begin + ShiftCount = P.XLEN - 1; + CSRegNo = 1; + RegReadOnly = 1; + end + [`X0_REGNO:`X15_REGNO] : begin ShiftCount = P.XLEN - 1; GPRegNo = 1; @@ -91,17 +120,16 @@ module rad import cvw::*; #(parameter cvw_t P) ( InvalidRegNo = ~(P.F_SUPPORTED | P.D_SUPPORTED | P.Q_SUPPORTED); FPRegNo = 1; end - `MISA_REGNO : begin - ShiftCount = SCANCHAINLEN - MISA_IDX; - InvalidRegNo = ~P.ZICSR_SUPPORTED; - RegReadOnly = 1; - end + //`MISA_REGNO : begin + // ShiftCount = SCANCHAINLEN - MISA_IDX; + // InvalidRegNo = ~P.ZICSR_SUPPORTED; + // RegReadOnly = 1; + //end `TRAPM_REGNO : begin ShiftCount = SCANCHAINLEN - TRAPM_IDX; InvalidRegNo = ~P.ZICSR_SUPPORTED; RegReadOnly = 1; end - `DPC_REGNO, // BOZO: Alias to PCM until DPC CSR is added `PCM_REGNO : begin ShiftCount = SCANCHAINLEN - PCM_IDX; InvalidRegNo = ~(P.ZICSR_SUPPORTED | P.BPRED_SUPPORTED); diff --git a/src/fpu/fpu.sv b/src/fpu/fpu.sv index c2adffaaf..40e785518 100755 --- a/src/fpu/fpu.sv +++ b/src/fpu/fpu.sv @@ -63,13 +63,13 @@ module fpu import cvw::*; #(parameter cvw_t P) ( output logic FCvtIntW, // select FCvtIntRes (to IEU) output logic [P.XLEN-1:0] FIntDivResultW, // Result from integer division (to IEU) // Debug scan chain - input logic FPRSel, + input logic DebugSel, + input logic [4:0] RegAddr, input logic DebugCapture, input logic DebugRegUpdate, - input logic [4:0] RegAddr, - input logic FPRScanEn, - input logic FPRScanIn, - output logic FPRScanOut + input logic DebugScanEn, + input logic DebugScanIn, + output logic DebugScanOut ); // RISC-V FPU specifics: @@ -205,11 +205,11 @@ module fpu import cvw::*; #(parameter cvw_t P) ( .a1(RA1), .a2(InstrD[24:20]), .a3(InstrD[31:27]), .a4(WA1), .wd4(FResultWM), .rd1(FRD1D), .rd2(FRD2D), .rd3(FRD3D)); - assign FRegWriteWM = FPRSel ? DebugRegUpdate : FRegWriteW; - assign RA1 = FPRSel ? RegAddr : InstrD[19:15]; - assign WA1 = FPRSel ? RegAddr : RdW; - assign FResultWM = FPRSel ? DebugFPRWriteD : FResultW; - flopenrs #(P.FLEN) FPScanReg(.clk, .reset, .en(DebugCapture), .d(FRD1D), .q(DebugFPRWriteD), .scan(FPRScanEn), .scanin(FPRScanIn), .scanout(FPRScanOut)); + assign FRegWriteWM = DebugSel ? DebugRegUpdate : FRegWriteW; + assign RA1 = DebugSel ? RegAddr : InstrD[19:15]; + assign WA1 = DebugSel ? RegAddr : RdW; + assign FResultWM = DebugSel ? DebugFPRWriteD : FResultW; + flopenrs #(P.FLEN) FPScanReg(.clk, .reset, .en(DebugCapture), .d(FRD1D), .q(DebugFPRWriteD), .scan(DebugScanEn), .scanin(DebugScanIn), .scanout(DebugScanOut)); end else begin fregfile #(P.FLEN) fregfile (.clk, .reset, .we4(FRegWriteW), .a1(InstrD[19:15]), .a2(InstrD[24:20]), .a3(InstrD[31:27]), diff --git a/src/ieu/datapath.sv b/src/ieu/datapath.sv index 75029b421..d1e35257b 100644 --- a/src/ieu/datapath.sv +++ b/src/ieu/datapath.sv @@ -75,16 +75,16 @@ module datapath import cvw::*; #(parameter cvw_t P) ( input logic [4:0] RdW, // Destination register // Hazard Unit signals // Debug scan chain - input logic DebugScanEn, - input logic DebugScanIn, - output logic DebugScanOut, - input logic GPRSel, - input logic DebugCapture, - input logic DebugRegUpdate, - input logic [4:0] RegAddr, - input logic GPRScanEn, - input logic GPRScanIn, - output logic GPRScanOut + input logic DebugScanEn, + input logic DebugScanIn, + output logic DebugScanOut, + input logic MiscSel, + input logic GPRSel, + input logic DebugCapture, + input logic DebugRegUpdate, + input logic [4:0] RegAddr, + input logic GPRScanIn, + output logic GPRScanOut ); // Fetch stage signals @@ -123,7 +123,7 @@ module datapath import cvw::*; #(parameter cvw_t P) ( assign Rs1DM = GPRSel ? RegAddr : Rs1D; assign RdWM = GPRSel ? RegAddr : RdW; assign ResultWM = GPRSel ? DebugGPRWriteD : ResultW; - flopenrs #(P.XLEN) GPScanReg(.clk, .reset, .en(DebugCapture), .d(R1D), .q(DebugGPRWriteD), .scan(GPRScanEn), .scanin(GPRScanIn), .scanout(GPRScanOut)); + flopenrs #(P.XLEN) GPScanReg(.clk, .reset, .en(DebugCapture), .d(R1D), .q(DebugGPRWriteD), .scan(DebugScanEn & GPRSel), .scanin(GPRScanIn), .scanout(GPRScanOut)); end else begin regfile #(P.XLEN, P.E_SUPPORTED) regf(clk, reset, RegWriteW, Rs1D, Rs2D, RdW, ResultW, R1D, R2D); end @@ -146,7 +146,7 @@ module datapath import cvw::*; #(parameter cvw_t P) ( flopenrc #(P.XLEN) SrcAMReg(clk, reset, FlushM, ~StallM, SrcAE, SrcAM); flopenrc #(P.XLEN) IEUResultMReg(clk, reset, FlushM, ~StallM, IEUResultE, IEUResultM); if (P.DEBUG_SUPPORTED) - flopenrcs #(P.XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, ForwardedSrcBE, WriteDataM, DebugScanEn, DebugScanIn, DebugScanOut); + flopenrcs #(P.XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, ForwardedSrcBE, WriteDataM, (DebugScanEn & MiscSel), DebugScanIn, DebugScanOut); else flopenrc #(P.XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, ForwardedSrcBE, WriteDataM); diff --git a/src/ieu/ieu.sv b/src/ieu/ieu.sv index 6de57f56d..a36e08712 100644 --- a/src/ieu/ieu.sv +++ b/src/ieu/ieu.sv @@ -81,16 +81,15 @@ module ieu import cvw::*; #(parameter cvw_t P) ( output logic CSRWriteFenceM, // CSR write or fence instruction needs to flush subsequent instructions // Debug scan chain input logic DebugScanEn, - input logic DebugScanIn, - output logic DebugScanOut, - // GPR debug scan chain + input logic MiscSel, input logic GPRSel, + input logic DebugScanIn, + input logic GPRScanIn, + output logic DebugScanOut, + output logic GPRScanOut, input logic DebugCapture, input logic DebugRegUpdate, - input logic [4:0] RegAddr, - input logic GPRScanEn, - input logic GPRScanIn, - output logic GPRScanOut + input logic [4:0] RegAddr ); logic [2:0] ImmSrcD; // Select type of immediate extension @@ -134,7 +133,7 @@ module ieu import cvw::*; #(parameter cvw_t P) ( .StallM, .FlushM, .MemRWE, .MemRWM, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M, .RegWriteM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM, .StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .InvalidateICacheM, - .RdW, .RdE, .RdM, .DebugScanEn, .DebugScanIn, .DebugScanOut(DSCR)); + .RdW, .RdE, .RdM, .DebugScanEn(DebugScanEn & MiscSel), .DebugScanIn, .DebugScanOut(DSCR)); datapath #(P) dp( .clk, .reset, .ImmSrcD, .InstrD, .Rs1D, .Rs2D, .Rs2E, .StallE, .FlushE, .ForwardAE, .ForwardBE, .W64E, .SubArithE, @@ -143,5 +142,5 @@ module ieu import cvw::*; #(parameter cvw_t P) ( .StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW, .StallW, .FlushW, .RegWriteW, .IntDivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW, .CSRReadValW, .MDUResultW, .FIntDivResultW, .RdW, .DebugScanEn, .DebugScanIn(DSCR), .DebugScanOut, - .GPRSel, .DebugCapture, .DebugRegUpdate, .RegAddr, .GPRScanEn, .GPRScanIn, .GPRScanOut); + .MiscSel, .GPRSel, .DebugCapture, .DebugRegUpdate, .RegAddr, .GPRScanIn, .GPRScanOut); endmodule diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index 23f9860dd..679bd4170 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -94,7 +94,10 @@ module csr import cvw::*; #(parameter cvw_t P) ( output logic IllegalCSRAccessM, // Illegal CSR access: CSR doesn't exist or is inaccessible at this privilege level output logic BigEndianM, // memory access is big-endian based on privilege mode and STATUS register endian fields // Debug scan chain + input logic DebugSel, + input logic [11:0] DebugRegAddr, input logic DebugCapture, + input logic DebugRegUpdate, input logic DebugScanEn, input logic DebugScanIn, output logic DebugScanOut @@ -107,7 +110,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( logic [P.XLEN-1:0] CSRReadValM; logic [P.XLEN-1:0] CSRSrcM; logic [P.XLEN-1:0] CSRRWM, CSRRSM, CSRRCM; - logic [P.XLEN-1:0] CSRWriteValM; + logic [P.XLEN-1:0] CSRWriteValM, CSRWriteValDM, DebugCSRScanVal; logic [P.XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW; logic [P.XLEN-1:0] STVEC_REGW, MTVEC_REGW; logic [P.XLEN-1:0] MEPC_REGW, SEPC_REGW; @@ -118,7 +121,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( logic WriteFRMM, WriteFFLAGSM; logic [P.XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextMtvalM; logic [4:0] NextCauseM; - logic [11:0] CSRAdrM; + logic [11:0] CSRAdrM, CSRAdrDM; logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM; logic InsufficientCSRPrivilegeM; logic IllegalCSRMWriteReadonlyM; @@ -134,6 +137,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( logic [P.XLEN-1:0] SENVCFG_REGW; logic ENVCFG_STCE; // supervisor timer counter enable logic ENVCFG_FIOM; // fence implies io (presently not used) + logic CSRMWriteDM; // only valid unflushed instructions can access CSRs assign InstrValidNotFlushedM = InstrValidM & ~StallW & ~FlushW; @@ -184,7 +188,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( CSRSrcM = InstrM[14] ? {{(P.XLEN-5){1'b0}}, InstrM[19:15]} : SrcAM; // CSR set and clear for MIP/SIP should only touch internal state, not interrupt inputs - if (CSRAdrM == MIP | CSRAdrM == SIP) CSRReadVal2M = {{(P.XLEN-12){1'b0}}, MIP_REGW_writeable}; + if (CSRAdrDM == MIP | CSRAdrDM == SIP) CSRReadVal2M = {{(P.XLEN-12){1'b0}}, MIP_REGW_writeable}; else CSRReadVal2M = CSRReadValM; // Compute AND/OR modification @@ -204,10 +208,10 @@ module csr import cvw::*; #(parameter cvw_t P) ( /////////////////////////////////////////// assign CSRAdrM = InstrM[31:20]; - assign UnalignedNextEPCM = TrapM ? PCM : CSRWriteValM; + assign UnalignedNextEPCM = TrapM ? PCM : CSRWriteValDM; assign NextEPCM = P.ZCA_SUPPORTED ? {UnalignedNextEPCM[P.XLEN-1:1], 1'b0} : {UnalignedNextEPCM[P.XLEN-1:2], 2'b00}; // 3.1.15 alignment - assign NextCauseM = TrapM ? {InterruptM, CauseM}: {CSRWriteValM[P.XLEN-1], CSRWriteValM[3:0]}; - assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM; + assign NextCauseM = TrapM ? {InterruptM, CauseM}: {CSRWriteValDM[P.XLEN-1], CSRWriteValDM[3:0]}; + assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValDM; assign UngatedCSRMWriteM = CSRWriteM & (PrivilegeModeW == P.M_MODE); assign CSRMWriteM = UngatedCSRMWriteM & InstrValidNotFlushedM; assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW) & InstrValidNotFlushedM; @@ -220,37 +224,37 @@ module csr import cvw::*; #(parameter cvw_t P) ( /////////////////////////////////////////// csri #(P) csri(.clk, .reset, - .CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM, + .CSRMWriteM, .CSRSWriteM, .CSRWriteValM(CSRWriteValDM), .CSRAdrM(CSRAdrDM), .MExtInt, .SExtInt, .MTimerInt, .STimerInt, .MSwInt, .MIDELEG_REGW, .ENVCFG_STCE, .MIP_REGW, .MIE_REGW, .MIP_REGW_writeable); csrsr #(P) csrsr(.clk, .reset, .StallW, .WriteMSTATUSM, .WriteMSTATUSHM, .WriteSSTATUSM, .TrapM, .FRegWriteM, .NextPrivilegeModeM, .PrivilegeModeW, - .mretM, .sretM, .WriteFRMM, .WriteFFLAGSM, .CSRWriteValM, .SelHPTW, + .mretM, .sretM, .WriteFRMM, .WriteFFLAGSM, .CSRWriteValM(CSRWriteValDM), .SelHPTW, .MSTATUS_REGW, .SSTATUS_REGW, .MSTATUSH_REGW, .STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .STATUS_TW, .STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TVM, .STATUS_FS, .BigEndianM); csrm #(P) csrm(.clk, .reset, - .UngatedCSRMWriteM, .CSRMWriteM, .MTrapM, .CSRAdrM, + .UngatedCSRMWriteM, .CSRMWriteM, .MTrapM, .CSRAdrM(CSRAdrDM), .NextEPCM, .NextCauseM, .NextMtvalM, .MSTATUS_REGW, .MSTATUSH_REGW, - .CSRWriteValM, .CSRMReadValM, .MTVEC_REGW, + .CSRWriteValM(CSRWriteValDM), .CSRMReadValM, .MTVEC_REGW, .MEPC_REGW, .MCOUNTEREN_REGW, .MCOUNTINHIBIT_REGW, .MEDELEG_REGW, .MIDELEG_REGW,.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .MIP_REGW, .MIE_REGW, .WriteMSTATUSM, .WriteMSTATUSHM, .IllegalCSRMAccessM, .IllegalCSRMWriteReadonlyM, - .MENVCFG_REGW, .DebugCapture, .DebugScanEn, .DebugScanIn, .DebugScanOut); + .MENVCFG_REGW); if (P.S_SUPPORTED) begin:csrs logic STCE; assign STCE = P.SSTC_SUPPORTED & (PrivilegeModeW == P.M_MODE | (MCOUNTEREN_REGW[1] & ENVCFG_STCE)); csrs #(P) csrs(.clk, .reset, - .CSRSWriteM, .STrapM, .CSRAdrM, + .CSRSWriteM, .STrapM, .CSRAdrM(CSRAdrDM), .NextEPCM, .NextCauseM, .NextMtvalM, .SSTATUS_REGW, .STATUS_TVM, - .CSRWriteValM, .PrivilegeModeW, + .CSRWriteValM(CSRWriteValDM), .PrivilegeModeW, .CSRSReadValM, .STVEC_REGW, .SEPC_REGW, .SCOUNTEREN_REGW, .SATP_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MTIME_CLINT, .STCE, @@ -268,7 +272,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( // Floating Point CSRs in User Mode only needed if Floating Point is supported if (P.F_SUPPORTED | P.D_SUPPORTED) begin:csru csru #(P) csru(.clk, .reset, .InstrValidNotFlushedM, - .CSRUWriteM, .CSRAdrM, .CSRWriteValM, .STATUS_FS, .CSRUReadValM, + .CSRUWriteM, .CSRAdrM(CSRAdrDM), .CSRWriteValM(CSRWriteValDM), .STATUS_FS, .CSRUReadValM, .SetFflagsM, .FRM_REGW, .WriteFRMM, .WriteFFLAGSM, .IllegalCSRUAccessM); end else begin @@ -283,7 +287,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( .BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM, .BPWrongM, .IClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .sfencevmaM, .InterruptM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE, - .CSRAdrM, .PrivilegeModeW, .CSRWriteValM, + .CSRAdrM(CSRAdrDM), .PrivilegeModeW, .CSRWriteValM(CSRWriteValDM), .MCOUNTINHIBIT_REGW, .MCOUNTEREN_REGW, .SCOUNTEREN_REGW, .MTIME_CLINT, .CSRCReadValM, .IllegalCSRCAccessM); end else begin @@ -308,9 +312,23 @@ module csr import cvw::*; #(parameter cvw_t P) ( flopenrc #(P.XLEN) CSRValWReg(clk, reset, FlushW, ~StallW, CSRReadValM, CSRReadValW); // merge illegal accesses: illegal if none of the CSR addresses is legal or privilege is insufficient - assign InsufficientCSRPrivilegeM = (CSRAdrM[9:8] == 2'b11 & PrivilegeModeW != P.M_MODE) | - (CSRAdrM[9:8] == 2'b01 & PrivilegeModeW == P.U_MODE); + // TODO: ignore/modify this check when in debug mode + assign InsufficientCSRPrivilegeM = (CSRAdrDM[9:8] == 2'b11 & PrivilegeModeW != P.M_MODE) | + (CSRAdrDM[9:8] == 2'b01 & PrivilegeModeW == P.U_MODE); assign IllegalCSRAccessM = ((IllegalCSRCAccessM & IllegalCSRMAccessM & IllegalCSRSAccessM & IllegalCSRUAccessM | InsufficientCSRPrivilegeM) & CSRReadM) | IllegalCSRMWriteReadonlyM; + + // Debug module CSR access + // TODO: should DM be able to access CSRs when hart isn't in M mode? + if (P.DEBUG_SUPPORTED) begin + assign CSRAdrDM = DebugSel ? DebugRegAddr : CSRAdrM; + //assign CSRMWriteDM = DebugSel ? DebugRegUpdate : CSRMWriteM; // TODO: add write support + assign CSRWriteValDM = DebugSel ? DebugCSRScanVal : CSRWriteValM; + flopenrs #(P.XLEN) GPScanReg(.clk, .reset, .en(DebugCapture), .d(CSRReadValM), .q(DebugCSRScanVal), .scan(DebugScanEn), .scanin(DebugScanIn), .scanout(DebugScanOut)); + end else begin + assign CSRAdrDM = CSRAdrM; + //assign CSRMWriteDM = CSRMWriteM; + assign CSRWriteValDM = CSRWriteValM; + end endmodule diff --git a/src/privileged/csrm.sv b/src/privileged/csrm.sv index 10d65224a..692ead2b2 100644 --- a/src/privileged/csrm.sv +++ b/src/privileged/csrm.sv @@ -49,20 +49,17 @@ module csrm import cvw::*; #(parameter cvw_t P) ( output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0], output logic WriteMSTATUSM, WriteMSTATUSHM, output logic IllegalCSRMAccessM, IllegalCSRMWriteReadonlyM, - output logic [63:0] MENVCFG_REGW, - // Debug scan chain - input logic DebugCapture, - input logic DebugScanEn, - input logic DebugScanIn, - output logic DebugScanOut + output logic [63:0] MENVCFG_REGW ); - logic [P.XLEN-1:0] MISA_REGW, MHARTID_REGW, DCSR_REGW, DPC_REGW; + logic [P.XLEN-1:0] MISA_REGW, MHARTID_REGW; logic [P.XLEN-1:0] MSCRATCH_REGW, MTVAL_REGW, MCAUSE_REGW; logic [P.XLEN-1:0] MENVCFGH_REGW; logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM; logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM; logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM; + logic [31:0] DCSR_REGW, DPC_REGW; + logic WriteDPCM, WriteDCSRM; // Machine CSRs localparam MVENDORID = 12'hF11; @@ -136,13 +133,8 @@ module csrm import cvw::*; #(parameter cvw_t P) ( // MISA is hardwired. Spec says it could be written to disable features, but this is not supported by Wally assign MISA_REGW = {(P.XLEN == 32 ? 2'b01 : 2'b10), {(P.XLEN-28){1'b0}}, MISA_26[25:0]}; // Debug registers (stubbed out) - assign DPC_REGW = {P.XLEN{1'b0}}; - assign DCSR_REGW = {P.XLEN{1'b0}}; - - // Dummy register to provide MISA read access to DM - if (P.DEBUG_SUPPORTED) begin - flopenrs #(P.XLEN) MISAScanReg (.clk, .reset, .en(DebugCapture), .d(MISA_REGW), .q(), .scan(DebugScanEn), .scanin(DebugScanIn), .scanout(DebugScanOut)); - end + assign DPC_REGW = {32'hd099f00d}; + assign DCSR_REGW = {32'hdeadbeef}; // MHARTID is hardwired. It only exists as a signal so that the testbench can easily see it. assign MHARTID_REGW = '0; @@ -159,11 +151,10 @@ module csrm import cvw::*; #(parameter cvw_t P) ( assign WriteMTVALM = MTrapM | (CSRMWriteM & (CSRAdrM == MTVAL)); assign WriteMCOUNTERENM = CSRMWriteM & (CSRAdrM == MCOUNTEREN); assign WriteMCOUNTINHIBITM = CSRMWriteM & (CSRAdrM == MCOUNTINHIBIT); + assign WriteDPCM = CSRMWriteM & (CSRAdrM == DPC); + assign WriteDCSRM = CSRMWriteM & (CSRAdrM == DCSR); - assign WriteDPC = CSRMWriteM & (CSRAdrM == DPC); - assign WriteDCSR = CSRMWriteM & (CSRAdrM == DCSR); - - assign IllegalCSRMWriteReadonlyM = UngatedCSRMWriteM & (CSRAdrM == MVENDORID | CSRAdrM == MARCHID | CSRAdrM == MIMPID | CSRAdrM == MHARTID | CSRAdrM == MCONFIGPTR); + assign IllegalCSRMWriteReadonlyM = UngatedCSRMWriteM & (CSRAdrM == MVENDORID | CSRAdrM == MARCHID | CSRAdrM == MIMPID | CSRAdrM == MHARTID | CSRAdrM == MCONFIGPTR); // TODO: add DPC // CSRs flopenr #(P.XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[P.XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW); @@ -180,6 +171,12 @@ module csrm import cvw::*; #(parameter cvw_t P) ( if (P.U_SUPPORTED) begin: mcounteren // MCOUNTEREN only exists when user mode is supported flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], MCOUNTEREN_REGW); end else assign MCOUNTEREN_REGW = '0; + if (P.DEBUG_SUPPORTED) begin + //flopenr #(32) DPCreg(clk, reset, WriteDPCM, CSRWriteValM[31:0], DPC_REGW); // TODO: update DPC from PC (M?) + //flopenr #(32) DCSRreg(clk, reset, WriteDCSRM, CSRWriteValM[31:0], DCSR_REGW); // TODO: control writes to DCSR + end else begin + assign {DPC_REGW,DCSR_REGW} = '0; + end // MENVCFG register if (P.U_SUPPORTED) begin // menvcfg only exists if there is a lower privilege to control @@ -256,8 +253,10 @@ module csrm import cvw::*; #(parameter cvw_t P) ( MENVCFGH: if (P.U_SUPPORTED & P.XLEN==32) CSRMReadValM = MENVCFGH_REGW; else IllegalCSRMAccessM = 1'b1; MCOUNTINHIBIT: CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTINHIBIT_REGW}; - DCSR: CSRMReadValM = DCSR_REGW; - DPC: CSRMReadValM = DPC_REGW; + DCSR: if (P.DEBUG_SUPPORTED) CSRMReadValM = DCSR_REGW; + else IllegalCSRMAccessM = 1'b1; + DPC: if (P.DEBUG_SUPPORTED) CSRMReadValM = DPC_REGW; + else IllegalCSRMAccessM = 1'b1; default: IllegalCSRMAccessM = 1'b1; endcase end diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index 9c8cc40e9..e1fada421 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -98,7 +98,10 @@ module privileged import cvw::*; #(parameter cvw_t P) ( // Fault outputs output logic wfiM, IntPendingM, // Stall in Memory stage for WFI until interrupt pending or timeout // Debug scan chain + input logic DebugSel, + input logic [11:0] DebugRegAddr, input logic DebugCapture, + input logic DebugRegUpdate, input logic DebugScanEn, input logic DebugScanIn, output logic DebugScanOut @@ -153,7 +156,7 @@ module privileged import cvw::*; #(parameter cvw_t P) ( .SetFflagsM, .FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .ENVCFG_ADUE, .EPCM, .TrapVectorM, .CSRReadValW, .IllegalCSRAccessM, .BigEndianM, - .DebugCapture, .DebugScanEn, .DebugScanIn, .DebugScanOut); + .DebugSel, .DebugRegAddr, .DebugCapture, .DebugRegUpdate, .DebugScanEn, .DebugScanIn, .DebugScanOut); // pipeline early-arriving trap sources privpiperegs ppr(.clk, .reset, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index 44a0ed818..0445cd961 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -28,39 +28,38 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( - input logic clk, reset, + input logic clk, reset, // Privileged - input logic MTimerInt, MExtInt, SExtInt, MSwInt, - input logic [63:0] MTIME_CLINT, + input logic MTimerInt, MExtInt, SExtInt, MSwInt, + input logic [63:0] MTIME_CLINT, // Bus Interface - input logic [P.AHBW-1:0] HRDATA, - input logic HREADY, HRESP, - output logic HCLK, HRESETn, - output logic [P.PA_BITS-1:0] HADDR, - output logic [P.AHBW-1:0] HWDATA, - output logic [P.XLEN/8-1:0] HWSTRB, - output logic HWRITE, - output logic [2:0] HSIZE, - output logic [2:0] HBURST, - output logic [3:0] HPROT, - output logic [1:0] HTRANS, - output logic HMASTLOCK, - input logic DebugStall, + input logic [P.AHBW-1:0] HRDATA, + input logic HREADY, HRESP, + output logic HCLK, HRESETn, + output logic [P.PA_BITS-1:0] HADDR, + output logic [P.AHBW-1:0] HWDATA, + output logic [P.XLEN/8-1:0] HWSTRB, + output logic HWRITE, + output logic [2:0] HSIZE, + output logic [2:0] HBURST, + output logic [3:0] HPROT, + output logic [1:0] HTRANS, + output logic HMASTLOCK, + input logic DebugStall, // Debug scan chain - input logic DebugScanEn, - input logic DebugScanIn, - output logic DebugScanOut, - input logic GPRSel, - input logic DebugCapture, - input logic DebugRegUpdate, - input logic [4:0] RegAddr, - input logic GPRScanEn, - input logic GPRScanIn, - output logic GPRScanOut, - input logic FPRSel, - input logic FPRScanEn, - input logic FPRScanIn, - output logic FPRScanOut + input logic DebugScanEn, // puts scannable flops into scan mode + output logic DebugScanOut, // (misc) scan chain data out + output logic GPRScanOut, // (GPR) scan chain data out + output logic FPRScanOut, // (FPR) scan chain data out + output logic CSRScanOut, // (CSR) scan chain data out + input logic DebugScanIn, // scan chain data in + input logic MiscSel, // selects general scan chain + input logic GPRSel, // selects GPR scan chain + input logic FPRSel, // selects FPR scan chain + input logic CSRSel, // selects CSR scan chain + input logic [11:0] DebugRegAddr, // address for scanable regfiles (GPR, FPR, CSR) + input logic DebugCapture, // latches values into scan register before scanning out + input logic DebugRegUpdate // writes values from scan register after scanning in ); logic StallF, StallD, StallE, StallM, StallW; @@ -185,7 +184,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( logic wfiM, IntPendingM; // Debug register scan chain interconnects - logic [3:0] ScanReg; + logic [2:0] ScanReg; // instruction fetch unit: PC, branch prediction, instruction cache ifu #(P) ifu(.clk, .reset, @@ -209,7 +208,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE, .ITLBWriteF, .sfencevmaM, .ITLBMissF, // pmp/pma (inside mmu) signals. .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .InstrAccessFaultF, .InstrUpdateDAF, - .DebugScanEn, .DebugScanIn(ScanReg[1]), .DebugScanOut(ScanReg[2])); + .DebugScanEn(DebugScanEn & MiscSel), .DebugScanIn(ScanReg[0]), .DebugScanOut(ScanReg[1])); // integer execution unit: integer register file, datapath and controller ieu #(P) ieu(.clk, .reset, @@ -235,8 +234,8 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .StructuralStallD, .LoadStallD, .StoreStallD, .PCSrcE, .CSRReadM, .CSRWriteM, .PrivilegedM, .CSRWriteFenceM, .InvalidateICacheM, - .DebugScanEn, .DebugScanIn(ScanReg[2]), .DebugScanOut(ScanReg[3]), - .GPRSel, .DebugCapture, .DebugRegUpdate, .RegAddr, .GPRScanEn, .GPRScanIn, .GPRScanOut); + .DebugScanEn, .DebugScanIn(ScanReg[1]), .GPRScanIn(DebugScanIn), .DebugScanOut(ScanReg[2]), .GPRScanOut, + .MiscSel, .GPRSel, .DebugCapture, .DebugRegUpdate, .DebugRegAddr(DebugRegAddr[4:0])); lsu #(P) lsu( .clk, .reset, .StallM, .FlushM, .StallW, .FlushW, @@ -272,7 +271,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .StoreAmoAccessFaultM, // connects to privilege .InstrUpdateDAF, .PCSpillF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, .SelHPTW, - .LSUStallM, .DebugCapture, .DebugScanEn, .DebugScanIn(ScanReg[3]), .DebugScanOut); + .LSUStallM, .DebugCapture, .DebugScanEn(DebugScanEn & MiscSel), .DebugScanIn(ScanReg[2]), .DebugScanOut); if(P.BUS_SUPPORTED) begin : ebu ebu #(P) ebu(// IFU connections @@ -326,9 +325,9 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .ENVCFG_ADUE, .wfiM, .IntPendingM, .BigEndianM, - .DebugCapture, .DebugScanEn, .DebugScanIn, .DebugScanOut(ScanReg[0])); + .DebugSel(CSRSel), .DebugRegAddr, .DebugCapture, .DebugRegUpdate, .DebugScanEn(DebugScanEn & CSRSel), .DebugScanIn, .DebugScanOut(CSRScanOut)); if (P.DEBUG_SUPPORTED) begin - flopenrs #(1) scantrapm (.clk, .reset, .en(DebugCapture), .d(TrapM), .q(), .scan(DebugScanEn), .scanin(ScanReg[0]), .scanout(ScanReg[1])); + flopenrs #(1) scantrapm (.clk, .reset, .en(DebugCapture), .d(TrapM), .q(), .scan(DebugScanEn), .scanin(DebugScanIn), .scanout(ScanReg[0])); end end else begin assign {CSRReadValW, PrivilegeModeW, @@ -337,7 +336,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( ENVCFG_CBE, ENVCFG_PBMTE, ENVCFG_ADUE, EPCM, TrapVectorM, RetM, TrapM, sfencevmaM, BigEndianM, wfiM, IntPendingM} = '0; - assign ScanReg[1] = ScanReg[0]; + assign ScanReg[0] = DebugScanIn; end // multiply/divide unit @@ -377,13 +376,13 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .IllegalFPUInstrD, // Is the instruction an illegal fpu instruction .SetFflagsM, // FPU flags (to privileged unit) .FIntDivResultW, - .FPRSel, + .DebugSel(FPRSel), + .DebugRegAddr(DebugRegAddr[4:0]), .DebugCapture, .DebugRegUpdate, - .RegAddr, - .FPRScanEn, - .FPRScanIn, - .FPRScanOut); + .DebugScanEn(DebugScanEn & FPRSel), + .DebugScanIn, + .DebugScanOut(FPRScanOut)); end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low assign {FPUStallD, FWriteIntE, FCvtIntE, FIntResM, FCvtIntW, IllegalFPUInstrD, SetFflagsM, FpLoadStoreM, diff --git a/src/wally/wallypipelinedsoc.sv b/src/wally/wallypipelinedsoc.sv index b3b8166ca..c4f104668 100644 --- a/src/wally/wallypipelinedsoc.sv +++ b/src/wally/wallypipelinedsoc.sv @@ -76,20 +76,19 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( // Debug Module signals logic NdmReset; logic DebugStall; - logic ScanEn; - logic ScanIn; - logic ScanOut; + logic DebugScanEn; + logic DebugScanIn; + logic GPRScanIn; + logic FPRScanIn; + logic CSRScanIn; + logic DebugScanOut; + logic MiscSel; logic GPRSel; + logic FPRSel; + logic CSRSel; + logic [11:0] DebugRegAddr; logic DebugCapture; logic DebugRegUpdate; - logic [4:0] RegAddr; - logic GPRScanEn; - logic GPRScanIn; - logic GPRScanOut; - logic FPRSel; - logic FPRScanEn; - logic FPRScanIn; - logic FPRScanOut; // synchronize reset to SOC clock domain synchronizer resetsync(.clk, .d(reset_ext), .q(reset)); @@ -99,9 +98,8 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( .MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT, .HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, - .DebugStall, .DebugScanEn(ScanEn), .DebugScanIn(ScanOut), .DebugScanOut(ScanIn), - .GPRSel, .DebugCapture, .DebugRegUpdate, .RegAddr, .GPRScanEn, .GPRScanIn(GPRScanOut), .GPRScanOut(GPRScanIn), - .FPRSel, .FPRScanEn, .FPRScanIn(FPRScanOut), .FPRScanOut(FPRScanIn)); + .DebugStall, .DebugScanEn, .DebugScanOut(DebugScanIn), .GPRScanOut(GPRScanIn), .FPRScanOut(FPRScanIn), .CSRScanOut(CSRScanIn), + .DebugScanIn(DebugScanOut), .MiscSel, .GPRSel, .FPRSel, .CSRSel, .DebugRegAddr, .DebugCapture, .DebugRegUpdate); // instantiate uncore if a bus interface exists if (P.BUS_SUPPORTED) begin : uncoregen // Hack to work around Verilator bug https://github.com/verilator/verilator/issues/4769 @@ -117,13 +115,9 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( // instantiate debug module if (P.DEBUG_SUPPORTED) begin : dm - dm #(P) dm (.clk, .rst(reset), .NdmReset, .tck, .tdi, .tms, .tdo, - .DebugStall, .ScanEn, .ScanIn, .ScanOut, .GPRSel, .DebugCapture, .DebugRegUpdate, - .RegAddr, .GPRScanEn, .GPRScanIn, .GPRScanOut, .FPRSel, - .FPRScanEn, .FPRScanIn, .FPRScanOut); - end else begin - assign {NdmReset, DebugStall, ScanOut, GPRSel, DebugCapture, DebugRegUpdate, RegAddr, GPRScanEn, GPRScanOut, - FPRSel, FPRScanEn, FPRScanOut} = '0; + dm #(P) dm (.clk, .rst(reset), .tck, .tdi, .tms, .tdo, .NdmReset, .DebugStall, + .DebugScanEn, .DebugScanIn, .GPRScanIn, .FPRScanIn, .CSRScanIn, .DebugScanOut, + .MiscSel, .GPRSel, .FPRSel, .CSRSel, .RegAddr(DebugRegAddr), .DebugCapture, .DebugRegUpdate); end endmodule