void load_videoin_config(void) { set_format(config_read_int("vin_format", VIDEO_FORMAT_CVBS6)); set_value(CONTROL_BRIGHTNESS, config_read_int("vin_brightness", 0)); set_value(CONTROL_CONTRAST, config_read_int("vin_contrast", 0x80)); set_value(CONTROL_HUE, config_read_int("vin_hue", 0)); mtk_cmdf(appid, "s_brightness.set(-value %d)", brightness); mtk_cmdf(appid, "s_contrast.set(-value %d)", contrast); mtk_cmdf(appid, "s_hue.set(-value %d)", hue); }
void frm_spatial_report_config_read(struct config_t *config) { char *section; char *file_name; /*Nothing if section or config is not present */ section = frm_spatial_report_section_name; if (!config_section_exists(config, section)) { /*no spatial profiling */ return; } /* Spatial reports are active */ frm_spatial_report_active = 1; /* Interval */ config_var_enforce(config, section, "Interval"); spatial_profiling_interval = config_read_int(config, section, "Interval", spatial_profiling_interval); /* File name */ config_var_enforce(config, section, "File"); file_name = config_read_string(config, section, "File", NULL); if (!file_name || !*file_name) fatal("%s: %s: invalid or missing value for 'File'", frm_spatial_report_section_name, section); spatial_report_filename = str_set(NULL, file_name); spatial_report_file = file_open_for_write(spatial_report_filename); if (!spatial_report_file) fatal("%s: could not open spatial report file", spatial_report_filename); }
void evg_spatial_report_config_read(struct config_t *config) { char *section; /* Nothing if section or config is not present */ section = evg_spatial_report_section_name; if (!config_section_exists(config, section)) { /*no spatial profiling */ return; } /* Spatial reports are active */ evg_spatial_report_active = 1; /* Interval */ config_var_enforce(config, section, "Interval"); spatial_profiling_interval = config_read_int(config, section, "Interval", spatial_profiling_interval); spatial_report_file = file_open_for_write(spatial_report_filename); if (!spatial_report_file) fatal("%s: could not open spatial report file", spatial_report_filename); // FILE *f = spatial_report_file ; /*fprintf(f,"CU,CFInst,MemAcc,TEXInstn,ALUInstn,Cycles\n");*/ }
void load_dmx_config(void) { int i, value; char confname[12]; for(i=0;i<IDMX_COUNT;i++) { sprintf(confname, "idmx%d", i+1); value = config_read_int(confname, i+1); mtk_cmdf(appid, "e_idmx%d.set(-text \"%d\")", i, value); } for(i=0;i<DMX_COUNT;i++) { sprintf(confname, "dmx%d", i+1); value = config_read_int(confname, i+1); mtk_cmdf(appid, "e_dmx%d.set(-text \"%d\")", i, value); } set_chain_mode(config_read_int("dmx_chain", 1)); }
void X86ReadTraceCacheConfig(struct config_t *config) { char *section; char *file_name; /* Section in configuration file */ section = "TraceCache"; file_name = config_get_file_name(config); /* Read variables */ x86_trace_cache_present = config_read_bool(config, section, "Present", 0); x86_trace_cache_num_sets = config_read_int(config, section, "Sets", 64); x86_trace_cache_assoc = config_read_int(config, section, "Assoc", 4); x86_trace_cache_trace_size = config_read_int(config, section, "TraceSize", 16); x86_trace_cache_branch_max = config_read_int(config, section, "BranchMax", 3); x86_trace_cache_queue_size = config_read_int(config, section, "QueueSize", 32); /* Integrity checks */ if ((x86_trace_cache_num_sets & (x86_trace_cache_num_sets - 1)) || !x86_trace_cache_num_sets) fatal("%s: %s: 'Sets' must be a power of 2 greater than 0", file_name, section); if ((x86_trace_cache_assoc & (x86_trace_cache_assoc - 1)) || !x86_trace_cache_assoc) fatal("%s: %s: 'Assoc' must be a power of 2 greater than 0", file_name, section); if (!x86_trace_cache_trace_size) fatal("%s: %s: Invalid value for 'TraceSize'", file_name, section); if (!x86_trace_cache_branch_max) fatal("%s: %s: Invalid value for 'BranchMax'", file_name, section); if (x86_trace_cache_branch_max > x86_trace_cache_trace_size) fatal("%s: %s: 'BranchMax' must be equal or less than 'TraceSize'", file_name, section); if (x86_trace_cache_branch_max > 31) fatal("%s: %s: Maximum value for 'BranchMax' is 31", file_name, section); }
void X86ReadBranchPredConfig(struct config_t *config) { char *section; section = "BranchPredictor"; x86_bpred_kind = config_read_enum(config, section, "Kind", x86_bpred_kind_twolevel, x86_bpred_kind_map, 6); x86_bpred_btb_sets = config_read_int(config, section, "BTB.Sets", 256); x86_bpred_btb_assoc = config_read_int(config, section, "BTB.Assoc", 4); x86_bpred_bimod_size = config_read_int(config, section, "Bimod.Size", 1024); x86_bpred_choice_size = config_read_int(config, section, "Choice.Size", 1024); x86_bpred_ras_size = config_read_int(config, section, "RAS.Size", 32); x86_bpred_twolevel_l1size = config_read_int(config, section, "TwoLevel.L1Size", 1); x86_bpred_twolevel_l2size = config_read_int(config, section, "TwoLevel.L2Size", 1024); x86_bpred_twolevel_hist_size = config_read_int(config, section, "TwoLevel.HistorySize", 8); /* Two-level branch predictor parameter */ x86_bpred_twolevel_l2height = 1 << x86_bpred_twolevel_hist_size; /* Integrity */ if (x86_bpred_bimod_size & (x86_bpred_bimod_size - 1)) fatal("number of entries in bimodal precitor must be a power of 2"); if (x86_bpred_choice_size & (x86_bpred_choice_size - 1)) fatal("number of entries in choice predictor must be power of 2"); if (x86_bpred_btb_sets & (x86_bpred_btb_sets - 1)) fatal("number of BTB sets must be a power of 2"); if (x86_bpred_btb_assoc & (x86_bpred_btb_assoc - 1)) fatal("BTB associativity must be a power of 2"); if (x86_bpred_twolevel_hist_size < 1 || x86_bpred_twolevel_hist_size > 30) fatal("predictor history size must be >=1 and <=30"); if (x86_bpred_twolevel_l1size & (x86_bpred_twolevel_l1size - 1)) fatal("two-level predictor sizes must be power of 2"); if (x86_bpred_twolevel_l2size & (x86_bpred_twolevel_l2size - 1)) fatal("two-level predictor sizes must be power of 2"); }
void net_read_config(void) { struct config_t *config; struct list_t *net_name_list; char *section; int i; /* Configuration file */ if (!*net_config_file_name) { net_domain_index = esim_new_domain(net_frequency); return; } /* Open network configuration file */ config = config_create(net_config_file_name); if (*net_config_file_name) config_load(config); /* Section with generic configuration parameters */ section = "General"; /* Frequency */ net_frequency = config_read_int(config, section, "Frequency", net_frequency); if (!IN_RANGE(net_frequency, 1, ESIM_MAX_FREQUENCY)) fatal("%s: invalid value for 'Frequency'", net_config_file_name); /* Create frequency domain */ net_domain_index = esim_new_domain(net_frequency); /* Create a temporary list of network names found in configuration * file */ net_name_list = list_create(); for (section = config_section_first(config); section; section = config_section_next(config)) { char *delim = "."; char section_str[MAX_STRING_SIZE]; char *token; char *net_name; /* Create a copy of section name */ snprintf(section_str, sizeof section_str, "%s", section); section = section_str; /* First token must be 'Network' */ token = strtok(section, delim); if (strcasecmp(token, "Network")) continue; /* Second token is network name */ net_name = strtok(NULL, delim); if (!net_name) continue; /* No third token */ token = strtok(NULL, delim); if (token) continue; /* Insert new network name */ net_name = xstrdup(net_name); list_add(net_name_list, net_name); } /* Print network names */ net_debug("%s: loading network configuration file\n", net_config_file_name); net_debug("networks found:\n"); for (i = 0; i < net_name_list->count; i++) net_debug("\t%s\n", (char *)list_get(net_name_list, i)); net_debug("\n"); /* Load networks */ net_table = hash_table_create(0, 0); for (i = 0; i < net_name_list->count; i++) { struct net_t *network; char *net_name; net_name = list_get(net_name_list, i); network = net_create_from_config(config, net_name); hash_table_insert(net_table, net_name, network); } /* Free list of network names and configuration file */ while (net_name_list->count) free(list_remove_at(net_name_list, 0)); list_free(net_name_list); config_free(config); }
void dram_system_read_config(void) { int i ; struct config_t *config; struct list_t *dram_system_list; char *section; if (!*dram_config_file_name) { dram_domain_index = esim_new_domain(dram_frequency); return; } config = config_create(dram_config_file_name); if (*dram_config_file_name) config_load(config); /* Section with Generic Configuration Parameters */ section = "General"; /* Frequency */ dram_frequency = config_read_int(config, section, "Frequency", dram_frequency); if (!IN_RANGE(dram_frequency, 1, ESIM_MAX_FREQUENCY)) fatal("%s: Invalid value for 'Frequency'", dram_config_file_name); /* Creating the Frequency Domain */ dram_domain_index = esim_new_domain(dram_frequency); /* Create a temporary List of all Dram Systems found in * the configuration file */ dram_system_list = list_create(); for (section = config_section_first(config); section; section = config_section_next(config)) { char *delim = "."; char section_str[MAX_STRING_SIZE]; char *token; char *dram_system_name; /*Creating a copy of the name of the section */ snprintf(section_str, sizeof section_str, "%s", section); section = section_str; /* First Token Must be 'DRAMsystem' */ token = strtok(section, delim); if (strcasecmp(token, "DRAMsystem")) continue; /* Second Token must be the system Name */ dram_system_name = strtok(NULL, delim); if (!dram_system_name) continue; /* No third term is required */ token = strtok(NULL, delim); if (token) continue; /* Insert the new DRAM system name */ dram_system_name = xstrdup(dram_system_name); list_add(dram_system_list, dram_system_name); } /* Print DRAM system Names in debug */ dram_debug("%s: loading DRAM system configuration file \n", dram_config_file_name); dram_debug("DRAM systems found:\n"); for (i = 0; i < dram_system_list->count; i++) dram_debug("\t%s\n", (char *) list_get(dram_system_list, i)); dram_debug("\n"); /* Load DRAM systems */ dram_system_table = hash_table_create(0, 0); for ( i = 0; i < dram_system_list->count; i++) { struct dram_system_t *system; char *dram_system_name; dram_system_name = list_get(dram_system_list, i); system = dram_system_config_with_file(config, dram_system_name); hash_table_insert(dram_system_table, dram_system_name, system); } while (dram_system_list->count) free(list_remove_at(dram_system_list, 0)); list_free(dram_system_list); config_free(config); }
struct dram_system_t *dram_system_config_with_file(struct config_t *config, char *system_name) { int j; int controller_sections = 0; unsigned int highest_addr = 0; char *section; char section_str[MAX_STRING_SIZE]; char *row_buffer_policy_map[] = {"OpenPage", "ClosePage", "hybird"}; char *scheduling_policy_map[] = {"RankBank", "BankRank"}; struct dram_system_t *system; /* Controller parameters * FIXME: we should create a default variation for times this values * are not assigned. For now we set it as DRAM DDR3 Micron * */ unsigned int num_physical_channels = 1; unsigned int request_queue_depth = 32; enum dram_controller_row_buffer_policy_t rb_policy = open_page_row_buffer_policy; enum dram_controller_scheduling_policy_t scheduling_policy = rank_bank_round_robin; unsigned int dram_num_ranks = 8; unsigned int dram_num_devices_per_rank = 1; unsigned int dram_num_banks_per_device = 1; unsigned int dram_num_rows_per_bank = 8192; unsigned int dram_num_columns_per_row = 1024; unsigned int dram_num_bits_per_column = 16; unsigned int dram_timing_tCAS = 24; unsigned int dram_timing_tRCD = 10; unsigned int dram_timing_tRP = 10; unsigned int dram_timing_tRAS = 24; unsigned int dram_timing_tCWL = 9; unsigned int dram_timing_tCCD = 4; system = dram_system_create(system_name); /* DRAM system configuration */ snprintf(section_str, sizeof section_str, "DRAMsystem.%s", system_name); for (section = config_section_first(config); section; section = config_section_next(config)) { if (strcasecmp(section, section_str)) continue; system->num_logical_channels = config_read_int(config, section, "NumLogicalChannels", system->num_logical_channels); } /* Create controllers */ for (section = config_section_first(config); section; section = config_section_next(config)) { char *delim = "."; char *token; char *controller_name; /* First token must be 'Network' */ snprintf(section_str, sizeof section_str, "%s", section); token = strtok(section_str, delim); if (!token || strcasecmp(token, "DRAMsystem")) continue; /* Second token must be the name of the network */ token = strtok(NULL, delim); if (!token || strcasecmp(token, system_name)) continue; /* Third token must be 'Node' */ token = strtok(NULL, delim); if (!token || strcasecmp(token, "Controller")) continue; /* Get name */ controller_name = strtok(NULL, delim); token = strtok(NULL, delim); if (!controller_name || token) fatal("%s:%s: wrong format for controller name .\n%s", system->name, section, dram_err_config); /* Read Properties */ num_physical_channels = config_read_int(config, section, "NumPhysicalChannels", num_physical_channels); dram_num_ranks = config_read_int(config, section, "NumRanks", dram_num_ranks); dram_num_devices_per_rank = config_read_int(config, section, "NumDevicesPerRank", dram_num_devices_per_rank); dram_num_banks_per_device = config_read_int(config, section, "NumBanksPerDevice", dram_num_banks_per_device); dram_num_rows_per_bank = config_read_int(config, section, "NumRowsPerBank", dram_num_rows_per_bank); dram_num_columns_per_row = config_read_int(config, section, "NumColumnPerRow", dram_num_columns_per_row); dram_num_bits_per_column = config_read_int(config, section, "NumBitsPerColumn", dram_num_bits_per_column); request_queue_depth = config_read_int(config, section, "RequestQueueDepth", request_queue_depth); rb_policy = config_read_enum(config, section, "RowBufferPolicy", rb_policy, row_buffer_policy_map, 3); scheduling_policy = config_read_enum(config, section, "SchedulingPolicy", scheduling_policy, scheduling_policy_map, 2); dram_timing_tCAS = config_read_int(config, section, "tCAS", dram_timing_tCAS); dram_timing_tRCD = config_read_int(config, section, "tRCD", dram_timing_tRCD); dram_timing_tRP = config_read_int(config, section, "tRP", dram_timing_tRP); dram_timing_tRAS = config_read_int(config, section, "tRAS", dram_timing_tRAS); dram_timing_tCWL = config_read_int(config, section, "tCWL", dram_timing_tCWL); dram_timing_tCCD = config_read_int(config, section, "tCCD", dram_timing_tCCD); /* Create controller */ struct dram_controller_t *controller; controller = dram_controller_create(request_queue_depth, rb_policy, scheduling_policy); /* Assign controller parameters */ controller->id = controller_sections; if (!controller_sections) controller->lowest_addr = 0; else controller->lowest_addr = highest_addr + 1; controller->highest_addr = controller->lowest_addr + ((dram_num_bits_per_column * dram_num_devices_per_rank) / 8 * dram_num_columns_per_row * dram_num_rows_per_bank * dram_num_banks_per_device * dram_num_ranks * num_physical_channels) - 1; controller->dram_addr_bits_rank = log_base2(dram_num_ranks); controller->dram_addr_bits_row = log_base2(dram_num_rows_per_bank); controller->dram_addr_bits_bank = log_base2(dram_num_banks_per_device); controller->dram_addr_bits_column = log_base2(dram_num_columns_per_row); controller->dram_addr_bits_physical_channel = log_base2(num_physical_channels); controller->dram_addr_bits_byte = log_base2(dram_num_bits_per_column * dram_num_devices_per_rank / 8); controller->dram_timing_tCAS = dram_timing_tCAS; controller->dram_timing_tRCD = dram_timing_tRCD; controller->dram_timing_tRP = dram_timing_tRP; controller->dram_timing_tRAS = dram_timing_tRAS; controller->dram_timing_tCWL = dram_timing_tCWL; controller->dram_timing_tCCD = dram_timing_tCCD; /* Update the highest address in memory system */ highest_addr = controller->highest_addr; /* Add controller to system */ list_add(system->dram_controller_list, controller); /* Create and add DRAM*/ for (j = 0; j < num_physical_channels; j++) { struct dram_t *dram; dram = dram_create(dram_num_ranks, dram_num_devices_per_rank, dram_num_banks_per_device, dram_num_rows_per_bank, dram_num_columns_per_row, dram_num_bits_per_column); dram->timing_tCAS = dram_timing_tCAS; dram->timing_tRCD = dram_timing_tRCD; dram->timing_tRP = dram_timing_tRP; dram->timing_tRAS = dram_timing_tRAS; dram->timing_tCWL = dram_timing_tCWL; dram_controller_add_dram(list_get(system->dram_controller_list, controller_sections), dram); } controller_sections++; } if (controller_sections != system->num_logical_channels) fatal("%s: number of controllers should match the number of logical" "channels \n%s", system->name, dram_err_config); /* Request Section */ for (section = config_section_first(config); section; section = config_section_next(config)) { char *delim = "."; char *token; char *token_endl; /* First token must be 'Network' */ snprintf(section_str, sizeof section_str, "%s", section); token = strtok(section_str, delim); if (!token || strcasecmp(token, "DRAMsystem")) continue; /* Second token must be the name of the network */ token = strtok(NULL, delim); if (!token || strcasecmp(token, system_name)) continue; /* Third token must be 'Commands' */ token = strtok(NULL, delim); if (!token || strcasecmp(token, "Requests")) continue; token_endl = strtok(NULL, delim); if (token_endl) fatal("%s: %s: bad format for Commands section.\n%s", system_name, section, dram_err_config); /* Requests */ dram_config_request_create(system, config, section); config_check(config); } /* Return dram_system on success */ return system; }
void X86CpuReadConfig(void) { struct config_t *config; char *section; /* Open file */ config = config_create(x86_config_file_name); if (*x86_config_file_name) config_load(config); /* General configuration */ section = "General"; x86_cpu_frequency = config_read_int(config, section, "Frequency", x86_cpu_frequency); if (!IN_RANGE(x86_cpu_frequency, 1, ESIM_MAX_FREQUENCY)) fatal("%s: invalid value for 'Frequency'.", x86_config_file_name); x86_cpu_num_cores = config_read_int(config, section, "Cores", x86_cpu_num_cores); x86_cpu_num_threads = config_read_int(config, section, "Threads", x86_cpu_num_threads); x86_cpu_fast_forward_count = config_read_llint(config, section, "FastForward", 0); x86_cpu_context_quantum = config_read_int(config, section, "ContextQuantum", 100000); x86_cpu_thread_quantum = config_read_int(config, section, "ThreadQuantum", 1000); x86_cpu_thread_switch_penalty = config_read_int(config, section, "ThreadSwitchPenalty", 0); x86_cpu_recover_kind = config_read_enum(config, section, "RecoverKind", x86_cpu_recover_kind_writeback, x86_cpu_recover_kind_map, 2); x86_cpu_recover_penalty = config_read_int(config, section, "RecoverPenalty", 0); x86_emu_process_prefetch_hints = config_read_bool(config, section, "ProcessPrefetchHints", 1); prefetch_history_size = config_read_int(config, section, "PrefetchHistorySize", 10); /* Section '[ Pipeline ]' */ section = "Pipeline"; x86_cpu_fetch_kind = config_read_enum(config, section, "FetchKind", x86_cpu_fetch_kind_timeslice, x86_cpu_fetch_kind_map, 3); x86_cpu_decode_width = config_read_int(config, section, "DecodeWidth", 4); x86_cpu_dispatch_kind = config_read_enum(config, section, "DispatchKind", x86_cpu_dispatch_kind_timeslice, x86_cpu_dispatch_kind_map, 2); x86_cpu_dispatch_width = config_read_int(config, section, "DispatchWidth", 4); x86_cpu_issue_kind = config_read_enum(config, section, "IssueKind", x86_cpu_issue_kind_timeslice, x86_cpu_issue_kind_map, 2); x86_cpu_issue_width = config_read_int(config, section, "IssueWidth", 4); x86_cpu_commit_kind = config_read_enum(config, section, "CommitKind", x86_cpu_commit_kind_shared, x86_cpu_commit_kind_map, 2); x86_cpu_commit_width = config_read_int(config, section, "CommitWidth", 4); x86_cpu_occupancy_stats = config_read_bool(config, section, "OccupancyStats", 0); /* Section '[ Queues ]' */ section = "Queues"; x86_fetch_queue_size = config_read_int(config, section, "FetchQueueSize", 64); x86_uop_queue_size = config_read_int(config, section, "UopQueueSize", 32); x86_rob_kind = config_read_enum(config, section, "RobKind", x86_rob_kind_private, x86_rob_kind_map, 2); x86_rob_size = config_read_int(config, section, "RobSize", 64); x86_iq_kind = config_read_enum(config, section, "IqKind", x86_iq_kind_private, x86_iq_kind_map, 2); x86_iq_size = config_read_int(config, section, "IqSize", 40); x86_lsq_kind = config_read_enum(config, section, "LsqKind", x86_lsq_kind_private, x86_lsq_kind_map, 2); x86_lsq_size = config_read_int(config, section, "LsqSize", 20); /* Register file */ X86ReadRegFileConfig(config); /* Functional Units */ X86ReadFunctionalUnitsConfig(config); /* Branch predictor */ X86ReadBranchPredConfig(config); /* Trace Cache */ X86ReadTraceCacheConfig(config); /* Close file */ config_check(config); config_free(config); }
void FrmGpuMemConfigParseEntry(Timing *self, struct config_t *config, char *section) { char *file_name; char *module_name; int sm_id; FrmSM *sm; /* Get configuration file name */ file_name = config_get_file_name(config); /* Allow these sections in case we quit before reading them. */ config_var_allow(config, section, "Module"); /* Read SM */ sm_id = config_read_int(config, section, "SM", -1); if (sm_id < 0) fatal("%s: section [%s]: invalid or missing value for 'SM'", file_name, section); /* Check SM boundaries */ if (sm_id >= frm_gpu_num_sms) { warning("%s: section [%s] ignored, referring to Fermi SM[%d].\n" "\tThis section refers to a SM that does not currently exist.\n" "\tPlease review your Fermi configuration file if this is not the\n" "\tdesired behavior.\n", file_name, section, sm_id); return; } /* Check that entry has not been assigned before */ sm = frm_gpu->sms[sm_id]; if (sm->global_memory) fatal("%s: section [%s]: entry from SM[%d] already assigned.\n" "\tA different [Entry <name>] section in the memory configuration file has already\n" "\tassigned an entry for this particular SM. Please review your\n" "\tconfiguration file to avoid duplicates.\n", file_name, section, sm_id); /* Read module */ module_name = config_read_string(config, section, "Module", NULL); if (!module_name) fatal("%s: section [%s]: variable 'Module' missing.\n" "\tPlease run use '--mem-help' for more information on the\n" "\tconfiguration file format, or consult the Multi2Sim Guide.\n", file_name, section); /* Assign module */ sm->global_memory = mem_system_get_mod(module_name); if (!sm->global_memory) fatal("%s: section [%s]: '%s' is not a valid module name.\n" "\tThe given module name must match a module declared in a section\n" "\t[Module <name>] in the memory configuration file.\n", file_name, section, module_name); /* Add modules to list of memory entries */ linked_list_add(arch_fermi->mem_entry_mod_list, sm->global_memory); /* Debug */ mem_debug("\tFermi SM[%d]\n", sm_id); mem_debug("\t\tEntry -> %s\n", sm->global_memory->name); mem_debug("\n"); }
void evg_gpu_read_config(void) { struct config_t *gpu_config; char *section; char *err_note = "\tPlease run 'm2s --evg-help' or consult the Multi2Sim Guide for a\n" "\tdescription of the GPU configuration file format."; char *gpu_register_alloc_granularity_str; char *gpu_sched_policy_str; /* Load GPU configuration file */ gpu_config = config_create(evg_gpu_config_file_name); if (*evg_gpu_config_file_name) config_load(gpu_config); /* Device */ section = "Device"; /* Frequency */ evg_gpu_frequency = config_read_int(gpu_config, section, "Frequency", evg_gpu_frequency); if (!IN_RANGE(evg_gpu_frequency, 1, ESIM_MAX_FREQUENCY)) fatal("%s: invalid value for 'Frequency'.\n%s", evg_gpu_config_file_name, err_note); evg_gpu_num_compute_units = config_read_int(gpu_config, section, "NumComputeUnits", evg_gpu_num_compute_units); evg_gpu_num_stream_cores = config_read_int(gpu_config, section, "NumStreamCores", evg_gpu_num_stream_cores); evg_gpu_num_registers = config_read_int(gpu_config, section, "NumRegisters", evg_gpu_num_registers); evg_gpu_register_alloc_size = config_read_int(gpu_config, section, "RegisterAllocSize", evg_gpu_register_alloc_size); gpu_register_alloc_granularity_str = config_read_string(gpu_config, section, "RegisterAllocGranularity", "WorkGroup"); evg_emu_wavefront_size = config_read_int(gpu_config, section, "WavefrontSize", evg_emu_wavefront_size); evg_gpu_max_work_groups_per_compute_unit = config_read_int(gpu_config, section, "MaxWorkGroupsPerComputeUnit", evg_gpu_max_work_groups_per_compute_unit); evg_gpu_max_wavefronts_per_compute_unit = config_read_int(gpu_config, section, "MaxWavefrontsPerComputeUnit", evg_gpu_max_wavefronts_per_compute_unit); gpu_sched_policy_str = config_read_string(gpu_config, section, "SchedulingPolicy", "RoundRobin"); if (evg_gpu_num_compute_units < 1) fatal("%s: invalid value for 'NumComputeUnits'.\n%s", evg_gpu_config_file_name, err_note); if (evg_gpu_num_stream_cores < 1) fatal("%s: invalid value for 'NumStreamCores'.\n%s", evg_gpu_config_file_name, err_note); if (evg_gpu_register_alloc_size < 1) fatal("%s: invalid value for 'RegisterAllocSize'.\n%s", evg_gpu_config_file_name, err_note); if (evg_gpu_num_registers < 1) fatal("%s: invalid value for 'NumRegisters'.\n%s", evg_gpu_config_file_name, err_note); if (evg_gpu_num_registers % evg_gpu_register_alloc_size) fatal("%s: 'NumRegisters' must be a multiple of 'RegisterAllocSize'.\n%s", evg_gpu_config_file_name, err_note); evg_gpu_register_alloc_granularity = str_map_string_case(&evg_gpu_register_alloc_granularity_map, gpu_register_alloc_granularity_str); if (evg_gpu_register_alloc_granularity == evg_gpu_register_alloc_invalid) fatal("%s: invalid value for 'RegisterAllocGranularity'.\n%s", evg_gpu_config_file_name, err_note); evg_gpu_sched_policy = str_map_string_case(&evg_gpu_sched_policy_map, gpu_sched_policy_str); if (evg_gpu_sched_policy == evg_gpu_sched_invalid) fatal("%s: invalid value for 'SchedulingPolicy'.\n%s", evg_gpu_config_file_name, err_note); if (evg_emu_wavefront_size < 1) fatal("%s: invalid value for 'WavefrontSize'.\n%s", evg_gpu_config_file_name, err_note); if (evg_gpu_max_work_groups_per_compute_unit < 1) fatal("%s: invalid value for 'MaxWorkGroupsPerComputeUnit'.\n%s", evg_gpu_config_file_name, err_note); if (evg_gpu_max_wavefronts_per_compute_unit < 1) fatal("%s: invalid value for 'MaxWavefrontsPerComputeUnit'.\n%s", evg_gpu_config_file_name, err_note); /* Local memory */ section = "LocalMemory"; evg_gpu_local_mem_size = config_read_int(gpu_config, section, "Size", evg_gpu_local_mem_size); evg_gpu_local_mem_alloc_size = config_read_int(gpu_config, section, "AllocSize", evg_gpu_local_mem_alloc_size); evg_gpu_local_mem_block_size = config_read_int(gpu_config, section, "BlockSize", evg_gpu_local_mem_block_size); evg_gpu_local_mem_latency = config_read_int(gpu_config, section, "Latency", evg_gpu_local_mem_latency); evg_gpu_local_mem_num_ports = config_read_int(gpu_config, section, "Ports", evg_gpu_local_mem_num_ports); if ((evg_gpu_local_mem_size & (evg_gpu_local_mem_size - 1)) || evg_gpu_local_mem_size < 4) fatal("%s: %s->Size must be a power of two and at least 4.\n%s", evg_gpu_config_file_name, section, err_note); if (evg_gpu_local_mem_alloc_size < 1) fatal("%s: invalid value for %s->Allocsize.\n%s", evg_gpu_config_file_name, section, err_note); if (evg_gpu_local_mem_size % evg_gpu_local_mem_alloc_size) fatal("%s: %s->Size must be a multiple of %s->AllocSize.\n%s", evg_gpu_config_file_name, section, section, err_note); if ((evg_gpu_local_mem_block_size & (evg_gpu_local_mem_block_size - 1)) || evg_gpu_local_mem_block_size < 4) fatal("%s: %s->BlockSize must be a power of two and at least 4.\n%s", evg_gpu_config_file_name, section, err_note); if (evg_gpu_local_mem_alloc_size % evg_gpu_local_mem_block_size) fatal("%s: %s->AllocSize must be a multiple of %s->BlockSize.\n%s", evg_gpu_config_file_name, section, section, err_note); if (evg_gpu_local_mem_latency < 1) fatal("%s: invalid value for %s->Latency.\n%s", evg_gpu_config_file_name, section, err_note); if (evg_gpu_local_mem_size < evg_gpu_local_mem_block_size) fatal("%s: %s->Size cannot be smaller than %s->BlockSize * %s->Banks.\n%s", evg_gpu_config_file_name, section, section, section, err_note); /* CF Engine */ section = "CFEngine"; evg_gpu_cf_engine_inst_mem_latency = config_read_int(gpu_config, section, "InstructionMemoryLatency", evg_gpu_cf_engine_inst_mem_latency); if (evg_gpu_cf_engine_inst_mem_latency < 1) fatal("%s: invalid value for %s->InstructionMemoryLatency.\n%s", evg_gpu_config_file_name, section, err_note); /* ALU Engine */ section = "ALUEngine"; evg_gpu_alu_engine_inst_mem_latency = config_read_int(gpu_config, section, "InstructionMemoryLatency", evg_gpu_alu_engine_inst_mem_latency); evg_gpu_alu_engine_fetch_queue_size = config_read_int(gpu_config, section, "FetchQueueSize", evg_gpu_alu_engine_fetch_queue_size); evg_gpu_alu_engine_pe_latency = config_read_int(gpu_config, section, "ProcessingElementLatency", evg_gpu_alu_engine_pe_latency); if (evg_gpu_alu_engine_inst_mem_latency < 1) fatal("%s: invalid value for %s->InstructionMemoryLatency.\n%s", evg_gpu_config_file_name, section, err_note); if (evg_gpu_alu_engine_fetch_queue_size < 56) fatal("%s: the minimum value for %s->FetchQueueSize is 56.\n" "This is the maximum size of one VLIW bundle, including 5 ALU instructions\n" "(2 words each), and 4 literal constants (1 word each).\n%s", evg_gpu_config_file_name, section, err_note); if (evg_gpu_alu_engine_pe_latency < 1) fatal("%s: invalid value for %s->ProcessingElementLatency.\n%s", evg_gpu_config_file_name, section, err_note); /* TEX Engine */ section = "TEXEngine"; evg_gpu_tex_engine_inst_mem_latency = config_read_int(gpu_config, section, "InstructionMemoryLatency", evg_gpu_tex_engine_inst_mem_latency); evg_gpu_tex_engine_fetch_queue_size = config_read_int(gpu_config, section, "FetchQueueSize", evg_gpu_tex_engine_fetch_queue_size); evg_gpu_tex_engine_load_queue_size = config_read_int(gpu_config, section, "LoadQueueSize", evg_gpu_tex_engine_load_queue_size); if (evg_gpu_tex_engine_inst_mem_latency < 1) fatal("%s: invalid value for %s.InstructionMemoryLatency.\n%s", evg_gpu_config_file_name, section, err_note); if (evg_gpu_tex_engine_fetch_queue_size < 16) fatal("%s: the minimum value for %s.FetchQueueSize is 16.\n" "This size corresponds to the 4 words comprising a TEX Evergreen instruction.\n%s", evg_gpu_config_file_name, section, err_note); if (evg_gpu_tex_engine_load_queue_size < 1) fatal("%s: the minimum value for %s.LoadQueueSize is 1.\n%s", evg_gpu_config_file_name, section, err_note); /* Periodic report */ evg_periodic_report_config_read(gpu_config); evg_spatial_report_config_read(gpu_config); /* Close GPU configuration file */ config_check(gpu_config); config_free(gpu_config); }
static void si_config_read(void) { struct config_t *gpu_config; char *section; char *err_note = "\tPlease run 'm2s --help-gpu-config' or consult the Multi2Sim Guide for a\n" "\tdescription of the GPU configuration file format."; char *gpu_register_alloc_granularity_str; char *gpu_sched_policy_str; /* Load GPU configuration file */ gpu_config = config_create(si_gpu_config_file_name); if (*si_gpu_config_file_name && !config_load(gpu_config)) fatal("%s: cannot load GPU configuration file", si_gpu_config_file_name); /* Device */ section = "Device"; si_gpu_num_compute_units = config_read_int(gpu_config, section, "NumComputeUnits", si_gpu_num_compute_units); si_gpu_num_wavefront_pools = config_read_int(gpu_config, section, "NumWavefrontPools", si_gpu_num_wavefront_pools); si_gpu_num_stream_cores = config_read_int(gpu_config, section, "NumStreamCores", si_gpu_num_stream_cores); si_gpu_num_registers = config_read_int(gpu_config, section, "NumRegisters", si_gpu_num_registers); si_gpu_register_alloc_size = config_read_int(gpu_config, section, "RegisterAllocSize", si_gpu_register_alloc_size); gpu_register_alloc_granularity_str = config_read_string(gpu_config, section, "RegisterAllocGranularity", "WorkGroup"); si_emu_wavefront_size = config_read_int(gpu_config, section, "WavefrontSize", si_emu_wavefront_size); si_gpu_max_work_groups_per_wavefront_pool = config_read_int(gpu_config, section, "MaxWorkGroupsPerComputeUnit", si_gpu_max_work_groups_per_wavefront_pool); si_gpu_max_wavefronts_per_wavefront_pool = config_read_int(gpu_config, section, "MaxWavefrontsPerComputeUnit", si_gpu_max_wavefronts_per_wavefront_pool); si_gpu_fetch_latency = config_read_int(gpu_config, section, "FetchLatency", si_gpu_fetch_latency); si_gpu_decode_latency = config_read_int(gpu_config, section, "DecodeLatency", si_gpu_decode_latency); si_gpu_simd_issue_width = config_read_int(gpu_config, section, "SIMDIssueWidth", si_gpu_simd_issue_width); si_gpu_simd_alu_latency = config_read_int(gpu_config, section, "SIMDALULatency", si_gpu_simd_alu_latency); si_gpu_scalar_unit_issue_width= config_read_int(gpu_config, section, "ScalarUnitIssueWidth", si_gpu_scalar_unit_issue_width); si_gpu_scalar_unit_alu_latency = config_read_int(gpu_config, section, "ScalarUnitALULatency", si_gpu_scalar_unit_alu_latency); si_gpu_branch_unit_issue_width = config_read_int(gpu_config, section, "BranchUnitIssueWidth", si_gpu_branch_unit_issue_width); si_gpu_branch_unit_latency = config_read_int(gpu_config, section, "BranchUnitLatency", si_gpu_branch_unit_latency); gpu_sched_policy_str = config_read_string(gpu_config, section, "SchedulingPolicy", "RoundRobin"); if (si_gpu_num_compute_units < 1) fatal("%s: invalid value for 'NumComputeUnits'.\n%s", si_gpu_config_file_name, err_note); if (si_gpu_num_wavefront_pools < 1) fatal("%s: invalid value for 'NumWavefrontPools'.\n%s", si_gpu_config_file_name, err_note); if (si_gpu_num_stream_cores < 1) fatal("%s: invalid value for 'NumStreamCores'.\n%s", si_gpu_config_file_name, err_note); if (si_gpu_register_alloc_size < 1) fatal("%s: invalid value for 'RegisterAllocSize'.\n%s", si_gpu_config_file_name, err_note); if (si_gpu_num_registers < 1) fatal("%s: invalid value for 'NumRegisters'.\n%s", si_gpu_config_file_name, err_note); if (si_gpu_num_registers % si_gpu_register_alloc_size) fatal("%s: 'NumRegisters' must be a multiple of 'RegisterAllocSize'.\n%s", si_gpu_config_file_name, err_note); si_gpu_register_alloc_granularity = map_string_case(&si_gpu_register_alloc_granularity_map, gpu_register_alloc_granularity_str); if (si_gpu_register_alloc_granularity == si_gpu_register_alloc_invalid) fatal("%s: invalid value for 'RegisterAllocGranularity'.\n%s", si_gpu_config_file_name, err_note); si_gpu_sched_policy = map_string_case(&si_gpu_sched_policy_map, gpu_sched_policy_str); if (si_gpu_sched_policy == si_gpu_sched_invalid) fatal("%s: invalid value for 'SchedulingPolicy'.\n%s", si_gpu_config_file_name, err_note); if (si_emu_wavefront_size < 1) fatal("%s: invalid value for 'WavefrontSize'.\n%s", si_gpu_config_file_name, err_note); if (si_gpu_max_work_groups_per_wavefront_pool < 1) fatal("%s: invalid value for 'MaxWorkGroupsPerComputeUnit'.\n%s", si_gpu_config_file_name, err_note); if (si_gpu_max_wavefronts_per_wavefront_pool < 1) fatal("%s: invalid value for 'MaxWavefrontsPerComputeUnit'.\n%s", si_gpu_config_file_name, err_note); /* Local memory */ section = "LocalMemory"; si_gpu_local_mem_size = config_read_int(gpu_config, section, "Size", si_gpu_local_mem_size); si_gpu_local_mem_alloc_size = config_read_int(gpu_config, section, "AllocSize", si_gpu_local_mem_alloc_size); si_gpu_local_mem_block_size = config_read_int(gpu_config, section, "BlockSize", si_gpu_local_mem_block_size); si_gpu_local_mem_latency = config_read_int(gpu_config, section, "Latency", si_gpu_local_mem_latency); si_gpu_local_mem_num_ports = config_read_int(gpu_config, section, "Ports", si_gpu_local_mem_num_ports); if ((si_gpu_local_mem_size & (si_gpu_local_mem_size - 1)) || si_gpu_local_mem_size < 4) fatal("%s: %s->Size must be a power of two and at least 4.\n%s", si_gpu_config_file_name, section, err_note); if (si_gpu_local_mem_alloc_size < 1) fatal("%s: invalid value for %s->Allocsize.\n%s", si_gpu_config_file_name, section, err_note); if (si_gpu_local_mem_size % si_gpu_local_mem_alloc_size) fatal("%s: %s->Size must be a multiple of %s->AllocSize.\n%s", si_gpu_config_file_name, section, section, err_note); if ((si_gpu_local_mem_block_size & (si_gpu_local_mem_block_size - 1)) || si_gpu_local_mem_block_size < 4) fatal("%s: %s->BlockSize must be a power of two and at least 4.\n%s", si_gpu_config_file_name, section, err_note); if (si_gpu_local_mem_alloc_size % si_gpu_local_mem_block_size) fatal("%s: %s->AllocSize must be a multiple of %s->BlockSize.\n%s", si_gpu_config_file_name, section, section, err_note); if (si_gpu_local_mem_latency < 1) fatal("%s: invalid value for %s->Latency.\n%s", si_gpu_config_file_name, section, err_note); if (si_gpu_local_mem_size < si_gpu_local_mem_block_size) fatal("%s: %s->Size cannot be smaller than %s->BlockSize * %s->Banks.\n%s", si_gpu_config_file_name, section, section, section, err_note); /* Close GPU configuration file */ config_check(gpu_config); config_free(gpu_config); }
void SIGpuMemConfigParseEntry(Timing *self, struct config_t *config, char *section) { char *file_name; char *vector_module_name; char *scalar_module_name; int unified_present; int separate_present; int compute_unit_id; struct si_compute_unit_t *compute_unit; /* Get configuration file name */ file_name = config_get_file_name(config); /* Allow these sections in case we quit before reading them. */ config_var_allow(config, section, "DataModule"); config_var_allow(config, section, "ConstantDataModule"); config_var_allow(config, section, "Module"); unified_present = config_var_exists(config, section, "Module"); separate_present = config_var_exists(config, section, "DataModule") && config_var_exists(config, section, "ConstantDataModule"); if (!unified_present && !separate_present) { fatal( "%s: section [%s]: variable 'Module' missing.\n" "\tPlease run use '--mem-help' for more information on the\n" "\tconfiguration file format, or consult the Multi2Sim Guide.\n", file_name, section); } if (!(unified_present ^ separate_present)) { fatal( "%s: section [%s]: invalid combination of modules.\n" "\tA Southern Islands entry to the memory hierarchy needs to specify\n" "\teither a unified entry for vector and scalar caches (variable \n" "\t'Module'), or two separate entries for data and scalar (constant)\n" "\tdata (variables 'DataModule' and 'ConstantDataModule'), but not\n" "\tboth.\n", file_name, section); } /* Read compute unit */ compute_unit_id = config_read_int(config, section, "ComputeUnit", -1); if (compute_unit_id < 0) { fatal("%s: section [%s]: invalid or missing value for " "'ComputeUnit'", file_name, section); } /* Check compute unit boundaries */ if (compute_unit_id >= si_gpu_num_compute_units) { warning( "%s: section [%s] ignored, referring to Southern Islands \n" "\tcompute unit %d. This section refers to a compute unit that\n" "\tdoes not currently exist. Please review your Southern Islands\n" "\tconfiguration file if this is not the desired behavior.\n", file_name, section, compute_unit_id); return; } /* Check that entry has not been assigned before */ compute_unit = si_gpu->compute_units[compute_unit_id]; if (compute_unit->vector_cache) { fatal( "%s: section [%s]: entry from compute unit %d already assigned.\n" "\tA different [Entry <name>] section in the memory configuration\n" "\tfile has already assigned an entry for this particular compute \n" "\tunit. Please review your tconfiguration file to avoid duplicates.\n", file_name, section, compute_unit_id); } /* Read modules */ if (separate_present) { vector_module_name = config_read_string(config, section, "DataModule", NULL); scalar_module_name = config_read_string(config, section, "ConstantDataModule", NULL); } else { vector_module_name = scalar_module_name = config_read_string(config, section, "Module", NULL); } assert(vector_module_name); assert(scalar_module_name); /* Assign modules */ compute_unit->vector_cache = mem_system_get_mod(vector_module_name); if (!compute_unit->vector_cache) { fatal( "%s: section [%s]: '%s' is not a valid module name.\n" "\tThe given module name must match a module declared in a section\n" "\t[Module <name>] in the memory configuration file.\n", file_name, section, vector_module_name); } compute_unit->scalar_cache = mem_system_get_mod(scalar_module_name); if (!compute_unit->scalar_cache) { fatal( "%s: section [%s]: '%s' is not a valid module name.\n" "\tThe given module name must match a module declared in a section\n" "\t[Module <name>] in the memory configuration file.\n", file_name, section, scalar_module_name); } /* Add modules to list of memory entries */ linked_list_add(arch_southern_islands->mem_entry_mod_list, compute_unit->vector_cache); linked_list_add(arch_southern_islands->mem_entry_mod_list, compute_unit->scalar_cache); /* Debug */ mem_debug("\tSouthern Islands compute unit %d\n", compute_unit_id); mem_debug("\t\tEntry for vector mem -> %s\n", compute_unit->vector_cache->name); mem_debug("\t\tEntry for scalar mem -> %s\n", compute_unit->scalar_cache->name); mem_debug("\n"); }
struct net_t *net_create_from_config(struct config_t *config, char *name) { int routing_type = 0; struct net_t *net; char *section; char section_str[MAX_STRING_SIZE]; int def_input_buffer_size; int def_output_buffer_size; int def_bandwidth; /* Create network */ net = net_create(name); /* Main section */ snprintf(section_str, sizeof section_str, "Network.%s", name); for (section = config_section_first(config); section; section = config_section_next(config)) { if (strcasecmp(section, section_str)) continue; net->def_input_buffer_size = config_read_int(config, section, "DefaultInputBufferSize", 0); net->def_output_buffer_size = config_read_int(config, section, "DefaultOutputBufferSize", 0); def_bandwidth = config_read_int(config, section, "DefaultBandwidth", 0); if (!net->def_input_buffer_size) fatal("%s:%s: DefaultInputBufferSize: invalid/missing value.\n%s", net->name, section, net_err_config); if (!net->def_output_buffer_size) fatal("%s:%s: DefaultOutputBufferSize: invalid/missing value.\n%s", net->name, section, net_err_config); if (!def_bandwidth) fatal("%s:%s: DefaultBandwidth: invalid/missing value.\n%s", net->name, section, net_err_config); def_output_buffer_size = net->def_output_buffer_size; def_input_buffer_size = net->def_input_buffer_size; } /* Nodes */ for (section = config_section_first(config); section; section = config_section_next(config)) { char *delim = "."; char *token; char *node_name; char *node_type; int input_buffer_size; int output_buffer_size; int bandwidth; int lanes; /* BUS lanes */ /* First token must be 'Network' */ snprintf(section_str, sizeof section_str, "%s", section); token = strtok(section_str, delim); if (!token || strcasecmp(token, "Network")) continue; /* Second token must be the name of the network */ token = strtok(NULL, delim); if (!token || strcasecmp(token, name)) continue; /* Third token must be 'Node' */ token = strtok(NULL, delim); if (!token || strcasecmp(token, "Node")) continue; /* Get name */ node_name = strtok(NULL, delim); token = strtok(NULL, delim); if (!node_name || token) fatal("%s:%s: wrong format for node.\n%s", net->name, section, net_err_config); /* Get properties */ node_type = config_read_string(config, section, "Type", ""); input_buffer_size = config_read_int(config, section, "InputBufferSize", def_input_buffer_size); output_buffer_size = config_read_int(config, section, "OutputBufferSize", def_output_buffer_size); bandwidth = config_read_int(config, section, "BandWidth", def_bandwidth); lanes = config_read_int(config, section, "Lanes", 1); /* Create node */ if (!strcasecmp(node_type, "EndNode")) net_add_end_node(net, input_buffer_size, output_buffer_size, node_name, NULL); else if (!strcasecmp(node_type, "Switch")) net_add_switch(net, input_buffer_size, output_buffer_size, bandwidth, node_name); else if (!strcasecmp(node_type, "Bus")) { /* Right now we ignore the size of buffers. But we * can set it as the value for bus ports, making the * connecting switches asymmetric. */ if (input_buffer_size != def_input_buffer_size || output_buffer_size != def_output_buffer_size) fatal("%s:%s: BUS does not contain input/output buffers. " "Size values will be ignored \n", net->name, section); /* If the number of lanes is smaller than 1 produce * an error */ if (lanes < 1) fatal("%s:%s: BUS cannot have less than 1 number of lanes \n%s", net->name, section, net_err_config); net_add_bus(net, bandwidth, node_name, lanes); } else fatal("%s:%s: Type: invalid/missing value.\n%s", net->name, section, net_err_config); } /* Links */ for (section = config_section_first(config); section; section = config_section_next(config)) { char *delim = "."; char *token; char *link_name; char *link_type; char *src_node_name; char *dst_node_name; int bandwidth; int v_channel_count; int src_buffer_size; int dst_buffer_size; struct net_node_t *src_node; struct net_node_t *dst_node; /* First token must be 'Network' */ snprintf(section_str, sizeof section_str, "%s", section); token = strtok(section_str, delim); if (!token || strcasecmp(token, "Network")) continue; /* Second token must be the name of the network */ token = strtok(NULL, delim); if (!token || strcasecmp(token, name)) continue; /* Third token must be 'Link' */ token = strtok(NULL, delim); if (!token || strcasecmp(token, "Link")) continue; /* Fourth token must name of the link */ link_name = strtok(NULL, delim); token = strtok(NULL, delim); if (!link_name || token) fatal("%s: %s: bad format for link.\n%s", name, section, net_err_config); /* Fields */ link_type = config_read_string(config, section, "Type", "Unidirectional"); bandwidth = config_read_int(config, section, "Bandwidth", def_bandwidth); src_node_name = config_read_string(config, section, "Source", ""); dst_node_name = config_read_string(config, section, "Dest", ""); v_channel_count = config_read_int(config, section, "VC", 1); src_buffer_size = config_read_int(config, section, "SourceBufferSize", 0); dst_buffer_size = config_read_int(config, section, "DestBufferSize", 0); /* Nodes */ src_node = net_get_node_by_name(net, src_node_name); dst_node = net_get_node_by_name(net, dst_node_name); if (!src_node) fatal("%s: %s: %s: source node does not exist.\n%s", name, section, src_node_name, net_err_config); if (!dst_node) fatal("%s: %s: %s: destination node does not exist.\n%s", name, section, dst_node_name, net_err_config); /* If it is a link connection */ if (src_node->kind != net_node_bus && dst_node->kind != net_node_bus) { int link_src_bsize; int link_dst_bsize; if (v_channel_count >= 1) { if (!strcasecmp(link_type, "Unidirectional")) { link_src_bsize = (src_buffer_size)? src_buffer_size : src_node->output_buffer_size; link_dst_bsize = (dst_buffer_size) ?dst_buffer_size : dst_node->input_buffer_size; net_add_link(net, src_node, dst_node, bandwidth, link_src_bsize, link_dst_bsize, v_channel_count); } else if (!strcasecmp(link_type, "Bidirectional")) { net_add_bidirectional_link(net, src_node, dst_node, bandwidth, src_buffer_size, dst_buffer_size, v_channel_count); } } else fatal("%s: %s: Unacceptable number of virtual channels \n %s", name, section, net_err_config); } /* If is is a Bus Connection */ else { if (v_channel_count > 1) fatal("%s: %s: BUS can not have virtual channels. \n %s", name, section, net_err_config); if (!strcasecmp(link_type, "Unidirectional")) { if ((src_node->kind == net_node_bus && src_buffer_size) || (dst_node->kind == net_node_bus && dst_buffer_size)) { fatal ("%s: %s: Source/Destination BUS cannot have buffer. \n %s " ,name, section, net_err_config); } net_add_bus_port(net, src_node, dst_node, src_buffer_size, dst_buffer_size); } else if (!strcasecmp(link_type, "Bidirectional")) { net_add_bidirectional_bus_port(net, src_node, dst_node, src_buffer_size, dst_buffer_size); } } } /* initializing the routing table */ net_routing_table_initiate(net->routing_table); /* Routes */ for (section = config_section_first(config); section; section = config_section_next(config)) { char *delim = "."; char *token; char *token_endl; /* First token must be 'Network' */ snprintf(section_str, sizeof section_str, "%s", section); token = strtok(section_str, delim); if (!token || strcasecmp(token, "Network")) continue; /* Second token must be the name of the network */ token = strtok(NULL, delim); if (!token || strcasecmp(token, name)) continue; /* Third token must be 'Routes' */ token = strtok(NULL, delim); if (!token || strcasecmp(token, "Routes")) continue; token_endl = strtok(NULL, delim); if (token_endl) fatal("%s: %s: bad format for route.\n%s", name, section, net_err_config); /* Routes */ routing_type = 1; net_config_route_create(net, config, section); config_check(config); } /* Commands */ for (section = config_section_first(config); section; section = config_section_next(config)) { char *delim = "."; char *token; char *token_endl; /* First token must be 'Network' */ snprintf(section_str, sizeof section_str, "%s", section); token = strtok(section_str, delim); if (!token || strcasecmp(token, "Network")) continue; /* Second token must be the name of the network */ token = strtok(NULL, delim); if (!token || strcasecmp(token, name)) continue; /* Third token must be 'Commands' */ token = strtok(NULL, delim); if (!token || strcasecmp(token, "Commands")) continue; token_endl = strtok(NULL, delim); if (token_endl) fatal("%s: %s: bad format for Commands section.\n%s", name, section, net_err_config); /* Commands */ net_config_command_create(net, config, section); config_check(config); } /* If there is no route section, Floyd-Warshall calculates the * shortest path for all the nodes in the network */ if (routing_type == 0) net_routing_table_floyd_warshall(net->routing_table); /* Return */ return net; }
void x86_mem_config_parse_entry(struct config_t *config, char *section) { char *file_name; int core; int thread; int unified_present; int data_inst_present; char *data_module_name; char *inst_module_name; /* Get configuration file name */ file_name = config_get_file_name(config); /* Allow these sections in case we quit before reading them. */ config_var_allow(config, section, "DataModule"); config_var_allow(config, section, "InstModule"); config_var_allow(config, section, "Module"); /* Check right presence of sections */ unified_present = config_var_exists(config, section, "Module"); data_inst_present = config_var_exists(config, section, "DataModule") && config_var_exists(config, section, "InstModule"); if (!(unified_present ^ data_inst_present)) fatal("%s: section [%s]: invalid combination of modules.\n" "\tAn x86 entry to the memory hierarchy needs to specify either a unified\n" "\tentry for data and instructions (variable 'Module'), or two separate\n" "\tentries for data and instructions (variables 'DataModule' and 'InstModule'),\n" "\tbut not both.\n", file_name, section); /* Read core */ core = config_read_int(config, section, "Core", -1); if (core < 0) fatal("%s: section [%s]: invalid or missing value for 'Core'", file_name, section); /* Read thread */ thread = config_read_int(config, section, "Thread", -1); if (thread < 0) fatal("%s: section [%s]: invalid or missing value for 'Thread'", file_name, section); /* Check bounds */ if (core >= x86_cpu_num_cores || thread >= x86_cpu_num_threads) { warning("%s: section [%s] ignored, referring to x86 Core %d, Thread %d.\n" "\tThis section refers to a core or thread that does not currently exists.\n" "\tPlease review your x86 configuration file if this behavior is not desired.\n", file_name, section, core, thread); return; } /* Check that entry has not been assigned before */ if (X86_THREAD.data_mod || X86_THREAD.inst_mod) { assert(X86_THREAD.data_mod && X86_THREAD.inst_mod); fatal("%s: section [%s]: entry from Core %d, Thread %d already assigned.\n" "\tA different [Entry <name>] section in the memory configuration file has already\n" "\tassigned an entry for this particular core and thread. Please review your\n" "\tconfiguration file to avoid duplicates.\n", file_name, section, core, thread); } /* Read modules */ if (data_inst_present) { data_module_name = config_read_string(config, section, "DataModule", NULL); inst_module_name = config_read_string(config, section, "InstModule", NULL); assert(data_module_name); assert(inst_module_name); } else { data_module_name = inst_module_name = config_read_string(config, section, "Module", NULL); assert(data_module_name); } /* Assign data module */ X86_THREAD.data_mod = mem_system_get_mod(data_module_name); if (!X86_THREAD.data_mod) fatal("%s: section [%s]: '%s' is not a valid module name.\n" "\tThe given module name must match a module declared in a section\n" "\t[Module <name>] in the memory configuration file.\n", file_name, section, data_module_name); /* Assign instruction module */ X86_THREAD.inst_mod = mem_system_get_mod(inst_module_name); if (!X86_THREAD.inst_mod) fatal("%s: section [%s]: '%s' is not a valid module name.\n" "\tThe given module name must match a module declared in a section\n" "\t[Module <name>] in the memory configuration file.\n", file_name, section, inst_module_name); /* Add modules to entry list */ linked_list_add(x86_emu_arch->mem_entry_mod_list, X86_THREAD.data_mod); if (X86_THREAD.data_mod != X86_THREAD.inst_mod) linked_list_add(x86_emu_arch->mem_entry_mod_list, X86_THREAD.inst_mod); /* Debug */ mem_debug("\tx86 Core %d, Thread %d\n", core, thread); mem_debug("\t\tEntry for instructions -> %s\n", X86_THREAD.inst_mod->name); mem_debug("\t\tEntry for data -> %s\n", X86_THREAD.data_mod->name); mem_debug("\n"); }
void evg_mem_config_parse_entry(struct config_t *config, char *section) { char *file_name; char *module_name; int compute_unit_id; struct evg_compute_unit_t *compute_unit; /* Get configuration file name */ file_name = config_get_file_name(config); /* Allow these sections in case we quit before reading them. */ config_var_allow(config, section, "Module"); /* Read compute unit */ compute_unit_id = config_read_int(config, section, "ComputeUnit", -1); if (compute_unit_id < 0) fatal("%s: section [%s]: invalid or missing value for 'ComputeUnit'", file_name, section); /* Check compute unit boundaries */ if (compute_unit_id >= evg_gpu_num_compute_units) { warning("%s: section [%s] ignored, referring to Evergreen compute unit %d.\n" "\tThis section refers to a compute unit that does not currently exist.\n" "\tPlease review your Evergreen configuration file if this is not the\n" "\tdesired behavior.\n", file_name, section, compute_unit_id); return; } /* Check that entry has not been assigned before */ compute_unit = evg_gpu->compute_units[compute_unit_id]; if (compute_unit->global_memory) fatal("%s: section [%s]: entry from compute unit %d already assigned.\n" "\tA different [Entry <name>] section in the memory configuration file has already\n" "\tassigned an entry for this particular compute unit. Please review your\n" "\tconfiguration file to avoid duplicates.\n", file_name, section, compute_unit_id); /* Read module */ module_name = config_read_string(config, section, "Module", NULL); if (!module_name) fatal("%s: section [%s]: variable 'Module' missing.\n" "\tPlease run use '--mem-help' for more information on the\n" "\tconfiguration file format, or consult the Multi2Sim Guide.\n", file_name, section); /* Assign module */ compute_unit->global_memory = mem_system_get_mod(module_name); if (!compute_unit->global_memory) fatal("%s: section [%s]: '%s' is not a valid module name.\n" "\tThe given module name must match a module declared in a section\n" "\t[Module <name>] in the memory configuration file.\n", file_name, section, module_name); /* Add modules to list of memory entries */ linked_list_add(evg_emu_arch->mem_entry_mod_list, compute_unit->global_memory); /* Debug */ mem_debug("\tEvergreen compute unit %d\n", compute_unit_id); mem_debug("\t\tEntry -> %s\n", compute_unit->global_memory->name); mem_debug("\n"); }
/* Check CPU configuration file */ static void x86_cpu_config_check(void) { struct config_t *config; char *section; /* Open file */ config = config_create(x86_config_file_name); if (*x86_config_file_name) config_load(config); /* General configuration */ section = "General"; x86_cpu_num_cores = config_read_int(config, section, "Cores", x86_cpu_num_cores); x86_cpu_num_threads = config_read_int(config, section, "Threads", x86_cpu_num_threads); x86_cpu_fast_forward_count = config_read_llint(config, section, "FastForward", 0); x86_cpu_context_switch = config_read_bool(config, section, "ContextSwitch", 1); x86_cpu_context_quantum = config_read_int(config, section, "ContextQuantum", 100000); x86_cpu_thread_quantum = config_read_int(config, section, "ThreadQuantum", 1000); x86_cpu_thread_switch_penalty = config_read_int(config, section, "ThreadSwitchPenalty", 0); x86_cpu_recover_kind = config_read_enum(config, section, "RecoverKind", x86_cpu_recover_kind_writeback, x86_cpu_recover_kind_map, 2); x86_cpu_recover_penalty = config_read_int(config, section, "RecoverPenalty", 0); mmu_page_size = config_read_int(config, section, "PageSize", 4096); x86_emu_process_prefetch_hints = config_read_bool(config, section, "ProcessPrefetchHints", 1); prefetch_history_size = config_read_int(config, section, "PrefetchHistorySize", 10); /* Section '[ Pipeline ]' */ section = "Pipeline"; x86_cpu_fetch_kind = config_read_enum(config, section, "FetchKind", x86_cpu_fetch_kind_timeslice, x86_cpu_fetch_kind_map, 3); x86_cpu_decode_width = config_read_int(config, section, "DecodeWidth", 4); x86_cpu_dispatch_kind = config_read_enum(config, section, "DispatchKind", x86_cpu_dispatch_kind_timeslice, x86_cpu_dispatch_kind_map, 2); x86_cpu_dispatch_width = config_read_int(config, section, "DispatchWidth", 4); x86_cpu_issue_kind = config_read_enum(config, section, "IssueKind", x86_cpu_issue_kind_timeslice, x86_cpu_issue_kind_map, 2); x86_cpu_issue_width = config_read_int(config, section, "IssueWidth", 4); x86_cpu_commit_kind = config_read_enum(config, section, "CommitKind", x86_cpu_commit_kind_shared, x86_cpu_commit_kind_map, 2); x86_cpu_commit_width = config_read_int(config, section, "CommitWidth", 4); x86_cpu_occupancy_stats = config_read_bool(config, section, "OccupancyStats", 0); /* Section '[ Queues ]' */ section = "Queues"; x86_fetch_queue_size = config_read_int(config, section, "FetchQueueSize", 64); x86_uop_queue_size = config_read_int(config, section, "UopQueueSize", 32); x86_rob_kind = config_read_enum(config, section, "RobKind", x86_rob_kind_private, x86_rob_kind_map, 2); x86_rob_size = config_read_int(config, section, "RobSize", 64); x86_iq_kind = config_read_enum(config, section, "IqKind", x86_iq_kind_private, x86_iq_kind_map, 2); x86_iq_size = config_read_int(config, section, "IqSize", 40); x86_lsq_kind = config_read_enum(config, section, "LsqKind", x86_lsq_kind_private, x86_lsq_kind_map, 2); x86_lsq_size = config_read_int(config, section, "LsqSize", 20); x86_reg_file_kind = config_read_enum(config, section, "RfKind", x86_reg_file_kind_private, x86_reg_file_kind_map, 2); x86_reg_file_int_size = config_read_int(config, section, "RfIntSize", 80); x86_reg_file_fp_size = config_read_int(config, section, "RfFpSize", 40); x86_reg_file_xmm_size = config_read_int(config, section, "RfXmmSize", 40); /* Functional Units */ section = "FunctionalUnits"; x86_fu_res_pool[x86_fu_intadd].count = config_read_int(config, section, "IntAdd.Count", 4); x86_fu_res_pool[x86_fu_intadd].oplat = config_read_int(config, section, "IntAdd.OpLat", 2); x86_fu_res_pool[x86_fu_intadd].issuelat = config_read_int(config, section, "IntAdd.IssueLat", 1); x86_fu_res_pool[x86_fu_intmult].count = config_read_int(config, section, "IntMult.Count", 1); x86_fu_res_pool[x86_fu_intmult].oplat = config_read_int(config, section, "IntMult.OpLat", 3); x86_fu_res_pool[x86_fu_intmult].issuelat = config_read_int(config, section, "IntMult.IssueLat", 3); x86_fu_res_pool[x86_fu_intdiv].count = config_read_int(config, section, "IntDiv.Count", 1); x86_fu_res_pool[x86_fu_intdiv].oplat = config_read_int(config, section, "IntDiv.OpLat", 20); x86_fu_res_pool[x86_fu_intdiv].issuelat = config_read_int(config, section, "IntDiv.IssueLat", 20); x86_fu_res_pool[x86_fu_effaddr].count = config_read_int(config, section, "EffAddr.Count", 4); x86_fu_res_pool[x86_fu_effaddr].oplat = config_read_int(config, section, "EffAddr.OpLat", 2); x86_fu_res_pool[x86_fu_effaddr].issuelat = config_read_int(config, section, "EffAddr.IssueLat", 1); x86_fu_res_pool[x86_fu_logic].count = config_read_int(config, section, "Logic.Count", 4); x86_fu_res_pool[x86_fu_logic].oplat = config_read_int(config, section, "Logic.OpLat", 1); x86_fu_res_pool[x86_fu_logic].issuelat = config_read_int(config, section, "Logic.IssueLat", 1); x86_fu_res_pool[x86_fu_fpsimple].count = config_read_int(config, section, "FpSimple.Count", 2); x86_fu_res_pool[x86_fu_fpsimple].oplat = config_read_int(config, section, "FpSimple.OpLat", 2); x86_fu_res_pool[x86_fu_fpsimple].issuelat = config_read_int(config, section, "FpSimple.IssueLat", 2); x86_fu_res_pool[x86_fu_fpadd].count = config_read_int(config, section, "FpAdd.Count", 2); x86_fu_res_pool[x86_fu_fpadd].oplat = config_read_int(config, section, "FpAdd.OpLat", 5); x86_fu_res_pool[x86_fu_fpadd].issuelat = config_read_int(config, section, "FpAdd.IssueLat", 5); x86_fu_res_pool[x86_fu_fpmult].count = config_read_int(config, section, "FpMult.Count", 1); x86_fu_res_pool[x86_fu_fpmult].oplat = config_read_int(config, section, "FpMult.OpLat", 10); x86_fu_res_pool[x86_fu_fpmult].issuelat = config_read_int(config, section, "FpMult.IssueLat", 10); x86_fu_res_pool[x86_fu_fpdiv].count = config_read_int(config, section, "FpDiv.Count", 1); x86_fu_res_pool[x86_fu_fpdiv].oplat = config_read_int(config, section, "FpDiv.OpLat", 20); x86_fu_res_pool[x86_fu_fpdiv].issuelat = config_read_int(config, section, "FpDiv.IssueLat", 20); x86_fu_res_pool[x86_fu_fpcomplex].count = config_read_int(config, section, "FpComplex.Count", 1); x86_fu_res_pool[x86_fu_fpcomplex].oplat = config_read_int(config, section, "FpComplex.OpLat", 40); x86_fu_res_pool[x86_fu_fpcomplex].issuelat = config_read_int(config, section, "FpComplex.IssueLat", 40); x86_fu_res_pool[x86_fu_xmm_int].count = config_read_int(config, section, "XMMInt.Count", 1); x86_fu_res_pool[x86_fu_xmm_int].oplat = config_read_int(config, section, "XMMInt.OpLat", 2); x86_fu_res_pool[x86_fu_xmm_int].issuelat = config_read_int(config, section, "XMMInt.IssueLat", 2); x86_fu_res_pool[x86_fu_xmm_float].count = config_read_int(config, section, "XMMFloat.Count", 1); x86_fu_res_pool[x86_fu_xmm_float].oplat = config_read_int(config, section, "XMMFloat.OpLat", 10); x86_fu_res_pool[x86_fu_xmm_float].issuelat = config_read_int(config, section, "XMMFloat.IssueLat", 10); x86_fu_res_pool[x86_fu_xmm_logic].count = config_read_int(config, section, "XMMLogic.Count", 1); x86_fu_res_pool[x86_fu_xmm_logic].oplat = config_read_int(config, section, "XMMLogic.OpLat", 1); x86_fu_res_pool[x86_fu_xmm_logic].issuelat = config_read_int(config, section, "XMMLogic.IssueLat", 1); /* Branch Predictor */ section = "BranchPredictor"; x86_bpred_kind = config_read_enum(config, section, "Kind", x86_bpred_kind_twolevel, x86_bpred_kind_map, 6); x86_bpred_btb_sets = config_read_int(config, section, "BTB.Sets", 256); x86_bpred_btb_assoc = config_read_int(config, section, "BTB.Assoc", 4); x86_bpred_bimod_size = config_read_int(config, section, "Bimod.Size", 1024); x86_bpred_choice_size = config_read_int(config, section, "Choice.Size", 1024); x86_bpred_ras_size = config_read_int(config, section, "RAS.Size", 32); x86_bpred_twolevel_l1size = config_read_int(config, section, "TwoLevel.L1Size", 1); x86_bpred_twolevel_l2size = config_read_int(config, section, "TwoLevel.L2Size", 1024); x86_bpred_twolevel_hist_size = config_read_int(config, section, "TwoLevel.HistorySize", 8); /* Trace Cache */ x86_trace_cache_config_check(config); /* Close file */ config_check(config); config_free(config); }