diff --git a/.gitignore b/.gitignore index 6dfa59c33..7f65a18a6 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ wlft* /imperas-riscv-tests/FunctionRadix_64.addr /imperas-riscv-tests/FunctionRadix.addr /imperas-riscv-tests/ProgramMap.txt +/imperas-riscv-tests/logs /wally-pipelined/busybear-testgen/gdbcombined.txt /wally-pipelined/busybear-testgen/first10.txt *.o diff --git a/wally-pipelined/config/rv64ic/wally-config.vh b/wally-pipelined/config/rv64ic/wally-config.vh index 2e0d92fb8..bacd6f17a 100644 --- a/wally-pipelined/config/rv64ic/wally-config.vh +++ b/wally-pipelined/config/rv64ic/wally-config.vh @@ -31,7 +31,7 @@ `define XLEN 64 //`define MISA (32'h00000105) -`define MISA (32'h00000104 | 1<<5 | 1<<18 | 1 << 20 | 1 << 12 | 1 << 0) +`define MISA (32'h00000104 | 1<<5 | 1<<18 | 1 << 20 | 1 << 12 | 1 << 0 | 1 << 3) `define A_SUPPORTED ((`MISA >> 0) % 2 == 1) `define C_SUPPORTED ((`MISA >> 2) % 2 == 1) `define D_SUPPORTED ((`MISA >> 3) % 2 == 1) diff --git a/wally-pipelined/regression/regression-wally.py b/wally-pipelined/regression/regression-wally.py index 62d463206..56dfa4d9a 100755 --- a/wally-pipelined/regression/regression-wally.py +++ b/wally-pipelined/regression/regression-wally.py @@ -26,7 +26,7 @@ configs = [ TestCase( name="busybear", cmd="vsim -do wally-busybear-batch.do -c > {}", - grepstr="# loaded 40000 instructions" + grepstr="# loaded 100000 instructions" ), TestCase( name="buildroot", @@ -50,37 +50,50 @@ configs = [ ), ] -import multiprocessing, os +import os +from multiprocessing import Pool, TimeoutError def search_log_for_text(text, logfile): """Search through the given log file for text, returning True if it is found or False if it is not""" grepcmd = "grep -e '%s' '%s' > /dev/null" % (text, logfile) return os.system(grepcmd) == 0 -def run_test_case(case): +def run_test_case(config): """Run the given test case, and return 0 if the test suceeds and 1 if it fails""" - logname = "regression_logs/wally_"+case.name+".log" - cmd = case.cmd.format(logname) + logname = "regression_logs/wally_"+config.name+".log" + cmd = config.cmd.format(logname) print(cmd) os.system(cmd) - if search_log_for_text(case.grepstr, logname): - print("%s: Success" % logname) + if search_log_for_text(config.grepstr, logname): + print("%s: Success" % config.name) return 0 else: - print("%s: failures detected" % logname) + print("%s: Failures detected in output" % config.name) + print(" Check %s" % logname) return 1 def main(): """Run the tests and count the failures""" # Scale the number of concurrent processes to the number of test cases, but # max out at 12 concurrent processes to not overwhelm the system + TIMEOUT_DUR = 600 # seconds try: os.mkdir("regression_logs") except: pass - pool = multiprocessing.Pool(min(len(configs), 12)) + with Pool(processes=min(len(configs),12)) as pool: + num_fail = 0 + results = {} + for config in configs: + results[config] = pool.apply_async(run_test_case,(config,)) + for (config,result) in results.items(): + try: + num_fail+=result.get(timeout=TIMEOUT_DUR) + except TimeoutError: + num_fail+=1 + print("%s: Timeout - runtime exceeded %d seconds" % (config.name, TIMEOUT_DUR)) + # Count the number of failures - num_fail = sum(pool.map(run_test_case, configs)) if num_fail: print("Regression failed with %s failed configurations" % num_fail) # Remind the user to try `make allclean`, since it may be needed if test diff --git a/wally-pipelined/regression/wally-busybear.do b/wally-pipelined/regression/wally-busybear.do index f4e1a99a3..ac570b873 100644 --- a/wally-pipelined/regression/wally-busybear.do +++ b/wally-pipelined/regression/wally-busybear.do @@ -36,7 +36,7 @@ vopt +acc work.testbench -o workopt vsim workopt -suppress 8852,12070 #do ./wave-dos/peripheral-waves.do -do ./wave-dos/busybear-waves.do +do ./wave-dos/default-waves.do #do busy-mmu.do diff --git a/wally-pipelined/src/fpu/fctrl.sv b/wally-pipelined/src/fpu/fctrl.sv index 51f90aefc..994cb1e6f 100755 --- a/wally-pipelined/src/fpu/fctrl.sv +++ b/wally-pipelined/src/fpu/fctrl.sv @@ -200,7 +200,7 @@ module fctrl ( // fmv.d.w = ?101 // {?, is mv, is store, is double or fcvt.d.w} 3'b111 : OpCtrlD = {1'b0, OpD[6:5], Funct3D[0] | (OpD[6]&Funct7D[0])}; - default : begin OpCtrlD = 4'bxxxx; IllegalFPUInstrD = isFP; end + default : begin OpCtrlD = 4'bxxxx; IllegalFPUInstrD = 1'b1; end endcase end diff --git a/wally-pipelined/src/fpu/fpu.sv b/wally-pipelined/src/fpu/fpu.sv index 7fb77e261..76a46498b 100755 --- a/wally-pipelined/src/fpu/fpu.sv +++ b/wally-pipelined/src/fpu/fpu.sv @@ -48,9 +48,9 @@ module fpu ( localparam PipeEnable = 1'b1; always_comb begin - PipeEnableDE = StallE; - PipeEnableEM = StallM; - PipeEnableMW = StallW; + PipeEnableDE = ~StallE; + PipeEnableEM = ~StallM; + PipeEnableMW = ~StallW; PipeClearDE = FlushE; PipeClearEM = FlushM; PipeClearMW = FlushW; diff --git a/wally-pipelined/src/privileged/privdec.sv b/wally-pipelined/src/privileged/privdec.sv index 5e3581ff8..1330a62bc 100644 --- a/wally-pipelined/src/privileged/privdec.sv +++ b/wally-pipelined/src/privileged/privdec.sv @@ -47,7 +47,7 @@ module privdec ( assign wfiM = PrivilegedM & (InstrM[31:20] == 12'b000100000101); assign sfencevmaM = PrivilegedM & (InstrM[31:25] == 7'b0001001); assign IllegalPrivilegedInstrM = PrivilegedM & ~(uretM|sretM|mretM|ecallM|ebreakM|wfiM|sfencevmaM); - assign IllegalInstrFaultM = IllegalIEUInstrFaultM | IllegalFPUInstrM | IllegalPrivilegedInstrM | IllegalCSRAccessM | IllegalFPUInstrM; // *** generalize this for other instructions + assign IllegalInstrFaultM = (IllegalIEUInstrFaultM & IllegalFPUInstrM) | IllegalPrivilegedInstrM | IllegalCSRAccessM; // *** generalize this for other instructions // *** initially, wfi and sfencevma are nop // *** zfenci extension? diff --git a/wally-pipelined/src/privileged/privileged.sv b/wally-pipelined/src/privileged/privileged.sv index 509f769aa..2e3af3e2c 100644 --- a/wally-pipelined/src/privileged/privileged.sv +++ b/wally-pipelined/src/privileged/privileged.sv @@ -52,6 +52,7 @@ module privileged ( input logic TimerIntM, ExtIntM, SwIntM, input logic [`XLEN-1:0] InstrMisalignedAdrM, MemAdrM, input logic [4:0] SetFflagsM, + output logic IllegalFPUInstrE, output logic [1:0] PrivilegeModeW, output logic [`XLEN-1:0] SATP_REGW, output logic STATUS_MXR, STATUS_SUM, @@ -78,7 +79,7 @@ module privileged ( logic uretM, sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM; logic IllegalCSRAccessM; logic IllegalIEUInstrFaultE, IllegalIEUInstrFaultM; - logic IllegalFPUInstrE, IllegalFPUInstrM; + logic IllegalFPUInstrM; logic LoadPageFaultM, StorePageFaultM; logic InstrPageFaultF, InstrPageFaultD, InstrPageFaultE, InstrPageFaultM; logic InstrAccessFaultF, InstrAccessFaultD, InstrAccessFaultE, InstrAccessFaultM; diff --git a/wally-pipelined/src/wally/wallypipelinedhart.sv b/wally-pipelined/src/wally/wallypipelinedhart.sv index f93c6b285..2c7ccc053 100644 --- a/wally-pipelined/src/wally/wallypipelinedhart.sv +++ b/wally-pipelined/src/wally/wallypipelinedhart.sv @@ -96,7 +96,7 @@ module wallypipelinedhart ( logic SquashSCW; logic [31:0] FSROutW; logic DivSqrtDoneE; - logic IllegalFPUInstrD; + logic IllegalFPUInstrD, IllegalFPUInstrE; logic [`XLEN-1:0] FPUResultW; // memory management unit signals diff --git a/wally-pipelined/testbench/testbench-busybear.sv b/wally-pipelined/testbench/testbench-busybear.sv index f18469d1e..87ee82330 100644 --- a/wally-pipelined/testbench/testbench-busybear.sv +++ b/wally-pipelined/testbench/testbench-busybear.sv @@ -261,11 +261,10 @@ module testbench(); logic [`XLEN-1:0] readAdrExpected, readAdrTranslated; - import ahbliteState::*; always @(dut.HRDATA) begin #2; if (dut.hart.MemRWM[1] - && (dut.hart.ebu.BusState == MEMREAD || dut.hart.ebu.BusState == ATOMICREAD) + && (dut.hart.ebu.CaptureDataM) && dut.HRDATA !== {64{1'bx}}) begin //$display("%0t", $time); if($feof(data_file_memR)) begin @@ -469,12 +468,13 @@ module testbench(); speculative = ~equal(dut.hart.ifu.PCD,pcExpected,3); if(dut.hart.ifu.PCD===pcExpected) begin if(dut.hart.ifu.InstrRawD[6:0] == 7'b1010011) begin // for now, NOP out any float instrs - force CheckInstrD = 32'b0010011; - release CheckInstrD; - force dut.hart.ifu.InstrRawD = 32'b0010011; - #7; - release dut.hart.ifu.InstrRawD; $display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.hart.ifu.PCD, instrs, $time); + force CheckInstrD = 32'b0010011; + force dut.hart.ifu.InstrRawD = 32'b0010011; + while (clk != 0) #1; + while (clk != 1) #1; + release dut.hart.ifu.InstrRawD; + release CheckInstrD; warningCount += 1; forcedInstr = 1; end @@ -497,12 +497,13 @@ module testbench(); scan_file_PC = $fscanf(data_file_PC, "%x\n", CheckInstrD); if(dut.hart.ifu.PCD === pcExpected) begin if(dut.hart.ifu.InstrRawD[6:0] == 7'b1010011) begin // for now, NOP out any float instrs - force CheckInstrD = 32'b0010011; - release CheckInstrD; - force dut.hart.ifu.InstrRawD = 32'b0010011; - #7; - release dut.hart.ifu.InstrRawD; $display("warning: NOPing out %s at PC=%0x, instr %0d, time %0t", PCtext, dut.hart.ifu.PCD, instrs, $time); + force CheckInstrD = 32'b0010011; + force dut.hart.ifu.InstrRawD = 32'b0010011; + while (clk != 0) #1; + while (clk != 1) #1; + release dut.hart.ifu.InstrRawD; + release CheckInstrD; warningCount += 1; forcedInstr = 1; end diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 488fd6002..310207ab0 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -52,11 +52,110 @@ module testbench(); "rv64mmu/WALLY-VIRTUALMEMORY", "2000" }; + +string tests32f[] = '{ + "rv32f/I-FADD-S-01", "2000", + "rv32f/I-FCLASS-S-01", "2000", + "rv32f/I-FCVT-S-L-01", "2000", + "rv32f/I-FCVT-S-LU-01", "2000", + "rv32f/I-FCVT-S-W-01", "2000", + "rv32f/I-FCVT-S-WU-01", "2000", + "rv32f/I-FCVT-L-S-01", "2000", + "rv32f/I-FCVT-LU-S-01", "2000", + "rv32f/I-FCVT-W-S-01", "2000", + "rv32f/I-FCVT-WU-S-01", "2000", + "rv32f/I-FDIV-S-01", "2000", + "rv32f/I-FEQ-S-01", "2000", + "rv32f/I-FLE-S-01", "2000", + "rv32f/I-FLT-S-01", "2000", + "rv32f/I-FMADD-S-01", "2000", + "rv32f/I-FMAX-S-01", "2000", + "rv32f/I-FMIN-S-01", "2000", + "rv32f/I-FMSUB-S-01", "2000", + "rv32f/I-FMUL-S-01", "2000", + "rv32f/I-FMV-W-X-01", "2000", + "rv32f/I-FMV-X-W-01", "2000", + "rv32f/I-FNMADD-S-01", "2000", + "rv32f/I-FNMSUB-S-01", "2000", + "rv32f/I-FSGNJ-S-01", "2000", + "rv32f/I-FSGNJN-S-01", "2000", + "rv32f/I-FSGNJX-S-01", "2000", + "rv32f/I-FSQRT-S-01", "2000", + "rv32f/I-FSW-01", "2000", + "rv32f/I-FLW-01", "2000", + "rv32f/I-FSUB-S-01", "2000" + }; + string tests64f[] = '{ "rv64f/I-FADD-S-01", "2000", - "rv64f/I-FCLASS-S-01", "2000" + "rv64f/I-FCLASS-S-01", "2000", + "rv64f/I-FCVT-S-L-01", "2000", + "rv64f/I-FCVT-S-LU-01", "2000", + "rv64f/I-FCVT-S-W-01", "2000", + "rv64f/I-FCVT-S-WU-01", "2000", + "rv64f/I-FCVT-L-S-01", "2000", + "rv64f/I-FCVT-LU-S-01", "2000", + "rv64f/I-FCVT-W-S-01", "2000", + "rv64f/I-FCVT-WU-S-01", "2000", + "rv64f/I-FDIV-S-01", "2000", + "rv64f/I-FEQ-S-01", "2000", + "rv64f/I-FLE-S-01", "2000", + "rv64f/I-FLT-S-01", "2000", + "rv64f/I-FMADD-S-01", "2000", + "rv64f/I-FMAX-S-01", "2000", + "rv64f/I-FMIN-S-01", "2000", + "rv64f/I-FMSUB-S-01", "2000", + "rv64f/I-FMUL-S-01", "2000", + "rv64f/I-FMV-W-X-01", "2000", + "rv64f/I-FNMADD-S-01", "2000", + "rv64f/I-FNMSUB-S-01", "2000", + "rv64f/I-FSGNJ-S-01", "2000", + "rv64f/I-FSGNJN-S-01", "2000", + "rv64f/I-FSGNJX-S-01", "2000", + "rv64f/I-FSQRT-S-01", "2000", + "rv64f/I-FSW-01", "2000", + "rv64f/I-FLW-01", "2000", + "rv64f/I-FSUB-S-01", "2000" }; + + string tests64d[] = '{ + "rv64d/I-FMV-X-D-01", "2000", + "rv64d/I-FADD-D-01", "2000", + "rv64d/I-FCLASS-D-01", "2000", + "rv64d/I-FCVT-D-L-01", "2000", + "rv64d/I-FCVT-D-LU-01", "2000", + "rv64d/I-FCVT-D-S-01", "2000", + "rv64d/I-FCVT-D-W-01", "2000", + "rv64d/I-FCVT-D-WU-01", "2000", + "rv64d/I-FCVT-L-D-01", "2000", + "rv64d/I-FCVT-LU-D-01", "2000", + "rv64d/I-FCVT-S-D-01", "2000", + "rv64d/I-FCVT-W-D-01", "2000", + "rv64d/I-FCVT-WU-D-01", "2000", + "rv64d/I-FDIV-D-01", "2000", + "rv64d/I-FEQ-D-01", "2000", + "rv64d/I-FLD-D-01", "2000", + "rv64d/I-FLE-D-01", "2000", + "rv64d/I-FLT-D-01", "2000", + "rv64d/I-FMADD-D-01", "2000", + "rv64d/I-FMAX-D-01", "2000", + "rv64d/I-FMIN-D-01", "2000", + "rv64d/I-FMSUB-D-01", "2000", + "rv64d/I-FMUL-D-01", "2000", + "rv64d/I-FMV-D-X-01", "2000", + "rv64d/I-FNMADD-D-01", "2000", + "rv64d/I-FNMSUB-D-01", "2000", + "rv64d/I-FSD-01", "2000", + "rv64d/I-FSGNJ-D-01", "2000", + "rv64d/I-FSGNJN-D-01", "2000", + "rv64d/I-FSGNJX-D-01", "2000", + "rv64d/I-FSQRTD-01", "2000", + "rv64d/I-FSUB-D-01", "2000" + }; + + + string tests64a[] = '{ "rv64a/WALLY-AMO", "2110", "rv64a/WALLY-LRSC", "2110" @@ -426,10 +525,10 @@ module testbench(); if (`C_SUPPORTED) tests = {tests, tests64ic}; else tests = {tests, tests64iNOc}; if (`M_SUPPORTED) tests = {tests, tests64m}; - // if (`F_SUPPORTED) tests = {tests64f, tests}; - // if (`D_SUPPORTED) tests = {tests64d, tests}; if (`A_SUPPORTED) tests = {tests, tests64a}; if (`MEM_VIRTMEM) tests = {tests, tests64mmu}; + // if (`F_SUPPORTED) tests = {tests64f, tests}; + // if (`D_SUPPORTED) tests = {tests64d, tests}; end //tests = {tests64a, tests}; end else begin // RV32 @@ -555,6 +654,7 @@ module testbench(); errors = errors+1; $display(" Error on test %s result %d: adr = %h sim = %h, signature = %h", tests[test], i, (testadr+i)*`XLEN/8, dut.uncore.dtim.RAM[testadr+i], signature[i]); + // $stop;//***debug end end i = i + 1; @@ -633,11 +733,13 @@ module instrNameDecTB( logic [2:0] funct3; logic [6:0] funct7; logic [11:0] imm; + logic [4:0] rs2; 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]; // it would be nice to add the operands to the name // create another variable called decoded @@ -761,6 +863,67 @@ module instrNameDecTB( else if (funct7[6:2] == 5'b11100) name = "AMOMAXU.D"; else name = "ILLEGAL"; 10'b0001111_???: name = "FENCE"; + 10'b1000011_???: name = "FMADD"; + 10'b1000111_???: name = "FMSUB"; + 10'b1001011_???: name = "FNMSUB"; + 10'b1001111_???: name = "FNMADD"; + 10'b1010011_000: if (funct7[6:2] == 5'b00000) name = "FADD"; + else if (funct7[6:2] == 5'b00001) name = "FSUB"; + else if (funct7[6:2] == 5'b00010) name = "FMUL"; + else if (funct7[6:2] == 5'b00011) name = "FDIV"; + else if (funct7[6:2] == 5'b01011) name = "FSQRT"; + else if (funct7 == 7'b1100000 && rs2 == 5'b00000) name = "FCVT.W.S"; + else if (funct7 == 7'b1100000 && rs2 == 5'b00001) name = "FCVT.WU.S"; + else if (funct7 == 7'b1101000 && rs2 == 5'b00000) name = "FCVT.S.W"; + else if (funct7 == 7'b1101000 && rs2 == 5'b00001) name = "FCVT.S.WU"; + else if (funct7 == 7'b1110000 && rs2 == 5'b00000) name = "FMV.X.W"; + else if (funct7 == 7'b1111000 && rs2 == 5'b00000) name = "FMV.W.X"; + else if (funct7 == 7'b1110001 && rs2 == 5'b00000) name = "FMV.X.W"; // DOUBLE + else if (funct7 == 7'b1111001 && rs2 == 5'b00000) name = "FMV.W.X"; // DOUBLE + else if (funct7[6:2] == 5'b00100) name = "FSGNJ"; + else if (funct7[6:2] == 5'b00101) name = "FMIN"; + else if (funct7[6:2] == 5'b10100) name = "FLE"; + else name = "ILLEGAL"; + 10'b1010011_001: if (funct7[6:2] == 5'b00000) name = "FADD"; + else if (funct7[6:2] == 5'b00001) name = "FSUB"; + else if (funct7[6:2] == 5'b00010) name = "FMUL"; + else if (funct7[6:2] == 5'b00011) name = "FDIV"; + else if (funct7[6:2] == 5'b01011) name = "FSQRT"; + else if (funct7 == 7'b1100000 && rs2 == 5'b00000) name = "FCVT.W.S"; + else if (funct7 == 7'b1100000 && rs2 == 5'b00001) name = "FCVT.WU.S"; + else if (funct7 == 7'b1101000 && rs2 == 5'b00000) name = "FCVT.S.W"; + else if (funct7 == 7'b1101000 && rs2 == 5'b00001) name = "FCVT.S.WU"; + else if (funct7[6:2] == 5'b00100) name = "FSGNJN"; + else if (funct7[6:2] == 5'b00101) name = "FMAX"; + else if (funct7[6:2] == 5'b10100) name = "FLT"; + else if (funct7[6:2] == 5'b11100) name = "FCLASS"; + else name = "ILLEGAL"; + 10'b0101111_010: if (funct7[6:2] == 5'b00000) name = "FADD"; + else if (funct7[6:2] == 5'b00001) name = "FSUB"; + else if (funct7[6:2] == 5'b00010) name = "FMUL"; + else if (funct7[6:2] == 5'b00011) name = "FDIV"; + else if (funct7[6:2] == 5'b01011) name = "FSQRT"; + else if (funct7 == 7'b1100000 && rs2 == 5'b00000) name = "FCVT.W.S"; + else if (funct7 == 7'b1100000 && rs2 == 5'b00001) name = "FCVT.WU.S"; + else if (funct7 == 7'b1101000 && rs2 == 5'b00000) name = "FCVT.S.W"; + else if (funct7 == 7'b1101000 && rs2 == 5'b00001) name = "FCVT.S.WU"; + else if (funct7[6:2] == 5'b00100) name = "FSGNJX"; + else if (funct7[6:2] == 5'b10100) name = "FEQ"; + else name = "ILLEGAL"; + 10'b1010011_???: if (funct7[6:2] == 5'b00000) name = "FADD"; + else if (funct7[6:2] == 5'b00001) name = "FSUB"; + else if (funct7[6:2] == 5'b00010) name = "FMUL"; + else if (funct7[6:2] == 5'b00011) name = "FDIV"; + else if (funct7[6:2] == 5'b01011) name = "FSQRT"; + else if (funct7 == 7'b1100000 && rs2 == 5'b00000) name = "FCVT.W.S"; + else if (funct7 == 7'b1100000 && rs2 == 5'b00001) name = "FCVT.WU.S"; + else if (funct7 == 7'b1101000 && rs2 == 5'b00000) name = "FCVT.S.W"; + else if (funct7 == 7'b1101000 && rs2 == 5'b00001) name = "FCVT.S.WU"; + else name = "ILLEGAL"; + 10'b0000111_010: name = "FLW"; + 10'b0100111_010: name = "FSW"; + 10'b0000111_010: name = "FLD"; + 10'b0100111_010: name = "FSD"; default: name = "ILLEGAL"; endcase endmodule