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.
Co, jeśli muszę to potokować? Jak mam to zrobić, czy nie jest to trochę trudniejsze? – chitranna
Dodałem również do mojej odpowiedzi wersję potokową (zobacz EDYTUJ powyżej). – CliffordVienna
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