日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

Verilog设计分频器(面试必看)

發(fā)布時(shí)間:2024/9/5 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Verilog设计分频器(面试必看) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

分頻器是指使輸出信號(hào)頻率為輸入信號(hào)頻率整數(shù)分之一的電子電路。在許多電子設(shè)備中如電子鐘、頻率合成器等,需要各種不同頻率的信號(hào)協(xié)同工作,常用的方法是以穩(wěn)定度高的晶體振蕩器為主振源,通過(guò)變換得到所需要的各種頻率成分,分頻器是一種主要變換手段。
??  早期的分頻器多為正弦分頻器,隨著數(shù)字集成電路的發(fā)展,脈沖分頻器(又稱(chēng)數(shù)字分頻器)逐漸取代了正弦分頻器。

下面以Verilog HDL 語(yǔ)言為基礎(chǔ)介紹占空比為50%的分頻器。

1、偶分頻

  偶分頻電路指的是分頻系數(shù)為 2、4、6、8 ... 等偶數(shù)整數(shù)的分頻電路,我們可以直接進(jìn)行分頻。
?? 例如下面 divider.v 中,對(duì)輸入時(shí)鐘進(jìn)行6分頻,即假設(shè)clk 為 50MHz ,分頻后的時(shí)鐘頻率為 (50/6) MHz。程序如下:

設(shè)計(jì)代碼:

1 //rtl 2 module divider( 3 clk, 4 rst_n, 5 clk_div 6 ); 7 input clk; 8 input rst_n; 9 output clk_div; 10 reg clk_div; 11 12 parameter NUM_DIV = 6; 13 reg [3:0] cnt; 14 15 always @(posedge clk or negedge rst_n) 16 if(!rst_n) begin 17 cnt <= 4'd0; 18 clk_div <= 1'b0; 19 end 20 else if(cnt < NUM_DIV / 2 - 1) begin 21 cnt <= cnt + 1'b1; 22 clk_div <= clk_div; 23 end 24 else begin 25 cnt <= 4'd0; 26 clk_div <= ~clk_div; 27 end 28 endmodule View Code

?

仿真程序:

1 //tb 2 module divider_tb(); 3 reg clk; 4 reg rst_n; 5 wire clk_div; 6 parameter DELY=100; 7 divider U_divider( 8 .clk (clk ), 9 .rst_n (rst_n ), 10 .clk_div(clk_div) 11 ); 12 always #(DELY/2) clk=~clk;//產(chǎn)生時(shí)鐘波形 13 initial begin 14 $fsdbDumpfile("divider_even.fsdb"); 15 $fsdbDumpvars(0,U_divider); 16 end 17 initial begin 18 clk=0;rst_n=0; 19 #DELY rst_n=1; 20 #((DELY*20)) $finish; 21 end 22 endmodule View Code

可以看到,clk的上升沿,采樣到cnt=2的時(shí)候,就翻轉(zhuǎn),采樣到0和1的時(shí)候,保持。這樣就可以做到一半高電平,一半低電平。

2、奇分頻
  由于奇分頻需要保持分頻后的時(shí)鐘占空比為 50% ,所以不能像偶分頻那樣直接在分頻系數(shù)的一半時(shí)使時(shí)鐘信號(hào)翻轉(zhuǎn)(高電平一半,低電平一半)。
    在此我們需要利用輸入時(shí)鐘上升沿和下降沿來(lái)進(jìn)行設(shè)計(jì)。 接下來(lái)我們?cè)O(shè)計(jì)一個(gè) 5 分頻的模塊,設(shè)計(jì)思路如下: 采用計(jì)數(shù)器 cnt1 進(jìn)行計(jì)數(shù),在時(shí)鐘上升沿進(jìn)行加 1 操作,計(jì)數(shù)器的值為 0、1 時(shí),輸出時(shí)鐘信號(hào) clk_div 為高電平;計(jì)數(shù)器的值為2、3、4 時(shí),輸出時(shí)鐘信號(hào) clk_div 為低電平,計(jì)數(shù)到 5 時(shí)清零,從頭開(kāi)始計(jì)數(shù)。我們可以得到占空比為 40% 的波形 clk_div1。 采用計(jì)數(shù)器 cnt2進(jìn)行計(jì)數(shù),在時(shí)鐘下降沿進(jìn)行加 1 操作,計(jì)數(shù)器的值為 0、1 時(shí),輸出時(shí)鐘信號(hào) clk_div 為高電平;計(jì)數(shù)器的值為2、3、4 時(shí),輸出時(shí)鐘信號(hào) clk_div 為低電平,計(jì)數(shù)到 5 時(shí)清零,從頭開(kāi)始計(jì)數(shù)。我們可以得到占空比為 40% 的波形 clk_div2。
