Wie ordne ich eine Wahrheitstabelle ternären logischen Funktionen zu?

8

Bitte sei nett. Ich habe eine heikle und wichtige Frage aus einem anderen Bereich der Technik, deren Antwort in der Elektrotechnik ziemlich bekannt sein könnte. Ich habe eine ähnliche Frage zu StackOverflow gestellt


Angenommen, ich habe eine Wahrheitstabelle mit 5 Eingängen und 1 Ausgang. Ich habe den Espresso-Algorithmus (z. B. Logic Friday) verwendet, um die Tabelle zu minimieren und eine effiziente VHDL zu schreiben. Alles funktioniert gut.

Anstatt die Wahrheitstabelle zu minimieren und NAND-Gattern zuzuordnen, möchte ich eine beliebige ternäre logische Funktion abbilden. Ich interessiere mich nicht für mehrwertige Logik, sondern für logische Funktionen mit 3 Eingangsvariablen. Es gibt 256 dieser Funktionen, und 3-in-NAND ist nur eine davon. Möglicherweise sind nicht alle dieser 256 Funktionen interessant: Einige reduzieren sich auf ihre 2 Geschwister mit Eingangsvariablen.

Frage : Wie können Sie einer dieser 3-in-Funktionen eine Wahrheitstabelle (z. B. mit 7 Eingängen) zuordnen? Ein Tool, das etwas Ähnliches tut, wäre großartig, aber eine Methode zur Vereinfachung auf beliebige ternäre Funktionen wäre am besten.


Hintergrund: Moderne CPUs können beliebige ternäre Logikoperationen mit 512-Bit-Registern (z. B. Befehl vpternlog ) ausführen. Aufgrund der Komplexität überlassen Compiler dies jedoch dem Programmierer, der keine Ahnung hat , wie dies optimiert werden soll.

HJLebbink
quelle
Es gibt nicht einmal eine formale Möglichkeit, einer beliebigen Binärfunktion "zuzuordnen" . Und nicht jede Binärfunktion umfasst ein komplettes Funktionssystem. Gleiches gilt für ternäre.
Eugene Sh.
1
Ich glaube, das ist NP schwer für binäre Funktionen.
user110971
@ user110971 Ich glaube nicht .. Ich denke, Sie verwechseln mit dem SAT-Problem.
Eugene Sh.
1
@ EugeneSh. Ich denke, das Problem reduziert sich auf die Boolesche Minimierung, die NP-schwer ist, weil Sie sonst das SAT-Problem lösen könnten. Zumindest ist es das, was das OP meiner Meinung nach verlangt.
user110971
2
@ user110971 Die Standardalgorithmen (die mir bekannt sind) reduzieren sich nicht auf beliebige ternäre logische Funktionen (das ist die Frage). Sie vereinfachen sich zu 3-in-NANDs und 3-in-ANDs, jedoch nicht zu allen anderen logischen 3-in-Funktionen, die eine wesentlich kompaktere Reduzierung ermöglichen würden.
HJLebbink

Antworten:

4

Analyse

f ( a , b , c ) = a & ( ! b | c ) ,

f::Bool×Bool×BoolBool,
f(ein,b,c)=ein&(!b|c),
f(ein,b,c)=TERN101100002(ein,b,c),
wie aus einer Wahrheitstabelle ersichtlich ist.
a b c | f
------+--
0 0 0 | 0
0 0 1 | 0
0 1 0 | 0
0 1 1 | 0
1 0 0 | 1
1 0 1 | 1
1 1 0 | 0
1 1 1 | 1

Da die Codierung nur 8 Eingänge und nur 2 Binärergebnisse enthält, kann dies als 8-Bit-Zahl codiert werden, in diesem Fall 0b10110000 = 0xB0.

Optimierungen

Bei einer beliebigen n -ary-Funktion von Booleschen Werten müssen wir lediglich Binärfunktionen in ternäre Funktionen konvertieren. Wir können dies tun, weil wir wissen, dass wir jede Kombination von Funktionen berechnen können. Ausgehend von einem abstrakten Syntaxbaum von unären und binären Knoten würden wir zunächst unäre und binäre Funktionen auf ähnliche Weise wie oben beschrieben "codieren" darstellen.

Also, für unser f :

f = AND(a, OR(NOT(b), c)) = BIN[1000](a, BIN[1110](UNARY[10](b), c))

Mit rekursiver Logik können wir BIN und UNARY kombinieren in:

f = AND(a, OR(NOT(b), c)) = BIN[1000](a, BIN[1011](b, c))

Was dann optimiert werden kann (Konvertierungsregeln folgen leicht aus der booleschen Logik):

