Close

Simulating ternary in VHDL

A project log for Homebrew ternary computer

TRIADOR: The only ternary computer made for real in the past 50 years.

shaosSHAOS 07/02/2018 at 03:550 Comments

So, now we will show you how to use balanced ternary in VHDL (tested in Xilinx ISE v9.2i on CPLD CoolRunner-II). Similarly to Logisim approach when 2 "binary" wires were used to simulate 1 "ternary" wire we can define new VHDL type to handle ternary and call it "FakeTrit" that will be BIT_VECTOR with 2 wires in it - VHDL package built around this approach may look like this:

PACKAGE ternary IS

        SUBTYPE FakeTrit is BIT_VECTOR (1 downto 0);
        SUBTYPE FakeTriad is BIT_VECTOR (5 downto 0);
        SUBTYPE FakeTriadWithParity is BIT_VECTOR (7 downto 0);

        CONSTANT O : FakeTrit := "00";
        CONSTANT P : FakeTrit := "01";
        CONSTANT N : FakeTrit := "10";
        CONSTANT X : FakeTrit := "11";

        FUNCTION buf(T: FakeTrit) RETURN FakeTrit;
        FUNCTION inv(T: FakeTrit) RETURN FakeTrit;
        FUNCTION mux(T_C: FakeTrit; T_N: FakeTrit; T_O: FakeTrit; T_P: FakeTrit) RETURN FakeTrit;
        FUNCTION e12(T_C: FakeTrit; T_N: FakeTrit; T_P: FakeTrit) RETURN FakeTrit;
        FUNCTION e21(T_C: FakeTrit; T_N: FakeTrit; T_P: FakeTrit) RETURN FakeTrit;

END PACKAGE ternary;

PACKAGE BODY ternary IS

        FUNCTION buf(T: FakeTrit) RETURN FakeTrit IS
        begin
                case T is
                when N =>
                        return N;
                when O =>
                        return O;
                when P =>
                        return P;
                when others =>
                        return X;
                end case;
        end;

        FUNCTION inv(T: FakeTrit) RETURN FakeTrit IS
        begin
                case T is
                when N =>
                        return P;
                when O =>
                        return O;
                when P =>
                        return N;
                when others =>
                        return X;
                end case;
        end;

          FUNCTION mux(T_C: FakeTrit; T_N: FakeTrit; T_O: FakeTrit; T_P: FakeTrit) RETURN FakeTrit IS
          begin
                case T_C is
                when N =>
                        return T_N;
                when O =>
                        return T_O;
                when P =>
                        return T_P;
                when others => 
                        return X;
                end case;      
          end;

        FUNCTION e12(T_C: FakeTrit; T_N: FakeTrit; T_P: FakeTrit) RETURN FakeTrit IS
        begin
                case T_C is
                when N =>
                        return T_N;
                when O =>
                        return T_P;
                when P =>
                        return T_P;
                when others =>
                        return X;
                end case;
        end;

        FUNCTION e21(T_C: FakeTrit; T_N: FakeTrit; T_P: FakeTrit) RETURN FakeTrit IS
        begin
                case T_C is
                when N =>
                        return T_N;
                when O =>
                        return T_N;
                when P =>
                        return T_P;
                when others =>
                        return X;
                end case;
        end;

END ternary;

4th state X (11) might be used as an exception to detect error during simulation.

Now we can implement ternary half-adder (see example in previous log) in VHDL:

use ternary.all;

entity main is
    Port ( a : in FakeTrit;
           b : in FakeTrit;
           c : out FakeTrit;
           s : out FakeTrit
          );
end main;

architecture Behavioral of main is
signal r1,r2,r3,r4,r5,r6 : FakeTrit;
begin
process (a,b)
begin
    r1 <= mux(a,P,N,O);
    r2 <= mux(a,O,P,N);
    r3 <= mux(b,r1,a,r2);
    r4 <= e12(a,N,O);
    r5 <= e21(a,O,P);
    r6 <= mux(b,r4,O,r5);
    s <= r3;
    c <= r6;
end process;
end Behavioral;

It takes 4 macrocells (out of 256) of Xilinx CPLD CoolRunner-II XC2C256/144 (or 2%).


All results of activity around this could be found on GitLab: 

https://gitlab.com/ternary/ternary/tree/master/vhdl

Discussions