From 4c921fc79728b68806acf46558378a1280893e55 Mon Sep 17 00:00:00 2001 From: David Harris Date: Sun, 2 Jul 2023 13:29:27 -0700 Subject: [PATCH] Added logic to warn about x in memory reads. Added cbo instruction names to testbench decoder --- testbench/common/instrNameDecTB.sv | 16 ++++++++-- testbench/common/ramxdetector.sv | 45 +++++++++++++++++++++++++++++ testbench/common/riscvassertions.sv | 3 ++ testbench/testbench.sv | 22 ++++++++------ 4 files changed, 74 insertions(+), 12 deletions(-) create mode 100644 testbench/common/ramxdetector.sv diff --git a/testbench/common/instrNameDecTB.sv b/testbench/common/instrNameDecTB.sv index 1529de5e6..8f6fbe869 100644 --- a/testbench/common/instrNameDecTB.sv +++ b/testbench/common/instrNameDecTB.sv @@ -30,13 +30,14 @@ module instrNameDecTB( logic [2:0] funct3; logic [6:0] funct7; logic [11:0] imm; - logic [4:0] rs2; + logic [4:0] rs2, rd; assign op = instr[6:0]; assign funct3 = instr[14:12]; assign funct7 = instr[31:25]; assign imm = instr[31:20]; assign rs2 = instr[24:20]; + assign rd = instr[11:7]; // it would be nice to add the operands to the name // create another variable called decoded @@ -77,7 +78,10 @@ module instrNameDecTB( else if (funct7[6:1] == 6'b010010) name = "BEXTI"; else if (funct7 == 7'b0010100 & rs2 == 5'b00111) name = "ORC.B"; else name = "ILLEGAL"; - 10'b0010011_110: name = "ORI"; + 10'b0010011_110: if (rd == 0 & rs2 == 0) name = "PREFETCH.I"; + else if (rd == 0 & rs2 == 1) name = "PREFETCH.R"; + else if (rd == 0 & rs2 == 3) name = "PREFETCH.W"; + else name = "ORI"; 10'b0010011_111: name = "ANDI"; 10'b0010111_???: name = "AUIPC"; 10'b0100011_000: name = "SB"; @@ -215,7 +219,13 @@ module instrNameDecTB( else if (funct7[6:2] == 5'b11000) name = "AMOMINU.D"; else if (funct7[6:2] == 5'b11100) name = "AMOMAXU.D"; else name = "ILLEGAL"; - 10'b0001111_???: name = "FENCE"; + 10'b0001111_000: name = "FENCE"; + 10'b0001111_001: name = "FENCE.I"; + 10'b0001111_010: if (instr[31:20] == 12'd0) name = "CBO.INVAL"; + else if (instr[31:20] == 12'd1) name = "CBO.CLEAN"; + else if (instr[31:20] == 12'd2) name = "CBO.FLUSH"; + else if (instr[31:20] == 12'd4) name = "CBO.ZERO"; + else name = "ILLEGAL"; 10'b1000011_???: name = "FMADD"; 10'b1000111_???: name = "FMSUB"; 10'b1001011_???: name = "FNMSUB"; diff --git a/testbench/common/ramxdetector.sv b/testbench/common/ramxdetector.sv new file mode 100644 index 000000000..987bbefea --- /dev/null +++ b/testbench/common/ramxdetector.sv @@ -0,0 +1,45 @@ +/////////////////////////////////////////// +// ramxdetector.sv +// +// Written: David_Harris@hmc.edu +// Modified: 2 July 2023 +// +// Purpose: Detects if the processor is attempting to read unitialized RAM +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 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 +// 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 +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module ramxdetector #(parameter XLEN, LLEN) ( + input logic clk, + input logic MemReadM, + input logic LSULoadAccessFaultM, + input logic [LLEN-1:0] ReadDataM, + input logic [XLEN-1:0] PCM, + input logic [31:0] InstrM, + input logic [XLEN-1:0] IEUAdrM, + input string InstrMName +); + + always_ff @(posedge clk) + if (MemReadM & ~LSULoadAccessFaultM & (ReadDataM === 'bx)) begin + $display("WARNING: Attempting to read from unitialized RAM. Processor may go haywire if it uses x value. But this is normal in WALLY-mmu tests."); + $display(" PCM = %x InstrM = %x (%s), IEUAdrM = %x", PCM, InstrM, InstrMName, IEUAdrM); + //$stop; + end + +endmodule diff --git a/testbench/common/riscvassertions.sv b/testbench/common/riscvassertions.sv index 50577c37d..d1007ec41 100644 --- a/testbench/common/riscvassertions.sv +++ b/testbench/common/riscvassertions.sv @@ -58,6 +58,9 @@ module riscvassertions import cvw::*; #(parameter cvw_t P); assert ((P.ZMMUL_SUPPORTED == 0) || (P.M_SUPPORTED ==0)) else $error("At most one of ZMMUL_SUPPORTED and M_SUPPORTED can be enabled"); assert ((P.ZICNTR_SUPPORTED == 0) || (P.ZICSR_SUPPORTED == 1)) else $error("ZICNTR_SUPPORTED requires ZICSR_SUPPORTED"); assert ((P.ZIHPM_SUPPORTED == 0) || (P.ZICNTR_SUPPORTED == 1)) else $error("ZIPHM_SUPPORTED requires ZICNTR_SUPPORTED"); + assert ((P.ZICBOM_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $error("ZICBOM required DCACHE_SUPPORTED"); + assert ((P.ZICBOZ_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $error("ZICBOZ required DCACHE_SUPPORTED"); + assert ((P.ZICBOP_SUPPORTED == 0) || (P.DCACHE_SUPPORTED == 1)) else $error("ZICBOP required DCACHE_SUPPORTED"); end endmodule diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 4cab1a105..a41d61217 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -409,7 +409,20 @@ module testbench; // Support logic //////////////////////////////////////////////////////////////////////////////// + // Track names of instructions + string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; + logic [31:0] InstrW; + flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.InstrM, InstrW); + instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE, + dut.core.ifu.InstrRawF[31:0], + dut.core.ifu.InstrD, dut.core.ifu.InstrE, + dut.core.ifu.InstrM, InstrW, + InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); + + // watch for problems such as lockup, reading unitialized memory, bad configs watchdog #(P.XLEN, 1000000) watchdog(.clk, .reset); // check if PCW is stuck + ramxdetector #(P.XLEN, P.LLEN) ramxdetector(clk, dut.core.lsu.MemRWM[1], dut.core.lsu.LSULoadAccessFaultM, dut.core.lsu.ReadDataM, + dut.core.ifu.PCM, dut.core.ifu.InstrM, dut.core.lsu.IEUAdrM, InstrMName); riscvassertions #(P) riscvassertions(); // check assertions for a legal configuration loggers #(P, TEST, PrintHPMCounters, I_CACHE_ADDR_LOGGER, D_CACHE_ADDR_LOGGER, BPRED_LOGGER) loggers (clk, reset, DCacheFlushStart, DCacheFlushDone, memfilename); @@ -420,15 +433,6 @@ module testbench; .clk(clk), .ProgramAddrMapFile(ProgramAddrMapFile), .ProgramLabelMapFile(ProgramLabelMapFile)); end - // Track names of instructions - string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; - logic [31:0] InstrW; - flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.InstrM, InstrW); - instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE, - dut.core.ifu.InstrRawF[31:0], - dut.core.ifu.InstrD, dut.core.ifu.InstrE, - dut.core.ifu.InstrM, InstrW, - InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); // Termination condition // terminate on a specific ECALL after li x3,1 for old Imperas tests, *** remove this when old imperas tests are removed