設計規劃
依次點亮4個LED燈,實現流水燈的效果,兩燈之間點亮間隔為0.5s,LED燈一次點亮持續時間0.5s。
LED燈低電平點亮,因此流水燈應該是1110-1101-1011-0111-1110-1101-...
首先是時鐘信號、復位信號,由于需要計時,我們還要產生一個計數器cnt。然后還需要產生一個cnt_flag脈沖標志信號作為流水切換的標志,每當計數器計數到24_999_998時拉高并只產生一個時鐘的高電平(高電平出現LED狀態就開始切換)。最重要的是,流水燈的實現是通過左移操作,無法直接通過led_out的左移實現,因此需要定義一個led_out_reg(led_out從1110左移一次是1100,會有兩個燈點亮,而led_out_reg是LED的位反0001,左移一次是0010,取反后led_out是1101,就能實現流水的需求)。
編寫代碼
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:計數器計數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:計數器計數滿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循環流水
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:計數器變化的條件是時鐘上升和復位有效(復位下降),復位信號有效時cnt變為低電平;計滿時清零;其他時刻+1。
2、cnt_flag:計數器計滿的脈沖標志信號,變化條件和cnt一樣,復位有效時變為低電平;計滿前一個時鐘拉高;其他時刻都為0,這樣就能成為一個脈沖信號,并在計滿前拉高,標志led要左移。
3、led_out_reg:暫存led燈狀態,可以直接對這個信號進行操作來控制LED燈。復位和初始時是最右邊的燈亮,反推出led_out_reg=0001;當最左邊的燈亮且計滿標志信號拉高時,令最右邊的燈亮led_out_reg=0001;當計滿標志信號拉高時,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 ;
//初始化系統時鐘、全局復位
initial begin
sys_clk = 1'b1;
sys_rst_n <= 1'b0;
#20
sys_rst_n <= 1'b1;
end
//sys_clk:模擬系統時鐘,每10ns電平翻轉一次,周期為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分別對應了十六進制的e,d,b,7
由于在testbench模塊,為了節省時間將CNT_MAX設置成24,因此24個時鐘脈沖LED的狀態就會發生變化,波形和我們預想的一致。
分配管腳
-
FPGA
+關注
關注
1626文章
21667瀏覽量
601849 -
led燈
+關注
關注
22文章
1592瀏覽量
107837 -
計數器
+關注
關注
32文章
2253瀏覽量
94353 -
流水燈
+關注
關注
21文章
432瀏覽量
59637 -
時鐘信號
+關注
關注
4文章
445瀏覽量
28510
發布評論請先 登錄
相關推薦
評論