diff --git a/wally-pipelined/testbench/testbench-busybear.sv b/wally-pipelined/testbench/testbench-busybear.sv deleted file mode 100644 index c3c84de2..00000000 --- a/wally-pipelined/testbench/testbench-busybear.sv +++ /dev/null @@ -1,716 +0,0 @@ -`include "wally-config.vh" - - -module testbench(); - logic clk, reset; - logic [31:0] GPIOPinsIn; - logic [31:0] GPIOPinsOut, GPIOPinsEn; - - // instantiate device to be tested - logic [31:0] CheckInstrD; - - logic [`AHBW-1:0] HRDATA; - logic [31:0] HADDR; - logic [`AHBW-1:0] HWDATA; - logic HWRITE; - logic [2:0] HSIZE; - logic [2:0] HBURST; - logic [3:0] HPROT; - logic [1:0] HTRANS; - logic HMASTLOCK; - logic HCLK, HRESETn; - logic [`AHBW-1:0] HRDATAEXT; - logic HREADYEXT, HRESPEXT; - logic UARTSout; - - assign GPIOPinsIn = 0; - assign UARTSin = 1; - - // instantiate processor and memories - wallypipelinedsoc dut(.*); - - /** - * Walk the page table stored in dtim according to sv39 logic and translate a - * virtual address to a physical address. - * - * See section 4.3.2 of the RISC-V Privileged specification for a full - * explanation of the below algorithm. - */ - function logic [`XLEN-1:0] adrTranslator( - input logic [`XLEN-1:0] adrIn); - begin - logic SvMode, PTE_R, PTE_X; - logic [`XLEN-1:0] SATP, PTE; - logic [55:0] BaseAdr, PAdr; - logic [8:0] VPN [0:2]; - logic [11:0] Offset; - - int i; - - // Grab the SATP register from privileged unit - SATP = dut.hart.priv.csr.SATP_REGW; - - // Split the virtual address into page number segments and offset - VPN[2] = adrIn[38:30]; - VPN[1] = adrIn[29:21]; - VPN[0] = adrIn[20:12]; - Offset = adrIn[11:0]; - - // We do not support sv48; only sv39 - SvMode = SATP[63]; - - // Only perform translation if translation is on and the processor is not - // in machine mode - if (SvMode && (dut.hart.priv.PrivilegeModeW != `M_MODE)) begin - BaseAdr = SATP[43:0] << 12; - - for (i = 2; i >= 0; i--) begin - PAdr = BaseAdr + (VPN[i] << 3); - - // dtim.RAM is 64-bit addressed. PAdr specifies a byte. We right shift - // by 3 (the PTE size) to get the requested 64-bit PTE. - PTE = dut.uncore.dtim.RAM[PAdr >> 3]; - PTE_R = PTE[1]; - PTE_X = PTE[3]; - if (PTE_R || PTE_X) begin - // Leaf page found - break; - end else begin - // Go to next level of table - BaseAdr = PTE[53:10] << 12; - end - end - - // Determine which parts of the PTE page number to use based on the - // level of the page table we reached. - if (i == 2) begin - // Gigapage - assign adrTranslator = {8'b0, PTE[53:28], VPN[1], VPN[0], Offset}; - end else if (i == 1) begin - // Megapage - assign adrTranslator = {8'b0, PTE[53:19], VPN[0], Offset}; - end else begin - // Kilopage - assign adrTranslator = {8'b0, PTE[53:10], Offset}; - end - end else begin - // Direct translation if address translation is not on - assign adrTranslator = adrIn; - end - end - endfunction - - // initialize test - initial - begin - reset <= 1; # 22; reset <= 0; - end - - // read pc trace file - integer data_file_PC, scan_file_PC; - initial begin - data_file_PC = $fopen({`LINUX_TEST_VECTORS,"parsedPC.txt"}, "r"); - if (data_file_PC == 0) begin - $display("file couldn't be opened"); - $stop; - end - end - - integer data_file_PCW, scan_file_PCW; - initial begin - data_file_PCW = $fopen({`LINUX_TEST_VECTORS,"parsedPC.txt"}, "r"); - if (data_file_PCW == 0) begin - $display("file couldn't be opened"); - $stop; - end - end - - // read register trace file - integer data_file_rf, scan_file_rf; - initial begin - data_file_rf = $fopen({`LINUX_TEST_VECTORS,"parsedRegs.txt"}, "r"); - if (data_file_rf == 0) begin - $display("file couldn't be opened"); - $stop; - end - end - - // read CSR trace file - integer data_file_csr, scan_file_csr; - initial begin - data_file_csr = $fopen({`LINUX_TEST_VECTORS,"parsedCSRs2.txt"}, "r"); - if (data_file_csr == 0) begin - $display("file couldn't be opened"); - $stop; - end - end - - // read memreads trace file - integer data_file_memR, scan_file_memR; - initial begin - data_file_memR = $fopen({`LINUX_TEST_VECTORS,"parsedMemRead.txt"}, "r"); - if (data_file_memR == 0) begin - $display("file couldn't be opened"); - $stop; - end - end - - // read memwrite trace file - integer data_file_memW, scan_file_memW; - initial begin - data_file_memW = $fopen({`LINUX_TEST_VECTORS,"parsedMemWrite.txt"}, "r"); - if (data_file_memW == 0) begin - $display("file couldn't be opened"); - $stop; - end - end - - // initial loading of memories - initial begin - $readmemh({`LINUX_TEST_VECTORS,"bootmem.txt"}, dut.uncore.bootdtim.RAM, 'h1000 >> 3); // load at address 0x1000, start of boot TIM - $readmemh({`LINUX_TEST_VECTORS,"ram.txt"}, dut.uncore.dtim.RAM); - $readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.bpred.Predictor.DirPredictor.PHT.memory); - $readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.bpred.TargetPredictor.memory.memory); - end - - integer warningCount = 0; - integer instrs; - - //logic[63:0] adrTranslation[4:0]; - //string translationType[4:0] = {"rf", "writeAdr", "PCW", "PC", "readAdr"}; - //initial begin - // for(int i=0; i<5; i++) begin - // adrTranslation[i] = 64'b0; - // end - //end - - //function logic equal(logic[63:0] adr, logic[63:0] adrExpected, integer func); - // if (adr[11:0] !== adrExpected[11:0]) begin - // equal = 1'b0; - // end else begin - // equal = 1'b1; - // if ((adr+adrTranslation[func]) !== adrExpected) begin - // adrTranslation[func] = adrExpected - adr; - // $display("warning: probably new address translation %x for %s at instr %0d", adrTranslation[func], translationType[func], instrs); - // warningCount += 1; - // end - // end - //endfunction - - // pretty sure this isn't necessary anymore, but keeping this for now since its easier - function logic equal(logic[63:0] adr, logic[63:0] adrExpected, integer func); - equal = adr === adrExpected; - endfunction - - - `define ERROR \ - #10; \ - $display("processed %0d instructions with %0d warnings", instrs, warningCount); \ - $stop; - - logic [63:0] pcExpected; - logic [63:0] regExpected; - integer regNumExpected; - logic [`XLEN-1:0] PCW; - - flopenr #(`XLEN) PCWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.PCM, PCW); - - genvar i; - generate - for(i=1; i<32; i++) begin - always @(dut.hart.ieu.dp.regf.rf[i]) begin - if ($time == 0) begin - scan_file_rf = $fscanf(data_file_rf, "%x\n", regExpected); - if (dut.hart.ieu.dp.regf.rf[i] != regExpected) begin - $display("%0t ps, instr %0d: rf[%0d] does not equal rf expected: %x, %x", $time, instrs, i, dut.hart.ieu.dp.regf.rf[i], regExpected); - `ERROR - end - end else begin - scan_file_rf = $fscanf(data_file_rf, "%d\n", regNumExpected); - scan_file_rf = $fscanf(data_file_rf, "%x\n", regExpected); - if (i != regNumExpected) begin - $display("%0t ps, instr %0d: wrong register changed: %0d, %0d expected to switch to %x from %x", $time, instrs, i, regNumExpected, regExpected, dut.hart.ieu.dp.regf.rf[regNumExpected]); - `ERROR - end - if (~equal(dut.hart.ieu.dp.regf.rf[i],regExpected, 0)) begin - $display("%0t ps, instr %0d: rf[%0d] does not equal rf expected: %x, %x", $time, instrs, i, dut.hart.ieu.dp.regf.rf[i], regExpected); - `ERROR - end - //if (dut.hart.ieu.dp.regf.rf[i] !== regExpected) begin - // force dut.hart.ieu.dp.regf.rf[i] = regExpected; - // release dut.hart.ieu.dp.regf.rf[i]; - //end - end - end - end - endgenerate - - // RAM and bootram are addressed in 64-bit blocks - this logic handles R/W - // including subwords. Brief explanation on signals: - // - // readMask: bitmask of bits to read / write, left-shifted to align with - // nearest 64-bit boundary - examples - // HSIZE = 0 -> readMask = 11111111 - // HSIZE = 1 -> readMask = 1111111111111111 - // - // In the linux boot, the processor spends the first ~5 instructions in - // bootram, before jr jumps to main RAM - - logic [63:0] readMask; - assign readMask = ((1 << (8*(1 << HSIZE))) - 1) << 8 * HADDR[2:0]; - - logic [`XLEN-1:0] readAdrExpected, readAdrTranslated; - - always @(dut.HRDATA) begin - #2; - if (dut.hart.MemRWM[1] - && (dut.hart.ebu.CaptureDataM) - && dut.HRDATA !== {64{1'bx}}) begin - //$display("%0t", $time); - if($feof(data_file_memR)) begin - $display("no more memR data to read"); - `ERROR - end - scan_file_memR = $fscanf(data_file_memR, "%x\n", readAdrExpected); - scan_file_memR = $fscanf(data_file_memR, "%x\n", HRDATA); - assign readAdrTranslated = adrTranslator(readAdrExpected); - if (~equal(HADDR,readAdrTranslated,4)) begin - $display("%0t ps, instr %0d: HADDR does not equal readAdrExpected: %x, %x", $time, instrs, HADDR, readAdrTranslated); - `ERROR - end - if ((readMask & HRDATA) !== (readMask & dut.HRDATA)) begin - if (HADDR inside `LINUX_FIX_READ) begin - //$display("warning %0t ps, instr %0d, adr %0d: forcing HRDATA to expected: %x, %x", $time, instrs, HADDR, HRDATA, dut.HRDATA); - force dut.uncore.HRDATA = HRDATA; - #9; - release dut.uncore.HRDATA; - warningCount += 1; - end else begin - $display("%0t ps, instr %0d: ExpectedHRDATA does not equal dut.HRDATA: %x, %x from address %x, %x", $time, instrs, HRDATA, dut.HRDATA, HADDR, HSIZE); - `ERROR - end - end - //end else if(dut.hart.MemRWM[1]) begin - // $display("%x, %x, %x, %t", HADDR, dut.PCF, dut.HRDATA, $time); - - end - - end - - logic [`XLEN-1:0] writeDataExpected, writeAdrExpected, writeAdrTranslated; - - // this might need to change - //always @(HWDATA or HADDR or HSIZE or HWRITE) begin - always @(negedge HWRITE) begin - //#1; - if ($time != 0) begin - if($feof(data_file_memW)) begin - $display("no more memW data to read"); - `ERROR - end - scan_file_memW = $fscanf(data_file_memW, "%x\n", writeDataExpected); - scan_file_memW = $fscanf(data_file_memW, "%x\n", writeAdrExpected); - assign writeAdrTranslated = adrTranslator(writeAdrExpected); - - if (writeDataExpected != HWDATA && ~dut.uncore.HSELPLICD) begin - $display("%0t ps, instr %0d: HWDATA does not equal writeDataExpected: %x, %x", $time, instrs, HWDATA, writeDataExpected); - `ERROR - end - if (~equal(writeAdrTranslated,HADDR,1) && ~dut.uncore.HSELPLICD) begin - $display("%0t ps, instr %0d: HADDR does not equal writeAdrExpected: %x, %x", $time, instrs, HADDR, writeAdrTranslated); - `ERROR - end - end - end - - integer totalCSR = 0; - logic [99:0] StartCSRexpected[63:0]; - string StartCSRname[99:0]; - initial begin - while(1) begin - scan_file_csr = $fscanf(data_file_csr, "%s\n", StartCSRname[totalCSR]); - if(StartCSRname[totalCSR] == "---") begin - break; - end - scan_file_csr = $fscanf(data_file_csr, "%x\n", StartCSRexpected[totalCSR]); - totalCSR = totalCSR + 1; - end - end - - always @(dut.hart.priv.csr.genblk1.csrm.MCAUSE_REGW) begin - if (dut.hart.priv.csr.genblk1.csrm.MCAUSE_REGW == 2 && instrs > 1) begin - $display("!!!!!! illegal instruction !!!!!!!!!!"); - $display("(as a reminder, MCAUSE and MEPC are set by this)"); - $display("at %0t ps, instr %0d, HADDR %x", $time, instrs, HADDR); - `ERROR - end - if (dut.hart.priv.csr.genblk1.csrm.MCAUSE_REGW == 5 && instrs != 0) begin - $display("!!!!!! illegal (physical) memory access !!!!!!!!!!"); - $display("(as a reminder, MCAUSE and MEPC are set by this)"); - $display("at %0t ps, instr %0d, HADDR %x", $time, instrs, HADDR); - `ERROR - end - end - - `define CHECK_CSR2(CSR, PATH) \ - string CSR; \ - logic [63:0] expected``CSR``; \ - //CSR checking \ - always @(``PATH``.``CSR``_REGW) begin \ - if ($time > 1) begin \ - if ("SEPC" == `"CSR`") begin #1; end \ - if ("SCAUSE" == `"CSR`") begin #2; end \ - if ("SSTATUS" == `"CSR`") begin #3; end \ - scan_file_csr = $fscanf(data_file_csr, "%s\n", CSR); \ - scan_file_csr = $fscanf(data_file_csr, "%x\n", expected``CSR``); \ - if(CSR.icompare(`"CSR`")) begin \ - $display("%0t ps, instr %0d: %s changed, expected %s", $time, instrs, `"CSR`", CSR); \ - end \ - if(``PATH``.``CSR``_REGW != ``expected``CSR) begin \ - $display("%0t ps, instr %0d: %s does not equal %s expected: %x, %x", $time, instrs, `"CSR`", CSR, ``PATH``.``CSR``_REGW, ``expected``CSR); \ - `ERROR \ - end \ - end else begin \ - if (!(`BUILDROOT == 1 && "MSTATUS" == `"CSR`")) begin \ - for(integer j=0; j