2023-12-05 17:20:14 +00:00
import numpy as np
TRNG_PAIR_CNT = 64
if __name__ == ' __main__ ' :
# reading info file - length of trace, sampling frequency (not necessary to know in our case), random value generated by the TRNG
with open ( " data_info.txt " , " r " ) as fin :
tracelen = int ( fin . readline ( ) )
fs = int ( fin . readline ( ) )
trng_val = fin . readline ( )
traces = np . fromfile ( " data.bin " , dtype = ' uint8 ' ) # reading traces for individual ROs
traces = np . reshape ( traces , ( traces . size / / tracelen , tracelen ) ) # reshape of matrix, each row contains the trace for one RO
2023-12-05 18:36:31 +00:00
traces_bin = traces > 128 # conversion of waveforms to rectangles - everything below threshold is 0, otherwise 1 (they are boolean values actually)
rising_edges = np . logical_not ( traces [ : , 0 : - 2 ] & traces [ : , 1 : - 1 ] ) & traces [ : , 2 : ] # finding rising edges, each rising edge is represented by True
2023-12-05 17:20:14 +00:00
2023-12-05 18:36:31 +00:00
cnt = np . count_nonzero ( rising_edges , axis = 1 ) # count the number of rising edges in rows
2023-12-05 17:20:14 +00:00
# cnt is now a 1D vector
cnt = cnt . reshape ( TRNG_PAIR_CNT , 2 ) . min ( axis = 1 ) # Reshape of the count array into matrix, where each row contains 2 values - the number of rising edges for two ROs in a pair. Then we select the smaller value.
2023-12-05 18:36:31 +00:00
#cnt_sel = cnt & ?x???? # select only the two least significant bits
2023-12-05 17:20:14 +00:00
2023-12-05 18:36:31 +00:00
#estimate = ''.join([np.binary_repr(x, width=2) for x in cnt_sel]) # binary representation of the values (the last 2 bits) and joining them into one string
2023-12-05 17:20:14 +00:00
print ( ' {0:0>32x} ' . format ( int ( estimate , 2 ) ) )
print ( trng_val ) # from data_info, output of the RNG in FPGA