本文对TD软件中的FPGA工程创建、时钟系统、IP Generator使用、PLL核配置和例化以及LED流水灯和IO管脚输出演示
软件版本为5.6.1,安路FPGA的开发使用FPGA开发软件Anlogic TD,在安路科技官网的产品中心可以查看其简介和下载相关资料。
文中介绍的内容需结合软件说明手册进行理解,手册中的内容不再重复。
文中内容涉及以下手册:
1.1项目的创建以及文件管理
项目的创建可以参考TD软件使用手册中的第2章项目管理,软件的使用还是还简单的,创建的空工程如图所示。
项目版本上的注意事项:若项目是使用TD5.4之前的版本生成的.al文件,TD5.4及之后的版本打开时要求必须升级.al文件,且一旦升级后,.al文件将不可用TD5.4之前的版本打开,原.al会被自动备份为.al.back。
1.2 IP生成器
IP生成器是一个创建 IP核的图形交互设计界面。 用户可以在 IP生成器中对所选 IP进行配置, 并 自动生成相应的 IP模块。目前支持的 IP模块 分为 Primitive IP和 Soft IP 。
Primitive IP有 Common、 Clock、 Arithmetic、 Memory、 Analog Digital Convertor等
Soft IP有 Arithmetic、 Video & Display interface、 Generic Digital Signal Processing等 。
可以生成的IP核选项如图所示
TD软件使用手册的第3章IP生成器对图中的各种IP核的参数配置和例化使用都有详细的介绍。TOOL->IP Generator工具用于IP核的生成和修改已有IP核的参数,不过在生成IP核后,配置界面不会自动关闭,体验不是很好。
1.3 Demo板时钟资源
开发板上有25MHz的有源晶振为FPGA提供时钟源,从SF1S60G121I全局时钟管脚输入,与FGPA管脚的连接关系如表2。
表2 时钟输入管脚列表
SF1S60CG121I 管脚位置 |
SF1S60CG121I 管脚名称 |
IO电源域 |
时钟IO |
D7 |
IO_T8_3,GCLK3 |
3.3V |
SCLK_25M |
SF1S60CG121I的时钟资源有:
1.4 PLL核生成
使用前文提到的IP Generator可以生成PLL核,用来产生不同频率的时钟信号。PLL核手册中对IP Generator中对PLL核的各项参数都给出详细的说明,文中对PLL核采用最简单的设置,输入时钟设置为25MHz,输出两路时钟clk_0为50MHz,clk_1为100MHz。IP Generator参数设置和最后的数据界面如图所示。
生成IP后,可以在设备树查看
点击IP下的示例文件,可以查看模块的名称和参数,用于模块的例化。
1.5 LED和用户IO电路
查看安路demo板的硬件手册中对LED电路的描述,
LED电路示意图
LED电路通过一个NMOS管控制,控制引脚输出高电平LED亮,低电平LED灭;LED控制引脚与FPGA管脚的映射关系为:
SF1S60CG121I 管脚位置 |
SF1S60CG121I 管脚名称 |
IO电源域 |
指示灯IO |
J4 |
IO_B6N_2,GCLK4 |
1.2V |
LED_R |
J5 |
IO_B6P_2,GCLK5 |
1.2V |
LED_B |
H5 |
IO_B7N_2 |
1.2V |
LED_G |
用户扩展IO的示意图如图所示
用户IO管脚的定义
SF1S60CG121I 管脚位置 |
SF1S60CG121I 管脚名称 |
IO电源域 |
IO名称 |
IO序号 |
H9 |
IO_R1P_0,GCLK3 |
2.5V |
USER_IO0_N |
3 |
G9 |
IO_R1N_0,GCLK2 |
2.5V |
USER_IO0_P |
4 |
H8 |
IO_R0N_0,GCLK0 |
2.5V |
USER_IO1_N |
5 |
H7 |
IO_R0P,GCLK1 |
2.5V |
USER_IO1_P |
6 |
D11 |
IO_R7N_0 |
2.5V |
USER_IO2_N |
7 |
D10 |
IO_R7P_0 |
2.5V |
USER_IO2_P |
8 |
C11 |
IO_R8N_0,GCLK10,D3 |
2.5V |
USER_IO3_N |
9 |
C10 |
IO_R8P_0,GCLK11,D2 |
2.5V |
USER_IO3_P |
10 |
B11 |
IO_R9N_0 |
2.5V |
USER_IO4_N |
11 |
B10 |
IO_R9P_0 |
2.5V |
BUZZER |
12 |
A11 |
IO_R10N_0,GCLK12,D1 |
2.5V |
USER_IO5_N |
13 |
A10 |
IO_R10P_0,GCLK13,D0 |
2.5V |
USER_IO5_P |
14 |
B8 |
IO_R11N_0 |
2.5V |
USER_IO6_N |
15 |
B9 |
IO_R11P_0 |
2.5V |
USER_IO6_P |
16 |
A8 |
IO_R12N_0,GCLK14,USRCLK |
2.5V |
USER_IO7_N |
17 |
A9 |
IO_R12P_0,GCLK15,SCLK |
2.5V |
USER_IO7_P |
18 |
1.6 时钟输出、LED流水灯程序说明
程序使用PLL核生成两路时钟输出,PLL参数核时钟的输入为25MHz,输出clk_0(50MHz)和clk_1(100MHz)。top模块中的代码如下:
//sys_clk0为50MHz,sys_clk1为100MHz
sys_pll sys_pll_inst(
.refclk(refclk),
.reset(rst_n),
.extlock(),
.clk0_out(sys_clk0),
.clk1_out(sys_clk1)
);
为实现流水灯,为了能分辨出LED的状态翻转,设计了一个时钟分频器,可以实现任意整数的分频,分频模块的设计如下
module clk_divide(clk,rst_n,clkout);
input clk,rst_n;
output clkout;
parameter WIDTH=3;
parameter N=5;
reg [WIDTH-1:0] cnt_p,cnt_n;
reg clk_p,clk_n;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_p<=0;
else if (cnt_p==(N-1))
cnt_p<=0;
else cnt_p<=cnt_p+1;
end
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
clk_p<=0;
else if(cnt_p<(N>>1))
clk_p<=0;
else
clk_p<=1;
end
always @(negedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_n<=0;
else if(cnt_n==(N-1))
cnt_n<=0;
else cnt_n<=cnt_n+1;
end
always @(negedge clk or negedge rst_n)
begin
if(!rst_n)
clk_n<=0;
else if(cnt_n<(N>>1))
clk_n<=0;
else clk_n<=1;
end
assign clkout = (N==1)?clk:(N[0])?(clk_p&clk_n):clk_p;
endmodule
在top模块中的调用如下:
//时钟分频模块
//refclk为25MHz,计数器设置为25_000_000,输出1Hz,周期为1s的时钟信号
clk_divide #(.WIDTH(32),.N(25_000_000)) clk_divide_1s (
.clk(refclk),
.rst_n(key[0]),
.clkout(clk_1s));
//sys_clk0为50MHz,计数器设置为25_000_000,输出2Hz,周期为500ms的时钟信号
clk_divide #(.WIDTH(32),.N(25_000_000)) clk_divide_500ms (
.clk(sys_clk0),
.rst_n(key[0]),
.clkout(clk_500ms));
//sys_clk1为100MHz,计数器设置为20_000_000,输出5Hz,周期为200ms的时钟信号
clk_divide #(.WIDTH(32),.N(20_000_000)) clk_divide_200ms (
.clk(sys_clk1),
.rst_n(key[0]),
.clkout(clk_200ms));
top模块的整体设计如下:
module top(led0,led1,led2,refclk,key,clkout);
output led0,led1,led2,clkout;
input refclk;
input [2:0] key;
reg led0_r,led1_r,led2_r;
reg [31:0] cnt;
wire sys_clk0,sys_clk1;
wire clk_1s,clk_500ms,clk_200ms;
assign clkout=refclk;
assign rst_n=!key[0];
//sys_clk0为50MHz,sys_clk1为100MHz
sys_pll sys_pll_inst(
.refclk(refclk),
.reset(rst_n),
.extlock(),
.clk0_out(sys_clk0),
.clk1_out(sys_clk1)
);
//时钟分频模块
//refclk为25MHz,计数器设置为25_000_000,输出1Hz,周期为1s的时钟信号
clk_divide #(.WIDTH(32),.N(25_000_000)) clk_divide_1s (
.clk(refclk),
.rst_n(key[0]),
.clkout(clk_1s));
//sys_clk0为50MHz,计数器设置为25_000_000,输出2Hz,周期为500ms的时钟信号
clk_divide #(.WIDTH(32),.N(25_000_000)) clk_divide_500ms (
.clk(sys_clk0),
.rst_n(key[0]),
.clkout(clk_500ms));
//sys_clk1为100MHz,计数器设置为20_000_000,输出5Hz,周期为200ms的时钟信号
clk_divide #(.WIDTH(32),.N(20_000_000)) clk_divide_200ms (
.clk(sys_clk1),
.rst_n(key[0]),
.clkout(clk_200ms));
assign led0=led0_r;
assign led1=led1_r;
assign led2=led2_r;
//在各个时钟的上升沿,翻转led的状态
always @(posedge clk_1s) led0_r=~led0_r;
always @(posedge clk_500ms) led1_r=~led1_r;
always @(posedge clk_200ms) led2_r=~led2_r;
endmodule
1.7 为顶层模块添加约束
顶层模块搭建完毕后,需要为相关的引脚添加约束,在添加约束是,可以手动编写.adc(Anlogic Design Constraint)引脚约束文件,或者使用FPGA->Flow下的User Constraints->IO Constraint进行管脚的选择。TD软件支持多个引脚约束管理,限于篇幅关系,这里不进行介绍,关于引脚约束具体的操作可以参考TD软件使用手册的第4章用户约束部分。需要注意的是,在添加管脚约束前,要保证FPGA Flow 下的Syn Opt->Read Design 即FPGA源码综合无误,同时在修改top顶层的输入输出定义后,要重新综合后,添加引脚约束界面的引脚列表才会更新。而且删除定义的引脚后,必须使用IO Constraint进行一次保存操作或者自己手动删除文件中弃用的约束设置,否则删除的引脚在约束文件中依旧存在,导致工程报错。
结合前文列出的时钟、按键、LED和用户自定义IO,对相应的管脚进行约束。
完成了模块设计和管脚约束后,对时序要求高的,可以对时序进行约束,本文演示的例子逻辑简单,没有对时序进行相关的约束。
1.8 生成用于下载的Bit文件
TD软件使用手册中的第5章对如何实现HDL2Bit的过程进行详细的描述,简单说分为两步Syn Opt和Phy Opt。Syn Opt 对Verilog或VHLD设计的模块进行综合优化,而Phy Opt结合硬件对设计进行约束和优化。
双击或者右键弹出菜单中点击Run All即可完成bit文件的生成。生成的bits文件位于工程的project\project_Runs\phy_1目录下。在左侧的Design Summary中可以参看设计消耗的资源数,以及引脚约束和时序约束的报告。
使用ANFPGA-LINK可以将编译好的bits文件下载到FPGA中,调试器与FPGA的连接如图所示,调试器指示等为绿,表示可以正常工作。第一次使用时需要安装驱动,具体的操作办法可以参考TD软件使用手册的9.7USB下载驱动安装
1.9 程序的演示
下面的视频对示例程序进行演示
视频后半部分为在用户IO直接输出板上时钟源信号得到波形,FFT频谱上显示的频率成分在25MHz附近,符合预期,之前有一次是可以直接采集并测量出25MHz的时钟信号,但是后面就不行了,同时,使用PLL产生的时钟在用户IO输出时,采样的效果也不好,可能与线材和设备的采样速率、带宽有关。
到此,这是TD软件创建工程、使用IP核生成PLL并例化以及流水灯的介绍。
1.10
官方的文档有很长时间没有更新了,在操作过程中遇到的一些细节会有所不同,让人感觉很疑惑,看过之前坛友发的帖子,解决了很多疑惑,感谢论坛大佬们@qinyunti的探索。
过往贴子:
【国产FPGA评测】安路(型号SF1S60CG121I) 01开发板开箱及开发环境搭建 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)
本帖最后由 EPTmachine 于 2023-3-8 00:24 编辑
TD软件使用手册
示例程序
引用: Jacktang 发表于 2023-3-12 09:58 分辨出LED的状态翻转,设计了一个时钟分频器,可以实现任意整数的分频,分频模块的这段代码是楼主自己写的 ...
是参考网上的程序写的
Jacktang 发表于 2023-3-12 09:58 分辨出LED的状态翻转,设计了一个时钟分频器,可以实现任意整数的分频,分频模块的这段代码是楼主自己写的 ...
程序连接 5._时钟分频