奇分频电路如何实现? 负沿触发&非负沿触发
请设计一个奇分频电路,占空比为50%?
以下给出解答:
1、带负沿触发
module div //带负沿触发 #(parameter N = 5) //定义分频参数 ( input sys_clk , input sys_rst_n , output div_clk ); // 核心:在上下边沿的计数器 计数至 N/2 翻转 计数至 N-1 再翻转 // 上下边沿脉冲信号 或运算 即可得到最终的 奇分频结果 占空比50% reg clk_pose ; //上升沿 reg clk_nege ; //下降沿 reg [N:0] cnt_pose ; //上升沿计数 reg [N:0] cnt_nege ; //下降沿计数 always@(posedge sys_clk or negedge sys_rst_n) begin //在上升沿计数 if(!sys_rst_n) cnt_pose<='d0; else if(cnt_pose==N-1) cnt_pose<='d0; else cnt_pose<=cnt_pose+'d1; end always@(negedge sys_clk or negedge sys_rst_n) begin //在下升沿计数 if(!sys_rst_n) cnt_nege<=1'b0; else if(cnt_nege==N-1) cnt_nege<='d0; else cnt_nege<=cnt_nege+'d1; end always@(posedge sys_clk or negedge sys_rst_n) begin if(!sys_rst_n) clk_pose<=1'b0; else if(cnt_pose==N/2) clk_pose<=~clk_pose; else if(cnt_pose==N-1) clk_pose<=~clk_pose; else clk_pose<=clk_pose; end always@(negedge sys_clk or negedge sys_rst_n) begin if(!sys_rst_n) clk_nege<=1'b0; else if(cnt_nege==N/2) clk_nege<=~clk_nege; else if(cnt_nege==N-1) clk_nege<=~clk_nege; else clk_nege<=clk_nege; end assign div_clk= clk_nege |clk_pose ; //上升沿 和下降沿 或运算 得到 奇分频 endmodule
`timescale 1ns/1ns module tb_div(); reg sys_clk ; reg sys_rst_n ; wire div_clk ; initial begin sys_clk<=1'b0; sys_rst_n<=1'b0; #20 sys_rst_n<=1'b1; end always #10 sys_clk<=~sys_clk; div #(.N()) //可自己定义想要的分频参数 div_inst( .sys_clk (sys_clk) , .sys_rst_n (sys_rst_n) , .div_clk (div_clk) ); endmodule
波形图如下
2、不带负沿触发
module div //不带负边沿触发 #(parameter N = 5) //定义分频参数 ( input sys_clk , input sys_rst_n , output div_clk ); // 核心:构造一个与时钟相反的新时钟 在原时钟域下 在前N/2 时钟周期保持0 后面 N/2+1 ~N-1 翻转 // 在新时钟域下 在原时钟域下 在前N/2 时钟周期保持0 后面 N/2+1 ~N-1 翻转 //在新时钟域下 对分频寄存器打拍一拍 //对两个时钟域下的分频时钟寄存器想或 得到 奇分频结果 占空比50% reg clk_0 ; //原时钟域 reg clk_1 ; //新时钟域下 reg clk_2 ; //新时钟域下 reg [N:0] cnt ; //原时钟域上升沿计数 wire sys_clk_0 ; //构造的新时钟域 assign sys_clk_0=~sys_clk ; always@(posedge sys_clk or negedge sys_rst_n) begin //在上升沿计数 if(!sys_rst_n) cnt<='d0; else if(cnt==N-1) cnt<='d0; else cnt<=cnt+'d1; end always@(posedge sys_clk or negedge sys_rst_n) begin if(!sys_rst_n) clk_0<=1'b0; else if(cnt<=N/2) clk_0<=1'b0; else clk_0<=1'b1; end always@(posedge sys_clk_0 or negedge sys_rst_n) begin if(!sys_rst_n) begin clk_1<=1'b0; clk_2<=1'b0; end else if(cnt<=N/2) begin clk_1<=1'b0; clk_2<=clk_1; end else begin clk_1<=1'b1; clk_2<=clk_1; end end assign div_clk= clk_0 |clk_2 ; //对两个时钟域下的分频时钟寄存器想或 得到 奇分频结果占空比50% endmodule
`timescale 1ns/1ns module tb_div(); reg sys_clk ; reg sys_rst_n ; wire div_clk ; initial begin sys_clk<=1'b0; sys_rst_n<=1'b0; #20 sys_rst_n<=1'b1; end always #10 sys_clk<=~sys_clk; div #(.N()) //可自己定义想要的分频参数 div_inst( .sys_clk (sys_clk) , .sys_rst_n (sys_rst_n) , .div_clk (div_clk) ); endmodule
波形图如下:
以上是本人对奇分频电路的总结,若有不对的地方,敬请指正,万分感谢。
参考资料:
1、奇数分频--不使用负边沿触发verilog实现(占空比50%) - 影-fish - 博客园 (cnblogs.com)