基于verilog分频器总结
使用环境:Quartus II 8.0 + DE2(Cyclone II EP2C35F627C6)
1 占空比为50%的6分频电路。
源代码:
module clk_mod6_divide(
//input
clk,
rst_n,
//output
clk_divide,
);
input clk;
input rst_n;
output clk_divide;
reg clk_divide;
reg [2:0] cnt;
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
cnt <= 3'b0;
else if (cnt == 3'b101) // 0~5
cnt <= 3'b0;
else
cnt <= cnt + 1;
end
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
clk_divide <= 1'b0;
else if (cnt > 2) //修改分频占空比
clk_divide <= 1'b1;
else
clk_divide <= 1'b0;
end
endmodule
时序仿真图:
小结:
计数器为异步复位(当复位信号有效时,计数器立即复位不等时钟上升沿)。计数器5边界算在计数器计数范围内。注意占空比的修改。
2 占空比为50%的8分频电路。
方法1:
源代码:
module clk_mod8_divide(
//input
clk,
rst_n,
//output
clk_divide,
);
input clk;
input rst_n;
output clk_divide;
reg clk_divide;
reg [2:0] cnt;
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
cnt <= 3'b0;
else
cnt <= cnt + 1;
end
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
clk_divide <= 1'b0;
else if (cnt > 3)
clk_divide <= 1'b1;
else
clk_divide <= 1'b0;
end
endmodule
方法2:
源代码:
module clk_mod8_divide(
//input
clk,
rst_n,
//output
clk_divide,
);
input clk;
input rst_n;
output clk_divide;
//reg clk_divide;
reg [2:0] cnt;
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
cnt <= 3'b0;
else
cnt <= cnt + 1;
end
assign clk_divide = cnt[2]; //语句1
endmodule
小结:通过对8分频仿真,cnt[2]的时序与输出的分频时钟时序完全一致,因此可以用cnt[2]作为分频结果输出。进一步在模为2^N次分频时,可以用语句1的编码方式,可以节约逻辑资源。
方法3:
源代码:
module clk_mod8_divide (
//input
clk,
rst_n,
//output
clk_divide,
);
input clk;
input rst_n;
output clk_divide;
reg clk_divide;
reg [1:0] cnt; \\不同处
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
cnt <= 3'b0;
else
cnt <= cnt + 1;
end
always @(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
clk_divide <= 1'b0;
else if (cnt == 2) \\不同处
clk_divide <= ~clk_divide ;
end
endmodule
小结:方法3的写法分频的次数只能是2^(cnt的位数+1),本实验为cnt的位数为2.
总结;分频器关键在于计数器的边界值。
参考:王钿 卓兴旺. 基于Verilog的数字系统应用设计(第2版) 北京:国防工业出版社. 2007