【Verilog HDL 训练】第 11 天(分频电路)
【摘要】 设计一个占空比50%的三分频电路。
针对这个分频器,博文的末尾会给出一个反面教材,这是我上次写的一个分频器,看起来很好,其实是不能综合的。针对其中的错误,我令立博文记录之:【 Verilog 】always@()的敏感源中为什么不能双边沿触发?为什么不能双时钟触发?
感谢学习道路上的前辈给予的指导:下面的分频器思路是:
画了个草图:
给出Verilog HD...
设计一个占空比50%的三分频电路。
针对这个分频器,博文的末尾会给出一个反面教材,这是我上次写的一个分频器,看起来很好,其实是不能综合的。针对其中的错误,我令立博文记录之:【 Verilog 】always@()的敏感源中为什么不能双边沿触发?为什么不能双时钟触发?
感谢学习道路上的前辈给予的指导:下面的分频器思路是:
画了个草图:
给出Verilog HDL描述:
module Freq_divide(
input clk,
input rst_n,
output clk_divide
);
//先写一个占空比为1/3的分频时钟
reg clk_1_3;
reg [2:0] count;
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
count <= 0;
clk_1_3 <= 0;
end
else if(count == 1) begin
clk_1_3 <= ~clk_1_3;
count <= count + 1;
end
else if(count == 2) begin
count <= 0;
clk_1_3 <= ~clk_1_3;
end
else begin
count <= count + 1;
clk_1_3 <= clk_1_3;
end
end
reg clk_1_3_r;
//下降沿采样上述时钟
always@(negedge clk or negedge rst_n) begin
if(!rst_n) begin
clk_1_3_r <= 0;
end
else begin
clk_1_3_r <= clk_1_3;
end
end
//产生分频时钟
assign clk_divide = clk_1_3 | clk_1_3_r;
endmodule
再给出testbench文件以及行为仿真时序图:
`timescale 1ns / 1ps
module clk_divide_tb(
);
reg clk;
reg rst_n;
wire clk_divide;
initial begin
clk = 0;
forever
#2 clk = ~clk;
end
initial begin
rst_n = 0;
#10
rst_n = 1;
end
Freq_divide u0(
.clk(clk),
.rst_n(rst_n),
.clk_divide(clk_divide)
);
endmodule
可见,功能完好;
再给出RTL电路图:
3分频占空比为50的分频器到底为止,下面是一个反面教材:
记住,这种写法万万不可!
对于奇分频电路,我的思路是:
以3分频为例,那么周期为原来的3倍,那么对原时钟clk,经历1.5个时钟上升沿,分频时钟翻转一次即可。
可是这里有一个问题就是如何实现1.5时钟上升沿呢?(上升沿和下降沿都算?)
我们先对原时钟取反,即相位相差180°,得到时钟clk_reverse;之后对时钟clk和clk_reverse的上升沿计数,计数到2,分频时钟翻转一次即可。
Verilog描述为:
module Freq_divide(
input clk,
input rst_n,
output reg clk_divide
);
wire clk_reverse;
assign clk_reverse = ~clk;
reg [3:0] count;
always @ (posedge clk or posedge clk_reverse or negedge rst_n) begin
if(!rst_n) begin
count <= 0;
end
else if(count < 2) begin
count <= count + 1;
end
else begin
count <= 0;
end
end
always @ (posedge clk or posedge clk_reverse or negedge rst_n) begin
if(!rst_n) begin
clk_divide <= 0;
end
else if(count == 2) begin
clk_divide <= ~clk_divide;
end
else begin
clk_divide <= clk_divide;
end
end
endmodule
仿真文件:
`timescale 1ns / 1ps
module clk_divide_tb(
);
reg clk;
reg rst_n;
wire clk_divide;
initial begin
clk = 0;
forever
#2 clk = ~clk;
end
initial begin
rst_n = 0;
#10
rst_n = 1;
end
Freq_divide u0(
.clk(clk),
.rst_n(rst_n),
.clk_divide(clk_divide)
);
endmodule
行为仿真时序图:
可见,分频时钟clk_divide周期为原时钟clk的3倍,即完成了3分频的工作。
文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。
原文链接:reborn.blog.csdn.net/article/details/90215383
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)