Skip to content

Pulse2 processor

ishanpm edited this page Jan 27, 2019 · 10 revisions

The Pulse2 processor is a very small and basic processor unit, with a bounding box of only 298*248. On its own, it is not very powerful, but it can be tiled to create much more advanced logic. To start the processor, place a state 15 cell on the 2-cell wide area near the upper left.

Architecture

Instruction ROM

The ROM is the simplest part of the processor. It consists of the ROM itself and an instruction pointer accumulator. The first six bits of an incoming signal are added to the accumulator, and the resulting value is sent. A switch at the lower left controls whether the value is sent to the data bus or the instruction decoder.

Instruction decoder

The instruction decoder consists of the instruction register, an instruction table, and some other circuitry. Instructions are first held in the instruction register at the right. Signals flow through the instruction table, re-routed based on the state of the first 4 bits. The six conditional jump instructions are all handled by the circuit on top of the table.

The wires leading into the instruction table, from right to left, are as follows:

  • > Instruction pointer add
  • > Instruction pointer increment
  • < Init
  • > Read R1
  • < Read R1 result
  • > Write R2
  • < Write R2 finished
  • > Add to A
  • > Subtract from A
  • > Negate A
  • > Swap A and B
  • > Compare A with zero
  • < Arith. result / finished

Data bus

The data bus communicates between the instruction decoder and the various registers. Destinations are set based on the R1 and R2 values, and reads and writes are then performed. In order to allow arithmetic operations to work, the target is immediately set back to 0100 (A register) after any read or write.

Registers and Arithmetic register

There are four 16-bit registers, aptly named A, B, C, and D. The A register is special, because it can perform arithmetic commands using an accumulator. It is actually two parts, an input sub-register and the arithmetic register itself. The low-level operations of the accumulator are orchestrated by the microcode table in the upper left, which performs up to 4 micro-operations for a single command. For example, SUB is performed by inverting the register, adding the input, inverting the register again, then sending a spark to indicate success. The A register can also swap its contents with the B register by using the input sub-register as temporary storage.

IO ports

The processor is equipped with four IO ports, one for each side. Each one is only half of a proper IO port, since it only contains an output register. When connected to another IO port, the connection is completed and writes can be performed.

Machine language

The processor has 64 16-bit words of instruction memory, which wrap around when the program counter reaches the end. All instructions are 1 word long (unless they use an immediate value), and use the same fields, each 4 bits long:

Opcode - (ignored) - R1 - R2

Each word of instruction memory is represented as a column in the lookup table, with the least significant bit at the top. A positive bit is indicated by a single yellow (state 14) cell at the bottom of the two-cell gap. Instructions are executed from left to right.

Opcodes

Op 0x 0b Behavior
MOV 0 0000 Writes the value of R1 to R2
SWP 1 0001 Swaps the values of the A and B registers
ADD 4 0100 Adds R1 to the A register
SUB 5 0101 Subtracts R1 from the A register
NEG 6 0110 Negates the A register
JGZ 9 1001 Reads from R1 and jumps if A > zero
JEZ a 1010 Reads from R1 and jumps if A = zero
JGEZ b 1011 Reads from R1 and jumps if A >= zero
JLZ c 1100 Reads from R1 and jumps if A < zero
JNZ d 1101 Reads from R1 and jumps if A != zero
JLEZ e 1110 Reads from R1 and jumps if A <= zero
JMP f 1111 Performs a relative jump by the value of R1

Addressing modes

Name 0x 0b Behavior
IMM 0 0000 Reads the next word of program memory
0 1 0001 Returns 0
1 2 0010 Returns 1
-1 3 0011 Returns -1 (0xffff)
A 4 0100 Read/write A register
B 5 0101 Read/write B register
C 6 0110 Read/write C register
D 7 0111 Read/write D register
UP 8 1000 Read/write top IO
LEFT 9 1001 Read/write left IO
DOWN a 1010 Read/write bottom IO
RIGHT b 1011 Read/write right IO

Attempting to write to IMM or any of the constant modes will discard the value with no side effects.

The numbers -1, 0, and 1 can be expressed either as a constant mode or using immediate addressing. To disambiguate the two in assembly code, and to mark which instructions take up two words, all numbers encoded with immediate addressing will be preceded with a #.

IO ports block on read and write, waiting until the adjacent node does the opposite. If both nodes attempt to read or write, they will deadlock.

Modes 1100 and 1101 were originally meant to correspond to TIS-100's ANY and LAST, but this behavior has not been implemented.

Jumps

All jumps are relative jumps. For example, JMP 0 (0xf010 or 0b1111 0000 0001 0000) will put the processor in an infinite loop. If a jump uses an immediate value, then the jump is relative to the value, not the instruction itself. This means that JMP -1 would be an infinite loop if it used immediate addressing (JMP #-1, 0xf000 ffff) but would jump to the last instruction if it used the -1 constant (JMP -1, 0xf030). The value for a relative jump can also be provided by a register or IO.

There are six conditional relative jump instructions. The 2nd, 3rd, and 4th bits determine whether A should be less than, equal to, or greater than zero for the jump to be performed. The input value is always read, but is discarded if the condition does not match.

Example

This script writes 1 to the right output five times, then attempts to read from the right input:

MOV #5 A    ; 0004 0005
MOV 1 RIGHT ; 002b
SUB 1       ; 5020
JGZ #-3     ; 9000 fffd
MOV RIGHT 0 ; 00b1

To advance the write requests manually, place a state 15 cell on the lowest wire on the right IO port.

Other units

A few other devices can use the same IO ports that the processors do. No extra instructions are required to support them. The IO standard allows parts to passively check whether a read or write is waiting, although the processor itself ignores these signals.

RAM

The RAM node can store 16 bit values with 7 address bits, giving 128 words of memory. In order to communicate over a single port, it has an address mode and a data mode. To save space, the data is saved in timed loops. Read and write operations are synchronized to internal clocks to ensure data is completely read and written.

Action Behavior
Write (address mode) Set current address, switch to data mode
Write (data mode) Write to selected value, switch to address mode
Read Return selected value, switch to address mode

Decimal display

The decimal display node displays unsigned 16-bit integers. It uses the double-dabble algorithm to convert incoming binary numbers to BCD, then sends the BCD digits into some lookup tables for display. Since the algorithm expects numbers in big-endian, but the processor uses little-endian numbers, the numbers are copied to a temporary shift register to be reversed. The IO ports used are modified to access the other port's write buffer without actually performing a read operation.