1.项目需求
通过小脚丫FPGA核心板上的2个数码管和轻触按键制作一个秒表,通过按键来控制秒表的功能,并在数码管上显示数值。
使用七段显示器作为输出设备,在小脚丫FPGA核心板上创建一个2位数秒表。 秒表应从 0.0 秒计数到 9.9秒,然后翻转,计数值每0.1秒精确更新一次。
秒表使用四个按钮输入:开始、停止、增量和清除(重置)。 开始输入使秒表开始以10Hz时钟速率递增(即每0.1秒计数一次); 停止输入使计数器停止递增,但使数码管显示当前计数器值; 每次按下按钮时,增量输入都会导致显示值增加一次,无论按住增量按钮多长时间; 复位/清除输入强制计数器值为零。
2.需求分析
2.1 开始,停止,与计数器功能
通过对clk信号上升沿触发的计时器,每次到600000就让clk1h变为自身的相反数,再让clk1h去触发计时器模块。保证秒表以0.1Hz时钟速率递增。定义变量start_flag,通过start_flag的数值判定秒表当前的工作状态,而开始与停止按钮负责改变start_flag的数值。由clk1h驱动的计数模块通过对star_flag的判定来决定秒表的工作状态。
2.2 增量功能
判断是否摁下add_one按钮,然后在编辑个位数,十位数的功能中改变数值。并且保证无论摁下add_one按键的时间多长,都只会改变一次数值。
2.3 复位功能
将数值置0。
3.实现的方式
3.1 开始,停止按钮
检测按钮是否被摁下,并改变start_flag的数值。
3.2 计时功能
若start_flag == 1,改变cnt_shi,cnt_ge,并执行进位加法。判断cnt_ge == 9时进位,若cnt_shi,cnt_ge均等于9时全部归0。
3.3 增量按钮
保证无论摁下增量按钮多长时间都只会判断为一次摁下,故设置add_one_signal,add_one_signal2,add_one_signal为立即执行一次增加数字,add_one_signal2为当前一直处于按钮摁下的情况。就可以通过add_one_signal2==1,add_one_signal == 0,来判断是否处于按钮摁下且已经增量过的情况,规避摁下增量按钮之后不会只增量一次的情形。
3.4 复位按钮
检测按钮是否被摁下,并改变cnt_ge,cnt_shi的数值,置0。
4.功能框图
5.代码
module watch (
clk, // Clock Signal
start, //start button
stop, //stop button
add_one, //incremental button
rst, // clear button
display_ones,
display_tens // digital tube display
);
input clk,rst,start,stop;
input wire add_one;
output [8:0] display_ones;
output [8:0] display_tens;
reg clk1h; //big time counter
reg [27:0]clk_end; //small time counter
reg [6:0] seg [9:0];
reg [3:0] cnt_ge = 0; //single-digit
reg [3:0] cnt_shi = 0; //decimal fraction
reg start_flag = 0; //if == 0 stop ==1 start
reg add_one_signal = 0; //add_one is pressed signal
reg add_one_signal2 = 0;
reg add_one_counter; //Prevents unwanted changes in value due to continuous button presses.made a counter to use
parameter CLOCK = 600000 - 1;
initial
begin
seg[0] = 7'h3f; // 0
seg[1] = 7'h06; // 1
seg[2] = 7'h5b; // 2
seg[3] = 7'h4f; // 3
seg[4] = 7'h66; // 4
seg[5] = 7'h6d; // 5
seg[6] = 7'h7d; // 6
seg[7] = 7'h07; // 7
seg[8] = 7'h7f; // 8
seg[9] = 7'h6f; // 9
start_flag = 0;
cnt_ge = 0;
cnt_shi = 0;
clk_end = 0;
clk1h = 0;
add_one_signal = 0;
add_one_signal2 = 0; //if == 1,add_one has been pressed for a long time
add_one_counter = 0;
end
always @ (posedge clk) begin //Counts every 0.1 seconds
if (clk_end == CLOCK)begin
clk1h <= ~clk1h;
clk_end <= 0;
end
else
clk_end <= clk_end + 1;
end
always @ (posedge clk1h or negedge rst or negedge start or negedge stop) begin
if (!start == 1) begin // star or stop,change start_flag
start_flag <= 1;
end
else if (!stop == 1) begin
start_flag <= 0;
end
else if (!rst == 1) begin //rst has been pressed , set counter 0
cnt_ge <= 0;
cnt_shi <= 0;
start_flag <= 0;
end
else if (cnt_shi[3:0] == 4'd9 & cnt_ge[3:0] == 4'd9 & start_flag ==1) begin //Timer is functioning properly,this is Realisation of timekeeping functions
cnt_ge <= 0;
cnt_shi <= 0;
end
else if (cnt_ge[3:0] == 4'd9 & start_flag == 1) begin //implementation of the rounding system
cnt_shi <= cnt_shi + 1;
cnt_ge <= 0;
end
else if (start_flag == 1) begin
cnt_ge <= cnt_ge + 1;
end
else if (cnt_shi[3:0] == 4'd9 & cnt_ge[3:0] == 4'd9 & start_flag ==0 & add_one == 0 & add_one_signal == 0) begin //Implementing Incremental Functions
cnt_ge <= 0;
cnt_shi <= 0;
add_one_signal <= 1;
end
else if (cnt_ge[3:0] == 4'd9 & start_flag == 0 & add_one == 0 & add_one_signal == 0) begin // use add_one_signal,Avoid repeated increases
cnt_shi <= cnt_shi + 1;
cnt_ge <= 0;
add_one_signal <= 1;
end
else if (start_flag == 0 & add_one == 0 & add_one_signal == 0) begin // if add_one_signal == 1,avoid repeated again
cnt_ge <= cnt_ge + 1;
add_one_signal <= 1;
end
else if (start_flag == 0 & add_one_signal == 1 & add_one == 1)begin // if add_one_signal == 1 and do not press add_one button,set signal 0
add_one_signal <= 0;
end
end
assign display_ones[8:0] = {2'b00,seg[cnt_ge]}; //digital tube display
assign display_tens[8:0] = {2'b01,seg[cnt_shi]};
endmodule
主要功能代码段解释与说明:
1:设置变量start_flag,摁下start按钮变为1,摁下stop按钮变成0,计数模块中必须在start==1的时候才会运行。
2:通过计数器实现clk1h,实现分频。
3:通过add_one按钮情况与add_one_signal实现增量功能,当add_one_signal == 0时,若按钮被摁下,进行一次数值增加,并将add_one_signal置1,当add_one_signal==1且按钮被摁下不会增加,当add_one_signal == 1时,按钮松开,则将add_one_signal置0.
6.仿真波形图
7.FPGA资源利用说明