FPGA学习笔记【基础概念】

基础概念

Xilinx系FPGA使用vivado全家桶进行开发

性价比/低功耗:Spartan系列,常见Spartan-6、Spartan-7

中端/性价比:Artix系列,常见Artix-6、Artix-7

中高端:Kintex系列,常见Kintex-7

旗舰:Virtex系列,常见Virtex-7

命名规则:以Spartan-7 xc7s15ftgb196-1为例

用途级别 哪一代产品 逻辑单元数 封装类型 RoHS 封装元件号 引脚数 速度等级
xc 7 15 ft g b 196 -1
商业级 第7代 15k个逻辑单元(单位为k) 1mm 6/6 共196引脚 慢速

速度等级如下

-1 -L1 -L2 -2 -3
慢速 慢速低功耗 中等速度低功耗 中等速度 高速

FPGA内部资源简介

常用可编程逻辑器件:

  • CPLD:复杂可编程逻辑器件。基于乘积项的与或逻辑阵列,基于FLASH运行,逻辑写入后会一直保存,掉电不丢失
  • FPGA:现场可编程门阵列。基于查找表的CLB阵列,基于SRAM运行,采用CMOS工艺制造,逻辑写入后需要上电才能保存,掉电丢失

这两种器件都只能编程数字电路,无法在其上建立模拟电路

FPGA的编程数据实际上存储在其中的SRAM里,运行时将数据读出配置好片上硬件资源运行;很多FPGA会配有单独的PROM,在运行时先将PROM读入片内RAM,配置完成后,FPGA开始工作;掉电后FPGA内部逻辑关系清空

FPGA可以反复使用,一块Artix传祖孙三代天天用都不成问题;如果使用外接PROM的方法,FPGA的编程不需要专用的FPGA编程器,只要用通用的PROM编程器编程即可

FPGA内部一般有以下硬件资源:

  • 可编程逻辑单元(Xilinx制造的FPGA中将其称为CLB可编程逻辑块,由多个基本的LUT查找表、REG寄存器、MUX多路选择器组成)
  • 可编程IO单元(用于可编程逻辑与外部引脚的连接)
  • 底层嵌入功能单元(包括但不限于PLL、ADC等数字/模拟电路器件)
  • 嵌入式块RAM(用于存储内部数据和可编程的硬件逻辑)
  • 布线资源(将各个功能模块之间连接起来)
  • 硬核(只有一部分FPGA才会嵌入,一般功能比较专用)

其中CLB是组成FPGA的基本逻辑单元LUT则是FPGA中逻辑表达式的基础

常用电路结构

FPGA不擅长顺序结构,更擅长并行结构,如果要使用FPGA处理顺序结构的算法,比较常用有限状态机模型(FSM)

有限状态机FSM(Finite State Machine)

有限状态机:在有限个状态之间按一定规律转换的时序电路

在FPGA中经常使用mealy状态机,它由当前输入和当前状态共同决定其输出

状态机内部使用状态寄存器来存储当前状态:状态寄存器由一组触发器组成,用于记忆状态机当前所处的状态,这个状态的改变一般只发生在时钟信号跳变沿

