实验3 基于FPGA的常用数字系统设计 (使用Quartus编写Verilog程序)

发一发学习EDA实验课上的一些实验。

-------应读者要求加一下Pin脚绑定,注意仅适用这个设备

 

 

1.编写Verilog程序,实现8位数码动态扫描显示电路。在此基础上,用8位数码管实现电子表功能。

module scan(clk,seg8,bt);//顶层模块名,最好要和项目名同个
	input clk;
	output [7:0]seg8;
	output [7:0]bt;
	reg[7:0]seg8;
	reg[7:0]bt;
	reg[2:0]cnt8;
	reg[3:0]a;
	always@(cnt8)//时序逻辑用非阻塞语句赋值
		begin
			case(cnt8)//bt代表着数码管,通过cnt的计数实现不断对每位对于数码管进行动态扫描
                        //高频率(4096Hz)下,人眼看不出频闪。
				3'b000:begin bt<=8'b00000001;a<=1;end
				3'b001:begin bt<=8'b00000010;a<=3;end
				3'b010:begin bt<=8'b00000100;a<=5;end
				3'b011:begin bt<=8'b00001000;a<=7;end
				3'b100:begin bt<=8'b00010000;a<=9;end
				3'b101:begin bt<=8'b00100000;a<=10;end
				3'b110:begin bt<=8'b01000000;a<=11;end
				3'b111:begin bt<=8'b10000000;a<=12;end
				default begin bt<=8'b00000000;end
				endcase
		end
	always@(posedge clk) cnt8<=cnt8+1'b1;cnt从0加到8后溢出会自动归零重新计算,所以不需要归零语句
	always@(a)
	begin
		case(a)//每扫描一次bt的时候,实时更新对应位的数码管的值a,并输出
			0:seg8<=8'b00111111;
			1:seg8<=8'b00000110;
			2:seg8<=8'b01011011;
			3:seg8<=8'b01001111;
			4:seg8<=8'b01100110;
			5:seg8<=8'b01101101;
			6:seg8<=8'b01111101;
			7:seg8<=8'b00000111;
			8:seg8<=8'b01111111;
			9:seg8<=8'b01101111;
			10:seg8<=8'b01110111;
			11:seg8<=8'b01111110;
			12:seg8<=8'b00111001;
			13:seg8<=8'b01011110;
			14:seg8<=8'b01111001;
			15:seg8<=8'b01110001;
			default :seg8<=8'b00111111;
			endcase
			
	end
endmodule

2.

  1. 修改程序,继续使用实验箱左下角主板上“标准时钟信号源”模块的4096Hz时钟源,实现全部数码管显示相同的数字(从“1”至“8”循环显示),每组数字显示的时间为1秒。(提交代码及实验现象照片或截图)

module scan(rst,clk,seg8,bt);
	input clk;
	input rst;
	output [7:0]seg8;
	output [7:0]bt;
	reg[7:0]seg8;
	reg[7:0]bt;
	reg[2:0]cnt8;
	reg[2:0]a;
	wire clk2;

	cnt10 t1(rst,clk,clk2);//例化模块,将4096hz大小的频率clk分频成1hz大小clk2,即1s,
	
		always@(posedge clk2 or negedge rst)begin//每隔一秒改变a的值
			if(!rst)a<=0;
			else a<=a+1;
		end
		//值得注意的是,同一个变量并不能在不同的always和assign里赋值,
//也就是说,它只能在一个always或者assign里赋值
		always@(cnt8)
		begin
			case(cnt8)//依然像第一个实验一样在clk下直接不断扫描,但是不再赋值a值
				3'b000:begin bt<=8'b00000001;end
				3'b001:begin bt<=8'b00000010;end
				3'b010:begin bt<=8'b00000100;end
				3'b011:begin bt<=8'b00001000;end
				3'b100:begin bt<=8'b00010000;end
				3'b101:begin bt<=8'b00100000;end
				3'b110:begin bt<=8'b01000000;end
				3'b111:begin bt<=8'b10000000;end
				default begin bt<=8'b00000000;end
				endcase
		end
	always@(posedge clk) cnt8<=cnt8+1'b1;//cnt8,每次clk上升,cnt计数一次。

	always@(a)
	begin
		case(a)
			0:seg8<=8'b00111111;
			1:seg8<=8'b00000110;
			2:seg8<=8'b01011011;
			3:seg8<=8'b01001111;
			4:seg8<=8'b01100110;
			5:seg8<=8'b01101101;
			6:seg8<=8'b01111101;
			7:seg8<=8'b00000111;
			8:seg8<=8'b01111111;
			default :seg8<=8'b00111111;
			endcase
			
	end
