text: #Mahdi
  #This file reads the output from the simulator
  #and generates the histogram based on the values and accuracy
  import matplotlib.pyplot as plt
  import struct
  import math
  import sys
  
  ########################## ONLY CHANGE THIS SECTION ###########################
  int_bits = 5
  frac_bits = 10
  base = 2
  ###############################################################################
  
  
  # function for returning fractions
  def calcul(val):
  	totalfrac = 0
  	intval = int(val[1:(int_bits+1)],base)
  	for i in range(int_bits + 1, frac_bits + int_bits + 1):
  		frac = int(val[i],base) * base**(-(i-int_bits))
  		totalfrac += frac 
  	if (int(val[0], 0) == 0): return(totalfrac + intval)
  	else: 		       	  return(-1 * (totalfrac + intval))
  
  # function for returning fractions
  def calcul2(val):
  	totalfrac = 0
  	intval = int(val[1:(int_bits+2)],2)
  	for i in range(int_bits + 2, frac_bits + int_bits + 1):
  		frac = int(val[i],0) * base**(-(i-int_bits-1))
  		totalfrac += frac 
  	if (int(val[0], 0) == 0): return(totalfrac + intval)
  	else: 		       	  return(-1 * (totalfrac + intval))	
  
  # function for parsing the data
  def data_parser(text, dic):
  	for i, j in dic.iteritems():
  	    text = text.replace(i,j)
  	return text 
  
  values = [1.2, 2.3, 1.2]
  bins=[0.2, 1.1, 2.4, 3.5]
  r = []
  acc = []
  
  reps = {'*':' ','+':' ',':':' ','=':' ',' ':' ','\n':''} 
  
  realreps = open("realreps.dat","r")
  inputfile = open("out.dat","r")
  outputfile = open("out2.dat","w")
  
  #read the values in fixed.point format and do the computation
  #every line has arguments
  for line in realreps:
  		line2 = data_parser(line, reps)
  		temp = line2.split(" ")
  		print("Here is real rep values:")
  		print(float(temp[0]) + float(temp[2]))
  		print(float(temp[0]) * float(temp[2]))
  
  	#Exact values from computation: now in log domain
  		print("Here is real rep values in log:")	
  		num1 = math.log(float(temp[0]), base)
  		num2 = math.log(float(temp[2]),base)	
  		cf = math.log(1 + base ** (-abs(num1-num2)), base)
  		print(math.pow(base, max(num1, num2) + cf ))
  		print(math.pow(base, math.log(float(temp[0]),base) + math.log(float(temp[2]),base)) )
  
  	#Approximation: values from computation in log domain 
  		print("Approximated cf in log:")	
  		num1 = math.log(float(temp[0]), base)
  		num2 = math.log(float(temp[2]),base)
  		print(num1, num2)		
  		cf = base ** (-abs(num1-num2)) #in hardware approx. using a shifter	 
  		print(math.pow(base, max(num1, num2) + cf ))
  		print(math.pow(base, math.log(float(temp[0]),base) + math.log(float(temp[2]),base)) )
  
  opType = input()
  	
  #read back the generated values from verilog computation
  print("Here is values read back from FPGA:")
  
  if(opType == "add"):
     	
  	for line in inputfile:
  	    line2 = data_parser(line, reps)
  	    temp = line2.split(" ")
  	    #unpack the string values to binary	
  	    val1 = struct.unpack('16s', temp[0])[0]   #X
  	    val2 = struct.unpack('16s', temp[8])[0]   #Y
  	    res = struct.unpack('16s', temp[13])[0]
  
  	    #compute exact and approx values	
  	    exact = (base ** calcul(res))
  	    approx = (base**calcul(val1) + base**calcul(val2))	
  	    dev = abs(approx - exact)
  
  	    print( calcul(val1) ,"+", calcul(val2), "=", calcul(res))
  	    print( "Exact number:" , (base**calcul(val1) + base**calcul(val2)) )
  	    print( "Hardware Approx. number:", base ** calcul(res))
  	    print( "r is:", abs(calcul(val1) - calcul(val2)), "acc rate is:", abs(exact - dev)/exact )
  
  	    r.insert (0, abs(calcul(val1) - calcul(val2))) # r = |X - Y|
  	    acc.insert (0, abs(exact - dev) / exact) # acc% = approx./exact
  
  elif (opType == "mult"):
     	
  	for line in inputfile:
  	    line2 = data_parser(line, reps)
  	    temp = line2.split(" ")
  	    #unpack the string values to binary	
  	    val1 = struct.unpack('16s', temp[0])[0]   #X
  	    val2 = struct.unpack('16s', temp[8])[0]   #Y
  	    res = struct.unpack('17s', temp[13])[0]
  	
  	    #compute exact and approx values	
  	    exact = (base ** calcul2(res))
  	    approx = (base**calcul(val1) * base**calcul(val2))	
  	    dev = abs(approx - exact)
  
  	    print( calcul(val1) ,"*", calcul(val2), "=", calcul2(res), "which was", res)
  	    print( "Exact number:" , (base**calcul(val1) * base**calcul(val2)) )
  	    print( "Hardware Approx. number:", base ** calcul2(res))
  
  
  	    r.insert (0, abs(calcul(val1) - calcul(val2))) # r = |X - Y|
  	    acc.insert (0, abs(exact - dev) / exact) # acc% = approx./exact
  
  else: 
  	  print("Sorry, operator not supported.") 
  	  sys.exit(0)		
  	
  plt.scatter(r,acc)
  
  plt.xlabel('r = |X - Y|', fontsize=18)
  plt.ylabel('accuracy %', fontsize=16)
  plt.show()
  
  #close files
  inputfile.close()
  outputfile.close()
  