1.偶分頻模塊設(shè)計(jì)
偶分頻意思是時(shí)鐘模塊設(shè)計(jì)最為簡(jiǎn)單。首先得到分頻系數(shù)M和計(jì)數(shù)器值N。
M = 時(shí)鐘輸入頻率 / 時(shí)鐘輸出頻率
N = M / 2
如輸入時(shí)鐘為50M,輸出時(shí)鐘為25M,則M=2,N=1。偶分頻則意味著M為偶數(shù)。
以M=4,N=2為例,我們希望得到的輸出時(shí)鐘時(shí)序如下:
因此只需要將counter以clk_in為時(shí)鐘驅(qū)動(dòng)計(jì)數(shù),當(dāng)counter = (N-1)時(shí),clk_out翻轉(zhuǎn)即可。
verilog代碼如下,其中WIDTH為(N的位寬-1):
module time_adv_even #(parameter N = 2, WIDTH = 7)( input clk, input rst, output reg clk_out );reg [WIDTH:0]counter;always @(posedge clk or posedge rst) begin if (rst) begin // reset counter <= 0; end else if (counter == N-1) begin counter <= 0; end else begin counter <= counter + 1; endendalways @(posedge clk or posedge rst) begin if (rst) begin // reset clk_out <= 0; end else if (counter == N-1) begin clk_out <= !clk_out; endendendmodule
testbench測(cè)試8分頻即N=4,ISE仿真結(jié)果如下:
2.奇分頻模塊設(shè)計(jì)
奇分頻需要通過兩個(gè)時(shí)鐘共同得到。首先得到分頻系數(shù)M和計(jì)數(shù)器值N。
M = 時(shí)鐘輸入頻率 / 時(shí)鐘輸出頻率
N = (M-1) / 2
如輸入時(shí)鐘為50M,輸出時(shí)鐘為10M,則M=5,N=2。奇分頻則意味著M為奇數(shù)。以M=5,N=2為例,我們希望得到的輸出時(shí)鐘時(shí)序如下:
其中clk_out為最終輸出時(shí)鐘,clk_out1和clk_out2為輔助時(shí)鐘生成。
計(jì)數(shù)器counter由0技術(shù)至(M-1)。
clk_out1在在clk_in的上升延跳變,條件是counter==(N-1)或(M-1)。
clk_out2在在clk_in的下降延跳變,條件是counter==(N-1)或(M-1)。
之后clk_out = clk_out1 & clk_out2即可得到M分頻的時(shí)鐘。
verilog代碼如下,其中WIDTH為(N的位寬-1):
module time_adv_odd #(parameter N = 2, WIDTH = 7 )( input clk, input rst, output clk_out );reg [WIDTH:0]counter;always @(posedge clk or posedge rst) begin if (rst) begin // reset counter <= 0; end else if (counter == (N << 1)) begin counter <= 0; end else begin counter <= counter + 1; endendreg clk_out1;always @(posedge clk or posedge rst) begin if (rst) begin // reset clk_out1 <= 0; end else if (counter == N-1) begin clk_out1 <= !clk_out1; end else if (counter == (N << 1)) begin clk_out1 <= !clk_out1; endendreg clk_out2;always @(negedge clk or posedge rst) begin if (rst) begin // reset clk_out2 <= 0; end else if (counter == N-1) begin clk_out2 <= !clk_out2; end else if (counter == (N << 1)) begin clk_out2 <= !clk_out2; endendassign clk_out = clk_out1 & clk_out2;endmodule
testbench測(cè)試9分頻即N=4,ISE仿真結(jié)果如下:3.半分頻模塊設(shè)計(jì)
半分頻即2.5分頻等,設(shè)計(jì)最為復(fù)雜。首先得到分頻系數(shù)M:
M = 時(shí)鐘輸入頻率 / 時(shí)鐘輸出頻率
如輸入為50M,輸入為20M則分頻系數(shù)為2.5。此次設(shè)計(jì)未能完成占空比為50%的半分頻。
以M=2.5為例,我們希望得到的輸出時(shí)鐘時(shí)序如下:
可以看出輸出時(shí)鐘的兩個(gè)上升沿之間為2.5個(gè)輸入時(shí)鐘周期。
設(shè)計(jì)的關(guān)鍵在于信號(hào)維持半個(gè)周期的處理,因此引入了輔助信號(hào)clk_cnt,clk_vld。
clk_vld信號(hào)受到clk_out的驅(qū)動(dòng),檢測(cè)到clk_out的上升沿時(shí),信號(hào)翻轉(zhuǎn)。
clk_cnt信號(hào)受到clk_in驅(qū)動(dòng),受clk_vld控制,當(dāng)clk_vld==0時(shí),clk_cnt = clk_in;當(dāng)clk_vld==1時(shí),clk_cnt = !clk_in。
counter信號(hào)受clk_cnt驅(qū)動(dòng),計(jì)數(shù)(M-0.5)時(shí)歸零。
clk_out信號(hào)受clk_cnt驅(qū)動(dòng),當(dāng)counter == (M-1.5)或counter == (M-0.5)時(shí)翻轉(zhuǎn)。(此處在仿真時(shí)做了改變,見下方)
M=2.5時(shí),時(shí)序分析如下:
第一步:reset之后,clk_vld==0,clk_cnt = clk_in,counter由0開始計(jì)數(shù);
第二步:counter == 1時(shí),clk_out在clk_cnt的上升沿處跳變?yōu)?,引起clk_vld->1,進(jìn)而clk_cnt = !clk_in,這意味著clk_cnt立即由1歸為0;
第三步:半個(gè)周期后,clk_cnt 在此迎來上升沿,此時(shí)counter == 2,clk_out在clk_cnt的上升沿處跳變?yōu)?,counter也歸0;(實(shí)現(xiàn)了信號(hào)維持半個(gè)周期)
第四步:繼續(xù)正常計(jì)數(shù),counter == 1時(shí),clk_out在clk_cnt的上升沿處跳變?yōu)?,引起clk_vld->0,進(jìn)而clk_cnt = clk_in,這意味著clk_cnt立即由1歸為0;
第五步:重復(fù)至第一步。
然而在有一次的電路仿真中,可能受到仿真工具時(shí)鐘采樣影響,調(diào)整為
當(dāng)counter == (M-0.5)或counter == 0時(shí)翻轉(zhuǎn)
實(shí)現(xiàn)了正確的時(shí)鐘分頻。因此該值可能需要根據(jù)工具和開發(fā)板調(diào)整,或者說這樣的設(shè)計(jì)是不可靠的,當(dāng)然了如果需要半分頻時(shí)候最好還是通過pll實(shí)現(xiàn)吧。
理論上是當(dāng)counter == (M-0.5)或counter == (M-1.5)時(shí)翻轉(zhuǎn)沒錯(cuò),給出的代碼和波形也是這樣的。
verilog代碼如下,參數(shù)M實(shí)際為分頻系數(shù)-0.5(即3.5->3),WIDTH為(M的位寬-1):
module time_adv_half #( parameter M = 2, WIDTH = 7)( input clk, input rst, output reg clk_out );wire clk_cnt;assign clk_cnt = (clk_vld) ? !clk : clk;reg [WIDTH : 0]counter;always @(posedge clk_cnt or posedge rst) begin if (rst) begin // reset counter <= 0; end else if (counter == M) begin counter <= 0; end else begin counter <= counter + 1; endendreg clk_vld;always @(posedge clk_out or posedge rst) begin if (rst) begin // reset clk_vld <= 0; end else begin clk_vld <= !clk_vld; endendalways @(posedge clk_cnt or posedge rst) begin if (rst) begin // reset clk_out <= 0; end else if (counter == M-1) begin clk_out <= !clk_out; end else if (counter == M) begin clk_out <= !clk_out; endendendmodule
M=3時(shí)候的仿真波形如下:附:testbench
`timescale 1 ns / 1 psmodule TEST_gate; reg clk, rst; wire clk_out_even, clk_out_odd, clk_out_half; initial begin clk = 1'b0; forever #10 clk = ~clk; end initial begin rst = 1'b0; #2 rst = 1'b1; #9 rst = 1'b0; end time_adv_even #( .N(4) ,.WIDTH(5) )u0 ( .clk (clk) ,.rst (rst) ,.clk_out (clk_out_even) ); time_adv_odd #( .N(4) ,.WIDTH(5) )u1 ( .clk (clk) ,.rst (rst) ,.clk_out (clk_out_odd) ); time_adv_half #( .M(3) ,.WIDTH(5) )u2 ( .clk (clk) ,.rst (rst) ,.clk_out (clk_out_half) );endmodule
波形聯(lián)系客服