emulator is a system which can simulate a given general fixed-length encoded ISA,
Here is a working model of the system:
emulator has an internal simulated memory and registers.
it takes configuration of how to evaluate different machine codes, and based on configuration, takes list of machine codes and evaluates each one of them, by changing the memory and registers.
this part describes how the system will change the memory and registers when given a particular machine code.
this sections comprises of multiple modules,
what these modules have in common is that it setups the memory and registers and ways to access them.
There are three modules in the init section
size module decides the size and number of registers and memories
register-alias sets the mapping between register name and bitstrings that will be used to call the corresponding register
one can also add what other alias can be used to call that register.
register-value modules allows one to set the initial values of registers in the emulator.
NOTE: instruction-module, size, register-alias, and register-value needs to be present in a single file
this is the list of bitstrings that is evaluated by the emulator based on instruction-module.
it needs to be present in a separate file.
this module describes how the system will change the state of memory and
registers when given a particular machine code
register-aliasregister-alias sets the mapping between register name and bitstrings that will be used to call the corresponding register one can also add what other alias can be used to call that register.
register-valueregister-value modules allows one to set the initial values of registers in the emulator. NOTE: instruction-module, size, register-alias, and register-value needs to be present in a single file
machine codesthis is the list of bitstrings that is evaluated by the emulator based on instruction-module. it needs to be present in a separate file.
instruction-modulethis module describes how the system will change the state of memory and registers when given a particular machine code
the structure of the instruction-module is defined in the form of pairs of bistring format and exL statements
abstractly, it is defined in the form of
BitStringFormat specifies how a given bitstring should look like or, how different portions of bitstring should look like.
here BitStringFormat can be expanded like
B0 B1 B2 B3
where Bi is bitsring portion specifier i.e. it specifies what a portion of bitstring should have value.more specifically Bi should look like
here ri, ri+1 are non-negative integer, and ri should be greater than equal to ri+1
bits is a bitstring with length ri+1 - ri + 1
model of emulator working on instruction-module:
emulator stores the information from instruction-module into map structure between BitStringFormat and exL statements
emulator takes a machine code, and checks for a match in this structure, a match is successful if all the portions pointed in a BitStringFormat matches with all those portions of the machine code.
for example, [0-3]:1101 [4-5]:11 [8-10]:110 is a match with 110111011101010.
machine code in the portion separated formed 1101.11.01.110.1010
each bit string format can be mapped with one or more exL statements, and last statement ends with a semi-colon ';'.
exL is a language which can be used to give commands to emulator about how to change register/memory states for a given machine code.
exL is composed of combinations.
a combination is a line enclosed in a pair of parenthesis each statement contains at least one space-separated string in it.
e.g. (add PC 1) is a combination
the first string of each combination describes what needs to be done with other members of the combination. First string of each statement can be called operator. All strings other than operator can be called oeprands.
types of data
data for a statement represents operands.
following are the things that an operand can be
3.bitstring portion specifier. i.e. [x-y]
bitstringbitstrings are represented by just a string of 0s and 1s,
e.g. a statement with bitstring operand:
register aliasregister alias are represented by just the name of the register alias,
e.g. a statement with register alias as operand:
bitstring portion specifierbitstring portions are represented by [x-y] where x,y are non-negative integer and y is greater than equal to y.
e.g. a statement with register alias as operand:
internally, each of the above operands gets converted into a bitstring. the type of operand specifies how it will be converted into a bitstring.
for register alias, operand gets converted by using the bitstring mapped with its associated register.
for portion specifier:
one information before describing how portion specifier is converted, every statement is associated with a bitstring which is actually a machine code.
so portion specifier is converted to bitstring by getting the portion of machine code being specified by the portion specifier.
Executionhow a statement will be executed depends on the operator of the statement there are two types of operators:
Non-conditional operatorsThese operators apply same sequence of execution for each of their operands
e.g. statement with non-conditional operator
(add 100 10)
this statement will convert 100 and 10 into integer and add both of them and returns the result as binary string. These operators can be added/removed or modified in the operator.cc file.
These operators execute one of the third, fourth operand selectively based on
the value of the first operand.
if the first operand evaluates to 1, then third operand will be executed else
fourth operand will be executed.
e.g. (if [0-0] (add PC 1) (add PC 110))
Each statement returns a string, some statement returns an empty string, other
returns a bitstring, so this return value of a statement can be used as oeprand
for another statement.
e.g. (add PC (xor 1101001 [4-7]))
statement, with xor operator will be first executed, and then the operand in the parent statement will be replaced with the result of the xor statement.