查找 Verilog 数组中存在的最大数
Find Maximum Number present in Verilog array
我已经尝试编写一个小的 verilog 模块,它将在一个数组中找到最多 10 个数字。目前我只是想验证模块的正确性,而不是进入将执行此类任务的特定 RTL 方法。
我在综合这个模块时看到了几个寄存器。仅此而已。理想情况下,输出应为 7,位于索引 4 处,但我在 FPGA 板上或测试台上都看不到任何内容。我做错了什么?
module findmaximum(input clk,rst,output reg[3:0]max, output reg[3:0]index);
reg [3:0]corr_Output[0:9];
always@(posedge clk or posedge rst)
if(rst)
begin
corr_Output[0]=0;
corr_Output[1]=0;
corr_Output[2]=0;
corr_Output[3]=0;
corr_Output[4]=0;
corr_Output[5]=0;
corr_Output[6]=0;
corr_Output[7]=0;
corr_Output[8]=0;
corr_Output[9]=0;
end
else
begin
corr_Output[0]=0;
corr_Output[1]=0;
corr_Output[2]=0;
corr_Output[3]=0;
corr_Output[4]=7;
corr_Output[5]=0;
corr_Output[6]=0;
corr_Output[7]=0;
corr_Output[8]=0;
corr_Output[9]=0;
end
integer i;
always@(posedge clk or posedge rst)
if(rst)
begin
max=0;
index=0;
end
else
begin
max = corr_Output[0];
for (i = 0; i <= 9; i=i+1)
begin
if (corr_Output[i] > max)
begin
max = corr_Output[i];
index = i;
end
end
end
endmodule
看看你的代码,唯一可能的输出是 max=0,index=0 和重置后的一两个时钟 max=7,index=4。因此,您的合成器可能会使用更简单的逻辑优化具有等效行为的代码。
为了使查找最大值逻辑有意义,您需要定期更改 corr_Output
的值。这可以通过输入写入、LFSR(又名伪随机数生成器)和/或其他逻辑来完成。
其他问题:
同步逻辑(在时钟沿更新)应使用非阻塞 (<=
) 分配。组合逻辑应该分配阻塞(=
)。如果不遵循此指南,则仿真和综合之间存在行为差异的风险。如果您需要与中间值(如原始 max
和 index
)进行比较,则需要将逻辑分成两个始终块,如下所示。请参阅下面的代码。
此外,FPGA 往往具有有限的异步复位支持。通过从敏感列表中删除重置来使用同步重置。
always@(posedge clk) begin
if (rst) begin
max <= 4'h0;
index <= 4'h0;
end
else begin
max <= next_max;
index <= next_index;
end
always @* begin
next_max = corr_Output[0];
next_index = 4'h0;
for (i = 1; i <= 9; i=i+1) begin // <-- start at 1, not 0 (0 is same a default)
if (corr_Output[i] > next_max) begin
next_max = corr_Output[i];
next_index = i;
end
end
end
我已经尝试编写一个小的 verilog 模块,它将在一个数组中找到最多 10 个数字。目前我只是想验证模块的正确性,而不是进入将执行此类任务的特定 RTL 方法。
我在综合这个模块时看到了几个寄存器。仅此而已。理想情况下,输出应为 7,位于索引 4 处,但我在 FPGA 板上或测试台上都看不到任何内容。我做错了什么?
module findmaximum(input clk,rst,output reg[3:0]max, output reg[3:0]index);
reg [3:0]corr_Output[0:9];
always@(posedge clk or posedge rst)
if(rst)
begin
corr_Output[0]=0;
corr_Output[1]=0;
corr_Output[2]=0;
corr_Output[3]=0;
corr_Output[4]=0;
corr_Output[5]=0;
corr_Output[6]=0;
corr_Output[7]=0;
corr_Output[8]=0;
corr_Output[9]=0;
end
else
begin
corr_Output[0]=0;
corr_Output[1]=0;
corr_Output[2]=0;
corr_Output[3]=0;
corr_Output[4]=7;
corr_Output[5]=0;
corr_Output[6]=0;
corr_Output[7]=0;
corr_Output[8]=0;
corr_Output[9]=0;
end
integer i;
always@(posedge clk or posedge rst)
if(rst)
begin
max=0;
index=0;
end
else
begin
max = corr_Output[0];
for (i = 0; i <= 9; i=i+1)
begin
if (corr_Output[i] > max)
begin
max = corr_Output[i];
index = i;
end
end
end
endmodule
看看你的代码,唯一可能的输出是 max=0,index=0 和重置后的一两个时钟 max=7,index=4。因此,您的合成器可能会使用更简单的逻辑优化具有等效行为的代码。
为了使查找最大值逻辑有意义,您需要定期更改 corr_Output
的值。这可以通过输入写入、LFSR(又名伪随机数生成器)和/或其他逻辑来完成。
其他问题:
同步逻辑(在时钟沿更新)应使用非阻塞 (<=
) 分配。组合逻辑应该分配阻塞(=
)。如果不遵循此指南,则仿真和综合之间存在行为差异的风险。如果您需要与中间值(如原始 max
和 index
)进行比较,则需要将逻辑分成两个始终块,如下所示。请参阅下面的代码。
此外,FPGA 往往具有有限的异步复位支持。通过从敏感列表中删除重置来使用同步重置。
always@(posedge clk) begin
if (rst) begin
max <= 4'h0;
index <= 4'h0;
end
else begin
max <= next_max;
index <= next_index;
end
always @* begin
next_max = corr_Output[0];
next_index = 4'h0;
for (i = 1; i <= 9; i=i+1) begin // <-- start at 1, not 0 (0 is same a default)
if (corr_Output[i] > next_max) begin
next_max = corr_Output[i];
next_index = i;
end
end
end