一、计数器设计
所需软件
Verilog编程软件:Lattice Diamond(3.11.0.396.4_Diamond_x64)
Verilog仿真软件:ModelSim SE-64 10.2c(modelsim-win64-10.2c-se)
方法:用always语句实现计数器逻辑设计
符号图:
Verilog代码:
Part1:Test8_counter.v文件(Verilog工程文件)
//2022-05-28
//计数器-counter
module Test8_counter(
clk, //触发器要包含时钟信号和复位信号
res,
y
);
input clk; //时钟输入信号
input res; //复位输入信号
output[7:0] y; //8位计数器的输出寄存器
reg[7:0] y; //y是触发器(register),要在always语句中使用,要定义成reg型变量
wire[7:0] sum; //+1运算的结果
assign sum=y+1; //组合逻辑部分
always@(posedge clk or negedge res) //敏感变量为时钟的上升沿和复位的下降沿
if(~res)begin //如果复位信号到来
y<=0; //触发器复位时的动作(res为低时,y寄存器复位)。用<=来赋值
end
else begin
y<=sum; //触发器正常工作时的动作(res为高时,y正常工作)。只要时钟一到,sum就传给y
end
endmodule
Part2:Test8_counter_tb.v文件(Verilog仿真文件)
//2022-05-28
//计数器-testbench of counter
`timescale 1ns/10ps
module Test8_counter_tb;
reg clk_in,res_in;
wire[7:0] y_out; //计数的输出结果用wire型变量表示
Test8_counter Test8_counter( //异名例化时的module名要与源码里的Test8_counter相统一
.clk(clk_in),
.res(res_in),
.y(y_out)
);
initial begin
clk_in<=0;res_in<=0; //对clk和res赋初值(res为低,计数器处于复位状态)
#17 res_in<=1; //对res解复位
#6000 $stop; //将计数器程序遍历运行2遍。假如时钟周期是10ns,8位计数器遍历运行一遍需要2560ns。
end
always #5 clk_in<=~clk_in; //每过5ns,将clk_in的“非”运算值赋给clk_in,即将时钟周期设定为10ns。
endmodule
仿真波形:
注意事项
1、计数器的逻辑中要包含时钟信号和复位信号,在使用always语句时,应注意always语句中的敏感变量为时钟信号和复位信号,具体到本代码中为时钟信号的上升沿和复位信号的下降沿;
2、对低电平有效的复位信号进行解复位的方法:令复位信号为高电平“1”,例如:Test8_counter.v文件中的“#17 res_in<=1;”;
3、异名例化时的module名要与源码里的module名保持一致;
4、时钟周期为10ns的时钟的设置方法:每过5ns,将clk_in的“非”运算值幅给clk_in,即将时钟周期设定为10ns。例如Test8_counter_tb.v文件中的“always #5 clk_in<=~clk_in;”。