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:
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.