IT评测·应用市场-qidao123.com技术社区
标题:
蓝桥杯FPGA赛道模拟题1之步伐设计题代码
[打印本页]
作者:
来自云龙湖轮廓分明的月亮
时间:
2025-4-14 09:00
标题:
蓝桥杯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.引脚束缚
声明:本代码有参考网上的资料,如有侵权请联系作者删除,此外作者水平有限,如果错误请联系作责纠正
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/)
Powered by Discuz! X3.4