endmodule


module cnt10(rst,clk,clk2);//分频用的模块,是占空比位为50%的时钟分频形式,只适合偶数分频。

parameter all=2048;//原频率4096,那么为了达到占空比50%,就计数到一半的时候就翻转一次
input rst;
input clk;

output clk2;
reg[11:0] sum;//4096是2的12次方,所以位宽为12;
reg clk2;

	always @(posedge clk or negedge rst)
	begin
			
		if(!rst)
			begin
			sum<=0;clk2<=0;
			end
		else if(sum==all-1)begin sum<=0;clk2<=~clk2;end
//all-1的原因是因为all是从零开始的。计数到2047就满2048次了。
//只会在sum==2048的时候翻转,4098的时候不翻转。
//如果sum=4098的时候还翻转,那么时钟速度就是2hz即0.5s了!
		else begin
			sum<=sum+1'b1;
		end
	end

endmodule

话了一个很丑的图来看看为什么4096的时候不反转。从图里很明显看得出2048翻转的话,两次翻转加起来刚好是4096次。

 3.使用实验箱左下角主板上“标准时钟信号源”模块的4096Hz时钟和8位数码管实现电子钟的功能,即左数第1和2位数码管显示小时值,第4和5位显示分钟值,第7和8位显示秒值,第3和6位显示“-”作为分隔线.

module scan(rst,clk,seg8,bt);


	input clk;
	input rst;
	
	output [7:0]seg8;
	output [7:0]bt;

	reg[7:0]seg8;
	reg[7:0]bt;
	reg[5:0]timer[2:0];//6位的3字节寄存器数组,保存时分秒,xx:xx:xx,
	reg[2:0]cnt8;
	
	reg[3:0]a;
	reg[2:0]i;

	wire clk2;
	
	cnt10 t1(.rst(rst),.clk(clk),.clk2(clk2));//分频模块,分频到1Hz,输出clk2
	
	always@(posedge clk) cnt8<=cnt8+1'b1;//cnt8,每次clk上升,cnt计数一次。
	
	always@(posedge clk2 or negedge rst)//计算时分秒
	begin
		if(!rst)
		begin 
		for(i=0;i<3;i=i+1)begin timer[i]<=0;end 
		end
		else if(timer[0]==59)begin timer[0]<=0;timer[1]=timer[1]+1;end
		else if(timer[1]==59)begin timer[1]<=0;timer[2]=timer[2]+1; if(timer[2]==24)begin for(i=0;i<3;i=i+1)begin timer[i]<=0;end 
//分钟到时钟这一段和分钟本身的变换肯定存在问题,会导致时和分的变换之间的误差明显,但我不想改。
				end
			end
		else if(timer[2]==24)begin for(i=0;i<3;i=i+1)begin timer[i]<=0;end 
		end
		else timer[0]=timer[0]+1;

		

	end
		always@(posedge cnt8 or negedge rst)
		begin
			if(!rst)begin  bt<=8'b00000000;a<=0; end
			case(cnt8)//从上到下是时分秒,具体要看引脚绑定吧,看看那边是正方向,
				3'b000:begin bt<=8'b00000001;a<=timer[2]/10;end
				3'b001:begin bt<=8'b00000010;a<=timer[2]%10;end
				3'b010:begin bt<=8'b00000100;a<=10;end
				3'b011:begin bt<=8'b00001000;a<=timer[1]/10;end
				3'b100:begin bt<=8'b00010000;a<=timer[1]%10;end
				3'b101:begin bt<=8'b00100000;a<=10;end
				3'b110:begin bt<=8'b01000000;a<=timer[0]/10;end
				3'b111:begin bt<=8'b10000000;a<=timer[0]%10;end
				default begin bt<=8'b00000000;end
				endcase
		end
	
	always@(a)
	begin
		case(a)
			0:seg8<=8'b00111111;
			1:seg8<=8'b00000110;
			2:seg8<=8'b01011011;
			3:seg8<=8'b01001111;
			4:seg8<=8'b01100110;
			5:seg8<=8'b01101101;
			6:seg8<=8'b01111101;
			7:seg8<=8'b00000111;
			8:seg8<=8'b01111111;
			9:seg8<=8'b01101111;
			default :seg8<=8'b01000000;
			endcase
			
	end

		
