Xây dựng một máy nhân bằng các cổng logic NAND


20

Dựa trên câu hỏi trước đây của tôi cùng loại, Xây dựng máy thêm bằng cổng logic NAND , lần này bạn được yêu cầu nhân lên thay vì thêm.

Xây dựng một sơ đồ của cửa (hai dây) NAND logic đó sẽ lấy dây đầu vào A1, A2, A4, B1, B2, B4, đại diện cho hai số nhị phân Ađể B0-7, và các giá trị lợi nhuận trên dây đầu ra C1, C2, C4, C8, C16, và C32, đại diện C, đó là sản phẩm của AB.

Điểm của bạn được xác định bởi số lượng cổng NAND bạn sử dụng (1 điểm cho mỗi cổng). Để đơn giản hóa mọi thứ, bạn có thể sử dụng cổng AND, OR, NOT và XOR trong sơ đồ của mình, với các điểm tương ứng sau:

  • NOT: 1
  • AND: 2
  • OR: 3
  • XOR: 4

Mỗi điểm số này tương ứng với số lượng cổng NAND cần thiết để xây dựng cổng tương ứng.

Điểm số thấp nhất chiến thắng.


Tôi đang cố gắng tạo một ví dụ cuối cùng trong Logisim. Công cụ này là khó khăn.
Joe Z.

Tôi đã có đủ những thứ này trong trường học của tôi, không cảm ơn.
Julian Kuhn

7
Tôi có một trình tối ưu hóa phổ quát cho các nhiệm vụ như thế này. Nó có thể tìm thấy chương trình ngắn nhất để tính hàm boolean k-output. Nếu tôi cho nó một tuần, nó có thể cho tôi biết nếu số nhân 13 cổng 2x2 mà nó tìm thấy là tối ưu. 3x3? Tôi sẽ chết trước khi nó kết thúc.
gian hàng

1
Số nhân 2x2 13 cổng đó là tối ưu (và có trong câu trả lời của Jan). Với điều đó, và một vài phần khác tôi có thể tối ưu hóa, tôi rất nghi ngờ 60 là tối ưu cho vấn đề này. Tôi thực sự hy vọng ai đó chứng minh tôi sai.
gian hàng

@boothby Không hẳn. Ứng dụng ngây thơ của cây cộng dẫn đến giải pháp 18 cổng (4 AND, 2 nửa cộng), điều này dẫn tôi đến một ý tưởng: Tôi sẽ có thể đánh cắp ^ k ^ k ^ k ^ k ^ k sử dụng cổng 13 Số nhân 2x2.
John Dvorak

Câu trả lời:


24

60 55 50 48 cổng

Số nhân 48 cổng


Bản gốc (60 cổng) là cách tiếp cận có hệ thống - nhân từng chữ số với mỗi chữ số, sau đó tổng hợp chúng lại với nhau. Cụ thể, xem cây Wallacecây Dadda

Số nhân 60 cổng

Nửa trên cùng là mạng nhân - nhân mỗi chữ số với mỗi chữ số và nhóm chữ số đầu ra có cùng trọng số. Một số bit đã được đảo ngược để lưu cổng.

Nửa thứ hai là mạng cộng. Mỗi hộp đại diện cho một bộ cộng duy nhất - một nửa bộ cộng (5 cổng - 1x XOR và một biến tần) hoặc một bộ cộng đầy đủ (9 cổng - 2x XOR và NAND các bit mang ngược). Trên cùng là đầu vào, đầu ra dưới cùng là tổng, đầu ra bên trái là đầu ra. xem thử thách trước

Số nhân 2x2 sau đó đã được tối ưu hóa bằng tay với mạng 13 cổng được xây dựng tùy chỉnh, đây là kích thước tối ưu như được tìm thấy bởi @boothby . Cảm ơn!

Dán nó vào góc bit thấp và mở lại cây bộ cộng sẽ lưu năm cổng (xem bản sửa đổi số 2). Tuy nhiên, dán nó vào góc cao cũng tạo ra sự chồng chéo. Tuy nhiên, một chút toán học cho chúng ta biết rằng việc bỏ bit thấp của hệ số nhân cao sẽ giải quyết được sự chồng chéo và những gì còn lại phải làm là thêm hai bit còn lại và tổng hợp các thứ.

