Lots more python updates

This commit is contained in:
Jordan Carlin 2024-12-17 21:31:12 -08:00
parent 21e35c9068
commit 51c3d59605
No known key found for this signature in database
18 changed files with 483 additions and 560 deletions

View File

@ -65,10 +65,7 @@ with open(resultfile, mode='w', newline='') as csvfile:
# Loop through each architecture and run the make commands # Loop through each architecture and run the make commands
for arch in arch_list: for arch in arch_list:
if(str in arch): xlen_value = "32" if str in arch else "64"
xlen_value='32'
else:
xlen_value='64'
os.system("make clean") os.system("make clean")
make_all = f"make all XLEN={xlen_value} ARCH={arch}" make_all = f"make all XLEN={xlen_value} ARCH={arch}"
os.system(make_all) os.system(make_all)

View File

@ -30,12 +30,8 @@ def tabulate_arch_sweep(directory):
file = case+"_"+arch+".json" file = case+"_"+arch+".json"
file_path = os.path.join(directory, file) file_path = os.path.join(directory, file)
lines = [] lines = []
try: with open(file_path) as f:
f = open(file_path)
lines = f.readlines() lines = f.readlines()
except:
f.close()
#print(file_path+" does not exist")
for line in lines: for line in lines:
#print("File: "+file+" Line: "+line) #print("File: "+file+" Line: "+line)
#p = re.compile('".*" : .*,') #p = re.compile('".*" : .*,')

View File

@ -16,7 +16,7 @@ def loadCoremark():
keywordlist = ["CoreMark 1.0", "CoreMark Size", "MTIME", "MINSTRET", "Branches Miss Predictions", "BTB Misses"] keywordlist = ["CoreMark 1.0", "CoreMark Size", "MTIME", "MINSTRET", "Branches Miss Predictions", "BTB Misses"]
for keyword in keywordlist: for keyword in keywordlist:
bashInst = "cat " + coremarkPath + " | grep \"" + keyword + "\" | cut -d \':\' -f 2 | cut -d \" \" -f 2 | tail -1" bashInst = "cat " + coremarkPath + ' | grep "' + keyword + "\" | cut -d ':' -f 2 | cut -d \" \" -f 2 | tail -1"
result = subprocess.run(bashInst, stdout=subprocess.PIPE, shell=True) result = subprocess.run(bashInst, stdout=subprocess.PIPE, shell=True)
if (debug): print(result) if (debug): print(result)
coremarkData[keyword] = int(result.stdout) coremarkData[keyword] = int(result.stdout)
@ -25,8 +25,8 @@ def loadCoremark():
def loadEmbench(embenchPath, embenchData): def loadEmbench(embenchPath, embenchData):
"""loads the embench data dictionary""" """loads the embench data dictionary"""
f = open(embenchPath) with open(embenchPath) as f:
embenchData = json.load(f) embenchData = json.load(f)
if (debug): print(embenchData) if (debug): print(embenchData)
return embenchData return embenchData

View File

@ -284,7 +284,7 @@ def main(args):
elif lninfo[1] == 'A': elif lninfo[1] == 'A':
atoms += 1 atoms += 1
if not result == lninfo[2]: if result != lninfo[2]:
print(f"Result mismatch at address {lninfo[0]}. Wally: {lninfo[2]}, Sim: {result}") print(f"Result mismatch at address {lninfo[0]}. Wally: {lninfo[2]}, Sim: {result}")
mismatches += 1 mismatches += 1
if args.dist: if args.dist:

View File

@ -473,7 +473,7 @@ class TestRunner:
if failed_configs: if failed_configs:
md_file.write("## Failed Configurations\n\n") md_file.write("## Failed Configurations\n\n")
for config, log_file in failed_configs: for config, log_file in failed_configs:
md_file.write(f"- <span class=\"failure\" style=\"color: red;\">{config}</span> ({log_file})\n") md_file.write(f'- <span class="failure" style="color: red;">{config}</span> ({log_file})\n')
md_file.write("\n") md_file.write("\n")
else: else:
md_file.write("## Failed Configurations\n") md_file.write("## Failed Configurations\n")
@ -481,7 +481,7 @@ class TestRunner:
md_file.write("\n## Passed Configurations\n") md_file.write("\n## Passed Configurations\n")
for config in passed_configs: for config in passed_configs:
md_file.write(f"- <span class=\"success\" style=\"color: green;\">{config}</span>\n") md_file.write(f'- <span class="success" style="color: green;">{config}</span>\n')
self.logger.info("writing test outputs to markdown") self.logger.info("writing test outputs to markdown")
@ -526,7 +526,7 @@ class TestRunner:
md_file.write("\n") md_file.write("\n")
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
# Handle if the command fails # Handle if the command fails
md_file.write(f"Failed to identify host and Operating System information: {str(e)}") md_file.write(f"Failed to identify host and Operating System information: {e!s}")
# Which tests did we run # Which tests did we run
md_file.write(f"\n**Tests made:** `make {test_type}`\n") md_file.write(f"\n**Tests made:** `make {test_type}`\n")
@ -548,7 +548,7 @@ class TestRunner:
if len(item) == 0: if len(item) == 0:
md_file.write("\n") md_file.write("\n")
md_file.write("* <span class=\"no-failure\" style=\"color: green;\">No failures</span>\n") md_file.write('* <span class="no-failure" style="color: green;">No failures</span>\n')
md_file.write("\n") md_file.write("\n")
else: else:
for failed_test in item: for failed_test in item:
@ -556,7 +556,7 @@ class TestRunner:
log_file = failed_test[1] log_file = failed_test[1]
md_file.write("\n") md_file.write("\n")
md_file.write(f"* <span class=\"failure\" style=\"color: red;\">{config}</span> ({log_file})\n") md_file.write(f'* <span class="failure" style="color: red;">{config}</span> ({log_file})\n')
md_file.write("\n") md_file.write("\n")
# Successful Tests # Successful Tests
@ -571,14 +571,14 @@ class TestRunner:
if len(item) == 0: if len(item) == 0:
md_file.write("\n") md_file.write("\n")
md_file.write("* <span class=\"no-successes\" style=\"color: red;\">No successes</span>\n") md_file.write('* <span class="no-successes" style="color: red;">No successes</span>\n')
md_file.write("\n") md_file.write("\n")
else: else:
for passed_tests in item: for passed_tests in item:
config = passed_tests config = passed_tests
md_file.write("\n") md_file.write("\n")
md_file.write(f"* <span class=\"success\" style=\"color: green;\">{config}</span>\n") md_file.write(f'* <span class="success" style="color: green;">{config}</span>\n')
md_file.write("\n") md_file.write("\n")
self.logger.info("Combining markdown files") self.logger.info("Combining markdown files")
@ -800,7 +800,7 @@ def main():
logger.info(f"The total failures for all tests ran are: {total_number_failures}") logger.info(f"The total failures for all tests ran are: {total_number_failures}")
# Copy actual test logs from sim/questa, sim/verilator, sim/vcs # Copy actual test logs from sim/questa, sim/verilator, sim/vcs
if not args.tests == "test_lint": if args.tests != 'test_lint':
test_runner.copy_sim_logs([test_runner.cvw / "sim/questa/logs", test_runner.cvw / "sim/verilator/logs", test_runner.cvw / "sim/vcs/logs"]) test_runner.copy_sim_logs([test_runner.cvw / "sim/questa/logs", test_runner.cvw / "sim/verilator/logs", test_runner.cvw / "sim/vcs/logs"])
############################################# #############################################

View File

@ -46,14 +46,14 @@ def ParseBranchListFile(path):
is formated in row columns. Each row is a trace with the file, branch predictor type, and the parameters. is formated in row columns. Each row is a trace with the file, branch predictor type, and the parameters.
parameters can be any number and depend on the predictor type. Returns a list of lists.''' parameters can be any number and depend on the predictor type. Returns a list of lists.'''
lst = [] lst = []
BranchList = open(path) with open(path) as BranchList:
for line in BranchList: for line in BranchList:
tokens = line.split() tokens = line.split()
predictorLog = os.path.dirname(path) + '/' + tokens[0] predictorLog = os.path.dirname(path) + '/' + tokens[0]
predictorType = tokens[1] predictorType = tokens[1]
predictorParams = tokens[2::] predictorParams = tokens[2::]
lst.append([predictorLog, predictorType, predictorParams]) lst.append([predictorLog, predictorType, predictorParams])
#print(predictorLog, predictorType, predictorParams) #print(predictorLog, predictorType, predictorParams)
return lst return lst
def ProcessFile(fileName): def ProcessFile(fileName):
@ -62,22 +62,22 @@ def ProcessFile(fileName):
# 1 find lines with Read memfile and extract test name # 1 find lines with Read memfile and extract test name
# 2 parse counters into a list of (name, value) tuples (dictionary maybe?) # 2 parse counters into a list of (name, value) tuples (dictionary maybe?)
benchmarks = [] benchmarks = []
transcript = open(fileName)
HPMClist = { } HPMClist = { }
testName = '' testName = ''
for line in transcript.readlines(): with open(fileName) as transcript:
lineToken = line.split() for line in transcript.readlines():
if(len(lineToken) > 3 and lineToken[1] == 'Read' and lineToken[2] == 'memfile'): lineToken = line.split()
opt = lineToken[3].split('/')[-4] if(len(lineToken) > 3 and lineToken[1] == 'Read' and lineToken[2] == 'memfile'):
testName = lineToken[3].split('/')[-1].split('.')[0] opt = lineToken[3].split('/')[-4]
HPMClist = { } testName = lineToken[3].split('/')[-1].split('.')[0]
elif(len(lineToken) > 4 and lineToken[1][0:3] == 'Cnt'): HPMClist = { }
countToken = line.split('=')[1].split() elif(len(lineToken) > 4 and lineToken[1][0:3] == 'Cnt'):
value = int(countToken[0]) if countToken[0] != 'x' else 0 countToken = line.split('=')[1].split()
name = ' '.join(countToken[1:]) value = int(countToken[0]) if countToken[0] != 'x' else 0
HPMClist[name] = value name = ' '.join(countToken[1:])
elif ('is done' in line): HPMClist[name] = value
benchmarks.append((testName, opt, HPMClist)) elif ('is done' in line):
benchmarks.append((testName, opt, HPMClist))
return benchmarks return benchmarks

View File