??     clk_div1 和clk_div2 的上升沿到來(lái)時(shí)間相差半個(gè)輸入周期,所以將這兩個(gè)信號(hào)進(jìn)行或操作,即可得到占空比為 50% 的5分頻時(shí)鐘。程序如下: 設(shè)計(jì)代碼: 1 //rtl 2 module divider( 3 clk, 4 rst_n, 5 clk_div 6 ); 7 input clk; 8 input rst_n; 9 output clk_div; 10 reg clk_div; 11 12 parameter NUM_DIV = 5; 13 reg[2:0] cnt1; 14 reg[2:0] cnt2; 15 reg clk_div1, clk_div2; 16 17 always @(posedge clk or negedge rst_n) 18 if(!rst_n) 19 cnt1 <= 0; 20 else if(cnt1 < NUM_DIV - 1) 21 cnt1 <= cnt1 + 1'b1; 22 else 23 cnt1 <= 0; 24 25 always @(posedge clk or negedge rst_n) 26 if(!rst_n) 27 clk_div1 <= 1'b1; 28 else if(cnt1 < NUM_DIV / 2) 29 clk_div1 <= 1'b1; 30 else 31 clk_div1 <= 1'b0; 32 33 always @(negedge clk or negedge rst_n) 34 if(!rst_n) 35 cnt2 <= 0; 36 else if(cnt2 < NUM_DIV - 1) 37 cnt2 <= cnt2 + 1'b1; 38 else 39 cnt2 <= 0; 40 41 always @(negedge clk or negedge rst_n) 42 if(!rst_n) 43 clk_div2 <= 1'b1; 44 else if(cnt2 < NUM_DIV / 2) 45 clk_div2 <= 1'b1; 46 else 47 clk_div2 <= 1'b0; 48 49 assign clk_div = clk_div1 | clk_div2; 50 endmodule View Code

仿真代碼:

1 //tb 2 module divider_tb(); 3 reg clk; 4 reg rst_n; 5 wire clk_div; 6 parameter DELY=100; 7 divider U_divider( 8 .clk (clk ), 9 .rst_n (rst_n ), 10 .clk_div(clk_div) 11 ); 12 always #(DELY/2) clk=~clk;//產(chǎn)生時(shí)鐘波形 13 initial begin 14 $fsdbDumpfile("divider_odd.fsdb"); 15 $fsdbDumpvars(0,U_divider); 16 end 17 initial begin 18 clk=0;rst_n=0; 19 #DELY rst_n=1; 20 #((DELY*20)) $finish; 21 end 22 endmodule View Code

對(duì)其進(jìn)行測(cè)試和驗(yàn)證,得到如下波形:

3.任意占空比的任意分頻

??在verilog程序設(shè)計(jì)中,我們往往要對(duì)一個(gè)頻率進(jìn)行任意分頻,而且占空比也有一定的要求這樣的話(huà),對(duì)于程序有一定的要求。
? 現(xiàn)在在前面兩個(gè)實(shí)驗(yàn)的基礎(chǔ)上做一個(gè)簡(jiǎn)單的總結(jié),實(shí)現(xiàn)對(duì)一個(gè)頻率的任意占空比的任意分頻。
? 比如: FPGA系統(tǒng)時(shí)鐘是50M Hz,而我們要產(chǎn)生的頻率是880Hz,那么,我們需要對(duì)系統(tǒng)時(shí)鐘進(jìn)行分頻。很容易想到用計(jì)數(shù)的方式來(lái)分頻:50000000/880 = 56818。
? 顯然這個(gè)數(shù)字不是2的整冪次方,那么我們可以設(shè)定一個(gè)參數(shù),讓它到56818的時(shí)候重新計(jì)數(shù)就可以實(shí)現(xiàn)了。程序如下:

設(shè)計(jì)代碼:

1 //rtl 2 module div( 3 clk, 4 rst_n, 5 clk_div 6 ); 7 input clk,rst_n; 8 output clk_div; 9 reg clk_div; 10 11 reg [15:0] counter; 12 13 always @(posedge clk or negedge rst_n) 14 if(!rst_n) 15 counter <= 0; 16 else if(counter==56817) 17 counter <= 0; 18 else 19 counter <= counter+1; 20 21 assign clk_div = counter[15]; 22 endmodule View Code

仿真代碼:

1 //tb 2 module div_tb(); 3 reg clk; 4 reg rst_n; 5 wire clk_div; 6 parameter DELY=100; 7 div U_div( 8 .clk (clk ), 9 .rst_n (rst_n), 10 .clk_div(clk_div) 11 ); 12 always #(DELY/2) clk=~clk;//產(chǎn)生時(shí)鐘波形 13 initial begin 14 $fsdbDumpfile("div_any.fsdb"); 15 $fsdbDumpvars(0,U_div); 16 end 17 initial begin 18 clk=0;rst_n=0; 19 #DELY rst_n=1; 20 #((DELY*80000)) $finish; 21 end 22 endmodule View Code