Thật không may, một mình, không may, không cung cấp bất kỳ khoản tiết kiệm nào, nhưng nó mở ra hai sự tối ưu. Đầu tiên, hai số nhân có hai cổng chung và có thể hợp nhất với nhau. Tại thời điểm này, chúng tôi trở lại ở 55. Thứ hai, trong mạng bổ sung, chúng tôi không cần một nửa cộng bởi vì chúng tôi biết số tiền mang theo của nó sẽ bằng không. Chúng ta có thể thay thế nó bằng OR. OR là NAND với đầu vào đảo ngược. Điều này tạo ra chúng tôi với hai chuỗi 2 KHÔNG trên mỗi nhánh, sau đó có thể được gỡ bỏ, với tổng số tiết kiệm là năm cổng. Thật không may, nửa bộ cộng tại C16 vẫn mang theo, vì vậy chúng tôi không thể làm tương tự ở đó. Thứ ba, một bộ cộng đầy đủ có một thuộc tính hữu ích: nếu bạn đảo ngược đầu vào và đầu ra của nó, nó vẫn hoạt động như nhau. Vì tất cả các đầu vào của nó đã được đảo ngược, chúng ta cũng có thể di chuyển các bộ biến tần phía sau nó. Hai lần. Chúng tôi có thể đã làm như vậy trong bản gốc, nhưng ... ồ Chúng tôi vẫn có một nửa bộ cộng với hai đầu vào đảo ngược. Tôi muốn tối ưu hóa phần này nhiều hơn, nhưng tôi nghi ngờ tôi có thể.

Vì chúng ta rút ra KHÔNG từ bên trong một thành phần, chúng ta phải biểu thị điều đó bằng cách nào đó. Chúng tôi đã thu được một nửa bộ cộng với mang ngược (AKA khai thác XOR) với chi phí bốn cổng.

Trong khi đó, chúng tôi cũng đã vẽ lại sơ đồ đáng kể.


Phần duy nhất có khả năng tối ưu hóa là khối giữa của các bộ cộng. Yêu cầu logic là đối với một bộ cộng siêu nhanh (lấy 4 bit đầu vào, có hai bit đầu ra mang theo) và một bộ cộng đầy đủ; việc thực hiện của bạn với hai trình bổ sung đầy đủ và hai trình bổ sung nửa có vẻ khó cải thiện.
Peter Taylor

Tôi đã cố gắng tạo ra mạng chính xác này đêm qua, nhưng dường như tôi không đủ thành thạo trong các mạng logic.
Joe Z.

Xuất sắc nhất!
gian hàng

9

39 cổng

Tôi khá chắc chắn rằng không có thiết kế đơn giản hơn của tôi ở đây. Nó rất khó để thực hiện. Tôi làm cho các mạch tối thiểu khác quá.

Độ trễ truyền được biểu thị bằng vị trí hướng xuống của mỗi cổng NAND trên trang tính.

Số nhân tối thiểu 3 bit

Mã Verilog và thử nghiệm:

// MINIMAL 3 BIT MULTIPLICATOR
//
// The simplest 3 bit multiplicator possible, using 39 NAND gates only.
//
// I have also made multiplicators that are faster, more efficient,
// use different gates, and multiply bigger numbers. And I also do
// hard optimization of other circuits. You may contact me at
// kim.oyhus@gmail.com
// 
// This is my entry to win this hard Programming Puzzle & Code Golf
// at Stack Exchange:
// /codegolf/12261/build-a-multiplying-machine-using-nand-logic-gates/
//
// By Kim Øyhus 2018 (c) into (CC BY-SA 3.0)
// This work is licensed under the Creative Commons Attribution 3.0
// Unported License. To view a copy of this license, visit
// https://creativecommons.org/licenses/by-sa/3.0/


