Control Lines
As mentioned in µISA, some control lines are directly influenced by the microcode word, while others are controlled more indirectly.
Note that we make a slight difference between “external” control lines which leave the control unit, and “internal” control lines which only affect the control unit itself.
All external control lines are capitalized and most internal control lines lowercased.
The only exceptions are RESET_UINST_COUNTER and RELOAD_FLAGS.
These control lines are used on the clock and reset module to generate the FLAG/IMM_S input, so they could be considered to be internal as well.
Control lines which are active-low are prefixed with a ~.
Control Word Bits That are Control Lines
These control word bits are the simplest. They directly affect a control line, and do nothing else.
| Bit | Control line | Description | Used by |
|---|---|---|---|
| 5-7 | REG_R_IDX[0:2] | Selects the 16-bit register to read from. | Register file |
| 11 | REG_W_SEL_LO | Encodes which register half(s) to write to. The encoding is further specified by the memory team. | Register file |
| 12 | REG_W_SEL_HI | Encodes which register half(s) to write to. The encoding is further specified by the memory team. | Register file |
| 13 | ~REG_LATCH_LOAD | Loads the value from the 16-bit register selected by REG_R_IDX[0:2] into the address latch. | Address latch |
| 15 | REG_LATCH_UP/~DOWN | Encodes incrementing (high) or decrementing (low) for REG_LATCH_COUNT signals. | Address latch |
| 16 | IO/MEM_FROM_DBUS | Causes a store. | I/O |
| 17 | SPI_SEND/~REC | For sending and receiving data via SPI communication. | I/O |
| 18 | SPI_SCLK_EN | Enables clock of SPI device to make SPI communication possible according to SPI protocol. | I/O |
| 19-21 | ALU_OPERATION[0:2] | Sets the operation for the ALU (like addition/subtraction/...). | ALU |
| 22 | ALU_LATCH_SET | Update latch value on rising clock edge. | ALU |
| 23 | ALU_DBUS_TO_LATCH | Connect latch input to shifter output (low) or bus (high). | ALU |
| 24 | ALU_ACCU_SET | Update accu value (clocked on-board). | ALU |
| 25 | ALU_UPDATE_FLAGS | Update flags according to ALU_UPDATE_JUST_CARRY. | ALU |
| 26 | ALU_UPDATE_JUST_CARRY | Update zero flag, overflow flag and signed flag (clocked on-board) (high) or keep old values (low). | ALU |
| 27 | ALU_USE_SHADOW_CARRY | Use second independent carry flag. | ALU |
| 28 | ALU_FLAGS_SET_RAW | Calculate flags depending on shifter output (low) or set flags register directly from shifter output (high). | ALU |
| 29 | ALU_SHIFT_RIGHT | Right shift. | ALU |
| 30 | ASSERT_LED | Controls the assert LED. Can be used otherwise. | Debugging |
Note that IO/MEM_FROM_DBUS is also used to generate MEM_FROM_DBUS.
Almost-Direct Control Lines
| Bit | Control line | Description | Used by | Note that |
|---|---|---|---|---|
| 14 | REG_LATCH_COUNT | Causes the address latch to increment on the next clock falling edge. | address latch | Only active if the µinstruction counter is enabled |
Control lines controlled by the 4-to-16 decoder
Bits 1 through 4 of the control word are piped through a 4-to-16 decoder (consisting of two 3-to-8 decoders). The decoder will pull all lines high except for the one selected. Bit 4 contains the most significant bit. Some of these outputs are directly fed to control lines, while some cause more functionality in the control unit.
| Input | Control line | Description | Used by |
|---|---|---|---|
0000 | intentionally not connected | Used if no decoder output should be active. | — |
0001 | not connected | — | — |
0010 | ~clear_interrupt_inhibit | Clears the interrupt inhibit flag. | Control |
0011 | ~set_interrupt_inhibit | Sets the interrupt inhibit flag. | Control |
0100 | ~toggle_framebuffer | Selects the other framebuffer. | Control |
0101 | ~toggle_intack | Negates the value stored in the intack latch. | Control |
0110 | ~set_addr16 | Sets the prefix_a16 latch. | Control |
0111 | not connected | — | — |
1000 | ~regular_load | Causes a load. | Control/Memory |
1001 | ~imm_load | Causes a load, always from RAM. | Control/Memory |
1010 | ~REG_LO_TO_DBUS | Emits the LO part of the 16-bit register selected by REG_R_IDX[0:2] to the data bus. | Register file |
1011 | ~REG_HI_TO_DBUS | Emits the HI part of the 16-bit register selected by REG_R_IDX[0:2] to the data bus. | Register file |
1100 | ~ALU_ACCU_TO_DBUS | Moves the data from the accu to the data bus. | ALU |
1101 | ~ALU_FLAGS_TO_DBUS | Moves the data from flags to the data bus. | ALU |
1110 | ~ALU_LATCH_TO_DBUS | Moves the data from the latch to data bus. | ALU |
1111 | ~HLT | Halts the automatic clock. | Control (clock) |
Originally, we planned to pull the data bus down using LEDs.
However, when integrating the ALU into the build, we recognized strange electrical effects, causing the data bus to be in a floating state.
We could solve this issue by adding a bus-transceiver which emits 0x00 to the data bus if no other part emits anything on the data bus.
Hence, the internal control line ~zero_to_dbus is active if none of the following is active:
RESET_UINST_COUNTER, ~regular_load, ~imm_load, ~REG_LO_TO_DBUS, ~REG_HI_TO_DBUS, ~ALU_ACCU_TO_DBUS, ~ALU_FLAGS_TO_DBUS and ~ALU_LATCH_TO_DBUS.
Since most of these control lines are active when the decoder input bit 4 is active, decoding is fairly simple.
Mutually Ignoring Control Lines
There are three pairs of two control lines each where it is never the case that both control lines are actually used. For example, one such control line is REG_W_IDX[0], the other is ~ALU_ZERO_FLAGS_AND, since we never both write to a register and perform an ALU computation that would need to AND the new and old zero flag.
| Bit | Control line | Description | Used by | Not in use when |
|---|---|---|---|---|
| 8-10 | REG_W_IDX[0:2] | Selects the 16-bit register to write to. | Register file | REG_W_SEL_LO and REG_W_SEL_HI are not active |
| 8 | ~ALU_ZERO_FLAGS_AND | If active during a flag update, AND the new zero flag with the previous one (used for 16-bit add/sub). | ALU | ALU_UPDATE_FLAGS is not active |
| 9-10 | ALU_CARRY_SEL[0:1] | Selects which carry the ALU should use. | ALU | The ALU does not do an operation where the carry matters |
Internal Control Lines
| Bit | Control line | Description |
|---|---|---|
| 0 | RESET_UINST_COUNTER | Fetches the next instruction. |
| 31 | RELOAD_FLAGS | Sets the local copy of the flags latch, which is used to determine the microcode address to the actual value of the flags. |
Indirect Control Lines
Several control lines are controlled indirectly, by considering the state of several internal control lines and latch values:
INTACKis the value currently stored in theintacklatch. It is used by IO devices.FB_SELand~FB_SELreflect the value currently stored in thefb_sellatch. It is used by the GPU to select the current framebuffer.INT_MASKEDis the internal control line that is enabled whenRESET_UINST_COUNTERwould trigger an interrupt.IO/MEM_TO_DBUSis active wheneverregular_load,imm_loadorRESET_UINST_COUNTERare active. It is used by IO devices and the main memory.ADDR16is active wheneverprefix_a16stores a 1, and if also (REGULAR_LOADorIO/MEM_FROM_DBUS) are active. It is used by IO devices.~MEM_TO_DBUSis active wheneverIO/MEM_TO_DBUSis active andADDR16is not. It signals a read operation from main memory.~MEM_FROM_DBUSis active wheneverIO/MEM_FROM_DBUSis active andADDR16is not. It signals a write operation to main memory.BUSREQis active for one tick wheneverADDR16is active. During that one tick, the microcode counter is disabled. At the end of that tick,BUSREQbecomes disabled again, and we continue. See here for a timing diagram.
Inputs
INTis an input from IO devices. If it is enabled, then there is an interrupt. On the nextRESET_UINST_COUNTER, it triggers an interrupt iff- the
interrupt_inhibitlatch is not set - the
prefix_a16latch is not set
- the
- The
FLAG_C,FLAG_VandFLAG_Zinputs are from the ALU and yield the current flag status. FLAG/IMM_Sis the sign flag from the ALU afterRESET_UINST_COUNTERand the sign-bit of the immediate afterRELOAD_FLAGS. This signal is generated on the clock board.
µCode Flash Outputs
| Pin(s) | Meaning |
|---|---|
| 0 | RESET_UINST_COUNTER |
| 1:4 | → 4-to-16 decoder |
| 5 | REG_R_IDX0 |
| 6 | REG_R_IDX1 |
| 7 | REG_R_IDX2 |
| 8 | REG_W_IDX0, ~ALU_ZERO_FLAGS_AND |
| 9 | REG_W_IDX1, ALU_CARRY_SEL1 |
| 10 | REG_W_IDX2, ALU_CARRY_SEL0 |
| 11:12 | REG_W_SEL[LO:HI] |
| 13 | ~REG_LATCH_LOAD |
| 14 | → ~REG_LATCH_COUNT |
| 15 | REG_LATCH_DOWN/~UP |
| 16 | IO/MEM_FROM_DBUS |
| 17 | SPI_SEND/~REC |
| 18 | SPI_SCLK_EN |
| 19:21 | ALU_OPERATION[0:2] |
| 22 | ALU_LATCH_SET |
| 23 | ALU_DBUS_TO_LATCH |
| 24 | ALU_ACCU_SET |
| 25 | ALU_UPDATE_FLAGS |
| 26 | ALU_UPDATE_JUST_CARRY |
| 27 | ALU_USE_SHADOW_CARRY |
| 28 | ALU_SET_FLAGS_RAW |
| 29 | ALU_SHIFT_RIGHT |
| 30 | currently used for assertion failed LED |
| 31 | RELOAD_FLAGS |
“→” denotes that there is some further processing of the signals before they are output.
µCode Flash Input (Address)
| Bit | Meaning |
|---|---|
| 0:3 | µinstruction counter |
| 4 | sign flag / immediate sign bit |
| 5 | zero flag |
| 6 | overflow flag |
| 7 | carry flag |
| 8 | interrupt flag |
| 9:16 | opcode |
(0 is the LSB, 16 the MSB)