【ZYNQ学习之FPGA开发】二、FPGA快速上手,基础知识(总结版)

一、FPGA

  • PLD - 可编程逻辑器件

    • CPLD - 复杂可编程逻辑器件【基于乘积项的与或逻辑阵列】
    • FPGA - 现场可编程逻辑门阵列【基于查找表的CLB阵列】
    • 两者虽然有差异,但也只是硬件层面,在编程上是没有区别的!
  • 什么是FPGA?

    • 一种可通过编程来修改其逻辑功能的数字集成电路(芯片)
  • 与单片机的区别?

    • 单片机并不改变电路的内部连接结构,只是根据要求实现的功能来编写运行的程序(指令)

二、HDL

  • 数字系统设计流程?

    • 逻辑设计(前端)-> 电路实现(后端) -> 系统验证
  • 逻辑设计(前端)

    • HDL(硬件描述语言)可以在不同的层次数字电路结构、功能和行为进行描述。
    • 数字电路最基本的电路是门电路
  • 电路实现(后端)

    • HDL描述的电路,首先通过综合工具将其转换为门级电路网表,然后将其余某种工艺的基本元件逐一对应起来,再通过布局布线工具转换为电路布线结构!
  • Verilog HDL和VHDL区别

    • 在欧洲VHDL普及度比较广,在中国和美国Verilog HDL普及度比较广
    • Verilog HDL相对于VHDL灵活性较好,上手相对容易。
  • Verilog和C的区别?(FPGA和单片机最大的区别?)

    • Verilog是硬件描述语言,在编译下载到FPGA之后会生成电路。由于上电之后电路是并行的,所以Verilog也是并行的。(速度相对快)
    • C语言是软件编程语言,编译下载到单片机后是存储器中的一组指令,而单片机处理软件指令需要取指、译码、执行。这个过程是串行执行的。(速度相对慢)

