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:
INTACK
is the value currently stored in theintack
latch. It is used by IO devices.FB_SEL
and~FB_SEL
reflect the value currently stored in thefb_sel
latch. It is used by the GPU to select the current framebuffer.INT_MASKED
is the internal control line that is enabled whenRESET_UINST_COUNTER
would trigger an interrupt.IO/MEM_TO_DBUS
is active wheneverregular_load
,imm_load
orRESET_UINST_COUNTER
are active. It is used by IO devices and the main memory.ADDR16
is active wheneverprefix_a16
stores a 1, and if also (REGULAR_LOAD
orIO/MEM_FROM_DBUS
) are active. It is used by IO devices.~MEM_TO_DBUS
is active wheneverIO/MEM_TO_DBUS
is active andADDR16
is not. It signals a read operation from main memory.~MEM_FROM_DBUS
is active wheneverIO/MEM_FROM_DBUS
is active andADDR16
is not. It signals a write operation to main memory.BUSREQ
is active for one tick wheneverADDR16
is active. During that one tick, the microcode counter is disabled. At the end of that tick,BUSREQ
becomes disabled again, and we continue. See here for a timing diagram.
Inputs
INT
is 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_inhibit
latch is not set - the
prefix_a16
latch is not set
- the
- The
FLAG_C
,FLAG_V
andFLAG_Z
inputs are from the ALU and yield the current flag status. FLAG/IMM_S
is the sign flag from the ALU afterRESET_UINST_COUNTER
and 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)