【Verilog零基础入门-边看边练】学习笔记——第五讲 时序逻辑代码设计和仿真(秒计数器)(一)

一、秒计数器逻辑设计

所需软件

Verilog编程软件:Lattice Diamond(3.11.0.396.4_Diamond_x64)

Verilog仿真软件:ModelSim SE-64 10.2c(modelsim-win64-10.2c-se)

方法:用always语句实现秒计数器逻辑设计

符号图: 

Verilog代码:

Part1:Test10_s_counter.v文件(Verilog工程文件)

//2022-05-31
//秒计数器(s_counter,0-9秒循环计数)
//假设clk是24KHz系统时钟,秒分频产生秒脉冲s_pulse;
//秒计数模块对秒脉冲计数,计数范围是0-9,秒计数结果为s_num(位宽为4)
module Test10_s_counter(
						clk,
						res,
						s_num	
						);
input					clk;				//对系统时钟进行分频得到秒脉冲,之后对秒进行计数,即所谓秒计数器。
input					res;				//对秒计数器的复位
output[3:0]				s_num;				//秒计数模块
 
parameter				frequency_clk=24;	//假设系统时钟为24KHz
	
reg[24:0]				con_t;	//基于系统时钟的秒脉冲分频计数器。0到23999999计数,每循环一圈就是1秒。设系统时钟频率为24MHz。十进制的24兆(24000000D=‭0001011011100011011000000000‬B)转化为二进制需要占用25位。
reg						s_pulse;//秒脉冲尖。1秒出现一次。两个秒脉冲尖之间表示一个系统时钟宽度。当秒脉冲分频计数器con_t计数为0后,秒脉冲尖为1;当秒脉冲分频计数器con_t计数为1后时起,秒脉冲尖为0(无秒脉冲尖),直到秒脉冲分频计数器计数再次为0后,秒脉冲尖再次为1,如此反复。
reg[3:0]				s_num;	//秒计数。对秒脉冲出现的次数进行计数,计数范围是0-9。
								//虽然s_num是输出端口,但是若想在always语句里赋值,也需要把它定义成reg型变量。等同于一个触发器,故需要对其复位。

always@(posedge clk or negedge res)
if(~res) begin
	con_t<=0;s_pulse<=0;s_num<=0;
end
else begin
	//秒脉冲分频计数器con_t,计数范围0-23999999
	if(con_t==frequency_clk*1000-1) begin	//如果秒脉冲分频计数器con_t的计数值(1秒之内秒脉冲的个数)达到分频系数:frequency_clk*1000-1
		con_t<=0;								//对秒脉冲分频计数器清零
	end
	else begin									//如果秒脉冲分频计数器con_t的计数值(1秒之内秒脉冲的个数)未达到分频系数:frequency_clk*1000-1
		con_t<=con_t+1;							//秒脉冲分频计数器继续计数
	end
	
	//秒脉冲尖发生器s_pulse,电平状态1或0
	if(con_t==0) begin							//如果秒脉冲分频计数器con_t的计数值为零
		s_pulse<=1;								//将秒脉冲发生器s_pulse置1,秒脉冲是“尖”的形态,得到秒脉冲尖
	end
	else begin									//如果秒脉冲分频计数器con_t的计数值不为零
		s_pulse<=0;								//将秒脉冲发生器s_pulse置0,秒脉冲不是“尖”的形态
	end
	
	//秒(秒脉冲尖)计数器s_num,计数范围0-9
	if(s_pulse) begin							//如果秒脉冲发生器s_pulse不为0
		if(s_num==9) begin						//如果秒计数器s_num记录的秒脉冲尖(秒脉冲发生器s_pulse为1的状态)的个数已经达到9个
			s_num<=0;							//对秒计数器清零
		end
		else begin								//如果秒计数器s_num记录的秒脉冲尖(秒脉冲发生器s_pulse为1的状态)的个数未达到9个
			s_num<=s_num+1;						//秒计数器+1,用于对秒脉冲尖(秒脉冲发生器s_pulse为1的状态)计数。两个秒脉冲尖之间的时间间隔是1秒。
		end
	end
end
endmodule

Part2:Test10_s_counter_tb.v文件(Verilog仿真文件)

//2022-06-01
//秒计数器,testbench of Test10_s_counter
`timescale 1ns/10ps
module Test10_s_counter_tb;
reg									clk_in,res_in;
wire[3:0]							s_num_out;

Test10_s_counter Test10_s_counter(
									.clk(clk_in),
									.res(res_in),
									.s_num(s_num_out)	
									);
initial begin
									clk_in<=0;res_in<=0;
		#17							res_in<=1;				//过17ns,解除对时钟的复位
		#3000000					$stop;					//运行时长3000000ns。24KHz,计数24000次,一次10ns,循环一周期(计数一秒)为240000ns,则完成0~9的计数需要运行2400000ns。
end

always	#5							clk_in<=~clk_in;		//设定一个以10ns为周期的运行时钟

endmodule

仿真波形:

【Verilog零基础入门-边看边练】学习笔记——第五讲 时序逻辑代码设计和仿真(秒计数器)(一)_第1张图片

注意事项

1、一个变量,若想在always语句里赋值,即使它是输出变量,也需要把它定义成reg型变量。比如Test10_s_counter.v文件中的变量s_num;

2、若设定系统时钟为24KHz,且把分频系数选为23999,则需计数24000次,设定计数一次用时10ns(设定运行时钟周期为10ns),则循环一周期(计数1秒)为240000ns,那么完成0~9秒的计数需要运行2400000ns。

原教学视频链接如下

Verilog零基础入门_哔哩哔哩_bilibili 

你可能感兴趣的:(Lattice,学习,fpga开发,硬件工程)