|
1 |
| -# 9-level logic |
2 |
| -@parameters X |
3 |
| - |
4 |
| -logicmap = Dict(0 => 0, |
5 |
| - 1 => 1, |
6 |
| - :U => 2, # Uninitialized |
7 |
| - :X => 3, # Unknown |
8 |
| - :Z => 4, # High Impedence |
9 |
| - :W => 5, # Weak Unknown |
10 |
| - :L => 6, # Weak Low |
11 |
| - :H => 7, # Weak High |
12 |
| - :D => 8) # Don't Care; standard representation is `-` |
13 |
| - |
14 |
| -logic(l) = |
15 |
| - try |
16 |
| - logicmap[l] |
17 |
| - catch |
18 |
| - (ex) |
19 |
| - X |
| 1 | +struct LogicTable{N} <: AbstractArray{Logic, N} |
| 2 | + logic::Array{Logic, N} |
| 3 | + function LogicTable(l::Array{Logic}) |
| 4 | + any(i -> i != 9, size(l)) && |
| 5 | + throw(ArgumentError("Incorrect number of logic values are passed. A variable of type |
| 6 | +`LogicTable` must have nine entries corresponding to 9 logic levels")) |
| 7 | + new{ndims(l)}(l) |
20 | 8 | end
|
| 9 | +end |
| 10 | + |
| 11 | +Base.size(l::LogicTable) = size(l.logic) |
21 | 12 |
|
22 |
| -# SISO NOT gate |
23 |
| -NotTable = OffsetArray([ |
24 |
| - # 0 1 :U :X :Z :W :L :H :D |
25 |
| - 1; 0; :U; :X; :X; :X; 1; 0; :X], 0:8) |
| 13 | +Base.axes(l::LogicTable) = axes(l.logic) |
26 | 14 |
|
27 |
| -function _not(x) |
28 |
| - i = logic(x) |
29 |
| - typeof(i) != Int && return X |
30 |
| - NotTable[i] |
| 15 | +getindex(s::LogicTable, l::Logic) = getindex(s.logic, get_logic_level(l)) |
| 16 | +function Base.getindex(s::LogicTable, i1::Logic, i2::Logic) |
| 17 | + getindex(s.logic, get_logic_level(i1), get_logic_level(i2)) |
| 18 | +end |
| 19 | +function Base.getindex(s::LogicTable, i1::Logic, i2::Logic, |
| 20 | + I::Logic...) |
| 21 | + getindex(s.logic, get_logic_level(i1), get_logic_level(i2), get_logic_level(I...)...) |
| 22 | +end |
| 23 | + |
| 24 | +getindex(s::LogicTable, l::Int) = getindex(s.logic, l) |
| 25 | +function getindex(s::LogicTable, i1::Int, i2::Int, I::Int...) |
| 26 | + getindex(s.logic, i1, i2, I...) |
31 | 27 | end
|
32 |
| -@register_symbolic _not(x) |
33 | 28 |
|
34 |
| -# MISO AND gate |
35 |
| -AndTable = OffsetArray([ |
36 |
| - # 0 1 :U :X :Z :W :L :H :D |
37 |
| - 0 0 0 0 0 0 0 0 0 # 0 |
38 |
| - 0 1 :U :X :X :X 0 1 :X # 1 |
39 |
| - 0 :U :U :U :U :U 0 :U :U # :U |
40 |
| - 0 :X :U :X :X :X 0 :X :X # :X |
41 |
| - 0 :X :U :X :X :X 0 :X :X # :Z |
42 |
| - 0 1 :U :X :X :X 0 :X :X # :W |
43 |
| - 0 0 0 0 0 0 0 0 0 # :L |
44 |
| - 0 1 :U :X :X :X 0 1 :X # :H |
45 |
| - 0 :X :U :X :X :X 0 :X :X], 0:8, 0:8) |
46 |
| - |
47 |
| -function _and2(a, b) |
48 |
| - i, j = logic(a), logic(b) |
49 |
| - (typeof(i) != Int || typeof(j) != Int) && return X |
50 |
| - AndTable[i, j] |
| 29 | +function Base.setindex!(A::LogicTable, x::Logic, i1::Int) |
| 30 | + setindex!(A.logic, x, i1) |
51 | 31 | end
|
| 32 | +function Base.setindex!(A::LogicTable, x::Logic, i1::Int, i2::Int, I::Int...) |
| 33 | + setindex!(A.logic, x, i1, i2, I...) |
| 34 | +end |
| 35 | + |
| 36 | +get_logic_level(l::LogicTable) = Int.(l.logic) |
| 37 | + |
| 38 | +# AND gate |
| 39 | +const AndTable = LogicTable([ |
| 40 | + # U X F0 F1 Z W L H DC |
| 41 | + U U F0 U U U F0 U U # U |
| 42 | + U X F0 X X X F0 X X # X |
| 43 | + F0 F0 F0 F0 F0 F0 F0 F0 F0 # F0 |
| 44 | + U X F0 F1 X X F0 F1 X # F1 |
| 45 | + U X F0 X X X F0 X X # Z |
| 46 | + U X F0 X X X F0 X X # W |
| 47 | + F0 F0 F0 F0 F0 F0 F0 F0 F0 # L |
| 48 | + U X F0 F1 X X F0 F1 X # H |
| 49 | + U X F0 X X X F0 X X]) # DC |
| 50 | + |
| 51 | +function _and2(a::Logic, b::Logic) |
| 52 | + AndTable[a, b] |
| 53 | +end |
| 54 | +_and2(a::Number, b::Logic) = _and2(convert(Logic, a), b) |
| 55 | +_and2(a::Logic, b::Number) = _and2(a, convert(Logic, b)) |
| 56 | +_and2(a::Number, b::Number) = _and2(convert(Logic, a), convert(Logic, b)) |
| 57 | + |
52 | 58 | function _and(x...)
|
53 |
| - y = [_and2(x[1], x[1])] |
54 |
| - for i in 2:length(x) |
55 |
| - push!(y, _and2(x[i], y[i - 1])) |
| 59 | + y = x[1] |
| 60 | + for i in 2:lastindex(x) |
| 61 | + y = _and2(y, x[i]) |
56 | 62 | end
|
57 |
| - return y[end] |
| 63 | + return y |
58 | 64 | end
|
59 |
| -@register_symbolic _and(x...) |
| 65 | + |
60 | 66 | @register_symbolic _and(a, b)
|
61 |
| -@register_symbolic _and(a, b, c) |
62 |
| -@register_symbolic _and(a, b, c, d) |
63 |
| -@register_symbolic _and(a, b, c, d, e) |
64 |
| - |
65 |
| -# MISO OR gate |
66 |
| -OrTable = OffsetArray([ |
67 |
| - # 0 1 :U :X :Z :W :L :H :D |
68 |
| - 0 1 :U :X :X :X 0 1 :X # 0 |
69 |
| - 1 1 1 1 1 1 1 1 1 # 1 |
70 |
| - :U 1 :U :U :U :U :U 1 :U # :U |
71 |
| - :X 1 :U :X :X :X :X 1 :X # :X |
72 |
| - :X 1 :U :X :X :X :X 1 :X # :Z |
73 |
| - :X 1 :U :X :X :X :X 1 :X # :W |
74 |
| - 0 1 :U :X :X :X 0 1 :X # :L |
75 |
| - 1 1 1 1 1 1 1 1 1 # :H |
76 |
| - :X 1 :U :X :X :X :X 1 :X], 0:8, 0:8) |
77 |
| - |
78 |
| -function _or2(a, b) |
79 |
| - i, j = logic(a), logic(b) |
80 |
| - (typeof(i) != Int || typeof(j) != Int) && return X |
81 |
| - OrTable[i, j] |
| 67 | + |
| 68 | +# NOT gate |
| 69 | +const NotTable = LogicTable([U, X, F1, F0, X, X, F1, F0, X]) |
| 70 | + |
| 71 | +_not(x::Logic) = NotTable[x] |
| 72 | +_not(x::Number) = _not(convert(Logic, x)) |
| 73 | + |
| 74 | +@register_symbolic _not(x) |
| 75 | + |
| 76 | +# OR gate |
| 77 | +const OrTable = LogicTable([ |
| 78 | + # U X F0 F1 Z W L H DC |
| 79 | + U U U F1 U U U F1 U # U |
| 80 | + U X X F1 X X X F1 X # X |
| 81 | + U X F0 F1 X X F0 F1 X # F0 |
| 82 | + F1 F1 F1 F1 F1 F1 F1 F1 F1 # F1 |
| 83 | + U X X F1 X X X F1 X # Z |
| 84 | + U X X F1 X X X F1 X # W |
| 85 | + U X F0 F1 X X F0 F1 X # L |
| 86 | + F1 F1 F1 F1 F1 F1 F1 F1 F1 # H |
| 87 | + U X X F1 X X X F1 X]) # DC |
| 88 | + |
| 89 | +function _or2(a::Logic, b::Logic) |
| 90 | + OrTable[a, b] |
82 | 91 | end
|
| 92 | +_or2(a::Number, b::Logic) = _or2(convert(Logic, a), b) |
| 93 | +_or2(a::Logic, b::Number) = _or2(a, convert(Logic, b)) |
| 94 | +_or2(a::Number, b::Number) = _or2(convert(Logic, a), convert(Logic, b)) |
83 | 95 |
|
84 | 96 | function _or(x...)
|
85 |
| - y = [_or2(x[1], x[1])] |
86 |
| - for i in 2:length(x) |
87 |
| - push!(y, _or2(x[i], y[i - 1])) |
| 97 | + y = x[1] |
| 98 | + for i in 2:lastindex(x) |
| 99 | + y = _or2(y, x[i]) |
88 | 100 | end
|
89 |
| - return y[end] |
| 101 | + return y |
90 | 102 | end
|
91 |
| -@register_symbolic _or(x...) |
| 103 | + |
92 | 104 | @register_symbolic _or(a, b)
|
93 |
| -@register_symbolic _or(a, b, c) |
94 |
| -@register_symbolic _or(a, b, c, d) |
95 |
| -@register_symbolic _or(a, b, c, d, e) |
96 |
| -@register_symbolic _or(a, b, c, d, e, f, g, h) |
97 |
| - |
98 |
| -# MISO :XOR gate |
99 |
| - |
100 |
| -XorTable = OffsetArray([ |
101 |
| - # 0 1 :U :X :Z :W :L :H :D |
102 |
| - 0 1 :U :X :X :X 0 1 :X # 0 |
103 |
| - 1 0 :U :X :X :X 1 0 :X # 1 |
104 |
| - :U :U :U :U :U :U :U :U :U # :U |
105 |
| - :X :X :U :X :X :X :X :X :X # :X |
106 |
| - :X :X :U :X :X :X :X :X :X # :Z |
107 |
| - :X :X :U :X :X :X :X :X :X # :W |
108 |
| - 0 1 :U :X :X :X 0 1 :X # :L |
109 |
| - 1 0 :U :X :X :X 1 0 :X # :H |
110 |
| - :X :X :U :X :X :X :X :X :X], 0:8, 0:8) |
111 |
| - |
112 |
| -function _xor2(a, b) |
113 |
| - i, j = logic(a), logic(b) |
114 |
| - (typeof(i) != Int || typeof(j) != Int) && return X |
115 |
| - XorTable[i, j] |
| 105 | + |
| 106 | +# XOR gate |
| 107 | +const XorTable = LogicTable([ |
| 108 | + # U X F0 F1 Z W L H DC |
| 109 | + U U U U U U U U U # U |
| 110 | + U X X X X X X X X # X |
| 111 | + U X F0 F1 X X F0 F1 X # F0 |
| 112 | + U X F1 F0 X X F1 F0 X # F1 |
| 113 | + U X X X X X X X X # Z |
| 114 | + U X X X X X X X X # W |
| 115 | + U X F0 F1 X X F0 F1 X # L |
| 116 | + U X F1 F0 X X F1 F0 X # H |
| 117 | + U X X X X X X X X]) # DC |
| 118 | + |
| 119 | +function _xor2(a::Logic, b::Logic) |
| 120 | + XorTable[a, b] |
116 | 121 | end
|
| 122 | +_xor2(a::Number, b::Logic) = _xor2(convert(Logic, a), b) |
| 123 | +_xor2(a::Logic, b::Number) = _xor2(a, convert(Logic, b)) |
| 124 | +_xor2(a::Number, b::Number) = _xor2(convert(Logic, a), convert(Logic, b)) |
117 | 125 |
|
118 | 126 | function _xor(x...)
|
119 |
| - y = [_xor2(x[1], 0)] |
120 |
| - for i in 2:length(x) |
121 |
| - push!(y, _xor2(x[i], y[i - 1])) |
| 127 | + y = x[1] |
| 128 | + for i in 2:lastindex(x) |
| 129 | + y = _xor2(y, x[i]) |
122 | 130 | end
|
123 |
| - return y[end] |
| 131 | + return y |
124 | 132 | end
|
125 |
| -@register_symbolic _xor(x...) |
126 |
| -@register_symbolic _xor(a, b) |
127 |
| -@register_symbolic _xor(a, b, c) |
128 |
| -@register_symbolic _xor(a, b, c, d) |
129 |
| -@register_symbolic _xor(a, b, c, d, e) |
130 | 133 |
|
131 |
| -# TODO: revisit y[1] for all miso gates for 9-level logic |
| 134 | +@register_symbolic _xor(a, b) |
0 commit comments