From b93a37cdb661093556761edc7ddc63748bab9ecd Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Thu, 21 Jan 2021 16:17:34 -0500 Subject: [PATCH 01/14] copy testbench to modify for busybear --- wally-pipelined/src/testbench-busybear.sv | 475 ++++++++++++++++++++++ wally-pipelined/wally-busybear.do | 91 +++++ 2 files changed, 566 insertions(+) create mode 100644 wally-pipelined/src/testbench-busybear.sv create mode 100644 wally-pipelined/wally-busybear.do diff --git a/wally-pipelined/src/testbench-busybear.sv b/wally-pipelined/src/testbench-busybear.sv new file mode 100644 index 000000000..e28253dc4 --- /dev/null +++ b/wally-pipelined/src/testbench-busybear.sv @@ -0,0 +1,475 @@ +/////////////////////////////////////////// +// testbench.sv +// +// Written: David_Harris@hmc.edu 9 January 2021 +// Modified: +// +// Purpose: Wally Testbench and helper modules +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-macros.sv" + +module testbench_busybear #(parameter XLEN=64, MISA=32'h00000104, ZCSR = 1, ZCOUNTERS = 1)(); + logic clk; + logic reset; + + logic [XLEN-1:0] WriteData, DataAdr; + logic [1:0] MemRW; + + int test, i, errors, totalerrors; + logic [31:0] sig32[0:10000]; + logic [XLEN-1:0] signature[0:10000]; + logic [XLEN-1:0] testadr; + string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; + logic [31:0] InstrW; + logic [XLEN-1:0] meminit; + string tests64ic[] = '{ + + "rv64ic/I-C-ADD-01", "3000", + "rv64ic/I-C-ADDI-01", "3000", + "rv64ic/I-C-ADDIW-01", "3000", + "rv64ic/I-C-ADDW-01", "3000", + "rv64ic/I-C-AND-01", "3000", + "rv64ic/I-C-ANDI-01", "3000", + "rv64ic/I-C-BEQZ-01", "3000", + "rv64ic/I-C-BNEZ-01", "3000", + "rv64ic/I-C-EBREAK-01", "2000", + "rv64ic/I-C-J-01", "3000", + "rv64ic/I-C-JALR-01", "4000", + "rv64ic/I-C-JR-01", "4000", + "rv64ic/I-C-LD-01", "3420", + "rv64ic/I-C-LDSP-01", "3420", + "rv64ic/I-C-LI-01", "3000", + "rv64ic/I-C-LUI-01", "2000", + "rv64ic/I-C-LW-01", "3110", + "rv64ic/I-C-LWSP-01", "3110", + "rv64ic/I-C-MV-01", "3000", + "rv64ic/I-C-NOP-01", "2000", + "rv64ic/I-C-OR-01", "3000", + "rv64ic/I-C-SD-01", "3000", + "rv64ic/I-C-SDSP-01", "3000", + "rv64ic/I-C-SLLI-01", "3000", + "rv64ic/I-C-SRAI-01", "3000", + "rv64ic/I-C-SRLI-01", "3000", + "rv64ic/I-C-SUB-01", "3000", + "rv64ic/I-C-SUBW-01", "3000", + "rv64ic/I-C-SW-01", "3000", + "rv64ic/I-C-SWSP-01", "3000", + "rv64ic/I-C-XOR-01", "3000" + }; +string tests64iNOc[] = { + "rv64i/I-MISALIGN_JMP-01","2000" + }; + string tests64i[] = '{ + "rv64i/I-ADD-01", "3000", + "rv64i/I-ADDI-01", "3000", + "rv64i/I-ADDIW-01", "3000", + "rv64i/I-ADDW-01", "3000", + "rv64i/I-AND-01", "3000", + "rv64i/I-ANDI-01", "3000", + "rv64i/I-AUIPC-01", "3000", + "rv64i/I-BEQ-01", "4000", + "rv64i/I-BGE-01", "4000", + "rv64i/I-BGEU-01", "4000", + "rv64i/I-BLT-01", "4000", + "rv64i/I-BLTU-01", "4000", + "rv64i/I-BNE-01", "4000", + "rv64i/I-DELAY_SLOTS-01", "2000", + "rv64i/I-EBREAK-01", "2000", + "rv64i/I-ECALL-01", "2000", + "rv64i/I-ENDIANESS-01", "2010", + "rv64i/I-IO-01", "2050", + "rv64i/I-JAL-01", "3000", + "rv64i/I-JALR-01", "4000", + "rv64i/I-LB-01", "4020", + "rv64i/I-LBU-01", "4020", + "rv64i/I-LD-01", "4420", + "rv64i/I-LH-01", "4050", + "rv64i/I-LHU-01", "4050", + "rv64i/I-LUI-01", "2000", + "rv64i/I-LW-01", "4110", + "rv64i/I-LWU-01", "4110", + "rv64i/I-MISALIGN_LDST-01", "2010", + "rv64i/I-NOP-01", "2000", + "rv64i/I-OR-01", "3000", + "rv64i/I-ORI-01", "3000", + "rv64i/I-RF_size-01", "2000", + "rv64i/I-RF_width-01", "2000", + "rv64i/I-RF_x0-01", "2010", + "rv64i/I-SB-01", "4000", + "rv64i/I-SD-01", "4000", + "rv64i/I-SH-01", "4000", + "rv64i/I-SLL-01", "3000", + "rv64i/I-SLLI-01", "3000", + "rv64i/I-SLLIW-01", "3000", + "rv64i/I-SLLW-01", "3000", + "rv64i/I-SLT-01", "3000", + "rv64i/I-SLTI-01", "3000", + "rv64i/I-SLTIU-01", "3000", + "rv64i/I-SLTU-01", "3000", + "rv64i/I-SRA-01", "3000", + "rv64i/I-SRAI-01", "3000", + "rv64i/I-SRAIW-01", "3000", + "rv64i/I-SRAW-01", "3000", + "rv64i/I-SRL-01", "3000", + "rv64i/I-SRLI-01", "3000", + "rv64i/I-SRLIW-01", "3000", + "rv64i/I-SRLW-01", "3000", + "rv64i/I-SUB-01", "3000", + "rv64i/I-SUBW-01", "3000", + "rv64i/I-SW-01", "4000", + "rv64i/I-XOR-01", "3000", + "rv64i/I-XORI-01", "3000", + "rv64i/WALLY-ADD", "4000", + "rv64i/WALLY-SUB", "4000" + }; +string tests32ic[] = '{ +// "rv32ic/WALLY-C-ADHOC-01", "2000", + "rv32ic/I-C-ADD-01", "2000", + "rv32ic/I-C-ADDI-01", "2000", + "rv32ic/I-C-AND-01", "2000", + "rv32ic/I-C-ANDI-01", "2000", + "rv32ic/I-C-BEQZ-01", "2000", + "rv32ic/I-C-BNEZ-01", "2000", + "rv32ic/I-C-EBREAK-01", "2000", + "rv32ic/I-C-J-01", "2000", + "rv32ic/I-C-JALR-01", "3000", + "rv32ic/I-C-JR-01", "3000", + "rv32ic/I-C-LI-01", "2000", + "rv32ic/I-C-LUI-01", "2000", + "rv32ic/I-C-LW-01", "2110", + "rv32ic/I-C-LWSP-01", "2110", + "rv32ic/I-C-MV-01", "2000", + "rv32ic/I-C-NOP-01", "2000", + "rv32ic/I-C-OR-01", "2000", + "rv32ic/I-C-SLLI-01", "2000", + "rv32ic/I-C-SRAI-01", "2000", + "rv32ic/I-C-SRLI-01", "2000", + "rv32ic/I-C-SUB-01", "2000", + "rv32ic/I-C-SW-01", "2000", + "rv32ic/I-C-SWSP-01", "2000", + "rv32ic/I-C-XOR-01", "2000" +}; +string tests32iNOc[] = { + "rv32i/I-MISALIGN_JMP-01","2000" +}; +string tests32i[] = { + "rv32i/I-ADD-01", "2000", + "rv32i/I-ADDI-01","2000", + "rv32i/I-AND-01","2000", + "rv32i/I-ANDI-01","2000", + "rv32i/I-AUIPC-01","2000", + "rv32i/I-BEQ-01","3000", + "rv32i/I-BGE-01","3000", + "rv32i/I-BGEU-01","3000", + "rv32i/I-BLT-01","3000", + "rv32i/I-BLTU-01","3000", + "rv32i/I-BNE-01","3000", + "rv32i/I-DELAY_SLOTS-01","2000", + "rv32i/I-EBREAK-01","2000", + "rv32i/I-ECALL-01","2000", + "rv32i/I-ENDIANESS-01","2010", + "rv32i/I-IO-01","2030", + "rv32i/I-JAL-01","3000", + "rv32i/I-JALR-01","3000", + "rv32i/I-LB-01","3020", + "rv32i/I-LBU-01","3020", + "rv32i/I-LH-01","3050", + "rv32i/I-LHU-01","3050", + "rv32i/I-LUI-01","2000", + "rv32i/I-LW-01","3110", + "rv32i/I-MISALIGN_LDST-01","2010", + "rv32i/I-NOP-01","2000", + "rv32i/I-OR-01","2000", + "rv32i/I-ORI-01","2000", + "rv32i/I-RF_size-01","2000", + "rv32i/I-RF_width-01","2000", + "rv32i/I-RF_x0-01","2010", + "rv32i/I-SB-01","3000", + "rv32i/I-SH-01","3000", + "rv32i/I-SLL-01","2000", + "rv32i/I-SLLI-01","2000", + "rv32i/I-SLT-01","2000", + "rv32i/I-SLTI-01","2000", + "rv32i/I-SLTIU-01","2000", + "rv32i/I-SLTU-01","2000", + "rv32i/I-SRA-01","2000", + "rv32i/I-SRAI-01","2000", + "rv32i/I-SRL-01","2000", + "rv32i/I-SRLI-01","2000", + "rv32i/I-SUB-01","2000", + "rv32i/I-SW-01","3000", + "rv32i/I-XOR-01","2000", + "rv32i/I-XORI-01","2000", + "rv32i/WALLY-ADD", "3000", + "rv32i/WALLY-SUB", "3000" +}; + string tests[]; + + // pick tests based on modes supported + initial + if (XLEN == 64) begin // RV64 + tests = {tests64i}; + if (`C_SUPPORTED % 2 == 1) tests = {tests, tests64ic}; + else tests = {tests, tests64iNOc}; + end else begin // RV32 + tests = {tests32i}; + if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic}; + else tests = {tests, tests32iNOc}; + end + string signame, memfilename; + + logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn; + + // instantiate device to be tested + assign GPIOPinsIn = 0; + wallypipelined #(XLEN, MISA, ZCSR, ZCOUNTERS) dut( + clk, reset, WriteData, DataAdr, MemRW, + GPIOPinsIn, GPIOPinsOut, GPIOPinsEn + ); + + // Track names of instructions + instrTrackerTB #(XLEN) it(clk, reset, dut.hart.dp.FlushE, + dut.hart.dp.InstrDecompD, dut.hart.dp.InstrE, + dut.hart.dp.InstrM, InstrW, + InstrDName, InstrEName, InstrMName, InstrWName); + + // initialize test + initial + begin + test = 0; + totalerrors = 0; + testadr = 0; + // fill memory with defined values to reduce Xs in simulation + if (XLEN == 32) meminit = 32'hFEDC0123; + else meminit = 64'hFEDCBA9876543210; + for (i=0; i<=65535; i = i+1) begin + //dut.imem.RAM[i] = meminit; + // dut.dmem.RAM[i] = meminit; + end + // read test vectors into memory + memfilename = {"../imperas-riscv-tests/work/", tests[test], ".elf.memfile"}; + $readmemh(memfilename, dut.imem.RAM); + $readmemh(memfilename, dut.dmem.dtim.RAM); + reset = 1; # 22; reset = 0; + end + + // generate clock to sequence tests + always + begin + clk = 1; # 5; clk = 0; # 5; + end + + // check results + always @(negedge clk) + begin + if (dut.hart.dp.priv.EcallFaultM && + (dut.hart.dp.regf.rf[3] == 1 || (dut.hart.dp.regf.we3 && dut.hart.dp.regf.a3 == 3 && dut.hart.dp.regf.wd3 == 1))) begin + $display("Code ended with ecall with gp = 1"); + #60; // give time for instructions in pipeline to finish + // clear signature to prevent contamination from previous tests + for(i=0; i<10000; i=i+1) begin + sig32[i] = 'bx; + end + + // read signature, reformat in 64 bits if necessary + signame = {"../imperas-riscv-tests/work/", tests[test], ".signature.output"}; + $readmemh(signame, sig32); + i = 0; + while (i < 10000) begin + if (XLEN == 32) begin + signature[i] = sig32[i]; + i = i+1; + end else begin + signature[i/2] = {sig32[i+1], sig32[i]}; + i = i + 2; + end + end + + // Check errors + i = 0; + errors = 0; + if (XLEN == 32) + testadr = tests[test+1].atohex()/4; + else + testadr = tests[test+1].atohex()/8; + /* verilator lint_off INFINITELOOP */ + while (signature[i] !== 'bx) begin + //$display("signature[%h] = %h", i, signature[i]); + if (signature[i] !== dut.dmem.dtim.RAM[testadr+i]) begin + if (signature[i+4] !== 'bx || signature[i] !== 32'hFFFFFFFF) begin + // report errors unless they are garbage at the end of the sim + // kind of hacky test for garbage right now + errors = errors+1; + $display(" Error on test %s result %d: adr = %h sim = %h, signature = %h", + tests[test], i, (testadr+i)*XLEN/8, dut.dmem.dtim.RAM[testadr+i], signature[i]); + end + end + i = i + 1; + end + /* verilator lint_on INFINITELOOP */ + if (errors == 0) $display("%s succeeded. Brilliant!!!", tests[test]); + else begin + $display("%s failed with %d errors. :(", tests[test], errors); + totalerrors = totalerrors+1; + end + test = test + 2; + if (test == tests.size()) begin + if (totalerrors == 0) $display("SUCCESS! All tests ran without failures."); + else $display("FAIL: %d test programs had errors", totalerrors); + $stop; + end + else begin + memfilename = {"../imperas-riscv-tests/work/", tests[test], ".elf.memfile"}; + $readmemh(memfilename, dut.imem.RAM); + $readmemh(memfilename, dut.dmem.dtim.RAM); + $display("Read memfile %s", memfilename); + reset = 1; # 17; reset = 0; + end + end + end +endmodule + +/* verilator lint_on STMTDLY */ +/* verilator lint_on WIDTH */ + +module instrTrackerTB #(parameter XLEN=32) ( + input logic clk, reset, FlushE, + input logic [31:0] InstrD, + input logic [31:0] InstrE, InstrM, + output logic [31:0] InstrW, + output string InstrDName, InstrEName, InstrMName, InstrWName); + + // stage Instr to Writeback for visualization + flopr #(32) InstrWReg(clk, reset, InstrM, InstrW); + + instrNameDecTB ddec(InstrD, InstrDName); + instrNameDecTB edec(InstrE, InstrEName); + instrNameDecTB mdec(InstrM, InstrMName); + instrNameDecTB wdec(InstrW, InstrWName); +endmodule + +// decode the instruction name, to help the test bench +module instrNameDecTB( + input logic [31:0] instr, + output string name); + + logic [6:0] op; + logic [2:0] funct3; + logic [6:0] funct7; + logic [11:0] imm; + + assign op = instr[6:0]; + assign funct3 = instr[14:12]; + assign funct7 = instr[31:25]; + assign imm = instr[31:20]; + + // it would be nice to add the operands to the name + // create another variable called decoded + + always_comb + casez({op, funct3}) + 10'b0000000_000: name = "BAD"; + 10'b0000011_000: name = "LB"; + 10'b0000011_001: name = "LH"; + 10'b0000011_010: name = "LW"; + 10'b0000011_011: name = "LD"; + 10'b0000011_100: name = "LBU"; + 10'b0000011_101: name = "LHU"; + 10'b0000011_110: name = "LWU"; + 10'b0010011_000: if (instr[31:15] == 0 && instr[11:7] ==0) name = "NOP/FLUSH"; + else name = "ADDI"; + 10'b0010011_001: if (funct7[6:1] == 6'b000000) name = "SLLI"; + else name = "ILLEGAL"; + 10'b0010011_010: name = "SLTI"; + 10'b0010011_011: name = "SLTIU"; + 10'b0010011_100: name = "XORI"; + 10'b0010011_101: if (funct7[6:1] == 6'b000000) name = "SRLI"; + else if (funct7[6:1] == 6'b010000) name = "SRAI"; + else name = "ILLEGAL"; + 10'b0010011_110: name = "ORI"; + 10'b0010011_111: name = "ANDI"; + 10'b0010111_???: name = "AUIPC"; + 10'b0100011_000: name = "SB"; + 10'b0100011_001: name = "SH"; + 10'b0100011_010: name = "SW"; + 10'b0100011_011: name = "SD"; + 10'b0011011_000: name = "ADDIW"; + 10'b0011011_001: name = "SLLIW"; + 10'b0011011_101: if (funct7 == 7'b0000000) name = "SRLIW"; + else if (funct7 == 7'b0100000) name = "SRAIW"; + else name = "ILLEGAL"; + 10'b0111011_000: if (funct7 == 7'b0000000) name = "ADDW"; + else if (funct7 == 7'b0100000) name = "SUBW"; + else name = "ILLEGAL"; + 10'b0111011_001: name = "SLLW"; + 10'b0111011_101: if (funct7 == 7'b0000000) name = "SRLW"; + else if (funct7 == 7'b0100000) name = "SRAW"; + else name = "ILLEGAL"; + 10'b0110011_000: if (funct7 == 7'b0000000) name = "ADD"; + else if (funct7 == 7'b0000001) name = "MUL"; + else if (funct7 == 7'b0100000) name = "SUB"; + else name = "ILLEGAL"; + 10'b0110011_001: if (funct7 == 7'b0000000) name = "SLL"; + else if (funct7 == 7'b0000001) name = "MULH"; + else name = "ILLEGAL"; + 10'b0110011_010: if (funct7 == 7'b0000000) name = "SLT"; + else if (funct7 == 7'b0000001) name = "MULHSU"; + else name = "ILLEGAL"; + 10'b0110011_011: if (funct7 == 7'b0000000) name = "SLTU"; + else if (funct7 == 7'b0000001) name = "DIV"; + else name = "ILLEGAL"; + 10'b0110011_100: if (funct7 == 7'b0000000) name = "XOR"; + else if (funct7 == 7'b0000001) name = "MUL"; + else name = "ILLEGAL"; + 10'b0110011_101: if (funct7 == 7'b0000000) name = "SRL"; + else if (funct7 == 7'b0000001) name = "DIVU"; + else if (funct7 == 7'b0100000) name = "SRA"; + else name = "ILLEGAL"; + 10'b0110011_110: if (funct7 == 7'b0000000) name = "OR"; + else if (funct7 == 7'b0000001) name = "REM"; + else name = "ILLEGAL"; + 10'b0110011_111: if (funct7 == 7'b0000000) name = "AND"; + else if (funct7 == 7'b0000001) name = "REMU"; + else name = "ILLEGAL"; + 10'b0110111_???: name = "LUI"; + 10'b1100011_000: name = "BEQ"; + 10'b1100011_001: name = "BNE"; + 10'b1100011_100: name = "BLT"; + 10'b1100011_101: name = "BGE"; + 10'b1100011_110: name = "BLTU"; + 10'b1100011_111: name = "BGEU"; + 10'b1100111_000: name = "JALR"; + 10'b1101111_???: name = "JAL"; + 10'b1110011_000: if (imm == 0) name = "ECALL"; + else if (imm == 1) name = "EBREAK"; + else if (imm == 2) name = "URET"; + else if (imm == 258) name = "SRET"; + else if (imm == 770) name = "MRET"; + else name = "ILLEGAL"; + 10'b1110011_001: name = "CSRRW"; + 10'b1110011_010: name = "CSRRS"; + 10'b1110011_011: name = "CSRRC"; + 10'b1110011_101: name = "CSRRWI"; + 10'b1110011_110: name = "CSRRSI"; + 10'b1110011_111: name = "CSRRCI"; + 10'b0001111_???: name = "FENCE"; + default: name = "ILLEGAL"; + endcase +endmodule diff --git a/wally-pipelined/wally-busybear.do b/wally-pipelined/wally-busybear.do new file mode 100644 index 000000000..0200698e4 --- /dev/null +++ b/wally-pipelined/wally-busybear.do @@ -0,0 +1,91 @@ +# wally-pipelined.do +# +# Modification by Oklahoma State University & Harvey Mudd College +# Use with testbench_busybear +# James Stine, 2008; David Harris 2021 +# Go Cowboys!!!!!! +# +# Takes 1:10 to run RV64IC tests using gui + +# Use this wally-pipelined.do file to run this example. +# Either bring up ModelSim and type the following at the "ModelSim>" prompt: +# do wally-pipelined.do +# or, to run from a shell, type the following at the shell prompt: +# vsim -do wally-pipelined.do -c +# (omit the "-c" to see the GUI while running from the shell) + +onbreak {resume} + +# create library +if [file exists work] { + vdel -all +} +vlib work + +# compile source files +# suppress spurious warnngs about +# "Extra checking for conflicts with always_comb done at vopt time" +# because vsim will run vopt +vlog src/*.sv -suppress 2583 + +# start and run simulation +# remove +acc flag for faster sim during regressions if there is no need to access internal signals +vopt +acc work.testbench_busybear -o workopt +vsim workopt + +view wave + +-- display input and output signals as hexidecimal values +# Diplays All Signals recursively +add wave /testbench_busybear/clk +add wave /testbench_busybear/reset +add wave -divider +add wave -hex /testbench_busybear/dut/hart/dp/PCF +add wave -hex /testbench_busybear/dut/hart/dp/InstrF +add wave /testbench_busybear/InstrFName +#add wave -hex /testbench_busybear/dut/hart/dp/PCD +add wave -hex /testbench_busybear/dut/hart/dp/InstrD +add wave /testbench_busybear/InstrDName +add wave -divider +#add wave -hex /testbench_busybear/dut/hart/dp/PCE +#add wave -hex /testbench_busybear/dut/hart/dp/InstrE +add wave /testbench_busybear/InstrEName +add wave -hex /testbench_busybear/dut/hart/dp/SrcAE +add wave -hex /testbench_busybear/dut/hart/dp/SrcBE +add wave -hex /testbench_busybear/dut/hart/dp/ALUResultE +add wave /testbench_busybear/dut/hart/dp/PCSrcE +add wave -divider +#add wave -hex /testbench_busybear/dut/hart/dp/PCM +#add wave -hex /testbench_busybear/dut/hart/dp/InstrM +add wave /testbench_busybear/InstrMName +add wave /testbench_busybear/dut/dmem/dtim/memwrite +add wave -hex /testbench_busybear/dut/dmem/AdrM +add wave -hex /testbench_busybear/dut/dmem/WriteDataM +add wave -divider +add wave -hex /testbench_busybear/dut/hart/dp/PCW +#add wave -hex /testbench_busybear/dut/hart/dp/InstrW +add wave /testbench_busybear/InstrWName +add wave /testbench_busybear/dut/hart/dp/RegWriteW +add wave -hex /testbench_busybear/dut/hart/dp/ResultW +add wave -hex /testbench_busybear/dut/hart/dp/RdW +add wave -divider +#add ww +add wave -hex -r /testbench_busybear/* + +-- Set Wave Output Items +TreeUpdate [SetDefaultTree] +WaveRestoreZoom {0 ps} {100 ps} +configure wave -namecolwidth 250 +configure wave -valuecolwidth 120 +configure wave -justifyvalue left +configure wave -signalnamewidth 0 +configure wave -snapdistance 10 +configure wave -datasetprefix 0 +configure wave -rowmargin 4 +configure wave -childrowmargin 2 +set DefaultRadix hexadecimal + +-- Run the Simulation +#run 1000 +run -all +#quit From 3f2820646d1f253ffdc9e2fb990b10c0e0ff7493 Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Thu, 21 Jan 2021 17:55:05 -0500 Subject: [PATCH 02/14] More testbench setup work - Copy bare-bones testbench from E85 - have testbench instantiate a wallypipelinedhart so we can simulate memory/peripherals easier - Create .gitignore for vsim files - Make PC reset a macro, change to 0x1000 to conform to the bootloader I don't know a good way to put the linux register trace file we're generating on git, since its both nontrivial to make and way to big to keep in a git repo for now it lives in /mnt/scratch/riscv_testbench/ --- .gitignore | 5 + wally-pipelined/src/pclogic.sv | 2 +- wally-pipelined/src/testbench-busybear.sv | 486 ++-------------------- wally-pipelined/src/wally-macros.sv | 2 + wally-pipelined/wally-busybear.do | 98 ++--- 5 files changed, 86 insertions(+), 507 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..b3169c604 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +**/work + +#vsim work files to ignore +transcript +vsim.wlf diff --git a/wally-pipelined/src/pclogic.sv b/wally-pipelined/src/pclogic.sv index bc6af619b..dfbd1b3f1 100644 --- a/wally-pipelined/src/pclogic.sv +++ b/wally-pipelined/src/pclogic.sv @@ -39,7 +39,7 @@ module pclogic #(parameter XLEN=64, MISA=0) ( logic [XLEN-1:0] UnalignedPCNextF, PCNextF, PCTargetE; // logic [XLEN-1:0] ResetVector = 'h100; // logic [XLEN-1:0] ResetVector = 'he4; - logic [XLEN-1:0] ResetVector = {{(XLEN-32){1'b0}}, 32'h80000000}; + logic [XLEN-1:0] ResetVector = {{(XLEN-32){1'b0}}, `PC_RESET_VALUE }; logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM; logic StallExceptResolveBranchesF, PrivilegedChangePCM; logic [XLEN-3:0] PCPlusUpperF; diff --git a/wally-pipelined/src/testbench-busybear.sv b/wally-pipelined/src/testbench-busybear.sv index e28253dc4..bfbbc4dcb 100644 --- a/wally-pipelined/src/testbench-busybear.sv +++ b/wally-pipelined/src/testbench-busybear.sv @@ -1,475 +1,47 @@ -/////////////////////////////////////////// -// testbench.sv -// -// Written: David_Harris@hmc.edu 9 January 2021 -// Modified: -// -// Purpose: Wally Testbench and helper modules -// -// A component of the Wally configurable RISC-V project. -// -// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, -// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software -// is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -/////////////////////////////////////////// - `include "wally-macros.sv" module testbench_busybear #(parameter XLEN=64, MISA=32'h00000104, ZCSR = 1, ZCOUNTERS = 1)(); - logic clk; - logic reset; - logic [XLEN-1:0] WriteData, DataAdr; - logic [1:0] MemRW; - - int test, i, errors, totalerrors; - logic [31:0] sig32[0:10000]; - logic [XLEN-1:0] signature[0:10000]; - logic [XLEN-1:0] testadr; - string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; - logic [31:0] InstrW; - logic [XLEN-1:0] meminit; - string tests64ic[] = '{ - - "rv64ic/I-C-ADD-01", "3000", - "rv64ic/I-C-ADDI-01", "3000", - "rv64ic/I-C-ADDIW-01", "3000", - "rv64ic/I-C-ADDW-01", "3000", - "rv64ic/I-C-AND-01", "3000", - "rv64ic/I-C-ANDI-01", "3000", - "rv64ic/I-C-BEQZ-01", "3000", - "rv64ic/I-C-BNEZ-01", "3000", - "rv64ic/I-C-EBREAK-01", "2000", - "rv64ic/I-C-J-01", "3000", - "rv64ic/I-C-JALR-01", "4000", - "rv64ic/I-C-JR-01", "4000", - "rv64ic/I-C-LD-01", "3420", - "rv64ic/I-C-LDSP-01", "3420", - "rv64ic/I-C-LI-01", "3000", - "rv64ic/I-C-LUI-01", "2000", - "rv64ic/I-C-LW-01", "3110", - "rv64ic/I-C-LWSP-01", "3110", - "rv64ic/I-C-MV-01", "3000", - "rv64ic/I-C-NOP-01", "2000", - "rv64ic/I-C-OR-01", "3000", - "rv64ic/I-C-SD-01", "3000", - "rv64ic/I-C-SDSP-01", "3000", - "rv64ic/I-C-SLLI-01", "3000", - "rv64ic/I-C-SRAI-01", "3000", - "rv64ic/I-C-SRLI-01", "3000", - "rv64ic/I-C-SUB-01", "3000", - "rv64ic/I-C-SUBW-01", "3000", - "rv64ic/I-C-SW-01", "3000", - "rv64ic/I-C-SWSP-01", "3000", - "rv64ic/I-C-XOR-01", "3000" - }; -string tests64iNOc[] = { - "rv64i/I-MISALIGN_JMP-01","2000" - }; - string tests64i[] = '{ - "rv64i/I-ADD-01", "3000", - "rv64i/I-ADDI-01", "3000", - "rv64i/I-ADDIW-01", "3000", - "rv64i/I-ADDW-01", "3000", - "rv64i/I-AND-01", "3000", - "rv64i/I-ANDI-01", "3000", - "rv64i/I-AUIPC-01", "3000", - "rv64i/I-BEQ-01", "4000", - "rv64i/I-BGE-01", "4000", - "rv64i/I-BGEU-01", "4000", - "rv64i/I-BLT-01", "4000", - "rv64i/I-BLTU-01", "4000", - "rv64i/I-BNE-01", "4000", - "rv64i/I-DELAY_SLOTS-01", "2000", - "rv64i/I-EBREAK-01", "2000", - "rv64i/I-ECALL-01", "2000", - "rv64i/I-ENDIANESS-01", "2010", - "rv64i/I-IO-01", "2050", - "rv64i/I-JAL-01", "3000", - "rv64i/I-JALR-01", "4000", - "rv64i/I-LB-01", "4020", - "rv64i/I-LBU-01", "4020", - "rv64i/I-LD-01", "4420", - "rv64i/I-LH-01", "4050", - "rv64i/I-LHU-01", "4050", - "rv64i/I-LUI-01", "2000", - "rv64i/I-LW-01", "4110", - "rv64i/I-LWU-01", "4110", - "rv64i/I-MISALIGN_LDST-01", "2010", - "rv64i/I-NOP-01", "2000", - "rv64i/I-OR-01", "3000", - "rv64i/I-ORI-01", "3000", - "rv64i/I-RF_size-01", "2000", - "rv64i/I-RF_width-01", "2000", - "rv64i/I-RF_x0-01", "2010", - "rv64i/I-SB-01", "4000", - "rv64i/I-SD-01", "4000", - "rv64i/I-SH-01", "4000", - "rv64i/I-SLL-01", "3000", - "rv64i/I-SLLI-01", "3000", - "rv64i/I-SLLIW-01", "3000", - "rv64i/I-SLLW-01", "3000", - "rv64i/I-SLT-01", "3000", - "rv64i/I-SLTI-01", "3000", - "rv64i/I-SLTIU-01", "3000", - "rv64i/I-SLTU-01", "3000", - "rv64i/I-SRA-01", "3000", - "rv64i/I-SRAI-01", "3000", - "rv64i/I-SRAIW-01", "3000", - "rv64i/I-SRAW-01", "3000", - "rv64i/I-SRL-01", "3000", - "rv64i/I-SRLI-01", "3000", - "rv64i/I-SRLIW-01", "3000", - "rv64i/I-SRLW-01", "3000", - "rv64i/I-SUB-01", "3000", - "rv64i/I-SUBW-01", "3000", - "rv64i/I-SW-01", "4000", - "rv64i/I-XOR-01", "3000", - "rv64i/I-XORI-01", "3000", - "rv64i/WALLY-ADD", "4000", - "rv64i/WALLY-SUB", "4000" - }; -string tests32ic[] = '{ -// "rv32ic/WALLY-C-ADHOC-01", "2000", - "rv32ic/I-C-ADD-01", "2000", - "rv32ic/I-C-ADDI-01", "2000", - "rv32ic/I-C-AND-01", "2000", - "rv32ic/I-C-ANDI-01", "2000", - "rv32ic/I-C-BEQZ-01", "2000", - "rv32ic/I-C-BNEZ-01", "2000", - "rv32ic/I-C-EBREAK-01", "2000", - "rv32ic/I-C-J-01", "2000", - "rv32ic/I-C-JALR-01", "3000", - "rv32ic/I-C-JR-01", "3000", - "rv32ic/I-C-LI-01", "2000", - "rv32ic/I-C-LUI-01", "2000", - "rv32ic/I-C-LW-01", "2110", - "rv32ic/I-C-LWSP-01", "2110", - "rv32ic/I-C-MV-01", "2000", - "rv32ic/I-C-NOP-01", "2000", - "rv32ic/I-C-OR-01", "2000", - "rv32ic/I-C-SLLI-01", "2000", - "rv32ic/I-C-SRAI-01", "2000", - "rv32ic/I-C-SRLI-01", "2000", - "rv32ic/I-C-SUB-01", "2000", - "rv32ic/I-C-SW-01", "2000", - "rv32ic/I-C-SWSP-01", "2000", - "rv32ic/I-C-XOR-01", "2000" -}; -string tests32iNOc[] = { - "rv32i/I-MISALIGN_JMP-01","2000" -}; -string tests32i[] = { - "rv32i/I-ADD-01", "2000", - "rv32i/I-ADDI-01","2000", - "rv32i/I-AND-01","2000", - "rv32i/I-ANDI-01","2000", - "rv32i/I-AUIPC-01","2000", - "rv32i/I-BEQ-01","3000", - "rv32i/I-BGE-01","3000", - "rv32i/I-BGEU-01","3000", - "rv32i/I-BLT-01","3000", - "rv32i/I-BLTU-01","3000", - "rv32i/I-BNE-01","3000", - "rv32i/I-DELAY_SLOTS-01","2000", - "rv32i/I-EBREAK-01","2000", - "rv32i/I-ECALL-01","2000", - "rv32i/I-ENDIANESS-01","2010", - "rv32i/I-IO-01","2030", - "rv32i/I-JAL-01","3000", - "rv32i/I-JALR-01","3000", - "rv32i/I-LB-01","3020", - "rv32i/I-LBU-01","3020", - "rv32i/I-LH-01","3050", - "rv32i/I-LHU-01","3050", - "rv32i/I-LUI-01","2000", - "rv32i/I-LW-01","3110", - "rv32i/I-MISALIGN_LDST-01","2010", - "rv32i/I-NOP-01","2000", - "rv32i/I-OR-01","2000", - "rv32i/I-ORI-01","2000", - "rv32i/I-RF_size-01","2000", - "rv32i/I-RF_width-01","2000", - "rv32i/I-RF_x0-01","2010", - "rv32i/I-SB-01","3000", - "rv32i/I-SH-01","3000", - "rv32i/I-SLL-01","2000", - "rv32i/I-SLLI-01","2000", - "rv32i/I-SLT-01","2000", - "rv32i/I-SLTI-01","2000", - "rv32i/I-SLTIU-01","2000", - "rv32i/I-SLTU-01","2000", - "rv32i/I-SRA-01","2000", - "rv32i/I-SRAI-01","2000", - "rv32i/I-SRL-01","2000", - "rv32i/I-SRLI-01","2000", - "rv32i/I-SUB-01","2000", - "rv32i/I-SW-01","3000", - "rv32i/I-XOR-01","2000", - "rv32i/I-XORI-01","2000", - "rv32i/WALLY-ADD", "3000", - "rv32i/WALLY-SUB", "3000" -}; - string tests[]; - - // pick tests based on modes supported - initial - if (XLEN == 64) begin // RV64 - tests = {tests64i}; - if (`C_SUPPORTED % 2 == 1) tests = {tests, tests64ic}; - else tests = {tests, tests64iNOc}; - end else begin // RV32 - tests = {tests32i}; - if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic}; - else tests = {tests, tests32iNOc}; - end - string signame, memfilename; - - logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn; + logic clk, reset; + logic [XLEN-1:0] WriteDataM, DataAdrM; + logic [1:0] MemRWM; + logic [31:0] GPIOPinsIn; + logic [31:0] GPIOPinsOut, GPIOPinsEn; // instantiate device to be tested - assign GPIOPinsIn = 0; - wallypipelined #(XLEN, MISA, ZCSR, ZCOUNTERS) dut( - clk, reset, WriteData, DataAdr, MemRW, - GPIOPinsIn, GPIOPinsOut, GPIOPinsEn - ); - - // Track names of instructions - instrTrackerTB #(XLEN) it(clk, reset, dut.hart.dp.FlushE, - dut.hart.dp.InstrDecompD, dut.hart.dp.InstrE, - dut.hart.dp.InstrM, InstrW, - InstrDName, InstrEName, InstrMName, InstrWName); + logic [XLEN-1:0] PCF, ReadDataM; + logic [31:0] InstrF; + logic [7:0] ByteMaskM; + logic InstrAccessFaultF, DataAccessFaultM; + logic TimerIntM, SwIntM; // from CLINT + logic ExtIntM = 0; // not yet connected + + // instantiate processor and memories + wallypipelinedhart #(XLEN, MISA, ZCSR, ZCOUNTERS) dut(.ALUResultM(DataAdrM), .*); // initialize test initial begin - test = 0; - totalerrors = 0; - testadr = 0; - // fill memory with defined values to reduce Xs in simulation - if (XLEN == 32) meminit = 32'hFEDC0123; - else meminit = 64'hFEDCBA9876543210; - for (i=0; i<=65535; i = i+1) begin - //dut.imem.RAM[i] = meminit; - // dut.dmem.RAM[i] = meminit; - end - // read test vectors into memory - memfilename = {"../imperas-riscv-tests/work/", tests[test], ".elf.memfile"}; - $readmemh(memfilename, dut.imem.RAM); - $readmemh(memfilename, dut.dmem.dtim.RAM); - reset = 1; # 22; reset = 0; + reset <= 1; # 22; reset <= 0; end // generate clock to sequence tests always begin - clk = 1; # 5; clk = 0; # 5; + clk <= 1; # 5; clk <= 0; # 5; end - - // check results - always @(negedge clk) - begin - if (dut.hart.dp.priv.EcallFaultM && - (dut.hart.dp.regf.rf[3] == 1 || (dut.hart.dp.regf.we3 && dut.hart.dp.regf.a3 == 3 && dut.hart.dp.regf.wd3 == 1))) begin - $display("Code ended with ecall with gp = 1"); - #60; // give time for instructions in pipeline to finish - // clear signature to prevent contamination from previous tests - for(i=0; i<10000; i=i+1) begin - sig32[i] = 'bx; - end - // read signature, reformat in 64 bits if necessary - signame = {"../imperas-riscv-tests/work/", tests[test], ".signature.output"}; - $readmemh(signame, sig32); - i = 0; - while (i < 10000) begin - if (XLEN == 32) begin - signature[i] = sig32[i]; - i = i+1; - end else begin - signature[i/2] = {sig32[i+1], sig32[i]}; - i = i + 2; - end - end - - // Check errors - i = 0; - errors = 0; - if (XLEN == 32) - testadr = tests[test+1].atohex()/4; - else - testadr = tests[test+1].atohex()/8; - /* verilator lint_off INFINITELOOP */ - while (signature[i] !== 'bx) begin - //$display("signature[%h] = %h", i, signature[i]); - if (signature[i] !== dut.dmem.dtim.RAM[testadr+i]) begin - if (signature[i+4] !== 'bx || signature[i] !== 32'hFFFFFFFF) begin - // report errors unless they are garbage at the end of the sim - // kind of hacky test for garbage right now - errors = errors+1; - $display(" Error on test %s result %d: adr = %h sim = %h, signature = %h", - tests[test], i, (testadr+i)*XLEN/8, dut.dmem.dtim.RAM[testadr+i], signature[i]); - end - end - i = i + 1; - end - /* verilator lint_on INFINITELOOP */ - if (errors == 0) $display("%s succeeded. Brilliant!!!", tests[test]); - else begin - $display("%s failed with %d errors. :(", tests[test], errors); - totalerrors = totalerrors+1; - end - test = test + 2; - if (test == tests.size()) begin - if (totalerrors == 0) $display("SUCCESS! All tests ran without failures."); - else $display("FAIL: %d test programs had errors", totalerrors); - $stop; - end - else begin - memfilename = {"../imperas-riscv-tests/work/", tests[test], ".elf.memfile"}; - $readmemh(memfilename, dut.imem.RAM); - $readmemh(memfilename, dut.dmem.dtim.RAM); - $display("Read memfile %s", memfilename); - reset = 1; # 17; reset = 0; - end - end - end -endmodule - -/* verilator lint_on STMTDLY */ -/* verilator lint_on WIDTH */ - -module instrTrackerTB #(parameter XLEN=32) ( - input logic clk, reset, FlushE, - input logic [31:0] InstrD, - input logic [31:0] InstrE, InstrM, - output logic [31:0] InstrW, - output string InstrDName, InstrEName, InstrMName, InstrWName); - - // stage Instr to Writeback for visualization - flopr #(32) InstrWReg(clk, reset, InstrM, InstrW); - - instrNameDecTB ddec(InstrD, InstrDName); - instrNameDecTB edec(InstrE, InstrEName); - instrNameDecTB mdec(InstrM, InstrMName); - instrNameDecTB wdec(InstrW, InstrWName); -endmodule - -// decode the instruction name, to help the test bench -module instrNameDecTB( - input logic [31:0] instr, - output string name); - - logic [6:0] op; - logic [2:0] funct3; - logic [6:0] funct7; - logic [11:0] imm; - - assign op = instr[6:0]; - assign funct3 = instr[14:12]; - assign funct7 = instr[31:25]; - assign imm = instr[31:20]; - - // it would be nice to add the operands to the name - // create another variable called decoded - - always_comb - casez({op, funct3}) - 10'b0000000_000: name = "BAD"; - 10'b0000011_000: name = "LB"; - 10'b0000011_001: name = "LH"; - 10'b0000011_010: name = "LW"; - 10'b0000011_011: name = "LD"; - 10'b0000011_100: name = "LBU"; - 10'b0000011_101: name = "LHU"; - 10'b0000011_110: name = "LWU"; - 10'b0010011_000: if (instr[31:15] == 0 && instr[11:7] ==0) name = "NOP/FLUSH"; - else name = "ADDI"; - 10'b0010011_001: if (funct7[6:1] == 6'b000000) name = "SLLI"; - else name = "ILLEGAL"; - 10'b0010011_010: name = "SLTI"; - 10'b0010011_011: name = "SLTIU"; - 10'b0010011_100: name = "XORI"; - 10'b0010011_101: if (funct7[6:1] == 6'b000000) name = "SRLI"; - else if (funct7[6:1] == 6'b010000) name = "SRAI"; - else name = "ILLEGAL"; - 10'b0010011_110: name = "ORI"; - 10'b0010011_111: name = "ANDI"; - 10'b0010111_???: name = "AUIPC"; - 10'b0100011_000: name = "SB"; - 10'b0100011_001: name = "SH"; - 10'b0100011_010: name = "SW"; - 10'b0100011_011: name = "SD"; - 10'b0011011_000: name = "ADDIW"; - 10'b0011011_001: name = "SLLIW"; - 10'b0011011_101: if (funct7 == 7'b0000000) name = "SRLIW"; - else if (funct7 == 7'b0100000) name = "SRAIW"; - else name = "ILLEGAL"; - 10'b0111011_000: if (funct7 == 7'b0000000) name = "ADDW"; - else if (funct7 == 7'b0100000) name = "SUBW"; - else name = "ILLEGAL"; - 10'b0111011_001: name = "SLLW"; - 10'b0111011_101: if (funct7 == 7'b0000000) name = "SRLW"; - else if (funct7 == 7'b0100000) name = "SRAW"; - else name = "ILLEGAL"; - 10'b0110011_000: if (funct7 == 7'b0000000) name = "ADD"; - else if (funct7 == 7'b0000001) name = "MUL"; - else if (funct7 == 7'b0100000) name = "SUB"; - else name = "ILLEGAL"; - 10'b0110011_001: if (funct7 == 7'b0000000) name = "SLL"; - else if (funct7 == 7'b0000001) name = "MULH"; - else name = "ILLEGAL"; - 10'b0110011_010: if (funct7 == 7'b0000000) name = "SLT"; - else if (funct7 == 7'b0000001) name = "MULHSU"; - else name = "ILLEGAL"; - 10'b0110011_011: if (funct7 == 7'b0000000) name = "SLTU"; - else if (funct7 == 7'b0000001) name = "DIV"; - else name = "ILLEGAL"; - 10'b0110011_100: if (funct7 == 7'b0000000) name = "XOR"; - else if (funct7 == 7'b0000001) name = "MUL"; - else name = "ILLEGAL"; - 10'b0110011_101: if (funct7 == 7'b0000000) name = "SRL"; - else if (funct7 == 7'b0000001) name = "DIVU"; - else if (funct7 == 7'b0100000) name = "SRA"; - else name = "ILLEGAL"; - 10'b0110011_110: if (funct7 == 7'b0000000) name = "OR"; - else if (funct7 == 7'b0000001) name = "REM"; - else name = "ILLEGAL"; - 10'b0110011_111: if (funct7 == 7'b0000000) name = "AND"; - else if (funct7 == 7'b0000001) name = "REMU"; - else name = "ILLEGAL"; - 10'b0110111_???: name = "LUI"; - 10'b1100011_000: name = "BEQ"; - 10'b1100011_001: name = "BNE"; - 10'b1100011_100: name = "BLT"; - 10'b1100011_101: name = "BGE"; - 10'b1100011_110: name = "BLTU"; - 10'b1100011_111: name = "BGEU"; - 10'b1100111_000: name = "JALR"; - 10'b1101111_???: name = "JAL"; - 10'b1110011_000: if (imm == 0) name = "ECALL"; - else if (imm == 1) name = "EBREAK"; - else if (imm == 2) name = "URET"; - else if (imm == 258) name = "SRET"; - else if (imm == 770) name = "MRET"; - else name = "ILLEGAL"; - 10'b1110011_001: name = "CSRRW"; - 10'b1110011_010: name = "CSRRS"; - 10'b1110011_011: name = "CSRRC"; - 10'b1110011_101: name = "CSRRWI"; - 10'b1110011_110: name = "CSRRSI"; - 10'b1110011_111: name = "CSRRCI"; - 10'b0001111_???: name = "FENCE"; - default: name = "ILLEGAL"; - endcase + //// check results + //always @(negedge clk) + // begin + // if(MemWrite) begin + // if(DataAdr === 84 & WriteData === 71) begin + // $display("Simulation succeeded"); + // $stop; + // end else if (DataAdr !== 80) begin + // $display("Simulation failed"); + // $stop; + // end + // end + // end endmodule diff --git a/wally-pipelined/src/wally-macros.sv b/wally-pipelined/src/wally-macros.sv index 9ff616176..edda36937 100644 --- a/wally-pipelined/src/wally-macros.sv +++ b/wally-pipelined/src/wally-macros.sv @@ -20,5 +20,7 @@ `define S_MODE (2'b01) `define U_MODE (2'b00) +//PC reset value +`define PC_RESET_VALUE (32'h00001000) /* verilator lint_off STMTDLY */ /* verilator lint_off WIDTH */ diff --git a/wally-pipelined/wally-busybear.do b/wally-pipelined/wally-busybear.do index 0200698e4..259358cba 100644 --- a/wally-pipelined/wally-busybear.do +++ b/wally-pipelined/wally-busybear.do @@ -40,52 +40,52 @@ view wave add wave /testbench_busybear/clk add wave /testbench_busybear/reset add wave -divider -add wave -hex /testbench_busybear/dut/hart/dp/PCF -add wave -hex /testbench_busybear/dut/hart/dp/InstrF -add wave /testbench_busybear/InstrFName -#add wave -hex /testbench_busybear/dut/hart/dp/PCD -add wave -hex /testbench_busybear/dut/hart/dp/InstrD -add wave /testbench_busybear/InstrDName -add wave -divider -#add wave -hex /testbench_busybear/dut/hart/dp/PCE -#add wave -hex /testbench_busybear/dut/hart/dp/InstrE -add wave /testbench_busybear/InstrEName -add wave -hex /testbench_busybear/dut/hart/dp/SrcAE -add wave -hex /testbench_busybear/dut/hart/dp/SrcBE -add wave -hex /testbench_busybear/dut/hart/dp/ALUResultE -add wave /testbench_busybear/dut/hart/dp/PCSrcE -add wave -divider -#add wave -hex /testbench_busybear/dut/hart/dp/PCM -#add wave -hex /testbench_busybear/dut/hart/dp/InstrM -add wave /testbench_busybear/InstrMName -add wave /testbench_busybear/dut/dmem/dtim/memwrite -add wave -hex /testbench_busybear/dut/dmem/AdrM -add wave -hex /testbench_busybear/dut/dmem/WriteDataM -add wave -divider -add wave -hex /testbench_busybear/dut/hart/dp/PCW -#add wave -hex /testbench_busybear/dut/hart/dp/InstrW -add wave /testbench_busybear/InstrWName -add wave /testbench_busybear/dut/hart/dp/RegWriteW -add wave -hex /testbench_busybear/dut/hart/dp/ResultW -add wave -hex /testbench_busybear/dut/hart/dp/RdW -add wave -divider -#add ww -add wave -hex -r /testbench_busybear/* - --- Set Wave Output Items -TreeUpdate [SetDefaultTree] -WaveRestoreZoom {0 ps} {100 ps} -configure wave -namecolwidth 250 -configure wave -valuecolwidth 120 -configure wave -justifyvalue left -configure wave -signalnamewidth 0 -configure wave -snapdistance 10 -configure wave -datasetprefix 0 -configure wave -rowmargin 4 -configure wave -childrowmargin 2 -set DefaultRadix hexadecimal - --- Run the Simulation -#run 1000 -run -all -#quit +add wave -hex /testbench_busybear/dut/dp/PCF +add wave -hex /testbench_busybear/dut/dp/InstrF +#add wave /testbench_busybear/InstrFName +##add wave -hex /testbench_busybear/dut/dp/PCD +#add wave -hex /testbench_busybear/dut/dp/InstrD +#add wave /testbench_busybear/InstrDName +#add wave -divider +##add wave -hex /testbench_busybear/dut/dp/PCE +##add wave -hex /testbench_busybear/dut/dp/InstrE +#add wave /testbench_busybear/InstrEName +#add wave -hex /testbench_busybear/dut/dp/SrcAE +#add wave -hex /testbench_busybear/dut/dp/SrcBE +#add wave -hex /testbench_busybear/dut/dp/ALUResultE +#add wave /testbench_busybear/dut/dp/PCSrcE +#add wave -divider +##add wave -hex /testbench_busybear/dut/dp/PCM +##add wave -hex /testbench_busybear/dut/dp/InstrM +#add wave /testbench_busybear/InstrMName +#add wave /testbench_busybear/dut/dmem/dtim/memwrite +#add wave -hex /testbench_busybear/dut/dmem/AdrM +#add wave -hex /testbench_busybear/dut/dmem/WriteDataM +#add wave -divider +#add wave -hex /testbench_busybear/dut/dp/PCW +##add wave -hex /testbench_busybear/dut/dp/InstrW +#add wave /testbench_busybear/InstrWName +#add wave /testbench_busybear/dut/dp/RegWriteW +#add wave -hex /testbench_busybear/dut/dp/ResultW +#add wave -hex /testbench_busybear/dut/dp/RdW +#add wave -divider +##add ww +#add wave -hex -r /testbench_busybear/* +# +#-- Set Wave Output Items +#TreeUpdate [SetDefaultTree] +#WaveRestoreZoom {0 ps} {100 ps} +#configure wave -namecolwidth 250 +#configure wave -valuecolwidth 120 +#configure wave -justifyvalue left +#configure wave -signalnamewidth 0 +#configure wave -snapdistance 10 +#configure wave -datasetprefix 0 +#configure wave -rowmargin 4 +#configure wave -childrowmargin 2 +#set DefaultRadix hexadecimal +# +#-- Run the Simulation +run 100 +#run -all +##quit From 6d88c57f0fd61a6b55c638c4f5dd3ae9b262f7d1 Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Fri, 22 Jan 2021 14:11:17 -0500 Subject: [PATCH 05/14] load instructions from file line by line --- .gitignore | 1 + wally-pipelined/src/testbench-busybear.sv | 27 +++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/.gitignore b/.gitignore index b3169c604..69fb8f931 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ #vsim work files to ignore transcript vsim.wlf +wally-pipelined/wlft* diff --git a/wally-pipelined/src/testbench-busybear.sv b/wally-pipelined/src/testbench-busybear.sv index bfbbc4dcb..5f8880b5e 100644 --- a/wally-pipelined/src/testbench-busybear.sv +++ b/wally-pipelined/src/testbench-busybear.sv @@ -24,6 +24,33 @@ module testbench_busybear #(parameter XLEN=64, MISA=32'h00000104, ZCSR = 1, ZCOU begin reset <= 1; # 22; reset <= 0; end + + // read instr trace file + integer data_file, scan_file; + integer read_data; + initial begin + data_file = $fopen("busybear-testgen/parsed.txt", "r"); + if (data_file == 0) begin + $display("file couldn't be opened"); + $stop; + end + // scan_file = $fscanf(data_file, "%x\n", read_data); + // $display("%x", read_data); + + // scan_file = $fscanf(data_file, "%s\n", read_data); + // $display("%s", read_data); + // //if (!$feof(data_file)) begin + // // $display(read_data); + // //end + // end + end + + always @(PCF) begin + //$display("%x", PCF); + scan_file = $fscanf(data_file, "%x\n", InstrF); + //$display("%x", InstrF); + end + // generate clock to sequence tests always From 5b0070ac0b45bc6960ae957c416d9a624185a70f Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Fri, 22 Jan 2021 15:05:58 -0500 Subject: [PATCH 06/14] Start adding register checking I'm now realizing we need to simulate loads, or else these will all be wrong --- wally-pipelined/src/testbench-busybear.sv | 12 ++++++++ wally-pipelined/wally-busybear.do | 35 +++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/wally-pipelined/src/testbench-busybear.sv b/wally-pipelined/src/testbench-busybear.sv index 5f8880b5e..2e4638d17 100644 --- a/wally-pipelined/src/testbench-busybear.sv +++ b/wally-pipelined/src/testbench-busybear.sv @@ -44,10 +44,22 @@ module testbench_busybear #(parameter XLEN=64, MISA=32'h00000104, ZCSR = 1, ZCOU // //end // end end + logic [63:0] rfExpected[31:1]; + logic [63:0] pcExpected; always @(PCF) begin //$display("%x", PCF); scan_file = $fscanf(data_file, "%x\n", InstrF); + for(int i=1; i < 32; i++) begin + scan_file = $fscanf(data_file, "%x\n", rfExpected[i]); + end + scan_file = $fscanf(data_file, "%x\n", pcExpected); + //check things! + if (PCF != pcExpected) begin + $display("PC does not equal PC expected: %x, %x", PCF, pcExpected); + end + + //$display("%x", InstrF); end diff --git a/wally-pipelined/wally-busybear.do b/wally-pipelined/wally-busybear.do index 259358cba..259bf02d1 100644 --- a/wally-pipelined/wally-busybear.do +++ b/wally-pipelined/wally-busybear.do @@ -40,8 +40,43 @@ view wave add wave /testbench_busybear/clk add wave /testbench_busybear/reset add wave -divider +add wave -hex /testbench_busybear/pcExpected add wave -hex /testbench_busybear/dut/dp/PCF add wave -hex /testbench_busybear/dut/dp/InstrF +add wave -divider +# registers! +add wave -hex /testbench_busybear/rfExpected +add wave -hex /testbench_busybear/dut/dp/regf/rf[1] +add wave -hex /testbench_busybear/dut/dp/regf/rf[2] +add wave -hex /testbench_busybear/dut/dp/regf/rf[3] +add wave -hex /testbench_busybear/dut/dp/regf/rf[4] +add wave -hex /testbench_busybear/dut/dp/regf/rf[5] +add wave -hex /testbench_busybear/dut/dp/regf/rf[6] +add wave -hex /testbench_busybear/dut/dp/regf/rf[7] +add wave -hex /testbench_busybear/dut/dp/regf/rf[8] +add wave -hex /testbench_busybear/dut/dp/regf/rf[9] +add wave -hex /testbench_busybear/dut/dp/regf/rf[10] +add wave -hex /testbench_busybear/dut/dp/regf/rf[11] +add wave -hex /testbench_busybear/dut/dp/regf/rf[12] +add wave -hex /testbench_busybear/dut/dp/regf/rf[13] +add wave -hex /testbench_busybear/dut/dp/regf/rf[14] +add wave -hex /testbench_busybear/dut/dp/regf/rf[15] +add wave -hex /testbench_busybear/dut/dp/regf/rf[16] +add wave -hex /testbench_busybear/dut/dp/regf/rf[17] +add wave -hex /testbench_busybear/dut/dp/regf/rf[18] +add wave -hex /testbench_busybear/dut/dp/regf/rf[19] +add wave -hex /testbench_busybear/dut/dp/regf/rf[20] +add wave -hex /testbench_busybear/dut/dp/regf/rf[21] +add wave -hex /testbench_busybear/dut/dp/regf/rf[22] +add wave -hex /testbench_busybear/dut/dp/regf/rf[23] +add wave -hex /testbench_busybear/dut/dp/regf/rf[24] +add wave -hex /testbench_busybear/dut/dp/regf/rf[25] +add wave -hex /testbench_busybear/dut/dp/regf/rf[26] +add wave -hex /testbench_busybear/dut/dp/regf/rf[27] +add wave -hex /testbench_busybear/dut/dp/regf/rf[28] +add wave -hex /testbench_busybear/dut/dp/regf/rf[29] +add wave -hex /testbench_busybear/dut/dp/regf/rf[30] +add wave -hex /testbench_busybear/dut/dp/regf/rf[31] #add wave /testbench_busybear/InstrFName ##add wave -hex /testbench_busybear/dut/dp/PCD #add wave -hex /testbench_busybear/dut/dp/InstrD From adfeb29b7730078d0524dc702fd5fa99fc1cecce Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Fri, 22 Jan 2021 15:11:55 -0500 Subject: [PATCH 07/14] change regfile to not hold state of x0 --- wally-pipelined/src/regfile.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wally-pipelined/src/regfile.sv b/wally-pipelined/src/regfile.sv index a92497d01..78238a823 100644 --- a/wally-pipelined/src/regfile.sv +++ b/wally-pipelined/src/regfile.sv @@ -32,7 +32,7 @@ module regfile #(parameter XLEN=32) ( input logic [XLEN-1:0] wd3, output logic [XLEN-1:0] rd1, rd2); - logic [XLEN-1:0] rf[31:0]; + logic [XLEN-1:0] rf[31:1]; integer i; // three ported register file @@ -45,7 +45,7 @@ module regfile #(parameter XLEN=32) ( always_ff @(negedge clk or posedge reset) if (reset) for(i=0; i<32; i++) rf[i] <= 0; - else if (we3) rf[a3] <= wd3; + else if (we3 & (a3 != 0)) rf[a3] <= wd3; assign #2 rd1 = (a1 != 0) ? rf[a1] : 0; assign #2 rd2 = (a2 != 0) ? rf[a2] : 0; From cdcacb8dbe2eed0a96fd29fcdfda54260558d1ec Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Fri, 22 Jan 2021 20:27:01 -0500 Subject: [PATCH 08/14] change how testbench reads data we're not sure if this is a good idea, but for now, we broke things up into 3 seperate files, each read seperately. One for pc and instructions, one for registers, and one for memory reads. Each is scrolled through essentially independantly: new pc data is read and checked whenever pc changes, new register data is checked whenever any register changes, and a new mem read value is gotten whenever DataAdrM or MemRWM changes and MemRWM is not zero. I'm not super sure about the last one. Currently it looks like things should be working, but it goes wrong after, like, 3 instructions. --- wally-pipelined/src/testbench-busybear.sv | 70 ++++++++++++++++++----- 1 file changed, 56 insertions(+), 14 deletions(-) diff --git a/wally-pipelined/src/testbench-busybear.sv b/wally-pipelined/src/testbench-busybear.sv index 2e4638d17..1de8ca9c9 100644 --- a/wally-pipelined/src/testbench-busybear.sv +++ b/wally-pipelined/src/testbench-busybear.sv @@ -25,12 +25,11 @@ module testbench_busybear #(parameter XLEN=64, MISA=32'h00000104, ZCSR = 1, ZCOU reset <= 1; # 22; reset <= 0; end - // read instr trace file - integer data_file, scan_file; - integer read_data; + // read pc trace file + integer data_file_PC, scan_file_PC; initial begin - data_file = $fopen("busybear-testgen/parsed.txt", "r"); - if (data_file == 0) begin + data_file_PC = $fopen("busybear-testgen/parsedPC.txt", "r"); + if (data_file_PC == 0) begin $display("file couldn't be opened"); $stop; end @@ -44,23 +43,66 @@ module testbench_busybear #(parameter XLEN=64, MISA=32'h00000104, ZCSR = 1, ZCOU // //end // end end + + // read register trace file + integer data_file_rf, scan_file_rf; + initial begin + data_file_rf = $fopen("busybear-testgen/parsedRegs.txt", "r"); + if (data_file_rf == 0) begin + $display("file couldn't be opened"); + $stop; + end + end + + // read memreads trace file + integer data_file_mem, scan_file_mem; + initial begin + data_file_mem = $fopen("busybear-testgen/parsedMemRead.txt", "r"); + if (data_file_mem == 0) begin + $display("file couldn't be opened"); + $stop; + end + end + logic [63:0] rfExpected[31:1]; logic [63:0] pcExpected; + // I apologize for this hack, I don't have a clue how to properly work with packed arrays + logic [64*32:64] rf; + genvar i; + generate + for(i=1; i<32; i++) begin + assign rf[i*64+63:i*64] = dut.dp.regf.rf[i]; + end + endgenerate + + always @(rf) begin + for(int j=1; j<32; j++) begin + // read 31 integer registers + scan_file_rf = $fscanf(data_file_rf, "%x\n", rfExpected[j]); + // check things! + if (rf[j*64+63 -: 64] != rfExpected[j]) begin + $display("rf[%i] does not equal rf expected: %x, %x", j, rf[j*64+63 -: 64], rfExpected[j]); + end + end + end + + // this might need to change + always @(MemRWM or DataAdrM) begin + if (MemRWM != 0) begin + scan_file_mem = $fscanf(data_file_mem, "%x\n", ReadDataM); + end + end + always @(PCF) begin - //$display("%x", PCF); - scan_file = $fscanf(data_file, "%x\n", InstrF); - for(int i=1; i < 32; i++) begin - scan_file = $fscanf(data_file, "%x\n", rfExpected[i]); - end - scan_file = $fscanf(data_file, "%x\n", pcExpected); + // first read instruction + scan_file_PC = $fscanf(data_file_PC, "%x\n", InstrF); + // then expected PC value + scan_file_PC = $fscanf(data_file_PC, "%x\n", pcExpected); //check things! if (PCF != pcExpected) begin $display("PC does not equal PC expected: %x, %x", PCF, pcExpected); end - - - //$display("%x", InstrF); end From a66bd9008c18b7bd1ce574808d3bef2161e37386 Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Fri, 22 Jan 2021 21:14:45 -0500 Subject: [PATCH 09/14] slightly more info on errors, add instruction decoding --- wally-pipelined/src/testbench-busybear.sv | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/wally-pipelined/src/testbench-busybear.sv b/wally-pipelined/src/testbench-busybear.sv index 1de8ca9c9..2ff003a8f 100644 --- a/wally-pipelined/src/testbench-busybear.sv +++ b/wally-pipelined/src/testbench-busybear.sv @@ -81,7 +81,8 @@ module testbench_busybear #(parameter XLEN=64, MISA=32'h00000104, ZCSR = 1, ZCOU scan_file_rf = $fscanf(data_file_rf, "%x\n", rfExpected[j]); // check things! if (rf[j*64+63 -: 64] != rfExpected[j]) begin - $display("rf[%i] does not equal rf expected: %x, %x", j, rf[j*64+63 -: 64], rfExpected[j]); + $display("%t ps: rf[%i] does not equal rf expected: %x, %x", $time, j, rf[j*64+63 -: 64], rfExpected[j]); + $stop; end end end @@ -101,10 +102,19 @@ module testbench_busybear #(parameter XLEN=64, MISA=32'h00000104, ZCSR = 1, ZCOU scan_file_PC = $fscanf(data_file_PC, "%x\n", pcExpected); //check things! if (PCF != pcExpected) begin - $display("PC does not equal PC expected: %x, %x", PCF, pcExpected); + $display("%t ps: PC does not equal PC expected: %x, %x", $time, PCF, pcExpected); + $stop; end end + // Track names of instructions + string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; + logic [31:0] InstrW; + instrNameDecTB dec(InstrF, InstrFName); + instrTrackerTB #(XLEN) it(clk, reset, dut.dp.FlushE, + dut.dp.InstrDecompD, dut.dp.InstrE, + dut.dp.InstrM, InstrW, + InstrDName, InstrEName, InstrMName, InstrWName); // generate clock to sequence tests always From 117713be89d7d092af3e49b686964b2c5002167a Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Sat, 23 Jan 2021 16:42:17 -0500 Subject: [PATCH 10/14] Linux test now gets through first 8 instructions! fixes the python parser: get the value, not function name, of PC only write changes to registers instead of registers every cycle temporarilly NOP out CSRR instruction (with the canonical NOP), that was breaking this dont stop on errors, print them prettier --- wally-pipelined/src/testbench-busybear.sv | 6 +++--- wally-pipelined/wally-busybear.do | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/wally-pipelined/src/testbench-busybear.sv b/wally-pipelined/src/testbench-busybear.sv index 2ff003a8f..0537fb23d 100644 --- a/wally-pipelined/src/testbench-busybear.sv +++ b/wally-pipelined/src/testbench-busybear.sv @@ -81,8 +81,8 @@ module testbench_busybear #(parameter XLEN=64, MISA=32'h00000104, ZCSR = 1, ZCOU scan_file_rf = $fscanf(data_file_rf, "%x\n", rfExpected[j]); // check things! if (rf[j*64+63 -: 64] != rfExpected[j]) begin - $display("%t ps: rf[%i] does not equal rf expected: %x, %x", $time, j, rf[j*64+63 -: 64], rfExpected[j]); - $stop; + $display("%t ps: rf[%0d] does not equal rf expected: %x, %x", $time, j, rf[j*64+63 -: 64], rfExpected[j]); + // $stop; end end end @@ -103,7 +103,7 @@ module testbench_busybear #(parameter XLEN=64, MISA=32'h00000104, ZCSR = 1, ZCOU //check things! if (PCF != pcExpected) begin $display("%t ps: PC does not equal PC expected: %x, %x", $time, PCF, pcExpected); - $stop; + // $stop; end end diff --git a/wally-pipelined/wally-busybear.do b/wally-pipelined/wally-busybear.do index 259bf02d1..078127aa9 100644 --- a/wally-pipelined/wally-busybear.do +++ b/wally-pipelined/wally-busybear.do @@ -77,14 +77,14 @@ add wave -hex /testbench_busybear/dut/dp/regf/rf[28] add wave -hex /testbench_busybear/dut/dp/regf/rf[29] add wave -hex /testbench_busybear/dut/dp/regf/rf[30] add wave -hex /testbench_busybear/dut/dp/regf/rf[31] -#add wave /testbench_busybear/InstrFName +add wave /testbench_busybear/InstrFName ##add wave -hex /testbench_busybear/dut/dp/PCD #add wave -hex /testbench_busybear/dut/dp/InstrD -#add wave /testbench_busybear/InstrDName +add wave /testbench_busybear/InstrDName #add wave -divider ##add wave -hex /testbench_busybear/dut/dp/PCE ##add wave -hex /testbench_busybear/dut/dp/InstrE -#add wave /testbench_busybear/InstrEName +add wave /testbench_busybear/InstrEName #add wave -hex /testbench_busybear/dut/dp/SrcAE #add wave -hex /testbench_busybear/dut/dp/SrcBE #add wave -hex /testbench_busybear/dut/dp/ALUResultE @@ -92,14 +92,14 @@ add wave -hex /testbench_busybear/dut/dp/regf/rf[31] #add wave -divider ##add wave -hex /testbench_busybear/dut/dp/PCM ##add wave -hex /testbench_busybear/dut/dp/InstrM -#add wave /testbench_busybear/InstrMName +add wave /testbench_busybear/InstrMName #add wave /testbench_busybear/dut/dmem/dtim/memwrite #add wave -hex /testbench_busybear/dut/dmem/AdrM #add wave -hex /testbench_busybear/dut/dmem/WriteDataM #add wave -divider #add wave -hex /testbench_busybear/dut/dp/PCW ##add wave -hex /testbench_busybear/dut/dp/InstrW -#add wave /testbench_busybear/InstrWName +add wave /testbench_busybear/InstrWName #add wave /testbench_busybear/dut/dp/RegWriteW #add wave -hex /testbench_busybear/dut/dp/ResultW #add wave -hex /testbench_busybear/dut/dp/RdW From 71883dca821feb7b603cd2359b9501e961034f8d Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Sat, 23 Jan 2021 17:52:05 -0500 Subject: [PATCH 11/14] More linux testbench fixes So I'm super sorry for accidently overwriting the commits this morning Need to be more careful with force pushing :( This fixes the problem with CSRR somehow, by tying InstrAccessFaultF and DataAccessFaultM to zero for now. I feel like this is not a good solution and will cause problems in the future, but for the start it seems to work for now. I'm fair certain we need these to accurately simulate to do linux properly. Anyway, this super hackish solution is in place for now, now on to ignoring mispredicted reads --- wally-pipelined/src/testbench-busybear.sv | 6 +++++- wally-pipelined/wally-busybear.do | 10 +++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/wally-pipelined/src/testbench-busybear.sv b/wally-pipelined/src/testbench-busybear.sv index 0537fb23d..8fd14483c 100644 --- a/wally-pipelined/src/testbench-busybear.sv +++ b/wally-pipelined/src/testbench-busybear.sv @@ -15,6 +15,10 @@ module testbench_busybear #(parameter XLEN=64, MISA=32'h00000104, ZCSR = 1, ZCOU logic InstrAccessFaultF, DataAccessFaultM; logic TimerIntM, SwIntM; // from CLINT logic ExtIntM = 0; // not yet connected + + // for now, seem to need these to be zero until we get a better idea + assign InstrAccessFaultF = 0; + assign DataAccessFaultM = 0; // instantiate processor and memories wallypipelinedhart #(XLEN, MISA, ZCSR, ZCOUNTERS) dut(.ALUResultM(DataAdrM), .*); @@ -101,7 +105,7 @@ module testbench_busybear #(parameter XLEN=64, MISA=32'h00000104, ZCSR = 1, ZCOU // then expected PC value scan_file_PC = $fscanf(data_file_PC, "%x\n", pcExpected); //check things! - if (PCF != pcExpected) begin + if (PCF !== pcExpected) begin $display("%t ps: PC does not equal PC expected: %x, %x", $time, PCF, pcExpected); // $stop; end diff --git a/wally-pipelined/wally-busybear.do b/wally-pipelined/wally-busybear.do index 078127aa9..a52bda6a7 100644 --- a/wally-pipelined/wally-busybear.do +++ b/wally-pipelined/wally-busybear.do @@ -78,11 +78,11 @@ add wave -hex /testbench_busybear/dut/dp/regf/rf[29] add wave -hex /testbench_busybear/dut/dp/regf/rf[30] add wave -hex /testbench_busybear/dut/dp/regf/rf[31] add wave /testbench_busybear/InstrFName -##add wave -hex /testbench_busybear/dut/dp/PCD +add wave -hex /testbench_busybear/dut/dp/PCD #add wave -hex /testbench_busybear/dut/dp/InstrD add wave /testbench_busybear/InstrDName #add wave -divider -##add wave -hex /testbench_busybear/dut/dp/PCE +add wave -hex /testbench_busybear/dut/dp/PCE ##add wave -hex /testbench_busybear/dut/dp/InstrE add wave /testbench_busybear/InstrEName #add wave -hex /testbench_busybear/dut/dp/SrcAE @@ -90,14 +90,14 @@ add wave /testbench_busybear/InstrEName #add wave -hex /testbench_busybear/dut/dp/ALUResultE #add wave /testbench_busybear/dut/dp/PCSrcE #add wave -divider -##add wave -hex /testbench_busybear/dut/dp/PCM +add wave -hex /testbench_busybear/dut/dp/PCM ##add wave -hex /testbench_busybear/dut/dp/InstrM add wave /testbench_busybear/InstrMName #add wave /testbench_busybear/dut/dmem/dtim/memwrite #add wave -hex /testbench_busybear/dut/dmem/AdrM #add wave -hex /testbench_busybear/dut/dmem/WriteDataM #add wave -divider -#add wave -hex /testbench_busybear/dut/dp/PCW +add wave -hex /testbench_busybear/dut/dp/PCW ##add wave -hex /testbench_busybear/dut/dp/InstrW add wave /testbench_busybear/InstrWName #add wave /testbench_busybear/dut/dp/RegWriteW @@ -121,6 +121,6 @@ add wave /testbench_busybear/InstrWName #set DefaultRadix hexadecimal # #-- Run the Simulation -run 100 +run 300 #run -all ##quit From 6d846583694d118ca69b7ac50ea007dfd45257fc Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Sat, 23 Jan 2021 19:01:44 -0500 Subject: [PATCH 12/14] sucessfully simulate first 30 instructions still need to find a better solution to InstrAccessFault/DataAccessFault though --- wally-pipelined/src/testbench-busybear.sv | 46 ++++++++++++++--------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/wally-pipelined/src/testbench-busybear.sv b/wally-pipelined/src/testbench-busybear.sv index 8fd14483c..405feaefa 100644 --- a/wally-pipelined/src/testbench-busybear.sv +++ b/wally-pipelined/src/testbench-busybear.sv @@ -37,15 +37,6 @@ module testbench_busybear #(parameter XLEN=64, MISA=32'h00000104, ZCSR = 1, ZCOU $display("file couldn't be opened"); $stop; end - // scan_file = $fscanf(data_file, "%x\n", read_data); - // $display("%x", read_data); - - // scan_file = $fscanf(data_file, "%s\n", read_data); - // $display("%s", read_data); - // //if (!$feof(data_file)) begin - // // $display(read_data); - // //end - // end end // read register trace file @@ -98,16 +89,37 @@ module testbench_busybear #(parameter XLEN=64, MISA=32'h00000104, ZCSR = 1, ZCOU end end + logic speculative, nextSpec; + initial begin + speculative = 0; + nextSpec = 0; + end always @(PCF) begin - // first read instruction - scan_file_PC = $fscanf(data_file_PC, "%x\n", InstrF); - // then expected PC value - scan_file_PC = $fscanf(data_file_PC, "%x\n", pcExpected); - //check things! - if (PCF !== pcExpected) begin - $display("%t ps: PC does not equal PC expected: %x, %x", $time, PCF, pcExpected); - // $stop; + speculative <= nextSpec; + if (speculative) begin + speculative <= (PCF != pcExpected); + end + if (~speculative) begin + // first read instruction + scan_file_PC = $fscanf(data_file_PC, "%x\n", InstrF); + // then expected PC value + scan_file_PC = $fscanf(data_file_PC, "%x\n", pcExpected); + // are we at a branch/jump? + case (InstrF[6:0]) //todo: add C versions of these + 7'b1101111, //JAL + 7'b1100111, //JALR + 7'b1100011: //B + nextSpec <= 1; + default: + nextSpec <= 0; + endcase + + //check things! + if ((~nextSpec) && (PCF !== pcExpected)) begin + $display("%t ps: PC does not equal PC expected: %x, %x", $time, PCF, pcExpected); + // $stop; + end end end