123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524 |
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- #
- # AWL simulator - Generate instruction benchmark
- #
- # Copyright 2019 Michael Buesch <m@bues.ch>
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License along
- # with this program; if not, write to the Free Software Foundation, Inc.,
- # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- #
- from __future__ import division, absolute_import, print_function, unicode_literals
- import sys
- import random
- import getopt
- insnCollection = (
- (
- ( "U", "BOOL"),
- ), (
- ( "UN", "BOOL"),
- ), (
- ( "O", "BOOL"),
- ), (
- ( "ON", "BOOL"),
- ), (
- ( "X", "BOOL"),
- ), (
- ( "XN", "BOOL"),
- ), (
- ( "U", "RANDOM_BOOL"),
- ), (
- ( "UN", "RANDOM_BOOL"),
- ), (
- ( "O", "RANDOM_BOOL"),
- ), (
- ( "ON", "RANDOM_BOOL"),
- ), (
- ( "X", "RANDOM_BOOL"),
- ), (
- ( "XN", "RANDOM_BOOL"),
- ), (
- ( "U(", ""),
- ( ")", ""),
- ), (
- ( "UN(", ""),
- ( ")", ""),
- ), (
- ( "O(", ""),
- ( ")", ""),
- ), (
- ( "ON(", ""),
- ( ")", ""),
- ), (
- ( "X(", ""),
- ( ")", ""),
- ), (
- ( "XN(", ""),
- ( ")", ""),
- ), (
- ( "=", "BOOL"),
- ), (
- ( "R", "BOOL"),
- ), (
- ( "S", "BOOL"),
- ), (
- ( "NOT", ""),
- ), (
- ( "SET", ""),
- ), (
- ( "CLR", ""),
- ), (
- ( "SAVE", ""),
- ), (
- ( "FN", "BOOL"),
- ), (
- ( "FP", "BOOL"),
- ), (
- ( "==I", ""),
- ), (
- ( "<>I", ""),
- ), (
- ( ">I", ""),
- ), (
- ( "<I", ""),
- ), (
- ( ">=I", ""),
- ), (
- ( "<=I", ""),
- ), (
- ( "==D", ""),
- ), (
- ( "<>D", ""),
- ), (
- ( ">D", ""),
- ), (
- ( "<D", ""),
- ), (
- ( ">=D", ""),
- ), (
- ( "<=D", ""),
- ), (
- ( "==R", ""),
- ), (
- ( "<>R", ""),
- ), (
- ( ">R", ""),
- ), (
- ( "<R", ""),
- ), (
- ( ">=R", ""),
- ), (
- ( "<=R", ""),
- ), (
- ( "L", "0"),
- ( "BTI", ""),
- ), (
- ( "ITB", ""),
- ), (
- ( "L", "0"),
- ( "BTD", ""),
- ), (
- ( "ITD", ""),
- ), (
- ( "DTB", ""),
- ), (
- ( "DTR", ""),
- ), (
- ( "INVI", ""),
- ), (
- ( "INVD", ""),
- ), (
- ( "NEGI", ""),
- ), (
- ( "NEGD", ""),
- ), (
- ( "NEGR", ""),
- ), (
- ( "TAW", ""),
- ), (
- ( "TAD", ""),
- ), (
- ( "RND", ""),
- ), (
- ( "TRUNC", ""),
- ), (
- ( "RND+", ""),
- ), (
- ( "RND-", ""),
- ), (
- ( "FR", "COUNTER"),
- ), (
- ( "L", "RANDOM_DWORD"),
- ), (
- ( "LC", "WORD"),
- ), (
- ( "ZV", "COUNTER"),
- ), (
- ( "ZR", "COUNTER"),
- ), (
- ( "AUF", "DB"),
- ), (
- ( "TDB", ""),
- ), (
- ( "SPA", "LABEL"),
- ), (
- ( "L", "0"),
- ( "SPL", "LABEL"),
- ), (
- ( "SPB", "LABEL"),
- ), (
- ( "SPBN", "LABEL"),
- ), (
- ( "SPBB", "LABEL"),
- ), (
- ( "SPBNB", "LABEL"),
- ), (
- ( "SPBI", "LABEL"),
- ), (
- ( "SPBIN", "LABEL"),
- ), (
- ( "SPO", "LABEL"),
- ), (
- ( "SPS", "LABEL"),
- ), (
- ( "SPZ", "LABEL"),
- ), (
- ( "SPN", "LABEL"),
- ), (
- ( "SPP", "LABEL"),
- ), (
- ( "SPM", "LABEL"),
- ), (
- ( "SPPZ", "LABEL"),
- ), (
- ( "SPMZ", "LABEL"),
- ), (
- ( "SPU", "LABEL"),
- ), (
- ( "LOOP", "LABEL"),
- ), (
- ( "+I", ""),
- ), (
- ( "-I", ""),
- ), (
- ( "*I", ""),
- ), (
- ( "/I", ""),
- ), (
- ( "+", "0"),
- ), (
- ( "+D", ""),
- ), (
- ( "-D", ""),
- ), (
- ( "*D", ""),
- ), (
- ( "/D", ""),
- ), (
- ( "MOD", ""),
- ), (
- ( "+R", ""),
- ), (
- ( "-R", ""),
- ), (
- ( "*R", ""),
- ), (
- ( "/R", ""),
- ), (
- ( "ABS", ""),
- ), (
- ( "SQR", ""),
- ), (
- ( "SQRT", ""),
- ), (
- ( "EXP", ""),
- ), (
- ( "LN", ""),
- ), (
- ( "SIN", ""),
- ), (
- ( "COS", ""),
- ), (
- ( "TAN", ""),
- ), (
- ( "ASIN", ""),
- ), (
- ( "ACOS", ""),
- ), (
- ( "ATAN", ""),
- ), (
- ( "LAR1", ""),
- ), (
- ( "LAR2", ""),
- ), (
- ( "T", "DWORD"),
- ), (
- ( "TAR", ""),
- ), (
- ( "TAR1", ""),
- ), (
- ( "TAR2", ""),
- ), (
- ( "MCR(", ""),
- ( "MCRA", ""),
- ( "MCRD", ""),
- ( ")MCR", ""),
- ), (
- ( "SSI", ""),
- ), (
- ( "SSD", ""),
- ), (
- ( "SLW", ""),
- ), (
- ( "SRW", ""),
- ), (
- ( "SLD", ""),
- ), (
- ( "SRD", ""),
- ), (
- ( "RLD", ""),
- ), (
- ( "RRD", ""),
- ), (
- ( "RLDA", ""),
- ), (
- ( "RRDA", ""),
- ), (
- ( "L", "0"),
- ( "SI", "TIMER"),
- ), (
- ( "L", "0"),
- ( "SV", "TIMER"),
- ), (
- ( "L", "0"),
- ( "SE", "TIMER"),
- ), (
- ( "L", "0"),
- ( "SS", "TIMER"),
- ), (
- ( "L", "0"),
- ( "SA", "TIMER"),
- ), (
- ( "UW", ""),
- ), (
- ( "OW", ""),
- ), (
- ( "XOW", ""),
- ), (
- ( "UD", ""),
- ), (
- ( "OD", ""),
- ), (
- ( "XOD", ""),
- ), (
- ( "TAK", ""),
- ), (
- ( "PUSH", ""),
- ), (
- ( "POP", ""),
- ), (
- ( "ENT", ""),
- ), (
- ( "LEAVE", ""),
- ), (
- ( "INC", "0"),
- ), (
- ( "DEC", "0"),
- ), (
- ( "+AR1", ""),
- ), (
- ( "+AR2", ""),
- ), (
- ( "BLD", "0"),
- ), (
- ( "NOP", "0"),
- ), (
- ( "CALL", "FC 42"),
- ( "CALL", "FC 42"),
- ( "CALL", "FC 42"),
- ), (
- ( "CALL", "FB 45, DB 45"),
- ( "CALL", "FB 45, DB 45"),
- ( "CALL", "FB 45, DB 45"),
- ), (
- ( "SET", ""),
- ), (
- ( "CC", "FC 43"),
- ), (
- ( "UC", "FC 44"),
- ), (
- # Write some values to the HW module.
- ( "L", "MW 50"),
- ( "+", "1"),
- ( "T", "MW 50"),
- ( "T", "AW 0" )
- )
- )
- def out(data):
- print(data, end="\r\n")
- def error(msg):
- print(msg, file=sys.stderr)
- sys.exit(1)
- def usage(f=sys.stdout):
- print("generate_benchmark.py [OPTIONS]", file=f)
- print("", file=f)
- print(" -s|--seed SEED Set the randomizer seed. Default: 42", file=f)
- print(" -i|--iterations COUNT Set the number of iterations. Default: 10000", file=f)
- print(" -o|--one-cycle Generate CALL SFC 46 at the end of OB 1.", file=f)
- def getLabelName(index):
- if index < 0 or index >= 26 ** 4:
- raise ValueError("Label index out of range.")
- labelChars = [None] * 4
- for i in range(3, -1, -1):
- labelChars[i] = chr(ord("A") + (index % 26))
- index //= 26
- return "".join(labelChars)
- def main():
- opt_nrIterations = 10000
- opt_rngSeed = 42
- opt_oneCycle = False
- try:
- (opts, args) = getopt.getopt(sys.argv[1:],
- "hs:i:o",
- [ "help", "seed=", "iterations=", "one-cycle", ])
- except getopt.GetoptError as e:
- error(str(e))
- for (o, v) in opts:
- if o in ("-h", "--help"):
- usage()
- return 0
- if o in ("-s", "--seed"):
- try:
- opt_rngSeed = int(v)
- if opt_rngSeed < 0 or opt_rngSeed > 0xFFFFFFFF:
- raise ValueError
- except ValueError:
- error("Invalid RNG seed.")
- if o in ("-i", "--iterations"):
- try:
- opt_nrIterations = int(v)
- if opt_nrIterations < 0:
- raise ValueError
- except ValueError:
- error("Invalid number of iterations.")
- if o in ("-o", "--one-cycle"):
- opt_oneCycle = True
- if args:
- usage(f=sys.stderr)
- return 1
- rng = random.Random()
- rng.seed(opt_rngSeed)
- labelIndex = 0
- out("//")
- out("//")
- out("// GENERATED by generate_benchmark.py")
- out("//")
- out("// iterations=%d" % opt_nrIterations)
- out("// seed=%d" % opt_rngSeed)
- out("//")
- out("//")
- out("")
- out("ORGANIZATION_BLOCK OB 1")
- out("BEGIN")
- for i in range(opt_nrIterations):
- for insn, args in rng.choice(insnCollection):
- prefixStr = suffixStr = None
- if args == "":
- argsStr = ""
- elif args == "BOOL":
- argsStr = "M 0.4"
- elif args == "WORD":
- argsStr = "MW 0"
- elif args == "DWORD":
- argsStr = "MD 0"
- elif args == "TIMER":
- argsStr = "T 42"
- elif args == "COUNTER":
- argsStr = "Z 42"
- elif args == "DB":
- argsStr = "DB 42"
- elif args == "LABEL":
- try:
- labelName = getLabelName(labelIndex)
- except ValueError as e:
- error("Failed to generate jump label: %s\n"
- "The generated program is too big." % str(e))
- prefixStr = "\tL 0;\r\n\tCLR;"
- argsStr = labelName
- suffixStr = "%s:\tNOP 0;" % labelName
- labelIndex += 1
- elif args == "RANDOM_BOOL":
- argsStr = "TRUE" if rng.randint(0, 1) else "FALSE"
- elif args == "RANDOM_DWORD":
- argsStr = "DW#16#%08X" % rng.randint(0, 0xFFFFFFFF)
- else:
- argsStr = args
- if prefixStr:
- out(prefixStr)
- if argsStr:
- argsStr = " " + argsStr
- out("\t%s%s;" % (insn, argsStr))
- if suffixStr:
- out(suffixStr)
- if opt_oneCycle:
- out("\tCALL SFC 46 // STOP CPU")
- out("END_ORGANIZATION_BLOCK")
- out("\r\nDATA_BLOCK DB 42")
- out("\tSTRUCT")
- out("\t\tVAR : INT;")
- out("\tEND_STRUCT")
- out("BEGIN")
- out("END_DATA_BLOCK")
- out("\r\nFUNCTION FC 42 : VOID")
- out("BEGIN")
- out("\tBE;")
- out("END_FUNCTION")
- out("\r\nFUNCTION FC 43 : VOID")
- out("BEGIN")
- out("\tBEA")
- out("END_FUNCTION")
- out("\r\nFUNCTION FC 44 : VOID")
- out("BEGIN")
- out("\tSET;")
- out("\tBEB;")
- out("END_FUNCTION")
- out("\r\nFUNCTION_BLOCK FB 45")
- out("BEGIN")
- out("END_FUNCTION_BLOCK")
- out("\r\nDATA_BLOCK DB 45")
- out("\tFB 45")
- out("BEGIN")
- out("END_DATA_BLOCK")
- if __name__ == "__main__":
- sys.exit(main())
|