蓝桥杯FPGA赛道积分赛

发布于:2025-05-09 ⋅ 阅读:(22) ⋅ 点赞:(0)

一、第一期部分题目

代码如下: 

module led(
input wire clk,
input wire rst,
input wire  key1,
output wire  [7:0]led 
);


/*
always @(posedge clk or negedge rst)begin
	if(!rst)begin
	  led<=8'b1111_1111;
	end else begin
	if(key1==0)
	led<=8'b0101_0101;
	end 
end 
*/


assign led=(key1==0)?8'b0101_0101:8'b1111_1111;
endmodule

 

 

//状态机实现
module seg(
input wire clk,
input wire rst,
input wire [3:0]key,
output reg led1,
output  wire  [7:0]seg,
output  wire   [7:0]scl
);
 wire [3:0] key_value;
 reg  [31:0] dsp_data;
 //状态定义
 localparam IDLE=2'b00;
 localparam ON=2'b01;
 localparam OFF=2'b10;
 //状态切换的条件
 wire IDLE_ON;
 wire  ON_OFF;
 wire  OFF_ON;
 
 reg [1:0]cstatus;
 reg [1:0]nstatus;

 key key_inst(
 .sys_clk(clk),
 .sys_rst(rst),
 .key_in(key),
 .key_data(key_value) 
);

