Abstract Structure¶
Architecture¶
The main component of an ISA implementation is the Architecture
class. During simulation initialisation, a reference to an instance of the modelled architecture is passed to the model. It is later queried to determine how various components should be initialised, and supports components in performing architecture-specific operations during simulation.
Architectures are expected to support querying the following information:
The architectural register structure: the number of discrete types of registers, and the size and quantity of registers of each type.
The initial state of the architectural registers and process memory at the time the simulation begins.
Any updates to the state of the architectural registers and process memory throughout the simulation.
Pre-Decoding¶
The primary role of the Architecture
class is to enable the conversion of arbitrary bytes of instruction memory into Instruction
objects capable of performing operations. This process is referred to as pre-decoding, as it is responsible for grouping bytes into “macro ops” representing individual machine-code instructions, which in real hardware would be decoded later into one or more instructions (“micro-ops”). In SimEng, all the decoding is expected to be performed up-front: the generated macro-op is simply a vector of micro-ops. First, the macro-op is decoded and then, using an architecture-specific decoder, micro-ops are generated that replace the macro-op where necessary.
Exception Handling¶
Architecture implementations must be capable of generating an Exception Handler when presented with an instruction that has encountered an exception. To facilitate this, the architecture will be presented with references to the core model and process memory interface in use.
State changing¶
As stated, the Architecture
class is expected to support queries for the initial and updated architectural/memory state. These queries are detailed within a ProcessStateChange
structure which contains:
- ChangeType
The type of changes to be applied with the available options being REPLACEMENT, INCREMENT, and DECREMENT.
- modifiedRegisters
The registers to be modified.
- modifiedRegisterValues
The values to modify the defined registers with. How these registers are modified is dictated by the ChangeType.
- memoryAddresses
The memory addresses to be written to.
- memoryAddressValues
The values to be written to the defined memory addresses. Note the ChangeType for memory modifications is currently limited to REPLACEMENT only.
Instructions¶
As different ISAs typically define a unique set of instructions, it is expected that each architecture implementation will also supply a custom Instruction implementation. Instances of these instructions will be created during the pre-decode process performed by the main Architecture
instance, and will be responsible for modelling the correct behaviour of that individual instruction.
Exception Handler¶
For handling exceptions, SimEng provides an abstract ExceptionHandler
class. Instances of ExceptionHandler
should be generated by an Architecture
instance upon request, by supplying the exception-generating instruction, a reference to the core model, and a reference to the process memory interface. As the details of exception handling vary between architecture, each supported architecture is expected to supply its own custom ExceptionHandler
implementation.
Ticking¶
Exception handlers provide a tick
function, which may be called to process the exception it represents. Upon completing each tick, the exception handler will state whether or not further ticks are required, for example, to wait for a memory request to complete. If the exception requires further processing, the model will continue to tick it each cycle until completed.
Results¶
When the exception has been fully processed, the results may be retrieved from the handler to supply the following information:
Whether the exception was fatal
The address that execution should resume from
Any modifications to registers or process memory
If the exception is fatal, the core model will halt and the simulation will gracefully terminate with printed reasoning for termination. If not fatal, the supplied process state modifications, through a ProcessStateChange
structure, will be applied and process execution will resume from the specified instruction address.