FPGA实验板verilog hdl语言之流水灯计数

verilog hdl语言学习笔记

作业1:
程序语言VerilogHDL,用FPGA板完成要求:
用点亮4盏LED灯;
4盏LED灯在1秒内轮流点亮,即每盏LED灯的点亮时间是250毫秒;
一个轮流完成后,用一个4位的加法器累加LED循环的次数;
即当每一轮第四盏LED熄灭后,这四盏LED灯将以点亮的方式表示出加法器中的16进制的数值 (全灭为0,灭灭灭亮为1,灭灭亮灭为2,灭灭亮亮为3,依次类推),点亮时间为2秒;
加法器的数值从0~F循环。

我完成的代码:


`timescale 1ns / 1ps
module led_test
(
	input           clk,           // system clock 50Mhz on board
	input           rst_n,         // reset ,low active
	output reg[3:0] led            // LED,use for control the LED signal on board
);

//define the time counter
reg [31:0]      timer;
reg [3:0]       count;
//integer  i;
// cycle counter:from 0 to 4 sec
always@(posedge clk or negedge rst_n)
begin
	if (rst_n == 1'b0)
		    timer <= 32'd0;  		                          //when the reset signal valid,time counter clearing
	else if (timer == 32'd149_999_999)      //4 seconds count(50M*4-1=199999999)
		
		timer <= 32'd0;                     //count done,clearing the time counter 
		
	else
		timer <= timer + 4'd1;             //timer counter = timer counter + 1
end
// LED control
always@(posedge clk or negedge rst_n)
begin
  
	if (rst_n == 1'b0)
		led <= 4'b0001;
	else if (timer == 32'd0)        //time counter count to 1st sec,LED1 lighten 
		   led <= 4'b0001;            //when the reset signal active
	else if (timer == 32'd12_499_999)        //time counter count to 1st sec,LED1 lighten 
		  led <= 4'b0010;
	else if (timer == 32'd24_999_999)       //time counter count to 2nd sec,LED2 lighten
		led <= 4'b0100;
	else if (timer == 32'd37_499_999)      //time counter count to 3rd sec,LED3 lighten
		led <= 4'b1000;
	else if (timer == 32'd49_999_999)      //time counter count to 4th sec,LED4 lighten
		led <= 4'b0000;
	else if (timer == 32'd62_499_999)      //time counter count to 4th sec,LED4 lighten	   
//			i= (count[0]+(count{1}&2)+(count{2}&4)+(count{3}&8));                               
         case(count)
          4'b0000 : led <=4'b0000;  
          4'b0001 : led <=4'b1000;  
          4'b0010 : led <=4'b0100;  
          4'b0011 : led <=4'b1100;  
		 4'b0100 : led <=4'b0010; 
          4'b0101 : led <=4'b1010; 
         4'b0110 : led <=4'b0110; 
          4'b0111 : led <=4'b1110;
			 4'b1000 : led <=4'b0001; 
          4'b1001 : led <=4'b1001; 
          4'b1010 : led <=4'b0101; 
          4'b1011 : led <=4'b1101;
			 
			 4'b1100 : led <=4'b0011; 
         4'b1101 : led <=4'b1011; 
          4'b1110 : led <=4'b0111; 
          4'b1111 : led <=4'b1111;
          
        endcase                       	
end
always@(posedge clk or negedge rst_n)
begin
	if (rst_n == 1'b0)
		    count <= 4'd0; 	                          
	else if (timer == 32'd149_999_999)      	                   
		count <= count + 4'd1;  	
	         	
			
end


endmodule

更新代码(改进了最后led灯的赋值方式):


`timescale 1ns / 1ps
module led_test
(
	input           clk,           // system clock 50Mhz on board
	input           rst_n,         // reset ,low active
	output reg[3:0] led            // LED,use for control the LED signal on board
);

//define the time counter
reg [31:0]      timer;
reg [3:0]       o_cnt;

