diff --git a/dev/sim/verilator/tb-node.cpp b/dev/sim/verilator/tb-node.cpp deleted file mode 100644 index d65b7c7..0000000 --- a/dev/sim/verilator/tb-node.cpp +++ /dev/null @@ -1,173 +0,0 @@ -// simple verilator top -// uses a2owb with sim mem interface - -#define TRACING - -#include -#include -#include - -#include "verilated.h" -#include "Vc.h" - -#ifdef TRACING -#include "verilated_vcd_c.h" -VerilatedVcdC *t; -#else -unsigned int t = 0; -#endif - -/* -#include "uart/uartsim.h" -*/ - -Vc* m; - -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; -} - -const int resetCycle = 10; -const int threadRunCycle = 200; -const int runCycles = 1000; -const int hbCycles = 500; -const int threads = 1; // needs a more realistic a2l2 data return to work in smt - -int mem[16384][4]; // 16K QW - -void loadmem(void) { - int adr; - mem[0x0000/4] = 0x48000400; - adr = 0x400/4; - - mem[adr++] = threads == 1 ? 0x38200001 : 0x38200003; - mem[adr++] = 0x7C366BA6; - mem[adr++] = 0x7C366BA6; - mem[adr++] = 0x7C3E6AA6; - mem[adr++] = 0x4C00012C; - mem[adr++] = 0x2C010000; - mem[adr++] = 0x38200660; - mem[adr++] = 0x41820008; - mem[adr++] = 0x38210100; - mem[adr++] = 0x7C2903A6; - mem[adr++] = 0x4E800420; - -} - -// nclk = (clk,reset,clk2x,clk4x,-,-) - -int main(int argc, char **argv) { - using namespace std; - - loadmem(); - - cout << setfill('0'); - - Verilated::commandArgs(argc, argv); - m = new Vc; - -#ifdef TRACING - Verilated::traceEverOn(true); - t = new VerilatedVcdC; - m->trace(t, 99); - t->open("wtf.vcd"); - cout << "Tracing enabled." << endl; -#endif - - bool resetDone = false; - unsigned int threadStop = 0x3; - - unsigned int tick = 0; - unsigned int cycle = 1; - unsigned int readPending = 0; - unsigned int readAddr = 0; - unsigned int readTag = 0; - unsigned int readTID = 0; - unsigned int countReads = 0; - - m->nclk = 0x3C; // run 2x,4x = 1x - cout << setw(8) << cycle << "Resetting..." << endl; - - m->an_ac_pm_thread_stop = threadStop; - cout << setw(8) << cycle << "Thread stop=" << threadStop << endl; - - // can skip 4x with new gpr array - // 1x=4/4 2x=2/2 4x=1/1 - // 1 1 1 7 - // 1 1 0 6 - // 1 0 1 5 - // 1 0 0 4 - // 0 1 1 3 - // 0 1 0 2 - // 0 0 1 1 - // 0 0 0 0 - // (insert reset) - //const int clocks[8] = {11, 0, 11, 0, 11, 0, 11, 0}; // 2x,4x == 1x - //const int clocks[8] = {11, 10, 9, 8, 3, 2, 1, 0}; // 1x, 2x, 4x - //const int ticks1x = 8; - const int clocks[4] = {10, 8, 2, 0}; // 1x, 2x - const int ticks1x = 4; - - while (!Verilated::gotFinish()) { - - if (!resetDone && (cycle > resetCycle)) { - m->nclk &= 0x2F; - cout << setw(8) << cycle << "Releasing reset." << endl; - resetDone = true; - } - - if (threadStop && (cycle > threadRunCycle)) { - threadStop = 0x0; - m->an_ac_pm_thread_stop = threadStop; - cout << setw(8) << cycle << "Thread stop=" << threadStop << endl; - } - - m->nclk = (m->nclk & 0x10) | (clocks[tick % 8] << 2); - tick++; - m->eval(); - - // bus is 1x clock - if ((tick % ticks1x) == 0) { - - /* - cout << setw(8) << cycle << " an_ac_rsp: data="<< hex << uppercase << setw(8) << m->an_ac_reld_data[3] - << hex << uppercase << setw(8) << m->an_ac_reld_data[2] - << hex << uppercase << setw(8) << m->an_ac_reld_data[1] - << hex << uppercase << setw(8) << m->an_ac_reld_data[0] - << dec << nouppercase << endl; - */ - - } - - // finish clock stuff - if ((tick % ticks1x) == 0) { - cycle++; - if ((cycle % hbCycles) == 0) { - cout << setw(8) << cycle << " ...tick..." << endl; - } - } - #ifdef TRACING - t->dump(tick); - t->flush(); - #endif - - // check for fails - - // hit limit - if (cycle > runCycles) { - break; - } - - } - -#ifdef TRACING - t->close(); -#endif - m->final(); - - exit(EXIT_SUCCESS); - -} \ No newline at end of file diff --git a/dev/sim/verilator/tb.cpp b/dev/sim/verilator/tb.cpp index 2cff571..2409b0a 100644 --- a/dev/sim/verilator/tb.cpp +++ b/dev/sim/verilator/tb.cpp @@ -160,7 +160,7 @@ int main(int argc, char **argv) { cout << setw(8) << cycle << "Thread stop=" << threadStop << endl; } - m->nclk = (m->nclk & 0x10) | (clocks[tick % 8] << 2); + m->nclk = (m->nclk & 0x10) | (clocks[tick % ticks1x] << 2); tick++; m->eval(); diff --git a/dev/sim/verilator/tb_node.cpp b/dev/sim/verilator/tb_node.cpp new file mode 100644 index 0000000..71c14fa --- /dev/null +++ b/dev/sim/verilator/tb_node.cpp @@ -0,0 +1,305 @@ +// simple verilator top +// uses a2owb with sim mem interface + +#define TRACING + +#include +#include +#include +#include + +#include "verilated.h" +#include "Va2owb.h" + +// internal nets +#include "Va2owb___024root.h" +#include "Va2owb_a2owb.h" +#include "Va2owb_a2l2wb.h" + +#ifdef TRACING +#include "verilated_vcd_c.h" +VerilatedVcdC *t; +#else +unsigned int t = 0; +#endif + +/* +#include "uart/uartsim.h" +*/ + +Va2owb* m; + +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; +} + +const int resetCycle = 10; +const int threadRunCycle = 25; +const int runCycles = 500; +const int hbCycles = 500; +const int threads = 1; + +// Cythonize this and use it for cocotb too... + +class Memory { + std::unordered_map mem; + public: + bool le; + bool logStores; + int defaultVal; + Memory(); + void loadFile(std::string filename, unsigned int adr=0, bool le=false, std::string format="ascii"); + int read(unsigned int adr); + void write(unsigned int adr, unsigned int dat); + void write(unsigned int adr, unsigned int be, unsigned int dat); +}; + +Memory::Memory() { + + this->defaultVal = 0; + this->le = false; + this->logStores = true; + +} + +void Memory::loadFile(std::string filename, unsigned int adr, bool le, std::string format) { + + unsigned int dat; + std::ifstream f; + f.open(filename, std::fstream::in); + // "ascii" + //while (f.peek()!=EOF) { + //f >> std::hex >> dat; + // f >> dat; + while (f >> std::hex >> dat) { + this->write(adr, dat); + adr += 4; + } + +} + +// adr is word-aligned byte address +int Memory::read(unsigned int adr) { + if (this->mem.find(adr) != this->mem.end()) { + return this->mem[adr]; + } else { + return this->defaultVal; + } +} + +// adr is word-aligned byte address +void Memory::write(unsigned int adr, unsigned int dat) { + unsigned int startDat = this->read(adr); + this->mem[adr] = dat; + if (this->logStores) { + std::cout << std::setw(8) << std::hex << " * Mem Update @" << adr << " " << startDat << "->" << dat << std::endl; + } +} + +void Memory::write(unsigned int adr, unsigned int be, unsigned int dat) { + if (be == 0) return; + + int mask, startDat; + if (be >= 8) { + be = be - 8; + mask = 0xFF000000; + } else { + mask = 0; + } + if (be >= 4) { + be = be - 4; + mask |= 0x00FF0000; + } + if (be >= 2) { + be = be - 2; + mask |= 0x0000FF00; + } + if (be = 1) { + mask |= 0x000000FF; + } + + startDat = this->read(adr); + this->mem[adr] = (startDat & ~mask) | (dat & mask); + if (this->logStores) { + std::cout << std::setw(8) << std::hex << " * Mem Update @" << adr << " " << startDat << "->" << dat << std::endl; + } + +} + +Memory mem; + +int main(int argc, char **argv) { + using namespace std; + + cout << setfill('0'); + + Verilated::commandArgs(argc, argv); + m = new Va2owb; + +#ifdef TRACING + Verilated::traceEverOn(true); + t = new VerilatedVcdC; + m->trace(t, 99); + t->open("a2onode.vcd"); + cout << "Tracing enabled." << endl; +#endif + + bool resetDone = false; + unsigned int threadStop = 0x3; + + unsigned int tick = 0; + unsigned int cycle = 1; + unsigned int readPending = 0; + unsigned int readAddr = 0; + unsigned int readTag = 0; + unsigned int readTID = 0; + unsigned int countReads = 0; + + //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; + /* + iu0CompIFAR = sim.a2o.root.iuq0.iuq_cpl_top0.iuq_cpl0.cp2_i0_ifar + iu1Comp = sim.a2o.root.iu_lq_i1_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 + */ + + mem.write(0xFFFFFFFC, 0x48000002); + mem.loadFile("../mem/test3/rom.init"); + + m->nclk = 0x38; + cout << setw(8) << cycle << "Resetting..." << endl; + + m->an_ac_pm_thread_stop = threadStop; + cout << setw(8) << cycle << "Thread stop=" << threadStop << endl; + + const int clocks[4] = {0xA, 0x8, 0x2, 0x0}; // 1x, 2x + const int ticks1x = 4; + //const int clocks[8] = {11, 10, 9, 8, 3, 2, 1, 0}; // 1x, 2x, 4x + //const int ticks1x = 8; + + while (!Verilated::gotFinish()) { + + if (!resetDone && (cycle > resetCycle)) { + m->nclk &= 0x2F; + cout << setw(8) << cycle << "Releasing reset." << endl; + resetDone = true; + } + + if (threadStop && (cycle > threadRunCycle)) { + threadStop = 0x0; + m->an_ac_pm_thread_stop = threadStop; + cout << setw(8) << cycle << "Thread stop=" << threadStop << endl; + } + + m->nclk = (m->nclk & 0x10) | (clocks[tick % ticks1x] << 2); + tick++; + m->eval(); + + // bus is 1x clock + if ((tick % ticks1x) == 0) { + + /* + cout << setw(8) << cycle << " an_ac_rsp: data="<< hex << uppercase << setw(8) << m->an_ac_reld_data[3] + << hex << uppercase << setw(8) << m->an_ac_reld_data[2] + << hex << uppercase << setw(8) << m->an_ac_reld_data[1] + << hex << uppercase << setw(8) << m->an_ac_reld_data[0] + << dec << nouppercase << endl; + */ + +/* 16B BE read/write interface and sparse mem + + [0:31] mem_adr + [0:127] mem_dat + mem_wr_val + [0:15] mem_wr_be + [0:127] mem_wr_dat + + + addr = dut.mem_adr.value.integer + w0 = sim.mem.read(addr) + w1 = sim.mem.read(addr+4) + w2 = sim.mem.read(addr+8) + w3 = sim.mem.read(addr+12) + v = cocotb.binary.BinaryValue() + v.assign(f'{w0:0>32b}{w1:0>32b}{w2:0>32b}{w3:0>32b}') + dut.mem_dat.value = v.value + + if dut.mem_wr_val.value: + addr = dut.mem_adr.value.integer + dat = hex(dut.mem_wr_dat, 32) + be = f'{dut.mem_wr_be.value.integer:016b}' + for i in range(4): + sim.mem.write(addr, dat[i*8:i*8+8], be[i*4:i*4+4]) + addr += 4 +*/ + // update read dat + unsigned int adr = m->mem_adr; + m->mem_dat[3] = mem.read(adr); + adr += 4; + m->mem_dat[2] = mem.read(adr); + adr += 4; + m->mem_dat[1] = mem.read(adr); + adr += 4; + m->mem_dat[0] = mem.read(adr); + + // update mem[] if write + unsigned int mem_we = m->mem_wr_val; + unsigned int mem_be = m->mem_wr_be; + //unsigned int mem_datw[8] = m->mem_wr_dat; + + // check can access - ok + //m->rootp->a2owb->ac_an_req = 1; + //m->rootp->a2owb->ac_an_req = 0; + //m->rootp->a2owb->n0->cmdseq_q = 0; + /* + if (m->ac_an_req) { + readAddr = m->ac_an_req_ra; + readTag = m->ac_an_req_ld_core_tag; + readTID = m->ac_an_req_thread; + readPending = cycle + 3; + cout << setw(8) << cycle << " ac_an_req: T" << readTID << " ra=" << hex << uppercase << setw(8) << readAddr << dec << nouppercase << endl; + m->an_ac_req_ld_pop = 1; + } + */ + + } + + if (m->rootp->a2owb->ac_an_req == 1) { + cout << dec << setw(8) << cycle << "A2L2 Req RA=" << hex << m->rootp->a2owb->ac_an_ra << endl; + } +) + + // finish clock stuff + if ((tick % ticks1x) == 0) { + cycle++; + if ((cycle % hbCycles) == 0) { + cout << dec << setw(8) << cycle << " ...tick..." << endl; + } + } + #ifdef TRACING + t->dump(tick); + t->flush(); + #endif + + // check for fails + + // hit limit + if (cycle > runCycles) { + break; + } + + } + +#ifdef TRACING + t->close(); +#endif + m->final(); + + exit(EXIT_SUCCESS); + +} \ No newline at end of file diff --git a/dev/sim/verilator/verilog b/dev/sim/verilator/verilog new file mode 120000 index 0000000..b628320 --- /dev/null +++ b/dev/sim/verilator/verilog @@ -0,0 +1 @@ +../../verilog \ No newline at end of file