Author |
Message |
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22729 Location: Silicon Valley
|
Some draft architecture of ternary machine that may be built practically, designed by me 3 years ago (Dec 2004):
Ternary computer TRINITY will have data bus with width 3 trits (triad). Every trit can be in one of 3 state: N (-1), O (0), P (+1). 1 triad can be in one of 27 states: from NNN (-13) to PPP (+13).
TRINITY will have linear memory where address bus will have width 9 trits (in current prototype I plan to use only 8 trits - highest trit will be always 0). Memory itself will be regular "binary" chips (2 bits per 1 trit), because ternary memory is not yet available and it's almost impossible to create one "manually" using "flip-flap-flops". Address space is divided to 3 parts: -3280...-1094: space for peripheral devices (ternary or binary); -1093...+1093: space for ROM with basic system program; +1094...+3280: space for RAM with user program/data.
There are 9 directly available registers: -4 Dn: triad from memory by address DPn (see below); -3 Do: triad from memory by address DPo (see below); -2 Dp: triad from memory by address DPp (see below); -1 F: flag register (ASF-AccumulatorSignFlag, DPF-DataPointerFlag, BCF-BorrowCarryFlag); 0 A: accumulator register; +1 B: auxiliary register; +2 Dl: lower triad of data pointer; +3 Dm: middle triad of data pointer; +4 Dh: higher triad of data pointer. Data pointer actually is set of 3 9-trits data pointer register, available through Dl/Dm/Dh and multiplexed by flag DPF and we may name that 9-trit registers DPn, DPo, DPp. Register PC (program counter) is not available directly.
Command set has 3 groups of commands: load register A from other register (P??), save register A to other register (N??) and other commands (O??): ONN - SLA: shift register A to the left through flag BCF; ONO - ADD: add A with B and BCF, save result to A and BCF; ONP - SRA: shift register A to the right through flag BCF: OON - LAN #: load A by immediate triad; OOO - ADN #: add A with immediate triad and BCF, save result to A and BCF; OOP - OPA #: unary "tritwise" operation over register A (function set by immediate triad); OPN - LDP # # #: load to current data pointer (D2 D1 D0) immediate 3 triads; OPO - JMP # # #: jump to address set by immediate 3 triads (put it ot register PC: Pl Pm Ph); OPP - OPB # # #: binary "tritwise" operation over registers A and B, save result to A (function set by 3 immediate triads). Flag ASF always has sign (-1, 0, +1) of accumulator A value. Command of loading register A is written as LAr (P??), where r is name of source register. Command of saving regster A is written as SAr (N??), where r is name of destination register. You can see that we have couple of nonsense commands there (SAA - save A to A and LAA - load A from A). Instead of it on the same opcodes we will have 2 new ones: POO - LPD: load PC from D (Pl=Dl, Pm=Dm, Ph=Dh); NOO - SPD: save PC to D (Dl=Pl, Dm=Pm, Dh=Ph).
|
29 Dec 2007 14:41 |
|
|
eudoxie
Maniac
Joined: 17 Sep 2012 13:36 Posts: 277 Location: 81.170.128.52
|
Interesting architecture...
|
29 Dec 2007 15:43 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22729 Location: Silicon Valley
|
Design has a few problems, but I didn't have enough time to fix it...
|
29 Dec 2007 22:27 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22729 Location: Silicon Valley
|
Implementation of ternary conditional branch:
|
29 Dec 2007 22:34 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22729 Location: Silicon Valley
|
Call subroutine with saving return address in 9-trit register DPo (available in 3-trit registers Dl/Dm/Dh if DPF=O):
Return from subprogram to address saved in DPo:
Full return stack implementation is much more heavy...
|
29 Dec 2007 22:46 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22729 Location: Silicon Valley
|
Some words about universal operations OPA and OPB:
Operation OPA #ttt may describe ANY unary "tritwise" operation over accumulator A. For example:
OPA #OOO means set A to 0 (N -> O, O -> O, P -> O);
OPA #PON means ternary inversion or negation (N -> P, O -> O, P -> N);
OPA #OPN means "Shift Up" (N -> O, O -> P, P -> N);
OPA #NOP means "No Operation" (N -> N, O -> O, P -> P).
Operation OPB Tn To Tp may describe ANY binary "tritwise" operation over accumulator A and auxiliary register B. Rule for every trit in A: if trit value in register B is N then choose Tn, if trit value in register B is O then choose To, if trit value in register B is P then choose Tp, then use chosen triad as for OPA operation (lower trit for N, middle trit for O, higher trit for P). For example, using OPB for masking of flag BCF in F:
After that BCF will keep its value, but other trits will set to N.
|
29 Dec 2007 23:06 |
|
|
eudoxie
Maniac
Joined: 17 Sep 2012 13:36 Posts: 277 Location: 81.170.128.52
|
It's a bit claustrophobic, with the small data units. You can't store very much information with only 27 states, and storing in several data units creates overhead; which would be a problem in general purpose applications.
Though, I can imagine special purpose applications, like signal processing, where this sort of machine could be very useful.
|
30 Dec 2007 08:19 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22729 Location: Silicon Valley
|
Yes, it's kind of minimalistic, but main idea is ability almost for everyone to build this machine at home
|
30 Dec 2007 10:15 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22729 Location: Silicon Valley
|
I simply translated it in English from my Russian message from Dec 2004. No time to check correctness... Lets use stack of return addresses with depth 9 (27 triads). Stack pointer will move from xxx xxx PPP to xxx xxx NNN (only Dl changed). Stack pointer may be DPp, so first initialization is 7 triads: Call subroutine macro (47 triads): Return from subroutine macro (40 triads):
|
30 Dec 2007 10:43 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22729 Location: Silicon Valley
|
I have an idea about renaming registers to do names 1-character:
-4 N: triad from memory addressed by DPn (see below);
-3 O: triad from memory addressed by DPo (see below);
-2 P: triad from memory addressed by DPp (see below);
-1 F: flag register (see below);
0 A: accumulator register;
+1 B: auxiliary register;
+2 L: lower triad of current DP register (see below);
+3 M: middle triad of current DP register (see below);
+4 H: higher triad of current DP register (see below);
Register F is set of 3 flags:
Higher trit: ASF (Accumulator Sign Flag)
Middle trit: DPF (Data Pointer Flag)
Lower trit: BCF (Borrow Carry Flag)
There are 3 9-trit DP (data pointer) registers - DPn, DPo, DPp, available through L/M/H when flag DPF has corresponding value (N, O, P).
To separate meanings of P and PC we need to rename opcodes #POO and #NOO to LPCD and SPCD respectively. We need to rename opcodes #ONN and #ONP to RLA and RRA respectively ('R'otate instead of 'S'hift). Also we need to rename opcodes #OON, #OOO and #OPN to LAI, ADI and LDI respectively ('I'mmediate).
So full set of opcodes is:
#NNN (-13) SAN - save register A to register N;
#NNO (-12) SAO - save register A to register O;
#NNP (-11) SAP - save register A to register P;
#NON (-10) SAF - save register A to register F;
#NOO (-9) SPCD - save PC (program counter) to current data pointer;
#NOP (-8) SAB - save register A to register B;
#NPN (-7) SAL - save register A to register L (lower triade of current data pointer);
#NPO (-6) SAM - save register A to register M (middle triade of current data pointer);
#NPP (-5) SAH - save register A to register H (higher triade of current data pointer);
#ONN (-4) RLA - rotate register A to the left through flag BCF;
#ONO (-3) ADD - add register A with B and flag BCF, save result to A and BCF;
#ONP (-2) RRA - rotate register A to the right through flag BCF;
#OON (-1) LAI # - load register A from immediate triad;
#OOO (0) ADI # - add register A with immediate triad and flag BCF, save result to A and BCF;
#OOP (1) OPA # - perform unary "tritwise" operation over register A (function set by immediate triad);
#OPN (2) LDI # # # - load current data pointer by immediate 3 triads (lower, middle, higher);
#OPO (3) JMP # # # - jump to address set by immediate 3 triads (put it to register PC: lower, middle, higher);
#OPP (4) OPB # # # - perform binary "tritwise" operation over registers A and B, save result to A (function set by immediate 3 triad);
#PNN (5) LAN - load register A from register N;
#PNO (6) LAO - load register A from register O;
#PNP (7) LAP - load register A from register P;
#PON (8) LAF - load register A from register F;
#POO (9) LPCD - load PC (program counter) from current data pointer;
#POP (10) LAB - load register A from register B;
#PPN (11) LAL - load register A from register L (lower triad of current data pointer);
#PPO (12) LAM - load register A from register M (middle triad of current data pointer);
#PPP (13) LAH - load register A from register H (higher triad of current data pointer);
Last edited by Shaos on 20 Sep 2012 20:43, edited 1 time in total.
|
30 Dec 2007 17:06 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22729 Location: Silicon Valley
|
Lets name this instruction set as "TRINITY-2004" (year of design) It can be used as microcode for next generation of TRINITY processor! 1 trit - 3 values (N,O,P or -1,0,+1); 1 triad (3 trits) - 27 values; 1 tryte (6 trits, 2 triads) - 729 values; 1 tradr (9 trits, 3 triads) - 19 683 values; 1 trord (12 trits, 4 triads, 2 trytes) - 531 441 values; 1 truadr (18 trits, 6 triads, 3 trytes, 2 tradrs) - 387 420 489 values; 1 truble (24 trits, 8 triads, 4 trytes, 2 trords) - 282 429 536 481 values; New words "tradr" and "trord" mean "ternary address" and "ternary word" respectively New words "truadr" and "truble" mean "double ternary address" and "double ternary word" respectively P.S. And "tribble" must be 2 trits (3 tribbles = 1 tryte)
|
09 Jan 2008 06:35 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22729 Location: Silicon Valley
|
Another idea to rename "triad" (half of tryte) to "tribble" (like nibble that is half of byte)
|
10 Jan 2008 18:40 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22729 Location: Silicon Valley
|
Idea about representation of floating point numbers: Lets take "truble" and divide it to 2 parts: 6-trit exponent and 18-trit fraction. By accuracy it is better than 32-bit "float", worse than 64-bit "double" and similar to 36-bit floating number in IBM System/360 from 1964 that had 9-bit sign and exponent and 27-bit fraction. Because of nature of balanced ternary numeric system we don't need "biasing" exponent. Also we don't need separate sign bit - we simply combine it with "hidden" most significant bit of fraction instead and it will be part of full 18-trit fraction. So range of exponent is from -364 to +364 (3^6/2) and fraction from -193710244 to +193710244 (3^18/2 that is max possible integer represented by this floating point format). To simplify formula for calculation number from representation we may simply forget about "fractional" nature of fraction and say F*3^E
P.S. here ^ means "power"
|
16 Jan 2008 20:18 |
|
|
Mac Buster
Retired
Joined: 03 Aug 2003 22:37 Posts: 1474 Location: Moscow
|
So, let's take the representation as a basic representation of fractional numbers for ternary platform.
|
19 Jan 2008 04:07 |
|
|
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22729 Location: Silicon Valley
|
Right now I think that ability to compare normalized floating point numbers as integers is good and to have it we should do "fraction" really fractional (-1 < F < 1): (F*3^18)*3^E = F*3^(18+E). In this case for example to do float from integer 193710244 (PPPPPPPPPPPPPPPPPP) we have to add exponent +18 (OOPNOO): OOPNOOPPPPPPPPPPPPPPPPPP (here fraction is O.PPPPPPPPPPPPPPPPPP). Also to represent 0.5 we will use OOOOOOPPPPPPPPPPPPPPPPPP (error is 0.00000000258).
P.S. But in case of integer "fraction" described in my previous post we still can use normalization as shifting to the left and comparison "normalized" floating point numbers as regular integers...
Last edited by Shaos on 20 Sep 2012 20:43, edited 1 time in total.
|
19 Jan 2008 15:41 |
|
|