void motors_init(void) { int i; uint8_t pin_mask; uint32_t motor_per; // Set Pins to output/PWM in GPIO SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1); GPIOPinConfigure(GPIO_PF2_M1PWM6); GPIOPinConfigure(GPIO_PF3_M1PWM7); GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3); // Configure the pin for standby control GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6); SysCtlPWMClockSet(SYSCTL_PWMDIV_64); // Configure the PWM for each pin: // Turn on the generators and set the PW to 0 // The output is still OFF. Turn on with set_motor_pwm_state for (i = 0; i < NUM_MOTORS; i++) { PWMGenConfigure(motors[i].pwm_base_module, motors[i].pwm_generator, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC); motor_per = calc_cycles(MOTOR_PERIOD); PWMGenPeriodSet(motors[i].pwm_base_module, motors[i].pwm_generator, motor_per); PWMPulseWidthSet(motors[i].pwm_base_module, motors[i].pwm_pin, 0); PWMGenEnable(motors[i].pwm_base_module, motors[i].pwm_generator); pin_mask = 1 << (0x0000000F & motors[i].pwm_pin); PWMOutputState(motors[i].pwm_base_module, pin_mask, 0); } }
void set_pulse_width(motor_index_t index, uint32_t *uSec) { uint32_t cycles = calc_cycles(*uSec); uint8_t pin_mask; // set uSec as closest value as possible with Timer settings *uSec = calc_usec(cycles); pin_mask = 1 << (0x0000000F & motors[index].pwm_pin); if(cycles <= 0){ PWMOutputState(motors[index].pwm_base_module, pin_mask, 0); } else{ PWMOutputState(motors[index].pwm_base_module, pin_mask, 1); PWMPulseWidthSet(motors[index].pwm_base_module, motors[index].pwm_pin, cycles); } }
char *parse_note_string(char *ptr, struct defaults *def, struct note *note){ char len_string[3]; char pitch_string[3]; char octave_string[2]; char dot[2]; // eat whitespace / commas and advance the pointer char* dummy = malloc(strlen(ptr)+1); if (dummy == NULL){ error("malloc failed");} dummy[0] = '\0'; sscanf(ptr,"%[ ,]",dummy); ptr += strlen(dummy); free(dummy); DEBUG&&printf("Begin Parsing Note String...\n"); ptr = get_len(ptr, len_string, def->len); DEBUG&&printf("get_len Successful...\n"); ptr = get_pitch(ptr, pitch_string); DEBUG&&printf("get_pitch Successful...\n"); ptr = get_octave(ptr, octave_string, def->oct); DEBUG&&printf("get_octave Successful...\n"); ptr = get_dot(ptr, dot); DEBUG&&printf("get_dot Successful...\n"); strcpy(note->pitch, pitch_string); sscanf(len_string, "%d", &(note->length)); sscanf(octave_string, "%d", &(note->octave)); note->divisor = calc_divisor(pitch_string, octave_string); DEBUG&&printf("divisor successful\n"); note->cycles = calc_cycles(def, len_string, dot); DEBUG&&printf("cycles successful\n"); return ptr; }
/* * Version - 6.0 * * Perform exhaustive search across different bank organizatons, * router configurations, grid organizations, and wire models and * find an optimal NUCA organization * For different bank count values * 1. Optimal bank organization is calculated * 2. For each bank organization, find different NUCA organizations * using various router configurations, grid organizations, * and wire models. * 3. NUCA model with the least cost is picked for * this particular bank count * Finally include contention statistics and find the optimal * NUCA configuration */ void Nuca::sim_nuca() { /* temp variables */ int it, ro, wr; int num_cyc; unsigned int i, j; unsigned int r, c; int l2_c; int bank_count = 0; uca_org_t ures; nuca_org_t *opt_n; mem_array tag, data; list<nuca_org_t *> nuca_list; Router *router_s[ROUTER_TYPES]; router_s[0] = new Router(64.0, 8, 4, &(g_tp.peri_global)); router_s[0]->print_router(); router_s[1] = new Router(128.0, 8, 4, &(g_tp.peri_global)); router_s[1]->print_router(); router_s[2] = new Router(256.0, 8, 4, &(g_tp.peri_global)); router_s[2]->print_router(); int core_in; // to store no. of cores /* to search diff grid organizations */ double curr_hop, totno_hops, totno_hhops, totno_vhops, tot_lat, curr_acclat; double avg_lat, avg_hop, avg_hhop, avg_vhop, avg_dyn_power, avg_leakage_power; double opt_acclat = INF; //double opt_avg_lat = INF; //double opt_tot_lat = INF; int opt_rows = 0; int opt_columns = 0; //double opt_totno_hops = 0; double opt_avg_hop = 0; double opt_dyn_power = 0, opt_leakage_power = 0; min_values_t minval; int bank_start = 0; int flit_width = 0; /* vertical and horizontal hop latency values */ int ver_hop_lat, hor_hop_lat; /* in cycles */ /* no. of different bank sizes to consider */ int iterations; g_ip->nuca_cache_sz = g_ip->cache_sz; nuca_list.push_back(new nuca_org_t()); if (g_ip->cache_level == 0) l2_c = 1; else l2_c = 0; if (g_ip->cores <= 4) core_in = 2; else if (g_ip->cores <= 8) core_in = 3; else if (g_ip->cores <= 16) core_in = 4; else {cout << "Number of cores should be <= 16!\n"; exit(0);} // set the lower bound to an appropriate value. this depends on cache associativity if (g_ip->assoc > 2) { i = 2; while (i != g_ip->assoc) { MIN_BANKSIZE *= 2; i *= 2; } } iterations = (int)logtwo((int)g_ip->cache_sz/MIN_BANKSIZE); if (g_ip->force_wiretype) { if (g_ip->wt == Low_swing) { wt_min = Low_swing; wt_max = Low_swing; } else { wt_min = Global; wt_max = Low_swing-1; } } else { wt_min = Global; wt_max = Low_swing; } if (g_ip->nuca_bank_count != 0) { // simulate just one bank if (g_ip->nuca_bank_count != 2 && g_ip->nuca_bank_count != 4 && g_ip->nuca_bank_count != 8 && g_ip->nuca_bank_count != 16 && g_ip->nuca_bank_count != 32 && g_ip->nuca_bank_count != 64) { fprintf(stderr,"Incorrect bank count value! Please fix the value in cache.cfg\n"); } bank_start = (int)logtwo((double)g_ip->nuca_bank_count); iterations = bank_start+1; g_ip->cache_sz = g_ip->cache_sz/g_ip->nuca_bank_count; } cout << "Simulating various NUCA configurations\n"; for (it=bank_start; it<iterations; it++) { /* different bank count values */ ures.tag_array2 = &tag; ures.data_array2 = &data; /* * find the optimal bank organization */ solve(&ures); // output_UCA(&ures); bank_count = g_ip->nuca_cache_sz/g_ip->cache_sz; cout << "====" << g_ip->cache_sz << "\n"; for (wr=wt_min; wr<=wt_max; wr++) { for (ro=0; ro<ROUTER_TYPES; ro++) { flit_width = (int) router_s[ro]->flit_size; //initialize router nuca_list.back()->nuca_pda.cycle_time = router_s[ro]->cycle_time; /* calculate router and wire parameters */ double vlength = ures.cache_ht; /* length of the wire (u)*/ double hlength = ures.cache_len; // u /* find delay, area, and power for wires */ wire_vertical[wr] = new Wire((enum Wire_type) wr, vlength); wire_horizontal[wr] = new Wire((enum Wire_type) wr, hlength); hor_hop_lat = calc_cycles(wire_horizontal[wr]->delay, 1/(nuca_list.back()->nuca_pda.cycle_time*.001)); ver_hop_lat = calc_cycles(wire_vertical[wr]->delay, 1/(nuca_list.back()->nuca_pda.cycle_time*.001)); /* * assume a grid like topology and explore for optimal network * configuration using different row and column count values. */ for (c=1; c<=(unsigned int)bank_count; c++) { while (bank_count%c != 0) c++; r = bank_count/c; /* * to find the avg access latency of a NUCA cache, uncontended * access time to each bank from the * cache controller is calculated. * avg latency = * sum of the access latencies to individual banks)/bank * count value. */ totno_hops = totno_hhops = totno_vhops = tot_lat = 0; // k = 1; for (i=0; i<r; i++) { for (j=0; j<c; j++) { /* * vertical hops including the * first hop from the cache controller */ curr_hop = i + 1; curr_hop += j; /* horizontal hops */ totno_hhops += j; totno_vhops += (i+1); curr_acclat = (i * ver_hop_lat + CONTR_2_BANK_LAT + j * hor_hop_lat); tot_lat += curr_acclat; totno_hops += curr_hop; } } avg_lat = tot_lat/bank_count; avg_hop = totno_hops/bank_count; avg_hhop = totno_hhops/bank_count; avg_vhop = totno_vhops/bank_count; /* net access latency */ curr_acclat = 2*avg_lat + 2*(router_s[ro]->delay*avg_hop) + calc_cycles(ures.access_time, 1/(nuca_list.back()->nuca_pda.cycle_time*.001)); /* avg access lat of nuca */ avg_dyn_power = avg_hop * (router_s[ro]->power.readOp.dynamic) + avg_hhop * (wire_horizontal[wr]->power.readOp.dynamic) * (g_ip->block_sz*8 + 64) + avg_vhop * (wire_vertical[wr]->power.readOp.dynamic) * (g_ip->block_sz*8 + 64) + ures.power.readOp.dynamic; avg_leakage_power = bank_count * router_s[ro]->power.readOp.leakage + avg_hhop * (wire_horizontal[wr]->power.readOp.leakage* wire_horizontal[wr]->delay) * flit_width + avg_vhop * (wire_vertical[wr]->power.readOp.leakage * wire_horizontal[wr]->delay); if (curr_acclat < opt_acclat) { opt_acclat = curr_acclat; //opt_tot_lat = tot_lat; //opt_avg_lat = avg_lat; //opt_totno_hops = totno_hops; opt_avg_hop = avg_hop; opt_rows = r; opt_columns = c; opt_dyn_power = avg_dyn_power; opt_leakage_power = avg_leakage_power; } totno_hops = 0; tot_lat = 0; totno_hhops = 0; totno_vhops = 0; } nuca_list.back()->wire_pda.power.readOp.dynamic = opt_avg_hop * flit_width * (wire_horizontal[wr]->power.readOp.dynamic + wire_vertical[wr]->power.readOp.dynamic); nuca_list.back()->avg_hops = opt_avg_hop; /* network delay/power */ nuca_list.back()->h_wire = wire_horizontal[wr]; nuca_list.back()->v_wire = wire_vertical[wr]; nuca_list.back()->router = router_s[ro]; /* bank delay/power */ nuca_list.back()->bank_pda.delay = ures.access_time; nuca_list.back()->bank_pda.power = ures.power; nuca_list.back()->bank_pda.area.h = ures.cache_ht; nuca_list.back()->bank_pda.area.w = ures.cache_len; nuca_list.back()->bank_pda.cycle_time = ures.cycle_time; num_cyc = calc_cycles(nuca_list.back()->bank_pda.delay /*s*/, 1/(nuca_list.back()->nuca_pda.cycle_time*.001/*GHz*/)); if(num_cyc%2 != 0) num_cyc++; if (num_cyc > 16) num_cyc = 16; // we have data only up to 16 cycles if (it < 7) { nuca_list.back()->nuca_pda.delay = opt_acclat + cont_stats[l2_c][core_in][ro][it][num_cyc/2-1]; nuca_list.back()->contention = cont_stats[l2_c][core_in][ro][it][num_cyc/2-1]; } else { nuca_list.back()->nuca_pda.delay = opt_acclat + cont_stats[l2_c][core_in][ro][6][num_cyc/2-1]; nuca_list.back()->contention = cont_stats[l2_c][core_in][ro][6][num_cyc/2-1]; } nuca_list.back()->nuca_pda.power.readOp.dynamic = opt_dyn_power; nuca_list.back()->nuca_pda.power.readOp.leakage = opt_leakage_power; /* array organization */ nuca_list.back()->bank_count = bank_count; nuca_list.back()->rows = opt_rows; nuca_list.back()->columns = opt_columns; calculate_nuca_area (nuca_list.back()); minval.update_min_values(nuca_list.back()); nuca_list.push_back(new nuca_org_t()); opt_acclat = BIGNUM; } } g_ip->cache_sz /= 2; } delete(nuca_list.back()); nuca_list.pop_back(); opt_n = find_optimal_nuca(&nuca_list, &minval); print_nuca(opt_n); g_ip->cache_sz = g_ip->nuca_cache_sz/opt_n->bank_count; list<nuca_org_t *>::iterator niter; for (niter = nuca_list.begin(); niter != nuca_list.end(); ++niter) { delete *niter; } nuca_list.clear(); for(int i=0; i < ROUTER_TYPES; i++) { delete router_s[i]; } g_ip->display_ip(); // g_ip->force_cache_config = true; // g_ip->ndwl = 8; // g_ip->ndbl = 16; // g_ip->nspd = 4; // g_ip->ndcm = 1; // g_ip->ndsam1 = 8; // g_ip->ndsam2 = 32; }
void main_cuc (char *filename) { int i, j; char tmp1[256]; char filename_cut[256]; #if 0 /* Select prefix, based on binary program name */ for (i = 0; i < sizeof (filename_cut); i++) { if (isalpha (filename[i])) filename_cut[i] = filename[i]; else { filename_cut[i] = '\0'; break; } } #else strcpy (filename_cut, "cu"); #endif PRINTF ("Entering OpenRISC Custom Unit Compiler command prompt\n"); PRINTF ("Using profile file \"%s\" and memory profile file \"%s\".\n", config.sim.prof_fn, config.sim.mprof_fn); sprintf (tmp1, "%s.log", filename_cut); PRINTF ("Analyzing. (log file \"%s\").\n", tmp1); assert (flog = fopen (tmp1, "wt+")); /* Loads in the specified timings table */ PRINTF ("Using timings from \"%s\" at %s\n", config.cuc.timings_fn, generate_time_pretty (tmp1, config.sim.clkcycle_ps)); load_timing_table (config.cuc.timings_fn); runtime.cuc.cycle_duration = 1000. * config.sim.clkcycle_ps; PRINTF ("Multicycle logic %s, bursts %s, %s memory order.\n", config.cuc.no_multicycle ? "OFF" : "ON", config.cuc.enable_bursts ? "ON" : "OFF", config.cuc.memory_order == MO_NONE ? "no" : config.cuc.memory_order == MO_WEAK ? "weak" : config.cuc.memory_order == MO_STRONG ? "strong" : "exact"); prof_set (1, 0); assert (prof_acquire (config.sim.prof_fn) == 0); if (config.cuc.calling_convention) PRINTF ("Assuming OpenRISC standard calling convention.\n"); /* Try all functions except "total" */ for (i = 0; i < prof_nfuncs - 1; i++) { long orig_time; unsigned long start_addr, end_addr; orig_time = prof_func[i].cum_cycles; start_addr = prof_func[i].addr; /* Extract the function from the binary */ sprintf (tmp1, "%s.bin", prof_func[i].name); end_addr = extract_function (tmp1, start_addr); log ("Testing function %s (%08lx - %08lx)\n", prof_func[i].name, start_addr, end_addr); PRINTF ("Testing function %s (%08lx - %08lx)\n", prof_func[i].name, start_addr, end_addr); func[i] = analyse_function (prof_func[i].name, orig_time, start_addr, end_addr, config.cuc.memory_order, prof_func[i].calls); func_v[i] = 0; } set_func_deps (); while (1) { char *s; wait_command: PRINTF ("(cuc) "); fflush (stdout); wait_command_empty: s = fgets (tmp1, sizeof tmp1, stdin); usleep (100); if (!s) goto wait_command_empty; for (s = tmp1; *s != '\0' && *s != '\n' && *s != '\r'; s++); *s = '\0'; /* quit command */ if (strcmp (tmp1, "q") == 0 || strcmp (tmp1, "quit") == 0) { /* Delete temporary files */ for (i = 0; i < prof_nfuncs - 1; i++) { sprintf (tmp1, "%s.bin", prof_func[i].name); log ("Deleting temporary file %s %s\n", tmp1, remove (tmp1) ? "FAILED" : "OK"); sprintf (tmp1, "%s.bin.bb", prof_func[i].name); log ("Deleting temporary file %s %s\n", tmp1, remove (tmp1) ? "FAILED" : "OK"); } break; /* profile command */ } else if (strcmp (tmp1, "p") == 0 || strcmp (tmp1, "profile") == 0) { int ntime = 0; int size = 0; PRINTF ("-----------------------------------------------------------------------------\n"); PRINTF ("|function name |calls|avg cycles |old%%| max. f. | impr. f.| options |\n"); PRINTF ("|--------------------+-----+------------+----+----------|---------+---------|\n"); for (j = 0; j < prof_nfuncs; j++) { int bestcyc = 0, besti = 0; char tmp[100]; for (i = 0; i < prof_nfuncs; i++) if (prof_func[i].cum_cycles > bestcyc) { bestcyc = prof_func[i].cum_cycles; besti = i; } i = besti; PRINTF ("|%-20s|%5li|%12.1f|%3.0f%%| ", strstrip (tmp, prof_func[i].name, 20), prof_func[i].calls, ((double) prof_func[i].cum_cycles / prof_func[i].calls), (100. * prof_func[i].cum_cycles / prof_cycles)); if (func[i]) { double f = 1.0; if (func_v[i]) { int nt = calc_cycles (func[i]); int s = calc_size (func[i]); f = 1. * func[i]->orig_time / nt; ntime += nt; size += s; } else ntime += prof_func[i].cum_cycles; PRINTF ("%8.1f |%8.1f | %-8s|\n", 1.f * prof_func[i].cum_cycles / func[i]->timings.new_time, f, format_func_options (tmp, func[i])); } else { PRINTF (" N/A | N/A | N/A |\n"); ntime += prof_func[i].cum_cycles; } prof_func[i].cum_cycles = -prof_func[i].cum_cycles; } for (i = 0; i < prof_nfuncs; i++) prof_func[i].cum_cycles = -prof_func[i].cum_cycles; PRINTF ("-----------------------------------------------------------------------------\n"); PRINTF ("Total %i cycles (was %i), total added gates = %i. Speed factor %.1f\n", ntime, prof_cycles, size, 1. * prof_cycles / ntime); /* debug command */ } else if (strncmp (tmp1, "d", 1) == 0 || strncmp (tmp1, "debug", 5) == 0) { sscanf (tmp1, "%*s %i", &cuc_debug); if (cuc_debug < 0) cuc_debug = 0; if (cuc_debug > 9) cuc_debug = 9; /* generate command */ } else if (strcmp (tmp1, "g") == 0 || strcmp (tmp1, "generate") == 0) { /* check for function dependencies */ for (i = 0; i < prof_nfuncs; i++) if (func[i]) func[i]->tmp = func_v[i]; for (i = 0; i < prof_nfuncs; i++) if (func[i]) for (j = 0; j < func[i]->nfdeps; j++) if (!func[i]->fdeps[j] || !func[i]->fdeps[j]->tmp) { PRINTF ("Function %s must be selected for translation (required by %s)\n", prof_func[j].name, prof_func[i].name); goto wait_command; } for (i = 0; i < prof_nfuncs; i++) if (func[i] && func_v[i]) generate_function (func[i], prof_func[i].name, filename_cut); generate_main (prof_nfuncs, func, filename_cut); /* list command */ } else if (strcmp (tmp1, "l") == 0 || strcmp (tmp1, "list") == 0) { /* check for function dependencies */ for (i = 0; i < prof_nfuncs; i++) if (func_v[i]) { PRINTF ("%s\n", prof_func[i].name); } /* selectall command */ } else if (strcmp (tmp1, "sa") == 0 || strcmp (tmp1, "selectall") == 0) { int f; for (f = 0; f < prof_nfuncs; f++) if (func[f]) { func_v[f] = 1; PRINTF ("Function %s selected for translation.\n", prof_func[f].name); } /* select command */ } else if (strncmp (tmp1, "s", 1) == 0 || strncmp (tmp1, "select", 6) == 0) { char tmp[50], ch; int p, o, b, f; p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch); if (p < 1) PRINTF ("Invalid parameters.\n"); else { /* Check if we have valid option */ for (f = 0; f < prof_nfuncs; f++) if (strcmp (prof_func[f].name, tmp) == 0 && func[f]) break; if (f < prof_nfuncs) { if (p == 1) { if (func[f]) { func_v[f] = 1; PRINTF ("Function %s selected for translation.\n", prof_func[f].name); } else PRINTF ("Function %s not suitable for translation.\n", prof_func[f].name); } else { if (!func_v[f]) PRINTF ("Function %s not yet selected for translation.\n", prof_func[f].name); if (p < 3) goto invalid_option; for (o = 0; option_char[o] != '\0' && option_char[o] != ch; o++); if (!option_char[o]) goto invalid_option; if (b < 0 || b >= func[f]->num_bb) goto invalid_option; if (o < 0 || o >= func[f]->bb[b].ntim) goto invalid_option; /* select an option */ func[f]->bb[b].selected_tim = o; if (func[f]->bb[b].tim[o].nshared) { PRINTF ("Option has shared instructions: "); print_shared (func[f], func[f]->bb[b].tim[o].shared, func[f]->bb[b].tim[o].nshared); PRINTF ("\n"); } goto wait_command; invalid_option: PRINTF ("Invalid option.\n"); } } else PRINTF ("Invalid function.\n"); } /* unselect command */ } else if (strncmp (tmp1, "u", 1) == 0 || strncmp (tmp1, "unselect", 8) == 0) { char tmp[50], ch; int p, o, b, f; p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch); if (p < 1) PRINTF ("Invalid parameters.\n"); else { /* Check if we have valid option */ for (f = 0; f < prof_nfuncs; f++) if (strcmp (prof_func[f].name, tmp) == 0 && func[f]) break; if (f < prof_nfuncs) { if (p == 1) { if (func[f]) { func_v[f] = 0; PRINTF ("Function %s unselected for translation.\n", prof_func[f].name); } else PRINTF ("Function %s not suitable for translation.\n", prof_func[f].name); } else { if (p < 3) goto invalid_option; for (o = 0; option_char[o] != '\0' && option_char[o] != ch; o++); if (!option_char[o]) goto invalid_option; if (b < 0 || b >= func[f]->num_bb) goto invalid_option; if (o < 0 || o >= func[f]->bb[b].ntim) goto invalid_option; /* select an option */ func[f]->bb[b].selected_tim = -1; } } else PRINTF ("Invalid function.\n"); } /* options command */ } else if (strcmp (tmp1, "o") == 0 || strcmp (tmp1, "options") == 0) { int any = 0; PRINTF ("Available options:\n"); for (i = 0; i < prof_nfuncs; i++) if (func[i]) { options_cmd (i, func[i]); any = 1; } if (any) PRINTF ("-----------------------------------------------------------------------------\n"); else PRINTF ("Sorry. No available options.\n"); /* Ignore empty string */ } else if (strcmp (tmp1, "") == 0) { /* help command */ } else { if (strcmp (tmp1, "h") != 0 && strcmp (tmp1, "help") != 0) PRINTF ("Unknown command.\n"); PRINTF ("OpenRISC Custom Unit Compiler command prompt\n"); PRINTF ("Available commands:\n"); PRINTF (" h | help displays this help\n"); PRINTF (" q | quit returns to or1ksim prompt\n"); PRINTF (" p | profile displays function profiling\n"); PRINTF (" d | debug # sets debug level (0-9)\n"); PRINTF (" o | options displays available options\n"); PRINTF (" s | select func [option] selects an option/function\n"); PRINTF (" u | unselect func [option] unselects an option/function\n"); PRINTF (" g | generate generates verilog file\n"); PRINTF (" l | list displays selected functions\n"); } } /* Dispose memory */ for (i = 0; i < prof_nfuncs - 1; i++) if (func[i]) free_func (func[i]); fclose (flog); }