verilog-分频器的设定
2015-12-15 14:12
169 查看
分频器的verilog HDL描述(转) 分频器,在许多涉及时序的电路设计中都会用到,在这里,我转载某位高人的文章,关于分频器的设计 偶数倍分频:偶数倍分频应该是大家都比较熟悉的分频,通过计数器计数是完全可以实现的。如进行N倍偶数分频,那么可以通过由待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数。以此循环下去。这种方法可以实现任意的偶数分频。 module odd_division(clk,rst,count,clk_odd); input clk,rst; output clk_odd; output[3:0] count; reg clk_odd; reg[3:0] count; parameter N = 6; always @ (posedge clk) if(! rst) begin count <= 1'b0; clk_odd <= 1'b0; end else if ( count < N/2-1) begin count <= count + 1'b1; end else begin count <= 1'b0; clk_odd <= ~clk_odd; end endmodule 奇数倍分频:归类为一般的方法为:对于实现占空比为50%的N倍奇数分频,首先进行上升沿触发进行模N计数,计数从零开始,到(N-1)/2进行输出时钟翻转,然后经过(N-1)/2再次进行翻转得到一个占空比非50%奇数n分频时钟。再者同时进行下降沿触发的模N计数,到和上升沿过(N-1)/2时,输出时钟再次翻转生成占空比非50%的奇数n分频时钟。两个占空比非50%的n分频时钟相或运算,得到占空比为50%的奇数n分频时钟。 module even_division(clk,rst,count1,count2,clk_even); input clk,rst; output[3:0] count1,count2; output clk_even; reg[3:0] count1,count2; reg clkA,clkB; wire clk_even; parameter N = 5; assign clk_re = ~clk; assign clk_even = clkA | clkB; always @(posedge clk) if(! rst) begin count1 <= 1'b0; clkA <= 1'b0; end else if(count1 < (N - 1)) begin count1 <= count1 + 1'b1; if(count1 == (N - 1)/2) begin clkA <= ~clkA; end end else begin clkA <= ~clkA; count1 <= 1'b0; end always @ (posedge clk_re) if(! rst) begin count2 <= 1'b0; clkB <= 1'b0; end else if(count2 < (N - 1)) begin count2 <= count2 + 1'b1; if(count2 == (N - 1)/2) begin clkB <= ~clkB; end end else begin clkB <= ~clkB; count2 <= 1'b0; end endmodule 任意整数带小数分频的设计 任意整数带小数分频的基本原理是: 采用脉冲吞吐计数器和锁相环技术先设计两个不同分频比的整数分频器。 然后通过控制单位时间内两种分频比出现的不同次数来获得所需要的小数分频值。 若设计一个分频系数为10.1的分频器,即可以将分频器设计成9次10分频和1次11分频,这样,总的分频值为: F=(9×10+1×11)/(9+1)=10.1 从这种实现方法的特点可以看出,由于分频器的分频值不断改变,分频后得到的信号抖动一般较大。 当分频系数为N-0.5(N为整数)时,可控制扣除脉冲的时间,以使输出成为一个稳定的脉冲频率,而不是一次N分频,一次N-1分频。 一般而言,这种分频由于分频输出的时钟脉冲抖动很大,故在设计中的使用已经非常少。但是,这也是可以实现的。 上面都是用计数器实现的分频,除此之外,还可以用状态机来实现。 下面给出一个任意整数分频器的代码: module divn ( input clk, input rst_n, output o_clk ); parameter WIDTH = 3; parameter N = 6; reg [WIDTH-1:0] cnt_p; reg [WIDTH-1:0] cnt_n; reg clk_p; reg clk_n; assign o_clk = (N == 1) ? clk : (N[0]) ? (clk_p | clk_n) : (clk_p); always@(posedge clk or negedge rst_n) begin if (!rst_n) cnt_p <= 0; else if (cnt_p == (N-1)) cnt_p <= 0; else cnt_p <= cnt_p + 1; end always@(posedge clk or negedge rst_n) begin if (!rst_n) clk_p <= 1; else if (cnt_p < (N>>1)) clk_p = 1; else clk_p = 0; end always@(negedge clk or negedge rst_n) begin if (!rst_n) cnt_n <= 0; else if (cnt_n == (N-1)) cnt_n <= 0; else cnt_n <= cnt_n + 1; end always@(negedge clk or negedge rst_n) begin if (!rst_n) clk_n <= 1; else if (cnt_n < (N>>1)) clk_n = 1; else clk_n = 0; end endmodule
相关文章推荐
- Verilog文件格式范例
- [Verilog]个人.v文件书写规范
- Verilog HDL语言不全面但基本入门够用介绍
- Verilog $Scannf 使用小结
- 关于Error: Can't compile duplicate declarations of entity "**" into library "work"的错误
- ISE中将Verilog封装为IPcore
- (筆記) 如何設計邊緣檢測電路? (SOC) (Verilog)
- Verilog 有符号数无符号数混用
- Partitioning for Synthesis
- Veriog_Notes_Chapter 1
- Veriog_Notes_Chapter 2
- Veriog_Notes_Chapter 4
- Veriog_Notes_Chapter 6
- Veriog_Notes_Chapter 3
- Veriog_Notes_Chapter 5
- Veriog_Notes_Chapter 7
- Veriog_Notes_Summary 1
- Veriog_Notes_Summary 2
- UART 通信逻辑协议设计(2)
- Using XILINX IP Core Block RAM (1)