Come mappare una tabella di verità alle funzioni logiche ternarie?


8

Per favore sii gentile. Ho una domanda spinosa e importante da un diverso campo dell'ingegneria la cui risposta potrebbe essere abbastanza nota nell'ingegneria elettrica. Ho fatto una domanda simile su StackOverflow


Supponiamo di avere una tabella di verità con 5 input e 1 output. Ho usato l'algoritmo Espresso (ad es. Logic Friday) per minimizzare la tabella e scrivere un VHDL efficiente. Tutto funziona bene.

Invece di minimizzare e mappare la tabella della verità alle porte della NAND, vorrei mappare una funzione logica ternaria arbitraria. Non mi interessa la logica multivalore, ma le funzioni logiche che hanno 3 variabili di input. Esistono 256 di queste funzioni e 3-in NAND è solo una di queste. Non tutte queste 256 funzioni possono essere interessanti: alcune si riducono ai loro 2 fratelli variabili di input.

Domanda : come si può mappare una tabella di verità (ad esempio, con 7 ingressi) a una di queste funzioni 3 in. Uno strumento che fa qualcosa di simile sarebbe fantastico, ma sarebbe meglio un metodo su come semplificare le funzioni ternarie arbitrarie.


Contesto: le moderne CPU possono eseguire arbitrariamente operazioni logiche ternarie su registri a 512 bit (ad es. Istruzioni vpternlog ), ma a causa della complessità, i compilatori lo lasciano al programmatore, che non ha idea di come ottimizzarlo.


Non esiste un modo nemmeno formale di "mappare" una funzione binaria arbitraria . E non tutte le funzioni binarie comprendono un sistema funzionale completo. Lo stesso vale per il ternario.
Eugene Sh.

1
Credo che questo sia NP difficile per le funzioni binarie.
user110971

@ user110971 Non penso proprio .. Penso che ti confonda con il problema SAT.
Eugene Sh.

1
@EugeneSh. Penso che il problema si riduca alla minimizzazione booleana, che è NP difficile, perché altrimenti potresti risolvere il problema SAT. Almeno questo è ciò che penso che l'OP stia chiedendo.
user110971

2
@ user110971 Gli algoritmi standard (di cui sono a conoscenza) non si riducono a funzioni logiche ternarie arbitrarie (questa è la domanda). Semplificano con NAND 3-in e AND 3-in, ma non tutte le altre funzioni logiche 3-in che consentirebbero una riduzione molto più compatta.
HJLebbink,

Risposte:


4

Analisi

Si noti che l'istruzione codifica per tutte le possibili funzioni ternarie. Quindi, date tre variabili booleane e qualsiasi operazione bit-saggio su di esse, possiamo sempre trovare il byte di codifica. Ad esempio, se viene assegnata una funzione

f:Bool×Bool×BoolBool,
quindi il valore di verità può essere trovato per ogni combinazione di valori di input e memorizzato in una tabella. Ad esempio, se
f(un',B,c)=un'&(!B|c),
poi
f(un',B,c)=TERN101100002(un',B,c),
come si può vedere da una tabella di verità.
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

Poiché ci sono solo 8 input per la codifica e solo 2 risultati binari, questo può essere codificato come un numero a 8 bit, in questo caso 0b10110000 = 0xB0.

ottimizzazioni

Dato un arbitrario n funzione ario di valori booleani, tutto quello che dobbiamo fare è quello di convertire funzioni binarie in funzioni ternari. Possiamo farlo, perché sappiamo che possiamo calcolare qualsiasi combinazione di funzioni. Partendo da un albero di sintassi astratto di nodi unari e binari, inizieremmo rappresentando le funzioni unarie e binarie in modo simile alla "codifica" sopra.

Quindi, per la nostra f :

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

Usando la logica ricorsiva, possiamo combinare BIN e UNARY in:

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

Che può quindi essere ottimizzato in (le regole di conversione seguono facilmente dalla logica booleana):

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

Osservazione

Questo è molto simile al modo in cui vengono calcolate le tabelle di ricerca FPGA (LUT). Sono abbastanza sicuro che puoi trovare molti testi e algoritmi per mappare la logica ai LUT. Ad esempio: Flow-map ( http://cadlab.cs.ucla.edu/~cong/papers/tcad94.pdf )


1
Dici che "le regole di conversione seguono facilmente dalla logica booleana", quindi ho cercato di creare un Term Rewriting System (TRS) per fare proprio questo. <br/> Il primo BF a 4-ary (del tipo più complesso) BF [100010110, 4] ha una tabella di verità: <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)) Qual è la riduzione più piccola che ho trovato con la ricerca della forza bruta. <br/> La mia domanda: come riscriveresti questo (in modo inefficiente), non vedo come siano le regole di conversione dalla logica booleana di qualsiasi aiuto qui.
HJLebbink,

1
E dopo 6 minuti di lettura di questo non è nemmeno possibile rimuovere il non molto funzionale <br/>
HJLebbink

1
Non è necessario riscriverlo. Basta fare una valutazione della forza bruta per ogni combinazione di valori di verità.
Pål-Kristian Engstad,

@engstad: ah ho finalmente capito la tua osservazione: intendi qualcosa del tipo: BF [i, K] (a_0, ..., a_K) = BF [0xCA, 3] (a_0, BF [upperhalf (i), K-1 ] (a_1, ..., a_K), BF [lowerhalf (i), K-1] (a_1, ..., a_K))
HJLebbink

2

Estratto dalla mia stessa risposta .

  1. Traduci la tabella della verità in una formula logica; usare ad es. Logic Friday.
  2. Memorizza la formula logica nel formato di equazione di Synopsys (.eqn).

Contenuto di 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. Usa "ABC: un sistema per la sintesi sequenziale e la verifica" dal Centro di ricerca sulla verifica e sintesi di Berkeley.

In ABC corro:

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

Potrebbe essere necessario eseguire choice; if -K 3; ps più volte per ottenere risultati migliori.

Il BF_Q6.bench risultante contiene i 3-LUT per un 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 )

Questo può essere riscritto (meccanicamente) nel C ++ che stavo cercando.


1
Bel uso di ABC!
Pål-Kristian Engstad,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.