基于Verilog HDL的数字秒表&多功能数字钟
目录
一、数字秒表设计
工具:quartus
实验目的
- 复习EDA的设计方法及原理;
- 学习Verilog HDL的设计方法,会使用Verilog HDL进行较复杂数字系统的设计。
实验内容
用Verilog HDL设计一个数字跑表,所需引脚和功能如下所示
控制信号 | 取值 | 功能 |
---|---|---|
复位信号(Reset) | 0 | 计数 |
1 | 异步复位 | |
启动/暂停(pause) | 0 | 计数 |
1 | 暂停 |
1、创建新工程
点击new→new projectwizard…
选择路径以及编辑工程名称,点击next;
选择所属芯片,如图示操作
工程信息如下
点击finish,出现界面如示
2、添加Verilog文件
按图示流程点击操作
粘贴如下代码到文件
module mb(
clk,
reset,
pause,
msh,
msl,
sh,
sl,
minh,
minl);
input clk, reset, pause;
output [3:0] msh, msl, sh, sl, minh, minl;
reg [3:0] msh, msl, sh, sl, minh, minl;
reg count1, count2;
always@(posedge clk or posedge reset) begin
if(reset) begin
{
msh, msl} <= 0;
count1 <= 0;
end
else if(!pause) begin
if(msl == 9) begin
msl <= 0;
if(msh == 9) begin
msh <= 0;
count1 <= 1;
end
else
msh <= msh + 1;
end
else begin
msl <= msl + 1;
count1 <= 0;
end;
end
end
always@(posedge count1 or posedge reset) begin
if(reset) begin
{
sh, sl} <= 0;
count2 <= 0;
end
else if(sl == 9) begin
sl <= 0;
if(sh == 5) begin
sh <= 0;
count2 <= 1;
end
else
sh <= sh + 1;
end
else begin
sl <= sl + 1;
count2 <= 0;
end
end
always@(posedge count2 or posedge reset) begin
if(reset) begin
minh <= 0;
minl <= 0;
end
else if(minl == 9) begin
minl <= 0;
if(minh == 5)
minh <=0 ;
else
minh <= minh + 1;
end
else
minl <= minl + 1;
end
endmodule
点击保存(加后缀.v)
设为顶层文件
编译程序
编译结果
查看电路图
3、添加vwf文件
如图
导入相关数据
按图示步骤进行导入操作
设置时钟输入
图示如下
保存文件(file→save)
弹出如示提示框,点击保存
4、仿真
点击按钮,开始仿真
出现如示界面
解决方案(看图流程)
①
②
③
再次仿真
二进制转化为十进制
二、多功能数字钟
1、实验介绍
实验目的
①复习EDA的设计方法及原理;
②学习使用Verilog HDL进行复杂数字系统的分模设计方法。
实验内容
一、
多功能数字钟的设计要求如下:
(1)能够正常实现时间信息,包括小时、分钟、秒;
(2)能够设置与调整时间;
二、各按键说明如下
按键 | 功能 |
---|---|
按键一 | ①时间正常显示功能模式;②时间设置功能模式 |
按键二 | 主要实现时间设置,与按键1配合使用;在功能②模式时,用作时分秒的移位 |
按键三 | 主要用于时间设置中的调整按键,在②模式时,用作时分秒的数字调整 |
系统的设计方案如下
2、设计详解
新建工程与添加Verilog文件步骤同上
分频模块
//分频模块
module fenpin(
clk50MHz,
rst,
clk1Hz);
input clk50MHz, rst;
output clk1Hz;
reg clk_div;
reg[24:0] cnt;
always@(posedge clk50MHz or posedge rst) begin
if(rst) begin
clk_div <= 1'b0;
cnt <= 25'd0;
end
else if(cnt == 25'd0) begin
clk_div <= ~clk_div;
cnt <= 25'd0;
end
else
cnt <= cnt + 25'h1;
end
assign clk1Hz = clk_div;
endmodule
时钟模块
//时钟模块
module clock(
clk1Hz,
rst,
mode,
turn,
change,
sec,
min,
hour);
input clk1Hz, rst;
input mode, turn, change;
output[5:0] hour, min, sec;
reg[5:0] hour, min, sec;
reg[1:0] sel_num;
reg flag, flag2;
always@(posedge clk1Hz or posedge rst) begin
if(rst) begin
sec <= 0;
min <= 0;
hour <= 0;
end
else if(mode == 0) begin
if(sec == 6'd59)
sec <= 0;
else
sec <= sec + 6'd1;
if(min == 6'd59 & sec == 6'd59)
min <= 0;
else if(sec == 6'd59)
min <= min + 1;
else
min <= min;
if(hour == 6'd23 & min == 6'd59)
hour <= 0;
else if(min == 6'd59 & sec == 6'd59)
hour <= hour + 6'd1;
else
hour <= hour;
end
else if(flag2 == 1'b1 & mode == 1'b1) begin
case(sel_num)
2'b00:
begin
if(sec == 6'd59)
sec <= 6'd0;
else
sec <= sec + 6'd1;
end
2'b01:
begin
if(min == 6'd59)
min <= 6'd0;
else
min <= min + 6'd1;
end
2'b10:
begin
if(hour == 6'd23)
hour <= 6'd0;
else
hour <= hour + 6'd1;
end
default:sec <= sec;
endcase
end
else
sec <= sec;
end
always@(posedge clk1Hz or posedge rst) begin
if(rst) begin
flag = 1'b0;
flag2 = 1'b0;
end
else if(change == 1'b1 & flag == 1'b0) begin
flag = 1'b1;
flag2 = 1'b1;
end
else if(change == 1'b1 & flag == 1'b1)
flag2 = 1'b0;
else if(change == 1'b0)
flag = 1'b0;
else
flag = 1'b0;
end
always@(posedge turn or posedge rst) begin
if(rst) begin
sel_num <= 2'b00;
end
else if(turn == 1'b1 & mode == 1'b1) begin
if(sel_num == 2'b10)
sel_num <= 2'b00;
else
sel_num <= sel_num + 2'b1;
end
else
sel_num <= sel_num;
end
endmodule
秒表模块
//秒表模块
module runningclock(
clk1Hz,
rst,
mode,
pause,
qingling,
second,
minute);
input clk1Hz, rst;
input mode, pause, qingling;
output[5:0] second, minute;
reg[5:0] second, minute;
reg[2:0] mode_num, pause_num;
reg mode_c, mode_n, pause_c, pause_n, qingling_c, qingling_n;
always@(posedge rst or posedge clk1Hz) begin
if(rst)
{
second, minute} <= 0;
else if(mode_num == 3 && pause_num == 1 && qingling_c == 0) begin
if(second == 59) begin
second <= 0;
minute <= minute + 1;
end
else
second <= second + 1;
end
else if(mode_num == 3 && pause_num == 0 && qingling_c == 0) begin
second <= second;
minute <= minute;
end
else if(mode_num == 3 && qingling_c == 1) begin
second <= 0;
minute <= 0;
end
else
second <= second;
end
always@(posedge clk1Hz or posedge rst) begin
if(rst) begin
qingling_n <= 0;
qingling_c <= 0;
end
else begin
qingling_c <= qingling;
if(qingling)
qingling_c <= qingling_c ^ qingling;
else
qingling_c <= 0;
end
end
always@(posedge clk1Hz or posedge rst) begin
if(rst) begin
pause_n <= 0;
pause_c <= 0;
end
else begin
pause_n <= pause;
if(pause)
pause_c <= pause_n ^ pause;
else
pause_c <= 0;
end
end
always@(posedge rst or posedge pause_c) begin
if(rst)
pause_num <= 0;
else if(pause_num == 1)
pause_num <= 0;
else
pause_num <= pause_num + 1;
end
always@(posedge clk1Hz or posedge rst) begin
if(rst) begin
mode_n <= 0;
mode_c <= 0;
end
else begin
mode_n <= mode;
if(mode)
mode_c <= mode_n ^ mode;
else
mode_c <= 0;
end
end
always@(posedge rst or posedge mode_c) begin
if(rst)
mode_num <= 0;
else if(mode_num == 3)
mode_num <= 0;
else
mode_num <= mode_num + 1;
end
endmodule
建成文件如示
将clock文件置顶
改变输入电平(change、mode、turn)
仿真结果如下
三、总结
本篇文章是一个实验内容的基础练习,刚开始学习,很多东西还不会。在以后的学习中会加深理解与运用。