module mul3x3 ( in_000, in_001, in_002, in_003, in_004, in_005, out000, out001, out002, out003, out004, out005 );
  input  in_000, in_001, in_002, in_003, in_004, in_005;
  output out000, out001, out002, out003, out004, out005;
  wire   wir000, wir001, wir002, wir003, wir004, wir005, wir006, wir007, wir008, wir009, wir010, wir011, wir012, wir013, wir014, wir015, wir016, wir017, wir018, wir019, wir020, wir021, wir022, wir023, wir024, wir025, wir026, wir027, wir028, wir029, wir030, wir031, wir032;

  nand gate000 ( wir000, in_000, in_005 );
  nand gate001 ( wir001, in_000, in_004 );
  nand gate002 ( wir002, in_000, in_003 );
  nand gate003 ( out000, wir002, wir002 );
  nand gate004 ( wir003, in_004, in_001 );
  nand gate005 ( wir004, wir003, wir003 );
  nand gate006 ( wir005, in_003, in_002 );
  nand gate007 ( wir006, wir000, wir005 );
  nand gate008 ( wir007, in_004, in_002 );
  nand gate009 ( wir008, in_001, in_005 );
  nand gate010 ( wir009, wir008, wir007 );
  nand gate011 ( wir010, in_001, in_003 );
  nand gate012 ( wir011, wir001, wir010 );
  nand gate013 ( wir012, out000, wir004 );
  nand gate014 ( wir013, wir004, wir012 );
  nand gate015 ( wir014, wir011, wir012 );
  nand gate016 ( out001, wir014, wir014 );
  nand gate017 ( wir015, in_002, in_005 );
  nand gate018 ( wir016, wir015, wir015 );
  nand gate019 ( wir017, out000, wir016 );
  nand gate020 ( wir018, wir017, wir013 );
  nand gate021 ( wir019, wir016, wir018 );
  nand gate022 ( wir020, wir019, wir009 );
  nand gate023 ( wir021, wir020, wir017 );
  nand gate024 ( wir022, wir020, wir009 );
  nand gate025 ( wir023, wir022, wir021 );
  nand gate026 ( out005, wir022, wir022 );
  nand gate027 ( wir024, wir016, wir022 );
  nand gate028 ( wir025, wir006, wir018 );
  nand gate029 ( wir026, wir025, wir006 );
  nand gate030 ( wir027, wir025, wir018 );
  nand gate031 ( out002, wir026, wir027 );
  nand gate032 ( wir028, wir004, wir027 );
  nand gate033 ( wir029, wir023, wir028 );
  nand gate034 ( wir030, wir028, wir028 );
  nand gate035 ( wir031, wir030, wir021 );
  nand gate036 ( out004, wir031, wir024 );
  nand gate037 ( wir032, wir029, wir031 );
  nand gate038 ( out003, wir032, wir032 );
endmodule


module mul3x3_test; 
   reg  [5:0] AB; // C=A*B
   wire [5:0] C;

  mul3x3 U1 ( 
  .in_000 (AB[0]), 
  .in_001 (AB[1]), 
  .in_002 (AB[2]), 
  .in_003 (AB[3]), 
  .in_004 (AB[4]), 
  .in_005 (AB[5]), 
  .out000 (C[0]), 
  .out001 (C[1]), 
  .out002 (C[2]), 
  .out003 (C[3]), 
  .out004 (C[4]), 
  .out005 (C[5])
  ); 

  initial  AB=0;
  always  #10  AB = AB+1;
  initial  begin
    $display("\t\ttime,\tA,\tB,\tC"); 
    $monitor("%d,\t%b\t%b\t%b",$time, AB[5:3], AB[2:0],C); 
  end 
  initial  #630  $finish; 
endmodule


// iverilog -o mul3x3_test mul3x3_test.v
// vvp mul3x3_test

Kim husyhus


2
Bạn có một bằng chứng rằng câu trả lời của bạn là hợp lệ?
Jonathan Frech

3
Tôi muốn giới thiệu sơ đồ này trong Logisim (nó miễn phí), để nó có thể dễ dàng nhìn thấy và kiểm tra.
mbomb007

Nó quá lớn để được chứng minh là tối thiểu, ngoại trừ có lẽ bởi một máy tính lượng tử trong tương lai. Vì vậy, tôi sử dụng các phương pháp thống kê để xác minh tính tối ưu của nó. Nó vẫn mất quá nhiều thời gian tính toán.
KimOyhus

2
Jonathon yêu cầu một bằng chứng về tính hợp lệ, chứ không phải là một bằng chứng về sự lạc quan. Tôi không nghĩ bạn cần chứng minh nó hợp lệ. Nhưng thật tuyệt nếu chúng tôi dễ dàng kiểm tra xem điều này có hợp lệ hay không, thay vì lấy lời của bạn cho nó
H.PWiz

4
Điều này không hoạt động: thử trực tuyến!
Anders Kaseorg
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.