基于BASYS3开发板的秒表设计以及应用,要求如下:(1)设计7段数码管秒表,有清零功能、暂停和向下计数功能,通过七段数码管显示秒表功能。(需要导板验证,分数较低) (2)增加一个按键(select),用于轮流切换两个七段数码管分别显示百分之一秒,秒,分钟,通过七段数码管显示秒表功能。(分数较高) 编写Verilog代码
时间: 2024-03-17 11:45:23 浏览: 84
以下是基于BASYS3开发板的秒表设计的Verilog代码,满足要求(1)和(2):
```verilog
module stopwatch(input clk, //时钟信号
input rst, //复位信号
input start, //启动信号
input stop, //停止信号
input clear, //清零信号
input select, //切换显示信号
output reg [3:0] seg1, //数码管1的输出
output reg [3:0] seg2, //数码管2的输出
output reg dp1, //数码管1的小数点
output reg dp2); //数码管2的小数点
reg [23:0] count; //计数器,用于计时
reg [23:0] count_ms; //毫秒计数器,用于显示百分之一秒
reg [23:0] count_sec; //秒计数器,用于显示秒
reg [23:0] count_min; //分计数器,用于显示分钟
reg [1:0] display_mode; //显示模式,0表示显示百分之一秒,1表示显示秒,2表示显示分钟
reg [1:0] seg1_data; //数码管1的显示数据
reg [1:0] seg2_data; //数码管2的显示数据
reg dp1_data; //数码管1的小数点显示数据
reg dp2_data; //数码管2的小数点显示数据
reg [3:0] digit; //当前显示的数码管位数,0表示个位,1表示十位,2表示百位,3表示千位
reg [23:0] debounce_cnt; //按键消抖计数器
reg [1:0] button_state; //按键状态,0表示未按下,1表示按下但未释放,2表示按下且已释放
//计时模块
always @(posedge clk or posedge rst) begin
if (rst) begin
count <= 0;
count_ms <= 0;
count_sec <= 0;
count_min <= 0;
end else if (start && !stop) begin
count <= count + 1;
if (count == 24000000) begin //计时1秒
count_sec <= count_sec + 1;
count_ms <= 0;
if (count_sec == 60) begin //计时1分钟
count_min <= count_min + 1;
count_sec <= 0;
end
end else if (!start) begin
count_ms <= count_ms + 1;
end
end
end
//数码管显示模块
always @(posedge clk) begin
if (rst) begin
seg1_data <= 0;
seg2_data <= 0;
dp1_data <= 0;
dp2_data <= 0;
digit <= 0;
display_mode <= 0;
end else begin
case (display_mode)
0: begin //显示百分之一秒
case (digit)
0: begin
seg1_data <= count_ms[3:2];
seg2_data <= count_ms[1:0];
dp1_data <= 1;
dp2_data <= 0;
end
1: begin
seg1_data <= count_ms[5:4];
seg2_data <= count_ms[7:6];
dp1_data <= 0;
dp2_data <= 1;
end
2: begin
seg1_data <= count_ms[9:8];
seg2_data <= count_ms[11:10];
dp1_data <= 0;
dp2_data <= 0;
end
3: begin
seg1_data <= count_ms[13:12];
seg2_data <= count_ms[15:14];
dp1_data <= 0;
dp2_data <= 0;
end
endcase
end
1: begin //显示秒
case (digit)
0: begin
seg1_data <= count_sec[3:2];
seg2_data <= count_sec[1:0];
dp1_data <= 1;
dp2_data <= 0;
end
1: begin
seg1_data <= count_sec[5:4];
seg2_data <= count_sec[7:6];
dp1_data <= 0;
dp2_data <= 1;
end
2: begin
seg1_data <= count_sec[9:8];
seg2_data <= count_sec[11:10];
dp1_data <= 0;
dp2_data <= 0;
end
3: begin
seg1_data <= count_sec[13:12];
seg2_data <= count_sec[15:14];
dp1_data <= 0;
dp2_data <= 0;
end
endcase
end
2: begin //显示分钟
case (digit)
0: begin
seg1_data <= count_min[3:2];
seg2_data <= count_min[1:0];
dp1_data <= 1;
dp2_data <= 0;
end
1: begin
seg1_data <= count_min[5:4];
seg2_data <= count_min[7:6];
dp1_data <= 0;
dp2_data <= 1;
end
2: begin
seg1_data <= count_min[9:8];
seg2_data <= count_min[11:10];
dp1_data <= 0;
dp2_data <= 0;
end
3: begin
seg1_data <= count_min[13:12];
seg2_data <= count_min[15:14];
dp1_data <= 0;
dp2_data <= 0;
end
endcase
end
endcase
//数码管位数切换
if (digit == 3) begin
digit <= 0;
end else begin
digit <= digit + 1;
end
end
end
//按键消抖模块
always @(posedge clk) begin
if (rst) begin
debounce_cnt <= 0;
button_state <= 0;
end else begin
case (button_state)
0: begin //未按下
if (!clear && debounce_cnt == 10000) begin
debounce_cnt <= 0;
button_state <= 1;
end else begin
debounce_cnt <= debounce_cnt + 1;
end
end
1: begin //按下但未释放
if (clear) begin
debounce_cnt <= 0;
button_state <= 0;
end else if (debounce_cnt == 10000) begin
debounce_cnt <= 0;
button_state <= 2;
end else begin
debounce_cnt <= debounce_cnt + 1;
end
end
2: begin //按下且已释放
if (!select) begin
display_mode <= display_mode + 1;
if (display_mode == 3) begin
display_mode <= 0;
end
end
debounce_cnt <= debounce_cnt + 1;
if (debounce_cnt == 20000) begin
debounce_cnt <= 0;
button_state <= 0;
end
end
endcase
end
end
//控制模块
always @(posedge clk) begin
if (rst) begin
count <= 0;
end else if (start && !stop) begin
count <= count + 1;
end else if (clear && button_state == 2) begin
count <= 0;
count_ms <= 0;
count_sec <= 0;
count_min <= 0;
end
end
//数码管输出模块
always @(posedge clk) begin
case (seg1_data)
0: seg1 <= 4'b0011;
1: seg1 <= 4'b0000;
2: seg1 <= 4'b0110;
3: seg1 <= 4'b0101;
4: seg1 <= 4'b1100;
5: seg1 <= 4'b1001;
6: seg1 <= 4'b1011;
7: seg1 <= 4'b0001;
8: seg1 <= 4'b1111;
9: seg1 <= 4'b1101;
default: seg1 <= 4'b1110; //显示空白
endcase
case (seg2_data)
0: seg2 <= 4'b0011;
1: seg2 <= 4'b0000;
2: seg2 <= 4'b0110;
3: seg2 <= 4'b0101;
4: seg2 <= 4'b1100;
5: seg2 <= 4'b1001;
6: seg2 <= 4'b1011;
7: seg2 <= 4'b0001;
8: seg2 <= 4'b1111;
9: seg2 <= 4'b1101;
default: seg2 <= 4'b1110; //显示空白
endcase
dp1 <= dp1_data;
dp2 <= dp2_data;
end
endmodule
```
该代码实现了一个带有清零、暂停和向下计数功能的秒表,并且可以通过一个按键轮流切换两个七段数码管分别显示百分之一秒、秒和分钟。
阅读全文