分頻的應(yīng)用很廣泛,一般的做法是先用高頻時(shí)鐘計(jì)數(shù),然后使用計(jì)數(shù)器的某一位輸出作為工作時(shí)鐘進(jìn)行其他的邏輯設(shè)計(jì),上面的程序就是一個(gè)體現(xiàn)。
? 下面我們來(lái)算一下它的占空比:
? 我們清楚地知道,這個(gè)輸出波形在counter為0到32767(2的14次方)的時(shí)候?yàn)榈?#xff0c;在32768到56817的時(shí)候?yàn)楦?#xff0c;占空比為40%多一些,
? 如果我們需要占空比為50%,那么我們需要再設(shè)定一個(gè)參數(shù),使它為56817的一半,使達(dá)到它的時(shí)候波形翻轉(zhuǎn),就可以實(shí)現(xiàn)結(jié)果了。
? 程序如下:28408=56818/2-1,計(jì)數(shù)到28408就清零,翻轉(zhuǎn),其余的計(jì)數(shù)期間,保持不變。

設(shè)計(jì)代碼:

1 //rtl 2 module div( 3 clk, 4 rst_n, 5 clk_div 6 ); 7 input clk,rst_n; 8 output clk_div; 9 reg clk_div; 10 reg [14:0] counter; 11 always @(posedge clk or negedge rst_n) 12 if(!rst_n) 13 counter <= 0; 14 else if(counter==28408) 15 counter <= 0; 16 else 17 counter <= counter+1; 18 19 always @(posedge clk or negedge rst_n) 20 if(!rst_n) 21 clk_div <= 0; 22 else if(counter==28408) 23 clk_div <= ~clk_div; 24 endmodule View Code

仿真代碼:

1 //tb 2 module div_tb(); 3 reg clk; 4 reg rst_n=0; 5 wire clk_div; 6 parameter DELY=100; 7 div U_div( 8 .clk (clk ), 9 .rst_n (rst_n), 10 .clk_div(clk_div) 11 ); 12 always #(DELY/2) clk=~clk;//產(chǎn)生時(shí)鐘波形 13 initial begin 14 $fsdbDumpfile("div_any.fsdb"); 15 $fsdbDumpvars(0,U_div); 16 end 17 initial begin 18 clk=0;rst_n=0; 19 #DELY rst_n=1; 20 #((DELY*80000)) $finish; 21 end 22 endmodule View Code 繼續(xù)讓我們來(lái)看如何實(shí)現(xiàn)任意占空比,比如還是由50M分頻產(chǎn)生880Hz,而分頻得到的信號(hào)的占空比為30%。 56818×30%=17045 設(shè)計(jì)代碼: 1 //rtl 2 module div( 3 clk, 4 rst_n, 5 clk_div, 6 counter 7 ); 8 input clk,rst_n; 9 output clk_div; 10 reg clk_div; 11 output [15:0] counter; 12 reg [15:0] counter; 13 14 always @(posedge clk) 15 if(!rst_n) 16 counter <= 0; 17 else if(counter==56817) 18 counter <= 0; 19 else counter <= counter+1; 20 21 always @(posedge clk) 22 if(!rst_n) 23 clk_div <= 0; 24 else if(counter<17045) 25 clk_div <= 1; 26 else 27 clk_div <= 0; 28 endmodule View Code

仿真代碼:

1 //tb 2 module div_tb(); 3 reg clk; 4 reg rst_n; 5 wire clk_div; 6 wire [15:0] counter; 7 parameter DELY=100; 8 div U_div( 9 .clk (clk ), 10 .rst_n (rst_n ), 11 .counter(counter), 12 .clk_div(clk_div) 13 ); 14 always #(DELY/2) clk=~clk;//產(chǎn)生時(shí)鐘波形 15 initial begin 16 $fsdbDumpfile("div_any.fsdb"); 17 $fsdbDumpvars(0,U_div); 18 end 19 initial begin 20 clk=0;rst_n=0; 21 #DELY rst_n=1; 22 #((DELY*80000)) $finish; 23 end 24 endmodule View Code 4 小結(jié) 通過(guò)以上幾個(gè)例子對(duì)比不難發(fā)現(xiàn),借助計(jì)數(shù)器來(lái)實(shí)現(xiàn)任意點(diǎn)空比的任意分頻的方法簡(jiǎn)單,且用verilog語(yǔ)言進(jìn)行行為描述時(shí),代碼簡(jiǎn)潔、易懂、通用。
?通過(guò)以上的學(xué)習(xí),對(duì)分頻器有了比較深刻的認(rèn)識(shí),將在以后的學(xué)習(xí)中會(huì)有廣泛的應(yīng)用。

原出處:https://www.chipist.cn/article/166? 如有什么疑問(wèn),歡迎討論:QQ:447574829

?

轉(zhuǎn)載于:https://www.cnblogs.com/zhangxianhe/p/11083208.html

總結(jié)

以上是生活随笔為你收集整理的Verilog设计分频器(面试必看)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。