本次只简单实现MMCM分频功能
参考:正点原子 ZYNQ小系统板之FPGA开发指南V1.0
一、Vivado使用
1.创建new prj
2.新建IP核
选择MMCM
设置时钟频率50MHz,分频后的两个clkout分别为50MHz与200MHz。
默认生成pll文件,可直接例化:
3.Add sources编写Verilog代码
定义clk_in与rstn;例化clk_wiz。
module prj_pll(
input clk_in,
input rstn,
output clk_50m,
output clk_200m
);
wire locked;
// IBUFDS 实现差分到单端信号的转变
IBUF #(
.IBUF_LOW_PWR("TRUE"), // Low power="TRUE", Highest performance="FALSE"
.IOSTANDARD("DEFAULT") // Specify the input I/O standard
) IBUF_inst (
.O(clk_in_buf),
.I(clk_in)
);
//IP 核的instance
clk_wiz_0 u_clk_wiz
(
// Clock in ports
.clk_in1(clk_in_buf),
// Clock out ports
.clk_out1(clk_50m),
.clk_out2(clk_200m),
// Status and control signals
.reset(rstn), //input
.locked(locked) //output
);
endmodule
4.仿真
时钟 IP 核默认是高电平复位,而输入的系统复位信号 rstn 是低电平复位,因此要对系统复位信号进行取反。
因此,testbench中设置了rstn为1。
仿真波形如下:
二、Debug
因为想要debug输入的clk_in(即系统clk),所以参考别人的代码在module里面添加了:
IBUF #(
.IBUF_LOW_PWR("TRUE"), // Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
.IOSTANDARD("DEFAULT") // Specify the input I/O standard
) IBUF_inst (
.O(clk_in_buf), // Buffer output
.I(clk_in) // Buffer input (connect directly to top-level port)
);
这样的话就可以debug clk_in_buf信号了。
Clock Domain
但是生成的clk_out无法debug:
尝试解决clock domain问题
选择了clock domain(不知道能不能这样做):
BUT
参考了下别人的代码,发现clk_out好像本来就是undefined的clock domain设置。
所以要如何debug呢?
还是只能使用示波器查看输出波形呢?
删掉后进行分析和综合
程序烧录时出现问题:
vivado----fpga硬件调试 ----找不到ila核问题及解决_ila no content-CSDN博客
可能是clk_out的debug约束:
注释后烧录不报错。但是烧录后界面也没有变化,所以不知道有没有烧录成功。
时钟约束
查阅资料发现,在约束文件中,会有时钟约束(但自己只写了管脚约束)。不知道在这个prj下,时钟约束是否必要。
FPGA主时钟约束详解 Vivado添加时序约束方法-电子发烧友网
查看原理图发现系统时钟属于晶振提供的50MHz,因此应该是可以不写时钟约束的。
三、重新开始
还是要多了解PLL,不能光看开发指南。
超详细的Xilinx ISE的PLL锁相环IP核的使用教程与结果分析(ISE与Quartus PLL锁相环使用的区别,以及使用ISE倍频时遇到的问题)_ise pll-CSDN博客
【FPGA ZYNQ Ultrascale+ MPSOC教程】5.Vivado下PLL实验 - 知乎
讲的很详细:
https://blog.51cto.com/oliverHuang/6317215https://blog.51cto.com/oliverHuang/6317215
IBUFG即输入全局缓冲,是与专用全局时钟输入管脚相连接的首级全局缓冲。所有从全局时钟管脚输入的信号必须经过IBUFG 单元,否则在布局布线时会报错。
修改代码
顶层文件中:
clk_wiz_0 u_clk_wiz
(
.reset(~rstn), //input // 取反
);
原来vivado仿真有不同类型。试试后仿吧。
差得一塌糊涂。为什么reset不是~rstn?在tb中对rstn置高(开发板rstn低电平复位),reset应该为低电平才对。
重新加载一下试试看吧。
reset为低电平了,但是locked没有置高,clk_out也没有输出。
原来tb中例化的时候也~rstn了。。。修改后重新加载:
时序仿真
后仿
一整天都在学MMCM/PLL,结果进度感人。。。