Bất cứ khi nào tediously mã hóa một mô hình lặp đi lặp lại, bạn nên sử dụng một tuyên bố tạo ra thay vì:
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
tôi đã xác minh module này bằng cách sử dụng thử nghiệm băng ghế dự bị sau: http://svn.clifford.at/handicraft/2013/array_multiplier/array_multiplier_tb.v
EDIT:
Khi @Debian đã yêu cầu một phiên bản pipelined - đây là nó. Lần này sử dụng vòng lặp for trong vùng luôn cho phần mảng.
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
Lưu ý rằng với nhiều công cụ tổng hợp nó cũng có thể chỉ cần thêm (chiều rộng) đăng ký giai đoạn sau khi bộ cộng phi pipelined và để cho các công cụ đăng ký cân bằng đường chuyền làm pipelining.
Nếu tôi phải dẫn đường thì sao? Làm thế nào tôi sẽ làm điều đó, không phải là nó một chút khó khăn hơn? – chitranna
Tôi cũng đã thêm phiên bản pipelined vào câu trả lời của mình (xem EDIT ở trên). – CliffordVienna
Tôi biết một thời gian dài. Bạn có thể đánh giá lại mã của mình không? đầu ra [width-1: 0] y; // không nên [2 * chiều rộng - 1] y; – chitranna