分频器设计(采用或门,与门,异或门)
使用或门和与门的方法类似,思想就是采用下降沿产生一个半拍。对或门低电平持续周期为cnt<NUM_DIV/2;对与门低电平持续周期为cnt<=NUM_DIV/2;
对异或门先利用上升沿产生一个周期为2*NUM_DIV的div_clk1,利用下降沿产生一个与div_clk1相差NUM_DIV/2相位的div_clk2,两者异或即可。
1、采用或门生成占空比为%50的分频器(5分频)
module divider( clk, rst_n, clk_div ); input clk; input rst_n; output clk_div; wire clk_div; parameter NUM_DIV = 5; reg[2:0] cnt; reg clk_div1, clk_div2; always @(posedge clk or negedge rst_n) if(!rst_n) cnt <= 0; else if(cnt < NUM_DIV - 1) cnt <= cnt + 1'b1; else cnt <= 0; always @(posedge clk or negedge rst_n) if(!rst_n) clk_div1 <= 1'b1; else if(cnt < NUM_DIV / 2)//注意这里是小于,和与门的不同之处 clk_div1 <= 1'b1; else clk_div1 <= 1'b0; always @(negedge clk or negedge rst_n) if(!rst_n) clk_div2 <= 1'b1; else if(cnt < NUM_DIV / 2) //注意这里是小于,和与门的方法的不同之处 clk_div2 <= 1'b1; else clk_div2 <= 1'b0; assign clk_div = clk_div1 | clk_div2; endmodule
仿真代码见3;
仿真波形

2、 采用与门产生占空比%50的分频电路(5分频)
module divider( clk, rst_n, clk_div ); input clk; input rst_n; output clk_div; wire clk_div; parameter NUM_DIV = 5; reg[2:0] cnt; reg clk_div1, clk_div2; always @(posedge clk or negedge rst_n) if(!rst_n) cnt <= 0; else if(cnt < NUM_DIV - 1) cnt <= cnt + 1'b1; else cnt <= 0; always @(posedge clk or negedge rst_n) if(!rst_n) clk_div1 <= 1'b1; else if(cnt <= NUM_DIV / 2) //注意这里是小于等于 clk_div1 <= 1'b1; else clk_div1 <= 1'b0; always @(negedge clk or negedge rst_n) if(!rst_n) clk_div2 <= 1'b1; else if(cnt <= NUM_DIV / 2) //注意这里是小于等于 clk_div2 <= 1'b1; else clk_div2 <= 1'b0; assign clk_div = clk_div1 & clk_div2; endmodule
仿真代码见3;
仿真波形

3、采用异或门产生占空比%50的分频电路(3分频)
//rtl module divider( clk, rst_n, clk_div ); input clk; input rst_n; output clk_div; wire clk_div; parameter NUM_DIV = 3; reg[2:0] cnt; reg clk_div1, clk_div2; always @(posedge clk or negedge rst_n) if(!rst_n) cnt <= 0; else if(cnt < NUM_DIV - 1) cnt <= cnt + 1'b1; else cnt <= 0; always @(posedge clk or negedge rst_n) if(!rst_n) clk_div1 <= 1'b1; else if(cnt == NUM_DIV-1 ) //计数器计数到最大值,上升沿采样 clk_div1 <= ~clk_div1; else clk_div1 <= clk_div1; always @(negedge clk or negedge rst_n) if(!rst_n) clk_div2 <= 1'b1; else if(cnt == NUM_DIV/2 ) //计数器计数到中间值,下降沿采样 clk_div2 <= ~clk_div2; else clk_div2 <= clk_div2; assign clk_div = clk_div1 ^ clk_div2; endmodule
仿真代码
//tb module divider_tb(); reg clk; reg rst_n; wire clk_div; parameter DELY=100; divider U_divider( .clk (clk ), .rst_n (rst_n ), .clk_div(clk_div) ); always #(DELY/2) clk=~clk;//产生时钟波形 //initial begin // $fsdbDumpfile("divider_odd.fsdb"); // $fsdbDumpvars(0,U_divider); //end initial begin clk=0;rst_n=0; #DELY rst_n=1; #((DELY*20)) $finish; end endmodule
仿真波形

浙公网安备 33010602011771号