verilator litex
							parent
							
								
									5532d33b52
								
							
						
					
					
						commit
						5c12356d95
					
				| @ -0,0 +1,261 @@ | ||||
| // simple verilator top | ||||
| // uses a2owb with sim mem interface | ||||
|  | ||||
| #define TRACING | ||||
|  | ||||
| #include <cstddef> | ||||
| #include <iostream> | ||||
| #include <fstream> | ||||
| #include <iomanip> | ||||
|  | ||||
| #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 = resetCycle + 5; | ||||
| const int runCycles = 500; | ||||
| const int hbCycles = 500; | ||||
| const int threads = 1; | ||||
| const std::string testFile = "../mem/test1/rom.init"; | ||||
|  | ||||
| // Cythonize this and use it for cocotb too... | ||||
|  | ||||
| class Memory { | ||||
|    std::unordered_map<unsigned int, unsigned int> 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; | ||||
|    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; | ||||
|    /* | ||||
|    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(testFile); | ||||
|  | ||||
|    m->rst = 1; | ||||
|    cout << dec << setw(8) << cycle << " Resetting..." << endl; | ||||
|  | ||||
|    //m->an_ac_pm_thread_stop = threadStop; | ||||
|    //cout << dec << setw(8) << cycle << " Thread stop=" << threadStop << endl; | ||||
|  | ||||
|    const int clocks[4] = {0x3, 0x2, 0x1, 0x0};     // 1x, 2x | ||||
|    const int ticks1x = 4; | ||||
|  | ||||
|    while (!Verilated::gotFinish()) { | ||||
|  | ||||
|       if (!resetDone && (cycle > resetCycle)) { | ||||
|          m->rst = 0; | ||||
|          cout << dec << setw(8) << cycle << " Releasing reset." << endl; | ||||
|          resetDone = true; | ||||
|       } | ||||
|  | ||||
|       if (threadStop && (cycle > threadRunCycle)) { | ||||
|          //threadStop = 0x0; | ||||
|          //m->an_ac_pm_thread_stop = threadStop; | ||||
|          //cout << dec << setw(8) << cycle << " Thread stop=" << threadStop << endl; | ||||
|       } | ||||
|  | ||||
|       m->clk_1x = clocks[tick % ticks1x] >> 1; | ||||
|       m->clk_2x = clocks[tick % ticks1x] & 0x1; | ||||
|  | ||||
|       tick++; | ||||
|       m->eval(); | ||||
|  | ||||
|       // bus is 1x clock | ||||
|       if ((tick % ticks1x) == 0) { | ||||
|  | ||||
|          // wb | ||||
|          m->wb_ack = 0; | ||||
|          if (wbRdPending) { | ||||
|             m->wb_datr = mem.read(m->wb_adr); | ||||
|             m->wb_ack = 1; | ||||
|             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) { | ||||
|             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; | ||||
|             } 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; | ||||
|                wbWrPending = true; | ||||
|             } | ||||
|          } | ||||
|  | ||||
|       } | ||||
|  | ||||
|       // finish clock stuff | ||||
|       if ((tick % ticks1x) == 0) { | ||||
|          cycle++; | ||||
|          if ((cycle % hbCycles) == 0) { | ||||
|             cout << dec << setw(8) << setfill('0') << 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); | ||||
|  | ||||
| } | ||||
					Loading…
					
					
				
		Reference in New Issue
	
	 openpowerwtf
						openpowerwtf