本篇内容:
ip核开发实例
计数器级联
-
开发环境 Quartus 15 + modelsim se 10
-
一种推荐的开发方式,是使用IP核,使我们可以直接使用写好的模块,缩短开发周期。与此同时,这些模块还可以提供更好的性能(何乐而不为)。
- 使用IP核
-
首先说一下我一开始遇到的问题,也是为大家提供一点经验(避坑)参考。在我使用的版本中,没有找到教程里面添加IP核的入口。查找资料未果(可能和我之前查资料的方式有关,之前我一直在找教程里的入口在哪里,而没有直接查如何添加IP核,现在私以为是版本不同,添加IP核的入口也不一样了。ps:教程使用的版本较低,而我用的15)
经过一段时间的摸索与停滞,找到了位于 Tools->IP Catalog里面。接下来就和教程里面的完全一样了!
后面具体的操作就可以跟着教程做了,在此就先不一一列举。
代码文件:
counter_tb.v
/*
#是延时
repet 循环
注意counter_tb和counter-tb,昨晚我因为这个地方没有注意,一直报错# Optimization failed # Error loading design
*/
// 1.定义必须的变量
`timescale 1ns/1ns
`define clock_period 20 // 20ns 50MHz
// 2 添加module
module counter_tb;
// 4. 添加接口
// 激励信号
reg cin; // 进位输入
reg clk; // 计数基准时钟
// 观测信号
wire cout; // 进位输出 只有当cin为1的时候有效
wire [3:0] q; // 4位的
// 3. 例化
counter counter0( // counter 模块就是ip核的计数器!
.cin(cin),
.clock(clk),
.cout(cout),
.q(q));
// 产生时钟信号
initial clk = 1;
always
#(`clock_period/2)
clk = ~clk; // 系统时钟的一半 进行一次翻转
// cin信号的驱动
initial begin
repeat(20)begin // 重复5次 相当于循环
cin = 0;
#(`clock_period*5) cin=1;
#(`clock_period) cin=0;
end
//
#(`clock_period*20)
$stop;
end
endmodule
- 两个定时器级联
counter_top.v
// 用两个4位的 组成一个8位的
module counter_top(cin, clk, cout, q);
input cin;
input clk;
output cout;
output [7:0]q;
// 定义一条线,连接cout1和cin2
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
查看RTL-Viewer,可以看到两个定时器级联的效果:低位的进位输出接到高位的信号输入
仿真:
counter_top_tb.v
/*
级联的
*/
// 1.定义必须的变量
`timescale 1ns/1ns
`define clock_period 20 // 20ns 50MHz
// 2 添加module
module counter_top_tb;
// 4. 添加接口
// 激励信号
reg cin; // 进位输入
reg clk; // 计数基准时钟
// 观测信号
wire cout; // 进位输出 只有当cin为1的时候有效
wire [7:0] q; //
// 3. 例化
counter_top counter0(
.cin(cin),
.clk(clk),
.cout(cout),
.q(q));
// 产生时钟信号
initial clk = 1;
always
#(`clock_period/2)
clk = ~clk; // 系统时钟的一半 进行一次翻转
// cin信号的驱动
initial begin
repeat(300)begin // 重复5次 相当于循环
cin = 0;
#(`clock_period*5) cin=1;
#(`clock_period) cin=0;
end
//
#(`clock_period*20)
$stop;
end
endmodule
可以看到级联的输出波形
参考
小梅哥FPGA