|
@@ -68,6 +68,7 @@ def usage():
|
|
|
print(" default: Keep project settings (default)")
|
|
|
print(" all: Enable all optimizers")
|
|
|
print(" off: Disable all optimizers")
|
|
|
+ print(" --insn-meas OUTFILE Detailed instruction timing measurements")
|
|
|
print(" -L|--loglevel LVL Set the log level:")
|
|
|
print(" 0: Log nothing")
|
|
|
print(" 1: Log errors")
|
|
@@ -149,23 +150,12 @@ def emitCpuDump(dump):
|
|
|
clearConsole()
|
|
|
writeStdout(dump)
|
|
|
|
|
|
-def emitSpeedDump(cpu):
|
|
|
- dump = "S7 CPU speed: %s stmt/s" % cpu.insnPerSecondHR
|
|
|
- dump += " " * (79 - len(dump))
|
|
|
- writeStdout("\x1B[2J\x1B[H" + dump + "\n")
|
|
|
-
|
|
|
-def cpuDumpCallback(cpu):
|
|
|
+def cpuBlockExitCallback(cpu):
|
|
|
global nextScreenUpdate
|
|
|
if cpu.now >= nextScreenUpdate:
|
|
|
nextScreenUpdate = cpu.now + 0.3
|
|
|
emitCpuDump(str(cpu))
|
|
|
|
|
|
-def cpuStatsCallback(cpu):
|
|
|
- global nextScreenUpdate
|
|
|
- if cpu.now >= nextScreenUpdate:
|
|
|
- nextScreenUpdate = cpu.now + 1.0
|
|
|
- emitSpeedDump(cpu)
|
|
|
-
|
|
|
def assignCpuSpecs(cpuSpecs, projectCpuSpecs):
|
|
|
cpuSpecs.assignFrom(projectCpuSpecs)
|
|
|
if opt_nrAccus is not None:
|
|
@@ -198,6 +188,7 @@ def readInputFile(inputFile):
|
|
|
return project
|
|
|
|
|
|
def run(inputFile):
|
|
|
+ insnMeas = None
|
|
|
s = None
|
|
|
try:
|
|
|
if cython_helper.shouldUseCython():
|
|
@@ -279,11 +270,8 @@ def run(inputFile):
|
|
|
cpu = s.getCPU()
|
|
|
assignCpuSpecs(cpu.getSpecs(), project.getCpuSpecs())
|
|
|
assignCpuConf(cpu.getConf(), project.getCpuConf())
|
|
|
- if not opt_noCpuDump:
|
|
|
- if opt_speedStats:
|
|
|
- cpu.setBlockExitCallback(cpuStatsCallback, cpu)
|
|
|
- elif opt_loglevel >= Logging.LOG_INFO:
|
|
|
- cpu.setBlockExitCallback(cpuDumpCallback, cpu)
|
|
|
+ if not opt_noCpuDump and opt_loglevel >= Logging.LOG_INFO:
|
|
|
+ cpu.setBlockExitCallback(cpuBlockExitCallback, cpu)
|
|
|
|
|
|
# Download the program
|
|
|
printInfo("Initializing CPU...")
|
|
@@ -293,6 +281,10 @@ def run(inputFile):
|
|
|
s.loadLibraryBlock(libSel)
|
|
|
for parseTree in parseTrees:
|
|
|
s.load(parseTree)
|
|
|
+ s.build()
|
|
|
+
|
|
|
+ if opt_insnMeas:
|
|
|
+ insnMeas = cpu.setupInsnMeas()
|
|
|
|
|
|
# Run the program
|
|
|
s.startup()
|
|
@@ -310,7 +302,16 @@ def run(inputFile):
|
|
|
printError(e.getReport())
|
|
|
return ExitCodes.EXIT_ERR_SIM
|
|
|
except KeyboardInterrupt as e:
|
|
|
- pass
|
|
|
+ if insnMeas:
|
|
|
+ if insnMeas.haveAnyMeasurements:
|
|
|
+ if opt_insnMeas == "-":
|
|
|
+ insnMeas.dump()
|
|
|
+ else:
|
|
|
+ with open(opt_insnMeas, "wb") as fd:
|
|
|
+ fd.write(insnMeas.dumpCSV().encode("UTF-8"))
|
|
|
+ else:
|
|
|
+ printError("Instruction timing measurement: Not enough samples.")
|
|
|
+ return ExitCodes.EXIT_ERR_OTHER
|
|
|
except MaintenanceRequest as e:
|
|
|
if e.requestType in (MaintenanceRequest.TYPE_SHUTDOWN,
|
|
|
MaintenanceRequest.TYPE_STOP,
|
|
@@ -513,13 +514,13 @@ def main():
|
|
|
global opt_cycletime
|
|
|
global opt_maxRuntime
|
|
|
global opt_noCpuDump
|
|
|
- global opt_speedStats
|
|
|
global opt_nrAccus
|
|
|
global opt_extInsns
|
|
|
global opt_obtemp
|
|
|
global opt_clockMem
|
|
|
global opt_mnemonics
|
|
|
global opt_optimizers
|
|
|
+ global opt_insnMeas
|
|
|
global opt_hwmods
|
|
|
global opt_hwinfos
|
|
|
global opt_loglevel
|
|
@@ -533,13 +534,13 @@ def main():
|
|
|
opt_cycletime = None
|
|
|
opt_maxRuntime = None
|
|
|
opt_noCpuDump = False
|
|
|
- opt_speedStats = False
|
|
|
opt_nrAccus = None
|
|
|
opt_extInsns = None
|
|
|
opt_obtemp = None
|
|
|
opt_clockMem = None
|
|
|
opt_mnemonics = None
|
|
|
opt_optimizers = "default"
|
|
|
+ opt_insnMeas = None
|
|
|
opt_hwmods = []
|
|
|
opt_hwinfos = []
|
|
|
opt_loglevel = Logging.LOG_INFO
|
|
@@ -552,14 +553,15 @@ def main():
|
|
|
|
|
|
try:
|
|
|
(opts, args) = getopt.getopt(sys.argv[1:],
|
|
|
- "hY:M:24qDSxt:T:m:O:H:I:P:L:cC:bi:R:W:",
|
|
|
+ "hY:M:24qDxt:T:m:O:H:I:P:L:cC:bi:R:W:",
|
|
|
[ "help", "cycle-limit=", "max-runtime=", "twoaccu", "fouraccu",
|
|
|
- "quiet", "no-cpu-dump", "speed-stats", "extended-insns",
|
|
|
+ "quiet", "no-cpu-dump", "extended-insns",
|
|
|
"obtemp=", "clock-mem=", "mnemonics=", "optimizers=",
|
|
|
"hardware=", "hardware-info=", "profile=",
|
|
|
"loglevel=",
|
|
|
"connect", "connect-to=", "spawn-backend", "interpreter=",
|
|
|
- "mem-read=", "mem-write=", ])
|
|
|
+ "mem-read=", "mem-write=",
|
|
|
+ "insn-meas=", ])
|
|
|
except getopt.GetoptError as e:
|
|
|
printError(str(e))
|
|
|
usage()
|
|
@@ -586,8 +588,6 @@ def main():
|
|
|
opt_nrAccus = 4
|
|
|
if o in ("-D", "--no-cpu-dump"):
|
|
|
opt_noCpuDump = True
|
|
|
- if o in ("-S", "--speed-stats"):
|
|
|
- opt_speedStats = True
|
|
|
if o in ("-x", "--extended-insns"):
|
|
|
opt_extInsns = True
|
|
|
if o in ("-t", "--obtemp"):
|
|
@@ -618,6 +618,8 @@ def main():
|
|
|
except (ValueError, IndexError) as e:
|
|
|
printError("-O|--optimizers: Invalid optimization mode")
|
|
|
sys.exit(1)
|
|
|
+ if o == "--insn-meas":
|
|
|
+ opt_insnMeas = v
|
|
|
if o in ("-H", "--hardware"):
|
|
|
try:
|
|
|
v = v.split(':')
|