endmodule


module cnt10(rst,clk,clk2);
parameter all=2048;
input rst;
input clk;

output clk2;
reg[11:0] sum;
reg clk2;

	always @(posedge clk or negedge rst)
	begin
			
		if(!rst)
			begin
			sum<=0;clk2<=0;
			end
		else if(sum==all-1)begin sum<=0;clk2<=~clk2;end
		else begin
			sum<=sum+1'b1;
		end
	end

endmodule

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: Quartus是一款常用FPGA设计软件,可以用来编写Verilog程序Verilog是一种硬件描述语言,用于描述数字电路和系统的行为。在Quartus中,可以使用Verilog语言编写程序,然后将其合成为FPGA可执行的二进制文件。编写Verilog程序需要熟悉Verilog语言的语法和结构,以及数字电路的基本原理。在编写程序时,需要考虑时序、时钟、输入输出等因素,以确保程序的正确性和可靠性。 ### 回答2: Quartus是Intel公司推出的FPGA设计软件,可以用于编辑Verilog代码。编写Verilog程序的关键是理解Verilog语言的语法结构和语法规则,并熟练掌握Quartus软件的操作方法。 在Quartus中,首先需要创建一个新的设计项目,并在项目中添加Verilog文件。然后,可以在文件编辑器中输入Verilog代码。常用Verilog语法元素包括模块、端口、信号、赋值语句、条件语句、循环语句等,这些语法元素要按照规则书写,不可出现语法错误。 编写Verilog程序时,需要先确定设计的功能,再通过Verilog语言实现。例如,可以通过Verilog代码实现数码显示器,控制电机转动等功能。编写程序时,需要注意一些设计原则,如合理使用组合逻辑和时序逻辑、避免冲突和死锁、保证时序正确性等。 Verilog代码的编写完成后,需要进行仿真验证和实现。在Quartus中,可以通过仿真工具对Verilog代码进行验证,检查是否符合设计要求。如果验证通过,可以将设计实现到FPGA芯片中,用于实际应用。 总的来说,Quartus是一款集成开发环境,允许用户以图形方式设计与验证电路,这种方式既简单又快速,而Verilog又是一门较为通用的硬件描述语言,允许用户以一种完全数字的方式来描述电路设计,其扩展性极强,二者相结合,更是让硬件设计工作变得轻松简单。 ### 回答3: Quartus是一种集成电路设计软件,可以用于开发编写FPGAVerilog程序。以下是Quartus编写Verilog程序的一些步骤: 第一步:打开Quartus软件并创建一个新项目。从菜单栏中选择“File->New Project Wizard”,按照向导指示创建新项目并选择FPGA型号。 第二步:添加Verilog文件。在新项目中,右键单击文件夹并选择“Add/Remove Files”,将Verilog文件添加到项目中。 第三步:编写Verilog程序。用任何文本编辑器(例如notepad++)编写Verilog程序并将其保存到项目文件夹中。在Quartus软件中打开代码文件,确保代码无误。 第四步:进行综合。综合是将Verilog代码转换为适合FPGA使用的底层硬件电路的过程。在Quartus软件中点击“Processing->Start Compilation”,Quartus将对Verilog程序进行综合。 第五步:进行仿真。仿真是对FPGA电路进行测试的过程,以确保编写Verilog程序正常工作。在Quartus软件中点击“Tools->Run Simulation Tool->RTL Simulation”,选择仿真器并运行仿真。 第六步:生成比特流文件。比特流文件是将FPGA配置以便实现Verilog程序的文件。在Quartus软件中点击“File->Convert Programming Files”,选择所需的目标设备后将生成比特流文件。 Quartus编写Verilog程序需要一定的Verilog编程基础和对FPGA硬件电路的了解。通过以上简单的步骤,可以编写出可以使用Verilog程序并在FPGA上实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值