设计一个1-8分频电路?要求占空比50%
请设计一个1-8分频电路,占空比50%。
这样的分频电路其中有奇分频和偶分频,需要在一个电路中实现。其中奇分频和偶分频是在输入确定的分频值下,对其进行相应的奇偶分频。
给出设计的代码&激励&仿真波形
module fenpin_8 ( input sys_clk , input sys_rst_n , input [3:0] in , output clk_out ); //分频参数1-8 parameter DIV1= 1; parameter DIV2= 2; parameter DIV3= 3; parameter DIV4= 4; parameter DIV5= 5; parameter DIV6= 6; parameter DIV7= 7; parameter DIV8= 8; reg [7:0] fen_en ; //由输入决定对应的分频使能信号是否有效 reg clk_even ; //偶分频 计数翻转 reg clk_odd ; //奇分频 计数翻转 上升沿 reg clk_odd_r ; //奇分频 下降沿 对之前的信号打拍 reg [3:0] cnt ; //计数器 确定翻转的位置 always@(*) begin case(in) DIV1 : fen_en<=8'b0000_0001; DIV2 : fen_en<=8'b0000_0010; DIV3 : fen_en<=8'b0000_0100; DIV4 : fen_en<=8'b0000_1000; DIV5 : fen_en<=8'b0001_0000; DIV6 : fen_en<=8'b0010_0000; DIV7 : fen_en<=8'b0100_0000; DIV8 : fen_en<=8'b1000_0000; default : fen_en<=8'b0000_0000; endcase end always@(posedge sys_clk or negedge sys_rst_n) begin if(!sys_rst_n) begin clk_even<=1'b0; clk_odd<=1'b0; end else begin case(1'b1) fen_en[0] : ; //一分频 fen_en[1] : clk_even<=~clk_even ; //二分频 fen_en[2] : begin //三分频 if(cnt==1) clk_odd<=~clk_odd; else if(cnt==2) clk_odd<=~clk_odd; else clk_odd<=clk_odd; end fen_en[3] : begin //四分频 if(cnt==1) clk_even<=~clk_even; else if(cnt==3) clk_even<=~clk_even; else clk_even<=clk_even; end fen_en[4] : begin //五分频 if(cnt==2) clk_odd<=~clk_odd; else if(cnt==4) clk_odd<=~clk_odd; else clk_odd<=clk_odd; end fen_en[5] : begin //六分频 if(cnt==2) clk_even<=~clk_even; else if(cnt==5) clk_even<=~clk_even; else clk_even<=clk_even; end fen_en[6] : begin //七分频 if(cnt==3) clk_odd<=~clk_odd; else if(cnt==6) clk_odd<=~clk_odd; else clk_odd<=clk_odd; end fen_en[7] : begin //八分频 if(cnt==3) clk_even<=~clk_even; else if(cnt==7) clk_even<=~clk_even; else clk_even<=clk_even; end endcase end end //计数器开始计数 always@(posedge sys_clk or negedge sys_rst_n) begin if(!sys_rst_n) cnt<=4'd0; else begin case(1'b1) fen_en[0] : ; fen_en[1] : ; fen_en[2] : begin if(cnt==4'd2) cnt<=4'd0; else cnt<=cnt+1'b1; end fen_en[3] : begin if(cnt==4'd3) cnt<=4'd0; else cnt<=cnt+1'b1; end fen_en[4] : begin if(cnt==4'd4) cnt<=4'd0; else cnt<=cnt+1'b1; end fen_en[5] : begin if(cnt==4'd5) cnt<=4'd0; else cnt<=cnt+1'b1; end fen_en[6] : begin if(cnt==4'd6) cnt<=4'd0; else cnt<=cnt+1'b1; end fen_en[7] : begin if(cnt==4'd7) cnt<=4'd0; else cnt<=cnt+1'b1; end endcase end end //奇分频 在下降沿 打拍 always@(negedge sys_clk or negedge sys_rst_n ) begin if(!sys_rst_n) clk_odd_r<=1'b0; else begin case(1'b1) fen_en[0] : ; fen_en[1] : ; fen_en[2] : clk_odd_r<=clk_odd ; fen_en[3] : ; fen_en[4] : clk_odd_r<=clk_odd ; fen_en[5] : ; fen_en[6] : clk_odd_r<=clk_odd ; fen_en[7] : ; endcase end end //分频输出 assign clk_out =fen_en[0]?sys_clk : (fen_en[1]|fen_en[3]|fen_en[5]|fen_en[5])?clk_even:( clk_odd|clk_odd_r); endmodule
`timescale 1ns/1ns module tb_fenpin_8(); reg sys_clk ; reg sys_rst_n ; reg[3:0] in ; wire clk_out ; initial begin //模拟激励产生 sys_clk<=1'b0; sys_rst_n<=1'b0; in<=4'd0 ; #20 sys_rst_n<=1'b1; #50 in<=4'd1; #500 in<=4'd0; #20 in<=4'd2; #500; in<=4'd0; #20 in<=4'd3; #500 in<=4'd0; #20 in<=4'd4; #500 in<=4'd0; #20 in<=4'd5; #500 in<=4'd0; #20 in<=4'd6; #500 in<=4'd0; #20 in<=4'd7; #500 in<=4'd0; #20 in<=4'd8; #500 in<=4'd0; #20 in<=4'd1; end always #10 sys_clk<=~sys_clk ; fenpin_8 fenpin_8_inst ( .sys_clk (sys_clk ) , .sys_rst_n (sys_rst_n) , .in (in ) , .clk_out (clk_out ) ); endmodule
二分频:
三分频:
五分频:
在这里题目中学会了一种新的奇分频电路。
在这里与之前的做个对比。奇分频电路如下:
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
来自之前的:奇分频电路如何实现? 负沿触发&非负沿触发 - 余你余生 - 博客园 (cnblogs.com)
今天学到的五分频电路如下:
module fenpin ( input sys_clk , input sys_rst_n , output clk_out ); reg clk_odd ; //奇分频 计数翻转 上升沿 reg clk_odd_r ; //奇分频 下降沿 对之前的信号打拍 reg [3:0] cnt ; //计数器 确定翻转的位置 always@(posedge sys_clk or negedge sys_rst_n) begin //五分频 if(!sys_rst_n) begin clk_odd<=1'b0; end else begin if(cnt==2) clk_odd<=~clk_odd; else if(cnt==4) clk_odd<=~clk_odd; else clk_odd<=clk_odd; end end //计数器开始计数 always@(posedge sys_clk or negedge sys_rst_n) begin if(!sys_rst_n) cnt<=4'd0; else begin if(cnt==4'd4) cnt<=4'd0; else cnt<=cnt+1'b1; end end //奇分频 在下降沿 打拍 always@(negedge sys_clk or negedge sys_rst_n ) begin if(!sys_rst_n) clk_odd_r<=1'b0; else clk_odd_r<=clk_odd ; end //分频输出 assign clk_out = clk_odd|clk_odd_r; endmodule
`timescale 1ns/1ns module tb_fenpin(); reg sys_clk ; reg sys_rst_n ; wire clk_out ; initial begin //模拟激励产生 sys_clk<=1'b0; sys_rst_n<=1'b0; #20 sys_rst_n<=1'b1; end always #10 sys_clk<=~sys_clk ; fenpin fenpin_inst ( .sys_clk (sys_clk ) , .sys_rst_n (sys_rst_n) , .clk_out (clk_out ) ); endmodule
由此可见这种方法更简单,也更适用。奇分频采取这样的方法,简单快捷。感谢李锐博恩博主,这篇文章是基于他的之前的文章学习。
若有不对的地方,敬请指正,万分感谢。
参考资料: