@ -29,6 +29,14 @@
#include "Vsoc_iuq.h"
#include "Vsoc_iuq_cpl_top.h"
#include "Vsoc_iuq_cpl.h"
#include "Vsoc_iuq_slice_top.h"
#include "Vsoc_iuq_slice.h"
#include "Vsoc_iuq_rn_top.h"
#include "Vsoc_iuq_rn.h"
#include "Vsoc_iuq_rn_map__A24.h"
#include "Vsoc_xu.h"
#include "Vsoc_xu_gpr.h"
#include "Vsoc_tri_144x78_2r4w.h"
#ifdef TRACING
#include "verilated_vcd_c.h"
@ -37,9 +45,14 @@ VerilatedVcdC *t;
unsigned int t = 0;
#endif
/*
#include "uart/uartsim.h"
*/
// using https://github.com/ZipCPU/wbuart32 sim driver
// how does cpp get compiled in without this? can verilator be told to add more cpp? see a2p!
// UART=port
// 0xA20 = 2592
#ifdef UART
#include "wbuart32/bench/cpp/uartsim.h"
#include "wbuart32/bench/cpp/uartsim.cpp"
#endif
Vsoc* m;
#ifdef OLD_PUBLIC
@ -57,7 +70,7 @@ double sc_time_stamp() { // $time in verilog
const char* tbName = "tb_litex_soc";
const int resetCycle = 10;
const int threadRunCycle = resetCycle + 5;
const int runCycles = 100000;
const int runCycles = 100000000;
const int hbCycles = 500;
const int quiesceCycles = 50;
const int threads = 1;
@ -65,10 +78,11 @@ const std::string testFile = "";
const unsigned int bootAdr = 0x00000000;
const bool failMaxCycles = true;
const unsigned int stopOnHang = 500;
const unsigned int stopOnLoop = 10;
const unsigned int stopOnLoop = 20;
const unsigned long iarPass = 0x7F0;
const unsigned long iarFail = 0x7F4;
const bool debugWB = false;
const bool debugWB = true;
const bool debugWBReq = false;
// Cythonize this and use it for cocotb too...
@ -153,7 +167,6 @@ void Memory::write(unsigned int adr, unsigned int be, unsigned int dat) {
" " <<std::setw(8) << std::setfill('0') << std::uppercase << std::hex << startDat <<
"->" <<std::setw(8) << std::setfill('0') << std::uppercase << std::hex << this->read(adr) << std::endl;
}
}
Memory mem;
@ -179,6 +192,7 @@ int main(int argc, char **argv) {
cout << "Tracing enabled." << endl;
#endif
int i;
bool ok = true;
bool done = false;
bool resetDone = false;
@ -201,6 +215,22 @@ int main(int argc, char **argv) {
unsigned int iu0Comp, iu1Comp, iu0CompLast, iu1CompLast;
unsigned long iu0CompIFAR, iu1CompIFAR, iu0CompIFARLast, iu1CompIFARLast, iuCompFlushIFAR;
unsigned long gprCompMap[36], lastGprCompMap[36];
unsigned int vHi, vLo;
VlWide<3> gpr[144];
/*
# renamables
for i in range(36):
good, arch = sim.safeint(gprCompMap[i].value.binstr, 2, rc=True)
if good and arch != lastGprCompMap[i]:
sim.msg(f'C0: GPR Update: R{i:02d}={hex(gpr[arch], 16)}')
lastGprCompMap[i] = arch
*/
for (i = 0; i < 36; i++) {
lastGprCompMap[i] = i;
}
/*
# GPR pool and arch map
@ -261,9 +291,71 @@ int main(int argc, char **argv) {
*/
// memory setup
//mem.write(0xFFFFFFFC, 0x48000002);
//mem.loadFile(testFile);
// uart setup
/*
// i_setup[30] True if we are not using hardware flow control. This bit
// is ignored within this module, as any receive hardware flow
// control will need to be implemented elsewhere.
//
// i_setup[29:28] Indicates the number of data bits per word. This will
// either be 2'b00 for an 8-bit word, 2'b01 for a 7-bit word, 2'b10
// for a six bit word, or 2'b11 for a five bit word.
//
// i_setup[27] Indicates whether or not to use one or two stop bits.
// Set this to one to expect two stop bits, zero for one.
//
// i_setup[26] Indicates whether or not a parity bit exists. Set this
// to 1'b1 to include parity.
//
// i_setup[25] Indicates whether or not the parity bit is fixed. Set
// to 1'b1 to include a fixed bit of parity, 1'b0 to allow the
// parity to be set based upon data. (Both assume the parity
// enable value is set.)
//
// i_setup[24] This bit is ignored if parity is not used. Otherwise,
// in the case of a fixed parity bit, this bit indicates whether
// mark (1'b1) or space (1'b0) parity is used. Likewise if the
// parity is not fixed, a 1'b1 selects even parity, and 1'b0
// selects odd.
//
// i_setup[23:0] Indicates the speed of the UART in terms of clocks.
// So, for example, if you have a 200 MHz clock and wish to
// run your UART at 9600 baud, you would take 200 MHz and divide
// by 9600 to set this value to 24'd20834. Likewise if you wished
// to run this serial port at 115200 baud from a 200 MHz clock,
// you would set the value to 24'd1736
*/
/*
m_baud_counts = (isetup & 0x0ffffff);
m_nbits = 8-((isetup >> 28)&0x03);
m_nstop =((isetup >> 27)&1)+1;
m_nparity = (isetup >> 26)&1;
m_fixdp = (isetup >> 25)&1;
m_evenp = (isetup >> 24)&1;
*/
// 100MHz, 115200 = 868
#ifdef UART
UARTSIM *uart;
int uartPort = UART; // 0-stdin/stdout
//unsigned uartConfig = 1736;
unsigned uartConfig = 868;
//unsigned uartConfig = 434;
//unsigned uartConfig = 217;
//unsigned uartConfig = 217;
cout << "Initializing UART on port " << uartPort << " with config=" << hex << setw(8) << setfill('0') << uartConfig << endl;
uart = new UARTSIM(uartPort);
uart->setup(uartConfig);
#endif
// do something
root->soc->soc_rst = 1;
cout << dec << setw(8) << cycle << " Resetting..." << endl;
@ -298,6 +390,32 @@ int main(int argc, char **argv) {
if ((tick % ticks1x) == 0) {
// core
// completion
// gpr change
for (i = 0; i < 36; i++) {
gprCompMap[i] = root->soc->a2owb->c0->iuq0->iuq_slice_top0->slice0->rn_top0->fx_rn0->gpr_rn_map->comp_map_l2[i];
if (gprCompMap[i] != lastGprCompMap[i]) {
// need to left shift by 18 unused (96-78)!
vHi = root->soc->a2owb->c0->xu0->gpr->gpr0->mem[gprCompMap[i]][2] << 18;
vHi |= root->soc->a2owb->c0->xu0->gpr->gpr0->mem[gprCompMap[i]][1] >> 14;
vLo = root->soc->a2owb->c0->xu0->gpr->gpr0->mem[gprCompMap[i]][1] << 18;
vLo |= root->soc->a2owb->c0->xu0->gpr->gpr0->mem[gprCompMap[i]][0] >> 14;
cout << dec << setw(8) << setfill('0') << cycle << " C0: GPR Update: R";
cout << dec << setw(2) << setfill('0') << i << "=";
//cout << hex << setw(8) << setfill('0') << uppercase << root->soc->a2owb->c0->xu0->gpr->gpr0->mem[gprCompMap[i]][0] << " ";
//cout << hex << setw(8) << setfill('0') << uppercase << root->soc->a2owb->c0->xu0->gpr->gpr0->mem[gprCompMap[i]][1] << " ";
//cout << hex << setw(8) << setfill('0') << uppercase << root->soc->a2owb->c0->xu0->gpr->gpr0->mem[gprCompMap[i]][2] << " ";
cout << hex << setw(8) << setfill('0') << uppercase << vHi << "";
cout << hex << setw(8) << setfill('0') << uppercase << vLo << " ";
cout << "[" << dec << setw(3) << setfill('0') << gprCompMap[i] << "]";
cout << endl;
lastGprCompMap[i] = gprCompMap[i];
}
}
// completions
iu0Comp = root->soc->a2owb->c0->iuq0->iuq_cpl_top0->iuq_cpl0->cp2_i0_completed;
iu1Comp = root->soc->a2owb->c0->iuq0->iuq_cpl_top0->iuq_cpl0->cp2_i1_completed;
iu0CompIFAR = root->soc->a2owb->c0->iuq0->iuq_cpl_top0->iuq_cpl0->cp2_i0_ifar << 2;
@ -324,11 +442,13 @@ int main(int argc, char **argv) {
quiesceCount = 5;
} else if ((iu0Comp == iu0CompLast) && (!iu0Comp || (iu0CompIFAR == iu0CompIFARLast)) &&
(iu1Comp == iu1CompLast) && (!iu1Comp || (iu1CompIFAR == iu1CompIFARLast))) {
lastCompSame++;
if (stopOnLoop && (lastCompSame == stopOnLoop)) {
ok = false;
cout << "*** Loop detected for " << dec << stopOnLoop << " iterations ***" << endl;
}
if (!iu0Comp || !iu1Comp) { // don't count if both are valid (assume only 1-op loops are bad)
lastCompSame++;
if (stopOnLoop && (lastCompSame == stopOnLoop)) {
ok = false;
cout << "*** Loop detected for " << dec << stopOnLoop << " iterations ***" << endl;
}
}
} else {
iu0CompLast = iu0Comp;
iu0CompIFARLast = iu0CompIFAR;
@ -360,11 +480,11 @@ int main(int argc, char **argv) {
} else if (root->soc->a2owb->wb_cyc && root->soc->a2owb->wb_stb) {
if (!root->soc->a2owb->wb_we) {
if (debugWB)
if (!wbRdPending && debugWBReq)
cout << dec << setw(8) << setfill('0') << uppercase << cycle << " WB RD RA=" << setw(8) << hex << setfill('0') << root->soc->a2owb->wb_adr << endl;
wbRdPending = true;
} else {
if (debugWB)
if (!wbWrPending && debugWBReq)
cout << dec << setw(8) << setfill('0') << uppercase << cycle << " WB WR RA=" << setw(8) << hex << setfill('0') << root->soc->a2owb->wb_adr <<
" SEL=" << root->soc->a2owb->wb_sel << " DATA=" << setw(8) << hex << setfill('0') << root->soc->a2owb->wb_datw << endl;
wbWrPending = true;
@ -373,7 +493,13 @@ int main(int argc, char **argv) {
// leds, btns, mem, etc.
// uart
} else {
if (resetDone) {
#ifdef UART
m->serial_rx = (*uart)(m->serial_tx);
#endif
}
}