【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=0001011011100011011000000000B)转化为二进制需要占用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
仿真波形:

注意事项
1、一个变量,若想在always语句里赋值,即使它是输出变量,也需要把它定义成reg型变量。比如Test10_s_counter.v文件中的变量s_num;
2、若设定系统时钟为24KHz,且把分频系数选为23999,则需计数24000次,设定计数一次用时10ns(设定运行时钟周期为10ns),则循环一周期(计数1秒)为240000ns,那么完成0~9秒的计数需要运行2400000ns。
原教学视频链接如下
更多推荐
所有评论(0)