奇数分频模块算法及verilog实现

奇数倍分频有多种实现方法,下面介绍常用的错位异或法的原理:
以下是一个3分频电路的verilog代码:
module clk_div_3(clk_in, rst_n, clk_out);
input clk_in;
input rst_n;
output clk_out;

reg [1:0] cnt_p, cnt_n;
reg clk_out_p, clk_out_n;

always @(posedge clk_in) begin
if(!rst_n) begin
cnt_p <= 0;
clk_out_p <= 0;
end
else begin
if(cnt_p == 2'b10)begin
cnt_p <= 2'b00;
clk_out_p <= clk_out_p;
end
else begin
cnt_p <= cnt_p + 1;
clk_out_p <= ~clk_out_p;
end

end
end

always @(negedge clk_in) begin
if(!rst_n) begin
cnt_n <= 0;
clk_out_n <= 0;
end
else begin
if(cnt_n == 2'b10)begin
cnt_n <= 2'b00;
clk_out_n <= clk_out_n;
end
else begin
cnt_n <= cnt_n + 1;
clk_out_n <= ~clk_out_n;
end

end
end

assign clk_out = clk_out_p | clk_out_n;


endmodule

用testbenchwaveform产生逻辑仿真为:

[img]http://dl.iteye.com/upload/attachment/371630/2395a05a-599f-3ea0-aabc-305491915432.bmp[/img]


[color=darkred][size=medium]总结:这种错位异或法可以推广实现任意的奇数分频:对于实现占空比为50%的N倍奇数分频,首先进行上升沿触发的模N计数,计数到某一选定值(这里俺一般选第一个时钟沿)时进行输出时钟翻转,然后经过(N-1)/2再次进行翻转得到一个占空比非50%的奇数N分频时钟;再者同时进行下降沿触发的模N计数,到和上升沿触发输出时钟翻转选定值相同值时,进行输出时钟翻转,同样经过(N-1)/2时,输出时钟再次翻转生成占空比非50%的奇数N分频时钟。两个占空比非50%的N分频时钟相或运算,得到占空比为50%的奇数N分频时钟。[/size][/color]

以下是一个7分频电路的verilog代码:
module clk_div_7(clk_in, rst_n, clk_out);
input clk_in;
input rst_n;
output clk_out;

reg [2:0] cnt_p, cnt_n;
reg clk_out_p, clk_out_n;

always @(posedge clk_in) begin
if(!rst_n) begin
cnt_p <= 0;
clk_out_p <= 0;
end
else begin
if(cnt_p == 3'b110) begin
cnt_p <= 0;
clk_out_p <= clk_out_p;
end
else if(cnt_p == 3'b011) begin
cnt_p <= cnt_p + 1;
clk_out_p = ~clk_out_p;
end
else if(cnt_p == 3'b000) begin
cnt_p <= cnt_p + 1;
clk_out_p = ~clk_out_p;
end
else begin
cnt_p <= cnt_p + 1;
clk_out_p <= clk_out_p;
end
end
end

always @(negedge clk_in) begin
if(!rst_n) begin
cnt_n <= 0;
clk_out_n <= 0;
end
else begin
if(cnt_n == 3'b110) begin
cnt_n <= 0;
clk_out_n <= clk_out_n;
end
else if(cnt_n == 3'b011) begin
cnt_n <= cnt_n + 1;
clk_out_n = ~clk_out_n;
end
else if(cnt_n == 3'b000) begin
cnt_n <= cnt_n + 1;
clk_out_n = ~clk_out_n;
end
else begin
cnt_n <= cnt_n + 1;
clk_out_n <= clk_out_n;
end
end
end

assign clk_out = clk_out_p | clk_out_n;


endmodule

逻辑仿真图为:

[img]http://dl.iteye.com/upload/attachment/371634/df653e6e-eea5-33d2-9ffc-c36bea852973.bmp[/img]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值