状态是否改变、如何改变都取决于当前输入和当前状态的组合逻辑F(F是当前状态和输入信号的函数

状态机的输出则由当前输入和当前状态的输出组合逻辑G决定(G也是当前状态和输入信号的函数

组合逻辑F是状态寄存器的激励,当时钟信号跳变时,组合逻辑被读入状态寄存器,同时当前状态被输出到组合逻辑G

输出只取决于当前状态的状态机称为moore状态机

四段论法构建FSM

  1. 定义状态空间

主要任务是构建状态寄存器和输出寄存器

所有状态的集合称为状态空间

使用verilog对状态进行编码,使用一组二进制数表示状态的过程即为定义状态空间

之后应当定义两个reg变量,分别用于存储当前状态和下一个状态;如果需要用到以前的状态,相关变量也应该在这时候进行定义

推荐使用独热码进行编码

parameter a=4'b0001;
parameter a=4'b0010;
parameter a=4'b0100;
parameter a=4'b1000;

reg[3:0] current_state;
reg[3:0] next_state;

注意变量位宽与编码位宽一致

  1. 配置状态跳转规则(时序逻辑)

主要任务是构建组合逻辑G的状态转移部分

一般使用always块配合posedge、negedge进行控制,敏感列表以时钟信号和复位边沿信号的组合进行定义

在块中使用非阻塞赋值来保证电路实时性

  1. 判断下个状态(组合逻辑)

主要任务是构建组合逻辑F的输出部分

使用当前状态和输入信号组成always块的敏感列表

使用case语句通过当前状态的编码筛选出当前状态,在case语句内嵌套if..else...语句,根据输入信号情况为下一状态进行赋值(注意:if和else一定要配对,否则可能产生latch)

在块中使用阻塞赋值来保证电路不会出现时序错误

  1. 设置各个状态下的动作(组合逻辑)

主要任务是构建组合逻辑G的输出寄存器

一般是使用assign语句或always块对动作进行赋值

//使用assign语句
wire output_1;
assign output_1=(current_state == T) ? 1'b0 :1'b1;

//使用always块
wire output_1;
always @(current_state) begin
    if(current_state == T)
        output_1=1'b1;
    else
        output_1=1'b0;
end

不管使用哪种形式都应该以当前状态为基准进行判断

第四个部分搭建的电路相当于在组合输出逻辑G后面再加了一层由clk为控制时钟的同步寄存器,可以将输出逻辑与外部电路隔离

不加第四个部分的电路相当于由三段法构建,加上第四个部分的电路才是完整的四段法状态机

第四个部分的作用如下:

  • 滤除组合逻辑输出的毛刺
  • 更有效地进行时序计算与约束
  • 更容易使总线数据对齐,减小总线数据间偏移(防止总线信号线到达时间的差距),减小接收端数据采样出错的频率

加法器与乘法器

直接在verilog模块中使用普通加法、乘法运算,综合后就可以得到超前进位加法器、乘法器,可以通过设置综合优化项目获取更小面积或更高性能

开发流程

以点灯程序为例

确定设计方向

  1. 设计控制LED的GPIO,引出到外部引脚
  2. 设计计数器,控制1s延时
  3. 系统由50MHz时钟控制
  4. 需要一个复位信号输入

使用vivado开发

vivado是xilinx推出的专用于自家FPGA、SoC的IDE,提供了包括可视化IDE、Tcl脚本、Tcl Shell、IDE内嵌Tcl控制台命令的使用方式。使用流程在vivado界面左端的目录中展示

提供Tcl、AXI4、IP-XACT、Synopsys设计约束(SDC)等业界标准支持,Verilog HDL、VHDL、SystemVerilog三种硬件描述语言的支持,SystemC、C、C++三种软件语言高层次综合(HLS)的支持

vivado中的电路结构网表描述

网表由单元(Ceil)、引脚(Pin)、端口(Port)、网络(Net)组成

单元即设计单元,包括设计模块/实体、元件库中的基本元素(如LUT、FF、RAM、DSP等)、硬件功能的类属技术表示和黑盒

引脚是单元上的连接点

端口是设计的顶层端口

网络类似电路设计中的“节点”,连接引脚、端口

工程数据的目录结构

和其他软件IDE一样,vivado中所有用户工程数据保存在当前工程目录中

vivado将统一的数据模型贯穿于整个设计流程中,使用Design Checkpoint(包含逻辑网表、约束、物理数据)文件对开发进度进行管理,该文件会在开发过程中生成,后缀名为.dcp

项目目录下会包含以下内容

  • 工程名.xpr

    工程设置文件

  • 工程名.run目录

    包含所有运行数据

  • 工程名.srcs目录

    包含所有导入的HDL源文件、网表和XDC文件

    这些是设计过程中主要编写的文件

  • 工程名.data目录

    保存布局规划和网表数据

除此之外,vivado还会生成以下两种文件

  • Journal文件(Vivado.jou)

    只包含Vivado IDE中执行的Tcl命令

    该文件会被保存在用户主目录下(如${HOME}或C:\Users\Administrator\AppData\Roaming\Xilinx\Vivado)

    用这个文件实现类似shell中“记录历史命令”的功能

  • Log文件

    包含Vivado IDE中所产生的所有消息(也会包含Tcl命令和结果、警告/错误信息)

    一般会和Journal文件保存在一起

vivado项目文件夹

一个vivado项目的文件夹通常包含以下几项:

  • .xpr文件:Vivado IDE项目文件
  • .runs目录:包含所有运行数据
  • .srcs目录:包含所有被引用的HDL源文件和约束文件(网表文件、XDC文件等)
  • .data目录:存储和网表数据
  • .xdc目录:单独存储所有约束文件
  • .sim目录:存储所有仿真文件和testbench

Vivado设计模式

  1. 工程模式

    就是上面所说的创建工程-按照左边的流程一点点完成

  2. 非工程模式

    这是基于Tcl脚本的编译风格方法,用户需要自己管理源文件和设计流程

    全部使用Tcl指令运行,可以精确到每一步,会很繁琐但可以精细控制设计过程

XDC文件

Vivado的一个特殊点就是它使用Xilinx设计约束(XDC)格式,不再支持ISE曾使用的用户约束文件(UCF)格式

XDC约束是业界标准Synopsys设计约束(SDC)和Xilinx专有物理约束的组合

XDC文件是遵循Tcl语法的命令,使用vivado内置的Tcl解释器可以直接分析这些命令

特别注意:XDC命令是顺序执行

开发流程

使用外部晶振作为时钟

在高级应用中通常会再写一个分频器或倍频器用于稳定信号或用于控制电路频率

系统设计

外部时钟为50MHz

系统时钟部分

module LED(
    input clk,//外部晶振时钟输入
    input _rst,//复位引脚输入

    output [1:0] led//输出引脚控制LED
);

计数器部分

reg [25:0] counter;//外部时钟50MHz,计时1s,需要26位计数器

always @(posedge clk or negedge _rst)
begin
    if(!_rst)//如果复位引脚接地(按下复位按键)
        counter<=26'd0;//计数寄存器清零(复位)
    else if(counter<26'd5000_0000)
        counter<=counter+1'b1;//向上计数
    else
        counter<=26'd0;//到达计数上限时清零

LED状态控制部分

assign led=(counter<26'd2500_0000) ? 2'b01 : 2'b10;
//计数器小于计数位置时输出01,否则输出10

总文件如下所示

//`timescale 1ns / 1ps

module LED(
    input clk,
    input _rst,

    output [1:0] led
);

//时钟寄存器
reg [25:0] counter;

//IO输出部分
assign led=(counter<26'd2500_0000) ? 2'b01 : 2'b10;

//计数器部分
always @(posedge clk or negedge _rst)
begin
    if(!_rst)
        counter<=26'd0;
    else if(counter<26'd5000_0000)
        counter<=counter+1'b1;
    else
        counter<=26'd0;
end
endmodule

调用/自行配置IP、DSP等内部电路

在vivado创建工程界面中常使用以下工程种类:

  1. RTL工程

    用户可以添加RTL源文件、Xilinx IP目录内的已有IP、用于层次化模块的EDIF网表、Vivado IP集成器内创建的块设计、数字信号处理的源文件到Vivado的RTL工程。其中使用已有IP可以包含Xilinx生成的XCI文件、由核生成器工具生成的已经过时的XCO文件、预编译的EDIF或者GNC格式的IP网表这些类型

  2. Post-synthesis工程

    使用综合后的网表创建工程

    用户通过vivado、XST或第三方综合工具生成网表后选择这一工程选项,快速将其他平台的设计导入xilinx平台

  3. I/O Planning工程

    创建一个空的I/O规划工程,先分配I/O和约束,再创建CSV、XDC和RTL输出文件。这些文件可用于创建原理图符号或印制PCB

综合

综合:将RTL级设计描述转换成门级描述的过程

vivado的综合是基于时间驱动的,为存储器利用率和性能做了优化。目前综合工具支持SystemVerilog、VHDL、Verilog三种语言及它们的混合,且支持XDC格式

综合工具需要使用XDC约束驱动综合优化,所以必须存在XDC文件

确定约束

有两种类型的设计约束:

  • 物理约束:定义了引脚的位置和内部单元的绝对或相对位置,内部单元包括RAM、LUT、触发器和器件配置设置
  • 时序约束:定义设计要求的频率。如果没有时序约束,Vivado仅会对布线长度和布局阻塞进行优化

选择【Option】-【Strategy】右侧的下拉框中用于运行综合的预定义综合策略,设计者可以定义优化的方向

执行综合

RTL文件综合后将自动生成时序总结、时钟及其网络、DRC报告、噪声报告、利用率报告、功耗报告、原理图等选项,可以使用原理图查看综合后生成的完整网表结构

综合后,设计会表示为模块(Verilog中的module)、实体(VHDL中的Entity)的实例与基本元素(LUT、触发器、进位链元素、多路复用器MUX、块RAM、DSP单元、时钟元素、IO元素等)的网表集合

每个LUT表述的逻辑都能单独查看(真值表)

在windows下vivado的综合速度较慢,开始综合后需要等待一段时间

行为级仿真

在Simulation Sources目录下添加testbench文件,编写测试代码后就可以进行仿真

在左侧从窗口内找到SIMULATION选项并展开,点击【Run Simulation】-【Run Behavioral Simulation】就可以开始仿真

在Tcl Console中输入run命令可以控制仿真的运行时间;输入restart命令可以重新执行仿真

实现约束

I/O规划

使用I/O Planning进行FPGA的输出引脚规划

可以使用Vivado的图形化界面添加引脚约束(点击I/O Planning选项),也可以在Constraints目录下添加约束文件并自行编写引脚约束

注意约束文件使用XDC格式

设计实现

在左侧选择【IMPLEMENTATION】,选择实现策略,可以自行调节设计实现优化的方向,包括以下内容:

  • 提高设计性能
  • 减少LUT个数
  • 添加整体功耗优化
  • 修改流程步骤
  • 减少阻塞和相关问题

点击【Run Implementation】来执行设计实现

待完成后可以打开设计实现来查看FPGA内部布线及实际使用的逻辑资源

也可以查看相关报告

静态时序分析STA

一个器件的性能由构成设计单元的延迟决定,它可以通过静态时序分析(Static Timing Analysis,STA)验证

简单来说STA就是用来控制细化设备的延迟和时序的调试过程

时序仿真
  1. 选择需要使用的test-bench文件
  2. 选择vivado界面左侧【Run Simulation】-【Run Post-Implementation Timing Simulation】(运行实现后时序仿真)
  3. 执行时序仿真并观察仿真波形进行debug

生成比特流文件

比特流文件就是用于配置FPGA的编程文件,可以直接使用烧录器将比特流文件下载到目标FPGA中

  1. 配置器件属性

    选择器件型号并进一步选择生成比特流文件的硬件约束

  2. 生成可编程文件

    在左侧窗口中选择【PROGRAM AND DEBUG】并右键选择【Bitstream Settings】即可打开比特流优化配置界面

    默认只生成一个二进制比特流.bit文件

    可以选择配置设定产生原始比特流.rbt文件、掩码文件、ASCII逻辑定位文件.ll、纯二进制文件.bin等选项

烧录使用

  1. 开发板正常上电
  2. 开发板连接烧录器
  3. 将烧录器连接到PC并使用vivado连接烧录器(点击Auto Connect)
  4. 点击【Program Device】即可开始烧录

生成并烧录PROM文件

  1. 除了生成比特流文件外还需要再选中“-bin_file”生成纯二进制文件
  2. 重新生成比特流文件和二进制文件
  3. 按照上面步骤连接开发板并在【Add Configuration Memory Part】-【Select Configuration Memory Part】中设置可用的SPI FLASH
  4. 正常烧录
  5. 配置开发板使PROM上电后自动将逻辑配置文件加载到FPGA

vivado支持的特殊开发方式

vivado是以IP为核心的设计工具

vivado具有一个共享的IP数据库

高层次综合

使用Vivado HLS软件可以将c、c++、system c语言编写的算法代码直接综合生成RTL代码

HLS从C语言中提取硬件结构的思路如下

  1. 在顶层,从C代码中提取控制和数据通路
  2. 在顶层控制流的一些点将控制传递到子程序中
  3. 子程序可以与顶层或其他子程序并行执行
  4. 通过调度和绑定过程将C代码映射到硬件逻辑资源

C代码的关键属性

  • 函数

    所有代码由函数组成,函数名被对应到RTL描述的模块

  • 参数

    顶层函数的参数决定了硬件RTL本身的端口

  • 类型

    变量类型越复杂,实现该变量所占用的面积越多

  • 循环

    默认对于循环采用“回卷”的方式进行处理。对于每个C循环迭代,采用相同的状态或资源来实现。循环的处理分成三个部分:循环展开、循环平坦化和循环合并。默认情况下不展开循环,并将嵌套循环“平坦化”:将外层循环拆解为多个内层循环的组合;之后还会自动合并循环:将结果可以合并的多个循环在硬件层面上合并到统一的器件上

  • 数组

    C代码中的数组常常被映射到FPGA中的BRAM资源,会因为存储器的读写操作具有互斥性而使得它会变成设备的性能瓶颈

  • 操作符

    C代码中的操作符可能要求共享,通过共享可以在满足性能的前提下以控制面积或指定的硬件实现来满足并行化要求

类似的,也可以使用C++算法描述并进行HLS

IP集成库

Vivado提供了一个图形化界面用于调用自定义IP核,也可以使用代码方式调用IP核。IP核类似编程中的函数库,提供了数学运算加速器、硬件信号处理等电路,可以直接调用,非常方便

在左侧选择IP Catalog即可调用Vivado内置的一些IP核

点击即可调用,有些IP核需要自行下载

在弹出的窗口中调整IP核的相关约束,根据指示添加即可调用相关内容

用户也可以自行封装IP核以及自行连接已有IP核

你可能感兴趣的:(IC设计工具,FPGA,嵌入式,fpga,fpga/cpld)