Побудуйте множильну машину за допомогою логічних воріт NAND


20

На основі мого попереднього запитання того ж типу: Створіть додаючу машину за допомогою логічних воріт NAND , на цей раз вас просять помножити замість додавання.

Побудувати схему (двопровідний) NAND - логічних вентилів , які прийматимуть вхідні дроти A1, A2, A4, B1, B2, B4, що представляють два двійкових чисел Aв Bвід 0 до 7, а повернені значення на вихідних проводів C1, C2, C4, C8, C16, і C32, представляючи C, що є продуктом Aі B.

Ваш бал визначається кількістю NAND воріт, які ви використовуєте (1 бал за ворота). Щоб спростити речі, ви можете використовувати ворота AND, АБО, NOT і XOR у вашій діаграмі із наступними відповідними балами:

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

Кожен з цих балів відповідає кількості воріт NAND, необхідних для побудови відповідних воріт.

Виграє найнижчий рахунок.


Я намагаюся зробити приклад останнього місця в Logisim. Цей матеріал важкий.
Джо Z.

Мені цього в моїй школі було достатньо, дякую.
Йоганнес Кун

7
У мене є універсальний оптимізатор для таких завдань. Це, очевидно, знаходить найкоротшу програму для обчислення булева функція k-output. Якби я дав йому тиждень, він міг би сказати, чи кращий мультиплікатор 13 воріт 2x2, який він знайшов. 3х3? Я мертвий, перш ніж закінчиться.
кабінка

1
Цей множник 2x2 2x2 є оптимальним (і міститься у відповіді Яна). З огляду на це та ще декілька фрагментів, які я можу оптимізувати, я дуже сильно підозрюю, що 60 є оптимальними для цієї проблеми. Я дуже сподіваюся, що хтось докаже мене неправильно.
кабінка

@boothby Не дуже. Наївне застосування дерев, що додають, призводить до вирішення 18-ти воріт (4 ANDs, 2 half-adders), що підводить мене до ідеї: я повинен мати можливість вкрасти ^ k ^ k ^ k ^ k ^ k з використанням 13-х воріт 2х2 множник.
Джон Дворак

Відповіді:


24

60 55 50 48 воріт

48-затворний множник


Оригінальний (60 воріт) був систематичним підходом - помножуйте кожну цифру з кожною, а потім підсумовуйте їх разом. А саме, див. Дерева Уоллес та дерева татди

Множник на 60 воріт

Верхня половина - це мережа множення - множте кожну цифру з кожною, а групові вихідні цифри мають однакову вагу. Деякі біти залишилися перевернуті, щоб зберегти ворота.

Друга половина - це сумарна мережа. Кожне поле являє собою одиночний суматор - або наполовину суматор (5 воріт - 1х XOR і інвертор), або повний суматор (9 воріт - 2х XOR і NAND перевернуті біти переносу). Угорі - це входи, нижній - сума, лівий - результат. див. попередній виклик

Потім множник 2x2 був оптимізований вручну до побудованої на замовлення мережі 13-х воріт, що є оптимальним розміром, як виявив @boothby . Спасибі!

Вставивши його в низькорозрядний куточок і повторно оптимізувавши дерево, що додає, економить п'ять воріт (див. Редакцію №2). Однак, вставляючи його у кут із високим розрядом, він також створює перекриття. Трохи математики говорить нам, однак, що випадання низького біта високого множника вирішує перекриття, і що потрібно зробити, це додати два решти біта та підбити підсумки.

Це, на жаль, не забезпечує економії, але відкриває дві оптимізації. По-перше, два мультиплікатори мають два загальні ворота, і їх можна з'єднати разом. На даний момент ми знову на 55. По-друге, в мережі додавання нам не потрібна половина суматора, оскільки ми знаємо, що її перенос буде нульовим. Ми можемо замінити його АБО. АБО - це NAND з інвертованими входами. Це дає нам дві 2-ланцюжки NOT на кожній гілці, які потім можна буде видалити, для загальної економії п'яти воріт. На жаль, наполовину суматор у C16 все ще несе, тому ми не можемо зробити те саме там. По-третє, повний суматор має корисну властивість: якщо ви інвертуєте його входи та виходи, він все одно поводиться так само. Оскільки всі його входи вже інвертовані, ми можемо так само добре перемістити інвертори за ним. Двічі. Ми могли зробити те саме в оригіналі, але ... що ж, добре. У нас все ще є напівдобавка з двома перевернутими входами. Я хочу оптимізувати цю частину більше, але сумніваюся, що зможу.

Оскільки ми витягуємо НЕ зсередини компонента, ми мусимо якось це позначити. Ми отримали напівзабірник із перевернутим носієм (AKA нажатий XOR) вартістю чотирьох воріт.

Тим часом ми також значно переробили діаграму.


Єдина частина, яка виглядає потенційно оптимізованою - це середній блок добавників. Логічна вимога полягає у надповному суматорі (займає 4 вхідних біта, має два несучі вихідні біти) та повному суматорі; Ваша реалізація з двома повнорозмірними добавниками та двома напівзалежниками виглядає важко для покращення.
Пітер Тейлор

Я намагався зробити цю точну мережу вчора ввечері, але я недостатньо добре розбираюся в логічних мережах, здається.
Джо Z.

Найкраще!
кабінка

9

39 воріт

Я впевнений, що тут немає більш простих конструкцій, ніж моя. Зробити це було дуже важко. Я роблю і інші мінімальні схеми.

Затримка передачі позначається вниз вниз на кожному аркуші NAND на аркуші.

Мінімальний 3-розрядний множник

Код верифікації та тестування:

// 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

Кім Шюхус


2
Чи є у вас докази того, що ваша відповідь справедлива?
Джонатан Фрех

3
Я рекомендую схематизувати це в Logisim (безкоштовно), щоб його можна було легко побачити та перевірити.
mbomb007

Він занадто великий, щоб його можна було визнати мінімальним, за винятком, можливо, майбутнього квантового комп'ютера. Тому я використовую статистичні методи для перевірки його оптимальності. Це все ще займає надмірну кількість обчислювального часу.
КімОйгус

2
Джонатан попросив довести валідність, а не доказ оптимальності. Я не думаю, що вам потрібно доводити це дійсно. Але було б добре, якби нам було легше перевірити, чи дійсно це, а не брати за це своє слово
H.PWiz

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.