使用verilog編寫週期爲4s的呼吸燈,基於quartues平臺,並具有測試文件查看波形,適合新手入門

使用verilog編寫週期爲4s的呼吸燈,基於quartues平臺,並具有測試文件查看波形,適合新手入門

編寫文件如下:
module breath_led(clk,rst_n,led);
input wire clk; //50MHZ時鐘輸出
input wire rst_n; //復位
output reg [3:0] led; //同時輸出四位led

reg 		[6:0]					cnt1;			//20ns的時鐘計數應該是0~99,共100次,位寬爲7
reg 		[9:0]					cnt2;			//2us的時鐘計數應該是0~999,共1000次,位寬爲10
reg 		[9:0]					cnt3;			//2ms的時鐘計數應該是0~999,共1000次,位寬爲10

parameter 	CNT1_MAX			=	7'd100;			//定義參數,方便修改
parameter 	CNT2_MAX 			=	10'd1000;
parameter 	CNT3_MAX			=	10'd1000;


wire								flag1;					//定義標誌位
wire								flag2;					//定義標誌位
wire								wave;					//定義輸出波形
reg 								valid;					//定義變量

//--------------------20ns計數器計數100次
always @(posedge clk)
begin
if(!rst_n)
cnt1<=7’d0;
else
if(cnt1<CNT1_MAX-1’b1)
cnt1<=cnt1+1’b1;
else
cnt1<=7’d0;
end

assign flag1=(cnt1<CNT1_MAX-1’b1)?1’b1:1’b0;//判斷

//--------------------2us計數器計數1000次
always @(posedge clk)
begin
if(!rst_n)
cnt2<=10’d0;
else
if(flag1==1)
if(cnt2<CNT2_MAX-1’b1)
cnt2<=cnt2+1’b1;
else
cnt2<=10’d0;
else
cnt2<=cnt2;
end

assign flag2=(flag11’b1 && cnt2CNT2_MAX); //判斷

//--------------------2ms計數器計數1000次
always @(posedge clk)
begin
if(!rst_n)
cnt3<=10’d0;
else
if(flag2==1’b1)
if(cnt3<CNT3_MAX-1’b1)
cnt3<=cnt3+1’b1;
else
cnt3<=10’d0;
else
cnt3<=cnt3;
end

assign wave = (cnt3>cnt2)?1’b0:1’b1; //輸出的波形,通過計數器的數值比較輸出佔空比

always @(posedge clk)
begin
if(!rst_n)
valid<=1’b0;
else
if(flag21’b1 && cnt3CNT3_MAX-1’b1)//利用valid來判斷滿足三個條件
valid <= ~valid ;
else
valid <=valid;

end 

always @(posedge clk) //利用此模塊實現波形取反,從最暗到最亮到最暗
begin
if(!rst_n)
led<=1’b0;
else
if(valid ==1’b1)
led<=~{4{wave}};
else
led<={4{wave}};
end

endmodule

需要提醒的是wave爲1時與led輸出相同,否則相反,測試文件就比較簡單了:
`timescale 1ns/1ps
module breath_led_tb();
reg clk;
reg rst_n;

wire 	[3:0]						led;

//強制“訂餐”(定參),方便觀測波形
defparam breath_led_inst.CNT1_MAX=	7'd10;			
defparam breath_led_inst.CNT2_MAX=	10'd10;	
defparam breath_led_inst.CNT3_MAX=	10'd10;

breath_led breath_led_inst(
.clk(clk),
.rst_n(rst_n),
.led(led)
);

always #10 clk=~clk;
initial clk=1’b0;

initial
begin
rst_n=1’b0;
#200 @(posedge clk);
#2 rst_n=1’b1;
repeat(10101025)
begin
@(posedge clk);
end
$stop;

end 

endmodule

這個生成的邏輯電路需要慢慢分析
在這裏插入圖片描述
可以看到一個週期的時間,和不同的佔空比,因爲led[3:0]四個燈 的狀態是一樣的,所以隨便拿了led[3]來分析。再提醒一邊的是wave爲1時與led輸出相同,否則相反。
在這裏插入圖片描述

本人小白入門,把學到的東西分享,希望在此查看的老鐵批評指正,希望大家共同進步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章