TTA programs do not define the operations, but only the data transports needed to write and read the operand values. Operation itself is triggered by writing data to a triggering operand of an operation. Thus, an operation is executed as a side effect of the triggering data transport. Therefore, executing an addition operation in TTA requires three data transport definitions, also called moves. A move defines endpoints for a data transport taking place in a transport bus. For instance, a move can state that a data transport from function unit F, port 1, to register file R, register index 2, should take place in bus B1. In case there are multiple buses in the target processor, each bus can be utilized in parallel in the same clock cycle. Thus, it is possible to exploit data transport level parallelism by scheduling several data transports in the same instruction.
An addition operation can be executed in a TTA processor as follows:
r1 -> ALU.operand1 r2 -> ALU.add.trigger ALU.result -> r3
The second move, a write to the second operand of the function unit called ALU, triggers the addition operation. This makes the result of addition available in the output port 'result' after the execution latency of the 'add'.
The ports associated with the ALU may act as an accumulator, allowing creation of macro instructions that abstract away the underlying TTA:
lda r1 ; "load ALU": move value to ALU operand 1 add r2 ; add: move value to add trigger sta r3 ; "store ALU": move value from ALU result
They also link to the Copper Co-processor, but that has 3 instructions. In addition, the above shows how you can create the 3 "macro instructions" from the "move" instruction, so it sort of moves away from a more detailed explanation of the move instruction and how it can be used in a OISC.
The other wiki page also states:
A transport triggered architecture uses only the move instruction, hence it was originally called a "move machine". This instruction moves the contents of one memory location to another memory location combining with the current content of the new location:
move a to b ; Mem[b] := Mem[a] (+, -, *, /, ...) Mem[b]
So from all this I understand that basically the
move instruction moves data from one place in memory to another. The memory are the "register files" (which I'm not sure exactly what they are), and this is done by reading and writing from the "transport bus". But already there there are 2 operations (read and write), so I'm confused how this is only actually 1 instruction (a OISC). In addition, I don't see exactly how those
r1 -> ALU.operand1 3 "steps" are actually just 1 operation each, I would like to know a little more on what's actually happening.
This looks like it could help, so will take a look here as well.
3.2.1 Reading and Writing
The sequential TTA code of the program generated by the front-end is read by the back-end and transformed into an internal representation. The following definitions define the elements of this representation:
Definition 3.1 A program P describes the behavior of an application. It consists of a set of procedures.
Definition 3.2 A procedure P is a code abstraction element of a program. Each procedure implements a specific task. Each procedure consists of a set of basic blocks.
Definition 3.3 A basic block b is a sequence of consecutive instructions in which the flow of control always enters at the beginning and always leaves at the end. A basic block consists of a set of operations.
Definition 3.4 An operation o describes the computation to be performed on an FU. An operation consists of a set of moves.
Definition 3.5 A move m describes data transports between hardware components.
Seeing diagrams such as this make me wonder what the Function Units (FU) are implemented as, as it seems the MOVE instruction would then be delegating to either software or hardware defined "circuits" and thus not really be a true OISC, just hiding all the more-than-one instruction operations inside an FU.
After looking through this, it sounds like a Function Unit (FU) implements all the "primary" logic, and so hides implementation detail. So you can have an "ADD" FU, and that is some complex circuit. Would like to know if I am understanding this part correctly. My question then would be if the single MOVE instruction could be used to create all the Function Units, or if not, why not.
In looking through some papers on Transport Triggered Architectures (TTA), I've noticed they are calling it an OISC (One-Instruction Set Computer), even though the Function Units (FU) might implement complex logic outside of the TTA. This means to me it's not really a OISC. It's like saying that x86 is a OISC if you just think of all operations as being of the form
APPLY name, arg1, arg2, arg3. So I'm wondering if there are any examples of creating the FU components using the TTA, so that it would really be a one instruction set architecture. Or if not, why not, I'd be wondering then what you can't model or implement just using the MOVE instruction. But this is just tangential..
The main question is, given all logic gates can be assembled from NAND gates, if the Functional Units (FU) in a TTA can be built using the TTA itself, starting with implementing a NAND gate in the TTA directly somehow.