forked from Github_Repos/cvw
busybear: more adapting to new memory system
This commit is contained in:
parent
26d4024b33
commit
4833b36535
@ -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]
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user