牛客网分频原理
1、Verilog刷题进阶版VL13时钟分频偶数
描述
请使用D触发器设计一个同时输出2/4/8分频的50%占空比的时钟分频器
注意rst为低电平复位
波形示意图:
`timescale 1ns/1ns module even_div ( input wire rst , input wire clk_in, output wire clk_out2, output wire clk_out4, output wire clk_out8 ); //*************code***********// reg [2:0] cnt8; always@(posedge clk_in or negedge rst) begin if(!rst) cnt8<=3'b000; else cnt8<=cnt8-3'd1;//注意这里用减法,为了满足题目的时序图,248同时拉高 end assign clk_out2=(cnt8[0]==1'b1)?1:0; assign clk_out4=(cnt8[1]==1'b1)?1:0; assign clk_out8=(cnt8[2]==1'b1)?1:0; //*************code***********// endmodule
2、Verilog刷题进阶版VL18无占空比要求的奇数分频
描述
请设计一个同时输出5分频的时钟分频器,本题对占空比没有要求
注意rst为低电平复位
波形示意图:
1)由波形图可以看出每隔5个clk,clk_out5出现一次上升沿
2)其中clk_out5中间的一次由高到低的跳变,题目没有要求,随时可以跳变,题目中 的跳变方式占空比为50%
`timescale 1ns/1ns module odd_div ( input wire rst , input wire clk_in, output wire clk_out5 ); //*************code***********// parameter N=5; reg [2:0] cnt; reg clk_n; //cnt在0,1,2,3,4之间循环 always@(posedge clk_in or negedge rst) begin if(!rst) cnt<=3'b000; else if(cnt==N-1) cnt<=3'b000; else cnt<=cnt+1'b1; end //clk_out5下降沿的位置,第二个时钟周期时从高到低跳变 always@(posedge clk_in or negedge rst) begin if(!rst) clk_n<=1'b0; else if(cnt==(N-1)/2) clk_n<=~clk_n; else if(cnt<=3'b000) clk_n<=~clk_n; else clk_n<=clk_n; end assign clk_out5=clk_n; //*************code***********// endmodule
3、Verilog刷题进阶版VL16占空比为50%的奇数分频
描述
设计一个同时输出7分频的时钟分频器,占空比要求为50%
注意rst为低电平复位
波形示意图:
由波形图可以看出,clk_out7是在clk的下降沿拉高的,在clk的上升拉低
`timescale 1ns/1ns module odo_div_or ( input wire rst , input wire clk_in, output wire clk_out7 ); //*************code***********// parameter N=7; reg [3:0] cnt; //分频计数:0,1,2,3,4,5,6 always@(posedge clk_in or negedge rst) begin if(!rst) cnt<=4'b0000; else if(cnt==N-1) cnt<=4'b0000; else cnt<=cnt+1'b1; end //clk上升沿驱动的分频 reg clkp; always@(posedge clk_in or negedge rst) begin if(!rst) clkp<=1'b0; else if(cnt==(N>>1))//N右移一位,相当于除以2,结果为3;从3~6中间有3个时钟周期为高电频 clkp<=1; else if(cnt==N-1) clkp<=0; else clkp<=clkp; end //clk下降沿驱动的分频 reg clkn; always@(negedge clk_in or negedge rst) begin if(!rst) clkn<=1'b0; else if(cnt==(N>>1)) clkn<=1; else if(cnt==N-1) clkn<=0; else clkn<=clkn; end assign clk_out7=clkp|clkn; //*************code***********// endmodule
4、Verilog刷题进阶版VL17任意小数分频
描述
请设计一个可以实现任意小数分频的时钟分频器,比如说8.7分频的时钟信号
注意rst为低电平复位
波形示意图:
1)N=7,意味着在87个clk_in时钟周期里面,clk_out要翻转10次,即87个输入上升沿对应10个输出上升沿
87=10*8.7 //这10个输出上升沿,我们允许它们有些差别
87=9*9+1*6; //前9个输出的周期 ,每个周期占9个输入,最后一个输出周期占6个输入时钟
87=8*9+2*7.5
87=7*9+3*8 //前7个输出周期,每个周期占9个输入,最后三个输出周期,每个周期占8个输入时钟
... ...
2)一个周期包含一个高电平加一个低电平,即两个上升沿之间的时间
3)选择87=7*9+3*8 ;3个8分频,7个9分频
`timescale 1ns/1ns module div_M_N( input wire clk_in, input wire rst, output wire clk_out ); parameter M_N = 8'd87; parameter c89 = 8'd24; // 8/9时钟切换点 parameter div_e = 5'd8; //偶数周期 parameter div_o = 5'd9; //奇数周期 //*************code***********// reg [6:0] cnt; //总计数器 reg [3:0] cnt_e; //偶数周期技术 reg [3:0] cnt_o; //奇数周期计数 reg clk_MN; assign clk_out=clk_MN; //总计数器,0~86 always@(posedge clk_in or negedge rst) begin if(!rst) cnt<=7'd0; else begin if(cnt==M_N-1'b1) cnt<=7'd0; else cnt<=cnt+1'b1; end end always@(posedge clk_in or negedge rst) begin if(!rst) begin cnt_e<=4'd0; cnt_o<=4'd0; end else if(cnt<=c89-1'b1) begin//parameter c89 = 8'd24; 8/9时钟切换点 cnt_o=4'd0; if(cnt_e==div_e-1'b1)//parameter div_e = 5'd8; 偶数周期 cnt_e<=4'd0; else cnt_e<=cnt_e+1'b1; end else if(cnt>c89-1'b1) begin //实现7个9分频的时钟周期 cnt_e<=4'd0; if(cnt_o==div_o-1'b1)//parameter div_o = 5'd9; 奇数周期 cnt_o<=4'd0; else cnt_o<=cnt_o+1'b1; end end always@(posedge clk_in or negedge rst) begin if(!rst) clk_MN<=1'b0; else begin if(cnt<c89) if(cnt_e==4'd0 || cnt_e==div_e/2) clk_MN<=~clk_MN; if(cnt>=c89) if(cnt_o==4'd0 || cnt_o==(div_o-1'b1)/2) clk_MN<=~clk_MN; end end //*************code***********// endmodule