IP 介绍
IP核(Intellectual Property Core),即知识产权核或知识产权模块,是电子设计自动化(EDA)领域中的重要组成部分。根据美国知名咨询公司Dataquest的定义,半导体行业的IP指的是为ASIC或FPGA预先设计的电路功能模块,这些模块显著提高了设计效率。IP核可分为软IP、固IP和硬IP三类:软IP使用Verilog或VHDL等硬件描述语言进行描述,不涉及具体电路实现;固IP是经过综合的功能模块,适合快速集成;硬IP则提供了最终设计产品,通常为掩膜级别,适合高效生产。通过将复杂的数字电路功能模块(如ROM、FIFO、RAM、SDRAM 控制器、 PCIE 接口等)设计为灵活的可调参数模块,IP核极大地方便了工程师的工作。随着CPLD和FPGA规模的不断扩大以及设计复杂度的显著提升(例如,IC复杂度每年增长约55%,而设计能力仅提升21%),设计者面临着如何在有限时间内高效完成复杂设计的挑战。在这种背景下,IP核的应用不仅可以避免重复劳动,还能显著减轻工程师的负担,成为行业发展的重要趋势。同时,IP核的重用有效缩短了产品的上市时间,使企业能够迅速响应市场需求,提升竞争力。通过整合这些成熟的模块,企业得以专注于创新与差异化,推动技术进步与市场发展。
IP核可以以三种不同的形式存在,分别是HDL语言形式、网表形式和版图形式,对应于不同的功能描述类型:
软核(Soft IP Core):以HDL(硬件描述语言)形式提供,通常使用Verilog或VHDL描述,具有灵活性和可配置性,适合于多种实现。
固核(Firm IP Core):介于软核和硬核之间,通常以网表形式提供,已完成综合,适合于特定技术节点的集成,具有较好的性能和一定的灵活性。
硬核(Hard IP Core):以版图形式实现,通常是针对特定工艺节点的物理实现,性能优化程度高,但灵活性较低,适合于高效的生产和快速部署。
对于我们来说用IP核开发优点:
- 简化复杂功能模块:IP核将一些在数字电路中常用但复杂的功能模块简单化,设计者可以直接调用更改参数直接生成,从而避免重复劳动,大幅提升开发效率。
- 减少设计和调试时间:由于IP核经过验证和优化,设计者可以直接将其集成到自己的设计中,避免从头开始设计和调试,从而显著减少整体项目的设计和调试时间。
- 加快产品上市进程:随着CPLD/FPGA等可编程逻辑器件规模的扩大和设计复杂性的增加,能够更快速地完成任务,加快产品上市进程。
- 增强灵活性和适应性:软核和固核形式的IP核允许设计者在一定范围内对参数进行修改和定制,以适应不同设计需求,这种灵活性使得设计者能够更好地应对市场变化和客户需求的多样性。
凡事都有优缺点,接下来我们讲讲缺点:
- 跨平台兼容性问题:不同的FPGA平台或厂商之间,IP核往往不具备通用性。设计者可能需要根据新平台的特定要求进行重新设计或适配,增加了开发的复杂性。这种转换可能导致时间延误、资源浪费和额外的开发成本。
- 内部实现不可见性:IP核通常被视为“黑箱”,设计者只能访问其接口,无法查看或修改内部实现代码。这种透明度的缺乏使得在故障排查、性能优化和功能扩展时变得困难,限制了设计者的灵活性和创新性。
- 高昂的定制费用:定制IP核的开发和集成费用通常较高,特别是在特定应用或高性能需求的情况下。此外,随着项目的迭代更新,维护和支持成本也会增加,可能导致项目预算超支。
- 集成复杂性:不同的IP核在集成时可能会遇到兼容性问题,特别是当需要将多个IP核结合在一起工作时。这样的集成过程可能涉及大量的调试工作,增加了项目的复杂性和不确定性。
(注:如想了解更多IP核相关知识请自行百度)
高云提供全系列的IP核路径(\Gowin\Gowin_V1.9.10.02_x64\IDE\ipcore)感兴趣可以咨询查看,切记不要进行任何操作~
1、锁相环介绍
前面我们简单介绍一下IP核,接下来我将带领你们掌握常用 IP 核的配置及使用方法。
锁相环(Phase Locked Loop),简称 PLL,是一种时钟反馈电路,用于在频率合成、时钟恢复、时钟多路复用等应用中起到重要作用。
时钟资源对 FPGA 的应用至关重要。而高云半导体 FPGA 产品提供了可综合的时钟频率,可进行不同的参数频率调整、相位调整,占空比调整等。Gowin PLL 的电路框图如下图所示:
参考文档:官网Gowin时钟资源 17 页(https://cdn.gowinsemi.com.cn/UG286.pdf)
2、IP_PLL 配置
首先创建好高云 Gowin 项目工程,在菜单栏 Tools -> IP Core -> Generator 点击,在弹出来的 IP 核搜索框输出 PLL 后按回车在 Hard Module -> CLOCK -> rPLL 这就是本章所使用到的 PLL 锁相环的 IP 核,如下图所示:
点开 rPLL ,找到 General 栏,如下图所示:
IP核信息介绍:
- Device 和 Part Number为所选择的设备信息。
- Module Name 和 File Name 为配置产生的 IP 设计文件名,可重新编辑。
- Create In 为配置产生的 IP 设计文件的目标路径,可在文本框中重新编辑目标路径。
2.1 General 配置框
- Mode 为PLL的模式选择:
General Mode:一般模式
Advanced : 高级模式
- PLL Phase And Duty Cycle Adjustment 选项:
Dynamic :动态调整
Static : 静态调整
PLL Reset :配置 PLLO 的 RESET 使能模式,可以复位PLL。
PLL Power Down:配置 RESET_P 端口使 PLLO 处于节电模式;
2.2、CLKIN 输入频率
Clock Frequency :配置输入时钟的频率,上面明确规定了输入时钟的范围为 3-500MHz,我们这边是根据 逻辑派 原理图配置为 50MHz 输入频率。
2.3、CLKFB
CLKFB:配置 PLLO 反馈时钟的源和倍频参数。
2.4、CLKOUT 输出
Bypass :输出时钟的旁路功能。
Expected Frequency :配置输出时钟的频率,上面明确规定了输入时钟的范围为 3.90625~ 625MHz,我们这里配置输出 30MHz 频率输出。
Tolerance :CLKOUT 的频率和计算出的实际频率的允许误差,配置为 0.0 。
2.5、CLKOUTP 有相位输出
Enable CLKOUTP :是相移时钟输出使能,如果说要使用这个带相位输出功能的话,得先使能这个功能。
Bypass :输出时钟的旁路功能。
Phase(degree):静态模式下配置相位配置,这里选择 180° 是为了好查看波形。
Duty Cycle:占空比。
2.6、CLKOUTD 输出
Enable CLKOUTD :是 CLKOUTD 时钟输出使能。
Bypass :输出时钟的旁路功能。
Source :为输入频率资源选择,这里选择的是 CLKOUT 的输出时钟作为我们 CLKOUTD 的输入时钟。
Expected Frequency :配置输出时钟的频率,上面明确规定了输入时钟的范围为 0.031 ~ 312.5MHz,我们这里配置输出 5MHz 频率输出。
Tolerance :CLKOUTD 时钟输出期望频率和计算出的实际频率的允许误差。
Actual Frequency : 经计算得出的分频时钟输出的实际频率,不用户需要配置。
2.7、CLKOUTD3 输出
Enable CLKOUTD3 :是 CLKOUTD3 时钟输出使能。
Source :为输入频率资源选择,这里选择的是 CLKOUT 的输出时钟作为我们 CLKOUTD3 的输入时钟。
注:此时钟为三分频时钟,为什么这么说呢,内部是固定了一个三分频的时钟分频器,不能更改,在实际使用的时候要注意。
3、PLL 时钟配置汇总
IP 核的 rPLL 配置如下图所示:
在配置完所有参数后还需要点击 LOCK 前面的框,目的是打开 PLL 的输出锁定指示,打开之后,需要点一下 Calculate 按钮,用来验证是否有哪些地方时钟配置有错误,同时会计算一下分频时钟输出的实际频率,也当于一个编译的过程。
当配置好以后点击红框的 OK 按钮,会弹出是否添加 PLL 配置文件到当前目录里面,选择 YES 按钮后,在选择 OK 按钮,如下图所示:
添加完毕之后我们的工作就完成了一大半了,接下来该写顶层模块封装,将输入时钟和输出时钟给引到 I/O 引脚上面去。
接下来创建一个PLL_top.V的顶层文件,如下图所示:
4、程序编写
本节 PLL 锁相环(pll_top.v)代码编写如下:
module pll(
input sys_clk, //系统时钟
input sys_rst_n, //系统复位,低电平
output clk_30m, //CLKOUT
output clk_30m_180flip, //CLKOUTP
output clk_5m, //CLKOUTD
output clk_10m //CLKOUTD3
);
wire pll_lock;
//PLL锁相环
Gowin_rPLL u_Gowin_rPLL(
.clkout (clk_30m), //output lock
.lock (pll_lock),
.clkoutp (clk_30m_180flip), //output clkoutp
.clkoutd (clk_5m), //output clkoutd
.clkoutd3 (clk_10m), //output clkoutd3
.reset (~sys_rst_n), //input reset
.clkin (sys_clk) //input clkin
);
endmodule
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
5、仿真编写
PLL 锁相环仿真(pll_mod.v)代码编写如下:
`timescale 1ns / 1ps //仿真单位/仿真精度
module pll_mod();
//reg define
reg sys_clk;
reg sys_rst_n;
//wire define
wire clk_30m;
wire clk_30m_180flip;
wire clk_5m;
wire clk_10m;
//信号初始化
initial begin
sys_clk = 1'b0;
sys_rst_n = 1'b0;
#200
sys_rst_n = 1'b1;
end
//在对 FIFO 或者 SP IP 核等(或其它在底层转换 GSR 时调用了全局复位的 IP/原语)进行仿真时,在仿真代码中需要添加如下这一段代码,否则联合仿真时就会报错。
GSR GSR(.GSRI(1'b1));
//产生时钟
always #10 sys_clk = ~sys_clk;
pll u_pllL(
.sys_clk(sys_clk), //系统时钟
.sys_rst_n(sys_rst_n), //系统复位,低电平
.clk_30m(clk_30m), //CLKOUT
.clk_30m_180flip(clk_30m_180flip), //CLKOUTP
.clk_5m(clk_5m), //CLKOUTD
.clk_10m(clk_10m) //CLKOUTD3
);
endmodule
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
由于我们这里不需要对 pll_top.v 文件进行修改,则我们需要再 Modelsim 中分别添加 仿真文件 和 pll_top.v 等,需要添加文件如下所示:
仿真结果如下所示:
由上图可知,pll_lock 信号拉高之后,锁相环开始后输出四个稳定的时钟。clk_30m 和 clk_30m_180flip,周期都为 33.33ns ,频率为 30Mhz,但但 clk_30m_180flip 相对于 clk_30m 有 180 度的相位偏移;clk_5m 周期都为 200ns 也就是说 clk_10m ,周期为 100ns,我们创建的锁相环从仿真结果上来看是正确的。
6、下载验证
在仿真验证完成后,接下来使用 Gowin 对时钟约束和引脚进行分配并上板验证。本实验中,系统时钟、复位按键以及四个输出端口的管脚分配如下表所示:
信号 | 方向 | 引脚 | 端口作用 | 电平标准 |
---|---|---|---|---|
sys_clk | input | T7 | 时钟 | LVCMOS33 |
sys_rst_n | input | F10 | 复位 | LVCMOS33 |
clk_30m | input | K15 | 30MHz | LVCMOS33 |
clk_30m_180flip | output | K12 | 30MHz,相位偏移180° | LVCMOS33 |
clk_5m | output | P16 | 5MHz | LVCMOS33 |
clk_10m | output | R16 | 10MHz | LVCMOS33 |
Gowin 软件中 I/O Constraints 界面如下图所示:
连接开发板的下载器,下载码流文件到开发板里面,下载完成之后,我们就可以拿出示波器查看波形了。实际位置如下图所示:
根据上面的接线图来,示波器测量出的时钟频率为 5MHz ,跟仿真结果差不多。这主要是示波器这里有一点需要大家注意一下,实际上时钟输出的波形是方波,但是这里用示波器测出的波形却近似于三角波,这并不是输出的时钟信号错了,而是因为我们所使用的示波器的采样率不够导致的。这里我们就不做任何展示了~