cmseasy做網(wǎng)站簡(jiǎn)單嗎營(yíng)銷策劃培訓(xùn)
目錄
1.breath_led.v
2.tb_breath_led.v
呼吸燈就是從完全熄滅到完全點(diǎn)亮,再?gòu)耐耆c(diǎn)亮到完全熄滅。具體就是通過控制PWM的占空比控制亮滅程度。
繪制PWM波的步驟就是,首先燈是在第一個(gè)時(shí)鐘周期保持高電平熄滅狀態(tài),在第二個(gè)時(shí)鐘周期保持1/10個(gè)時(shí)鐘周期的低電平,其余都是高電平。在第3個(gè)時(shí)鐘周期保持2/10的低電平,剩余都是高電平,依次繪制下去直到第11個(gè)時(shí)鐘周期在一個(gè)周期內(nèi)都是低電平點(diǎn)亮狀態(tài)。然后下一個(gè)周期還是點(diǎn)亮狀態(tài),之后開始逐漸熄滅的波形圖的繪制。首先1/10的高電平其余全是低電平...
首先要知道從完全熄滅到完全點(diǎn)亮的時(shí)間是多少,定義為1S。聲明一個(gè)1S的計(jì)數(shù)器。初識(shí)狀態(tài)不在周期里面因此設(shè)置為10個(gè)周期,把1S分成1000份,1S/1000=0.001s=1ms,每個(gè)T就是1ms。為什么要分成1000份呢,因?yàn)榉值姆輸?shù)越大,看起來就越細(xì)膩,呼吸效果就越好。再把T分成1000份,每次增加一小份。1ms/1000=0.001ms=1us。因此這里就有3個(gè)計(jì)數(shù)器,我們可以先從1us繪制波形圖,當(dāng)滿足1000份就是1ms,這樣比全部用時(shí)鐘信號(hào)計(jì)數(shù)可以節(jié)約邏輯資源,最大計(jì)數(shù)都是999。
50Mhz,一個(gè)時(shí)鐘周期就是20ns,那么1us/20ns=1000ns/20ns=50,因此1us要計(jì)數(shù)50個(gè)時(shí)鐘周期,最大值就是49。當(dāng)us計(jì)數(shù)器從0計(jì)數(shù)到49的時(shí)候,ms計(jì)數(shù)器加1,目的是為了計(jì)算1ms計(jì)數(shù)器的數(shù)量,當(dāng)ms計(jì)數(shù)器計(jì)數(shù)到999的時(shí)候,s計(jì)數(shù)器就加1。當(dāng)s計(jì)數(shù)器計(jì)數(shù)到999的時(shí)候,此時(shí)就花了1s,就表示走過了從全暗到全亮的一個(gè)過程。
完整的波形圖如下:
以上的波形圖還不對(duì),因?yàn)檫€有完全點(diǎn)亮到逐漸熄滅的逆過程,可以通過對(duì)led_out取反獲得
增加了一個(gè)cnt_en使能信號(hào),前1s是低電平,后1s是高電平。
以上是從亮變暗的過程。當(dāng)cnt_en為低電平并且cnt_1ms<=cnt_1s時(shí),或者cnt_en為高電平并且cnt_1ms>cnt_1s時(shí),輸出led_out為低電平,反之為高電平。
1.breath_led.v
module breath_led#(parameter CNT_1US_MAX=6'd49,parameter CNT_1MS_MAX=10'd999,parameter CNT_1S_MAX=10'd999)
(input wire sys_clk ,input wire sys_rst_n ,output reg led_out
);reg [9:0]cnt_1s ;
reg [9:0] cnt_1ms;
reg [5:0] cnt_1us;
reg cnt_en;always@(posedge sys_clk or negedge sys_rst_n)if (sys_rst_n==1'b0)cnt_1us<=6'd0;else if(cnt_1us==CNT_1US_MAX)cnt_1us<=6'd0;elsecnt_1us<=cnt_1us+1'd1;always@(posedge sys_clk or negedge sys_rst_n)if (sys_rst_n==1'b0)cnt_1ms<=10'd0;else if((cnt_1us==CNT_1US_MAX)&&(cnt_1ms==CNT_1MS_MAX))cnt_1ms<=10'd0;else if(cnt_1us==CNT_1US_MAX)cnt_1ms<=cnt_1ms+1'd1;elsecnt_1ms<=cnt_1ms;always@(posedge sys_clk or negedge sys_rst_n)if (sys_rst_n==1'b0)cnt_1s<=10'd0;else if((cnt_1s==CNT_1S_MAX)&&(cnt_1ms==CNT_1MS_MAX)&&(cnt_1us==CNT_1US_MAX))cnt_1s<=10'd0;else if((cnt_1us==CNT_1US_MAX)&&(cnt_1ms==CNT_1MS_MAX))cnt_1s<=cnt_1s+1'd1;elsecnt_1s<=cnt_1s;always@(posedge sys_clk or negedge sys_rst_n)if (sys_rst_n==1'b0)cnt_en<=1'b0;else if ((cnt_1s==CNT_1S_MAX)&&(cnt_1ms==CNT_1MS_MAX)&&(cnt_1us==CNT_1US_MAX))cnt_en=~cnt_en;else cnt_en<=cnt_en;always@(posedge sys_clk or negedge sys_rst_n)if (sys_rst_n==1'b0)led_out<=1'b1;else if(((cnt_en==1'b0)&&(cnt_1ms<=cnt_1s))||((cnt_en==1'b1)&&(cnt_1ms>cnt_1s)))led_out<=1'b0;else led_out=1'b1;endmodule
2.tb_breath_led.v
`timescale 1ns/1nsmodule tb_breath_led();reg sys_clk;
reg sys_rst_n;wire led_out;initial beginsys_clk=1'b1;sys_rst_n<=1'b0;#20sys_rst_n<=1'b1; endalways #10 sys_clk=~sys_clk;breath_led
#(.CNT_1US_MAX (6'd4),.CNT_1MS_MAX (10'd9),.CNT_1S_MAX (10'd9))
breath_led_inst
(.sys_clk (sys_clk) ,.sys_rst_n (sys_rst_n),.led_out (led_out)
);
endmodule