vivado代碼編寫——分頻

要開始編寫verilog代碼了,以常用的分頻為例,編寫一個(gè)簡(jiǎn)單的代碼。

FPGA設(shè)計(jì)中,分頻分為偶數(shù)分頻和奇數(shù)分頻。

偶數(shù)分頻只要計(jì)上升沿的個(gè)數(shù),然后按照分頻要求的不同計(jì)相應(yīng)個(gè)數(shù)的上升沿并進(jìn)行波形翻轉(zhuǎn)即可。

例如二分頻,每計(jì)到一個(gè)上升沿,波形翻轉(zhuǎn)一次;

例如四分頻,每計(jì)到兩個(gè)上升沿,波形翻轉(zhuǎn)一次。

奇數(shù)分頻相對(duì)比較麻煩,因?yàn)槠鏀?shù)分頻經(jīng)常要在給出時(shí)鐘的下降沿進(jìn)行翻轉(zhuǎn),而Verilog本質(zhì)上是硬件描述,設(shè)計(jì)的本質(zhì)仍然是硬件設(shè)計(jì)。在綜合設(shè)計(jì)時(shí),Verilog代碼必須映射到FPGA上的可用硬件上。

FPGA常用的電路是觸發(fā)器,觸發(fā)器是一個(gè)具有時(shí)鐘且僅對(duì)該時(shí)鐘的一個(gè)邊沿敏感的器件。

always@(posedge clk)綜合后映射到只對(duì)一個(gè)時(shí)鐘邊沿敏感的觸發(fā)器,always@(posedge

clk or negedge rst)綜合后映射到有一個(gè)異步控制端且僅對(duì)時(shí)鐘的一個(gè)邊沿敏感的觸發(fā)器。

不管always@()綜合后映射到哪種觸發(fā)器,它都只能使用一個(gè)時(shí)鐘沿觸發(fā)。

奇數(shù)分頻注定要比偶數(shù)分頻復(fù)雜,可以采用這樣的方式進(jìn)行奇數(shù)分頻:

假設(shè)要對(duì)給定的時(shí)鐘進(jìn)行2N+1分頻:先計(jì)數(shù);將計(jì)數(shù)分成N、N+1的兩段;前一段將變量div1置0,后一段將變量div1置1;用一個(gè)下降沿觸發(fā)的觸發(fā)器,div1延遲半個(gè)時(shí)鐘周期后輸出,生成div2;div1和div2相與,即得到分頻后的時(shí)鐘。

module FreDivDou(

input? clk_i,

input? rst_n_i,


output div2_o,

output div3_o,

output div4_o,

output dou2_o,

output dou3_o

??? );


// 二分頻:在原來時(shí)鐘的上升沿翻轉(zhuǎn)

reg div2_o_r;

always @(posedge clk_i or negedge rst_n_i)

begin

? if(!rst_n_i)

??? div2_o_r <= 0;

? else

??? div2_o_r <= ~div2_o_r;

end

//div2_o_r要在always塊內(nèi)賦值,需要定義成reg型

//assign相當(dāng)于一條連線,將表達(dá)式右邊的電路直接通過wire(線網(wǎng)型)連接到左邊,

//左邊信號(hào)必須是wire型(output屬于wire型)。當(dāng)右邊變化時(shí),左邊立刻發(fā)生變化。

assign div2_o = div2_o_r;?


//四分頻,計(jì)數(shù),每計(jì)夠兩個(gè)上升沿翻轉(zhuǎn)一次

reg [1:0]? counter_div4;

reg div4_o_r;

always @(posedge clk_i or negedge rst_n_i)

begin

? if(!rst_n_i)? begin

??? counter_div4 <= 0;

??? div4_o_r <= 0;

? end

? else

??? if(counter_div4 <= 0)begin

????? counter_div4 <= 'b1;

????? div4_o_r <= div4_o_r;

??? end

??? else if(counter_div4 <='b1) begin

???? counter_div4 <= 0;

????? div4_o_r <=~div4_o_r;

??? end???

?end


assign div4_o = div4_o_r;


//3分頻,第0個(gè)上升沿div1為1,第1、2個(gè)上升沿div1為0

reg div1,div2;

reg [1:0] counter_div3;

always @(posedge clk_i or negedge rst_n_i)

begin

? if(!rst_n_i) begin

??? div1 <= 0;

??? counter_div3 <= 0;

? end

? else if(counter_div3 == 'd0)begin

??? div1 <= 'b1;

??? counter_div3 <=counter_div3 + 'b1;

? end

? else if(counter_div3 == 'd1)begin

??? div1 <= 0;

??? counter_div3 <=counter_div3 + 'b1;

? end

? else? begin

??? div1 <= 0;

??? counter_div3 <= 0;

? end

end


//3分頻,div1在時(shí)鐘的下降沿產(chǎn)生div2

always @(negedge clk_i or negedge rst_n_i)

if(!rst_n_i)

? div2 <= 0;

else

? div2 <= div1;


assign div3_o = div1 | div2;???


endmodule

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容