segdisplay segdisplay_inst
(
		.clk(clk)							,
	 	.rst(rst)							,
		.seg_number_in(dsp_data)		,
		.seg_number(seg)					,
		.seg_choice(scl)					
); 
assign IDLE_ON=(cstatus==IDLE&&key_value==4'b0001);
assign ON_OFF=(cstatus==ON&&key_value==4'b0001);
assign OFF_ON=(cstatus==OFF&&key_value==4'b0001);
//初始状态
always @(posedge clk or negedge rst)begin
	if(!rst)
		cstatus<=IDLE;
	else
		cstatus<=nstatus;
end 
//状态切换
always @(*)begin
  case(cstatus)
  IDLE:begin if(IDLE_ON) nstatus<=ON ;else  nstatus<=cstatus ; end 
  ON:begin if(ON_OFF) nstatus<=OFF ;else  nstatus<=cstatus  ;end 
  OFF:begin if(OFF_ON) nstatus<=ON ;else  nstatus<=cstatus ; end 
  default:nstatus<=IDLE;
  endcase
end
always @(*)begin
 case(cstatus)
	IDLE:begin dsp_data<={4'd10,4'd10,4'd10,4'd10,4'd10,4'd10,4'd10,4'd10}; led1<=1;end 
	ON:begin dsp_data<={4'd10,4'd10,4'd10,4'd10,4'd10,4'd10,4'd10,4'd1}; led1<=0; end 
	OFF:begin dsp_data<={4'd10,4'd10,4'd10,4'd10,4'd10,4'd10,4'd10,4'd0}; led1<=1; end 
	default:dsp_data<={4'd10,4'd10,4'd10,4'd10,4'd10,4'd10,4'd10,4'd10};
 endcase
end 
endmodule

按键驱动

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//消抖10ms
			
				//无按键,初始状态
				if(key_status==IDLE)begin//无按键按下,初始状态
					if(key_in!=4'b1111)//有按键动作产生(无按键时,IO信号:1111,)
						key_status<=PRESS;//按键处于按下状态
						
				   end  else if(key_status==PRESS)begin//有按键动作产生,需要根据IO状态,并且判断哪一个按键按下,按键状态:下一个状态
							case(key_in)
								4'b1110: begin key_data <=KEY_VAL_S1; key_status <=RELEASE; end //S1按下
								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
							
					//按键是否弹起,无任何按键按下,IO->1111	
					end else begin 
							if(key_in == 4'b1111)
									key_status <=IDLE;
							end
							
						end
					end else
					     key_data <=KEY_VAL_NL;//清零键值(清零键值)
				end 
			end 
endmodule

 

 二、第二期的部分题目

代码如下

module led(
input clk, 
input rst,
input [3:0]key_in,
output reg [7:0] led
);
reg [7:0]count;
wire [3:0]key_value;

always @(posedge clk or negedge rst)begin
 if(!rst)begin
	count<=0;
 end else
    case(key_value)
	 4'b0001:begin 
		if(count<255)
		count<=count+1;
		else
		count<=0;
	 end 
	 4'b0010:begin
	 if(count>0)
		count<=count-1;
	 else
		count<=255;
	 end 
	 default:count<=count;
	 endcase
end 
//1->0000_0001取反->1111_1110
always @(posedge clk or negedge rst)begin
	if(!rst)begin
	led<=8'b1111_1111;
	end else
	 led<=~count;
end 
key key_inst(
     .sys_clk(clk),
     .sys_rst(rst),
     .key_in(key_in),
	  .key_data(key_value) 
);

endmodule

 按键驱动

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//消抖10ms
			
				//无按键,初始状态
				if(key_status==IDLE)begin//无按键按下,初始状态
					if(key_in!=4'b1111)//有按键动作产生(无按键时,IO信号:1111,)
						key_status<=PRESS;//按键处于按下状态
						
				   end  else if(key_status==PRESS)begin//有按键动作产生,需要根据IO状态,并且判断哪一个按键按下,按键状态:下一个状态
							case(key_in)
								4'b1110: begin key_data <=KEY_VAL_S1; key_status <=RELEASE; end //S1按下
								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
							
					//按键是否弹起,无任何按键按下,IO->1111	
					end else begin 
							if(key_in == 4'b1111)
									key_status <=IDLE;
							end
							
						end
					end else
					     key_data <=KEY_VAL_NL;//清零键值(清零键值)
				end 
			end 
endmodule

代码如下: 

 顶层文件

module led(
input clk, 
input rst,
input [3:0]key_in,
output reg [7:0] led,
output wire [7:0]seg,
output wire  [7:0]sel
);
//按键键值
wire [3:0]key_value;
//数码管显示的数据
reg [31:0]data;
//计数值最大值
parameter [25:0] MS_MAX=26'd50_000_000;
//1秒计数值
reg [25:0] timer;
//计数值
reg [8:0] count;

parameter [3:0]STARTCOUNT=1;
parameter [3:0]STOPCOUNT=2;
parameter [3:0]COUNT_0=3;
reg [3:0] status_count;

//1s计时
always @(posedge clk or negedge rst)begin
	 if(!rst)begin
		timer<=0;
	 end else begin
		if(status_count==STARTCOUNT)begin
			if(timer==MS_MAX-1)
				timer<=0;
			else
				timer<=timer+1;
		end else 
			timer<=timer;
	  end
end 
//计数值加1
always @(posedge clk or negedge rst)begin
	 if(!rst)begin
		count<=0;
	 end else begin
	 if(status_count==STARTCOUNT)begin 
		if(timer==MS_MAX-1)begin
			if(count<80)
				count<=count+1;
			else
				count<=0;	
		end else
			count<=count;
	  end else if(status_count==STOPCOUNT)begin
			count<=count;
	  end else
			count<=0;
	end
end
 
//

always @(posedge clk or negedge rst)begin
 if(!rst)begin
	status_count<=STOPCOUNT;
 end else
    case(key_value)
	 4'b0001:begin 
		status_count<=STARTCOUNT;
	 end 
	 4'b0010:begin
	   status_count<=STOPCOUNT;
	 end 
	 4'b0100:begin
	   status_count<=COUNT_0;
	 end 
	 default:status_count<=status_count;
	 endcase
end 
always @(posedge clk or negedge rst)begin
	if(!rst)begin
		led<=8'b1111_1111;	
	end begin
		case(count)
		0:led<=8'b1111_1111;
		10:led<=8'b1111_1110;
		20:led<=8'b1111_1100;
		30:led<=8'b1111_1000;
		40:led<=8'b1111_0000;
		50:led<=8'b1110_0000;
		60:led<=8'b1100_0000;
		70:led<=8'b1000_0000;
		80:led<=8'b0000_0000;
		default:led<=8'b1111_1111;
		endcase
	end 
end 

always @(posedge clk or negedge rst)begin
	if(!rst)begin
		data<={4'd10,4'd11,4'd11,4'd11,4'd11,4'd11,4'd0,4'd0};
	end else begin 
		data[7:4]<=count/10;
		data[3:0]<=count%10;
	end 
end

key key_inst(
     .sys_clk(clk),
     .sys_rst(rst),
     .key_in(key_in),
	  .key_data(key_value) 
);

seg seg_inst
(
.clk(clk)						,
.rst(rst)						,
.dsp_data(data)				,
.seg(seg)					   ,//段选端
.sel(sel)					//位选段
);

endmodule

 按键驱动

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//消抖10ms
			
				//无按键,初始状态
				if(key_status==IDLE)begin//无按键按下,初始状态
					if(key_in!=4'b1111)//有按键动作产生(无按键时,IO信号:1111,)
						key_status<=PRESS;//按键处于按下状态
						
				   end  else if(key_status==PRESS)begin//有按键动作产生,需要根据IO状态,并且判断哪一个按键按下,按键状态:下一个状态
							case(key_in)
								4'b1110: begin key_data <=KEY_VAL_S1; key_status <=RELEASE; end //S1按下
								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
							
					//按键是否弹起,无任何按键按下,IO->1111	
					end else begin 
							if(key_in == 4'b1111)
									key_status <=IDLE;
							end
							
						end
					end else
					     key_data <=KEY_VAL_NL;//清零键值(清零键值)
				end 
			end 
endmodule

数码管驱动

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 [7:0] DIGIT0 =8'b1100_0000 ;//16精制C0
localparam [7:0] DIGIT1 =8'b1111_1001 ;//F9
localparam [7:0] DIGIT2 =8'b1010_0100;//A4
localparam [7:0] DIGIT3 =8'b1011_0000;//B0
localparam [7:0] DIGIT4 =8'b1001_1001;//99
localparam [7:0] DIGIT5 =8'b1001_0010;//92
localparam [7:0] DIGIT6 =8'b1000_0010;//82
localparam [7:0] DIGIT7 =8'b1111_1000;//F8
localparam [7:0] DIGIT8 =8'b1000_0000;//80
localparam [7:0] DIGIT9 =8'b1001_0000 ;//90
localparam [7:0] DIGITX =8'b1011_1111 ;//
localparam [7:0] DIGOFF =8'b1111_1111 ;//FF
localparam [7:0] DIGITC =8'hC6 ;
localparam 		DSP_COUNT = 20'd50000; //

reg 	[19:0] 	dsp_count		;
reg 	[3:0]	   bits				;
reg 	[3:0]		bcd				;


//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//每一毫秒更新一次
		 if(bits==4'd8)
		    bits <=4'd0;
		 else
			 bits<=bits+4'd1;
		 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'd10:seg<=DIGITC;
			
			//4'ha: seg<=DIGOFF;
			//4'hb: seg<=DIGITX;
		default: seg<=DIGOFF;
	endcase
  end 
end 
endmodule		

        声明:本代码借鉴网络资料,如有侵权和错误请联系作者删除。

 三、蓝桥杯备赛总结

我是从寒假开始备赛的,由于我基础不行,备赛过程中也是混混呃呃的,备赛效率不高,总体来说备赛不认真,有点拖拉,但是最后我也坚持备赛到了今天,在备赛过程中,即复习了旧的东西,也学到了新的东西,总结起来还是有点收获的,后天北京、天津、河北地区就要进行省赛了,我会全力以赴,不管结果怎么样,尽力就好,最后祝大家都能取到好成绩,也感谢大家对我写的博客文章的支持,接下来我会努力创造出更好的博客文章,大家一起共同进步。


网站公告

今日签到

点亮在社区的每一天
去签到