如何将真值表映射到三元逻辑函数?


8

请客气。我有一个来自不同工程领域的棘手且重要的问题,其答案在电气工程领域可能是众所周知的。我在StackOverflow上问了类似的问题


假设我有一个包含5个输入和1个输出的真值表。我使用了Espresso算法(例如Logic Friday)来最小化表格并编写一些有效的VHDL。一切正常。

我不想将真值表最小化并映射到与非门,而是想映射到任意三元逻辑函数。我对多值逻辑不感兴趣,但是对具有3个输入变量的逻辑函数不感兴趣。这些功能共有256种,而3-in NAND只是其中之一。这256个功能中的全部功能可能并不是全部有趣:一些功能减少到了2个输入变量同级。

问题:如何将真值表(例如,具有7个输入)映射到这些3合功能中的任何一个。做类似事情的工具会很棒,但是关于如何简化为任意三元函数的方法最好。


背景技术:现代CPU可以对512位寄存器(例如,指令vpternlog)执行任意三元逻辑运算,但是由于复杂性,编译器将其留给了程序员,程序员对如何对其进行优化一无所知。


甚至没有正式的方法来“映射”到任意二进制函数。并非每个二进制函数都包含完整的功能系统。三元也是如此。
尤金(Eugene Sh)。

1
我相信这对于二进制函数来说很难。
user110971

@ user110971我不这么认为..我认为您对SAT问题感到困惑。
尤金(Eugene Sh)。

1
@EugeneSh。我认为问题可以归结为布尔最小化,这是NP难的,因为否则您可以解决SAT问题。至少我认为这是OP的要求。
user110971 '17

2
@ user110971(我知道)标准算法不会简化为任意三元逻辑函数(这就是问题)。它们简化为3英寸NAND和3英寸AND,但不是所有其他的3英寸逻辑功能,这将允许更紧凑的缩减。
HJLebbink '17

Answers:


4

分析

注意,该指令对所有可能的三元函数进行了编码。因此,给定任何三个布尔变量和对其进行任何按位运算,我们总能找到编码字节。例如,如果给定函数 则可以为每种输入值组合找到真值,并存储在表格中 例如,如果 则 从真值表可以看出。

f:Bool×Bool×BoolBool,
f(a,b,c)=a&(!b|c),
f(a,b,c)=TERN101100002(a,b,c),
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

由于只有8个输入要编码,而只有2个二进制结果,因此可以将其编码为8位数字,在这种情况下为0b10110000 = 0xB0。

最佳化

给定布尔值的任意n元函数,我们要做的就是将二进制函数转换为三进制函数。我们可以这样做,因为我们知道我们可以计算函数的任意组合。从一元和二进制节点的抽象语法树开始,我们将以与上述“编码”类似的方式表示一元和二进制函数开始。

因此,对于我们的f

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

使用递归逻辑,我们可以将BIN和UNARY合并为:

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

然后可以对其进行优化(转换规则很容易遵循布尔逻辑):

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

观察

这与计算FPGA查找表(LUT)的方式非常相似。我很确定您可以找到许多将逻辑映射到LUT的文本和算法。例如:流程图(http://cadlab.cs.ucla.edu/~cong/papers/tcad94.pdf


1
您说“转换规则很容易遵循布尔逻辑”,因此我尝试构建一个术语重写系统(TRS)来做到这一点。<br/>第一个四进制BF(最复杂的类型)BF [100010110, 4]包含真值表:<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))这是我用蛮力搜索可以找到的最小缩减量。<br/> 我的问题:如何(低效地)重写它,我看不出布尔逻辑的转换规则如何这里有什么帮助
HJLebbink '17

1
而6分钟后,阅读你甚至不能删除不是非常实用<BR/>
HJLebbink

1
您不需要重写它。只需对每个真值组合进行暴力评估。
保罗·克里斯蒂安·恩斯塔德

@engstad:啊,我终于明白了您的话:您的意思是: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

摘自我自己的回答

  1. 将真值表转换为逻辑公式;使用例如Logic Friday。
  2. 将逻辑公式存储为Synopsys公式格式(.eqn)。

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. 使用Berkeley验证和综合研究中心的“ ABC:用于顺序合成和验证的系统”。

在ABC中,我运行:

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

您可能需要运行choice; if -K 3; ps多个时间才能获得更好的结果。

生成的BF_Q6.bench包含一个FPGA的3-LUT:

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 )

可以将其(机械地)重写为我正在寻找的C ++。


1
很好地使用ABC!
保罗
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.