Verilog学习记录(二):秒计数器

本次学习的内容来自B站:Verilog零基础入门

目录

一、秒计数器

1.原理及代码设计

2.Modelsim仿真

二、七段数码管动态显示

1.原理及代码设计

2.Modelsim仿真

总结


一、秒计数器

1.原理及代码设计

秒计数器是计数器的一种,昨天学习了计数器的知识。我们知道计数器可以通过时钟的变化进行+1的操作,但是这个变化是由时钟周期决定的,在仿真中可以我们自定义,但是在实际开发板中,每一块开发板的晶振都是固定的,也就是时钟周期是固定的。如果在这种情况下我们想进行精准的秒计数,又应该怎么做呢?这时,我们就需要进行分频操作。以50MHz晶振源为例,在1秒钟内会产生50M个时钟周期,那么我们就可以每过50M个时钟周期对计数器进行加一。这样就可以实现任意时间段的计数器了,比如0.5s(每过25M个时钟周期对计数器进行加一),这样就构成了我们的秒计数器。(对于分频,由于本人只是初学者,也有许多地方不太明白,以上只是我的个人理解,如果有错请大佬们纠正)。

下面就让我们来实现代码的编写吧!

//2023.4.13 Bread
//秒计数器,0-9循环
`timescale 1ns/1ps


module s_counter(
				clk,
				rst,
				s_num
				);
input			clk;
input			rst;
output[3:0]		s_num;

parameter		frequency_clk=24;//24KHz



reg[15:0]			con_t;//秒脉冲分频计数器
reg					s_pulse;//秒脉冲尖;
reg[3:0]			s_num;


always@(posedge clk or negedge rst)
if(~rst)begin
	con_t<=0;s_pulse<=0;s_num<=0;
end
else begin
	if(con_t==frequency_clk*1000-1)begin
		con_t<=0;
	end
	else begin
		con_t<=con_t+1;
	end
	
	if(con_t==0)begin
		s_pulse<=1;
	end
	else begin
		s_pulse<=0;
	end
	
	if(s_pulse) begin
		if(s_num==9) begin
			s_num<=0;
		end
		else begin
		s_num<=s_num+1;
		end
	end
end
endmodule

本次示例假设时钟频率为24KHz(Hz太大仿真太麻烦,在实际开发板实验中需要使用开发板的时钟频率!)

其中con_t用于记录时钟周期数,每过一个时钟周期加一,当con_t累加到23999时,产生一个秒脉冲s_pulseb,表示过了一秒,计数器加一,这样我们的秒计数器就完成了。下面编写testbench文件:

module s_counter_tb;

reg 				clk;
reg					rst;
wire[3:0]			s_num;

s_counter s_counter(
					.clk(clk),
					.rst(rst),
					.s_num(s_num)
					);
initial begin
				clk<=0;rst<=0;
		#17		rst<=1;
		#1000	$stop;
end

always #5	clk<=~clk;
endmodule

这里要注意以下,我们在这里只经过1000ns就stop是很不合理的,但是把他写大一点又太奇怪了 但是这里不用担心,一会仿真的时候会有解决办法!同时这里的时钟周期也要注意,如果使用开发板实验,一定要根据开发板的时钟周期来,我们这里只是为了方便,随便选择的一个数(10ns),其实这也是不合理的,因为我们假设的时钟频率是24KHz,那么他真正的周期应该是\frac{1}{24K}\times10 ^{^{9_{}^{}}}纳秒! 

2.Modelsim仿真

Modelsim仿真与之前的类似,但是因为我们这里的时钟频率和截至时间太短,所以需要一点额外的步骤才能得到想要的结果:

首先我们对编写的文件编译后,simulate我们的tb文件,将想要观察的波形加入到波形图中,点击Restart和Runall后,得到如下结果:

 

可以看到,这里的计数器只得到了1就停止了,原因就是上面说的我们的时间太短,这里我们需要点击上方的ContinueRun,点击之后再点击Break,就可以得到我们想要的波形啦。

 

 

 这里我们就得到了一个从0-9计数的秒计数器了。

 

二、七段数码管动态显示

1.原理及代码设计

我们之前所设计的七段数码管同样只能根据一个时钟周期(准确的说是根据输入值)改变显示的内容,下面我们将秒计数器加入到里面实现七段数码管的动态显示吧!

//2023.4.14 Bread
//七段数码管动态显示
module seq_dec_dyn(clk,rst,a_g);
input				clk;
input				rst;
output[6:0]			a_g;

reg[6:0]			a_g;
reg[3:0]			s_num;
reg[24:0]			con_t;//秒脉冲分频计数器
reg					s_pulse;//秒脉冲尖;
parameter		frequency_clk=24;

always@(posedge clk or negedge rst)
if(~rst)begin
	con_t<=0;s_pulse<=0;s_num<=0;
end
else begin
	if(con_t==frequency_clk*1000-1)begin
		con_t<=0;
	end
	else begin
		con_t<=con_t+1;
	end
	
	if(con_t==0)begin
		s_pulse<=1;
	end
	else begin
		s_pulse<=0;
	end
	
	if(s_pulse) begin
		if(s_num==9) begin
			s_num<=0;
		end
		else begin
		s_num<=s_num+1;
		end
	end
end
always @ (s_num) begin
	case(s_num)
	4'd0: 	begin a_g<=7'b111_1110; end
	4'd1: 	begin a_g<=7'b011_0000;	end
	4'd2: 	begin a_g<=7'b110_1101;	end
	4'd3:	begin a_g<=7'b111_1100;	end
	4'd4: 	begin a_g<=7'b011_0011;	end
	4'd5: 	begin a_g<=7'b101_1011;	end
	4'd6: 	begin a_g<=7'b101_1111;	end
	4'd7: 	begin a_g<=7'b111_0000;	end
	4'd8: 	begin a_g<=7'b111_1111;	end
	4'd9: 	begin a_g<=7'b111_1011;	end
	default begin a_g<=7'b000_0001;	end
	
	endcase
end

endmodule

相应的testbench如下:

//----testbench----

module seq_dec_dyn_tb;
reg						clk;
reg						rst;
wire[6:0]				a_g;

seq_dec_dyn seq_dec_dyn(
						.clk(clk),
						.rst(rst),
						.a_g(a_g)
							);
initial begin
				clk<=0;rst<=0;
		#17		rst<=1;
		#3000	$stop;
end
always	#5		clk<=~clk;							
													
endmodule

这里是我根据这两个模块整合重新编写的,按照视频中老师的方法是编写一个top文件,将这两个模块例化进去(应该是这样?)。 

 但是我这样编写在Modelsim里将信号添加到波形图中不会产生任何波形,加入initial语句又会报错有知道的大佬麻烦不吝赐教!(在Modelsim仿真,top层应该怎么写呢?)

2.Modelsim仿真

按照之前的方法在Modelsim进行仿真,得到的结果如下:

到这里我们的七段数码管动态显示就完成了。可以看到随着计数器数字的改变,我们数码管的显示也是跟着变的,而且刚好显示的数字是和计数器一一对应,这样我们就实现数码管0-9的动态显示了! 

总结

以上就是本文的全部内容,实际上对于分频我还有很多不明白的地方,也不知道我自己理解的是否正确,学会fpga还有很长的路要走,希望可以坚持下去吧!


 

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值