-1

我设计了一个 16*16 的蒙哥马利乘法器。该代码使用一个 16*16 乘法器来执行三个乘法。使用相同的乘法器一个接一个地执行乘法,并且每次乘法的结果存储在寄存器中。单个 16*16 乘法器的执行频率约为 1550 MHz,但当三个乘法器串联执行时,Montgomery 乘法器(使用单个 16*16 乘法器 3 次)的频率降低到几乎 500 MHz。我想避免频率降低,并希望以单倍频器的频率对其进行操作。在这方面需要帮助。

提供了代码。(在这种情况下仅提供乘法。为简单起见,已排除加法,移位)

`define m 11
`define mbar 245
module test_mul(a,b,clk,reg2,reset);

input [15:0] a,b;
input clk,reset;
output reg [31:0] reg2;


reg [15:0] x,y;

reg [31:0] reg0,reg1;
reg [5:0] count;

wire [31:0]p;


test_mul16 a1 (x,y,clk, p);


always @ (posedge clk)
begin
if (reset)
begin  x <= a; y <= b; count= 6'd0 end

else begin

if (count == 11)
reg2 <= p;
if (count == 12)
begin x <= reg0[15:0]; y <=`mbar; end
if (count == 27)
reg1 <= p;
else if (count == 28)
begin
x <= reg1[15:0];
y <= `m;
end
else if (count == 39)
begin
reg2 <= p;
end

count = count+1;

end
end

endmodule

module test_mul16(a,b,clk,reg2);

input [15:0] a,b;
input clk;
output reg [31:0] reg2;

reg [31:0] reg0, reg1;
always @ (posedge clk)
begin
reg0<= a*b;
reg1<=reg0;
reg2<=reg1;
end
endmodule
4

1 回答 1

0

好的,所以根据 Hida 说这是一个时间问题的评论,我认为这里可能会发生一些事情。我可以帮助您改善时序,但我不确定我们能否达到 1.5Ghz。您也应该让我们知道您使用的是哪个供应商。

您有一个带有重置的 if,但您不会重置所有变量。只要你知道你没有任何未初始化的东西,那没关系。但这里真正的事情是,许多新的 FPGA 技术,如果你不需要,不希望你使用复位。我注意到您正在使用输入 a 和 b 重置 x 和 y。你必须这样做吗?如果您不必将 x 和 y 分别重置为 a 和 b,则可以将它们从重置中删除,这将有助于改善时序。

您的状态机(使用变量状态)不是一个热门的。您可能会考虑编写代码以使用一个热点,这会给您带来一点帮助。

为此,将 count 设为 40 位寄存器,将其重置为 40'h00001,然后在时钟上将其分配为 count <= {count[38:0],count[39]}; 然后使用单个位来触发您的逻辑。

接下来,看看你的 if's 你有一堆一次性的 if's。在某些情况下,您有多个 if 分配相同的变量。这可能没问题,但合成器可能不得不解决一些问题,如果你以不同的方式编码,它可能不会像它可能的效率那么高。尝试使用 case 语句。如果您遵循上面的 one-hot 建议,您的案例陈述将像这样 case(count) 40'd11 : begin do some stuff end 40'd12 : begin do some other things end etc... endcase

最后,同样在你的 IF 中,你有一些 if 和 if else 的情况。将那些按摩到上面的这个案例语句中,因为您基本上可以将优先级分配给计数 27、28 和 39。对于一个变量,值之间可以而且应该没有优先级。该值是 27、28 或 39,或其他值,并且逻辑永远不会有选择一种状态而不选择另一种状态的情况。

如果您进行其中一些更改,您的速度应该会提高。真的很想知道哪个供应商说你达到了 1.5Ghz。

于 2017-02-21T01:23:27.087 回答