// ======================================================================================================== // ======================================================================================================== // ******************************************** token_common.h ******************************************** // ======================================================================================================== // ======================================================================================================== #include "common.h" #include "token_common.h" // ======================================================================================================== // ======================================================================================================== // Get the vectors and masks to be applied to the functional unit. Verifier will send number of rising // vectors (inspects vectors as it reads them) and indicate whether masks will also be sent. int ReceiveVectors(int str_length, int verifier_socket_desc, int max_vecs, unsigned char *first_vecs_b[max_vecs], unsigned char *second_vecs_b[max_vecs], int vec_len_bits, int *num_rise_vecs_ptr, int *has_masks_ptr, int mask_len_bits, unsigned char *masks[max_vecs]) { int num_vecs, vec_pair_num, vec_num; char num_vecs_str[str_length]; unsigned char *vec_ptr; // Get the number of vectors that verifier intends to send. if ( SockGetB((unsigned char *)num_vecs_str, str_length, verifier_socket_desc) < 0 ) { printf("ERROR: ReceiveVectors(): Failed to receive 'num_vecs_str'!\n"); fflush(stdout); exit(EXIT_FAILURE); } // DEBUG //printf("ReceiveVectors(): 'num_vecs_str' received from verifier '%s'\n", num_vecs_str); fflush(stdout); if ( sscanf(num_vecs_str, "%d %d %d", &num_vecs, num_rise_vecs_ptr, has_masks_ptr) != 3 ) { printf("ERROR: ReceiveVectors(): Expected 'num_vecs', 'num_rise_vecs' and 'has_masks' in '%s'\n", num_vecs_str); fflush(stdout); exit(EXIT_FAILURE); } // Receive the first_vecs and second_vecs sent by the verifier. vec_num = 0; vec_pair_num = 0; while ( vec_num != num_vecs ) { // Allocate space to store the binary vectors if ( vec_pair_num == 0 ) { first_vecs_b[vec_num] = (unsigned char *)malloc(sizeof(char)*vec_len_bits/8); vec_ptr = first_vecs_b[vec_num]; } else if ( vec_pair_num == 1 ) { second_vecs_b[vec_num] = (unsigned char *)malloc(sizeof(char)*vec_len_bits/8); vec_ptr = second_vecs_b[vec_num]; } else masks[vec_num] = (unsigned char *)malloc(sizeof(char)*mask_len_bits/8); // Get the binary vector data if ( vec_pair_num <= 1 ) { if ( SockGetB(vec_ptr, vec_len_bits/8, verifier_socket_desc) != vec_len_bits/8 ) { printf("ERROR: ReceiveVectors(): number of vector bytes received is not equal to %d\n", vec_len_bits/8); fflush(stdout); exit(EXIT_FAILURE); } } else if ( SockGetB(masks[vec_num], mask_len_bits/8, verifier_socket_desc) != mask_len_bits/8 ) { printf("ERROR: ReceiveVectors(): number of mask bytes received is not equal to %d\n", mask_len_bits/8); fflush(stdout); exit(EXIT_FAILURE); } // DEBUG //printf("Vector %d\n\t", vec_num); //int i; //for ( i = 0; i < vec_len_bits/8; i++ ) // printf("%02X ", vec_ptr[i]); //printf("\n"); // Increment to next vector after both vectors (first and second), and potentially the mask, have been received. if ( (*has_masks_ptr == 0 && vec_pair_num == 1) || (*has_masks_ptr == 1 && vec_pair_num == 2) ) { vec_num++; vec_pair_num = 0; } else vec_pair_num++; } // DEBUG //printf("ReceiveVectors(): %d vector pairs received from verifier!\n", vec_num); fflush(stdout); return num_vecs; } // ======================================================================================================== // ======================================================================================================== // Transfer a vector pair plus optionally a mask through the GPIO to the VHDL side. void LoadVecPairMask(int str_length, volatile unsigned int *CtrlRegA, volatile unsigned int *DataRegA, int max_vecs, int vec_num, unsigned char *first_vecs_b[max_vecs], unsigned char *second_vecs_b[max_vecs], int ctrl_mask, int vec_len_bits, int vec_chunk_size, int has_masks, int mask_len_bits, unsigned char *masks[max_vecs]) { int word_num, iter_num, load_iterations, bit_len; unsigned char *vec_ptr; int vec_val_chunk; // Sanity check if ( (vec_len_bits % vec_chunk_size) != 0 ) { printf("ERROR: LoadVecPairMask(): Vector size %d must be evenly divisible by %d!\n", vec_len_bits, vec_chunk_size); fflush(stdout); exit(EXIT_FAILURE); } // Reset the VHDL pointers to the vector buffers. *CtrlRegA = ctrl_mask | (1 << OUT_CP_DTO_RESTART); *CtrlRegA = ctrl_mask; //printf("LoadVecPairMask(): Reset VHDL vector pointers!\n"); fflush(stdout); if ( has_masks == 0 ) load_iterations = 2; else load_iterations = 3; // Send a 416-bit binary vector, 16-bits at a time, starting with the low order to high order bits. // Vector format is RndI, RndC, RndI_n, RndC_n from high to low. for ( iter_num = 0; iter_num < load_iterations; iter_num++ ) { // Set size of data transfer. if ( iter_num < 2 ) bit_len = vec_len_bits; else bit_len = mask_len_bits; //printf("LoadVecPairMask(): Current control mask '%08X'\n", ctrl_mask); fflush(stdout); // Iterate over each 26 16-bit chunks of string data for vectors and 25 for mask. Verifier has ordered the data from low order // to high order, i.e., the exact format that we need to load it up by in the VHDL. for ( word_num = 0; word_num < bit_len/vec_chunk_size; word_num++ ) { // Add 2 bytes at a time to the pointer. In binary, there are only 52 bytes for the vectors (in ASCII, there were 416 bytes) // and 50 for the mask. if ( iter_num == 0 ) vec_ptr = first_vecs_b[vec_num] + word_num*2; else if ( iter_num == 1 ) vec_ptr = second_vecs_b[vec_num] + word_num*2; else vec_ptr = masks[vec_num] + word_num*2; //printf("LoadVecPairMask(): vec_ptr pointer '%s'!\n", vec_ptr); fflush(stdout); vec_val_chunk = (vec_ptr[1] << 8) + vec_ptr[0]; //printf("LoadVecPairMask(): 16-bit binary value in hex '%04X'\n", vec_val_chunk); fflush(stdout); // Four step protocol // 1) Assert 'data_ready' while putting the 16-bit binary value on the low order bits of CtrlReg //printf("LoadVecPairMask(): Writing 'data_ready' with 16-bit binary value in hex '%04X'\n", vec_val_chunk); fflush(stdout); *CtrlRegA = ctrl_mask | (1 << OUT_CP_DTO_DATA_READY) | vec_val_chunk; // 2) Wait for 'done_reading to go to 1 (it is low by default). State machine latches data in 2 clk cycles. // Maintain 1 on 'data_ready' and continue to hold 16-bit binary chunk. //printf("LoadVecPairMask(): Waiting state machine 'done_reading' to be set to '1'\n"); fflush(stdout); while ( (*DataRegA & (1 << IN_SM_DTO_DONE_READING)) == 0 ); // 3) Once 'done_reading' goes to 1, set 'data_ready' to 0 and remove chunk; //printf("LoadVecPairMask(): De-asserting 'data_ready'\n"); fflush(stdout); *CtrlRegA = ctrl_mask; // 4) Wait for 'done_reading to go to 0. //printf("LoadVecPairMask(): Waiting state machine 'done_reading' to be set to '0'\n"); fflush(stdout); while ( (*DataRegA & (1 << IN_SM_DTO_DONE_READING)) != 0 ); //printf("LoadVecPairMask(): Done handshake associated with vector chunk transfer\n"); fflush(stdout); } } // 6/1/2016: Tell CollectPNs (if it is waiting) that vector and possibly a mask have been loaded. *CtrlRegA = ctrl_mask | (1 << OUT_CP_DTO_VEC_LOADED); *CtrlRegA = ctrl_mask; return; }