f = AND(a, OR(NOT(b), c)) = TERN[10110000](a, b, c)

Überwachung

Dies ist sehr ähnlich der Berechnung von FPGA-Nachschlagetabellen (LUTs). Ich bin mir ziemlich sicher, dass Sie viele Texte und Algorithmen für die Zuordnung von Logik zu LUTs finden können. Zum Beispiel: Flow-Map ( http://cadlab.cs.ucla.edu/~cong/papers/tcad94.pdf )

Pål-Kristian Engstad
quelle
1
Sie sagen, "Konvertierungsregeln folgen leicht aus der booleschen Logik", deshalb habe ich versucht, ein Term Rewriting System (TRS) zu erstellen, um genau das zu tun. <br/> Das erste 4-ary BF (der komplexesten Art) BF [100010110, 4] hat Wahrheitstabelle: <br/> 0000 => 1 <br/> 0010 => 1 <br/> 0100 => 1 <br/> 1000 => 1 <br/> A'B'C'D + A'B'CD '+ A'BC'D' + AB'C'D '= BF [0xd1,3] (A, BF [0x16,3] (D, C, B), BF [0x02,3] (C, B, A)) Dies ist die kleinste Reduzierung, die ich durch Brute-Force-Suche finden konnte. <br/> Meine Frage: Wie würden Sie dies (ineffizient) umschreiben ? Ich sehe nicht, wie die Konvertierungsregeln aus der Booleschen Logik sind von jeglicher Hilfe hier.
HJLebbink
1
Und nach 6 Minuten Lesen können Sie nicht einmal die nicht sehr funktionale <br/>
HJLebbink
1
Sie müssen es nicht umschreiben. Führen Sie einfach eine Brute-Force-Bewertung für jede Kombination von Wahrheitswerten durch.
Pål-Kristian Engstad
@engstad: ah, ich habe endlich deine Bemerkung verstanden: du meinst so etwas wie: BF [i, K] (a_0, ..., a_K) = BF [0xCA, 3] (a_0, BF [obere Hälfte (i), K-1 ] (a_1, ..., a_K), BF [untere Hälfte (i), K-1] (a_1, ..., a_K))
HJLebbink
2

Auszug aus meiner eigenen Antwort .

  1. Übersetzen Sie die Wahrheitstabelle in eine logische Formel. Verwenden Sie zB Logic Friday.
  2. Speichern Sie die logische Formel im Synopsys-Gleichungsformat (.eqn).

Inhalt von BF_Q6.eqn:

INORDER = A B C D E F; 
OUTORDER = F0 F1;
F0 = (!A*!B*!C*!D*!E*F) + (!A*!B*!C*!D*E*!F) + (!A*!B*!C*D*!E*!F) + (!A*!B*C*!D*!E*!F) + (!A*B*!C*!D*!E*!F) + (A*!B*!C*!D*!E*!F);
F1 = (!A*!B*!C*!D*E) + (!A*!B*!C*D*!E) + (!A*!B*C*!D*!E) + (!A*B*!C*!D*!E) + (A*!B*!C*!D*!E);
  1. Verwenden Sie "ABC: Ein System für die sequentielle Synthese und Verifizierung" des Berkeley Verification and Synthesis Research Center.

In ABC laufe ich:

abc 01> read_eqn BF_Q6.eqn
abc 02> choice; if -K 3; ps
abc 03> lutpack -N 3 -S 3; ps
abc 04> show
abc 05> write_bench BF_Q6.bench

Möglicherweise müssen Sie choice; if -K 3; psmehrere Male ausführen , um bessere Ergebnisse zu erzielen .

Die resultierende BF_Q6.bench enthält die 3-LUTs für ein FPGA:

INPUT(A)
INPUT(B)
INPUT(C)
INPUT(D)
INPUT(E)
INPUT(F)
OUTPUT(F0)
OUTPUT(F1)
n11         = LUT 0x01 ( B, C, D )
n12         = LUT 0x1 ( A, E )
n14         = LUT 0x9 ( A, E )
n16         = LUT 0xe9 ( B, C, D )
n18         = LUT 0x2 ( n11, n14 )
F1          = LUT 0xae ( n18, n12, n16 )
n21         = LUT 0xd9 ( F, n11, n14 )
n22         = LUT 0xd9 ( F, n12, n16 )
F0          = LUT 0x95 ( F, n21, n22 )

Dies kann (mechanisch) in das gesuchte C ++ umgeschrieben werden.

HJLebbink
quelle
1
Gute Verwendung von ABC!
Pål-Kristian Engstad