Eliminowanie nieużywanych bitów: tworzenie syntezowalnych wielowymiarowych tablic o różnych wymiarach
To jest kolejne pytanie zW jaki sposób mogę iteracyjnie tworzyć magistrale sparametryzowanego rozmiaru, aby połączyć moduły również utworzone iteracyjnie?. Odpowiedź jest zbyt skomplikowana, aby odpowiedzieć w komentarzu, a rozwiązanie może być pomocne dla innych SO. To pytanie jest następującesamodzielna odpowiedź format. Zachęca się do dodawania odpowiedzi.
Poniższy kod działa i używa tablicy dwukierunkowej.
module Multiplier #(parameter M = 4, parameter N = 4)(
input [M-1:0] A, //Input A, size M
input [N-1:0] B, //Input B, size N
output [M+N-1:0] P ); //Output P (product), size M+N
wire [M+N-1:0] PP [N-1:0]; // Partial Product array
assign PP[0] = { {N{1'b0}} , { A & {M{B[0]}} } }; // Pad upper bits with 0s
assign P = PP[N-1]; // Product
genvar i;
generate
for (i=1; i < N; i=i+1)
begin: addPartialProduct
wire [M+i-1:0] gA,gB,gS; wire Cout;
assign gA = { A & {M{B[i]}} , {i{1'b0}} };
assign gB = PP[i-1][M+i-1:0];
assign PP[i] = { {(N-i){1'b0}}, Cout, gS}; // Pad upper bits with 0s
RippleCarryAdder#(M+i) adder( .A(gA), .B(gB), .S(gS), .Cin(1'b0), .* );
end
endgenerate
endmodule
Niektóre bity nigdy nie są używane, na przykładPP[0][M+N-1:M+1]
. Syntezator zazwyczaj usuwa te bity podczas optymalizacji i prawdopodobnie ostrzega. Niektóre syntezatory nie są wystarczająco zaawansowane, aby zrobić to poprawnie. Aby rozwiązać ten problem, projektant musi wdrożyć dodatkową logikę. W tym przykładzie parametr dla wszystkich RippleCarryAdder będzie ustawiony naM+N
. Dodatkowy obszar logiki marnotrawstwa i silnie obniża wydajność.
W jaki sposób niewykorzystane bity można bezpiecznie wyeliminować? Czy można używać tablic wielowymiarowych o różnych wymiarach? Czy kod końcowy będzie czytelny i możliwy do debugowania?