Costruisci una macchina moltiplicatrice usando le porte logiche NAND


20

Sulla base della mia precedente domanda dello stesso tipo, Costruisci una macchina addizionatrice usando le porte logiche NAND , questa volta ti viene chiesto di moltiplicare invece di aggiungere.

Costruire un diagramma di cancelli (bifilare) logiche NAND che porterà i cavi di ingresso A1, A2, A4, B1, B2, B4, rappresentano due numeri binari Aa Bda 0 a 7, e valori di ritorno sui fili di uscita C1, C2, C4, C8, C16, e C32, rappresentando C, che è il prodotto di Ae B.

Il tuo punteggio è determinato dal numero di gate NAND che usi (1 punto per gate). Per semplificare le cose, puoi usare le porte AND, OR, NOT e XOR nel diagramma, con i seguenti punteggi corrispondenti:

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

Ognuno di questi punteggi corrisponde al numero di porte NAND necessarie per costruire la porta corrispondente.

Il punteggio più basso vince.


Sto cercando di fare un esempio dell'ultimo posto in Logisim. Questa roba è difficile.
Joe Z.

Ne ho abbastanza di queste cose nella mia scuola, no grazie.
Johannes Kuhn,

7
Ho un ottimizzatore universale per attività come questa. Trova di sicuro il programma più breve per calcolare una funzione booleana k-output. Se gli dessi una settimana, potrebbe dirmi se il moltiplicatore 13 gate 2x2 trovato è ottimale. 3x3? Sarò morto prima che finisca.
stand dal

1
Quel moltiplicatore 13 gate 2x2 è ottimale (e contenuto nella risposta di Jan). Detto questo, e alcuni altri pezzi che posso ottimizzare, sospetto fortemente che 60 sia ottimale per questo problema. Spero davvero che qualcuno mi dimostri di sbagliare.
stand dal

@boothby Non proprio. Un'applicazione ingenua degli alberi di vipera porta a una soluzione a 18 porte (4 AND, 2 semi-additivi), che mi porta a un'idea: dovrei essere in grado di rubare ^ k ^ k ^ k ^ k ^ k utilizzare il 13-gate Moltiplicatore 2x2.
John Dvorak,

Risposte:


24

60 55 50 48 porte

Moltiplicatore a 48 gate


L'originale (60 porte) era l'approccio sistematico: moltiplicare ogni cifra con ciascuna e quindi sommarle. Vale a dire, vedere gli alberi Wallace e gli alberi Dadda

Moltiplicatore a 60 gate

La metà superiore è la rete di moltiplicazione: moltiplica ciascuna cifra con ciascuna e raggruppa le cifre di output con lo stesso peso. Alcuni bit sono stati lasciati invertiti per salvare le porte.

La seconda metà è la rete dei sommatori. Ogni casella rappresenta un singolo sommatore - o un mezzo sommatore (5 porte - 1x XOR e un inverter), oppure un sommatore completo (9 porte - 2x XOR e NAND i bit di trasporto invertiti). La parte superiore sono input, l'output inferiore è la somma, l'output sinistro è il carry-out. vedi la sfida precedente

Il moltiplicatore 2x2 è stato quindi ottimizzato a mano su una rete a 13 gate personalizzata, che è la dimensione ottimale trovata da @boothby . Grazie!

Incollandolo nell'angolo di bit basso e riaottimando l'albero sommatore si salvano cinque porte (vedere la revisione n. 2). Incollarlo anche nell'angolo di bit alto, tuttavia, produce sovrapposizioni. Un po 'di matematica ci dice, tuttavia, che far cadere il bit basso del moltiplicatore alto risolve la sovrapposizione e ciò che resta da fare è aggiungere i due bit rimanenti e riassumere le cose.

Questo da solo, purtroppo, non offre alcun risparmio, ma apre due ottimizzazioni. Innanzitutto, i due moltiplicatori hanno due porte in comune e possono essere fuse insieme. A questo punto, siamo tornati a 55. In secondo luogo, nella rete di addizione, non abbiamo bisogno di un mezzo inseritore perché sappiamo che il suo carry sarà zero. Possiamo sostituirlo con un OR. Un OR è una NAND con i suoi ingressi invertiti. Questo ci produce con due 2 catene di NOT su ciascun ramo, che possono quindi essere rimosse, per un risparmio totale di cinque porte. Sfortunatamente, il mezzo-sommatore al C16 porta ancora, quindi non possiamo fare lo stesso lì. Terzo, un sommatore completo ha una proprietà utile: se si inverte i suoi input e i suoi output, si comporta comunque allo stesso modo. Poiché tutti i suoi ingressi sono già invertiti, possiamo anche spostare gli inverter dietro di esso. Due volte. Avremmo potuto fare lo stesso nell'originale, ma ... Oh bene. Abbiamo ancora un mezzo sommatore con due ingressi invertiti. Voglio ottimizzare di più questa parte, ma dubito di poterlo fare.

Dato che stiamo estraendo un NOT dall'interno di un componente, dobbiamo indicarlo in qualche modo. Abbiamo ottenuto un mezzo sommatore con carry invertito (AKA tappato XOR) al costo di quattro porte.

Nel frattempo, abbiamo anche ridisegnato in modo significativo il diagramma.


L'unica parte che sembra potenzialmente ottimizzabile è il blocco centrale di additivi. Il requisito logico è per un superfull-adder (accetta 4 bit di input, ha due bit di output carry) e un sommatore completo; l'implementazione con due full-adder e due half-adder sembra difficile da migliorare.
Peter Taylor,

Ho cercato di creare questa rete esatta ieri sera, ma non sono abbastanza esperto nelle reti logiche, a quanto pare.
Joe Z.

Eccellente!
stand dal

9

39 porte

Sono abbastanza sicuro che non ci siano progetti più semplici dei miei qui. È stato molto difficile da realizzare. Realizzo anche altri circuiti minimi.

Il ritardo di trasmissione è indicato dalla posizione verso il basso di ciascuna porta NAND sul foglio.

Moltiplicatore minimo a 3 bit

Codice Verilog e test:

// 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
Hai una prova che la tua risposta è valida?
Jonathan Frech,

3
Consiglierei questo diagramma in Logisim (è gratuito), in modo che possa essere facilmente visto e testato.
mbomb007,

È troppo grande per essere dimostrato come minimo, tranne forse da un futuro computer quantistico. Quindi uso metodi statistici per verificarne l'ottimalità. Ci vuole ancora una quantità eccessiva di tempo di elaborazione.
KimOyhus,

2
Jonathon ha chiesto una prova di validità, piuttosto che una prova di ottimalità. Non credo sia necessario dimostrarlo valido. Ma sarebbe bello se fosse più facile per noi testare se questo è valido, piuttosto che prendere la parola per questo
H.Pwiz,

4
Questo funziona: provalo online!
Anders Kaseorg,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.