設(shè)計規(guī)劃
依次點亮4個LED燈,實現(xiàn)流水燈的效果,兩燈之間點亮間隔為0.5s,LED燈一次點亮持續(xù)時間0.5s。
LED燈低電平點亮,因此流水燈應(yīng)該是1110-1101-1011-0111-1110-1101-...
首先是時鐘信號、復(fù)位信號,由于需要計時,我們還要產(chǎn)生一個計數(shù)器cnt。然后還需要產(chǎn)生一個cnt_flag脈沖標志信號作為流水切換的標志,每當(dāng)計數(shù)器計數(shù)到24_999_998時拉高并只產(chǎn)生一個時鐘的高電平(高電平出現(xiàn)LED狀態(tài)就開始切換)。最重要的是,流水燈的實現(xiàn)是通過左移操作,無法直接通過led_out的左移實現(xiàn),因此需要定義一個led_out_reg(led_out從1110左移一次是1100,會有兩個燈點亮,而led_out_reg是LED的位反0001,左移一次是0010,取反后led_out是1101,就能實現(xiàn)流水的需求)。
編寫代碼
module water_led
#(
parameter CNT_MAX = 25'd24_999_999
)
(
input wire sys_clk ,
input wire sys_rst_n ,
output wire [3:0] led_out
);
//reg define
reg [24:0] cnt ;
reg cnt_flag ;
reg [3:0] led_out_reg ;
//cnt:計數(shù)器計數(shù)500ms
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt <= 25'b0;
else if(cnt == CNT_MAX)
cnt <= 25'b0;
else
cnt <= cnt + 1'b1;
//cnt_flag:計數(shù)器計數(shù)滿500ms標志信號
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_flag <= 1'b0;
else if(cnt == CNT_MAX - 1)
cnt_flag <= 1'b1;
else
cnt_flag <= 1'b0;
//led_out_reg:led循環(huán)流水
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
led_out_reg <= 4'b0001;
else if(led_out_reg == 4'b1000 && cnt_flag == 1'b1)
led_out_reg <= 4'b0001;
else if(cnt_flag == 1'b1)
led_out_reg <= led_out_reg < < 1'b1; //左移
assign led_out = ~led_out_reg;
endmodule
三個中間信號的定義:cnt,cnt_flag,led_out_reg。
1、cnt:計數(shù)器變化的條件是時鐘上升和復(fù)位有效(復(fù)位下降),復(fù)位信號有效時cnt變?yōu)榈碗娖剑挥嫕M時清零;其他時刻+1。
2、cnt_flag:計數(shù)器計滿的脈沖標志信號,變化條件和cnt一樣,復(fù)位有效時變?yōu)榈碗娖剑挥嫕M前一個時鐘拉高;其他時刻都為0,這樣就能成為一個脈沖信號,并在計滿前拉高,標志led要左移。
3、led_out_reg:暫存led燈狀態(tài),可以直接對這個信號進行操作來控制LED燈。復(fù)位和初始時是最右邊的燈亮,反推出led_out_reg=0001;當(dāng)最左邊的燈亮且計滿標志信號拉高時,令最右邊的燈亮led_out_reg=0001;當(dāng)計滿標志信號拉高時,led_out_reg左移。而控制LED電平的輸出信號led_out是led_out_reg的按位取反。
編寫testbench
`timescale 1ns/1ns
module tb_water_led();
//wire define
wire [3:0] led_out ;
//reg define
reg sys_clk ;
reg sys_rst_n ;
//初始化系統(tǒng)時鐘、全局復(fù)位
initial begin
sys_clk = 1'b1;
sys_rst_n <= 1'b0;
#20
sys_rst_n <= 1'b1;
end
//sys_clk:模擬系統(tǒng)時鐘,每10ns電平翻轉(zhuǎn)一次,周期為20ns,頻率為50MHz
always #10 sys_clk = ~sys_clk;
//-------------------- water_led_inst --------------------
water_led
#(
.CNT_MAX (25'd24)
)
water_led_inst
(
.sys_clk (sys_clk ), //input sys_clk
.sys_rst_n (sys_rst_n ), //input sys_rst_n
.led_out (led_out ) //output [3:0] led_out
);
endmodule
testbench代碼是非常熟悉的,信號定義,初始化,實例化。
對比波形
1110-1101-1011-0111分別對應(yīng)了十六進制的e,d,b,7
由于在testbench模塊,為了節(jié)省時間將CNT_MAX設(shè)置成24,因此24個時鐘脈沖LED的狀態(tài)就會發(fā)生變化,波形和我們預(yù)想的一致。
分配管腳
-
FPGA
+關(guān)注
關(guān)注
1629文章
21735瀏覽量
603171 -
led燈
+關(guān)注
關(guān)注
22文章
1592瀏覽量
107974 -
計數(shù)器
+關(guān)注
關(guān)注
32文章
2256瀏覽量
94521 -
流水燈
+關(guān)注
關(guān)注
21文章
432瀏覽量
59705 -
時鐘信號
+關(guān)注
關(guān)注
4文章
448瀏覽量
28558
發(fā)布評論請先 登錄
相關(guān)推薦
評論