基于Verilog使用Quartus设计数字秒表和数字时钟

目录

  • 一、数字秒表
    • 1.1 新建工程
    • 1.2 添加 Verilog 文件
    • 1.3 添加 VWF 文件
    • 1.4 波形仿真
  • 二、多功能数字钟
  • 三、总结

本文内容:使用 Quartus 基于 Verilog 语言进行数字秒表和多功能数字时钟的设计。

一、数字秒表

实验目的:

  • 复习 EDA 的设计方法及原理;
  • 学习 Verilog HDL 的设计方法,会使用 Verilog HDL 进行较复杂数字系统的设计。

实验内容:

  • 用 Verilog HDL 设计一个数字跑表,所需引脚和功能如下所示:
    基于Verilog使用Quartus设计数字秒表和数字时钟_第1张图片
    基于Verilog使用Quartus设计数字秒表和数字时钟_第2张图片
控制信号 取值 功能
复位信号 reset 0 计数
1 异步复位
启动/暂停 pause 0 计数
1 暂停

实验步骤如下:

1.1 新建工程

  • 点击【File】→【New Project Wizard…】。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第3张图片
  • 点击【Next >】进入下图的界面。
  • 选择工程保存路径及工程名,然后点击【Next >】。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第4张图片
  • 点击【Next >】进入下图的界面。
  • 【Family】选择 Cyclone IV E,芯片选择 EP4CE115F29C7,然后点击【Next >】。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第5张图片
  • 然后点击【Finish】即可。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第6张图片

1.2 添加 Verilog 文件

  • 点击【File】→【New…】。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第7张图片
  • 选择【Verilog HDL File】,再点击【OK】。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第8张图片
  • 复制粘贴如下代码:
module running_gly(
	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

  • 保存文件。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第9张图片
  • 重命名为 running_gly.v 再点击【保存(s)】。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第10张图片
  • 点击【Project】→【Set as Top-Level Entity】,将刚刚的 running_gly.v 文件置顶。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第11张图片
  • 编译程序。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第12张图片
  • 查看电路图:【Tools】→【Netlist Viewers】→【RTL Viewer】。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第13张图片
    基于Verilog使用Quartus设计数字秒表和数字时钟_第14张图片

1.3 添加 VWF 文件

  • 点击【File】→【New】,选择【University Program VWF】。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第15张图片
  • 点击【Edit】→【Insert】→【Insert Node or Bus…】。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第16张图片
  • 按下图所示步骤进行。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第17张图片
  • 设置时钟输入。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第18张图片
  • 保存文件:【File】→【Save】。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第19张图片
  • 点击【保存】。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第20张图片

1.4 波形仿真

  • 点击仿真按钮,出现如下错误。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第21张图片
  • 没有连接 Modelsim SE 连接,参考博客:Quartus-II 13.1 详细安装、注册、配置步骤
  • 再次仿真,出现如下步骤。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第22张图片

解决方法:

  • 点击【Tools】→【Lauch Simulation Library Compiler】。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第23张图片
  • 选择工程目录下的 ...\simulation\qsim 文件夹,然后点击【Start Compilation】。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第24张图片
  • 无错误后,点击【OK】→【close】。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第25张图片
  • 再次回到波形仿真界面,点击仿真按钮进行仿真。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第26张图片
  • 将显示的二进制转化为十进制:右击 msl,点击【Radix】→【Hexadecimal】即可。
    基于Verilog使用Quartus设计数字秒表和数字时钟_第27张图片

二、多功能数字钟

实验目的:

  • 复习 EDA 的设计方法及原理;
  • 学习使用 Verilog HDL 进行复杂数字系统的分模块设计方法。

实验内容:

  • 多功能数字钟的设计要求如下:
    (1)能够正常实现时间信息,包括小时、分钟、秒;
    (2)能够设置与调整时间;
    基于Verilog使用Quartus设计数字秒表和数字时钟_第28张图片
  • 各按键说明如下:
按键 功能 说明
按键 1 功能1 时间正常显示功能模式(数码管显示可以暂时放在下一个实验中实现)
功能 2 时间设置功能模式
按键 2 / 主要实现时间设置,在功能 2 模式时,用作时、分、秒的移位,按一下,就会实现“时-分-秒”的依次移位,便于在特定位置进行设置
按键 3 / 主要用于时间设置中的调整按键,在功能 2 模式时,用作时、分、秒的数字调整,按一下,将会使当前按键 2 选择的位置的数字加 1
  • 系统的设计方案如图:
    基于Verilog使用Quartus设计数字秒表和数字时钟_第29张图片

实验步骤:

  • 实验步骤如第一部分一样,只不过这里需要添加三个 Verilog 文件,分别如下:
    基于Verilog使用Quartus设计数字秒表和数字时钟_第30张图片
  • fenpin.v
//分频模块
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
	
  • clock.v
//时钟模块
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
				
  • runningclock.v
//秒表模块
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.v 置顶,否则仿真时报如下的错:
.# ** Error: (vsim-3170) Could not find
E:/code/Quartus/d_clock/simulation/qsim/work.fenpin_vlg_vec_tst'.
# Error loading design
Error loading design

  • 仿真的时候,可以改变 change、mode、turn 三个输入端口的电平,如下图所示:
    基于Verilog使用Quartus设计数字秒表和数字时钟_第31张图片
  • 仿真结果如下:
    基于Verilog使用Quartus设计数字秒表和数字时钟_第32张图片

三、总结

  • 由于笔者也是初学者,对于 Verilog 语言不是特别熟悉,所以代码没有那么多的注释,作此文章,留待慢慢研究学习。
  • 大致上来讲,有点像 C 语言,没那么难理解。

你可能感兴趣的:(verilog)