2013-05-23 13 views
6

Wiem, jak zaprojektować mnożnik macierzy 4x4, ale jeśli zastosuję tę samą logikę, kodowanie stanie się nudne.Jak zaprojektować mnożnik macierzy 64 x 64 bit w Verilog?

  • 4 x 4 - 16 produkty częściowego
  • 64 x 64 - 4096 produktów częściowych.

Wraz z 8 pełnymi dodawcami i 4 dodawaczami połówek, ile pełnych sumatorów i półrozpakowaczy jest potrzebnych dla 64 x 64 bitów. Jak zmniejszyć liczbę produktów częściowych? Czy istnieje prosty sposób na rozwiązanie tego problemu?

Odpowiedz

8

Ilekroć żmudnego kodowania powtarzalny wzór należy użyć oświadczenie generowania zamiast:

module array_multiplier(a, b, y); 

parameter width = 8; 
input [width-1:0] a, b; 
output [width-1:0] y; 

wire [width*width-1:0] partials; 

genvar i; 
assign partials[width-1 : 0] = a[0] ? b : 0; 
generate for (i = 1; i < width; i = i+1) begin:gen 
    assign partials[width*(i+1)-1 : width*i] = (a[i] ? b << i : 0) + 
            partials[width*i-1 : width*(i-1)]; 
end endgenerate 

assign y = partials[width*width-1 : width*(width-1)]; 

endmodule 

I zostały zweryfikowane ten moduł za pomocą następującego laboratoryjnej: http://svn.clifford.at/handicraft/2013/array_multiplier/array_multiplier_tb.v

EDIT:

Jako że @Debian poprosił o wersję potokową - oto jest. Tym razem za pomocą pętli for w obszarze zawsze dla części tablicowej.

module array_multiplier_pipeline(clk, a, b, y); 

parameter width = 8; 

input clk; 
input [width-1:0] a, b; 
output [width-1:0] y; 

reg [width-1:0] a_pipeline [0:width-2]; 
reg [width-1:0] b_pipeline [0:width-2]; 
reg [width-1:0] partials [0:width-1]; 
integer i; 

always @(posedge clk) begin 
    a_pipeline[0] <= a; 
    b_pipeline[0] <= b; 
    for (i = 1; i < width-1; i = i+1) begin 
     a_pipeline[i] <= a_pipeline[i-1]; 
     b_pipeline[i] <= b_pipeline[i-1]; 
    end 

    partials[0] <= a[0] ? b : 0; 
    for (i = 1; i < width; i = i+1) 
     partials[i] <= (a_pipeline[i-1][i] ? b_pipeline[i-1] << i : 0) + 
       partials[i-1]; 
end 

assign y = partials[width-1]; 

endmodule 

Należy zauważyć, że z wielu narzędzi syntezy jest to również możliwe, aby po prostu dodać (szerokość) zarejestrować etapy po non-potokowym żmija i niech narzędzia równoważenia zarejestrować przepustkę wykonać rurociąg.

+0

Co, jeśli muszę to potokować? Jak mam to zrobić, czy nie jest to trochę trudniejsze? – chitranna

+0

Dodałem również do mojej odpowiedzi wersję potokową (zobacz EDYTUJ powyżej). – CliffordVienna

+0

Wiem od dawna. Czy możesz ponownie ocenić swój kod? wyjście [szerokość-1: 0] y; // nie powinno być [2 * szerokość - 1] y; – chitranna

Powiązane problemy