4 16-bit general-purpose registers r0, r1, r2, r3 ALU2: misc misc add sub addpc and or xor ALU1: inc dec neg comp ALUA: add ALUI: lsl lsr asr rol clr set tog ext 7654_3210 --------- --------- 0000_0000 => HALT: halt 0000_0001 => NOPE: nope 000?_???? => RESERVED 0ooo_aabb => ALU2: a = a op b 1000_aabb => JALR: jalr ra # when a == b 1000_aabb => MOVE: a = b # when a != b 1001_aaoo => ALU1: a = op a 101f_aabb => LDST: a <-> [b] 1100_0000 iiii_iiii => JUMP: jump offset 1101_aabb fiii_iiii => LSI0: a <-> [imm * 2] # a == b 110o_aabb oiii_iiii => BRNC: branch if a op b # when a != b 1110_aa00 iiii_iiii => ALUA: a = a + imm 1110_aa01 oooo_iiii => ALUI: a = a op imm 1110_aa10 iiii_iiii => LDLI: lo(a) = imm 1110_aa11 iiii_iiii => LDUI: hi(a) = imm 1111_aabb wpsi_iiii => MEM2 7654_3210 wps (write | push/pop | size) --------- --------- 1111_aabb 000i_iiii => LDBI 1111_aabb 001i_iiii => LDWI 1111_aabb 100i_iiii => STBI 1111_aabb 101i_iiii => STWI 1111_aabb 010i_iiii => POPB 1111_aabb 011i_iiii => POPW 1111_aabb 110i_iiii => PSHB 1111_aabb 111i_iiii => PSHW Encoding branch conditions: We want: eq/ne, test/testn, lt/gt, ule/ugt We have 2 operand bits, so we can encode eq, test, lt, ult, and get the negations by swapping operands. For example, if aa < bb, then we use eq, and if bb < aa, we use ne. This is natural for lt/gt, and the comparison for eq/ne etc. just needs 1 LUT4. Load/store should use register pairs, and then specific registers numbers can encode whether it should use the larger instructions. Skip is valuable because it lets you implement wider add/sub with a relatively short instruction sequence, in particular this wide add is 4 bytes not 5. For instance, you can do: a1 = a1 + b1 a2 = a2 + b2 branch if b1 ule a1 a2 = a2 + 1 to compute [a2:a1] + [b2:b1]