三、Verilog基本语法

  • 常用的进制

    • 二进制,4’b0101(4表示位宽)
    • 十进制,4’d2(4’b0010)
    • 十六进制,4’ha(4’b1010)
    • 当没有明确给出位宽时,默认是32位位宽。若进制也没有的话,则默认是表示十进制。
    • 给数值添加下划线,增加可读性。16’b1001_1010_1010_1001 = 16’h9AA9
  • 标识符(类似变量名):定义模块名、端口名、信号名(变量或常量)

    • 第一个字符必须是字母或者下划线
    • 可以是任意一组字母、数字、$、_ 的组合
    • 区分大小写
  • 数据类型

    扫描二维码关注公众号,回复: 11483811 查看本文章
    • 寄存器、线网、参数
    • 真正在数字电路起作用的数据类型应该是寄存器和线网,而参数数据类型主要是给编译器识别用的。
  • 寄存器数据类型

    • 关键字:reg。默认初始值为不定值x。
      • reg[31:0] delay_cnt; 定义了一个32位的位宽的寄存器
      • reg key_reg; 定义了一个1位的位宽寄存器(没有给定位宽,就默认是1)
    • reg类型只能在always语句和initial语句赋值
      • 若always语句带有时钟信号(描述的是时序逻辑),则该寄存器变量对应为触发器
      • 若always语句不带有时钟信号(描述的是组合逻辑),则该寄存器变量对应为硬件连线
  • 线网数据类型(当没有明确定义变量的类型,那么它就是线网类型)

    • 表示结构实体(比如门)之间的物理连线
    • 关键字:wire(常用)和tri(少用)
    • 线网类型不能存储值,它的值有驱动它的元件所决定。
      • 可以驱动线网类型的元件有:门、连续赋值语句、assign
    • 若没有驱动元件,则该元件为高阻态z
      • wire key_flag; 1位位宽的wire类型变量
  • 参数数据类型

    • 定义常量,类似C语言的define
    • 关键字:parameter
      • parameter H_SYNC = 11’d41; 定义H_SYNC 常量,注意相比C的define有等号也有分号。
    • 可以一次定义多个参数,参数与参数之间用逗号隔开,但是不美观。
    • 右边必须是常数
    • 参数数据类型可以咏柳定义状态机的状态、数据位宽、延迟大小
  • 运算符需要注意的

    • 左移时,位宽增加;右移时,位宽不变;移位都是用0来补上空位
    • 位拼接运算符
      • {a,b},a和b拼接起来
      • c[11:0] = {a[7:0], b[3:0] }
  • 常用关键字

    • 在这里插入图片描述
  • Verilog的基本设计单元是“模块”,同C语言的函数

    • 模块由2部分组成:描述接口、描述逻辑功能
    • 每个Verilog程序包括4个主要的部分:
      • 端口定义、IO说明、内部信号声明、功能定义
  • Verilog里定义功能有三种方法:

    • assign语句:描述组合逻辑
    • always语句:描述时序/组合逻辑
    • 例化实例元件:eg:and #2 u1(q,a,b); 例化一个与门,#2表示延时2(至于单位,要具体看情况)
    • 以上三种逻辑功能是并行的!
    • 注意
      • 在always模块中的逻辑是顺序执行的
      • 多个always模块间是并行
  • 例化一个模块时注意事项:

    time_count #(
        .MAX_NUM	(TIME_SHOW)
    ) u_time_count(
        .clk	(sys_clk),
        .rst_n	(sys_rst_n),
        .flag	(add_flag)
    );
    
    • 输出信号必须是一个wire类型的!
    • #(xx)这个里面一般是进行parameter类型的变量赋值
    • u_time_count里面的赋值是wire和reg类型的!
  • 过程块:

    • initial
    • always
  • initial(里面按顺序执行)

    • 在模块中只执行一次
    • 常用于测试文件的编写,用来产生仿真测试信号(激励信号),或者用于对存储器变量赋初值
  • always(里面按顺序执行)

    • 一直在不断地重复活动,但是只有和一定的时间控制结合在一起才有作用。
    • always #10 sys_clk <= ~sys_clk产生周期为20ns的时钟信号
    • always的时间控制可以是沿触发,也可以是电平触发;可以是单个信号,也可以是多个信号,多个信号之间要用关键字or连接。
    • always后紧跟的过程块(顺序块)是否运行,要看它的触发条件是否满足。always @(posedge sys_clk or negedge sys_rst_n)...表示sys_clk上升沿或者sys_rst_n下降沿触发
    • 由or连接的多个事件名或信号名组成的列表成为“敏感列表”
    • 沿触发的always块常常用来描述时序逻辑行为
    • 电平触发的always块常常用来描述组合逻辑
      • 组合逻辑块语句的输入变量很多,如下
      • always @(a or b or c or d or e or ....)
      • 这时我们可以直接使用always @(*)替代上面的写法
  • 关于Verilog里面的begin end可以类比C语言的大花括号{}

  • 延时

    • 通常在一个.v文件开头定义延时单位和精度,比如timescale 1ns / 1ps
    • 那么#200 的意思就是延时200ns
    • 那么#200.123的意思就是延时200.123ns,注意200.123ns = 200123ps,这个是由1ps决定的!
  • 赋值语句

    • 阻塞赋值:eg:b = a
      • 计算右边并更新左边
    • 非阻塞赋值:eg:b <= a
      • 赋值开始的时候,计算右边
      • 赋值结束的时候,更新左边
      • 非阻塞只能用于对寄存器类型变量赋值
    • 什么时候用阻塞赋值,什么时候用非阻塞呢?
      • 描述组合逻辑电路always块用阻塞赋值
        • 这种电路之与输入电平的变化有关
      • 描述时序逻辑电路always块用非阻塞赋值
        • 这种电路往往与触发沿有关(敏感列表中有posedge或者negedge)
      • 注意
        • 在一个always块中不要既用非阻塞又用阻塞
        • 不允许在多个always块中对同一个变量赋值
  • 条件语句

    • if
      • 必须在过程块中使用。(initial和always中)
      • 0、x(不定值)、z(高阻态)均为假。
    • case
      • 在这里插入图片描述
  • 状态机

    • 检测顺序逻辑

    • 在有限个状态之间按一定规律转换的时序电路,成为有限状态机(FSM)

    • Mealy【两个组合逻辑,一个时序逻辑】

    • Moore(特殊的Mealy)

      • 在这里插入图片描述
    • 状态机的设计 - 四段论

      • 状态空间定义
        • 在这里插入图片描述

        • 注意:

          • 位宽得一样
          • 独热码(one hot code):每个状态只有一个寄存器置位,译码逻辑简单
      • 状态跳转【时序逻辑】
        • 在这里插入图片描述

        • 注意是非阻塞赋值

      • 下个状态判断【组合逻辑】
        • 在这里插入图片描述

        • 对应模型中的:在这里插入图片描述

        • 阻塞赋值

        • latch是指锁存器 - 电平触发存储器;触发器 - 边沿触发的存储器;

        • 在编写Verilog时要注意,避免产生无谓的锁存器

          • 锁存器只在组合逻辑中产生,锁存器会造成最后生成的电路毛刺较多;会影响我们对整个电路的时序分析
          • 如果使用if,没有配套的else会产生锁存器;如果case语句没有写全,但有没有写default也会产生。
      • 各个状态下的动作【组合逻辑】
        • 对应模型中的在这里插入图片描述

        • 在这里插入图片描述

        • 在这里插入图片描述

        • 阻塞赋值

  • 三段式状态机(四段论的改进)

    • 在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ReCclay/article/details/107742655
今日推荐