1 / 33

Cesare Di Mauro PyCon X – Florence May 2019

Ternary CPUs: how they work and how Python helps designing one. Cesare Di Mauro PyCon X – Florence May 2019. In the beginning it was… binary!. Computers use a binary numeral system ( two symbols ). Two symbols that may represent: 0, 1 False, True Off, On -, +. Numbers: 1100100 2

allender
Download Presentation

Cesare Di Mauro PyCon X – Florence May 2019

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Ternary CPUs: how they work and how Python helps designing one Cesare Di Mauro PyCon X – Florence May 2019 Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  2. In the beginning it was… binary! Computers use a binary numeral system (two symbols) • Two symbols that may represent: • 0, 1 • False, True • Off, On • -, + Numbers: 11001002 1·26 + 1·25 + 0·24 + 0·23 + 1·22 + 0·21 + 0·20 6410 + 3210 + 410 + 210 10010 Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  3. Information in base-2 Commonly defined conventions Bit: one binary digit 0 or 1, False or True, etc. 3 bits: one octal digit 0002 = 08 = 010, …, 1112 = 78 = 010 4 bits: one nibble one hex (hexadecimal) digit 00002 = 016 = 010, …, 11112 = F8 = 1510 8 bits: one byte 000000002 = 010, …, 111111112 = 25510 Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  4. Integers in base-2 Signed numbers: two’s complement 10010 = 011001002 -10010 = 100111002 8 bits: one byte unsigned: 0..255 signed: -128..127 16 bits: two bytes unsigned: 0..65535 signed: -32768..32767 32 bits: four bytes unsigned: 0..4294967295 signed: -2147483648..2147483647 Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  5. Now it’s ternary time! A ternary numeral system uses three symbols • Three symbols may represent: • 0, 1, 2 • -1, 0, 1 • -, 0, + • False, True, Unknown Numbers: 102013 1·34 + 0·33 + 2·32 + 0·31 + 1·30 8110 + 1810 + 110 10010 Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  6. Encoding information in base-3 Three symbols = one ternary digit = one trit 0 or 1 or 2, -1 or 0 or 1, - or 0 or +, etc. Three symbols ≠ +50% over two symbols (base-2)! Encoded information = = 1.5849625… bits Example: two trits = 32 = 9 symbols vs three bits = 23 = 8 symbols Two trits ≠ three bits: we have one more symbol available! Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  7. Signed numbers in base-3* Trit: one ternary digit 0 or 1 or 2, -1 or 0 or 1, - or 0 or +, etc. 3 trits: one tribble 33 == 27 symbols Balanced Ternary: -, 0, and + are shortcuts for -1, 0, and +1. Example: -0+ = (-1)·32 + 0·31 + 1·30 = -9 + 1 = -8 *http://homepage.divms.uiowa.edu/~jones/ternary/numbers.shtml Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  8. Defining the “Tribble” Same as base-2: defining conventions 3 trits: one tribble 33 = 27 symbols 0003 = 010, …, 2223 = 2610 From Hexadecimal (base-16) to Heptavintimal (base-27) 0123456789ABCDEFGHKMNPRTVXZ* Heptavintimal “pack” more information when representing ternary numbers/data; similar to hexadecimal vs binary. Example: 20 trits are represented by 7 tribbles (hept digits). *http://homepage.divms.uiowa.edu/~jones/ternary/hept.shtml Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  9. Defining the “Tryte” Possible choices for the byte equivalent: 5, 6, or 9 trits. 5 trits: -13 symbols* losing some information unsigned: 0..242 signed: -121..121 6 trits: +473 symbols* much more information unsigned: 0..728 signed: -364..364 9 trits: +19427 symbols* way more information! unsigned: 0..19682 signed: -9841..9841 My personal choice: 1 tryte = 5 trits. Closely matches a byte. *Compared to one byte Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  10. Integers in base-3 5 trits: one tryte unsigned: 0..242 signed: -121..121 Reference: ±10010 10 trits: two trytes unsigned: 0..59048 signed: -29524..29524 Reference: ±10,00010 20 trits: four trytes unsigned: 0..3486784400 signed: -1743392200..1743392200 Reference: ±1,000,000,00010 Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  11. Floating points in base-3 fp20 1 tryte for exponent  -121..121 (in base-3! Wider range) 3 trytes for mantissa & sign  6-7 decimal digits* 20-trits float in base-3 ≈ 32-bit float in base-2 fp40 7 trits for exponent  -1093..1093 (in base-3! Wider range) 33 trits for mantissa & sign  15-16 decimal digits* 40-trits float in base-3 ≈ 64-bit float in base-2 *A bit less information is available, due to a slightly small mantissa range, and the sign which is encoded into the mantissa. Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  12. The 3ISA – Ternary Architecture Like almost all modern ISAs: it’s a N-RISC* Not-Reduced Instruction Set Architecture (more CISC-like) • Many instructions (and room for more) • Not only “simple” instructions (even multi-cycles ones) • Variable-length opcodes • 2 trytes minimum (10 trits. Then 15, 20, 25, etc.) • Base ISA is fixed-length: 4 trytes (20 trits) • Load & store • Feature-complete: “integer” (scalar), FPU, vector/SIMD • *https://www2.eecs.berkeley.edu/Pubs/TechRpts/1982/CSD-82-106.pdf Pag.2 “Design goals for RISC I” Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  13. The 3ISA opcodes structure Compact opcodes (Integer) 2 trytes (10 trits) 3 trytes (15 trits) Standard/base opcodes (Integer, FPU)  Implemented 4 trytes (20 trits) Vector (SIMD with masks. Like Intel’s AVX-512) opcodes 5 trytes (25 trits) Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  14. General specs • 27 General purpose registers R0..R26. • R0 fixed to zero (not writable  fault raised). • R1 used as a stack pointer (PUSH/POP instructions). • R26 used as link register (CALL instructions). • GP registers are either 20 or 40 trits (4 or 8 trytes). • 1 PC (Program Counter) register (20 or 40 trits). • 1 F (Flags) register (20 or 40 trits). User-mode. • Note: the architecture is little-endian (LSTrit/Tryte first). Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  15. Float and vector registers • 27 FPU & Vector registers F0..F26 or V0..V26. • Shared (e.g.: F0 = lower part of V0). • 10, 20, 40, or 80 trits FPU registers (depending on the supported maximum floating point precision). • Roughly equivalent to fp16, fp32, fp64, fp128 in base-2. • Minimum vector registers size = maximum FPU registers size. • Maximum vector size depends on specific implementation (e.g. ISA is variable-length & length-agnostic). Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  16. Instructions groups • Quaternary (3 sources, 1 destination)* • Ternary (2 sources, 1 destination)* • Binary (1 source, 1 destination)* • Unary (1 source or destination) • User mode & privilege mode • Calls (jump & link using R26) • Conditional jumps (up to 27 conditions), cmp regs & jump • Load & Store (one address mode: base reg + offset) • Loads with immediate. Load immediate from PC • *Support quick immediate as the last source Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  17. Ternary (diadic) instructions Most are common: Arithmetic  ADD, ADDC, SUB, SUBC Shift/rotate  SHL, SHR, SAR, ROL, ROR, RCL, RCR Logical ones are quite different*: TMIN  Ternary AND, TMAX  Ternary OR TANTIMIN  Ternary Antimin (NAND) TANTIMAX  Ternary Antimax (NOR) TXOR  Ternary XOR New ones*: TSUM, TANY, TEQUAL, TCONS *http://homepage.divms.uiowa.edu/~jones/ternary/logic.shtml Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  18. Binary (monadic) instructions Some are common: MOV, CMP, TEST Logical ones (NOT, specifically) are quite different*: STI  Standard Ternary Inverter NTI  Negative Ternary Inverter PTI  Positive Ternary Inverter New ones*: ISUNK  Is Unknown, ISFALSE  Is False, ISTRUE  Is True SHIFTD  Shift Down, SHIFTU  Shift Up ROTD  Rotate Down, ROTU  Rotate Up SWAPN  Swap Negative, SWAPP  Swap Positive *http://homepage.divms.uiowa.edu/~jones/ternary/logic.shtml Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  19. The 3ISA assembler specs • Supports: • all 3ISA (integer) instructions • directives (ORG, EQU, SET, PRINT) • labels and local labels (e.g. internal to subroutines) • comments • data constant & storage definition • expressions with classic unary (+, -, ~) and binary (<<, >>, &, !, ^, *, /, %, +, -, =, <, >, <>, <=, >=) operators • decimal, binary, octal, hexadecimal literals • single quoted and double quoted strings Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  20. 3ISA assembly example • L2NextEQU l2 + 4PRINTL2NextL2SizeSET L2 - Labelcmpjs r14,r26,L2loadl r2,-(@5-2+2*5)loadh r2,$Dloadpc r2,%100 load5 r3,[r4,13] store5 r3,[r4,-81] loadu5 r3,[r4,243]DC.T 'A'L0DC.T 1, $f, 'A'DS.L 5 • StartORG 12.LocalLabel:PRINT.LocalLabelPRINT *add r1,r2,r3; Commentmov r1,r2cmp r1,r2 call r1add r1,r2,-4mov r1,-4cmp r1,-4Label: call l2 call r13,13L2jz Label Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  21. Building the assembler: ANTLR • ANTLR (ANother Tool for Language Recognition) • https://www.antlr.org • Parser generator for: • lexer • (language) syntax parser • AST (Abstract Syntax Tree)  Tree walker • A single grammar for all parsers! • Parsers generated for several languages (Python included) Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  22. The ANTLR grammar for 3ISA • grammarasm3isa;options{language= Python2; // Generated code for Python.}module // This is the main/start rule.: (line? NEWLINE)+;line: directive| compound_instruction| standalone_label| standalone_comment;standalone_label: label ':’; • comment: ~NEWLINE*;standalone_comment: ('*' | ';') comment;label: SYMBOL {self.define_label($SYMBOL)}; // Embedded Python code. Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  23. ANTLRWorks2: an ANTLR tool ANTLRWorks2 is an IDE to help develop ANTLR grammars http://tunnelvisionlabs.com/products/demo/antlrworks It can generate syntax diagrams for rules Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  24. The generated object file The object file: a pure sequence of trits?!? Representing trits on a binary system: -  002 0  012 +  102 Space wasted (e.g.: 112 not used): 1 trit 2 bits. 1 tryte  10 bits. Object file  sequence of bytes Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  25. Testing assembler and emulator • Assembler testing goals: • Check ternary (the expected one) • Check stdout (expected) • Emulator testing goals: • Initialize the emulator state • Check conditions all times (invariants) • Check final state (post-conditions) • Assembler and emulator goals: • Same assembly code for assembler and emulator • More complex test scenarios Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  26. Beautiful testing with Python class TernaryTests(BaseTest):@expected_ternary('++----0+00+-000---++')@expected_output('')@init(r2=2, r3=3)@postconditions(r2=2, r3=3, exception=WriteToR0)def test_write_to_r0(self):"""add r0,r2,r3"""@expected_ternary('++----0+00+-00+---++')@init(r2=2, r3=3)@invariants(r2=2, r3=3)@postconditions(r1=5, r2=2, r3=3, pc=4, f=9)def test_add(self):"""add r1,r2,r3""" No code: “just” simple, explicit, readable declarations… Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  27. How the trick works • @expected_ternary('++----0+00+-000---++')@expected_output('') • @init(r2=2, r3=3)@invariants(r2=2, r3=3)@postconditions(r1=5, r2=2, r3=3, pc=4, f=9) • Decorators collect all requirements • args or kwargs are stored in test method • Requirements used & checked by “test executor” @postconditions(r2=2, r3=3, exception=WriteToR0) Exceptions can be trapped and checked Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  28. Reusing standard Python features • class TernaryTests(BaseTest):def test_add(self):"""add r1,r2,r3""" Doc string  3ISA assembly source code Doc string is compiled and used (run) by “test executor” class EmulatorTests(BaseTest):@postconditions()deftest_init(self):assertlen(self.emulator.memory) == 0, "The emulator memoryisnotempty!" Method code  extra, more complex, conditions Method code is executed by “test executor” after emulator execution and post-condition checks. Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  29. Testing framework limits • Emulator’s memory status not yet testable on invariants and post-conditions checks. • Assembler should be run as separate process (and killed on timeout) to avoid deadlocks (e.g.: compilation never completes). • Same issue for emulator (e.g: never-ending loops). • Invariants checks totally own emulator’s single-step execution. Single-step cannot be used/tested by per-se • Assembler’s stderr not intercepted/collected and checked. Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  30. Conclusion • PROs • Better code density 20 trits≈ 32 bits for opcodes • Better data density5/10/20 trits≈ 8/16/32 bits for data • Much less wiring (and chip area)* • Better power consumption • CONs • Effort to convert/adapt existing software • New encodings needed (e.g.: ASCII, UTF-8, RGB, etc.) • Interfacing with existing binary world • Possible lower frequencies reached for chips (3 states) • * http://homepage.divms.uiowa.edu/~jones/ternary/ Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  31. Bibliography / references The Ternary Manifesto by Douglas W. Jones THE UNIVERSITY OF IOWA Department of Computer Science http://homepage.divms.uiowa.edu/~jones/ternary/ Ternary Computer System Project By Claudio La Rosa (thanks for involving me!) http://www.ternary-computing.com https://www.facebook.com/Ternary-Computer-System-1959288864198262/ Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  32. The first ternary computer board Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

  33. Q&A Cesare Di Mauro – PyCon X Ternary CPUs: how they work and how Python helps designing one

More Related