![]() |
![]() |
![]() |
![]() |
The core of any simulator is the process of interpreting the bits that make up a machine instruction, deciding what that instruction is and executing some code that simulates the function. Simulators essentially are comprised of a big loop that interprets each instruction in turn and gives some feedback of the state of the machine to the user.
The simplest form of instruction simulation uses a switch statement to match the bit pattern of the instruction to a few lines of code to simulate the function. Though compilers can dramatically improve the execution of a switch statement, the basic behaviour is 'Is it this instruction? No.. Is it this instruction? No..' and so on until a match is found. In C we can explicity do what a compiler might do for us, making the whole process more efficient by using a lookup table.
The lookup table matches an instruction against a function that will simulate it. The code simply has to lookup the function for a given instruction and call it. Unfortunately this is not possible in Java, because we don't have the equivalent of function pointers and can't produce an lookup table as we would in C.
However, there is a neat solution. We can represent an instruction as an object that knows how to simulate itself. Instead of a table that allows us to lookup functions, we have a table that allows us to lookup Instruction objects. We can then just ask the relevant Instruction to 'simulate yourself' and we have quickly called the right code.
miSim DE uses exactly this approach. An abstract class 'Instruction' provides all the common things that an instruction needs to know about and do. For each of the different processor instructions, we can then extend that class and implement the missing 'simulate yourself' method that will be specific to that instruction.
As the PIC® MCU uses a Harvard Architecture, our simulation job is easy. The machine cannot change the code that it runs, so we can read the program, transform it into an array of Instructions and we are then ready to simulate the processor. To run the simulation, we start at the beginning of the array, ask the first Instruction to simulate itself, then the next, then the next and so on..
We get some things 'for free' from this approach. With a few simple additions, an instruction can know what it looks like to a programmer (its Mnemonic), how to display itself in a listing and even how to build itself from source code. Our Instruction class can then do more than simulate the processor, it can act as a disassembler and an assembler. Suddenly we have a complete development environment.
Supported Processors
miSim DE is designed to be able to support different
processors both for simulation and assembly. With the release of version 2.0,
this is reflected in full support for both the PIC16x5x range of 12-bit devices
from Microchip Technology Inc. and their 14-bit range, in particular the 16x8x
devices. Support for a processor range means that the assembler can identify
those devices and create correctly assembled opcodes from the appropriate
mnemonics. In addition, simulation will work for 'raw code' (that is, code that
does not make use of the particular device's peripheral features). Specific
support for a particular device may add partial or complete implementation
of that device's peripheral features.
This list shows the devices supported in the 2.0 release - it is set to expand as more devices and their peripherals are implemented.
The original PIC 16x8x devices are simulated:
16f83, 16cr83
16c84, 16f84, 16cr84
In addition, these processors are supported, though not all
peripheral devices are simulated
- the most significant of these ommisions are noted below:
16f873, 16f876 - No Analog, PWM, Serial I/O
16f874, 16f877 - No Analog, PWM, Serial I/O, Port D/E
The Watchdog timer is also simulated for 16x8x devices.
The MCU Reset hardware is not simulated.
![]() |
![]() |