一、调用IP核的步骤
1、新建项目project
2、打开Tools中的megaWizrd Plug-in Manager
3、选择create a new …
4、左侧直接搜索想要的功能,这里是counter,点击
5、选择计数器的位数,选择是增加、减少或者是都有,我们选择up only
6、Plain binary是二进制直接计数,
modulus,with a count of 设置一个最大值
carry-in有效的时候进行计数
carry-out是产生一个输出说计数满了
7、后面暂不管,next,next,finish
二、打开项目文件
这个文件里面只有一些相关信息,真正的文件是counter.v,也就是上面第7步里面的内容,需要右键Files添加
右键,set as top-level,然后可以直接分析和综合
观察电路图
双击观察内部电路
三、然后可以直接新建一个counter_tb进行仿真
`timescale 1ns/1ps
`define clock_period 20//定义时钟周期,时钟50M
module counter_ip_tb;
reg cin;//进位输入
reg clk;//计数基准时钟
wire cout;//进位输出
wire [3:0] q;
counter counter0(
.cin(cin),
.clock(clk),
.cout(cout),
.q(q)
);
initial clk = 1;
always #(`clock_period/2) clk =~clk;
initial begin
repeat(5)begin //5个时钟周期为0,一个周期为1,重复5次
cin = 0;
#(`clock_period*5) cin = 1;//RTL仿真中看到只有cin=1时,计数器才在计数
#(`clock_period) cin = 0;
end
#(`clock_period*200);
$stop;
end
endmodule
RTL simulation结果:
可以看到时钟clk一直在走,但q这个计数只有在cin为1的时候才进行了加一。
1、接下来将repeat(5)改为了repeat(20),可以观察到因为设置了最大值,所以计数器只能到9。同时,cout在计数器到最大值9之后产生一个值1。
2、不设置计数器的最大值
结果:
自然计数到4位计数器的最大值15,后面的竖线是毛刺。
四、将两个四位计数器级联成一个八位计数器
module counter_top(cin,clk,cout,q);
input cin;
input clk;
output cout;
output [7:0]q;
wire cout1;
counter counter1(
.cin(cin),
.clock(clk),
.cout(cout1),
.q(q[3:0])
);
counter counter2(
.cin(cout1),
.clock(clk),
.cout(cout),
.q(q[7:4])
);
endmodule
每次更换文件仿真之前都要重新assignments-》setting–》simulation进行重新设置
仿真结果如上图所示,结果正确。
如果又改为设置计数器最大值为10的情况下,应该是99是最大值。