2021-01-24 22:10:00 +00:00
|
|
|
`include "wally-config.vh"
|
2021-01-21 21:17:34 +00:00
|
|
|
|
2021-01-24 22:10:00 +00:00
|
|
|
module testbench_busybear();
|
2021-01-21 21:17:34 +00:00
|
|
|
|
2021-01-21 22:55:05 +00:00
|
|
|
logic clk, reset;
|
|
|
|
logic [31:0] GPIOPinsIn;
|
|
|
|
logic [31:0] GPIOPinsOut, GPIOPinsEn;
|
2021-01-21 21:17:34 +00:00
|
|
|
|
|
|
|
// instantiate device to be tested
|
2021-01-30 17:38:18 +00:00
|
|
|
logic [`XLEN-1:0] PCF;
|
2021-01-21 22:55:05 +00:00
|
|
|
logic [31:0] InstrF;
|
|
|
|
logic InstrAccessFaultF, DataAccessFaultM;
|
2021-01-25 01:43:47 +00:00
|
|
|
logic TimerIntM = 0, SwIntM = 0; // from CLINT
|
2021-01-21 22:55:05 +00:00
|
|
|
logic ExtIntM = 0; // not yet connected
|
2021-01-23 22:52:05 +00:00
|
|
|
|
2021-01-29 17:46:50 +00:00
|
|
|
logic [`AHBW-1:0] HRDATA;
|
|
|
|
logic HREADY, HRESP;
|
|
|
|
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;
|
2021-01-30 17:38:18 +00:00
|
|
|
logic HCLK, HRESETn;
|
2021-01-29 17:46:50 +00:00
|
|
|
|
|
|
|
assign GPIOPinsIn = 0;
|
|
|
|
assign UARTSin = 1;
|
|
|
|
assign HREADY = 1;
|
|
|
|
assign HRESP = 0;
|
|
|
|
assign HRDATA = 0;
|
|
|
|
|
2021-01-23 22:52:05 +00:00
|
|
|
// for now, seem to need these to be zero until we get a better idea
|
|
|
|
assign InstrAccessFaultF = 0;
|
|
|
|
assign DataAccessFaultM = 0;
|
2021-01-21 22:55:05 +00:00
|
|
|
|
|
|
|
// instantiate processor and memories
|
2021-01-28 06:21:47 +00:00
|
|
|
wallypipelinedhart dut(.*);
|
2021-01-21 21:17:34 +00:00
|
|
|
|
|
|
|
// initialize test
|
|
|
|
initial
|
|
|
|
begin
|
2021-01-21 22:55:05 +00:00
|
|
|
reset <= 1; # 22; reset <= 0;
|
2021-01-21 21:17:34 +00:00
|
|
|
end
|
2021-01-22 19:11:17 +00:00
|
|
|
|
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.
2021-01-23 01:27:01 +00:00
|
|
|
// read pc trace file
|
|
|
|
integer data_file_PC, scan_file_PC;
|
2021-01-22 19:11:17 +00:00
|
|
|
initial begin
|
2021-01-26 01:37:18 +00:00
|
|
|
data_file_PC = $fopen("../busybear-testgen/parsedPC.txt", "r");
|
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.
2021-01-23 01:27:01 +00:00
|
|
|
if (data_file_PC == 0) begin
|
2021-01-22 19:11:17 +00:00
|
|
|
$display("file couldn't be opened");
|
|
|
|
$stop;
|
|
|
|
end
|
|
|
|
end
|
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.
2021-01-23 01:27:01 +00:00
|
|
|
|
2021-02-01 23:57:06 +00:00
|
|
|
integer data_file_PCW, scan_file_PCW;
|
|
|
|
initial begin
|
|
|
|
data_file_PCW = $fopen("../busybear-testgen/parsedPC.txt", "r");
|
|
|
|
if (data_file_PCW == 0) begin
|
|
|
|
$display("file couldn't be opened");
|
|
|
|
$stop;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
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.
2021-01-23 01:27:01 +00:00
|
|
|
// read register trace file
|
|
|
|
integer data_file_rf, scan_file_rf;
|
|
|
|
initial begin
|
2021-01-26 01:37:18 +00:00
|
|
|
data_file_rf = $fopen("../busybear-testgen/parsedRegs.txt", "r");
|
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.
2021-01-23 01:27:01 +00:00
|
|
|
if (data_file_rf == 0) begin
|
|
|
|
$display("file couldn't be opened");
|
|
|
|
$stop;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-02-02 03:08:11 +00:00
|
|
|
// read CSR trace file
|
|
|
|
integer data_file_csr, scan_file_csr;
|
|
|
|
initial begin
|
|
|
|
data_file_csr = $fopen("../busybear-testgen/parsedCSRs.txt", "r");
|
|
|
|
if (data_file_csr == 0) begin
|
|
|
|
$display("file couldn't be opened");
|
|
|
|
$stop;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
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.
2021-01-23 01:27:01 +00:00
|
|
|
// read memreads trace file
|
2021-01-25 01:43:47 +00:00
|
|
|
integer data_file_memR, scan_file_memR;
|
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.
2021-01-23 01:27:01 +00:00
|
|
|
initial begin
|
2021-01-26 01:37:18 +00:00
|
|
|
data_file_memR = $fopen("../busybear-testgen/parsedMemRead.txt", "r");
|
2021-01-25 01:43:47 +00:00
|
|
|
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
|
2021-01-26 01:37:18 +00:00
|
|
|
data_file_memW = $fopen("../busybear-testgen/parsedMemWrite.txt", "r");
|
2021-01-25 01:43:47 +00:00
|
|
|
if (data_file_memW == 0) begin
|
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.
2021-01-23 01:27:01 +00:00
|
|
|
$display("file couldn't be opened");
|
|
|
|
$stop;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-01-22 20:05:58 +00:00
|
|
|
logic [63:0] pcExpected;
|
2021-02-02 01:27:43 +00:00
|
|
|
logic [63:0] regExpected;
|
|
|
|
integer regNumExpected;
|
|
|
|
|
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.
2021-01-23 01:27:01 +00:00
|
|
|
genvar i;
|
|
|
|
generate
|
2021-02-02 01:27:43 +00:00
|
|
|
for(i=1; i<32; i++) begin
|
|
|
|
always @(dut.ieu.dp.regf.rf[i]) begin
|
|
|
|
if ($time != 0) 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("%t ps, instr %0d: wrong register changed: %0d, %0d expected", $time, instrs, i, regNumExpected);
|
|
|
|
end
|
|
|
|
if (dut.ieu.dp.regf.rf[i] != regExpected) begin
|
|
|
|
$display("%t ps, instr %0d: rf[%0d] does not equal rf expected: %x, %x", $time, instrs, i, dut.ieu.dp.regf.rf[i], regExpected);
|
|
|
|
end
|
|
|
|
end
|
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.
2021-01-23 01:27:01 +00:00
|
|
|
end
|
|
|
|
end
|
2021-02-02 01:27:43 +00:00
|
|
|
endgenerate
|
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.
2021-01-23 01:27:01 +00:00
|
|
|
|
2021-01-28 18:16:38 +00:00
|
|
|
logic [`XLEN-1:0] readAdrExpected;
|
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.
2021-01-23 01:27:01 +00:00
|
|
|
// this might need to change
|
2021-01-30 17:38:18 +00:00
|
|
|
always @(dut.MemRWM[1] or HADDR) begin
|
|
|
|
if (dut.MemRWM[1]) begin
|
2021-01-28 18:16:38 +00:00
|
|
|
if($feof(data_file_memR)) begin
|
|
|
|
$display("no more memR data to read");
|
|
|
|
$stop;
|
|
|
|
end
|
|
|
|
scan_file_memR = $fscanf(data_file_memR, "%x\n", readAdrExpected);
|
2021-01-30 17:38:18 +00:00
|
|
|
scan_file_memR = $fscanf(data_file_memR, "%x\n", HRDATA);
|
|
|
|
#1;
|
|
|
|
if (HADDR != readAdrExpected) begin
|
|
|
|
$display("%t ps, instr %0d: HADDR does not equal readAdrExpected: %x, %x", $time, instrs, HADDR, readAdrExpected);
|
2021-01-28 18:16:38 +00:00
|
|
|
end
|
2021-01-25 01:43:47 +00:00
|
|
|
end
|
|
|
|
end
|
2021-01-30 17:38:18 +00:00
|
|
|
|
2021-01-26 01:06:13 +00:00
|
|
|
logic [`XLEN-1:0] writeDataExpected, writeAdrExpected;
|
2021-01-25 01:43:47 +00:00
|
|
|
// this might need to change
|
2021-01-30 17:38:18 +00:00
|
|
|
always @(HWDATA or HADDR or HSIZE) begin
|
2021-01-26 01:06:13 +00:00
|
|
|
#1;
|
2021-01-30 17:38:18 +00:00
|
|
|
if (HWRITE) begin
|
2021-01-28 18:16:38 +00:00
|
|
|
if($feof(data_file_memW)) begin
|
|
|
|
$display("no more memW data to read");
|
|
|
|
$stop;
|
|
|
|
end
|
2021-01-25 01:43:47 +00:00
|
|
|
scan_file_memW = $fscanf(data_file_memW, "%x\n", writeDataExpected);
|
2021-01-26 01:06:13 +00:00
|
|
|
scan_file_memW = $fscanf(data_file_memW, "%x\n", writeAdrExpected);
|
2021-01-30 17:38:18 +00:00
|
|
|
if (writeDataExpected != HWDATA) begin
|
|
|
|
$display("%t ps, instr %0d: HWDATA does not equal writeDataExpected: %x, %x", $time, instrs, HWDATA, writeDataExpected);
|
2021-01-26 01:06:13 +00:00
|
|
|
end
|
2021-01-30 17:38:18 +00:00
|
|
|
if (writeAdrExpected != HADDR) begin
|
|
|
|
$display("%t ps, instr %0d: HADDR does not equal writeAdrExpected: %x, %x", $time, instrs, HADDR, writeAdrExpected);
|
2021-01-25 01:43:47 +00:00
|
|
|
end
|
2021-01-22 20:05:58 +00:00
|
|
|
end
|
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.
2021-01-23 01:27:01 +00:00
|
|
|
end
|
|
|
|
|
2021-02-02 06:06:03 +00:00
|
|
|
`define CHECK_CSR(CSR) \
|
|
|
|
string CSR; \
|
|
|
|
logic [63:0] expected``CSR``; \
|
|
|
|
//CSR checking \
|
|
|
|
always @(dut.priv.csr.``CSR``_REGW) begin \
|
|
|
|
if ($time > 1) begin \
|
|
|
|
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("%t ps, instr %0d: %s changed, expected %s", $time, instrs, `"CSR`", CSR); \
|
|
|
|
end \
|
|
|
|
if(dut.priv.csr.``CSR``_REGW != ``expected``CSR) begin \
|
|
|
|
$display("%t ps, instr %0d: %s does not equal %s expected: %x, %x", $time, instrs, CSR, CSR, dut.priv.csr.``CSR``_REGW, ``expected``CSR); \
|
|
|
|
end \
|
|
|
|
end \
|
|
|
|
end
|
|
|
|
|
|
|
|
//`CHECK_CSR(FCSR)
|
|
|
|
`CHECK_CSR(MCOUNTEREN)
|
|
|
|
`CHECK_CSR(MEDELEG)
|
|
|
|
`CHECK_CSR(MIDELEG)
|
|
|
|
`CHECK_CSR(MIE)
|
|
|
|
//`CHECK_CSR(MSCRATCH)
|
|
|
|
`CHECK_CSR(MSTATUS)
|
|
|
|
`CHECK_CSR(MTVEC)
|
|
|
|
//`CHECK_CSR(SATP)
|
|
|
|
`CHECK_CSR(SCOUNTEREN)
|
2021-02-02 03:08:11 +00:00
|
|
|
|
2021-01-26 00:45:26 +00:00
|
|
|
logic speculative;
|
2021-01-24 00:01:44 +00:00
|
|
|
initial begin
|
|
|
|
speculative = 0;
|
2021-01-26 00:45:26 +00:00
|
|
|
speculative = 0;
|
2021-01-24 00:01:44 +00:00
|
|
|
end
|
2021-01-26 00:45:26 +00:00
|
|
|
logic [63:0] lastInstrF, lastPC, lastPC2;
|
2021-02-01 23:57:06 +00:00
|
|
|
|
|
|
|
string PCtextW, PCtext2W;
|
|
|
|
logic [31:0] InstrWExpected;
|
|
|
|
logic [63:0] PCWExpected;
|
|
|
|
always @(dut.ifu.PCW or dut.ieu.InstrValidW) begin
|
|
|
|
if(dut.ieu.InstrValidW && dut.ifu.PCW != 0) begin
|
|
|
|
if($feof(data_file_PCW)) begin
|
|
|
|
$display("no more PC data to read");
|
|
|
|
$stop;
|
|
|
|
end
|
|
|
|
scan_file_PCW = $fscanf(data_file_PCW, "%s\n", PCtextW);
|
|
|
|
if (PCtextW != "ret") begin
|
|
|
|
scan_file_PC = $fscanf(data_file_PCW, "%s\n", PCtext2W);
|
|
|
|
PCtextW = {PCtextW, " ", PCtext2W};
|
|
|
|
end
|
|
|
|
scan_file_PCW = $fscanf(data_file_PCW, "%x\n", InstrWExpected);
|
|
|
|
// then expected PC value
|
|
|
|
scan_file_PCW = $fscanf(data_file_PCW, "%x\n", PCWExpected);
|
|
|
|
if(dut.ifu.PCW != PCWExpected) begin
|
|
|
|
$display("%t ps, instr %0d: PCW does not equal PCW expected: %x, %x", $time, instrs, dut.ifu.PCW, PCWExpected);
|
|
|
|
end
|
|
|
|
//if(it.InstrW != InstrWExpected) begin
|
|
|
|
// $display("%t ps, instr %0d: InstrW does not equal InstrW expected: %x, %x", $time, instrs, it.InstrW, InstrWExpected);
|
|
|
|
//end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-01-26 17:34:12 +00:00
|
|
|
string PCtext, PCtext2;
|
2021-01-25 01:43:47 +00:00
|
|
|
integer instrs;
|
|
|
|
initial begin
|
|
|
|
instrs = 0;
|
|
|
|
end
|
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.
2021-01-23 01:27:01 +00:00
|
|
|
always @(PCF) begin
|
2021-01-26 00:45:26 +00:00
|
|
|
lastInstrF = InstrF;
|
|
|
|
lastPC <= PCF;
|
|
|
|
lastPC2 <= lastPC;
|
|
|
|
if (speculative && lastPC != pcExpected) begin
|
|
|
|
speculative = (PCF != pcExpected);
|
2021-01-24 00:01:44 +00:00
|
|
|
end
|
2021-01-26 00:45:26 +00:00
|
|
|
else begin
|
|
|
|
//if (~speculative) begin
|
2021-01-28 18:16:38 +00:00
|
|
|
if($feof(data_file_PC)) begin
|
|
|
|
$display("no more PC data to read");
|
|
|
|
$stop;
|
|
|
|
end
|
2021-01-24 00:01:44 +00:00
|
|
|
// first read instruction
|
2021-01-28 19:47:40 +00:00
|
|
|
scan_file_PC = $fscanf(data_file_PC, "%s\n", PCtext);
|
|
|
|
if (PCtext != "ret") begin
|
|
|
|
scan_file_PC = $fscanf(data_file_PC, "%s\n", PCtext2);
|
|
|
|
PCtext = {PCtext, " ", PCtext2};
|
|
|
|
end
|
2021-01-24 00:01:44 +00:00
|
|
|
scan_file_PC = $fscanf(data_file_PC, "%x\n", InstrF);
|
2021-02-01 19:44:56 +00:00
|
|
|
if(InstrF[6:0] == 7'b1010011) begin // for now, NOP out any float instrs
|
2021-01-30 19:52:47 +00:00
|
|
|
InstrF = 32'b0010011;
|
2021-02-01 23:57:06 +00:00
|
|
|
$display("warning: NOPing out %s at PC=%0x", PCtext, PCF);
|
2021-02-01 19:44:56 +00:00
|
|
|
end
|
2021-01-24 00:01:44 +00:00
|
|
|
// then expected PC value
|
|
|
|
scan_file_PC = $fscanf(data_file_PC, "%x\n", pcExpected);
|
2021-01-29 00:44:58 +00:00
|
|
|
if (instrs <= 10 || (instrs <= 100 && instrs % 10 == 0) ||
|
2021-01-29 05:13:14 +00:00
|
|
|
(instrs <= 1000 && instrs % 100 == 0) || (instrs <= 10000 && instrs % 1000 == 0) ||
|
|
|
|
(instrs <= 100000 && instrs % 10000 == 0)) begin
|
2021-01-28 18:33:22 +00:00
|
|
|
$display("loaded %0d instructions", instrs);
|
|
|
|
end
|
2021-01-25 01:43:47 +00:00
|
|
|
instrs += 1;
|
2021-01-24 00:01:44 +00:00
|
|
|
// are we at a branch/jump?
|
2021-01-28 19:40:35 +00:00
|
|
|
casex (lastInstrF[15:0])
|
|
|
|
16'bXXXXXXXXX1101111, // JAL
|
|
|
|
16'bXXXXXXXXX1100111, // JALR
|
|
|
|
16'bXXXXXXXXX1100011, // B
|
2021-01-28 21:35:12 +00:00
|
|
|
16'b110XXXXXXXXXXX01, // C.BEQZ
|
|
|
|
16'b111XXXXXXXXXXX01, // C.BNEZ
|
2021-01-28 19:40:35 +00:00
|
|
|
16'b101XXXXXXXXXXX01: // C.J
|
|
|
|
speculative = 1;
|
|
|
|
16'b1001000000000010: // C.EBREAK:
|
|
|
|
speculative = 0; // tbh don't really know what should happen here
|
|
|
|
16'b1000XXXXX0000010, // C.JR
|
|
|
|
16'b1001XXXXX0000010: // C.JALR //this is RV64 only so no C.JAL
|
2021-01-26 00:45:26 +00:00
|
|
|
speculative = 1;
|
2021-01-24 00:01:44 +00:00
|
|
|
default:
|
2021-01-26 00:45:26 +00:00
|
|
|
speculative = 0;
|
2021-01-24 00:01:44 +00:00
|
|
|
endcase
|
|
|
|
|
|
|
|
//check things!
|
2021-01-26 00:45:26 +00:00
|
|
|
if ((~speculative) && (PCF !== pcExpected)) begin
|
2021-01-29 05:13:14 +00:00
|
|
|
$display("%t ps, instr %0d: PC does not equal PC expected: %x, %x", $time, instrs, PCF, pcExpected);
|
2021-01-24 00:01:44 +00:00
|
|
|
// $stop;
|
|
|
|
end
|
2021-01-22 20:05:58 +00:00
|
|
|
end
|
2021-01-22 19:11:17 +00:00
|
|
|
end
|
|
|
|
|
2021-01-23 02:14:45 +00:00
|
|
|
// Track names of instructions
|
|
|
|
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
|
|
|
|
logic [31:0] InstrW;
|
|
|
|
instrNameDecTB dec(InstrF, InstrFName);
|
2021-01-27 17:54:09 +00:00
|
|
|
instrTrackerTB it(clk, reset, dut.ieu.dp.FlushE,
|
2021-01-28 04:42:19 +00:00
|
|
|
dut.ifu.InstrD, dut.ifu.InstrE,
|
|
|
|
dut.ifu.InstrM, InstrW,
|
2021-01-23 02:14:45 +00:00
|
|
|
InstrDName, InstrEName, InstrMName, InstrWName);
|
2021-01-21 21:17:34 +00:00
|
|
|
|
|
|
|
// generate clock to sequence tests
|
|
|
|
always
|
|
|
|
begin
|
2021-01-21 22:55:05 +00:00
|
|
|
clk <= 1; # 5; clk <= 0; # 5;
|
2021-01-21 21:17:34 +00:00
|
|
|
end
|
|
|
|
|
2021-01-21 22:55:05 +00:00
|
|
|
//// 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
|
2021-01-21 21:17:34 +00:00
|
|
|
endmodule
|