蓝桥杯FPGA赛道模拟题1之程序设计题代码

1.顶层文件

module test(
input  wire sys_clk,
input  wire sys_rst,
input  wire [3:0]key_in,
output wire [7:0]sel,
output wire [7:0]seg,
output reg  [7:0]led

);
//定义状态
localparam STOP=3'd0;
localparam START=3'd1;
localparam PAUSE=3'd2;
//signals define
wire [4:0]  d_count;
wire [3:0]   key_data;
reg  [31:0] data;
reg    en_count;
reg    rst_count;
reg  [2:0] st_count;
reg  [7:0] u_count1;
reg   [7:0] u_count2;
reg   [23:0]led_count;

cdown cdown_inst(
.sys_clk  (sys_clk  ),
.sys_rst  (sys_rst  ),
.count_en  (en_count),
.count_rst  (rst_count),
.count     (d_count)
);

seg seg_inst(
	.clk      (sys_clk),
	.rst      (sys_rst),
	.seg      (seg),
	.sel      (sel),
	.dsp_data (data)
	);
key key_inst(
	.sys_clk (sys_clk),
	.sys_rst (sys_rst),
	.key_in  (key_in),
	.key_data (key_data)
);
//LED 
always @(posedge sys_clk or negedge sys_rst)begin
	if(sys_rst==1'b0)begin
		led<=8'b1111_1111;
		led_count<=0;
	end else begin
		if(st_count==STOP)//停止状态
		  led<=8'b1111_1111;
		else if(st_count==START)//开始状态灯亮
		  led<=8'b1111_1110;  
		else begin
		   if(led_count==24'd5_000_000)begin 
			led_count<=0;
			led<=led ^ 8'b0000_0001;//led灯每隔0.01秒闪烁
	    end else
			led_count<=led_count+1;
		end
	end
end 

//seg
always @(posedge sys_clk or negedge sys_rst)begin
	if(sys_rst==1'b0)
	data <={4'd2,4'd0,4'd10,4'd0,4'd0,4'd11,4'd0,4'd0};
	else begin
		data[31:28]<=d_count/10;
		data[27:24]<=d_count%10;
		data[19:16]<=u_count1/10;
		data[15:12]<=u_count1%10;
		data[7:4]<=u_count2/10;
		data[3:0]<=u_count2%10;
	end 
end 
//KEY
always @(posedge sys_clk or negedge sys_rst)begin
     if(sys_rst==1'b0)begin
	  u_count1<=8'b0;
	  u_count2<=8'b0;
	  en_count<=1'b0;
	  st_count<=STOP;
	end else begin
		case(key_data)//状态更新
		4'b0001:     begin
								if(st_count==START)//如果当前按键状态处于开始,则按下按键1计数器1加1
									u_count1<=u_count1+8'd1;
						 end 
		4'b0010:     begin
								if(st_count==START)//如果当前状态处于处于开始,按下按键三计数器加1
									u_count2<=u_count2+8'd1;
						 end 
		4'b0100:     begin
								if(st_count==STOP)begin//如果处于停止状态,则下一个状态切换到开始状态
								en_count<=1'b1;
								st_count<=START;
								rst_count<=1'b1;
								end else if((st_count==START)&&(d_count!=4'd0))begin//如果当前状态处于开始状态,并且倒计时计数器不为0则切换到停止状态,并且倒计时计数器停止计数
							st_count<=PAUSE;
							en_count<=1'b0;
							end else if(st_count==PAUSE)begin//否则如果当前状态处于停止状态,则下一个状态切换到开始状态,继续使能倒计时计数器
							st_count<=START;
							en_count<=1'b1;
						end
					end 
		endcase
	if((st_count==START)&&(d_count==4'd0))begin//没有任何按键按下时,如果处于开始状态,并且倒计时计数器自动计数记到0,自动切换到停止状态
			st_count<=STOP;
			en_count<=1'b0;
			rst_count<=1'b0;
		end  
	end  
end 							 
endmodule

 2、计数模块

module cdown(
input wire sys_clk,
input wire sys_rst,
input wire count_en,
input wire count_rst,
output reg [4:0] count
);

localparam COUNT_MAX_1S=28'd50_000_000;
localparam COUNT_MAX_10=5'd20;

reg [27:0] count_reg;
//1s计数器
always @(posedge sys_clk or negedge sys_rst)begin
	if(sys_rst==1'b0)
		count_reg<=0;
	else begin
		if(count_en==1'b1)begin
			if(count_reg==COUNT_MAX_1S-1)
				count_reg<=0;
			else
				count_reg<=count_reg+1;
		end
	end 
end 

//倒计时器
always @(posedge sys_clk or negedge sys_rst)begin
	if(sys_rst==1'b0)begin
		count<=5'd20;
	end else begin
		if(count_en==1'b1)begin
		 if((count_reg==COUNT_MAX_1S-1)&&(count!=0))begin
				count<=count-1;
		 end
	 end else if(count_rst==1'b0)
			count<=5'd20;
	end
end 
endmodule

3.按键模块

module key(
    input   wire                sys_clk,
    input   wire                sys_rst,
    input   wire    [3:0]       key_in,
	 output reg      [3:0]		  key_data 
);

//按键键值定义
localparam  KEY_VAL_S1 =4'b0001;
localparam  KEY_VAL_S2 =4'b0010;
localparam  KEY_VAL_S3 =4'b0100;
localparam  KEY_VAL_S4=4'b1000;
localparam  KEY_VAL_NL=4'b1111;

localparam  KEY_COUNT_MAX =20'd500000;
//按键状态定义
localparam  IDLE      =3'd0;
localparam  PRESS     =3'd1;
localparam  RELEASE   =3'd2;

//按键扫描计数器,每隔0.01秒扫描一次按键
reg [19:0]   key_count;
//寄存器的定义用来存储不同的状态
reg [3:0]    key_status;

//按键计数更新
always@(posedge sys_clk or negedge sys_rst) begin
    if(sys_rst==1'b0)
        key_count <=0;
        else begin
             if(key_count == KEY_COUNT_MAX-1)begin
                key_count <= 0;
            end else
                key_count = key_count + 1;    
        end
    end

//按键状态更新
always@(posedge sys_clk or negedge sys_rst)begin
    if(sys_rst==1'b0)begin//复位
        key_data <= KEY_VAL_NL;
		  key_status<=IDLE;
	 end else begin
    if(key_data == KEY_VAL_NL) begin
			if(key_count==KEY_COUNT_MAX-1)begin
				if(key_status==IDLE)begin//当前没有按键时,并且按键扫描时间到,进行判断
				if(key_in!=4'b1111)//当按键键不等于1111
						key_status<=PRESS;//按键处于按下状态
				   end  else if(key_status==PRESS)begin//在有按键按下,赋予键值
							case(key_in)
								4'b1110: begin key_data <=KEY_VAL_S1; key_status <=RELEASE; end 
								4'b1101: begin key_data <=KEY_VAL_S2; key_status <=RELEASE; end
								4'b1011: begin key_data <=KEY_VAL_S3; key_status <=RELEASE; end
								4'b0111: begin key_data <=KEY_VAL_S4; key_status <=RELEASE; end 
								default: begin key_data <=KEY_VAL_NL; key_status <=IDLE;    end 
							endcase
					end else begin 
							if(key_in == 4'b1111)
									key_status <=IDLE;
							end
						end
					end else
					     key_data <=KEY_VAL_NL;
				end 
			end 
endmodule

4.数码管

module seg
(
	input	   wire 		      clk						,
	input 	wire 			   rst						,
	input 	wire	[31:0] 	dsp_data				,
	output 	reg 	[7:0] 	seg					,//段选端
	output 	reg 	[7:0] 	sel					//位选段
);
	
/*
localparam 	SEG_0 = 8'b1100_0000, SEG_1 = 8'b1111_1001,
				SEG_2 = 8'b1010_0100, SEG_3 = 8'b1011_0000,
				SEG_4 = 8'b1001_1001, SEG_5 = 8'b1001_0010,
				SEG_6 = 8'b1000_0010, SEG_7 = 8'b1111_1000,
				SEG_8 = 8'b1000_0000, SEG_9 = 8'b1001_0000,
				SEG_A = 8'b1000_1000, SEG_B = 8'b1000_0011,
				SEG_C = 8'b1100_0110, SEG_D = 8'b1010_0001,
				SEG_E = 8'b1000_0110, SEG_F = 8'b1000_1110,
				SEG_X = 8'b1011_1111;	//-
*/
localparam [7:0] DIGIT0 =8'b1100_0000 ;
localparam [7:0] DIGIT1 =8'b1111_1001 ;
localparam [7:0] DIGIT2 =8'b1010_0100;
localparam [7:0] DIGIT3 =8'b1011_0000;
localparam [7:0] DIGIT4 =8'b1001_1001;
localparam [7:0] DIGIT5 =8'b1001_0010;
localparam [7:0] DIGIT6 =8'b1000_0010;
localparam [7:0] DIGIT7 =8'b1111_1000;
localparam [7:0] DIGIT8 =8'b1000_0000;
localparam [7:0] DIGIT9 =8'b1001_0000 ;
localparam [7:0] DIGITX =8'b1011_1111 ;
localparam [7:0] DIGOFF =8'b1111_1111 ;
localparam 		DSP_COUNT = 20'd50000; //
//reg define
/*
localparam 	SEG_C7 = 8'b0000_0001,
				SEG_C6 = 8'b0000_0010,
				SEG_C5 = 8'b0000_0100,
				SEG_C4 = 8'b0000_1000,
				SEG_C3 = 8'b0001_0000,
				SEG_C2 = 8'b0010_0000,
				SEG_C1 = 8'b0100_0000,
				SEG_C0 = 8'b1000_0000;
*/
/* */
reg 	[19:0] 	dsp_count				;
reg 	[3:0]	   bits					;
reg 	[3:0]		bcd				;
reg 	[31:0]	dsp_reg						;
reg 	[7:0] 	dsp_code				;

//1ms的计数器		
always @(posedge clk or negedge rst)begin 	
	if(!rst)
		dsp_count <= 20'd0;
	else begin 
		if (dsp_count == DSP_COUNT-1) begin 
			dsp_count <= 20'd0;
		end else 
			dsp_count <= dsp_count + 20'd1;
		end	
end 		
//		
always @(posedge clk or negedge rst) begin 
	 if(!rst)begin
	   sel <= 8'b1111_1111;
		bits <=4'd0;
	 end else begin 
	    if(dsp_count==DSP_COUNT-1)begin//每一毫秒更新一次
		    bits<=bits+4'd1;
		 if(bits==4'd8)
		    bits <=4'd0;
		 case(bits)
				 4'd0: begin sel<=8'b1111_1110;bcd<=dsp_data[31:28] ;end
				 4'd1: begin sel<=8'b1111_1101;bcd<=dsp_data[27:24] ;end
				 4'd2: begin sel<=8'b1111_1011;bcd<=dsp_data[23:20] ;end
				 4'd3: begin sel<=8'b1111_0111;bcd<=dsp_data[19:16] ;end
				 4'd4: begin sel<=8'b1110_1111;bcd<=dsp_data[15:12] ;end
				 4'd5: begin sel<=8'b1101_1111;bcd<=dsp_data[11:8] ;end
				 4'd6: begin sel<=8'b1011_1111;bcd<=dsp_data[7:4] ;end
				 4'd7: begin sel<=8'b0111_1111;bcd<=dsp_data[3:0] ;end
		 default:sel<=8'b1111_1111;
	    endcase
	 end 
  end
end 
always @(posedge clk or negedge rst)begin
	if(!rst)
		seg<=DIGOFF;
  else begin 
		case(bcd)
			4'd0: seg<=DIGIT0;
			4'd1: seg<=DIGIT1;
			4'd2: seg<=DIGIT2;
			4'd3: seg<=DIGIT3;
			4'd4: seg<=DIGIT4;
			4'd5: seg<=DIGIT5;
			4'd6: seg<=DIGIT6;
			4'd7: seg<=DIGIT7;
			4'd8: seg<=DIGIT8;
			4'd9: seg<=DIGIT9;
			4'ha: seg<=DIGOFF;
			4'hb: seg<=DIGITX;
		default: seg<=DIGOFF;
	endcase
  end 
end 
endmodule		

5.引脚约束

 声明:本代码有参考网上的资料,如有侵权请联系作者删除,此外作者水平有限,如果错误请联系作责纠正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值