Struct lc3_ensemble::sim::Simulator
source · pub struct Simulator {
pub mem: MemArray,
pub reg_file: RegFile,
pub pc: u16,
pub frame_stack: FrameStack,
pub instructions_run: u64,
pub observer: ChangeObserver,
pub flags: SimFlags,
pub breakpoints: HashSet<Breakpoint>,
pub device_handler: DeviceHandler,
/* private fields */
}Expand description
Executes assembled code.
Fields§
§mem: MemArrayThe simulator’s memory.
Note that this is held in the heap, as it is too large for the stack.
reg_file: RegFileThe simulator’s register file.
pc: u16The program counter.
frame_stack: FrameStackThe frame stack.
instructions_run: u64The number of instructions successfully run since this Simulator was initialized.
This can be set to 0 to reset the counter.
observer: ChangeObserverTracks changes in simulator state.
flags: SimFlagsConfiguration settings for the simulator.
These are preserved between resets.
See SimFlags for more details on what configuration
settings are available.
breakpoints: HashSet<Breakpoint>Breakpoints for the simulator.
device_handler: DeviceHandlerAll external devices connected to the system (IO and interrupting devices).
Implementations§
source§impl Simulator
impl Simulator
sourcepub fn new(flags: SimFlags) -> Self
pub fn new(flags: SimFlags) -> Self
Creates a new simulator with the provided initializers and with the OS loaded, but without a loaded object file.
sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Resets the simulator.
This resets the state of the Simulator back to before any execution calls,
while preserving configuration and debug state.
Note that this function preserves:
- Flags
- Breakpoints
- External interrupts
- MCR reference (i.e., anything with access to the Simulator’s MCR can still control it)
- IO (however, note that it does not reset IO state, which must be manually reset)
This also does not reload object files. Any object file data has to be reloaded into the Simulator.
sourcepub fn read_mem(&mut self, addr: u16, ctx: MemAccessCtx) -> Result<Word, SimErr>
pub fn read_mem(&mut self, addr: u16, ctx: MemAccessCtx) -> Result<Word, SimErr>
Fallibly reads the word at the provided index, erroring if not possible.
This accepts a MemAccessCtx, that describes the parameters of the memory access.
The simulator provides a default MemAccessCtx under Simulator::default_mem_ctx.
The flags are used as follows:
privileged: if false, this access errors if the address is a memory location outside of the user range.strict: not used forread
Note that this method is used for simulating a read to memory-mapped IO.
If you would like to query the memory’s state, consider using index on MemArray.
sourcepub fn write_mem(
&mut self,
addr: u16,
data: Word,
ctx: MemAccessCtx,
) -> Result<(), SimErr>
pub fn write_mem( &mut self, addr: u16, data: Word, ctx: MemAccessCtx, ) -> Result<(), SimErr>
Fallibly writes the word at the provided index, erroring if not possible.
This accepts a MemAccessCtx, that describes the parameters of the memory access.
The simulator provides a default MemAccessCtx under Simulator::default_mem_ctx.
The flags are used as follows:
privileged: if false, this access errors if the address is a memory location outside of the user range.strict: If true, all accesses that would cause a memory location to be set with uninitialized data causes an error.
Note that this method is used for simulating a write to memory-mapped IO.
If you would like to edit the memory’s state, consider using index_mut on MemArray.
sourcepub fn load_obj_file(&mut self, obj: &ObjectFile)
pub fn load_obj_file(&mut self, obj: &ObjectFile)
Loads an object file into this simulator.
sourcepub fn prefetch_pc(&self) -> u16
pub fn prefetch_pc(&self) -> u16
Gets the value of the prefetch PC.
This function is useful as it returns the location of the currently executing instruction in memory.
sourcepub fn hit_breakpoint(&self) -> bool
pub fn hit_breakpoint(&self) -> bool
Indicates whether the last execution of the simulator hit a breakpoint.
sourcepub fn hit_halt(&self) -> bool
pub fn hit_halt(&self) -> bool
Indicates whether the last execution of the simulator resulted in a HALT successfully occurring.
This is defined as:
HALTbeing executed while virtual HALTs are enabledMCRbeing set tox0000during the execution of the program.
sourcepub fn default_mem_ctx(&self) -> MemAccessCtx
pub fn default_mem_ctx(&self) -> MemAccessCtx
Computes the default memory access context,
which are the default flags to use (see Simulator::read_mem and Simulator::write_mem).
sourcepub fn call_subroutine(&mut self, addr: u16) -> Result<(), SimErr>
pub fn call_subroutine(&mut self, addr: u16) -> Result<(), SimErr>
Calls a subroutine.
This does all the steps for calling a subroutine, namely:
- Setting the PC to the subroutine’s start address
- Setting R7 to the original PC (return address)
- Adding information to the frame stack
sourcepub fn run_while(
&mut self,
tripwire: impl FnMut(&mut Simulator) -> bool,
) -> Result<(), SimErr>
pub fn run_while( &mut self, tripwire: impl FnMut(&mut Simulator) -> bool, ) -> Result<(), SimErr>
Runs until the tripwire condition returns false (or any of the typical breaks occur).
The typical break conditions are:
HALTis executed- the MCR is set to false
- A breakpoint matches
sourcepub fn run(&mut self) -> Result<(), SimErr>
pub fn run(&mut self) -> Result<(), SimErr>
Execute the program.
This blocks until the program ends.
If you would like to limit the maximum number of steps to execute, consider Simulator::run_with_limit.
sourcepub fn run_with_limit(&mut self, max_steps: u64) -> Result<(), SimErr>
pub fn run_with_limit(&mut self, max_steps: u64) -> Result<(), SimErr>
Execute the program with a limit on how many steps to execute.
This blocks until the program ends or until the number of steps to execute has been hit.