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.