时间、波特率
TIME_100MS - 1
的具体含义
以流水灯代码为例:
parameter TIME_100MS = 5000000; // 注释说明:100ms对应5000000个时钟周期(20ns/周期)
-
TIME_100MS 的计算逻辑 100ms(0.1 秒)对应的时钟周期数为: 因此,
TIME_100MS
代表 “100 毫秒对应的时钟周期数”。 -
为什么减 1? 计数器通常从 0 开始计数,当计数值达到
N-1
时,实际已完成 N 次计数。例如:- 若要计数到 3(0,1,2,3),实际计数次数为 4 次(从 0 开始)。
- 因此,当需要计数 N 个周期时,比较条件应为
count == N-1
。 在代码中, - ==
if(s0_cnt == TIME_100MS - 1)
表示:当s0_cnt
从 0 计数到 4,999,999 时,恰好完成 5,000,000 个时钟周期的计数,对应 100 毫秒的延时。==
三、实际应用场景
在流水灯模块中,TIME_100MS - 1
用于控制每个 LED 状态的保持时间:
- 每个状态(如 S0、S1 等)对应一个计数器(如 s0_cnt、s1_cnt)。
- 当计数器计满
TIME_100MS - 1
时,状态切换,LED 显示下一个模式。 - 最终实现每个 LED 状态保持 100 毫秒,形成流水灯效果。
四、延伸:计数器设计的常见误区
- 误区 1:==直接使用
count == N
若不减 1,计数器需从 0 计数到 N,实际计数次数为 (N+1) 次,导致延时超过预期。== - 误区 2:忽略时钟周期与时间的换算 需确保
TIME_100MS
的值与实际时钟频率匹配,例如:- ==时钟频率为 50MHz(周期 20ns)时,100ms 对应 周期。==
- 若时钟频率改为 100MHz(周期 10ns),则 100ms 对应 周期。
五、优化建议(针对流水灯代码)
- 统一计数器逻辑 原代码中每个状态对应独立计数器,可简化为共用一个计数器:
reg [23:0] cnt; always @(posedge clk or negedge rst_n) begin if (!rst_n) cnt <= 0; else if (curr_st == curr_st) // 当前状态持续时计数 cnt <= cnt + 1; else cnt <= 0; end // 状态切换条件改为:if (cnt == TIME_100MS - 1)
波特率
parameter baud_num=5208; // 50MHz时钟下的9600bps (50,000,000/9600 ≈ 5208)