1、LED 灯结构组成
LED 灯(发光二极管)是一种半导体光源,主要结构包括以下部分:
外壳: 通常由塑料或玻璃制成,用于保护内部元件。
发光材料: LED 最核心的部分,由特殊半导体材料制成,例如:常见的 InGaN(氮化铟镓)或 AlInGaP(铝铟镓磷)。
芯片: 用于产生光的发光二极管芯片。
引线: 提供电连接的金属引线。
焊点: 将LED 芯片与引线连接在一起的焊接点。
电极: 负责连接半导体材料与外部电路,通常由金属制成。
反射腔: 用于增强发光效果的一个结构,将发出的光反射到正面。
2、LED 灯发光原理
LED(发光二极管)发光原理基于半导体特性。在半导体中,存在着两类载流子:电子( n 型半导体)和空穴( p 型半导体)。当 n 型与 p 型半导体材料接触时,会在交界处形成一个层结。当施加适当的电压时,层结中空穴和电子可重组并释放能量。这个能量以光子的形式释放出来,产生光。
3、LED 灯驱动原理
LED 驱动指的是通过稳定的电源为 LED 提供合适的电流和电压,使其正常工作点亮。LED 驱动方式主要有恒流和恒压两种。限定电流的恒流驱动是最常见的方式,因为 LED 灯对电流敏感,电流大于其额定值可能导致损坏。恒流驱动保证了稳定的电流,从而确保了 LED 安全。 LED 灯的驱动比较简单,只需要给将对应的正负极接到单片机的正负极即可驱动。LED 的接法也分有两种,灌入电流和输出电流。
灌入电流指的是 LED 的供电电流是由外部提供电流,将电流灌入我们的 FPGA ;风险是当外部电源出现变化时,会导致 FPGA 的引脚烧坏。
输出电流指的是由 FPGA 提供电压电流,将电流输出给LED;如果使用 FPGA 的 GPIO 直接驱动 LED,则驱动能力较弱,可能无法提供足够的电流驱动 LED。
需要注意的 是 LED 灯的颜色不同,对应的电压也不同。电流不可过大,通常需要接入220欧姆到10K欧姆左右的限流电阻,限流电阻的阻值越大,LED的亮度越暗。
4、RGB 灯原理图
逻辑派使用的共阳RGB灯的工作原理与普通LED灯相似,只是将三个普通LED灯的阳极连接在一起,形成了共阳RGB灯;相对应的,共阴RGB灯则是将三个LED的阴极连接在一起。
原理图中,电源 3V3 连接到LED灯的正极,而LED的负极则通过一个限流电阻连接到FPGA的引脚。通过LED灯的驱动原理可以知道,只要控制FPGA的负极引脚输出低电平,就可以点亮对应的LED灯:
5、实战任务
以 0.5S 的间隔进行交替闪烁。
6、系统框图
在本次实验中,我们需要实现一个交替闪烁的效果,使用两个LED灯,每隔0.5秒切换状态。为此,我们将模块命名为 led_light
。流水灯的时间间隔将通过计数器控制,计数器利用外部 50Mhz 晶振时钟来实现精确计时。此外,系统复位功能也很重要,以便在程序出现异常时能将系统恢复到初始状态。
因此,本实验需要两个输入端口:系统时钟 sys_clk 和系统复位信号 sys_rst_n,输出端口为两个LED灯(分别为 LED0 和 LED1 ),模块框图如下图所示:
7、时序图
时序图对于 FPGA 至关重要,因为它帮助设计师了解信号的变化与时钟周期之间的关系。通过时序图,设计师可以确保不同信号在FPGA内部正确地同步,避免时序冲突和数据错误,从而保证电路的稳定性和功能的正确性。
系统时钟 sys_clk 的时钟周期为 20ns(对应开发板板载的晶振频率为 50MHz),计数器计时 0.5s 需要 500000000ns/20ns = 25_000_000 个时钟周期,由于计数器是从 0 开始计数,所以计数器最大计数到 25000000-1,刚好是 0.5s。
8、软件编写
8.1 新建工程
首先我们需要创建 Gowin 文件夹里面创建一个文件夹名叫 led_light ,再在这个文件夹里面创建几个子文件夹,如下图所示:
打开 Gowin 软件,然后新建一个工程,我们可以通过创建工程向导的方式来创建工程;工程建立完成后,我们需要新建一个 Verilog 文件,然后我们将设计的代码写入到新建的 Verilog 顶层文件中,并对工程进行配置,编译等,步骤如下:
首先打开高云的软件,点击新建工程,后会弹出下示对话框,点击 OK 按钮:如下图所示:
接下来就会出现一个工程向导,如下图所示:
注: Name 为工程名字。
Create in 为工程路径(工程路径不能包含中文、空格或者其它一些特殊的符号,尽量使用英文、数字和下划线,否则工程会创建失败,在Windows系统路径长度限制为260个字符)
创建完毕之后就可以点击 Next 按钮进行下一步,接下来是芯片类型的选择,如下图所示:
名称的含义:
Series: | 芯片系列,我们这里选择 GW2A |
Package: | 芯片的封装类型,我们这里选择 PBGA256 |
Device: | 器件类型,我们这里选择 GW2A-18 |
Speed: | 芯片速度等级,我们这里选择 C8/I7 |
Device Version: | 器件版本,我们这里选择 C |
Part Number: | 芯片型号,该栏会显示所选择器件的详细资源信息 |
我们在 Filter 中选择的系列、封装、器件、速度等级和版本,都会在下面匹配出唯一的型号,点击选择你手中开发板的型号,选择信息如下图所示:
然后进行下一步,在 Summary 中软件会将我们新建的 FPGA 工程信息做有一个汇总,方便我们查看有没有点错的地方,如下图所示:
我们直接点击 Finish 按钮完成工程的创建,工程创建完成后,就进入了高云的工程主界,如下图所示:
Gowin 工程的子窗口说明:
1、菜单栏:提供一些工具,包括File、Edit、Project、Tools、Window和Help选项。
2、工具栏:提供一下常用功能,如新建工程、打开工程、保存工程等。
3,工程管理区(Design):提供工程及其相关文件的管理和显示功能,显示或编辑工程所用器件信息、用户设计文件、用户设计约束文件以及配置文件等。
4、过程管理区(Process) :提供用户 FPGA 设计流程,包括综合(Synthesize)、布局布线(Place& Route)以及编程器件(Programer),同时可双击启动时序约束和物理约 束工具进行约束文件编辑。
5、设计层级显示区(Hierarchy):加载设计文件后,软件会先对设计文件进行解析,Hierarchy 窗口会显示当前工程的设计层级关系。通过 Hierarchy 窗口可以定位某个 module 的 定义以及实例化在设计文件中的位置,还可以将某个 module 设为 top module。在 Hierarchy 窗口中,Unit 列显示设计文件的 module 层级结构,Files 列显示 module 定义所在的文件。目前 Hierarchy 已支持对 Verilog 语言、VHDL 语言以及 System Verilog 语言的解析。
6、工程信息显示区:提供工程路径信息显示和所选择的器件信息的显示功能。
7、信息输出区:显示软件在运行过程中的处理信息, 配合下面2个的可手动切换标签页查看不同类型的输出信息。
8、Tcl 命令编辑区:在窗口中输入 Tcl 命令后通过回车键来执行相关命令。
9、全部输出信息显示区(Console 选项):包括 Tcl 命令窗口、 警告信息、 错误信息等。
10、输出信息分类汇总区(Message 选项):包括 Note 信息、 警告信息、 错误信息。
注:详细请查看官网的Gowin文档(链接:https://cdn.gowinsemi.com.cn/SUG100-4.1_Gowin云源软件用户指南.pdf)
接下来我们该进行工程文件的添加了在 工程管理区 空白处 右击选择 New File... 如下图所示:
会弹出新建文件的的对话框,如下图所示:
选择创建 Verilog File 文件,选择 OK 按钮,接下来该对这个新建的 Verilog 文件进行命名,命名完毕后选择 OK 按钮,如下图所示:
注:Name 为工程名字,这里我们命名为 led_light ,其后面名是 .v 这个是默认的不用管。
Create in 为Verilog文件路径,保持默认。
点击 OK 按钮后软件自动我我们打开 led_light.v 的 Verilog 文件的编写窗口了,接下来大家跟着我在 led_light.v 里面写我们的闪烁例程,程序如下所示:
module led_light(
input sys_clk, //全局系统时钟
input sys_rst_n, //全局系统复位,低电平有效
output reg [1:0] led //LED 灯状态输出
);
reg [25:0] count; //计数器
parameter Scends = 50_000_000; // 1S 所需的脉冲,时钟频率为50MHz
//定时 1 S
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
count <= 26'd0; // 如果复位,计数器清零
else if(count < Scends - 26'd1 )
count <= count +26'd1; //如果时间没到定时1S,则计数器加一
else
count <= 26'd0; // 计数到达设定值后清零
end
//LED 输出
always @(*) begin
if(!sys_rst_n)
led <= 2'b00; // 如果复位,LED 状态为 00
else if(count < Scends / 2 )
led <= 2'b01; // 在计数器的前半段,LED 状态为 01
else
led <= 2'b10; // 在计数器的后半段,LED状态为 10
end
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
led_light 模块详解:
第 1 行和第 34 行是 Verilog 语言中模块定义的标准语句,分别表示模块的开始和结束。第 1 行 module 后的 led_light() 是模块名称,它应与 Verilog 工程的命名保持一致。
第 2 行:clk 表示本模块的时钟信号。如果前缀为 sys 则表示这是全局时钟,即整个工程的时钟由此信号提供。时钟信号如同数字电路的心脏,提供脉动以控制信号的变化,确保各个模块的同步和协调运行
第 3 行:rst 的全称是 Reset ,在 RAM 、FAPG 中 Reset 代表重置信号,用于将系统或电路恢复到初始状态。如果前面加上 sys 则表示全局复位,也就是整个工程的复位都由它靠它。在 Verilog 代码中,加 _n 表示低电平有效,即当 sys_rst_n 为低电平(0)时,系统会被复位。
第 5 行:定义一个 2 位宽的输出端口 led。
第 9 行:定义了一个 26 位的寄存器 count,用于计数系统时钟的脉冲数量(即计数器的值),从而实现定时功能。count 用于计数,从而精确控制 LED 的闪烁频率,确保其按照预定节奏进行闪烁。
第 10 行:定义一个常量参数,你可以在设计中使用一个名称来引用一个值,并且只需要在一个地方修改它的定义即可更新整个设计中使用到这个值的所有地方。这种方法提高了代码的可维护性和可读性。
第 14 ~ 21 行:在 sys_clk 的上升沿或 sys_rst_n 的下降沿触发时,计数器 count 会在达到预设值后自动清零,并重新开始计数。如果 sys_rst_n 为低电平(表示复位状态),则 count 会立即清零并重新启动计数过程。
第 24 ~ 32 行:* 为通配符,表示只要 if 或 else 括号中的条件,则立即执行下面的代码。在任何时刻 count 小于 (Scends / 2) - 26'd1 ,led0 被点亮;否则,led1 被点亮。这样,LED 将以 0.5 秒的间隔交替闪烁。
接下来我们回到 led_light.v 的编辑窗口,此时需要点击工具栏中的保存按钮(左边的是仅保存当前文件,右边的是保存所有文件)或者按下键盘的 Ctrl+S ,来保存编辑后的代码,如下图所示:
保存成功后保存按钮会变灰色, led_light.v 文件的 * 也会消失。
接下来我们就要验证代码是否正确,我们可以在过程管理窗口 Process -> Synthesize 右击 -> Run 来验证语法是否正确,接下来我们对工程进行语法检查,右击过程管理窗口窗口中的 Synthesize -> Run ,如下图所示:
工程在编译文件过程中没有错误,则 Synthesize 前会有一个 √ ,否则就会在 Messages 栏中显示 errors 的错误。如图所示,包括各种 Warning 和 Error 。 其中 Error 是重点关注对象。
可以看出,我们点亮 LED 的代码并没有产生错误和警告提示。
8.2、Modelsim 仿真
接下来我们需要使用 Gowin 来创建编写仿真文件。首先在工程管理区 空白处 右击选择 New File... :会弹出新建文件的的对话框,选择创建 Verilog File 文件,选择 OK 按钮,将新建的 Verilog 文件命名为 led_mod.v,需要更改其路径(Gowin\led_light\sim) led_light_mod.v 如下图所示:
接下来大家跟着我 led_light_mod.v 里面写我们的仿真例程,程序如下所示:
`timescale 1ns/1ns // 时间尺度预编译指令:时间单位/时间精度
// 第一个 1ns 是时间单位(每个时间单位表示 1 纳秒)。
// 第二个 1ns 是时间精度(时间精度决定了仿真时间的分辨率,也就是说,模拟器能区分的最小时间间隔为 1 纳秒)。
module led_light_mod(); // 定义测试模块
// reg define
reg sys_clk; // 定义仿真文件全局时钟信号
reg sys_rst_n; // 定义仿真文件全局复位信号,下降沿有效
// wire define
wire [1:0] led; // 定义仿真文件的 LED 端口,使用 2 位宽度
always #10 sys_clk = ~sys_clk; // 每 10ns 反转一次 sys_clk 的值
initial begin
sys_clk = 1'd0; // 初始时钟状态为高电平
sys_rst_n = 1'd0; // 将复位信号拉低(有效复位)
#200; // 延时 200ns
sys_rst_n = 1'd1; // 将复位信号拉高(复位结束)
#200; // 延时 200ns
end
// 实例化
led_light u_led_light(
.sys_clk(sys_clk), // 将仿真文件的 sys_clk 连接到被测模块的时钟输入
.sys_rst_n(sys_rst_n), // 将仿真文件的复位信号连接到被测模块的复位输入
.led(led) // 将被测模块的 LED 输出连接到仿真文件的 LED 端口
);
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
仿真模块详解:
第 1 行 :时间尺度预编译指令 时间单位/时间精度,第一个 1ns 是时间单位,第二个 1ns 是时间精度。
第 7 - 12 行:这里就是 led_light 文件里面需要的一些信号。
第 14 行: 初始化是将 sys_clk 的信号先拉高,每 10 ns 再将 sys_clk 进行翻转。
第 21-28 行: 将复位信号 和 时钟 拉低,延时 200ns ,再复位信号拉高后,在延时 200ns 开始仿真。确保仿真前信号都是最初的状态。
第 25 - 29 行:将仿真文件和 led_light 进行引脚绑定。
保存文件后,我们将点击 led_light.v 文件,做修改(目的:减少仿真时间,让波形更短方便我们查看),如下图所示:
接下来我们就该将我们的仿真文件进行使能或者删除在目录中。让它无法参与高云 Gowin 的编译当中来,首先我们选中 led_light_mod.v 这个文件,然后鼠标右键 -> Remove.... ,(如果需要修改此文件,我建议尽量使能)如下图所示:
选中完毕后,点击 OK 按键,即可,如下图所示:
我们就该验证搭建的 Modelsim 环境,打开 Modelsim 软件,在 Modelsim 建立一个新的 project 。选择 “File -> New -> project”,如下图所示:
进入新工程的设置界面,在 Project Name 一栏中填写工程名。这里我们把工程命名为相对应的工程名 led_light ,Project Location 是工程路径,点击 Browse 进行设置,根据需要我们把仿真工程保存到我们设计工程下,找到 sim 文件夹并选择,如下图所示:
在点击 OK 之后,出现如下图所示的界面,从图中可以看出,有四种操作可以选择:Create New File(创建新文件)、Add Existing File(添加已有文件)、Create Simulation(创建仿真)和 Create New Floder(创建新文件夹),我们这里选择 Add Existing File 。
在弹出的对话框中,选择 Browse 选择本次实验需要分别添加的工程设计文件 led_light.v 、led_light_mod.v 。
首先添加,led_light_mod.v 如下图所示:
接下来添加,led_light.v 如下图所示:
添加完成之后,可以在 Modelsim 软件中看到我们添加的工程文件,如下图所示:
接下来就是编译仿真文件,编译的方式有两种:第一种 Compile Selected(编译所选文件),编译所选文件功能需要先选中一个或几个文件,执行命令之后可以完成对选中文件的编译;第二种是 Compile All(编译全部文件),该命令是按编译顺序对工程中的所有文件进行编译。这里,我们选择编译所有文件,选择 Compile->Compile All ,如下图所示:
在 project 状态栏中找一个空白地方,右键点击,然后选择 Add to Project -> Simulation Configuration… 并点击,如下图所示:
进入 Add Simulation Configuration 页面,我们在 Design 标签页面找到并选择中 led_light 库中的 led_light_mod 模块作为设计顶层,接下来点击 Optimization Options… ,如下图所示:
进入弹出 Optimization Options..子窗口中选择 Apply full visibility to all modules(full debug module) ,点击 OK ,如下图所示:
将 Design Unit(S) 的名字复制到,Simulation Configuration Name 框中,确保命名保持一致,如下图所示:
首先点击 libraries 设置栏,在 Search libraries(-L) 一栏中点击 Add… 添加我们新建的高云的库文件 GW2A ,然后点击 OK 确认,如下图所示:
Search Libraries First(-Lf) 也和上面操作一样,然后点击 OK 确认,再点击 Save 保存设置,如下图所示:
接下来双击新生成的仿真文件 led_light_mod ,如下图所示:
进入 sim 界面,如下图所示。
在 sim 界面我们可以添加我们想要观察模块的波形,选中模块,右键点击选择 Add Wave ,如下图所示:
添加好波形后回到 Library 栏 -> 右键单击 led_light -> 点击 Update ,将 led_light_mod 文件更新在 led_light 项目下面,如下图所示。
点击 Run all,开始跑仿真,如下图所示:
注:有些同学的波形显示面板在最右边可以拉过来,如下图所示:
此时点击 Zoom Full 可以快速观察到波形
在开发过程中,在更改设计文件后,点击保存并检查语法无误后重新运行程序。在 Modelsim 中,我们进入 Library 界面,在 Work 目录下对 led_top.v 和 led_light.v 进行重新 Recompile ,重新进行仿真波形的加载。
在波形图界面,按住 Ctrl + 鼠标滑轮 进行缩放,这个时候你会发现,count 的计数器是 16 进制,怎么转变为 10 进制,如下图所示:
接下来,我们观察仿真波形发现,当 count 在 0 ~ 24 之间时,LED0 为高电平,而在 24 ~ 49 之间,LED1 为高电平。接下来,我们需要检查仿真文件中的代码,分析是否存在和我们仿真文件相差点,仿真代码如下图所示:
count 在 0 ~ 24 时,仿真图如下图所示:
count
在 24 ~ 49 时,仿真图如下图所示:
根据仿真结果,当 count 在 0 ~ 24 时,LED0 处于高电平,而当 count 在 24 ~ 49 之间时,LED1 处于高电平。这表明 led_light 程序在实现这些功能方面符合最初的设计要求和想法,因此程序没有错误。
到此我们的 Modelsim 仿真验证就完成了
8.3、I/O 绑定
接下来就该是分配 FPGA 的 LED 的 I/O 引脚,一共有3种方法,第一种点击菜单栏Tools -> FloorPlanner 如下图所示:
方法二:过程管理窗口 Process -> User Constratints > FloorPlanner > 右击选择 Run 如下图所示:
方法三:工具栏找到可以找到 FloorPlanner 图标,如下图所示:
点击 FloorPlanner 后会转跳到如下图所示界面。如果没有创建 CST 文件,会提示创建,这里选择 OK 按钮:
接下来跳转到 FloorPlanner 选项卡。如下图所示:
在该窗口选择 I/O Constraints ,开始分配 I/O 口,如下图所示:
首先来介绍这个 I/O 分配的选项:
Port 列: 用于描述 port 的名字
Direction 列: 显示 I/O 类型 input、output、inout
Different Pair 列: 差分对
Location 列: 约束的管脚
BANK 列: 该管脚所在的 bank
Exclusive 列: 专属引脚
IO Type 列: 设置电平标准
Drive 列: 设置驱动电压
Pull Mode 列: 设置上拉模式
PCI Clamp 列: 设置 PCI 协议开关
Hysteresis 列: 设置迟滞量
Open Drain 列: 设置开漏电路的开关
Vref 列: 设置外部参考电压
Single Resistor 列: 设置单端电阻的开关
Diff Resistorl 列: 设置差分电阻开关
Bank Vccio 列: 设置 Bank 电压
注:详细请查看官网的Gowin文档(链接:https://cdn.gowinsemi.com.cn/SUG935-1.4.3_Gowin设计物理约束用户指南.pdf)
接下来就该查看 逻辑派 的原理图了,看看我们的复位、晶振时钟、LED用到了那个 I/O 口上。
晶振时钟电路,如下图所示:
复位电路,如下图所示:
LED 电路,如下图所示(LED暂时用红框里面的引脚):
接下来我们该确定该引脚使用的 BANK 电源是多少,如下图所示
由上面的原理图可知,所需引脚如下表所示:
信号 | 方向 | 引脚 | 端口作用 | 电平标准 |
---|---|---|---|---|
sys_clk | input | T7 | 时钟 | LVCMOS33 |
sys_rst_n | input | F10 | 复位 | LVCMOS33 |
led[0] | output | R9 | LED0 | LVCMOS33 |
led[1] | output | N6 | LED1 | LVCMOS33 |
接下来我们可以根据上面表格进行管脚约束。约束完毕如下图所示:
引脚约束完成后,我们进行保存设置,如下图所示:
保持完毕之后我们,回到 Gowin 工程软件窗口,会发现在 Design
子窗口中会生成一个后缀为 .cst
的文件,这就是我们的管脚约束文件。如下图所示:
8.4、时钟约束
时钟约束在 FPGA 设计中至关重要,因为它确保了信号在时钟周期内的稳定性和可靠性。它帮助确定时钟的频率、相位、延迟和数据保持时间,确保设计在实际硬件上能够按预期工作,避免时序违例和数据丢失,从而实现系统的最终性能和稳定性。
接下来我将带领大家怎么去创建时序约束文件,一共有 3 种方法。
方法一:Tools -> Timing Constraints Editor 如图所示:
方法二:过程管理窗口 Process -> User Constratints > Timing Constraints Editor > 右击选择 Run
如下图所示
方法三:工具栏找到可以找到 Timing Constraints Editor 图标,如下图所示:
会生成一个 .sdc 时序约束文件,点击 OK 按钮,如下图所示:
接下来我们依次点击 led_light > Ports(4) > 右键 sys_clk(input) > Add Clock 完成后,如下图所示:
点击后会弹出一个时钟约束的界面,填完相应数据后点击 OK ,如下图所示:
Clock name: 时钟名称,用于为所创建的时钟约束命名。
Period: 周期,系统时钟为 50MHz(即一个时钟周期为 20ns),占空比为 50%,则Period 设置为20。
Frequency: 频率。
Rising 和 Falling: 表示时钟上升沿和下降沿所在的时间。
注:Rising 设置为 0, Falling 设置为 10 表示时钟上升沿在 0ns 处,下降沿在 10ns 处。
并保存该文件,如下图所示:
时钟约束完毕之后,我们还需要修改一下程序代码,将Scends 改回 50_000_000,如下图所示:
接下来在过程管理窗口 Process > Place & Route > Run,来对代码布局布线进行综合,如下图所示:
综合完毕之后 ,会在则 Place & Route 前会有一个 √ 如下图所示:
综合完毕之后会生成的四种报告文件,包括布局布线报告(Place & RouteReport)、 时序分析报告(Timing Analysis Report)、 端口属性报告(Ports & Pins Report) 及功耗分析报告(Power AnalysisReport)。
我们接下来看看我们的LED程序生成的电路图,点击菜单栏 Tools > Schematic Viewer > RTLDesignViewer 如下图所示:
接下来我们就可以看到代码综合后生成的电路图,你们可以自行放大查看,如下图所示:
到此小伙伴可以先下载程序试试,或者继续往下走。
8.5、Gao 在线逻辑分析仪
GAO 在线逻辑分析仪是高云半导体自主研发的数字信号分析工具。它能快速进行系统分析和故障定位,从而提高设计效率,也是我们实际开发中不可缺少的一部分。
在启动 GAO 配置文件窗口之前,需在工程管理区新建 GAO 配置文件,如下图所示:
弹出 New GAO Wizard 对话框,这里我们保持默认不变,如下图所示:
注:Type一栏中有两种选项:
For RTL Design: 用于捕获综合优化前 RTL 信号,生成配置文件扩展名.rao
For Post-Synthesis Netlist: 用于捕获综合优化后 Netlist 信号,生成配置文件扩展.gao
Mode一栏也有两种选项:
Standard: 是标准版,最多可以支持 16 个功能内核,每个内核可配置一个或多个触发端口,支持多级静态或动态触发表达式。
Lite: 是精简版,无需设置触发条件,可以捕获信号的初始值,方便用户分析上电瞬间的工作状态。
注:详细请查看官网的Gowin文档(链接:https://cdn.gowinsemi.com.cn/SUG100-4.1.1_Gowin云源软件用户指南.pdf )
然后在弹出的窗口中的 Name 编辑框中输入配置文件名称,默认和工程名保持一致,这里按照默认名称,单击 Next 按钮,如下所示。
最后弹出 Summary 对话框,点击 Finish 完成 GAO 文件的建立,如下图所示:
GAO 文件建立完成之后,将会在 Design -> GAO Config Files -> src\led_light.rao ,双击进入 GAO 配置窗口,如下图所示:
如果在双击 .gao
文件的时候,出现如下图警告,需要我们先分析综合 Synthesize
之后,然后再双击 Design -> GAO Config Files -> src\led_light.rao1
文件进入 GAO
配置窗口。
GAO
配置窗口包括配置功能内核数量的和对应 Core
的信号配置视图,其中 Core
信号配置视图包括配置信号触发条件的 Trigger Options 视图和配置信号采样条件的 Captrue Options 视图
注:
Ao Core:
功能内核数量。
Core:
信号配置视图包括配置信号触发条件的 Trigger Options 视图和配置信号采样条件的 Captrue Options 视图。
Match Units:
设置触发条件,可以设置多个,共计16个;(M0——M15)
Expressions:
设置前面的M0—M15的组合关系,可以使用任意一个,也可以使用几个进行逻辑组合来使用触发条件,这一点比较不错。
Core 0 的 Trigger Ports 视图下用于配置功能内核触发端口,可以看到一共有 16 个触发端口,我们使用Trigger Port 0,双击之后,进入端口配置界面 Trigger Port,如下图所示,图中的 MSB 和 LSB 分别表示触发端口的高位与低位。
我们这里点击 +
添加,如下图所示:
进入 Search Nets 对话框,在 Name 一栏中输入你想要添加的触发方式,我们这次实验想要观察 LED 灯的状态信号 led,输入 led ,然后点击搜索,如下图所示:
然后回到 Trigger Port 点击 OK ,如下图所示:(如果说添加某个信号不想要了,可以先选择信号,然后点击那个 -`,将添加错了的信号就被删除)
这里我们选择 M0,双击,在弹出的 Match Unit Config 对话框中对触发条件进行配置,如下图所示:
接下来单击 On Trigger Port 下拉框,在下拉列表中选择触发端口 Trigger Port 0 。
在 Match Type 和 Function 的下拉列表中,可进行匹配类型的选择,详细信息如下:
注:详细请查看官网的Gowin文档(链接:https://cdn.gowinsemi.com.cn/SUG114.pdf )
Match Unit Config 对话框中各项配置用户可以根据自己的需求进行配置,这里我们 Function 改为 != ,然后点击 OK ,如下图所示:
在 Expressions 栏任意空白处,双击 ,弹出 Expression 对话框,如下图所示:
由于只有一个触发匹配单元 M0,点击 M0 ,然后点击 OK 即可,如下图所示:
添加完成之后,如下图所示,用户可以双击 M0 进行修改。
点击 Capture Options 进入采样信号配置视图,如下图所示:
注:
Sample Clock: 为输入采样时钟信号的名称;
Storage Size: 存储深度,即允许的数据采样存储器地址长度。
Segments Number: 采集分段数目,即采集缓冲区的分段数目。功能内核采用分段采集模式。
Capture Amount: 采样长度,即每个采集缓冲区分段实际使用的采样存储器的地址长度。
GAO Implementation: GAO 实现方式,即采样信号数据的存储方式。
Trigger Position: 触发点位置,即触发时所采样数据在存储器地址中的位置。
Capture Initial Data: 用于在上电或复位之后但在手动启动 GAO 之前发生的触发事件。
Force Trigger by Falling Edge: 用于改善 TCK 的时序,默认状态为不勾选。
注:详细请查看官网的Gowin文档(链接:https://cdn.gowinsemi.com.cn/SUG114.pdf )
接下来,我们开始配置采样时钟 SampleClock 栏 -> Clock,点击 Clock 后的 进入 Search Nets 界面,在文件框中直接输入采样时钟 sys_clk,然后点击搜索,进行添加,如下图所示:
然后存储深度 Storage Size 和 采样长度 Capture Amount 都为 4096,采集窗口数目 1 个,触发点位置为 0 ,数据的存储方式为 BSRAM ,如下图所示:
注:存储深即允许的数据采样的存储器地址长度,采样长度,即每个采集缓冲区页面实际使用的采样存储器的地址长度,采样长度不能超过设置的存储深度。
例如存储深度为 4096 ,采样长度为 1024 ,这样实际抓取时采样的数据个数就是 1024 个,通常设置时,我们将存储深度和采样深度设置一致。
选择采样的数据信号,点击 Add 按钮,然后弹出 Search Nets 对话框,这里我们添加 count[25:0] 信号进行观察,如下图所示:
接下来我们点击 Add From Trigger ,添加我们的采样触发信号作为采样数据信号,如下所示:
至此,GAO 文件就配置完成了,Ctrl+S 保存,保存过程中没有报错,则代表配置没有出现错误,如果出现错误,请检查自己的步骤是否完整,是不是哪个环节漏掉了,或者配置出错。
在此之前我们还需要重新将我们的 led_light.v 的文件做一点小小的改动,有些小伙伴多半已经猜到了,那就是将 Scends 改为 50 ,这样方便我们观察仿真(记得保存哦~),如下图所示:
接下来点击 Process -> Synthesize 右击 -> Run 编译,还要一步点击 Process -> Place & Route 右击 -> Run来综合整个工程,综合完之后都由一个绿色 √
,表示工程整体没有错误。
然后点击工具栏中的 Tools -> Gowin Analyzer Oscilloscope ,进入高云在线逻辑分析界面,如下图所示:
进入高云在线逻辑分析界面前需要将 逻辑派 ,连接好下载器和电源,再点击进入,如下图所示:
差个图
我们进入是 Cable 一定要选择 Gowin USB Cable(FT2CH)。如果不是,仿真会一直不触发,从而导致波形一直不显示,
注:由于电脑驱动不同可能存在端口识别有差异,可能识别到端口0或者端口1,如果下载不成功,可以切换端口试试。如下图所示:
然后我们开始在仿真软件界面下载程序,首先将 Enable Programmer 前打钩,如下图所示:
接下来,我们开始下载程序,点击红框里面的按钮,如下图所示:
下载完成之后,上面会出现一个绿色的 Ready to acquire ,Output 窗口也没有出现红色字,这表示我们的下载程序到 FPGA 的 SRAM Program 里面,如下图所示:
接下来,我们开始仿真,点击开启 GAO 捕捉,如下图所示:
等待一会就会弹出波形图,首先我们将 count 的数据转为 10进制 显示, 首先 选择 count[25:0] -> Format -> Usigned Decimal ,如下图所示:
按住 Ctrl + 鼠标滑轮 进行缩放,可以看出来再仿真结果是,当 count 在 0 ~ 24 时,LED0 处于高电平,而当 count 在 24 ~ 49 之间时,LED1 处于高电平。
count 在 0 ~ 24 时,仿真图如下图所示:
count 在 24 ~ 49 时,仿真图如下图所示:
根据这 2 张图来看和我们的仿真结果一摸一样的证明我们的下载到 FPGA 的程序是没有问题。
8.6、程序固化
因为我们的程序存储在 SRAM 中,而 SRAM 存储电容会逐渐丧失电荷,导致数据逐渐消失。为了解决这个问题,大多数 FPGA 会通过外部 Flash 等方式来固化程序(如果有学过其他 FPGA 就知道),确保数据的长期保存。接下来,我将介绍如何将程序固化到外部 Flash 中。
首先我们先得将之前在 led_light.v 文件中的内容改回之前的状态,如下图所示:
接下来点击 Process -> Synthesize 右击 -> Run 编译,还要一步点击 Process -> Place & Route 右击 -> 选择 Run 来综合整个工程,如下图所示:
前面布局布线完成后已经生成了码流文件文件,接下来点击工程管理区 Design 中的 右击 Programmer -> 选择 Run,如下图所示:
点击 Run 按钮之后,会弹出下载界面,如下图所示:
点击保存后,进入下载界面,蓝框是选择下载码流文件的地方,红色框框中的 .FS 后缀结尾文件的就是下载的码流文件,如下图所示:
双击 SRAM Program (蓝色框框)选项卡,会弹出 Device configuration 窗口,如下图所示:
Access Mode: 选择设备的编程模式;这里选择 External Flash Mode。
Operation: 选择设备编程操作;先擦除外部 Flash,然后将数据写入外部 Flash。
File name: 选择编程数据文件(就是你的 .fs 码流文件的路径)。
Device: 选择外部 Flash 型号,这里直接保持默认。
Start Address: 选择外部 Flash 起始地址,这里直接保持默认。
接下来,点击 Save 保存按钮,再点击下载,如下所示:
文件写到 Flash 需要较长的时间,等待窗口的进度条拉满到达 100%,回到下载界面,自此程序固化到外部 Flash 就完成。如下图所示:
当我们重新上电后,两个 LED 重新的地来回亮灭~
至此,我们的工程创建和程序固化就完成,希望大家能够多多练习。