// cycle counter:from 0 to 4 sec
always@(posedge clk or negedge rst_n)
begin
	if (rst_n == 1'b0)
	begin
		timer <= 32'd0; 
      o_cnt <= 4'd0;                		//when the reset signal valid,time counter clearing
	end
	else if (timer == 32'd99_999_999)      //4 seconds count(50M*4-1=199999999)
	begin
		timer <= 32'd0;                     //count done,clearing the time counter
		o_cnt = o_cnt + 4'd1;
	end
	else
		timer <= timer + 32'd1;             //timer counter = timer counter + 1
end

// LED control
always@(posedge clk or negedge rst_n)
begin
	if (rst_n == 1'b0)
		led <= 4'b0000;	                   //when the reset signal active
	else if (timer == 32'd12_499_999)       //time counter count to 1st sec,LED1 lighten
		led <= 4'b0001;
	else if (timer == 32'd24_999_999)       //time counter count to 2nd sec,LED2 lighten
		led <= 4'b0010;
	else if (timer == 32'd37_499_999)      //time counter count to 3rd sec,LED3 lighten
		led <= 4'b0100;
	else if (timer == 32'd49_999_999)      //time counter count to 4th sec,LED4 lighten
		led <= 4'b1000;
	else if (timer == 32'd62_499_999)
		led = o_cnt;
//	else if (timer == 32'd74_999_999)
//		led <= o_cnt;
//	else if (timer == 32'd87_499_999)
//		led <= o_cnt;
//	else if (timer == 32'd99_999_999)
//		led <= o_cnt;	
end

endmodule

作业2:
在第一次作业的基础上,增加按键功能:
功能按键1——功能按键1按下后,暂停计数器计数,4盏LED持续循环点亮;当再次按下功能按键1后,计数器恢复计数功能。
复位按键2——复位按键2按下后,计数器将复位;

我感觉难点在于按键的消抖上,下面代码按键消抖有问题,但又没想明白错在哪?有大佬路过指点一下!!

`timescale 1ns / 1ps
module led_test
(
	input           clk,           // system clock 50Mhz on board
	input           rst_n,         // reset ,low active
	input [0:0]        key,
	output reg[3:0] led            // LED,use for control the LED signal on board
);
reg [31:0]      timer;
reg [3:0]       count;
reg [0:0]        flag;
reg [31:0]      t1;
//reg [31:0]      t2;
localparam delay_param = 32'd499_999;
       
wire  delay_10ms =((timer - t1) >= delay_param)?1'b1:1'b0;    //本意是通过按键操作前与按后的时间差达到10ms,但是这样是有问题的?
	
always@(posedge clk or negedge rst_n)
begin
	if (rst_n == 1'b0)
		timer <= 32'd0;                     
	else if (timer == 32'd149_999_999) 
	     timer <= 32'd0;    
	
	else if((timer == 32'd49_999_999) &&(flag== 1'd1))     
    	   timer <= 32'd0; 
 
	else
       timer <= timer + 32'd1;            
end	
// LED control
always@(posedge clk or negedge rst_n)
begin
	if (rst_n == 1'b0)
		begin
	   	led <= 4'b0000;
		   count <= 4'd0; flag <= 1'd0; 
		end  
  
   else if (key==1'd0)
	     begin                  //按键的部分
		    if(delay_10ms)            
	          flag <= ~flag;		//标志位翻转			
	      end  
	else if (timer == 32'd0)        
		  led <= 4'b0001; 
	else if (timer == 32'd12_499_999)       
		  led <= 4'b0010;
	else if (timer == 32'd24_999_999)      
		  led <= 4'b0100;
	else if (timer == 32'd37_499_999)     
		  led <= 4'b1000;	 
	else if (timer == 32'd49_999_999)      
		  led <= 4'b0000; 	   	
	else if ((timer == 32'd62_499_999)&& (flag == 0) )                        
		 begin 
	     	 count <= count + 4'd1;
		    led = count; 	
		 end
    else
	      t1 = timer;	                   //这个地方注意一下
		 
end

endmodule

参考了网上消抖后,没有问题的代码:


`timescale 1ns / 1ps
module led_test
(
	input           clk,           // system clock 50Mhz on board
	input           rst_n,         // reset ,low active
	input [0:0]        key,
	output reg[3:0] led            // LED,use for control the LED signal on board
);

//define the time counter
reg [31:0]      timer;
reg [3:0]       count;
reg [0:0]        flag;
reg cnt_full;
reg [19:0] cnt;
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		cnt <= 20'd0;
	else if(cnt == 20'd999_999)
			cnt <= 20'd0;
		 else 
			cnt <= cnt + 1'b1; 	 
end
//计数满信号
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		cnt_full <= 1'b0;
	else if(cnt == 20'd999_999)
			cnt_full <= 1'b1;
		 else 
		 	cnt_full <= 1'b0;
end

reg [0:0] key_in_r;
reg [0:0] key_in_r_next;
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		key_in_r_next <= 1'b1;
	else if(cnt_full)
			key_in_r_next <= key;
		 else 
		 	key_in_r_next <= key_in_r_next;
end
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		key_in_r <= 1'b1;
	else
		key_in_r <= key_in_r_next;
end
wire [0:0] key_out;
assign key_out = key_in_r & (~key_in_r_next);

always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		flag <= 1'd0; 
   else if (key_out==1'd1)   
         flag <= ~flag;	
end
/	
always@(posedge clk or negedge rst_n)
begin
	if (rst_n == 1'b0)
		timer <= 32'd0;                     
	else if (timer == 32'd149_999_999) 
	     timer <= 32'd0;    
	
	else if((timer == 32'd49_999_999) &&(flag== 1'd1))
    	   timer <= 32'd0; 
 
	else
       timer <= timer + 32'd1;            
end
	
// LED control
always@(posedge clk or negedge rst_n)
begin
	if (rst_n == 1'b0)
		begin
	   	led <= 4'b0000;
		   count <= 4'd0;
		end   
	    	 		    
	else if (timer == 32'd0)        
		  led <= 4'b0001; 
	else if (timer == 32'd12_499_999)       
		  led <= 4'b0010;
	else if (timer == 32'd24_999_999)      
		  led <= 4'b0100;
	else if (timer == 32'd37_499_999)     
		  led <= 4'b1000;	 
	else if (timer == 32'd49_999_999)      
		  led <= 4'b0000; 	   	
	else if ((timer == 32'd62_499_999)&& (flag == 0) )                        
		 begin 
	     	 count <= count + 4'd1;
		    led = count; 	
		 end
    
end

endmodule

猜你喜欢

转载自blog.csdn.net/weixin_43175701/article/details/109251410
今日推荐