// ======================================================================================================== // ======================================================================================================== // ********************************************* LoadUnload.c ********************************************* // ======================================================================================================== // ======================================================================================================== #include "common.h" // ======================================================================================================== // ======================================================================================================== // Read integer data from a file and store it in an array. int ReadData(int max_string_len, int max_data_vals, char *infile_name, short *data_arr_in) { char line[max_string_len], *char_ptr; float temp_float; FILE *INFILE; int val_num; if ( (INFILE = fopen(infile_name, "r")) == NULL ) { printf("ERROR: ReadData(): Could not open %s\n", infile_name); fflush(stdout); exit(EXIT_FAILURE); } val_num = 0; while ( fgets(line, max_string_len, INFILE) != NULL ) { // Find the newline and eliminate it. if ((char_ptr = strrchr(line, '\n')) != NULL) *char_ptr = '\0'; // Skip blank lines if ( strlen(line) == 0 ) continue; // Sanity check if ( val_num >= max_data_vals ) { printf("ERROR: ReadData(): Exceeded maximum number of vals %d!\n", max_data_vals); fflush(stdout); exit(EXIT_FAILURE); } // Read and convert value into an integer if ( sscanf(line, "%f", &temp_float) != 1 ) { printf("ERROR: ReadData(): Failed to read an float value from file '%s'!\n", line); fflush(stdout); exit(EXIT_FAILURE); } // Sanity check if ( (int)(temp_float*16) > MAX_SHORT_POS || (int)(temp_float*16) < MAX_SHORT_NEG ) { printf("ERROR: ReadData(): Scaled float (by 16) larger than max or smaller than min value for short %d!\n", data_arr_in[val_num]); fflush(stdout); exit(EXIT_FAILURE); } data_arr_in[val_num] = (int)(temp_float*16); val_num++; } fclose(INFILE); return val_num; } // ======================================================================================================== // ======================================================================================================== // Load the data from the data arry into the secure BRAM void LoadUnloadBRAM(int max_string_len, int max_vals, int load_unload, int num_vals, short *IOData, volatile unsigned int *CtrlRegA, volatile unsigned int *DataRegA, int ctrl_mask) { int val_num, locked_up; // Set load control flag ctrl_mask = ctrl_mask | (load_unload << OUT_CP_LM_ULM_LOAD_UNLOAD); // Wait for the hardware to be ready while ( ((*DataRegA) & (1 << IN_SM_READY)) == 0 ); // Start the VHDL FSM memory controller *CtrlRegA = ctrl_mask | (1 << OUT_CP_START); *CtrlRegA = ctrl_mask; for ( val_num = 0; val_num < num_vals; val_num++ ) { // Sanity check if ( val_num >= max_vals ) { printf("ERROR: LoadUnloadBRAM(): val_num %d greater than max_vals %d\n", val_num, max_vals); exit(EXIT_FAILURE); } // Four step protocol // 1) Wait for 'stopped' from hardware to be asserted //printf("LoadUnloadBRAM(): Waiting 'stopped'\n"); fflush(stdout); locked_up = 0; while ( ((*DataRegA) & (1 << IN_SM_HANDSHAKE)) == 0 ) { locked_up++; if ( locked_up > 10000000 ) { printf("ERROR: LoadUnloadBRAM(): 'stopped' has not been asserted for the threshold number of cycles -- Locked UP?\n"); fflush(stdout); locked_up = 0; } } // 2) Put data into GPIO (load) or get data from GPIO (unload). Assert 'continue' for hardware // Put the data bytes into the register and assert 'continue' (OUT_CP_HANDSHAKE). //printf("LoadUnloadBRAM(): Reading/writing data and asserting 'continue'\n"); fflush(stdout); if ( load_unload == 0 ) *CtrlRegA = ctrl_mask | (1 << OUT_CP_HANDSHAKE) | (0x0000FFFF & IOData[val_num]); // When 'stopped' is asserted, the data is ready on the output register from the PNL BRAM -- get it. else { IOData[val_num] = (0x0000FFFF & *DataRegA); *CtrlRegA = ctrl_mask | (1 << OUT_CP_HANDSHAKE); } printf("%d\tData value written or read %d\n", val_num, IOData[val_num]); fflush(stdout); // 3) Wait for hardware to de-assert 'stopped' //printf("LoadUnloadBRAM(): Waiting de-assert of 'stopped'\n"); fflush(stdout); while ( ((*DataRegA) & (1 << IN_SM_HANDSHAKE)) != 0 ); // 4) De-assert 'continue'. ALSO, assert 'done' (OUT_CP_LM_ULM_DONE) SIMULTANEOUSLY if last word to inform hardware. //printf("LoadUnloadBRAM(): De-asserting 'continue' and possibly setting 'done'\n"); fflush(stdout); if ( val_num == num_vals - 1 ) *CtrlRegA = ctrl_mask | (1 << OUT_CP_LM_ULM_DONE); else *CtrlRegA = ctrl_mask; } // Handle case where 'num_vals' is 0. if ( num_vals == 0 ) *CtrlRegA = ctrl_mask | (1 << OUT_CP_LM_ULM_DONE); // De-assert 'OUT_CP_LM_ULM_DONE' *CtrlRegA = ctrl_mask; fflush(stdout); return; } // ======================================================================================================== // ======================================================================================================== // ======================================================================================================== int main(int argc, char *argv[]) { volatile unsigned int *CtrlRegA; volatile unsigned int *DataRegA; unsigned int ctrl_mask; char infile_name[MAX_STRING_LEN]; char outfile_name[MAX_STRING_LEN]; // data arrays short *data_arr_in; short *data_arr_out; int num_vals; int load_unload; //Timing variables. #if DEBUG struct timeval t0, t1; long elapsed; #endif // ====================================================================================================================== // COMMAND LINE if ( argc != 2 ) { printf("ERROR: LoadUnload.elf(): Datafile name (test_data_10vals.txt)\n"); return(1); } sscanf(argv[1], "%s", infile_name); // Open up the memory mapped device so we can access the GPIO registers. int fd = open("/dev/mem", O_RDWR|O_SYNC); if (fd < 0) { printf("ERROR: /dev/mem could NOT be opened!\n"); exit(EXIT_FAILURE); } // Add 2 for the DataReg (for an offset of 8 bytes for 32-bit integer variables) DataRegA = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_0_BASE_ADDR); CtrlRegA = DataRegA + 2; // Define array into which file data will be read if ( (data_arr_in = (short *)calloc(sizeof(short), MAX_DATA_VALS)) == NULL ) { printf("ERROR: Failed to calloc data 'in' array!\n"); exit(EXIT_FAILURE); } if ( (data_arr_out = (short *)calloc(sizeof(short), MAX_DATA_VALS)) == NULL ) { printf("ERROR: Failed to calloc data 'out' array!\n"); exit(EXIT_FAILURE); } // Read the data from the input file num_vals = ReadData(MAX_STRING_LEN, MAX_DATA_VALS, infile_name, data_arr_in); // Set the control mask to indicate enrollment. ctrl_mask = 0; // Run time information #ifdef DEBUG gettimeofday(&t0, 0); #endif // Do a soft RESET *CtrlRegA = ctrl_mask | (1 << OUT_CP_RESET); *CtrlRegA = ctrl_mask; usleep(10000); // Load data into secure BRAM load_unload = 0; LoadUnloadBRAM(MAX_STRING_LEN, MAX_DATA_VALS, load_unload, num_vals, data_arr_in, CtrlRegA, DataRegA, ctrl_mask); // Read data back load_unload = 1; LoadUnloadBRAM(MAX_STRING_LEN, MAX_DATA_VALS, load_unload, num_vals, data_arr_out, CtrlRegA, DataRegA, ctrl_mask); return 0; }