NAND mantık kapılarını kullanarak bir çarpma makinesi oluşturun


20

Aynı türdeki önceki soruma dayanarak, NAND mantık kapılarını kullanarak bir ekleme makinesi oluşturun , bu sefer siz eklemek yerine çarpmanız isteniyor.

Giriş telleri sürer (iki kablolu) NAND mantık kapıları bir diyagram oluşturmak A1, A2, A4, B1, B2, B4, iki ikili sayılar temsil Aiçin Bçıkış teller üzerinde 0 ile 7 arasında, ve geri dönüş değerleri C1, C2, C4, C8, C16, ve C32temsil C, olan bir ürünü olduğu, Ave B.

Puanınız kullandığınız NAND geçidi sayısıyla belirlenir (kapı başına 1 puan). İşleri basitleştirmek için, diyagramınızda AND, OR, NOT ve XOR geçitlerini aşağıdaki karşılık gelen puanlarla kullanabilirsiniz:

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

Bu puanların her biri, ilgili kapıyı inşa etmek için gereken NAND kapılarının sayısına karşılık gelir.

En düşük puan kazanır.


Logisim'de son bir örnek yapmaya çalışıyorum. Bu zor.
Joe Z.

Okulumda bu kadar şey var, teşekkürler.
Johannes Kuhn

7
Bu gibi görevler için evrensel bir optimize edicim var. Bir k-çıkışı boole işlevini hesaplamak için en kısa programı bulur. Bir hafta verirsem, bulduğu 13 kapı 2x2 çarpanının optimal olup olmadığını söyleyebilirdi. 3x3? Bitmeden öleceğim.
boothby

1
Bu 13 kapı 2x2 çarpanı optimal (ve Jan'ın cevabında yer alıyor). Bununla ve optimize edebileceğim birkaç parça daha, 60'ın bu sorun için en uygun olduğundan şüpheleniyorum. Umarım birileri beni yanlış kanıtlar.
boothby

@boothby Pek değil. Toplayıcı ağaçların saf uygulaması 18 kapılı bir çözüme (4 AND, 2 yarım toplayıcı) yol açıyor, bu da beni bir fikre götürüyor: 13-kapıyı kullanmak için ^ k ^ k ^ k ^ k ^ k çalabilmeliyim 2x2 çarpanı.
John Dvorak

Yanıtlar:


24

60 55 50 48 kapı

48 kapılı çarpan


Orijinal (60 kapı) sistematik bir yaklaşımdı - her haneyi her biri ile çarpın ve sonra bunları toplayın. Yani Wallace ağaçları ve Dadda ağaçları

60 kapılı çarpan

Üst yarı çarpma ağıdır - her haneyi her biri ile çarpın ve aynı çıktıya sahip grup çıktı basamaklarını. Kapıları kurtarmak için bazı bitler ters çevrildi.

İkinci yarı toplayıcı ağdır. Her kutu tek bir toplayıcıyı temsil eder - ya bir yarı toplayıcı (5 kapı - 1x XOR ve bir invertör) veya bir tam toplayıcı (9 kapı - 2x XOR ve NAND ters taşıma bitleri). Üst girişler, alt çıkış toplam, sol çıkış gerdirme. önceki meydan okumayı gör

Daha sonra 2x2 çarpanı, @boothby tarafından bulunan en uygun boyut olan özel olarak oluşturulmuş 13 kapılı bir ağ için elle optimize edilmiştir . Teşekkürler!

Düşük bit köşesine yapıştırmak ve toplayıcı ağacını yeniden optimize etmek beş kapıdan tasarruf sağlar (revizyon # 2'ye bakın). Bununla birlikte, yüksek bit köşesine yapıştırılması da çakışma oluşturur. Bununla birlikte, biraz matematik bize, yüksek çarpanın düşük bitini düşürmenin örtüşmeyi çözdüğünü ve geriye kalan iki bit eklemek ve bir şeyler toplamak olduğunu söyler.

Bu tek başına maalesef herhangi bir tasarruf sağlamaz, ancak iki optimizasyon açar. İlk olarak, iki çarpanın iki ortak kapısı vardır ve birbirine birleştirilebilir. Bu noktada, 55 yaşındayız. İkincisi, toplama ağında, yarı toplayıcıya ihtiyacımız yok çünkü taşınmasının sıfır olacağını biliyoruz. Bir OR ile değiştirebiliriz. OR, girişleri ters çevrilmiş bir NAND'dır. Bu, toplam beş kapı tasarrufu için, her dalda iki 2 zincirli NOT ile üretilir ve daha sonra çıkarılabilir. Ne yazık ki, C16'daki yarı toplayıcı hala taşıyor, bu yüzden orada aynı şeyi yapamayız. Üçüncü olarak, tam bir toplayıcının kullanışlı bir özelliği vardır: girişlerini ve çıktılarını ters çevirirseniz, yine de aynı şekilde davranır. Tüm girişleri zaten ters çevrildiğinden, invertörleri de arkasına taşıyabiliriz. İki defa. Orijinalinde de aynısını yapabilirdik ama ... Oh iyi. Hala iki ters girişi olan bir yarı toplayıcı var. Bu kısmı daha da optimize etmek istiyorum, ama yapabileceğimden şüpheliyim.

Bir bileşenin içinden NOT DEĞİL çektiğimizden, bunu bir şekilde belirtmeliyiz. Dört kapılı bir maliyetle ters taşıyıcılı (AKA XOR'a hafifçe vurulmuş) bir yarı toplayıcı elde ettik.

Bu arada, diyagramı da önemli ölçüde yeniden çizdik.


Potansiyel olarak optimize edilebilir görünen tek parça, toplayıcıların orta bloğudur. Mantıksal gereklilik, süper-toplayıcı (4 giriş biti alır, iki taşıma çıkış bitine sahiptir) ve tam bir toplayıcı içindir; iki tam toplayıcı ve iki yarım toplayıcı ile uygulamanızı geliştirmek zor görünüyor.
Peter Taylor

Dün gece tam olarak bu ağı yapmaya çalıştım, ama mantıksal ağlarda yeterince bilgili değilim.
Joe Z.

En mükemmel!
boothby

9

39 kapı

Burada benimkinden daha basit tasarımlar olmadığından eminim. Yapması çok zordu. Başka minimal devreler de yapıyorum.

İletim gecikmesi, sayfadaki her bir NAND geçidinin aşağı konumuyla gösterilir.

Minimum 3 bit çarpan

Verilog kodu ve testi:

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


2
Cevabınızın geçerli olduğuna dair bir kanıtınız var mı?
Jonathan Frech

3
Bunu Logisim'de (ücretsiz) diyagramlamayı tavsiye ederim , böylece kolayca görülebilir ve test edilebilir.
mbomb007

Belki de gelecekteki bir kuantum bilgisayarı dışında, asgari olarak kanıtlanması çok büyük. Bu yüzden onun en iyi olduğunu doğrulamak için istatistiksel yöntemler kullanıyorum. Yine de aşırı miktarda hesaplama süresi gerekiyor.
KimOyhus

2
Jonathon, bir iyimserlik kanıtı yerine geçerlilik kanıtı istedi. Geçerli olduğunu kanıtlamanız gerektiğini düşünmüyorum . Ancak,
sözünüzü

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.