- //`define N 5
- module div_N (
- input CLK, // 基准时钟
- output CLK_div_N, // N分频后得到的时钟
- input rst
- );
- wire [31:0] N=5; // ★ N为分频系数,N≥2即可,N的值为CLK除以CLK_div_N后取整(四舍五入)
- /******************** 产生备用时钟1 ***************/
- reg [31:0] cnt1;
- reg CLK_div_N_1;
- always @ (posedge CLK or negedge rst)
- begin
- if(!rst)
- begin
- cnt1<=0;
- CLK_div_N_1<=0;
- end
- else if(N[0]==0) // 如果N为偶数,比N%2==0这种判断方式更节省资源
- begin
- if(N==2) // 如果N为2
- CLK_div_N_1 <= ~CLK_div_N_1;
- else
- if(cnt1==((N-2)>>1)) //比cnt1==(N-2)/2这种判断方式更节省资源
- begin
- cnt1 <= 0;
- CLK_div_N_1 <= ~CLK_div_N_1;
- end
- else
- cnt1 <= cnt1+1;
- end
- end
- else // 如果N为奇数
- if(cnt1==(N-1)/2)
- begin
- CLK_div_N_1 <= ~CLK_div_N_1;cnt1<=cnt1+1'b1;
- end
- else if(cnt1==N-1) begin cnt1 <= 0;CLK_div_N_1 <= ~CLK_div_N_1;end
- else
- cnt1<=cnt1+1'b1;
- end
- /*********************** 产生备用时钟2 *********************/
- wire CLK0=(N%2)? (~CLK):0; // 如果N为偶数,备用时钟2(CLK_div_N_2)恒为0,即不需要用到此备用时钟
- reg [31:0] cnt2;
- reg CLK_div_N_2;
- always @ (posedge CLK0 or negedge rst)
- if(!rst)
- begin
- cnt2<=0;
- CLK_div_N_2<=0;
- end
- else
- if(cnt2==(N-1)/2)
- begin
- CLK_div_N_2 <= ~CLK_div_N_2;cnt2 <= cnt2+1;
- end
- else if(cnt2==N-1) begin cnt2 <= 0;CLK_div_N_2 <= ~CLK_div_N_2;end
- else
- cnt2 <= cnt2+1;
- /******************** 产生最终分频时钟************************/
- assign CLK_div_N = CLK_div_N_1 | CLK_div_N_2;
- endmodule
- verilog代码
[plain] view plain copy
- module div_N_tb;
- reg CLK,rst;
- wire CLK_div_N;
- div_N U1(
- .CLK(CLK),
- .CLK_div_N(CLK_div_N),
- .rst(rst)
- );
- initial
- begin
- CLK=0;
- rst=0;
- #5 rst=1;
- forever
- #5 CLK=~CLK;
- end
- endmodule
- TB代码
|