From 4833b36535173a011eacf8ebcfbd3b0900a9e68e Mon Sep 17 00:00:00 2001 From: Noah Boorstin Date: Mon, 1 Mar 2021 18:50:42 +0000 Subject: [PATCH] busybear: more adapting to new memory system --- wally-pipelined/regression/wally-busybear.do | 14 +- wally-pipelined/src/uncore/dtim.sv | 22 +-- wally-pipelined/src/uncore/uncore.sv | 10 +- .../testbench/testbench-busybear.sv | 167 ++++++++---------- 4 files changed, 99 insertions(+), 114 deletions(-) diff --git a/wally-pipelined/regression/wally-busybear.do b/wally-pipelined/regression/wally-busybear.do index 4f7e4219..56d5398a 100644 --- a/wally-pipelined/regression/wally-busybear.do +++ b/wally-pipelined/regression/wally-busybear.do @@ -37,8 +37,10 @@ mem load -startaddress 0 -endaddress 2047 -filltype value -fillradix hex -fillda mem load -startaddress 512 -i "/courses/e190ax/busybear_boot/bootmem.txt" -format hex /testbench_busybear/dut/uncore/bootdtim/RAM mem load -startaddress 0 -endaddress 2047 -filltype value -fillradix hex -filldata 0 /testbench_busybear/dut/imem/bootram mem load -startaddress 512 -i "/courses/e190ax/busybear_boot/bootmem.txt" -format hex /testbench_busybear/dut/imem/bootram -mem load -startaddress 0 -endaddress 16777216 -filltype value -fillradix hex -filldata 0 /testbench_busybear/RAM -mem load -startaddress 0 -i "/courses/e190ax/busybear_boot/ram.txt" -format hex /testbench_busybear/RAM +mem load -startaddress 268435456 -endaddress 285212671 -filltype value -fillradix hex -filldata 0 /testbench_busybear/dut/uncore/maindtim/RAM +mem load -startaddress 268435456 -i "/courses/e190ax/busybear_boot/ram.txt" -format hex /testbench_busybear/dut/uncore/maindtim/RAM +mem load -startaddress 268435456 -endaddress 285212671 -filltype value -fillradix hex -filldata 0 /testbench_busybear/dut/imem/RAM +mem load -startaddress 268435456 -i "/courses/e190ax/busybear_boot/ram.txt" -format hex /testbench_busybear/dut/imem/RAM view wave @@ -57,7 +59,12 @@ add wave /testbench_busybear/lastCheckInstrF add wave /testbench_busybear/speculative add wave /testbench_busybear/lastPC2 add wave -divider -add wave -hex /testbench_busybear/readRAM +add wave /testbench_busybear/dut/uncore/HSELBootTim +add wave /testbench_busybear/dut/uncore/HSELTim +add wave /testbench_busybear/dut/uncore/HREADTim +add wave /testbench_busybear/dut/uncore/maindtim/HREADTim0 +add wave /testbench_busybear/dut/uncore/HREADYTim +add wave /testbench_busybear/dut/uncore/HADDR #add wave -hex /testbench_busybear/dut/hart/priv/csr/MTVEC_REG #add wave -hex /testbench_busybear/dut/hart/priv/csr/MSTATUS_REG #add wave -hex /testbench_busybear/dut/hart/priv/csr/SCOUNTEREN_REG @@ -73,6 +80,7 @@ add wave -hex /testbench_busybear/dut/hart/MemRWM[1] add wave -hex /testbench_busybear/HWDATA add wave -hex /testbench_busybear/HRDATA add wave -hex /testbench_busybear/HADDR +add wave -hex /testbench_busybear/readAdrExpected add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[1] add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[2] add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[3] diff --git a/wally-pipelined/src/uncore/dtim.sv b/wally-pipelined/src/uncore/dtim.sv index 009fb03d..cf7b39cc 100644 --- a/wally-pipelined/src/uncore/dtim.sv +++ b/wally-pipelined/src/uncore/dtim.sv @@ -28,7 +28,7 @@ module dtim #(parameter BASE=0, RANGE = 65535) ( input logic HCLK, HRESETn, input logic [1:0] MemRWtim, - input logic [18:0] HADDR, + input logic [31:0] HADDR, input logic [`XLEN-1:0] HWDATA, input logic HSELTim, output logic [`XLEN-1:0] HREADTim, @@ -36,8 +36,8 @@ module dtim #(parameter BASE=0, RANGE = 65535) ( ); //logic [`XLEN-1:0] RAM[0:65535]; - logic [`XLEN-1:0] RAM[BASE>>(1+`XLEN/32):(RANGE-BASE)>>1+(`XLEN/32)]; - logic [18:0] HWADDR; + logic [`XLEN-1:0] RAM[BASE>>(1+`XLEN/32):(RANGE+BASE)>>1+(`XLEN/32)]; + logic [31:0] HWADDR; logic [`XLEN-1:0] HREADTim0; // logic [`XLEN-1:0] write; @@ -83,21 +83,21 @@ module dtim #(parameter BASE=0, RANGE = 65535) ( generate if (`XLEN == 64) begin // always_ff @(negedge HCLK) -// if (memwrite) RAM[HWADDR[17:3]] <= HWDATA; +// if (memwrite) RAM[HWADDR[31:3]] <= HWDATA; always_ff @(posedge HCLK) begin - //if (memwrite) RAM[HADDR[17:3]] <= HWDATA; + //if (memwrite) RAM[HADDR[31:3]] <= HWDATA; HWADDR <= HADDR; - HREADTim0 <= RAM[HADDR[17:3]]; - if (memwrite && HREADYTim) RAM[HWADDR[17:3]] <= HWDATA; + HREADTim0 <= RAM[HADDR[31:3]]; + if (memwrite && HREADYTim) RAM[HWADDR[31:3]] <= HWDATA; end end else begin // always_ff @(negedge HCLK) -// if (memwrite) RAM[HWADDR[17:2]] <= HWDATA; +// if (memwrite) RAM[HWADDR[31:2]] <= HWDATA; always_ff @(posedge HCLK) begin - //if (memwrite) RAM[HADDR[17:2]] <= HWDATA; + //if (memwrite) RAM[HADDR[31:2]] <= HWDATA; HWADDR <= HADDR; - HREADTim0 <= RAM[HADDR[17:2]]; - if (memwrite && HREADYTim) RAM[HWADDR[17:2]] <= HWDATA; + HREADTim0 <= RAM[HADDR[31:2]]; + if (memwrite && HREADYTim) RAM[HWADDR[31:2]] <= HWDATA; end end endgenerate diff --git a/wally-pipelined/src/uncore/uncore.sv b/wally-pipelined/src/uncore/uncore.sv index ab66af9f..bcb60271 100644 --- a/wally-pipelined/src/uncore/uncore.sv +++ b/wally-pipelined/src/uncore/uncore.sv @@ -95,8 +95,8 @@ module uncore ( subwordwrite sww(.*); // tightly integrated memory - dtim #(.BASE(`TIMBASE), .RANGE(`TIMRANGE)) maindtim (.HADDR(HADDR[18:0]), .*); - dtim #(.BASE(`BOOTTIMBASE), .RANGE(`BOOTTIMRANGE)) bootdtim (.HADDR(HADDR[18:0]), .MemRWtim(MemRWboottim), + dtim #(.BASE(`TIMBASE), .RANGE(`TIMRANGE)) maindtim (.*); + dtim #(.BASE(`BOOTTIMBASE), .RANGE(`BOOTTIMRANGE)) bootdtim (.MemRWtim(MemRWboottim), .HSELTim(HSELBootTim), .HREADTim(HREADBootTim), .HRESPTim(HRESPBootTim), .HREADYTim(HREADYBootTim), .*); // memory-mapped I/O peripherals @@ -110,11 +110,11 @@ module uncore ( // AHB Read Multiplexer assign HRDATA = ({`XLEN{HSELTim}} & HREADTim) | ({`XLEN{HSELCLINT}} & HREADCLINT) | ({`XLEN{HSELBootTim}} & HREADBootTim) | ({`XLEN{HSELUART}} & HREADUART); - assign HRESP = HSELBootTim & HRESPBootTim | HSELTim & HRESPTim | HSELCLINT & HRESPCLINT | HSELGPIO & HRESPGPIO | HSELUART & HRESPUART; - assign HREADY = HSELBootTim & HREADYBootTim | HSELTim & HREADYTim | HSELCLINT & HREADYCLINT | HSELGPIO & HREADYGPIO | HSELUART & HREADYUART; + assign HRESP = HSELBootTim & HRESPBootTim | HSELTim & HRESPTim | HSELCLINT & HRESPCLINT | HSELUART & HRESPUART; + assign HREADY = HSELBootTim & HREADYBootTim | HSELTim & HREADYTim | HSELCLINT & HREADYCLINT | HSELUART & HREADYUART; // Faults - assign DataAccessFaultM = ~(HSELTim | HSELCLINT | HSELGPIO | HSELUART); + assign DataAccessFaultM = ~(HSELTim | HSELCLINT | HSELUART); endmodule diff --git a/wally-pipelined/testbench/testbench-busybear.sv b/wally-pipelined/testbench/testbench-busybear.sv index 7a59cc52..39638839 100644 --- a/wally-pipelined/testbench/testbench-busybear.sv +++ b/wally-pipelined/testbench/testbench-busybear.sv @@ -174,52 +174,27 @@ module testbench_busybear(); // In the linux boot, the processor spends the first ~5 instructions in // bootram, before jr jumps to main RAM - logic [`XLEN-1:0] RAM[('h8000000 >> 3):0]; - logic [`XLEN-1:0] bootram[('h2000 >> 3):0]; - logic [`XLEN-1:0] readRAM; - integer RAMAdr, RAMPC; - assign RAMAdr = (HADDR - (HADDR > 'h2fff ? 'h80000000 : 'h1000)) >> 3; - assign RAMPC = (dut.PCF - (dut.PCF > 'h2fff ? 'h80000000 : 'h1000)) >> 3; logic [63:0] readMask; assign readMask = ((1 << (8*(1 << HSIZE))) - 1) << 8 * HADDR[2:0]; logic [`XLEN-1:0] readAdrExpected; - always @(HWDATA or HADDR or HSIZE or HWRITE or dut.hart.MemRWM[1]) begin - - if ((HWRITE || dut.hart.MemRWM[1]) && (HADDR >= 'h80000000 && HADDR <= 'h87FFFFFF)) begin - if (HWRITE) begin - RAM[RAMAdr] = (RAM[RAMAdr] & (~readMask)) | ((HWDATA << 8 * HADDR[2:0]) & readMask); // aligns write data for correct subword size - end else begin - readRAM = RAM[RAMAdr] & readMask; - end - end - - if ((HWRITE || dut.hart.MemRWM[1]) && (HADDR >= 'h1000 && HADDR <= 'h2FFF)) begin - if (HWRITE) begin - bootram[RAMAdr] = (bootram[RAMAdr] & (~readMask)) | ((HWDATA << 8 * HADDR[2:0]) & readMask); - end else begin - readRAM = bootram[RAMAdr] & readMask; - end - end - end - always @(dut.hart.MemRWM[1] or HADDR) begin - if (dut.hart.MemRWM[1]) begin + if (dut.hart.MemRWM[1] && HADDR != dut.PCF) begin 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); - #1; + #2; if (~equal(HADDR,readAdrExpected,4)) begin $display("%0t ps, instr %0d: HADDR does not equal readAdrExpected: %x, %x", $time, instrs, HADDR, readAdrExpected); `ERROR end - if (((readMask & HRDATA) !== (readMask & readRAM)) && (HADDR >= 'h80000000 && HADDR <= 'h87FFFFFF)) begin - $display("warning %0t ps, instr %0d: HRDATA does not equal readRAM: %x, %x from address %x, %x", $time, instrs, HRDATA, readRAM, HADDR, HSIZE); + if (((readMask & HRDATA) !== (readMask & dut.HRDATA)) && (HADDR >= 'h80000000 && HADDR <= 'h87FFFFFF)) begin + $display("warning %0t ps, instr %0d: HRDATA does not equal dut.HRDATA: %x, %x from address %x, %x", $time, instrs, HRDATA, dut.HRDATA, HADDR, HSIZE); warningCount += 1; `ERROR end @@ -360,79 +335,81 @@ module testbench_busybear(); end logic [31:0] InstrMask; logic forcedInstr; - always @(dut.PCF) begin - lastCheckInstrF = CheckInstrF; - lastPC <= dut.PCF; - lastPC2 <= lastPC; - if (speculative && (lastPC != pcExpected)) begin - speculative = ~equal(dut.PCF,pcExpected,3); - end - else begin - if($feof(data_file_PC)) begin - $display("no more PC data to read"); - `ERROR - end - scan_file_PC = $fscanf(data_file_PC, "%s\n", PCtext); - if (PCtext != "ret" && PCtext != "fence" && PCtext != "nop" && PCtext != "mret" && PCtext != "sfence.vma" && PCtext != "unimp") begin - scan_file_PC = $fscanf(data_file_PC, "%s\n", PCtext2); - PCtext = {PCtext, " ", PCtext2}; - end - scan_file_PC = $fscanf(data_file_PC, "%x\n", CheckInstrF); - if(CheckInstrF[6:0] == 7'b1010011) begin // for now, NOP out any float instrs - CheckInstrF = 32'b0010011; - $display("warning: NOPing out %s at PC=%0x", PCtext, dut.PCF); - warningCount += 1; - forcedInstr = 1; + always @(dut.PCF or dut.hart.ifu.InstrF) begin + if (~reset && dut.hart.ifu.InstrF !== {32{1'bx}}) begin + lastCheckInstrF = CheckInstrF; + lastPC <= dut.PCF; + lastPC2 <= lastPC; + if (speculative && (lastPC != pcExpected)) begin + speculative = ~equal(dut.PCF,pcExpected,3); end else begin - if(CheckInstrF[28:27] != 2'b11 && CheckInstrF[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD - CheckInstrF = {12'b0, CheckInstrF[19:7], 7'b0000011}; - $display("warning: replacing AMO instr %s at PC=%0x with ld", PCtext, dut.PCF); + if($feof(data_file_PC)) begin + $display("no more PC data to read"); + `ERROR + end + scan_file_PC = $fscanf(data_file_PC, "%s\n", PCtext); + if (PCtext != "ret" && PCtext != "fence" && PCtext != "nop" && PCtext != "mret" && PCtext != "sfence.vma" && PCtext != "unimp") begin + scan_file_PC = $fscanf(data_file_PC, "%s\n", PCtext2); + PCtext = {PCtext, " ", PCtext2}; + end + scan_file_PC = $fscanf(data_file_PC, "%x\n", CheckInstrF); + if(CheckInstrF[6:0] == 7'b1010011) begin // for now, NOP out any float instrs + CheckInstrF = 32'b0010011; + $display("warning: NOPing out %s at PC=%0x", PCtext, dut.PCF); warningCount += 1; forcedInstr = 1; end else begin - forcedInstr = 0; + if(CheckInstrF[28:27] != 2'b11 && CheckInstrF[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD + CheckInstrF = {12'b0, CheckInstrF[19:7], 7'b0000011}; + $display("warning: replacing AMO instr %s at PC=%0x with ld", PCtext, dut.PCF); + warningCount += 1; + forcedInstr = 1; + end + else begin + forcedInstr = 0; + end end - end - // then expected PC value - scan_file_PC = $fscanf(data_file_PC, "%x\n", pcExpected); - if (instrs <= 10 || (instrs <= 100 && instrs % 10 == 0) || - (instrs <= 1000 && instrs % 100 == 0) || (instrs <= 10000 && instrs % 1000 == 0) || - (instrs <= 100000 && instrs % 10000 == 0) || (instrs <= 1000000 && instrs % 100000 == 0)) begin - $display("loaded %0d instructions", instrs); - end - instrs += 1; - // are we at a branch/jump? - casex (lastCheckInstrF[31:0]) - 32'b00000000001000000000000001110011, // URET - 32'b00010000001000000000000001110011, // SRET - 32'b00110000001000000000000001110011, // MRET - 32'bXXXXXXXXXXXXXXXXXXXXXXXXX1101111, // JAL - 32'bXXXXXXXXXXXXXXXXXXXXXXXXX1100111, // JALR - 32'bXXXXXXXXXXXXXXXXXXXXXXXXX1100011, // B - 32'bXXXXXXXXXXXXXXXX110XXXXXXXXXXX01, // C.BEQZ - 32'bXXXXXXXXXXXXXXXX111XXXXXXXXXXX01, // C.BNEZ - 32'bXXXXXXXXXXXXXXXX101XXXXXXXXXXX01: // C.J - speculative = 1; - 32'bXXXXXXXXXXXXXXXX1001000000000010: // C.EBREAK: - speculative = 0; // tbh don't really know what should happen here - 32'bXXXXXXXXXXXXXXXX1000XXXXX0000010, // C.JR - 32'bXXXXXXXXXXXXXXXX1001XXXXX0000010: // C.JALR //this is RV64 only so no C.JAL - speculative = 1; - default: - speculative = 0; - endcase + // then expected PC value + scan_file_PC = $fscanf(data_file_PC, "%x\n", pcExpected); + if (instrs <= 10 || (instrs <= 100 && instrs % 10 == 0) || + (instrs <= 1000 && instrs % 100 == 0) || (instrs <= 10000 && instrs % 1000 == 0) || + (instrs <= 100000 && instrs % 10000 == 0) || (instrs <= 1000000 && instrs % 100000 == 0)) begin + $display("loaded %0d instructions", instrs); + end + instrs += 1; + // are we at a branch/jump? + casex (lastCheckInstrF[31:0]) + 32'b00000000001000000000000001110011, // URET + 32'b00010000001000000000000001110011, // SRET + 32'b00110000001000000000000001110011, // MRET + 32'bXXXXXXXXXXXXXXXXXXXXXXXXX1101111, // JAL + 32'bXXXXXXXXXXXXXXXXXXXXXXXXX1100111, // JALR + 32'bXXXXXXXXXXXXXXXXXXXXXXXXX1100011, // B + 32'bXXXXXXXXXXXXXXXX110XXXXXXXXXXX01, // C.BEQZ + 32'bXXXXXXXXXXXXXXXX111XXXXXXXXXXX01, // C.BNEZ + 32'bXXXXXXXXXXXXXXXX101XXXXXXXXXXX01: // C.J + speculative = 1; + 32'bXXXXXXXXXXXXXXXX1001000000000010: // C.EBREAK: + speculative = 0; // tbh don't really know what should happen here + 32'bXXXXXXXXXXXXXXXX1000XXXXX0000010, // C.JR + 32'bXXXXXXXXXXXXXXXX1001XXXXX0000010: // C.JALR //this is RV64 only so no C.JAL + speculative = 1; + default: + speculative = 0; + endcase - //check things! - if ((~speculative) && (~equal(dut.PCF,pcExpected,3))) begin - $display("%0t ps, instr %0d: PC does not equal PC expected: %x, %x", $time, instrs, dut.PCF, pcExpected); - `ERROR - end - InstrMask = CheckInstrF[1:0] == 2'b11 ? 32'hFFFFFFFF : 32'h0000FFFF; - if ((~forcedInstr) && (~speculative) && ((InstrMask & dut.InstrF) !== (InstrMask & CheckInstrF))) begin - $display("%0t ps, instr %0d: InstrF does not equal CheckInstrF: %x, %x, PC: %x", $time, instrs, dut.InstrF, CheckInstrF, dut.PCF); - `ERROR + //check things! + if ((~speculative) && (~equal(dut.PCF,pcExpected,3))) begin + $display("%0t ps, instr %0d: PC does not equal PC expected: %x, %x", $time, instrs, dut.PCF, pcExpected); + `ERROR + end + InstrMask = CheckInstrF[1:0] == 2'b11 ? 32'hFFFFFFFF : 32'h0000FFFF; + if ((~forcedInstr) && (~speculative) && ((InstrMask & dut.hart.ifu.InstrF) !== (InstrMask & CheckInstrF))) begin + $display("%0t ps, instr %0d: InstrF does not equal CheckInstrF: %x, %x, PC: %x", $time, instrs, dut.hart.ifu.InstrF, CheckInstrF, dut.PCF); + `ERROR + end end end end @@ -440,7 +417,7 @@ module testbench_busybear(); // Track names of instructions string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; logic [31:0] InstrW; - instrNameDecTB dec(dut.InstrF, InstrFName); + instrNameDecTB dec(dut.hart.ifu.InstrF, InstrFName); instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE, dut.hart.ifu.InstrD, dut.hart.ifu.InstrE, dut.hart.ifu.InstrM, InstrW,