TTA processor. Part 1

Foreword


The idea of ​​creating my own simple processor, if I may call it that, I fired up for a long time. The choice of architecture is an ambiguous matter, but being partly minimalist, I wanted to implement something simple, at the same time powerful and expandable, TTA was perfect for this.
Part 1.
Part 2.
In short, the idea is that the control unit would have only one data movement command, and the calculations would be a by-product of these movements.

I will bring it to life in a simple program for compiling and simulating logical and electrical circuits - Logisim , chose it because of its simplicity and accessibility, in case of successful implementation, it is planned to rewrite to Verilog .

When reading it is better to touch the project right away, it can be found at the end of the article.

Control block


The control unit is the main component. For simplicity, it was decided to choose 16 inputs and 16 outputs, as a result, the command received in the control unit is 8-bit, the first half of which points to one of the inputs, the other to one of the outputs. In order for the receiving block to understand that the data has come to it, 1 bit is added to each input from the block, it is customary to call these blocks functional blocks.

So:



Memory


In order for the control unit to execute the program, it must be stored somewhere, the memory will be a functional unit, one of the outputs that will be connected to the control unit bus.

So:


The lowest input is a clock signal, the leftmost one is input data, the rightmost one is output data, they are also BU commands and the last one is the one that serves as a flag, reporting data arrival. When data is received, it is written to the counter, which indicates the current command, with each clock pulse, the counter increases, and the control unit transfers data from one FU to another.

Other simple fu


Create simple FUs that will perform commonplace addition and subtraction actions.
The FU template looks like this: at the input there are 8-bit registers according to the number of inputs, writing to them is carried out upon receipt of data. The output may also contain the registers in which the answer will be stored, but this is not necessary for the adder.

Thus, the adder and subtracter will look like this:



Finished device


Let's connect the memory and the control unit, and after that we will try to create a new control unit and write a program.
The button will act as a clock signal.

So the connection:


Now connect the adder and subtracter, as well as two input constants:


Everything is ready to write a program, it will perform a banal sequence of actions: add one to the previous value of the adder, and then go to the beginning by means of a relative transition (for this, a subtractor was made: 3).

Let's write a program.

Initially, all the registers are reset, so there is no point in doing it, the first command is to send a unit to one of the adder's input (In3 -> O2), send the adder's output to its second input (In1 -> O1), send the current memory address to the subtractor input (In0 -> O3), sending the address change to another input of the subtractor, it will be subtracted (In4 -> O4), after the subtractor goes to the input of the address pointer, thereby completing the transition (In2 -> O0).

The program looks like this:

1. In3 -> O2
2. In1 -> O1
3. In0 -> O3
4. In4 -> O4
5. In2 -> O0

In memory:


That's all. This program is working properly. I plan to make more FUs and make their connection with the control unit more convenient, by the way FUs are practically ControlFlow devices. You can also connect several control units together, that is, create a network of such devices.

Thank you for the attention!

GitHub

All Articles