FPGA-分頻器
當給你一個時鐘,你覺得頻率太快了,想進行就分頻,就會使用到我們的分頻器,非常簡單且實用,且寫的無聊,
寫給出總體代碼
module div_frequency(
input clk_i,
input rst_n_i,
output div2_o,
output div3_o,
output div4_o,
output div8_o
);
reg div2_o_r;
always@(posedge clk_i or negedge rst_n_i)
begin
if(!rst_n_i)
div2_o_r<=1’b0;
else
div2_o_r<=~div2_o_r;
end
reg [1:0] div_cnt1;
always@(posedge clk_i or negedge rst_n_i)
begin
if(!rst_n_i)
div_cnt1<=2’b00;
else
div_cnt1<=div_cnt1+1’b1;
end
reg div4_o_r;
reg div8_o_r;
always@(posedge clk_i or negedge rst_n_i)
begin
if(!rst_n_i)
div4_o_r<=1’b0;
else if(div_cnt12’b00 || div_cnt12’b10)
div4_o_r<=~div4_o_r;
else
div4_o_r<=div4_o_r;
end
always@(posedge clk_i or negedge rst_n_i)
begin
if(!rst_n_i)
div8_o_r<=1’b0;
else if(div_cnt1==2’b00)
div8_o_r<=~div8_o_r;
else
div8_o_r<=div8_o_r;
end
reg [1:0] pos_cnt;
reg [1:0] neg_cnt;
always@(posedge div2_o_r or negedge rst_n_i)
begin
if(!rst_n_i)
pos_cnt<=2’b00;
else if(pos_cnt==2’d2)
pos_cnt<=2’b00;
else
pos_cnt<=pos_cnt+1’b1;
end
always@(negedge div2_o_r or negedge rst_n_i)
begin
if(!rst_n_i)
neg_cnt<=2’b00;
else if(neg_cnt==2’d2)
neg_cnt<=2’b00;
else
neg_cnt<=neg_cnt+1’b1;
end
reg div3_o_r0;
reg div3_o_r1;
always@(posedge div2_o_r or negedge rst_n_i)
begin
if(!rst_n_i)
div3_o_r0<=1’b0;
else if(pos_cnt<2’d1)
div3_o_r0<=1’b1;
else
div3_o_r0<=1’b0;
end
always@(negedge div2_o_r or negedge rst_n_i)
begin
if(!rst_n_i)
div3_o_r1<=1’b0;
else if(neg_cnt<2’d1)
div3_o_r1<=1’b1;
else
div3_o_r1<=1’b0;
end
reg div2hz_o_r;
assign div2_o=div2_o_r;
assign div3_o=div3_o_r0 | div3_o_r1;
assign div4_o=div4_o_r;
assign div8_o=div8_o_r;
endmodule
一,2分頻部分
reg div2_o_r;
always@(posedge clk_i or negedge rst_n_i)
begin
if(!rst_n_i)
div2_o_r<=1’b0;
else
div2_o_r<=~div2_o_r;
end
我們設輸入時鐘的周期為T,
由上面代碼可知,每當輸入時鐘上升沿的時候,我們就會翻轉,輸入時鐘一個周期只有一個上升沿,那么也就意味著2分頻高低電平持續時間是一個輸入時鐘周期T,則2分頻的周期就是2T,達到了分頻的效果,
(明明很簡單,寫的卻很羅里吧嗦,還沒圖
二,四分頻
有了上面2分頻思想,四分頻不是有手就行
我們只需要將always@(posedge clk_i or negedge rst_n_i),這個里面 clk_i換成我們已經寫好的2分頻,四分頻就出來了,那八分頻不也簡單的狠,
但是如果每次都那么一個一個的寫,不是很麻煩嗎
那么我就加個計數器
reg [1:0] div_cnt1;
always@(posedge clk_i or negedge rst_n_i)
begin
if(!rst_n_i)
div_cnt1<=2’b00;
else
div_cnt1<=div_cnt1+1’b1;
end
reg div4_o_r;
always@(posedge clk_i or negedge rst_n_i)
begin
if(!rst_n_i)
div4_o_r<=1’b0;
else if(div_cnt12’b00 || div_cnt12’b10)
div4_o_r<=~div4_o_r;
else
div4_o_r<=div4_o_r;
end
每當輸入時鐘上升沿,計數器開始計數,也就是每過T,我們開始計數,沒過2T我們來翻轉電平,那么周期為4T,那么
其他偶數分頻不是有手就行,
三,奇數分頻
我們以3分頻為例,為什么呢?(因為上面寫了)
reg [1:0] pos_cnt;
reg [1:0] neg_cnt;
always@(posedge div2_o_r or negedge rst_n_i)
begin
if(!rst_n_i)
pos_cnt<=2’b00;
else if(pos_cnt==2’d2)
pos_cnt<=2’b00;
else
pos_cnt<=pos_cnt+1’b1;
end
always@(negedge div2_o_r or negedge rst_n_i)
begin
if(!rst_n_i)
neg_cnt<=2’b00;
else if(neg_cnt==2’d2)
neg_cnt<=2’b00;
else
neg_cnt<=neg_cnt+1’b1;
end
reg div3_o_r0;
reg div3_o_r1;
always@(posedge div2_o_r or negedge rst_n_i)
begin
if(!rst_n_i)
div3_o_r0<=1’b0;
else if(pos_cnt<2’d1)
div3_o_r0<=1’b1;
else
div3_o_r0<=1’b0;
end
always@(negedge div2_o_r or negedge rst_n_i)
begin
if(!rst_n_i)
div3_o_r1<=1’b0;
else if(neg_cnt<2’d1)
div3_o_r1<=1’b1;
else
div3_o_r1<=1’b0;
end
assign div3_o=div3_o_r0 | div3_o_r1;
看了代碼,我們三分頻是基于2分頻時鐘,有兩個計時器 pos_cnt;neg_cnt;
由代碼我們可以看出,他們分別從二分頻的上升沿和下降沿開始從0到2計數(顯然時間間隔為T)
div3_o_r0 和 div3_o_r1在pos_cnt;neg_cnt為0的時刻為1,在1,2時間為0,
則div3_o當出現0時為1,無0則為1
從0計數到2,時間為6T,則每個數字為持續時間為2T
我們將0用00計,則每個數字持續時間為T
| pos_cnt | 0 | 0 | 1 | 1 | 2 | 2 | 0 | 0 | 1 | 1 | 2 | 2 | 0 | 0 | 1 | 1 | 2 | 2 | 0 | 0 | 1 | 1 | 2 | 2 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| neg_cnt | 2 | 0 | 0 | 1 | 1 | 2 | 2 | 0 | 0 | 1 | 1 | 2 | 2 | 0 | 0 | 1 | 1 | 2 | 2 | 0 | 0 | 1 | 1 | 2 |
| div3_o | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 1 |
(為什么不畫個圖?顯然不會,而且圖多了,反而不好看)
顯然其周期為6T,是對2分頻時鐘進行三分頻,(以此內推)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/244328.html
標籤:其他
上一篇:綜合javaweb專案。