@ -268,21 +268,12 @@ def addTests(tests, sim):
for test in tests: for test in tests:
config = test[0] config = test[0]
suites = test[1] suites = test[1]
if len(test) >= 3: args = f" --args {test[2]}" if len(test) >= 3 else ""
args = f" --args {test[2]}" gs = test[3] if len(test) >= 4 else "All tests ran without failures"
else:
args = ""
if len(test) >= 4:
gs = test[3]
else:
gs = "All tests ran without failures"
cmdPrefix=f"wsim --sim {sim} {coverStr} {config}" cmdPrefix=f"wsim --sim {sim} {coverStr} {config}"
for t in suites: for t in suites:
sim_log = f"{sim_logdir}{config}_{t}.log" sim_log = f"{sim_logdir}{config}_{t}.log"
if len(test) >= 5: grepfile = sim_logdir + test[4] if len(test) >= 5 else sim_log
grepfile = sim_logdir + test[4]
else:
grepfile = sim_log
tc = TestCase( tc = TestCase(
name=t, name=t,
variant=config, variant=config,
@ -535,9 +526,7 @@ def main():
os.system('rm -f questa/fcov_ucdb/* questa/fcov_logs/* questa/fcov/*') os.system('rm -f questa/fcov_ucdb/* questa/fcov_logs/* questa/fcov/*')
elif args.buildroot: elif args.buildroot:
TIMEOUT_DUR = 60*1440 # 1 day TIMEOUT_DUR = 60*1440 # 1 day
elif args.testfloat: elif args.testfloat or args.nightly:
TIMEOUT_DUR = 30*60 # seconds
elif args.nightly:
TIMEOUT_DUR = 30*60 # seconds TIMEOUT_DUR = 30*60 # seconds
else: else:
TIMEOUT_DUR = 10*60 # seconds TIMEOUT_DUR = 10*60 # seconds
@ -545,10 +534,7 @@ def main():
# Scale the number of concurrent processes to the number of test cases, but # Scale the number of concurrent processes to the number of test cases, but
# max out at a limited number of concurrent processes to not overwhelm the system # max out at a limited number of concurrent processes to not overwhelm the system
# right now fcov, ccov, nightly all use Imperas # right now fcov, ccov, nightly all use Imperas
if (args.ccov or args.fcov or args.nightly): ImperasDVLicenseCount = 16 if args.ccov or args.fcov or args.nightly else 10000
ImperasDVLicenseCount = 16 # limit number of concurrent processes to avoid overloading ImperasDV licenses
else:
ImperasDVLicenseCount = 10000 # effectively no license limit for non-lockstep tests
with Pool(processes=min(len(configs),multiprocessing.cpu_count(), ImperasDVLicenseCount)) as pool: with Pool(processes=min(len(configs),multiprocessing.cpu_count(), ImperasDVLicenseCount)) as pool:
num_fail = 0 num_fail = 0
results = {} results = {}

View File

@ -67,8 +67,8 @@ def main():
parser.add_argument('-d', "--dist", action='store_true', help="Report distribution of operations") parser.add_argument('-d', "--dist", action='store_true', help="Report distribution of operations")
parser.add_argument('-s', "--sim", help="Simulator", choices=["questa", "verilator", "vcs"], default="verilator") parser.add_argument('-s', "--sim", help="Simulator", choices=["questa", "verilator", "vcs"], default="verilator")
args = parser.parse_args() args = parser.parse_args()
simargs = "I_CACHE_ADDR_LOGGER=1\\\'b1 D_CACHE_ADDR_LOGGER=1\\\'b1" simargs = "I_CACHE_ADDR_LOGGER=1\\'b1 D_CACHE_ADDR_LOGGER=1\\'b1"
testcmd = "wsim --sim " + args.sim + " rv64gc {} --params \"" + simargs + "\" > /dev/null" testcmd = "wsim --sim " + args.sim + ' rv64gc {} --params "' + simargs + '" > /dev/null'
#cachecmd = "CacheSim.py 64 4 56 44 -f {} --verbose" #cachecmd = "CacheSim.py 64 4 56 44 -f {} --verbose"
cachecmd = "CacheSim.py 64 4 56 44 -f {}" cachecmd = "CacheSim.py 64 4 56 44 -f {}"
mismatches = 0 mismatches = 0

View File

@ -13,8 +13,8 @@ if not os.path.isfile(sys.path[0]+'/slack-webhook-url.txt'):
print('Tutorial for slack webhook urls: https://bit.ly/BenSlackNotifier') print('Tutorial for slack webhook urls: https://bit.ly/BenSlackNotifier')
print('==============================================================') print('==============================================================')
else: else:
urlFile = open(sys.path[0]+'/slack-webhook-url.txt') with open(sys.path[0]+'/slack-webhook-url.txt') as urlFile:
url = urlFile.readline().strip('\n') url = urlFile.readline().strip('\n')
# Traverse 3 parents up the process tree # Traverse 3 parents up the process tree
result = subprocess.check_output('ps -o ppid -p $PPID',shell=True) result = subprocess.check_output('ps -o ppid -p $PPID',shell=True)
@ -25,7 +25,7 @@ else:
result = subprocess.check_output('ps -o cmd -p '+PPID3,shell=True) result = subprocess.check_output('ps -o cmd -p '+PPID3,shell=True)
cmdName = str(result).split('\\n')[1] cmdName = str(result).split('\\n')[1]
# Get current time # Get current time
timezone_offset = -8.0 # Pacific Standard Time (UTC08:00) timezone_offset = -8.0 # Pacific Standard Time (UTC-08:00)
tzinfo = timezone(timedelta(hours=timezone_offset)) tzinfo = timezone(timedelta(hours=timezone_offset))
time = datetime.now(tzinfo).strftime('%I:%M %p') time = datetime.now(tzinfo).strftime('%I:%M %p')
# Send message # Send message

View File

@ -24,7 +24,7 @@ def runFindCommand(cmd):
res = subprocess.check_output(cmd, shell=True, ) res = subprocess.check_output(cmd, shell=True, )
res = str(res) res = str(res)
res = res.replace("\\n", " ") # replace newline with space res = res.replace("\\n", " ") # replace newline with space
res = res.replace("\'", "") # strip off quotation marks res = res.replace("'", "") # strip off quotation marks
res = res[1:] # strip off leading b from byte string res = res[1:] # strip off leading b from byte string
return res return res
@ -81,13 +81,10 @@ def processArgs(wkdir, args):
def setupParamOverrides(wkdir, args): def setupParamOverrides(wkdir, args):
paramOverrideFile = os.path.join(wkdir, "param_overrides.txt") paramOverrideFile = os.path.join(wkdir, "param_overrides.txt")
with open(paramOverrideFile, "w", encoding="utf-8") as f: with open(paramOverrideFile, "w") as f:
for param in args.params.split(): for param in args.params.split():
[param, value] = param.split("=") [param, value] = param.split("=")
if r"\'" in value: # for bit values value = value.replace("\\'", "'") if "\\'" in value else f'"{value}"' # transform quotes/bit indicators
value = value.replace(r"\'", "'")
else: # for strings
value = f'"{value}"'
f.write(f"assign {value} {args.tb}/{param}\n") f.write(f"assign {value} {args.tb}/{param}\n")
return f" -parameters {wkdir}/param_overrides.txt " return f" -parameters {wkdir}/param_overrides.txt "

View File

@ -27,48 +27,44 @@ def synthsintocsv():
specReg = re.compile('[a-zA-Z0-9]+') specReg = re.compile('[a-zA-Z0-9]+')
metricReg = re.compile('-?\d+\.\d+[e]?[-+]?\d*') metricReg = re.compile('-?\d+\.\d+[e]?[-+]?\d*')
file = open("Summary.csv", "w") with open("Summary.csv", "w") as file:
writer = csv.writer(file) writer = csv.writer(file)
writer.writerow(['Width', 'Config', 'Mod', 'Tech', 'Target Freq', 'Delay', 'Area']) writer.writerow(['Width', 'Config', 'Mod', 'Tech', 'Target Freq', 'Delay', 'Area'])
for oneSynth in allSynths: for oneSynth in allSynths:
descrip = specReg.findall(oneSynth) descrip = specReg.findall(oneSynth)
# print("From " + oneSynth + " Find ") # print("From " + oneSynth + " Find ")
# for d in descrip: # for d in descrip:
# print(d) # print(d)
if (descrip[3] == "sram"): base = 4 if descrip[3] == "sram" else 3
base = 4 width = descrip[base][:4]
else: config = descrip[base][4:]
base = 3 if descrip[base+1][-2:] == 'nm':
width = descrip[base][:4] mod = ''
config = descrip[base][4:] else:
if descrip[base+1][-2:] == 'nm': mod = descrip[base+1]
mod = '' descrip = descrip[1:]
else: tech = descrip[base+1][:-2]
mod = descrip[base+1] freq = descrip[base+2]
descrip = descrip[1:] # print(width, config, mod, tech, freq)
tech = descrip[base+1][:-2] metrics = []
freq = descrip[base+2] for phrase in ['Path Slack', 'Design Area']:
# print(width, config, mod, tech, freq) bashCommand = 'grep "{}" '+ oneSynth[2:]+'/reports/*qor*'
metrics = [] bashCommand = bashCommand.format(phrase)
for phrase in ['Path Slack', 'Design Area']: # print(bashCommand)
bashCommand = 'grep "{}" '+ oneSynth[2:]+'/reports/*qor*' try:
bashCommand = bashCommand.format(phrase) output = subprocess.check_output(['bash','-c', bashCommand])
# print(bashCommand) nums = metricReg.findall(str(output))
try: nums = [float(m) for m in nums]
output = subprocess.check_output(['bash','-c', bashCommand]) metrics += nums
nums = metricReg.findall(str(output)) except:
nums = [float(m) for m in nums] print(width + config + tech + '_' + freq + " doesn't have reports")
metrics += nums if metrics == []:
except: pass
print(width + config + tech + '_' + freq + " doesn't have reports") else:
if metrics == []: delay = 1000/int(freq) - metrics[0]
pass area = metrics[1]
else: writer.writerow([width, config, mod, tech, freq, delay, area])
delay = 1000/int(freq) - metrics[0]
area = metrics[1]
writer.writerow([width, config, mod, tech, freq, delay, area])
file.close()
def synthsfromcsv(filename): def synthsfromcsv(filename):
@ -93,7 +89,7 @@ def freqPlot(tech, width, config):
freqsL, delaysL, areasL = ([[], []] for i in range(3)) freqsL, delaysL, areasL = ([[], []] for i in range(3))
for oneSynth in allSynths: for oneSynth in allSynths:
if (width == oneSynth.width) & (config == oneSynth.config) & (tech == oneSynth.tech) & ('orig' == oneSynth.mod): if (width == oneSynth.width) & (config == oneSynth.config) & (tech == oneSynth.tech) & (oneSynth.mod == 'orig'):
ind = (1000/oneSynth.delay < (0.95*oneSynth.freq)) # when delay is within target clock period ind = (1000/oneSynth.delay < (0.95*oneSynth.freq)) # when delay is within target clock period
freqsL[ind] += [oneSynth.freq] freqsL[ind] += [oneSynth.freq]
delaysL[ind] += [oneSynth.delay] delaysL[ind] += [oneSynth.delay]
@ -101,10 +97,7 @@ def freqPlot(tech, width, config):
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True) fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
allFreqs = list(flatten(freqsL)) allFreqs = list(flatten(freqsL))
if allFreqs != []: median = np.median(allFreqs) if allFreqs != [] else 0
median = np.median(allFreqs)
else:
median = 0
for ind in [0,1]: for ind in [0,1]:
areas = areasL[ind] areas = areasL[ind]
@ -169,11 +162,10 @@ def plotFeatures(tech, width, config):
delays, areas, labels = ([] for i in range(3)) delays, areas, labels = ([] for i in range(3))
freq = techdict[tech].targfreq freq = techdict[tech].targfreq
for oneSynth in allSynths: for oneSynth in allSynths:
if (tech == oneSynth.tech) & (freq == oneSynth.freq): if (tech == oneSynth.tech) & (freq == oneSynth.freq) & (oneSynth.config == config) & (width == oneSynth.width):
if (oneSynth.config == config) & (width == oneSynth.width): delays += [oneSynth.delay]
delays += [oneSynth.delay] areas += [oneSynth.area]
areas += [oneSynth.area] labels += [oneSynth.mod]
labels += [oneSynth.mod]
if (delays == []): if (delays == []):
print("No delays found for tech ", tech, " freq ", freq, ". Did you set --sky130freq, --sky90freq and --tsmcfreq?\n") print("No delays found for tech ", tech, " freq ", freq, ". Did you set --sky130freq, --sky90freq and --tsmcfreq?\n")

View File

@ -50,49 +50,48 @@ def synthsintocsv():
specReg = re.compile("[a-zA-Z0-9]+") specReg = re.compile("[a-zA-Z0-9]+")
metricReg = re.compile("-?\d+\.\d+[e]?[-+]?\d*") metricReg = re.compile("-?\d+\.\d+[e]?[-+]?\d*")
file = open("ppaData.csv", "w") with open("ppaData.csv", "w") as file:
writer = csv.writer(file) writer = csv.writer(file)
writer.writerow( writer.writerow(
[ [
"Module", "Module",
"Tech", "Tech",
"Width", "Width",
"Target Freq", "Target Freq",
"Delay", "Delay",
"Area", "Area",
"L Power (nW)", "L Power (nW)",
"D energy (nJ)", "D energy (nJ)",
] ]
) )
for oneSynth in allSynths: for oneSynth in allSynths:
module, width, risc, tech, freq = specReg.findall(oneSynth)[1:6] module, width, risc, tech, freq = specReg.findall(oneSynth)[1:6]
tech = tech[:-2] tech = tech[:-2]
metrics = [] metrics = []
for phrase in [["Path Slack", "qor"], ["Design Area", "qor"], ["100", "power"]]: for phrase in [["Path Slack", "qor"], ["Design Area", "qor"], ["100", "power"]]:
bashCommand = 'grep "{}" ' + oneSynth[2:] + "/reports/*{}*" bashCommand = 'grep "{}" ' + oneSynth[2:] + "/reports/*{}*"
bashCommand = bashCommand.format(*phrase) bashCommand = bashCommand.format(*phrase)
try: try:
output = subprocess.check_output(["bash", "-c", bashCommand]) output = subprocess.check_output(["bash", "-c", bashCommand])
except: except:
print(module + width + tech + freq + " doesn't have reports") print(module + width + tech + freq + " doesn't have reports")
print("Consider running cleanup() first") print("Consider running cleanup() first")
nums = metricReg.findall(str(output)) nums = metricReg.findall(str(output))
nums = [float(m) for m in nums] nums = [float(m) for m in nums]
metrics += nums metrics += nums
delay = 1000 / int(freq) - metrics[0] delay = 1000 / int(freq) - metrics[0]
area = metrics[1] area = metrics[1]
lpower = metrics[4] lpower = metrics[4]
tpower = (metrics[2] + metrics[3] + metrics[4]*.000001) tpower = (metrics[2] + metrics[3] + metrics[4]*.000001)
denergy = ( denergy = (
(tpower) / int(freq) * 1000 (tpower) / int(freq) * 1000
) # (switching + internal powers)*delay, more practical units for regression coefs ) # (switching + internal powers)*delay, more practical units for regression coefs
if "flop" in module: # since two flops in each module if "flop" in module: # since two flops in each module
[area, lpower, denergy] = [n / 2 for n in [area, lpower, denergy]] [area, lpower, denergy] = [n / 2 for n in [area, lpower, denergy]]
writer.writerow([module, tech, width, freq, delay, area, lpower, denergy]) writer.writerow([module, tech, width, freq, delay, area, lpower, denergy])
file.close()
def cleanup(): def cleanup():
@ -129,10 +128,7 @@ def getVals(tech, module, var, freq=None, width=None):
works at a specified target frequency or if none is given, uses the synthesis with the best achievable delay for each width works at a specified target frequency or if none is given, uses the synthesis with the best achievable delay for each width
""" """
if width is not None: widthsToGet = width if width is not None else widths
widthsToGet = width
else:
widthsToGet = widths
metric = [] metric = []
widthL = [] widthL = []
@ -171,37 +167,30 @@ def csvOfBest(filename):
m = np.Inf # large number to start m = np.Inf # large number to start
best = None best = None
for oneSynth in allSynths: # best achievable, rightmost green for oneSynth in allSynths: # best achievable, rightmost green
if ( if (oneSynth.width == w) & (oneSynth.tech == tech) & (oneSynth.module == mod):
(oneSynth.width == w) if (oneSynth.delay < m) & (1000 / oneSynth.delay > oneSynth.freq):
& (oneSynth.tech == tech)
& (oneSynth.module == mod)
):
if (oneSynth.delay < m) & (
1000 / oneSynth.delay > oneSynth.freq
):
m = oneSynth.delay m = oneSynth.delay
best = oneSynth best = oneSynth
if (best is not None) & (best not in bestSynths): if (best is not None) & (best not in bestSynths):
bestSynths += [best] bestSynths += [best]
file = open(filename, "w") with open(filename, "w") as file:
writer = csv.writer(file) writer = csv.writer(file)
writer.writerow( writer.writerow(
[ [
"Module", "Module",
"Tech", "Tech",
"Width", "Width",
"Target Freq", "Target Freq",
"Delay", "Delay",
"Area", "Area",
"L Power (nW)", "L Power (nW)",
"D energy (nJ)", "D energy (nJ)",
] ]
) )
for synth in bestSynths: for synth in bestSynths:
writer.writerow(list(synth)) writer.writerow(list(synth))
file.close()
return bestSynths return bestSynths
@ -229,7 +218,7 @@ def genLegend(fits, coefs, r2=None, spec=None, ale=False):
eq = "" eq = ""
ind = 0 ind = 0
for k in eqDict.keys(): for k in eqDict:
if k in fits: if k in fits:
if str(coefsr[ind]) != "0": if str(coefsr[ind]) != "0":
eq += " + " + coefsr[ind] + eqDict[k] eq += " + " + coefsr[ind] + eqDict[k]
@ -277,10 +266,7 @@ def oneMetricPlot(
modFit = fitDict[module] modFit = fitDict[module]
fits = modFit[ale] fits = modFit[ale]
if freq: ls = "--" if freq else "-"
ls = "--"
else:
ls = "-"
for spec in techSpecs: for spec in techSpecs:
# print(f"Searching for module of spec {spec} and module {module} and var {var}") # print(f"Searching for module of spec {spec} and module {module} and var {var}")
@ -403,72 +389,16 @@ def makeCoefTable():
"""writes CSV with each line containing the coefficients for a regression fit """writes CSV with each line containing the coefficients for a regression fit
to a particular combination of module, metric (including both techs, normalized) to a particular combination of module, metric (including both techs, normalized)
""" """
file = open("ppaFitting.csv", "w") with open("ppaFitting.csv", "w") as file:
writer = csv.writer(file) writer = csv.writer(file)
writer.writerow( writer.writerow(
["Module", "Metric", "Target", "1", "N", "N^2", "log2(N)", "Nlog2(N)", "R^2"] ["Module", "Metric", "Target", "1", "N", "N^2", "log2(N)", "Nlog2(N)", "R^2"]
) )
for module in modules: for module in modules:
for freq in [10, None]: for freq in [10, None]:
target = "easy" if freq else "hard" target = "easy" if freq else "hard"
for var in ["delay", "area", "lpower", "denergy"]: for var in ["delay", "area", "lpower", "denergy"]:
ale = var != "delay"
metL = []
modFit = fitDict[module]
fits = modFit[ale]
for spec in techSpecs:
metric = getVals(spec.tech, module, var, freq=freq)
techdict = spec._asdict()
norm = techdict[var]
metL += [m / norm for m in metric]
xp, pred, coefs, r2 = regress(widths * 2, metL, fits, ale)
coefs = np.ndarray.tolist(coefs)
coefsToWrite = [None] * 5
fitTerms = "clsgn"
ind = 0
for i in range(len(fitTerms)):
if fitTerms[i] in fits:
coefsToWrite[i] = coefs[ind]
ind += 1
row = [module, var, target] + coefsToWrite + [r2]
writer.writerow(row)
file.close()
def sigfig(num, figs):
return "{:g}".format(float("{:.{p}g}".format(num, p=figs)))
def makeEqTable():
"""writes CSV with each line containing the equations for fits for each metric
to a particular module (including both techs, normalized)
"""
file = open("ppaEquations.csv", "w")
writer = csv.writer(file)
writer.writerow(
[
"Element",
"Best delay",
"Fast area",
"Fast leakage",
"Fast energy",
"Small area",
"Small leakage",
"Small energy",
]
)
for module in modules:
eqs = []
for freq in [None, 10]:
for var in ["delay", "area", "lpower", "denergy"]:
if (var == "delay") and (freq == 10):
pass
else:
ale = var != "delay" ale = var != "delay"
metL = [] metL = []
modFit = fitDict[module] modFit = fitDict[module]
@ -482,12 +412,63 @@ def makeEqTable():
xp, pred, coefs, r2 = regress(widths * 2, metL, fits, ale) xp, pred, coefs, r2 = regress(widths * 2, metL, fits, ale)
coefs = np.ndarray.tolist(coefs) coefs = np.ndarray.tolist(coefs)
eqs += [genLegend(fits, coefs, ale=ale)] coefsToWrite = [None] * 5
row = [module] + eqs fitTerms = "clsgn"
writer.writerow(row) ind = 0
for i in range(len(fitTerms)):
if fitTerms[i] in fits:
coefsToWrite[i] = coefs[ind]
ind += 1
row = [module, var, target] + coefsToWrite + [r2]
writer.writerow(row)
file.close()
def sigfig(num, figs):
return "{:g}".format(float("{:.{p}g}".format(num, p=figs)))
def makeEqTable():
"""writes CSV with each line containing the equations for fits for each metric
to a particular module (including both techs, normalized)
"""
with open("ppaEquations.csv", "w") as file:
writer = csv.writer(file)
writer.writerow(
[
"Element",
"Best delay",
"Fast area",
"Fast leakage",
"Fast energy",
"Small area",
"Small leakage",
"Small energy",
]
)
for module in modules:
eqs = []
for freq in [None, 10]:
for var in ["delay", "area", "lpower", "denergy"]:
if (var == "delay") and (freq == 10):
pass
else:
ale = var != "delay"
metL = []
modFit = fitDict[module]
fits = modFit[ale]
for spec in techSpecs:
metric = getVals(spec.tech, module, var, freq=freq)
techdict = spec._asdict()
norm = techdict[var]
metL += [m / norm for m in metric]
xp, pred, coefs, r2 = regress(widths * 2, metL, fits, ale)
coefs = np.ndarray.tolist(coefs)
eqs += [genLegend(fits, coefs, ale=ale)]
row = [module] + eqs
writer.writerow(row)
def genFuncs(fits="clsgn"): def genFuncs(fits="clsgn"):
"""helper function for regress() """helper function for regress()
@ -819,10 +800,7 @@ def stdDevError():
norm = techdict[var] norm = techdict[var]
metL += [m / norm for m in metric] metL += [m / norm for m in metric]
if ale: ws = [w / normAddWidth for w in widths] if ale else widths
ws = [w / normAddWidth for w in widths]
else:
ws = widths
ws = ws * 2 ws = ws * 2
mat = [] mat = []
for w in ws: for w in ws:
@ -896,7 +874,7 @@ if __name__ == "__main__":
"flop": ["c", "l", "l"], "flop": ["c", "l", "l"],
"binencoder": ["cg", "l", "l"], "binencoder": ["cg", "l", "l"],
} }
fitDict.update(dict.fromkeys(["mux2", "mux4", "mux8"], ["cg", "l", "l"])) fitDict.update({key: ["cg", "l", "l"] for key in ["mux2", "mux4", "mux8"]})
TechSpec = namedtuple("TechSpec", "tech color shape delay area lpower denergy") TechSpec = namedtuple("TechSpec", "tech color shape delay area lpower denergy")
# FO4 delay information information # FO4 delay information information

View File

@ -21,53 +21,46 @@ args=parser.parse_args()
fin_path = glob.glob(f"{os.getenv('WALLY')}/src/**/{args.DESIGN}.sv",recursive=True)[0] fin_path = glob.glob(f"{os.getenv('WALLY')}/src/**/{args.DESIGN}.sv",recursive=True)[0]
fin = open(fin_path) with open(fin_path) as fin:
lines = fin.readlines()
lines = fin.readlines() # keeps track of what line number the module header begins
lineModuleStart = 0
# keeps track of what line number the module header begins # keeps track of what line number the module header ends
lineModuleStart = 0 lineModuleEnd = 0
# keeps track of what line number the module header ends # keeps track of module name
lineModuleEnd = 0 moduleName = ""
# keeps track of module name # string that will keep track of the running module header
moduleName = "" buf = 'import cvw::*;\n`include "config.vh"\n`include "parameter-defs.vh"\n'
# string that will keep track of the running module header # are we writing into the buffer
buf = "import cvw::*;\n`include \"config.vh\"\n`include \"parameter-defs.vh\"\n" writeBuf=False
# are we writing into the buffer index=0
writeBuf=False
index=0 # string copy logic
for l in lines:
if l.lstrip().find("module") == 0:
lineModuleStart = index
moduleName = l.split()[1]
writeBuf = True
buf += f"module {moduleName}wrapper (\n"
continue
if (writeBuf):
buf += l
if l.lstrip().find (");") == 0:
lineModuleEnd = index
break
index+=1
# string copy logic # post-processing buffer: add DUT and endmodule lines
for l in lines: buf += f"\t{moduleName} #(P) dut(.*);\nendmodule"
if l.lstrip().find("module") == 0:
lineModuleStart = index
moduleName = l.split()[1]
writeBuf = True
buf += f"module {moduleName}wrapper (\n"
continue
if (writeBuf):
buf += l
if l.lstrip().find (");") == 0:
lineModuleEnd = index
break
index+=1
# post-processing buffer: add DUT and endmodule lines # path to wrapper
buf += f"\t{moduleName} #(P) dut(.*);\nendmodule" wrapperPath = f"{args.HDLPATH}/{moduleName}wrapper.sv"
# path to wrapper with open(wrapperPath, "w") as fout:
wrapperPath = f"{args.HDLPATH}/{moduleName}wrapper.sv" fout.write(buf)
fout = open(wrapperPath, "w")
fout.write(buf)
fin.close()
fout.close()
#print(buf)

View File

@ -7,10 +7,7 @@ import argparse
def runSynth(config, mod, tech, freq, maxopt, usesram): def runSynth(config, mod, tech, freq, maxopt, usesram):
global pool global pool
if (usesram): prefix = "syn_sram_" if usesram else "syn_"
prefix = "syn_sram_"
else:
prefix = "syn_"
cfg = prefix + config cfg = prefix + config
command = f"make synth DESIGN=wallypipelinedcore CONFIG={cfg} MOD={mod} TECH={tech} DRIVE=FLOP FREQ={freq} MAXOPT={maxopt} USESRAM={usesram} MAXCORES=1" command = f"make synth DESIGN=wallypipelinedcore CONFIG={cfg} MOD={mod} TECH={tech} DRIVE=FLOP FREQ={freq} MAXOPT={maxopt} USESRAM={usesram} MAXCORES=1"
pool.map(mask, [command]) pool.map(mask, [command])

View File

@ -6,8 +6,9 @@ import fileinput
address = 0 address = 0
for line in fileinput.input('-'): with fileinput.input('-') as f:
# the 14- is to reverse the byte order to little endian for line in f:
formatedLine = ' '.join(line[14-i:14-i+2] for i in range(0, len(line), 2)) # the 14- is to reverse the byte order to little endian
sys.stdout.write(f'@{address:08x} {formatedLine:s}\n') formatedLine = ' '.join(line[14-i:14-i+2] for i in range(0, len(line), 2))
address+=8 sys.stdout.write(f'@{address:08x} {formatedLine:s}\n')
address+=8

View File

@ -40,9 +40,9 @@ mem_addr = mem_start_addr
def wl(line="", comment=None, fname=test_name): def wl(line="", comment=None, fname=test_name):
with open(fname, "a") as f: with open(fname, "a") as f:
instr = False if (":" in line or instr = not (":" in line or
".align" in line or ".align" in line or
"# include" in line) else True "# include" in line)
indent = 6 if instr else 0 indent = 6 if instr else 0
comment = "// " + comment if comment is not None else "" comment = "// " + comment if comment is not None else ""
to_write = " " * indent + line + comment + "\n" to_write = " " * indent + line + comment + "\n"

View File

@ -76,218 +76,212 @@ def create_vectors(my_config):
operation = my_config.op_code operation = my_config.op_code
rounding_mode = "X" rounding_mode = "X"
flags = "XX" flags = "XX"
# use name to create our new tv # use name to create our new tv and open vectors
dest_file = open(f"{dest_dir}cvw_{my_config.bits}_{vector1[:-2]}.tv", 'w') with open(f"{dest_dir}cvw_{my_config.bits}_{vector1[:-2]}.tv", 'w') as dest_file, open(source_dir1 + vector1) as src_file1, open(source_dir2 + vector2) as src_file2:
# open vectors # for each test in the vector
src_file1 = open(source_dir1 + vector1)
src_file2 = open(source_dir2 + vector2)
# for each test in the vector
reading = True
src_file2.readline() #skip first bc junk
# print(my_config.bits, my_config.letter)
if my_config.letter == "F" and my_config.bits == 64:
reading = True reading = True
# print("trigger 64F") src_file2.readline() #skip first bc junk
#skip first 2 lines bc junk # print(my_config.bits, my_config.letter)
src_file2.readline() if my_config.letter == "F" and my_config.bits == 64:
while reading: reading = True
# get answer and flags from Ref...signature # print("trigger 64F")
# answers are before deadbeef (first line of 4) #skip first 2 lines bc junk
# flags are after deadbeef (third line of 4) src_file2.readline()
answer = src_file2.readline().strip() while reading:
deadbeef = src_file2.readline().strip() # get answer and flags from Ref...signature
# print(answer) # answers are before deadbeef (first line of 4)
if not (answer == "e7d4b281" and deadbeef == "6f5ca309"): # if there is still stuff to read # flags are after deadbeef (third line of 4)
# get flags answer = src_file2.readline().strip()
packed = src_file2.readline().strip()[6:] deadbeef = src_file2.readline().strip()
flags, rounding_mode = unpack_rf(packed) # print(answer)
# skip 00000000 buffer if not (answer == "e7d4b281" and deadbeef == "6f5ca309"): # if there is still stuff to read
src_file2.readline() # get flags
packed = src_file2.readline().strip()[6:]
# parse through .S file
detected = False
done = False
op1val = "0"
op2val = "0"
while not (detected or done):
# print("det1")
line = src_file1.readline()
# print(line)
if "op1val" in line:
# print("det2")
# parse line
# handle special case where destination register is hardwired to zero
if "dest:x0" in line:
answer = "x" * len(answer)
op1val = line.split("op1val")[1].split("x")[1].split(";")[0]
if my_config.op != "fsqrt": # sqrt doesn't have two input vals
op2val = line.split("op2val")[1].split("x")[1].strip()
if op2val[-1] == ";": op2val = op2val[:-1] # remove ; if it's there
else:
op2val = 32*"X"
# go to next test in vector
detected = True
elif "RVTEST_CODE_END" in line:
done = True
# put it all together
if not done:
translation = f"{operation}_{ext_bits(op1val)}_{ext_bits(op2val)}_{ext_bits(answer.strip())}_{flags}_{rounding_mode}"
dest_file.write(translation + "\n")
else:
# print("read false")
reading = False
elif my_config.letter == "M" and my_config.bits == 64:
reading = True
#skip first 2 lines bc junk
src_file2.readline()
while reading:
# print("trigger 64M")
# get answer from Ref...signature
# answers span two lines and are reversed
answer2 = src_file2.readline().strip()
answer1 = src_file2.readline().strip()
answer = answer1 + answer2
#print(answer1,answer2)
if not (answer2 == "e7d4b281" and answer1 == "6f5ca309"): # if there is still stuff to read
# parse through .S file
detected = False
done = False
op1val = "0"
op2val = "0"
while not (detected or done):
# print("det1")
line = src_file1.readline()
# print(line)
if "op1val" in line:
# print("det2")
# parse line
# handle special case where destination register is hardwired to zero
if "dest:x0" in line:
answer = "x" * len(answer)
op1val = line.split("op1val")[1].split("x")[1].split(";")[0]
if "-" in line.split("op1val")[1].split("x")[0]: # neg sign handling
op1val = twos_comp(my_config.bits, op1val)
if my_config.op != "fsqrt": # sqrt doesn't have two input vals, unnec here but keeping for later
op2val = line.split("op2val")[1].split("x")[1].strip()
if op2val[-1] == ";": op2val = op2val[:-1] # remove ; if it's there
if "-" in line.split("op2val")[1].split("x")[0]: # neg sign handling
op2val = twos_comp(my_config.bits, op2val)
# go to next test in vector
detected = True
elif "RVTEST_CODE_END" in line:
done = True
# ints don't have flags
flags = "XX"
# put it all together
if not done:
translation = f"{operation}_{ext_bits(op1val)}_{ext_bits(op2val)}_{ext_bits(answer.strip())}_{flags.strip()}_{rounding_mode}"
dest_file.write(translation + "\n")
else:
# print("read false")
reading = False
elif my_config.letter == "M" and my_config.bits == 32:
reading = True
while reading:
# print("trigger 64M")
# get answer from Ref...signature
# answers span two lines and are reversed
answer = src_file2.readline().strip()
# print(f"Answer: {answer}")
#print(answer1,answer2)
if not (answer == "6f5ca309"): # if there is still stuff to read
# parse through .S file
detected = False
done = False
op1val = "0"
op2val = "0"
while not (detected or done):
# print("det1")
line = src_file1.readline()
# print(line)
if "op1val" in line:
# print("det2")
# parse line
# handle special case where destination register is hardwired to zero
if "dest:x0" in line:
answer = "x" * len(answer)
op1val = line.split("op1val")[1].split("x")[1].split(";")[0]
if "-" in line.split("op1val")[1].split("x")[0]: # neg sign handling
op1val = line.split("op1val")[1].split("x")[1].split(";")[0]
if "-" in line.split("op1val")[1].split("x")[0]: # neg sign handling
op1val = twos_comp(my_config.bits, op1val)
if my_config.op != "fsqrt": # sqrt doesn't have two input vals, unnec here but keeping for later
op2val = line.split("op2val")[1].split("x")[1].strip()
if op2val[-1] == ";": op2val = op2val[:-1] # remove ; if it's there
if "-" in line.split("op2val")[1].split("x")[0]: # neg sign handling
op2val = twos_comp(my_config.bits, op2val)
# go to next test in vector
detected = True
elif "RVTEST_CODE_END" in line:
done = True
# ints don't have flags
flags = "XX"
# put it all together
if not done:
translation = f"{operation}_{ext_bits(op1val)}_{ext_bits(op2val)}_{ext_bits(answer.strip())}_{flags.strip()}_{rounding_mode}"
dest_file.write(translation + "\n")
else:
# print("read false")
reading = False
else:
while reading:
# get answer and flags from Ref...signature
answer = src_file2.readline()
#print(answer)
packed = src_file2.readline()[6:]
#print("Packed: ", packed)
if len(packed.strip())>0: # if there is still stuff to read
# print("packed")
# parse through .S file
detected = False
done = False
op1val = "0"
op2val = "0"
while not (detected or done):
# print("det1")
line = src_file1.readline()
# print(line)
if "op1val" in line:
# print("det2")
# parse line
# handle special case where destination register is hardwired to zero
if "dest:x0" in line:
answer = "x" * len(answer)
op1val = line.split("op1val")[1].split("x")[1].split(";")[0]
if "-" in line.split("op1val")[1].split("x")[0]: # neg sign handling
op1val = twos_comp(my_config.bits, op1val)
if my_config.op != "fsqrt": # sqrt doesn't have two input vals
op2val = line.split("op2val")[1].split("x")[1].strip()
if op2val[-1] == ";": op2val = op2val[:-1] # remove ; if it's there
if "-" in line.split("op2val")[1].split("x")[0]: # neg sign handling
op2val = twos_comp(my_config.bits, op2val)
# go to next test in vector
detected = True
elif "RVTEST_CODE_END" in line:
done = True
# rounding mode for float
if not done and (my_config.op == "fsqrt" or my_config.op == "fdiv"):
flags, rounding_mode = unpack_rf(packed) flags, rounding_mode = unpack_rf(packed)
# skip 00000000 buffer
src_file2.readline()
# put it all together # parse through .S file
if not done: detected = False
translation = f"{operation}_{ext_bits(op1val)}_{ext_bits(op2val)}_{ext_bits(answer.strip())}_{flags}_{rounding_mode}" done = False
dest_file.write(translation + "\n") op1val = "0"
else: op2val = "0"
# print("read false") while not (detected or done):
reading = False # print("det1")
# print("out") line = src_file1.readline()
dest_file.close() # print(line)
src_file1.close() if "op1val" in line:
src_file2.close() # print("det2")
# parse line
# handle special case where destination register is hardwired to zero
if "dest:x0" in line:
answer = "x" * len(answer)
op1val = line.split("op1val")[1].split("x")[1].split(";")[0]
if my_config.op != "fsqrt": # sqrt doesn't have two input vals
op2val = line.split("op2val")[1].split("x")[1].strip()
if op2val[-1] == ";": op2val = op2val[:-1] # remove ; if it's there
else:
op2val = 32*"X"
# go to next test in vector
detected = True
elif "RVTEST_CODE_END" in line:
done = True
# put it all together
if not done:
translation = f"{operation}_{ext_bits(op1val)}_{ext_bits(op2val)}_{ext_bits(answer.strip())}_{flags}_{rounding_mode}"
dest_file.write(translation + "\n")
else:
# print("read false")
reading = False
elif my_config.letter == "M" and my_config.bits == 64:
reading = True
#skip first 2 lines bc junk
src_file2.readline()
while reading:
# print("trigger 64M")
# get answer from Ref...signature
# answers span two lines and are reversed
answer2 = src_file2.readline().strip()
answer1 = src_file2.readline().strip()
answer = answer1 + answer2
#print(answer1,answer2)
if not (answer2 == "e7d4b281" and answer1 == "6f5ca309"): # if there is still stuff to read
# parse through .S file
detected = False
done = False
op1val = "0"
op2val = "0"
while not (detected or done):
# print("det1")
line = src_file1.readline()
# print(line)
if "op1val" in line:
# print("det2")
# parse line
# handle special case where destination register is hardwired to zero
if "dest:x0" in line:
answer = "x" * len(answer)
op1val = line.split("op1val")[1].split("x")[1].split(";")[0]
if "-" in line.split("op1val")[1].split("x")[0]: # neg sign handling
op1val = twos_comp(my_config.bits, op1val)
if my_config.op != "fsqrt": # sqrt doesn't have two input vals, unnec here but keeping for later
op2val = line.split("op2val")[1].split("x")[1].strip()
if op2val[-1] == ";": op2val = op2val[:-1] # remove ; if it's there
if "-" in line.split("op2val")[1].split("x")[0]: # neg sign handling
op2val = twos_comp(my_config.bits, op2val)
# go to next test in vector
detected = True
elif "RVTEST_CODE_END" in line:
done = True
# ints don't have flags
flags = "XX"
# put it all together
if not done:
translation = f"{operation}_{ext_bits(op1val)}_{ext_bits(op2val)}_{ext_bits(answer.strip())}_{flags.strip()}_{rounding_mode}"
dest_file.write(translation + "\n")
else:
# print("read false")
reading = False
elif my_config.letter == "M" and my_config.bits == 32:
reading = True
while reading:
# print("trigger 64M")
# get answer from Ref...signature
# answers span two lines and are reversed
answer = src_file2.readline().strip()
# print(f"Answer: {answer}")
#print(answer1,answer2)
if answer != '6f5ca309': # if there is still stuff to read
# parse through .S file
detected = False
done = False
op1val = "0"
op2val = "0"
while not (detected or done):
# print("det1")
line = src_file1.readline()
# print(line)
if "op1val" in line:
# print("det2")
# parse line
# handle special case where destination register is hardwired to zero
if "dest:x0" in line:
answer = "x" * len(answer)
op1val = line.split("op1val")[1].split("x")[1].split(";")[0]
if "-" in line.split("op1val")[1].split("x")[0]: # neg sign handling
op1val = line.split("op1val")[1].split("x")[1].split(";")[0]
if "-" in line.split("op1val")[1].split("x")[0]: # neg sign handling
op1val = twos_comp(my_config.bits, op1val)
if my_config.op != "fsqrt": # sqrt doesn't have two input vals, unnec here but keeping for later
op2val = line.split("op2val")[1].split("x")[1].strip()
if op2val[-1] == ";": op2val = op2val[:-1] # remove ; if it's there
if "-" in line.split("op2val")[1].split("x")[0]: # neg sign handling
op2val = twos_comp(my_config.bits, op2val)
# go to next test in vector
detected = True
elif "RVTEST_CODE_END" in line:
done = True
# ints don't have flags
flags = "XX"
# put it all together
if not done:
translation = f"{operation}_{ext_bits(op1val)}_{ext_bits(op2val)}_{ext_bits(answer.strip())}_{flags.strip()}_{rounding_mode}"
dest_file.write(translation + "\n")
else:
# print("read false")
reading = False
else:
while reading:
# get answer and flags from Ref...signature
answer = src_file2.readline()
#print(answer)
packed = src_file2.readline()[6:]
#print("Packed: ", packed)
if len(packed.strip())>0: # if there is still stuff to read
# print("packed")
# parse through .S file
detected = False
done = False
op1val = "0"
op2val = "0"
while not (detected or done):
# print("det1")
line = src_file1.readline()
# print(line)
if "op1val" in line:
# print("det2")
# parse line
# handle special case where destination register is hardwired to zero
if "dest:x0" in line:
answer = "x" * len(answer)
op1val = line.split("op1val")[1].split("x")[1].split(";")[0]
if "-" in line.split("op1val")[1].split("x")[0]: # neg sign handling
op1val = twos_comp(my_config.bits, op1val)
if my_config.op != "fsqrt": # sqrt doesn't have two input vals
op2val = line.split("op2val")[1].split("x")[1].strip()
if op2val[-1] == ";": op2val = op2val[:-1] # remove ; if it's there
if "-" in line.split("op2val")[1].split("x")[0]: # neg sign handling
op2val = twos_comp(my_config.bits, op2val)
# go to next test in vector
detected = True
elif "RVTEST_CODE_END" in line:
done = True
# rounding mode for float
if not done and (my_config.op == "fsqrt" or my_config.op == "fdiv"):
flags, rounding_mode = unpack_rf(packed)
# put it all together
if not done:
translation = f"{operation}_{ext_bits(op1val)}_{ext_bits(op2val)}_{ext_bits(answer.strip())}_{flags}_{rounding_mode}"
dest_file.write(translation + "\n")
else:
# print("read false")
reading = False
# print("out")
config_list = [ config_list = [
Config(32, "M", "div", "div-", 0), Config(32, "M", "div", "div-", 0),

View File

@ -39,19 +39,15 @@ for vector in div_vectors:
config_list = vector.split(".")[0].split("_") config_list = vector.split(".")[0].split("_")
operation = "1" #float div operation = "1" #float div
rounding_mode = round_dict[str(config_list[2])] rounding_mode = round_dict[str(config_list[2])]
# use name to create our new tv # use name to create our new tv and open vector
dest_file = open(dest_dir + "cvw_" + vector, 'a') with open(dest_dir + "cvw_" + vector, 'a') as dest_file, open(source_dir + vector) as src_file:
# open vector # for each test in the vector
src_file = open(source_dir + vector) for i in src_file.readlines():
# for each test in the vector translation = "" # this stores the test that we are currently working on
for i in src_file.readlines(): [input_1, input_2, answer, flags] = i.split("_") # separate inputs, answer, and flags
translation = "" # this stores the test that we are currently working on # put it all together, strip nec for removing \n on the end of the flags
[input_1, input_2, answer, flags] = i.split("_") # separate inputs, answer, and flags translation = f"{operation}_{ext_bits(input_1)}_{ext_bits(input_2)}_{ext_bits(answer)}_{flags.strip()}_{rounding_mode}"
# put it all together, strip nec for removing \n on the end of the flags dest_file.write(translation + "\n")
translation = f"{operation}_{ext_bits(input_1)}_{ext_bits(input_2)}_{ext_bits(answer)}_{flags.strip()}_{rounding_mode}"
dest_file.write(translation + "\n")
dest_file.close()
src_file.close()
print("creating testfloat sqrt test vectors") print("creating testfloat sqrt test vectors")
@ -64,16 +60,12 @@ for vector in sqrt_vectors:
config_list = vector.split(".")[0].split("_") config_list = vector.split(".")[0].split("_")
operation = "2" #sqrt operation = "2" #sqrt
rounding_mode = round_dict[str(config_list[2])] rounding_mode = round_dict[str(config_list[2])]
# use name to create our new tv # use name to create our new tv and open vector
dest_file = open(dest_dir + "cvw_" + vector, 'a') with open(dest_dir + "cvw_" + vector, 'a') as dest_file, open(source_dir + vector) as src_file:
# open vector # for each test in the vector
src_file = open(source_dir + vector) for i in src_file.readlines():
# for each test in the vector translation = "" # this stores the test that we are currently working on
for i in src_file.readlines(): [input_1, answer, flags] = i.split("_") # separate inputs, answer, and flags
translation = "" # this stores the test that we are currently working on # put it all together, strip nec for removing \n on the end of the flags
[input_1, answer, flags] = i.split("_") # separate inputs, answer, and flags translation = "{}_{}_{}_{}_{}_{}".format(operation, ext_bits(input_1), "X"*32, ext_bits(answer), flags.strip(), rounding_mode)
# put it all together, strip nec for removing \n on the end of the flags dest_file.write(translation + "\n")
translation = "{}_{}_{}_{}_{}_{}".format(operation, ext_bits(input_1), "X"*32, ext_bits(answer), flags.strip(), rounding_mode)
dest_file.write(translation + "\n")
dest_file.close()
src_file.close()