/* * global config */ #define CONFIG_GDB_SERVER /* * headers */ #ifdef _OPENMP #include #endif #include #include #include #ifdef CONFIG_GDB_SERVER #include "gdbserver.h" #endif #include "mapping_table.h" #include "mips32.h" #include "vci_cc_vcache_wrapper_v4.h" #include "vci_simple_ram.h" #include "vci_mem_cache_v4.h" #include "vci_simhelper.h" #include "vci_multi_tty.h" #include "vci_xicu.h" #include "vci_block_device_tsar_v4.h" #include "vci_vgmn.h" #include "alloc_elems.h" /* * pf global config */ using namespace sc_core; using namespace soclib::caba; using namespace soclib::common; #define cell_width 4 #define address_width 32 #define plen_width 8 #define error_width 2 #define clen_width 1 #define rflag_width 1 #define srcid_width 14 #define pktid_width 4 #define trdid_width 4 #define wrplen_width 1 typedef VciParams vci_param; /* mapping table for data */ MappingTable maptabd(32, IntTab(6), IntTab(6), 0xf0000000); /* mapping table for coherence */ MappingTable maptabc(32, IntTab(srcid_width), IntTab(srcid_width), 0xf0000000); /* * segmentation */ #include "segmentation.h" /* * default parameters */ char *soft_path = NULL; char *bd_path = NULL; bool trace_enabled = false; size_t trace_start_cycle = 0; /* * arguments parsing */ void args_parse(unsigned int argc, char *argv[]) { if (argc > 1) { for (size_t n = 1; n < argc; n = n + 2) { if ((strcmp(argv[n], "-soft") == 0) && ((n + 1) < argc)) { assert((soft_path = strdup(argv[n + 1])) && "insufficient memory"); } else if ((strcmp(argv[n], "-img") == 0) && ((n + 1) < argc)) { assert((bd_path = strdup(argv[n + 1])) && "insufficient memory"); } else if ((strcmp(argv[n], "-trace") == 0) && ((n + 1) < argc)) { trace_enabled = true; trace_start_cycle = atoi(argv[n + 1]); } else { std::cout << "Error: don't understand option " << argv[n] << std::endl; std::cout << "Accepted arguments are :" << std::endl; std::cout << "-soft pathname" << std::endl; std::cout << "-img pathname" << std::endl; std::cout << "[-trace trace_start_cycle]" << std::endl; exit(0); } } } assert(soft_path && "-soft is not optional"); assert(bd_path && "-img is not optional"); std::cout << std::endl; std::cout << "simulation parameters:" << std::endl; std::cout << " soft = " << soft_path << std::endl; std::cout << " img = " << bd_path << std::endl; std::cout << " trace = " << trace_enabled << std::endl; std::cout << std::endl; } /* * netlist */ int _main(int argc, char *argv[]) { #ifdef _OPENMP omp_set_dynamic(false); omp_set_num_threads(1); std::cerr << "Built with openmp version " << _OPENMP << std::endl; #endif /* parse arguments */ args_parse(argc, argv); /* * mapping table */ // caches ram bank maptabd.add(Segment("memc_d" , MEMC_BASE , MEMC_SIZE , IntTab(0), true)); maptabd.add(Segment("boot_d" , BOOT_BASE , BOOT_SIZE , IntTab(1), true)); // uncached peripherals maptabd.add(Segment("exit_d" , EXIT_BASE , EXIT_SIZE , IntTab(2), false)); maptabd.add(Segment("mtty_d" , MTTY_BASE , MTTY_SIZE , IntTab(3), false)); maptabd.add(Segment("xicu_d" , XICU_BASE , XICU_SIZE , IntTab(4), false)); maptabd.add(Segment("iobd_d" , IOBD_BASE , IOBD_SIZE , IntTab(5), false)); std::cout << maptabd << std::endl; // procs maptabc.add(Segment("proc_c" , 0x0000000 , 0x10 , IntTab(0) , false)); maptabc.add(Segment("memc_c" , 1 << (address_width - srcid_width) , 0x10 , IntTab(1) , false)); std::cout << maptabc << std::endl; /* * components */ Loader loader; loader.load_file(soft_path); #ifdef CONFIG_GDB_SERVER typedef GdbServer proc_iss; proc_iss::set_loader(loader); #else typedef Mips32ElIss proc_iss; #endif VciCcVCacheWrapperV4 proc("ccvcache", 0, // proc_id maptabd, // direct space maptabc, // coherence space IntTab(0), // srcid_d IntTab(0), // srcid_c IntTab(0), // tgtid_c 8, 8, // itlb size 8, 8, // dtlb size 4, 64, 16, // icache size 4, 64, 16, // dcache size 4, 4, // wbuf size 0, 0, // x, y Width 1, // memory cache local id 1000, // max frozen cycles trace_start_cycle, trace_enabled); VciSimpleRam xram("xram", IntTab(0), maptabd, loader); VciSimpleRam rom("rom", IntTab(1), maptabd, loader); VciMemCacheV4 memc("memc", maptabd, maptabc, maptabd, IntTab(0), IntTab(1), IntTab(0), IntTab(1), // srcid_d, srcid_c, tgtid_d, tgtid_c 16, 256, 16, // cache size 1024, 4, 4, // HEAP size, TRT size, UPT size trace_start_cycle, trace_enabled); VciSimhelper vciexit("vciexit", IntTab(2), maptabd); VciXicu xicu("xicu", maptabd, IntTab(4), 1, 2, 0, 1); // #timers, #hard_irqs, #soft_irqs, # output_irqs VciMultiTty mtty("mtty", IntTab(3), maptabd, "vcitty0", NULL); VciBlockDeviceTsarV4 iobd("iobd", maptabd, IntTab(1), IntTab(5), bd_path); // mapped_file[, block_size=512, latency=0] VciVgmn ringd("ringd", maptabd, 2, 6, // #initiators, #targets 2, 8); // min_latency, FIFO depth VciVgmn ringc("ringc", maptabc, 2, 2, // #initiators, #targets 2, 8); // min_latency, FIFO depth /* * signals */ /* clock and reset */ sc_clock signal_clk("signal_clk"); sc_signal signal_resetn("signal_resetn"); /* irq lines */ sc_signal *signal_proc_irq = alloc_elems >("signal_proc_irq", proc_iss::n_irq); sc_signal signal_mtty_irq("signal_mtty_irq"); sc_signal signal_iobd_irq("signal_iobd_irq"); /* vci */ VciSignals signal_vci_ini_d_proc("vci_ini_d_proc"); VciSignals signal_vci_ini_c_proc("vci_ini_c_proc"); VciSignals signal_vci_tgt_c_proc("vci_tgt_c_proc"); VciSignals signal_vci_xram("signal_vci_xram"); VciSignals signal_vci_tgt_d_brom("signal_vci_tgt_d_brom"); VciSignals signal_vci_ini_c_memc("signal_vci_ini_c_memc"); VciSignals signal_vci_tgt_d_memc("signal_vci_tgt_d_memc"); VciSignals signal_vci_tgt_c_memc("signal_vci_tgt_c_memc"); VciSignals signal_vci_tgt_d_exit("signal_vci_tgt_d_exit"); VciSignals signal_vci_tgt_d_xicu("signal_vci_tgt_d_xicu"); VciSignals signal_vci_tgt_d_mtty("signal_vci_tgt_d_mtty"); VciSignals signal_vci_ini_d_iobd("signal_vci_ini_d_iobd"); VciSignals signal_vci_tgt_d_iobd("signal_vci_tgt_d_iobd"); /* * netlist */ proc.p_clk(signal_clk); proc.p_resetn(signal_resetn); for (size_t i = 0; i < proc_iss::n_irq; i++) proc.p_irq[i](signal_proc_irq[i]); proc.p_vci_ini_d(signal_vci_ini_d_proc); proc.p_vci_ini_c(signal_vci_ini_c_proc); proc.p_vci_tgt_c(signal_vci_tgt_c_proc); xram.p_clk(signal_clk); xram.p_resetn(signal_resetn); xram.p_vci(signal_vci_xram); rom.p_clk(signal_clk); rom.p_resetn(signal_resetn); rom.p_vci(signal_vci_tgt_d_brom); memc.p_clk(signal_clk); memc.p_resetn(signal_resetn); memc.p_vci_tgt(signal_vci_tgt_d_memc); memc.p_vci_tgt_cleanup(signal_vci_tgt_c_memc); memc.p_vci_ini(signal_vci_ini_c_memc); memc.p_vci_ixr(signal_vci_xram); vciexit.p_clk(signal_clk); vciexit.p_resetn(signal_resetn); vciexit.p_vci(signal_vci_tgt_d_exit); xicu.p_resetn(signal_resetn); xicu.p_clk(signal_clk); xicu.p_vci(signal_vci_tgt_d_xicu); xicu.p_hwi[0](signal_mtty_irq); xicu.p_hwi[1](signal_iobd_irq); xicu.p_irq[0](signal_proc_irq[0]); mtty.p_clk(signal_clk); mtty.p_resetn(signal_resetn); mtty.p_vci(signal_vci_tgt_d_mtty); mtty.p_irq[0](signal_mtty_irq); iobd.p_clk(signal_clk); iobd.p_resetn(signal_resetn); iobd.p_vci_target(signal_vci_tgt_d_iobd); iobd.p_vci_initiator(signal_vci_ini_d_iobd); iobd.p_irq(signal_iobd_irq); ringd.p_clk(signal_clk); ringd.p_resetn(signal_resetn); ringd.p_to_initiator[0](signal_vci_ini_d_proc); ringd.p_to_initiator[1](signal_vci_ini_d_iobd); ringd.p_to_target[0](signal_vci_tgt_d_memc); ringd.p_to_target[1](signal_vci_tgt_d_brom); ringd.p_to_target[2](signal_vci_tgt_d_exit); ringd.p_to_target[3](signal_vci_tgt_d_mtty); ringd.p_to_target[4](signal_vci_tgt_d_xicu); ringd.p_to_target[5](signal_vci_tgt_d_iobd); ringc.p_clk(signal_clk); ringc.p_resetn(signal_resetn); ringc.p_to_initiator[0](signal_vci_ini_c_proc); ringc.p_to_initiator[1](signal_vci_ini_c_memc); ringc.p_to_target[0](signal_vci_tgt_c_proc); ringc.p_to_target[1](signal_vci_tgt_c_memc); /* * simulation */ sc_start(sc_time(0, SC_NS)); signal_resetn = false; sc_start(sc_time(1, SC_NS)); signal_resetn = true; if (trace_enabled) { if (trace_start_cycle > 1) // simulate without output until trace_start_cycle sc_start(sc_time(trace_start_cycle, SC_NS)); // enable debugging output for (size_t n = trace_start_cycle ;; n++) { std::cout << "****************** cycle " << std::dec << n << " ************************************************" << std::endl; proc.print_trace(); memc.print_trace(); signal_vci_ini_d_proc.print_trace("proc_ini_d"); signal_vci_tgt_c_proc.print_trace("proc_tgt_c"); signal_vci_ini_c_proc.print_trace("proc_ini_c"); signal_vci_tgt_d_memc.print_trace("memc_tgt_d"); signal_vci_tgt_c_memc.print_trace("memc_tgt_c"); signal_vci_ini_c_memc.print_trace("memc_ini_c"); if (signal_proc_irq[0].read()) std::cout << "---- IRQ ----" << std::endl; sc_start(sc_time(1, SC_NS)); } } else sc_start(); return EXIT_SUCCESS; } int sc_main (int argc, char *argv[]) { try { return _main(argc, argv); } catch (std::exception &e) { std::cout << e.what() << std::endl; } catch (...) { std::cout << "Unknown exception occurred" << std::endl; throw; } return EXIT_FAILURE; }