/* * 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_icu.h" #include "vci_multi_tty.h" #include "vci_timer.h" #include "vci_block_device_tsar_v4.h" #include "vci_framebuffer.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 */ struct param_s { char *rom_path; char *dsk_path; bool dummy_boot; bool trace_enabled; size_t trace_start_cycle; }; #define PARAM_INITIALIZER \ { \ .rom_path = NULL, \ .dsk_path = NULL, \ .dummy_boot = false, \ .trace_enabled = false, \ .trace_start_cycle = 0 \ } static inline void print_param(const struct param_s ¶m) { std::cout << std::endl; std::cout << "simulation parameters:" << std::endl; std::cout << " rom = " << param.rom_path << std::endl; std::cout << " dummy boot = " << param.dummy_boot << std::endl; std::cout << " dsk = " << param.dsk_path << std::endl; std::cout << " trace = " << param.trace_enabled << std::endl; if (param.trace_enabled) std::cout << " start cyc = " << param.trace_start_cycle << std::endl; std::cout << std::endl; } /* * arguments parsing */ void args_parse(unsigned int argc, char *argv[], struct param_s ¶m) { for (size_t n = 1; n < argc; n = n + 2) { if ((strcmp(argv[n], "--rom") == 0) && ((n + 1) < argc)) { assert((param.rom_path = strdup(argv[n + 1])) && "insufficient memory"); } else if ((strcmp(argv[n], "--dsk") == 0) && ((n + 1) < argc)) { assert((param.dsk_path = strdup(argv[n + 1])) && "insufficient memory"); } else if (strcmp(argv[n], "--dummy-boot") == 0) { param.dummy_boot = true; /* we don't have an extra argument */ n = n - 1; } else if ((strcmp(argv[n], "--trace") == 0) && ((n + 1) < argc)) { param.trace_enabled = true; param.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 << "--rom pathname" << std::endl; std::cout << "--dsk pathname" << std::endl; std::cout << "[--dummy-boot]" << std::endl; std::cout << "[--trace trace_start_cycle]" << std::endl; exit(0); } } /* check parameters */ assert(param.rom_path && "--rom is not optional"); assert(param.dsk_path && "--dsk is not optional"); print_param(param); } /* * 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 struct param_s param = PARAM_INITIALIZER; /* parse arguments */ args_parse(argc, argv, param); /* * mapping table (data and coherence) */ // 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("icu_d" , ICU_BASE , ICU_SIZE , IntTab(2), false)); maptabd.add(Segment("mtty_d" , MTTY_BASE , MTTY_SIZE , IntTab(3), false)); maptabd.add(Segment("timer_d" , TIMER_BASE , TIMER_SIZE , IntTab(4), false)); maptabd.add(Segment("bd_d" , BD_BASE , BD_SIZE , IntTab(5), false)); maptabd.add(Segment("fb_d" , FB_BASE , FB_SIZE , IntTab(6), 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(param.rom_path); #ifdef CONFIG_GDB_SERVER typedef GdbServer proc_iss; proc_iss::set_loader(loader); #else typedef Mips32ElIss proc_iss; #endif if (param.dummy_boot == true) { /* boot linux image directly */ uint64_t entry_addr = loader.get_entry_point_address(); std::cout << "setResetAdress: " << std::hex << entry_addr << std::endl << std::endl; proc_iss::setResetAddress(entry_addr); } 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 param.trace_start_cycle, param.trace_enabled); VciSimpleRam ram("ram", 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 param.trace_start_cycle, param.trace_enabled); VciIcu icu("icu", IntTab(2), maptabd, 3); // #input_irqs VciMultiTty mtty("mtty", IntTab(3), maptabd, "vcitty0", NULL); VciTimer timer("timer", IntTab(4), maptabd, 1); // #timers VciBlockDeviceTsarV4 bd("bd", maptabd, IntTab(1), IntTab(5), param.dsk_path); // mapped_file[, block_size=512, latency=0] VciFrameBuffer fb("fb", IntTab(6), maptabd, FB_XSIZE, FB_YSIZE, FbController::RGB_16); VciVgmn vgmnd("vgmnd", maptabd, 2, 7, // #initiators, #targets 2, 8, // min_latency, FIFO depth IntTab(1)); // default target VciVgmn vgmnc("vgmnc", 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_timer_irq("signal_timer_irq"); sc_signal signal_bd_irq("signal_bd_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_ram("signal_vci_ram"); VciSignals signal_vci_tgt_d_rom("signal_vci_tgt_d_rom"); 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_icu("signal_vci_tgt_d_icu"); VciSignals signal_vci_tgt_d_mtty("signal_vci_tgt_d_mtty"); VciSignals signal_vci_tgt_d_timer("signal_vci_tgt_d_timer"); VciSignals signal_vci_ini_d_bd("signal_vci_ini_d_bd"); VciSignals signal_vci_tgt_d_bd("signal_vci_tgt_d_bd"); VciSignals signal_vci_tgt_d_fb("signal_vci_tgt_d_fb"); /* * 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); ram.p_clk(signal_clk); ram.p_resetn(signal_resetn); ram.p_vci(signal_vci_ram); rom.p_clk(signal_clk); rom.p_resetn(signal_resetn); rom.p_vci(signal_vci_tgt_d_rom); 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_ram); icu.p_resetn(signal_resetn); icu.p_clk(signal_clk); icu.p_vci(signal_vci_tgt_d_icu); icu.p_irq_in[0](signal_mtty_irq); icu.p_irq_in[1](signal_timer_irq); icu.p_irq_in[2](signal_bd_irq); icu.p_irq(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); timer.p_clk(signal_clk); timer.p_resetn(signal_resetn); timer.p_vci(signal_vci_tgt_d_timer); timer.p_irq[0](signal_timer_irq); bd.p_clk(signal_clk); bd.p_resetn(signal_resetn); bd.p_vci_target(signal_vci_tgt_d_bd); bd.p_vci_initiator(signal_vci_ini_d_bd); bd.p_irq(signal_bd_irq); fb.p_clk(signal_clk); fb.p_resetn(signal_resetn); fb.p_vci(signal_vci_tgt_d_fb); vgmnd.p_clk(signal_clk); vgmnd.p_resetn(signal_resetn); vgmnd.p_to_initiator[0](signal_vci_ini_d_proc); vgmnd.p_to_initiator[1](signal_vci_ini_d_bd); vgmnd.p_to_target[0](signal_vci_tgt_d_memc); vgmnd.p_to_target[1](signal_vci_tgt_d_rom); vgmnd.p_to_target[2](signal_vci_tgt_d_icu); vgmnd.p_to_target[3](signal_vci_tgt_d_mtty); vgmnd.p_to_target[4](signal_vci_tgt_d_timer); vgmnd.p_to_target[5](signal_vci_tgt_d_bd); vgmnd.p_to_target[6](signal_vci_tgt_d_fb); vgmnc.p_clk(signal_clk); vgmnc.p_resetn(signal_resetn); vgmnc.p_to_initiator[0](signal_vci_ini_c_proc); vgmnc.p_to_initiator[1](signal_vci_ini_c_memc); vgmnc.p_to_target[0](signal_vci_tgt_c_proc); vgmnc.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 (param.trace_enabled) { if (param.trace_start_cycle > 1) // simulate without output until trace_start_cycle sc_start(sc_time(param.trace_start_cycle, SC_NS)); // enable debugging output for (size_t n = param.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; }