Verilog HDL分频
0赞
发表于 9/9/2012 1:37:33 AM
阅读(2754)
1.偶数分频
偶分频可用计数器的方法实现,例如进行N分频,可计一个计数器,当计数到N/N-1时,对时钟信号取反,即可满足要求。如下二分频代码,只需取计数器的最低位 cnt[ 0 ] 变化即可:
module fp_verilog_2( clk,rst_n, clk_div ); input clk; input rst_n; output clk_div; /*******************************************/ reg [1:0] cnt; always @(posedge clk or negedge rst_n) if(!rst_n) cnt <= 2'd0; else cnt <= cnt + 1'b1; /********************************************/ reg clk_div_r; always @(posedge clk or negedge rst_n) if(!rst_n) clk_div_r <=1'b0; else clk_div_r <= cnt[0]; /**********************************************/ assign clk_div =clk_div_r; endmodule
使用MModelSim-Altera仿真波形:

Quartus II RTL视图:

2.奇数分频
奇数分频也是通过计数器实现的,如三分频,就可以通过时钟的上升沿触发来进行计数,当计数器计到邻近的值时进行两次翻转。比如可以在计数器计到1时,输出时钟进行翻转,计数到2是再次翻转,这样,就在计数值邻近的1和2进行了2次翻转。如此可实现三分频,其占空比为1/3或者2/3。
如占空比为2/3的代码:
module fp_verilog_3( clk,rst_n, clk_out ); input clk; input rst_n; output clk_out; //-------------------------------------------------------- reg [1:0] cnt1; always @ (posedge clk or negedge rst_n) if(!rst_n) cnt1 <= 1'd0; else if(cnt1 == 2'b10) cnt1 <= 1'd0; else cnt1 <= cnt1 + 1'b1; //-------------------------------------------------------- reg qout1; always @ (posedge clk or negedge rst_n) if(!rst_n) qout1 <= 1'b0; else if(cnt1 == 2'b10) qout1 <= 1'd1; else qout1 <= 1'd0; //--------------------------------------------------------- assign clk_out = qout1; endmodule 使用ModelSim_Altera仿真波形:
如果要实现占空比为50%的三分频时钟的话,则可通过待分频时钟下降沿触发计数,并以和上升沿同样的方法进行计数三分频,然后对下降沿三分频时钟和上升沿时钟相或: 占空比为50%的三分频代码:
module fp_verilog_3( clk,rst_n, clk_out ); input clk; input rst_n; output clk_out; //-------------------------------------------------------- reg [1:0] cnt1,cnt2; always @ (posedge clk or negedge rst_n) if(!rst_n) cnt1 <= 1'd0; else if(cnt1 == 2'b10) cnt1 <= 1'd0; else cnt1 <= cnt1 + 1'b1; //-------------------------------------------------------- reg qout1; always @ (posedge clk or negedge rst_n) if(!rst_n) qout1 <= 1'b0; else if(cnt1 == 2'b10) qout1 <= 1'd1; else qout1 <= 1'd0; //--------------------------------------------------------- always @ (negedge clk or negedge rst_n) if(!rst_n) cnt2 <= 1'd0; else if(cnt1 == 2'b10) cnt2 <= 1'd0; else cnt2 <= cnt2 + 1'b1; //--------------------------------------------------------- reg qout2; always @ (negedge clk or negedge rst_n) if(!rst_n) qout2 <= 1'b0; else if(cnt2 == 2'b10) qout2 <= 1'd1; else qout2 <= 1'd0; //--------------------------------------------------------- assign clk_out = qout1 || qout2; endmodule 使用ModelSim-Altera仿真波形:
RTL视图:
