Làm thế nào để ánh xạ một bảng chân lý đến các hàm logic ba chiều?


8

Làm ơn. Tôi có một câu hỏi hóc búa và quan trọng từ một lĩnh vực kỹ thuật khác mà câu trả lời của họ có thể khá nổi tiếng trong ngành kỹ thuật điện. Tôi đã hỏi một câu hỏi tương tự trên StackOverflow


Giả sử tôi có một bảng chân lý gồm 5 đầu vào và 1 đầu ra. Tôi đã sử dụng thuật toán Espresso (ví dụ Logic Friday) để thu nhỏ bảng và viết một số VHDL hiệu quả. Mọi thứ đều hoạt động tốt.

Thay vì thu nhỏ và ánh xạ bảng chân lý tới các cổng NAND, tôi muốn ánh xạ tới hàm logic ternary tùy ý. Tôi không quan tâm đến logic đa giá trị, nhưng trong các hàm logic có 3 biến đầu vào. Có 256 chức năng này và NAND 3 trong chỉ là một trong số đó. Không phải tất cả 256 chức năng này có thể thú vị: một số giảm xuống 2 anh chị em biến đầu vào của chúng.

Câu hỏi : làm thế nào bạn có thể ánh xạ một bảng chân lý (ví dụ: với 7 đầu vào) cho bất kỳ chức năng 3 trong này. Một công cụ làm một cái gì đó tương tự sẽ là tuyệt vời, nhưng một phương pháp về cách đơn giản hóa các chức năng ternary tùy ý sẽ là tốt nhất.


Bối cảnh: CPU hiện đại có thể thực hiện các hoạt động logic tạm thời tùy ý trên các thanh ghi 512 bit (ví dụ: vpternlog hướng dẫn ), nhưng do sự phức tạp, các trình biên dịch để lại cho lập trình viên, người không biết gì về cách tối ưu hóa điều này.


Thậm chí không có cách chính thức nào để "ánh xạ" đến một hàm nhị phân tùy ý . Và không phải mọi hàm nhị phân đều bao gồm một hệ thống chức năng hoàn chỉnh. Điều này cũng đúng với chim nhạn.
Eugene Sh.

1
Tôi tin rằng đây là NP cứng cho các hàm nhị phân.
110971

@ user110971 Tôi không nghĩ vậy .. Tôi nghĩ bạn nhầm lẫn với vấn đề SAT.
Eugene Sh.

1
@EugeneSh. Tôi nghĩ rằng vấn đề giảm đến tối thiểu hóa Boolean, đó là NP khó, bởi vì nếu không bạn có thể giải quyết vấn đề SAT. Ít nhất đây là những gì tôi nghĩ OP đang yêu cầu.
110971

2
@ user110971 Các thuật toán tiêu chuẩn (mà tôi biết) không giảm xuống các hàm logic ternary tùy ý (đó câu hỏi). Chúng đơn giản hóa thành NAND 3 trong và AND 3 trong, nhưng không phải tất cả các hàm logic 3 trong khác sẽ cho phép giảm nhỏ gọn hơn nhiều.
HJLebbink

Câu trả lời:


4

Phân tích

Lưu ý rằng lệnh mã hóa tất cả các chức năng ternary có thể. Vì vậy, với bất kỳ ba biến boolean nào và bất kỳ hoạt động bit-khôn ngoan nào trên chúng, chúng ta luôn có thể tìm thấy byte mã hóa. Chẳng hạn, nếu được cung cấp một hàm thì có thể tìm thấy giá trị thật cho mỗi kết hợp các giá trị đầu vào, và được lưu trữ trong một bảng. Chẳng hạn, nếu thì như có thể được nhìn thấy từ một bảng sự thật.

f:Bool×Bool×BoolBool,
f(một,b,c)= =một&(!b|c),
f(một,b,c)= =Tern101100002(một,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

Vì chỉ có 8 đầu vào để mã hóa và chỉ có 2 kết quả nhị phân, nên điều này có thể được mã hóa thành số 8 bit, trong trường hợp này là 0b10110000 = 0xB0.

Tối ưu hóa

Với một tùy ý n chức năng -ary các giá trị boolean, tất cả chúng ta cần phải làm là để chuyển đổi chức năng nhị phân thành các hàm bậc ba. Chúng ta có thể làm điều này, bởi vì chúng ta biết rằng chúng ta có thể tính toán bất kỳ sự kết hợp nào của các hàm. Bắt đầu từ một cây cú pháp trừu tượng của các nút đơn và nhị phân, chúng ta sẽ bắt đầu bằng cách biểu diễn các hàm đơn nguyên và nhị phân theo kiểu tương tự như "mã hóa" ở trên.

Vì vậy, đối với f của chúng tôi :

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

Sử dụng logic đệ quy, chúng ta có thể kết hợp BIN và UNary thành:

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

Mà sau đó có thể được tối ưu hóa thành (quy tắc chuyển đổi dễ dàng tuân theo logic boolean):

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

Quan sát

Điều này rất giống với cách tính toán các bảng tra cứu đồ họa (LUT). Tôi khá chắc chắn rằng bạn có thể tìm thấy nhiều văn bản và thuật toán để ánh xạ logic tới LUT. Ví dụ: Flow-map ( http://cadlab.cs.ucla.edu/~cong/ con / tcad94.pdf )


1
Bạn nói "quy tắc chuyển đổi dễ dàng tuân theo logic boolean", do đó tôi đã cố gắng xây dựng Hệ thống viết lại thuật ngữ (TRS) để làm điều đó. <br/> BF 4-ary đầu tiên (thuộc loại phức tạp nhất) BF [100010110, 4] có bảng chân lý: <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)) Đây là mức giảm nhỏ nhất tôi có thể tìm thấy bằng cách tìm kiếm vũ lực. <br/> Câu hỏi của tôi: Bạn sẽ viết lại điều này như thế nào (không hiệu quả), tôi không thấy các quy tắc chuyển đổi từ logic Boolean là như thế nào của bất kỳ trợ giúp ở đây.
HJLebbink

1
Và sau 6 phút đọc , bạn thậm chí không thể xóa được
<br />

1
Bạn không cần phải viết lại nó. Chỉ cần thực hiện đánh giá vũ lực cho từng tổ hợp giá trị thật.
Pål-Kristian Engstad

@engstad: ah Cuối cùng tôi đã hiểu nhận xét của bạn: bạn có ý gì đó như: BF [i, K] (a_0, ..., a_K) = BF [0xCA, 3] (a_0, BF [Upperhalf (i), K-1 ] (a_1, ..., a_K), BF [hạ cấp (i), K-1] (a_1, ..., a_K))
HJLebbink

2

Trích từ câu trả lời của riêng tôi .

  1. Dịch bảng chân lý thành một công thức logic; sử dụng, ví dụ, thứ Sáu Logic.
  2. Lưu trữ công thức logic ở định dạng phương trình Synopsys (.eqn).

Nội dung của 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. Sử dụng "ABC: Hệ thống để tổng hợp và xác minh tuần tự" từ Trung tâm nghiên cứu xác minh và tổng hợp Berkeley.

Ở ABC tôi chạy:

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

Bạn có thể cần chạy choice; if -K 3; psnhiều lần để có kết quả tốt hơn.

Kết quả BF_Q6.bench chứa 3 LUT cho một 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 )

Điều này có thể được viết lại (một cách máy móc) cho C ++ mà tôi đang tìm kiếm.


1
Sử dụng tốt ABC!
Pål-Kristian Engstad
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.