|
|
|
@ -3,18 +3,30 @@
|
|
|
|
|
|
|
|
|
|
#define TRACING
|
|
|
|
|
|
|
|
|
|
// old public access method
|
|
|
|
|
//#define OLD_PUBLIC
|
|
|
|
|
|
|
|
|
|
#include <cstddef>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <iomanip>
|
|
|
|
|
#include <unordered_map>
|
|
|
|
|
|
|
|
|
|
#include "verilated.h"
|
|
|
|
|
#include "Va2owb.h"
|
|
|
|
|
|
|
|
|
|
#ifndef OLD_PUBLIC
|
|
|
|
|
// internal nets
|
|
|
|
|
#include "Va2owb___024root.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "Va2owb_a2owb.h"
|
|
|
|
|
#include "Va2owb_a2l2wb.h"
|
|
|
|
|
#include "Va2owb_c.h"
|
|
|
|
|
#include "Va2owb_iuq.h"
|
|
|
|
|
#include "Va2owb_iuq_cpl_top.h"
|
|
|
|
|
#include "Va2owb_iuq_cpl.h"
|
|
|
|
|
#include "Va2owb_iuq_cpl_ctrl.h"
|
|
|
|
|
|
|
|
|
|
#ifdef TRACING
|
|
|
|
|
#include "verilated_vcd_c.h"
|
|
|
|
@ -28,9 +40,13 @@ unsigned int t = 0;
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
Va2owb* m;
|
|
|
|
|
#ifdef OLD_PUBLIC
|
|
|
|
|
Va2owb* root;
|
|
|
|
|
#else
|
|
|
|
|
Va2owb___024root* root;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
vluint64_t main_time = 0; // in units of timeprecision used in verilog or --timescale-override
|
|
|
|
|
// what is it? it changed to 941621251 after calling loadmem()
|
|
|
|
|
|
|
|
|
|
double sc_time_stamp() { // $time in verilog
|
|
|
|
|
return main_time;
|
|
|
|
@ -38,10 +54,12 @@ double sc_time_stamp() { // $time in verilog
|
|
|
|
|
|
|
|
|
|
const int resetCycle = 10;
|
|
|
|
|
const int threadRunCycle = resetCycle + 5;
|
|
|
|
|
const int runCycles = 500;
|
|
|
|
|
const int runCycles = 501;
|
|
|
|
|
const int hbCycles = 500;
|
|
|
|
|
const int threads = 1;
|
|
|
|
|
const std::string testFile = "../mem/test1/rom.init";
|
|
|
|
|
const std::string testFile = "../mem/test3/rom.init";
|
|
|
|
|
const unsigned int bootAdr = 0x00000000;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Cythonize this and use it for cocotb too...
|
|
|
|
|
|
|
|
|
@ -139,16 +157,23 @@ int main(int argc, char **argv) {
|
|
|
|
|
|
|
|
|
|
Verilated::commandArgs(argc, argv);
|
|
|
|
|
m = new Va2owb;
|
|
|
|
|
#ifdef OLD_PUBLIC
|
|
|
|
|
root = m;
|
|
|
|
|
#else
|
|
|
|
|
root = m->rootp;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef TRACING
|
|
|
|
|
Verilated::traceEverOn(true);
|
|
|
|
|
t = new VerilatedVcdC;
|
|
|
|
|
m->trace(t, 99);
|
|
|
|
|
t->open("a2onode.vcd");
|
|
|
|
|
t->open("a2olitex.vcd");
|
|
|
|
|
cout << "Tracing enabled." << endl;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
bool ok = true;
|
|
|
|
|
bool resetDone = false;
|
|
|
|
|
bool booted = false;
|
|
|
|
|
unsigned int threadStop = 0x3;
|
|
|
|
|
|
|
|
|
|
unsigned int tick = 0;
|
|
|
|
@ -160,20 +185,107 @@ int main(int argc, char **argv) {
|
|
|
|
|
unsigned int countReads = 0;
|
|
|
|
|
bool wbRdPending = false, wbWrPending = false;
|
|
|
|
|
|
|
|
|
|
//unsigned int iu0Comp = m->rootp->a2owb->c0->iu_lq_i0_completed;
|
|
|
|
|
//unsigned int iu0Comp = m->rootp->a2owb__DOT__c0__DOT__lq0__DOT__lsq__DOT__odq__DOT__iu_lq_i0_completed_itag_int;
|
|
|
|
|
unsigned int iu0Comp, iu1Comp;
|
|
|
|
|
unsigned long iu0CompIFAR, iu1CompIFAR, cp3NIA;
|
|
|
|
|
/*
|
|
|
|
|
creditsLdErr = sim.a2o.root.lq0.lsq.arb.ld_cred_err_q
|
|
|
|
|
creditsStErr = sim.a2o.root.lq0.lsq.arb.st_cred_err_q
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
iu0CompIFAR = sim.a2o.root.iuq0.iuq_cpl_top0.iuq_cpl0.cp2_i0_ifar
|
|
|
|
|
iu1Comp = sim.a2o.root.iu_lq_i1_completed
|
|
|
|
|
iu1Comp = cp2_i0_completed
|
|
|
|
|
iu1CompIFAR = sim.a2o.root.iuq0.iuq_cpl_top0.iuq_cpl0.cp2_i1_ifar
|
|
|
|
|
iuCompFlushIFAR = sim.a2o.root.cp_t0_flush_ifar
|
|
|
|
|
cp3NIA = sim.a2o.root.iuq0.iuq_cpl_top0.iuq_cpl0.iuq_cpl_ctrl.cp3_nia_q # nia after last cycle's completions
|
|
|
|
|
comp = ''
|
|
|
|
|
#wtf seeing something weird here
|
|
|
|
|
# there are cases where x's are in some bits of comp ifar's; maybe ok (predict array?) but why is completed indicated?
|
|
|
|
|
|
|
|
|
|
if iu0Comp.value == 1:
|
|
|
|
|
comp = f'0:{sim.safeint(iu0CompIFAR.value.binstr + "00", 2):06X} '
|
|
|
|
|
|
|
|
|
|
if iu1Comp.value == 1:
|
|
|
|
|
comp = f'{comp}1:{sim.safeint(iu1CompIFAR.value.binstr + "00", 2):06X} '
|
|
|
|
|
|
|
|
|
|
if comp == '':
|
|
|
|
|
if sim.a2o.stopOnHang != 0 and sim.cycle - lastCompCycle > sim.a2o.stopOnHang:
|
|
|
|
|
sim.ok = False
|
|
|
|
|
sim.fail = f'No completion detected in {sim.a2o.stopOnHang} cycles'
|
|
|
|
|
assert False, sim.fail
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
comp = f'{comp}{sim.safeint(iuCompFlushIFAR.value.binstr + "00", 2):016X}'
|
|
|
|
|
sim.msg(f'C0: CP {comp}')
|
|
|
|
|
lastCompCycle = sim.cycle
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
# GPR pool and arch map
|
|
|
|
|
gprCompMap = []
|
|
|
|
|
lastGprCompMap = []
|
|
|
|
|
#wtf check what 33:36 are!
|
|
|
|
|
for i in range(36):
|
|
|
|
|
gprCompMap.append(sim.a2o.root.iuq0.iuq_slice_top0.slice0.rn_top0.fx_rn0.gpr_rn_map.xhdl3.comp_map0[i].comp_map_latch.dout)
|
|
|
|
|
lastGprCompMap.append(i)
|
|
|
|
|
|
|
|
|
|
gpr = []
|
|
|
|
|
for i in range(144):
|
|
|
|
|
gpr.append(sim.a2o.root.xu0.gpr.gpr0.loc[i].dat)
|
|
|
|
|
|
|
|
|
|
# CR fields pool and arch map
|
|
|
|
|
crCompMap = []
|
|
|
|
|
lastCrCompMap = []
|
|
|
|
|
for i in range(8):
|
|
|
|
|
crCompMap.append(sim.a2o.root.iuq0.iuq_slice_top0.slice0.rn_top0.fx_rn0.cr_rn_map.xhdl3.comp_map0[i].comp_map_latch.dout)
|
|
|
|
|
lastCrCompMap.append(i)
|
|
|
|
|
|
|
|
|
|
cr = []
|
|
|
|
|
for i in range(24):
|
|
|
|
|
cr.append(sim.a2o.root.xu0.cr.entry[i].reg_latch.dout)
|
|
|
|
|
|
|
|
|
|
# XER pool and arch map
|
|
|
|
|
xerCompMap = []
|
|
|
|
|
lastXerCompMap = []
|
|
|
|
|
for i in range(1):
|
|
|
|
|
xerCompMap.append(sim.a2o.root.iuq0.iuq_slice_top0.slice0.rn_top0.fx_rn0.xer_rn_map.xhdl3.comp_map0[i].comp_map_latch.dout)
|
|
|
|
|
lastXerCompMap.append(i)
|
|
|
|
|
|
|
|
|
|
xer = []
|
|
|
|
|
for i in range(12):
|
|
|
|
|
xer.append(sim.a2o.root.xu0.xer.entry[i].reg_latch.dout)
|
|
|
|
|
|
|
|
|
|
# CTR pool and arch map
|
|
|
|
|
ctrCompMap = []
|
|
|
|
|
lastCtrCompMap = []
|
|
|
|
|
for i in range(1):
|
|
|
|
|
ctrCompMap.append(sim.a2o.root.iuq0.iuq_slice_top0.slice0.rn_top0.fx_rn0.ctr_rn_map.xhdl3.comp_map0[i].comp_map_latch.dout)
|
|
|
|
|
lastCtrCompMap.append(i)
|
|
|
|
|
|
|
|
|
|
ctr = []
|
|
|
|
|
for i in range(8):
|
|
|
|
|
ctr.append(sim.a2o.root.xu0.ctr.entry[i].reg_latch.dout)
|
|
|
|
|
|
|
|
|
|
# LR pool and arch map
|
|
|
|
|
lrCompMap = []
|
|
|
|
|
lastLrCompMap = []
|
|
|
|
|
for i in range(1):
|
|
|
|
|
lrCompMap.append(sim.a2o.root.iuq0.iuq_slice_top0.slice0.rn_top0.fx_rn0.lr_rn_map.xhdl3.comp_map0[i].comp_map_latch.dout)
|
|
|
|
|
lastLrCompMap.append(i)
|
|
|
|
|
|
|
|
|
|
lr = []
|
|
|
|
|
for i in range(8):
|
|
|
|
|
lr.append(sim.a2o.root.xu0.lr.entry[i].reg_latch.dout)
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
mem.write(0xFFFFFFFC, 0x48000002);
|
|
|
|
|
mem.loadFile(testFile);
|
|
|
|
|
|
|
|
|
|
m->rst = 1;
|
|
|
|
|
|
|
|
|
|
cout << dec << setw(8) << cycle << " Resetting..." << endl;
|
|
|
|
|
|
|
|
|
|
//m->an_ac_pm_thread_stop = threadStop;
|
|
|
|
@ -182,7 +294,7 @@ int main(int argc, char **argv) {
|
|
|
|
|
const int clocks[4] = {0x3, 0x2, 0x1, 0x0}; // 1x, 2x
|
|
|
|
|
const int ticks1x = 4;
|
|
|
|
|
|
|
|
|
|
while (!Verilated::gotFinish()) {
|
|
|
|
|
while (!Verilated::gotFinish() && ok && cycle <= runCycles) {
|
|
|
|
|
|
|
|
|
|
if (!resetDone && (cycle > resetCycle)) {
|
|
|
|
|
m->rst = 0;
|
|
|
|
@ -198,29 +310,50 @@ int main(int argc, char **argv) {
|
|
|
|
|
|
|
|
|
|
m->clk_1x = clocks[tick % ticks1x] >> 1;
|
|
|
|
|
m->clk_2x = clocks[tick % ticks1x] & 0x1;
|
|
|
|
|
|
|
|
|
|
tick++;
|
|
|
|
|
m->eval();
|
|
|
|
|
|
|
|
|
|
// bus is 1x clock
|
|
|
|
|
// 1x clock
|
|
|
|
|
if ((tick % ticks1x) == 0) {
|
|
|
|
|
|
|
|
|
|
// core
|
|
|
|
|
iu0Comp = root->a2owb->c0->iuq0->iuq_cpl_top0->iuq_cpl0->cp2_i0_completed;
|
|
|
|
|
iu1Comp = root->a2owb->c0->iuq0->iuq_cpl_top0->iuq_cpl0->cp2_i1_completed;
|
|
|
|
|
iu0CompIFAR = root->a2owb->c0->iuq0->iuq_cpl_top0->iuq_cpl0->cp2_i0_ifar;
|
|
|
|
|
iu1CompIFAR = root->a2owb->c0->iuq0->iuq_cpl_top0->iuq_cpl0->cp2_i1_ifar;
|
|
|
|
|
|
|
|
|
|
if (iu0Comp || iu1Comp) {
|
|
|
|
|
cout << dec << setw(8) << setfill('0') << uppercase << cycle << " Completed:";
|
|
|
|
|
if (iu0Comp)
|
|
|
|
|
cout << " I0:" << iu0Comp << " " << setw(16) << setfill('0') << hex << (iu0CompIFAR << 2);
|
|
|
|
|
if (iu1Comp)
|
|
|
|
|
cout << " I1:" << iu1Comp << " " << setw(16) << setfill('0') << hex << (iu1CompIFAR << 2);
|
|
|
|
|
cout << endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// wb
|
|
|
|
|
m->wb_ack = 0;
|
|
|
|
|
if (wbRdPending) {
|
|
|
|
|
m->wb_datr = mem.read(m->wb_adr);
|
|
|
|
|
m->wb_datr = mem.read(m->wb_adr & 0xFFFFFFFC);
|
|
|
|
|
m->wb_ack = 1;
|
|
|
|
|
cout << dec << setw(8) << setfill('0') << uppercase << cycle << " WB RD ACK RA=" << setw(8) << hex << setfill('0') << (m->wb_adr & 0xFFFFFFFC) <<
|
|
|
|
|
" DATA=" << m->wb_datr << endl;
|
|
|
|
|
wbRdPending = false;
|
|
|
|
|
} else if (wbWrPending) {
|
|
|
|
|
mem.write(m->wb_adr, m->wb_datw, m->wb_sel);
|
|
|
|
|
m->wb_ack = 1;
|
|
|
|
|
wbWrPending = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!wbRdPending && !wbWrPending && m->wb_cyc && m->wb_stb) {
|
|
|
|
|
} else if (m->wb_cyc && m->wb_stb) {
|
|
|
|
|
if (!m->wb_we) {
|
|
|
|
|
cout << dec << setw(8) << setfill('0') << uppercase << cycle << " WB RD RA=" << setw(8) << hex << setfill('0') << m->wb_adr << endl;
|
|
|
|
|
wbRdPending = true;
|
|
|
|
|
if (m->wb_adr == bootAdr) {
|
|
|
|
|
if (booted) {
|
|
|
|
|
cout << "*** Fetch to boot address (" << dec << setw(8) << bootAdr << ") after initial boot! ***" << endl;
|
|
|
|
|
ok = false;
|
|
|
|
|
} else {
|
|
|
|
|
booted = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
cout << dec << setw(8) << setfill('0') << uppercase << cycle << " WB WR RA=" << setw(8) << hex << setfill('0') << m->wb_adr <<
|
|
|
|
|
" SEL=" << m->wb_sel << " DATA=" << m->wb_datw << endl;
|
|
|
|
@ -230,6 +363,8 @@ int main(int argc, char **argv) {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m->eval(); // NEED THIS!!!!
|
|
|
|
|
|
|
|
|
|
// finish clock stuff
|
|
|
|
|
if ((tick % ticks1x) == 0) {
|
|
|
|
|
cycle++;
|
|
|
|
@ -237,6 +372,9 @@ int main(int argc, char **argv) {
|
|
|
|
|
cout << dec << setw(8) << setfill('0') << cycle << " ...tick..." << endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tick++;
|
|
|
|
|
|
|
|
|
|
#ifdef TRACING
|
|
|
|
|
t->dump(tick);
|
|
|
|
|
t->flush();
|
|
|
|
@ -244,11 +382,6 @@ int main(int argc, char **argv) {
|
|
|
|
|
|
|
|
|
|
// check for fails
|
|
|
|
|
|
|
|
|
|
// hit limit
|
|
|
|
|
if (cycle > runCycles) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef TRACING
|
|
|
|
@ -256,6 +389,13 @@ int main(int argc, char **argv) {
|
|
|
|
|
#endif
|
|
|
|
|
m->final();
|
|
|
|
|
|
|
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
|
cout << endl << "Cycles run=" << cycle << endl << endl;
|
|
|
|
|
if (!ok) {
|
|
|
|
|
cout << "You are worthless and weak." << endl;
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
} else {
|
|
|
|
|
cout << "You has opulence." << endl;
|
|
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|