Clock & Instruction Cycles
The execution of all operations are split into phases called instruction cycles. The various types of instructions have a varying number of instruction cycles.
Each instruction cycle takes at least two clock cycles to complete.
Instruction Fetch Cycle
The first Instruction Cycle is the Instruction Fetch Cycle. During this cycle one or two words are fetched from memory, depending on the addressing mode.
The first clock cycle always reads the actual instruction into the control logic, where it will be decoded until the end of the Fetch Cycle.
A fast logic within the decoder decides whether or not the instruction needs an address/data read into the CPU for Direct Addressing, local addressing or absolute addressing, allowing it to be fetched during the second clock cycle.
Data Transfer Cycle
The Data Transfer Cycle is needed to transfer data either between registers, between external memory and registers or between registers, external memory and the ALU.
For data transfer operations, the actual Data Transfer Cycle takes a single clock cycle, but for timing consistency uses the full Instruction Cycle.
For operations using the ALU, the first clock cycle sees the transfer from a register into the ALU A register, while the second clock cycle sees the transfer of data from either another register or from external memory to the ALU B register.
Of the data transfer is purely internal, meaning that it does not involve the external bus, the control logic sets the DMA Enable signal, allowing the DMA controller to use it.
Execution Cycle
Only operations that utilise she ALU, Arithmetic Logical Operations and Branch Operations use the Execution Cycle.
During the first clock cycle of the Execution Cycle, the ALU executes to operation, while the second as cycle writes the result back I to a register, or, in the base of the branches, the control logic decides on the next step.
In some other operations this Institution Cycle is used for other means (see Instruction Set).
During this Instruction Cycle the DMA Enable line is set.
Jump Cycle
The Jump Cycle is used purely by branch and jump operations, to modify the Program Counter, loading it with either internal data from an Index Register or from external memory.
For Branch Operations, it includes waiting for the result of the comparison inside the ALU, while loading the jump address to a helper register in the control logic that is, depending on the result of the comparison, combined with or replaces the Program Counter.
The only operation that breaks the timing constraints of the Instruction Cycle length is the RTI
operation, as a return from an interrupt routine involves at least sixteen stack operations to repopulate the registers. Even if one stack operation takes a single clock cycle, the operation will take more then 16 clock cycles/8 Instruction Cycles.
Program Counter
Usually, it should be possible to simply increment the Program Counter at the end of the Instruction Fetch Cycle.
Other Operations
Among the other operations, the NOP
operation takes two Instruction Cycles, during which it does nothing, takings as much time as a data transfer operation.
However there are two instructions that take a dynamic length of Instruction and Clock Cycles, WAIT
and DMA
, where the CPU waits for an interrupt from an external device or the DMA controller, which can take a variable time. During the operation of this instruction, the ring counter inside the control logic is disabled
Conclusion
With this rather strict timing protocol of the Instructions Set, it is questionable if microcode is even necessary. Everything can easily be done by conventional logic, though there will be use cases for GAL16V8 and GAL20V10 programmable logic, for speed reasons alone.
OpCode Design
With the Instruction Cycles decided upon, it is now possible to take a closer look at the Instruction Set to begin working out some limited information to decide on the OpCodes. This is to simplify instruction decoding as much as possible.
Data Transfer Operations
All Data Transfer Operations can be executed in two Instruction Cycles, namely the Instruction Fetch Cycle and the Data Transfer Cycle.
The Data Transfer Operations can be separated into operations that either interact with memory or the single one that only deals with registers.
The memory addressing operations can then be separated into operations that move data I to our out of memory.
This makes OpCode design simple, as the operations only have two main switches.
- Bits 5 and 4 are identifying the operation as Data Transfer Operation.
- Bit 3 identifies the
MOV
operation. - Bit 2 identifies the direction of the data transfer, with
0
for a transfer from memory and1
for a transfer into memory. - Bit 1 identifies if the Operation involves the Stack (
1
) or not (0
). - Bit 0 is alway
1
.
Arithmetic Logic Operation
All Arithmetic Logic Operations are executed in three Instruction Cycles, namely the Instruction Fetch Cycle, the Data Transfer Cycle and the Execution Cycle.
The only actually useful and needed distinction between these operations is whether or not the operation has one or two operands. Since there are seven operations with two operands and nine with only one operand, it is not an equal split, but it is workable. In this case NOT
is selected to be the exception for the selection, as it only affects the Data Transfer Cycle of the operation.
Every other conversion must be made within the ALU for operation selection, as it simplifies wiring between control logic and ALU.
But even then, some bit masking should be used.
- Bits 5 and 4 are identifying the operation as a Arithmetic Logical Operation.
- Bit 3 identifies, broadly, the number of operands with
1
for a single operand and0
for two operands. - Bit 3 also identifies, together with Bits 2, 1 and 0 the operation to the ALU.
Control Operations
All Branch Operations are executed in three Instruction Cycles, depending on the result of the operation. These are the Instruction Fetch Cycle, the Data Transfer Cycle and the Jump Cycle.
All Jump Operations, except RTI, are executed in two Instruction Cycles, namely the Instruction Fetch Cycle and the Jump Cycle. RTI has an extended Jump Cycle, to transfer the contents of the registers before an interrupt from the Stack to the registers.
With just nine operations and five of them being Branch Operations and four being pure Jump Operations, it is again easy to set some switch bits.
One easy switch is to separate the branch and jump operations, with a second one being for a separation between two and three operand, respective one and no operand operations.
- Bits 5 and 4 are responsible to identify the Control Operations.
- Bit 3 is used to distinguish between Branch (1) and Jump (
0
) Operations. - Bit 2 is responsible to select between two (
0
) and three (1
), respective one and no operands/addresses. - Bits 1 and 0 are used to identify the operation.
Other Operations
Technically, all operations collected here have just two Instruction Cycles, namely the Instruction Fetch Cycle and the Execution Cycle. However, for WAIT
and DMA
, the Execution Cycles are extended, as it is not known when an Interrupt occurs, or when the DMA controller releases the bus. As such, both operations stop the ring counter used in the control logic.
With the low number of instructions it’s easy to separate them from each other.
INCO/DECO
are selected by a 1
in the Stack bit, while WAIT/DMA
are selected by a 1 in the Wait bit. NOP
simply sets all bits to 1
.
- Bits 5 to 4 are responsible for identify the other operations
- Bit 3 is always set to
0
. - Bit 2 is set to
1
if the operation is a Stack Operation. - Bit 1 is set to
1
if the operation is a Wait Operation. - Bit 0 is used to identify the operation.