0%

关于常量不加位数限制的坑

遇坑代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
module freq_div(
input clk_i,
input en,

output clk_o
);

parameter CNT_MAX = 25000 -1;
reg [12:0] clk_cnt = 13'b0;
reg clk_o_reg = 1'b0;

assign clk_o = clk_o_reg;

always @(posedge clk_i) begin
if (en) begin
if (clk_cnt == CNT_MAX) begin
clk_cnt <= 13'b0;
clk_o_reg <= ~clk_o_reg;
end else begin
clk_cnt <= clk_cnt + 1'b1;
end
end else begin
clk_cnt <= clk_cnt;
end
end

endmodule

综合后的结果如下:

image-20201023001837809

于是这个错误导致了动态数码管显示只显示了最低位的数码管。(但是由于Vivado并没有提示这个模块有任何报错or Warning,所以我一直没有注意到freq_div综合后的结果,一直去看该错误导致的另一个出现Warning的模块了)

导致综合并没有提示Error/Warning的罪魁祸首就是第8行的parameter CNT_MAX = 25000 -1。而本质错误是由于我的clk_cnt位数设置错误,因为24999已经超过了13位的最大范围。如果将第8行改为parameter CNT_MAX = 13'd25000 -1,那么综合后会产生常数因超过最大值而被截断的Warning(如下图),于是就能马上发现错误而改正。

image-20201023003048134

clk_cnt的位数改为32位,并将第8行改为parameter CNT_MAX = 32'd25000 -1,之后综合结果正常,如下:

image-20201023002502559

通过本次血泪史学到的教训——常数一定也要加位数限制,不要为了图方便而不写位数!同时写之前也要计算好常数的位数!