真实面经题目 · 原创解析
Verilog 写一个 32 分频电路时,翻转条件和计数边界怎么确定?
这题考偶数分频的边界理解,32 分频且希望 50% 占空比时,输出应每 16 个输入周期翻转一次。
真实面经题目 · 原创解析
这题考偶数分频的边界理解,32 分频且希望 50% 占空比时,输出应每 16 个输入周期翻转一次。
32 分频的意思是输出周期等于输入周期的 32 倍。如果要求接近 50% 占空比的方波,输出半周期就是 16 个输入时钟,所以计数器计 0 到 15,达到 15 时清零并翻转输出。这样两次翻转组成一个完整输出周期,共 32 个输入周期。写代码时用 4 位计数器即可表示 0 到 15,时序逻辑用非阻塞赋值,复位时计数器和输出都清零。容易错的是计到 16 再翻转,或者把每 32 拍翻转一次,那样得到的是 64 分频方波。
若输出是方波时钟,N 分频通常指输出完整周期是输入周期的 N 倍。方波有高低两个半周期,所以偶数 N 分频时,每 N/2 个输入周期翻转一次。
32 的一半是 16,因此输出每 16 个输入周期翻转。计数器可以从 0 计到 15,命中 15 时翻转输出并把计数器清零。两次翻转后完成 32 个输入周期。
0 到 15 共有 16 个状态,4 位计数器足够。若写成 cnt == 16,至少需要 5 位,而且半周期会变成 17 拍,分频比错误。
这种逻辑分频输出若要驱动大量时序逻辑,要考虑时钟网络和约束。很多工程更推荐使用 clock enable,或使用器件专用时钟资源产生真正的派生时钟。
module div32 (
input wire clk,
input wire rst_n,
output reg clk_div32
);
reg [3:0] cnt;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
cnt <= 4'd0;
clk_div32 <= 1'b0;
end else if (cnt == 4'd15) begin
cnt <= 4'd0;
clk_div32 <= ~clk_div32;
end else begin
cnt <= cnt + 4'd1;
end
end
endmodule 那就不翻转输出,而是在计数到 31 时打一拍 pulse,并清零计数器。它是周期性使能,不是 50% 占空比分频方波。
单边沿简单计数通常不能天然做到严格 50% 占空比,需要双边沿、PLL/MMCM 或更复杂结构,且要考虑可综合性和时钟资源。
我会至少做仿真、lint、综合后资源检查、时序约束和 STA;涉及跨时钟域还要做 CDC 检查,涉及板级接口还要结合时序裕量和实测波形验证。