blob: 17f7b4cd0cca5bd3ef221481261374fa117ac431 [file] [log] [blame]
#include "Vicache.h"
#include "Vicache___024root.h"
#include <iostream>
#include <verilated_vcd_c.h>
#include <verilated.h>
typedef Vicache Vdut;
uint64_t sim_time = 0;
int req_time = 0;
int req_addr = 0;
int burst_num = 0;
void settle(Vdut *d) {
d->i_clk = 0;
d->eval();
}
void tick(Vdut *d, VerilatedVcdC* vcd) {
sim_time++;
settle(d);
vcd->dump(sim_time*10-1);
d->i_clk = 1;
d->eval();
vcd->dump(sim_time*10);
d->i_clk = 0;
d->eval();
vcd->dump(sim_time*10+5);
vcd->flush();
std::cout<<".";
}
void cpu_reset(Vdut* dut, VerilatedVcdC* v_vcd) {
dut->i_rst = 1;
for(int i=0; i<4; i++)
tick(dut, v_vcd);
dut->i_rst = 0;
req_time = 0;
}
void sim_mem(Vdut* d) {
d->omem_ack = 0;
if(d->omem_req) {
if(!req_time) {
req_time = (rand()%4)+1;
req_addr = d->omem_addr;
burst_num = 0;
}
if(--req_time <= 0) {
assert(d->omem_burst4);
req_time = (rand()%2)+1;
d->omem_data = req_addr+burst_num;
d->omem_ack = 1;
std::cout<<"reqf"<<req_addr+burst_num<<'\n';
if(++burst_num >= 4) {
burst_num = 0;
req_time = 0;
}
}
}
}
int m_req_addr = 3;
int reqstime;
int main() {
Vdut *d = new Vdut;
Verilated::traceEverOn(true);
VerilatedVcdC *vcd = new VerilatedVcdC;
d->trace(vcd, 99);
vcd->open("waveform.vcd");
srand(5);
cpu_reset(d, vcd);
tick(d, vcd);
for(int i=0; i<10000; i++) {
bool first_cyc = false;
if(d->imem_ack) {
bool should_hit = (bool)(m_req_addr & 0x3);
std::cout<<d->imem_data<<' '<<m_req_addr<<'\n';
std::cout<<should_hit<<' '<<((bool)d->rootp->icache__DOT__cache_hit)<<'s'<<'\n';
assert(d->imem_data == m_req_addr);
if(should_hit)
assert(sim_time-reqstime <= 4);
else
assert(sim_time-reqstime > 4);
if(d->imem_next) {
first_cyc = true;
d->imem_req = 1;
d->imem_addr = ++m_req_addr;
reqstime = sim_time;
} else {
d->imem_req = 0;
}
d->imem_next = 0;
}
settle(d);
if(d->imem_req && !d->imem_next && (rand()&2) && !first_cyc) {
d->imem_next = 1;
d->imem_addr = m_req_addr+1;
}
d->imem_sync_next = 0;
if(!d->imem_req && (rand()&1)) {
first_cyc = true;
d->imem_next = 0;
d->imem_sync_next = d->imem_ack;
d->imem_addr = ++m_req_addr;
d->imem_req = 1;
reqstime = sim_time;
}
tick(d, vcd);
sim_mem(d);
settle(d);
}
d->imem_req = 0;
d->imem_next = 0;
cpu_reset(d, vcd);
tick(d, vcd);
d->imem_req = 1;
d->imem_next = 0;
d->imem_addr = 4;
do {
tick(d, vcd);
sim_mem(d);
settle(d);
d->imem_next = 1;
d->imem_sync_next = 1;
d->imem_addr = 5;
} while(!d->imem_ack);
int req[] = {5, 6, 7, 4, 5};
for(int i=0; i<5; i++) {
d->imem_req = 1;
d->imem_next = 1;
d->imem_sync_next = 1;
d->imem_addr = req[i];
tick(d, vcd);
sim_mem(d);
settle(d);
if(i!=0) // delay after cache update
assert(d->imem_ack);
}
d->imem_req = 1;
d->imem_next = 0;
d->imem_sync_next = 1;
d->imem_addr = 8;
tick(d, vcd);
sim_mem(d);
settle(d);
do {
tick(d, vcd);
sim_mem(d);
settle(d);
d->imem_next = 1;
d->imem_sync_next = 1;
d->imem_addr = 9;
} while(!d->imem_ack);
for(int i=0; i<2; i++) {
d->imem_req = 0;
tick(d, vcd);
sim_mem(d);
settle(d);
}
int req2[] = {9, 6, 7, 8};
for(int i=0; i<4; i++) {
d->imem_req = 1;
d->imem_next = 1;
d->imem_sync_next = 1;
d->imem_addr = req2[i];
tick(d, vcd);
sim_mem(d);
settle(d);
if(i!=0) // delay after cache update
assert(d->imem_ack);
}
for(int i=0; i<2; i++) {
d->imem_req = 0;
tick(d, vcd);
sim_mem(d);
settle(d);
if(!i)
assert(d->imem_ack);
}
d->final();
vcd->close();
delete d;
std::cout<<"\nALL TESTS PASSED\n\n";
return 0;
}