fpga数码管计数+键控作业

作业3:
利用LED、KEY和Segment LED,实现下面的功能;
(1)实现6位的10进制计数器计数,并在Segment LED显示计数器的次数;
即4盏LED一秒内循环点亮, 10进制计数器加1,同时在Segment LED上显示计数的次数;
(2)实现Reset 按键功能,按下按键后全部清零;
(3)功能按键1——按下功能按键1,暂停计数器计数,Segment LED维持当前数值显示,此时,4盏LED同时(同步)闪烁点亮;
(4)当再次按下功能按键1,计数器恢复计数功能, 4盏LED恢复一秒内循环点亮。
(5)功能按键2——按下功能按键2,自动完成功能:先暂停计数器计数(1秒),然后实现6位10进制计数器加10并显示,最后恢复计数器计数。
展示

数码管自动计数流程差不多是这个意思吧

代码分了五个.v文件



`timescale 1ns / 1ps
//*******************************************************************************/
module seg_test(
                input      clk,
                input      rst_n,
                output[5:0]seg_sel,
                output[7:0]seg_data,
			       input [1:0]      key,
	             output [3:0] led          
                );
					 
reg[31:0] timer_cnt;
reg en_1hz;                          //1 second , 1 counter enable
always@(posedge clk or negedge rst_n)
begin
    if(rst_n == 1'b0)
    begin
        en_1hz <= 1'b0;
        timer_cnt <= 32'd0;
    end
    else if(timer_cnt >= 32'd49_999_999)
    begin
        en_1hz <= 1'b1;
        timer_cnt <= 32'd0;
    end
    else
    begin
        en_1hz <= 1'b0;
        timer_cnt <= timer_cnt + 32'd1; 
    end
end



led_test  led_test0
(
	.clk           (clk),           // system clock 50Mhz on board
	.rst_n          (rst_n),         // reset ,low active
	.key           (key[0]),
	.led            (led)            // LED,use for control the LED signal on board
);

wire[3:0] count0;
wire t0;
count_m10 count10_m0(
    .clk    (clk),
    .rst_n  (rst_n),
    .en     (en_1hz),
    .clr    (1'b0),
	 .key      (key),
    .data   (count0),
    .t      (t0)
 );
wire[3:0] count1;
wire t1;
count_m10 count10_m1(
     .clk    (clk),
     .rst_n  (rst_n),
     .en     (t0),
     .clr    (1'b0),
	 .key      (2'b11),
     .data   (count1),
     .t      (t1)
 );

wire[3:0] count2;
wire t2;
count_m10 count10_m2(
    .clk   (clk),
    .rst_n (rst_n),
    .en    (t1),
    .clr   (1'b0),
	 .key      (2'b11),
    .data  (count2),
    .t     (t2)
);

wire[3:0] count3;
wire t3;
count_m10 count10_m3(
    .clk   (clk),
    .rst_n (rst_n),
    .en    (t2),
    .clr   (1'b0),
	 .key       (2'b11),
    .data  (count3),
    .t     (t3)
);

wire[3:0] count4;
wire t4;
count_m10 count10_m4(
    .clk   (clk),
    .rst_n (rst_n),
    .en    (t3),
    .clr   (1'b0),
	 .key        (2'b11),
    .data  (count4),
    .t     (t4)
);

wire[3:0] count5;
wire t5;
count_m10 count10_m5(
    .clk   (clk),
    .rst_n (rst_n),
    .en    (t4),
    .clr   (1'b0),
	 .key        (2'b11),
    .data  (count5),
    .t     (t5)
);

wire[6:0] seg_data_0;
seg_decoder seg_decoder_m0(
    .bin_data  (count5),
    .seg_data  (seg_data_0)
);
wire[6:0] seg_data_1;
seg_decoder seg_decoder_m1(
    .bin_data  (count4),
    .seg_data  (seg_data_1)
);
wire[6:0] seg_data_2;
seg_decoder seg_decoder_m2(
    .bin_data  (count3),
    .seg_data  (seg_data_2)
);
wire[6:0] seg_data_3;
seg_decoder seg_decoder_m3(
    .bin_data  (count2),
    .seg_data  (seg_data_3)
);
wire[6:0] seg_data_4;
seg_decoder seg_decoder_m4(
    .bin_data  (count1),
    .seg_data  (seg_data_4)
);

wire[6:0] seg_data_5;
seg_decoder seg_decoder_m5(
    .bin_data  (count0),
    .seg_data  (seg_data_5)
);

seg_scan seg_scan_m0(
    .clk        (clk),
    .rst_n      (rst_n),
    .seg_sel    (seg_sel),
    .seg_data   (seg_data),
    .seg_data_0 ({1'b1,seg_data_0}),      //The  decimal point at the highest bit,and low level effecitve
    .seg_data_1 ({1'b1,seg_data_1}), 
    .seg_data_2 ({1'b1,seg_data_2}),
    .seg_data_3 ({1'b1,seg_data_3}),
    .seg_data_4 ({1'b1,seg_data_4}),
    .seg_data_5 ({1'b1,seg_data_5})
);
endmodule 
//LED 灯控制
module led_test
(
	input           clk,           // system clock 50Mhz on board
	input           rst_n,         // reset ,low active
	input [1: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'd49_999_999) 
    	   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 (flag == 0)   	 		    
	   begin
	    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; 	   	
	   end
   else
	   begin  
	       if (timer == 32'd0) 
			 led <= 4'b0000; 
			 else if(timer == 32'd24_999_999) 
			 led <= 4'b1111; 
		end
end
endmodule

//扫描模块

module seg_scan(
	input           clk,
	input           rst_n,
	output reg[5:0] seg_sel,      //digital led chip select
	output reg[7:0] seg_data,     //eight segment digital tube output,MSB is the decimal point
	input[7:0]      seg_data_0,
	input[7:0]      seg_data_1,
	input[7:0]      seg_data_2,
	input[7:0]      seg_data_3,
	input[7:0]      seg_data_4,
	input[7:0]      seg_data_5
);
parameter SCAN_FREQ = 200;     //scan frequency
parameter CLK_FREQ = 50000000; //clock frequency

parameter SCAN_COUNT = CLK_FREQ /(SCAN_FREQ * 6) - 1;

reg[31:0] scan_timer;  //scan time counter
reg[3:0] scan_sel;     //Scan select counter
always@(posedge clk or negedge rst_n)
begin
	if(rst_n == 1'b0)
	begin
		scan_timer <= 32'd0;
		scan_sel <= 4'd0;
	end
	else if(scan_timer >= SCAN_COUNT)
	begin
		scan_timer <= 32'd0;
		if(scan_sel == 4'd5)
			scan_sel <= 4'd0;
		else
			scan_sel <= scan_sel + 4'd1;
	end
	else
		begin
			scan_timer <= scan_timer + 32'd1;
		end
end
always@(posedge clk or negedge rst_n)
begin
	if(rst_n == 1'b0)
	begin
		seg_sel <= 6'b111111;
		seg_data <= 8'hff;
	end
	else
	begin
		case(scan_sel)
			//first digital led
			4'd0:
			begin
				seg_sel <= 6'b11_1110;
				seg_data <= seg_data_0;
			end
			//second digital led
			4'd1:
			begin
				seg_sel <= 6'b11_1101;
				seg_data <= seg_data_1;
			end
			//...
			4'd2:
			begin
				seg_sel <= 6'b11_1011;
				seg_data <= seg_data_2;
			end
			4'd3:
			begin
				seg_sel <= 6'b11_0111;
				seg_data <= seg_data_3;
			end
			4'd4:
			begin
				seg_sel <= 6'b10_1111;
				seg_data <= seg_data_4;
			end
			4'd5:
			begin
				seg_sel <= 6'b01_1111;
				seg_data <= seg_data_5;
			end
			default:
			begin
				seg_sel <= 6'b11_1111;
				seg_data <= 8'hff;
			end
		endcase
	end
end

endmodule

module seg_decoder
(
	input[3:0]      bin_data,     // bin data input
	output reg[6:0] seg_data      // seven segments LED output
);

always@(*)
begin
	case(bin_data)
		4'd0:seg_data <= 7'b100_0000;
		4'd1:seg_data <= 7'b111_1001;
		4'd2:seg_data <= 7'b010_0100;
		4'd3:seg_data <= 7'b011_0000;
		4'd4:seg_data <= 7'b001_1001;
		4'd5:seg_data <= 7'b001_0010;
		4'd6:seg_data <= 7'b000_0010;
		4'd7:seg_data <= 7'b111_1000;
		4'd8:seg_data <= 7'b000_0000;
		4'd9:seg_data <= 7'b001_0000;
		4'ha:seg_data <= 7'b000_1000;
		4'hb:seg_data <= 7'b000_0011;
		4'hc:seg_data <= 7'b100_0110;
		4'hd:seg_data <= 7'b010_0001;
		4'he:seg_data <= 7'b000_0110;
		4'hf:seg_data <= 7'b000_1110;
		default:seg_data <= 7'b111_1111;
	endcase
end
endmodule


module count_m10(
                 input          clk,
                 input          rst_n,
                 input          en,    //Counter enable
                 input          clr,   //Counter synchronous reset 
					
					  input [1:0]        key,
                 output reg[3:0]data,  //counter value
                 output reg     t      // carry enable signal
                );
/				 
按键防抖
reg [0:0]        flag;
reg [0:0]        flag2;
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 [1:0] key_in_r;
reg [1:0] key_in_r_next;
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		key_in_r_next <= 2'b11;
	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 <= 2'b11;
	else
		key_in_r <= key_in_r_next;
end
wire [1:0] key_out;
assign key_out = key_in_r & (~key_in_r_next);

always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)		
		begin flag  <= 1'd0; 
		// flag2 <= 1'd0; 
		 end
   else if (key_out[0]==1)
	     flag <= ~flag;	  //按键1标志位
 //	 else if(key_out[1]==1)  
 //      flag2 <= ~flag2;	      //增加按键2标志位
    
end					          
///count_10m///
always@(posedge clk or negedge rst_n) 
begin
    if(rst_n==0)
      begin
        data <= 4'd0;
        t <= 1'd0; flag2 <= 1'd0;
       end
    else if(clr)
     begin
        data <= 4'd0;
        t <= 1'd0;      
      end
	 else if(key_out[1]==1)  
             flag2 <= ~flag2; 
    else if(en)               //1秒钟使能一次,计数en_1hz满 
     begin
        if(data==4'd9)
          begin
            t<= 1'b1;    //进位使能,data满9,前一位使能可以执行一次操作:data+1
            data <= 4'd0;
          end
		  
********改动部分**********///	  
      
		  else 
		     begin 
			    
			  if ((flag == 0)&&(flag2 == 0))       //按键1和2,有一个按下就停止计数                    
               data <= data + 4'd1;
		      else 
				 begin
				    if (flag2 == 1)      //按键2标志位
		           begin  
					  t<= 1'b1; 
					  flag2 <= ~flag2; 
					  end
               else
				     t <= 1'b0; 
			     end  
			  end   
				   
     end
             
	
	else
        t <= 1'b0;
end

endmodule

//不要白嫖,点个赞吧*-*

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值