奇分频电路如何实现? 负沿触发&非负沿触发

请设计一个奇分频电路,占空比为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)

posted @ 2023-07-27 15:24  来碗回锅肉盖饭  阅读(60)  评论(0编辑  收藏  举报