FPGA学习笔记

Source

一、第一周

第一天

理论基础

FPGA,Field Programmable Gate Array,现场可编程门阵列。

与单片机的区别:
系统结构:单片机—冯诺依曼,FPGA—查找表
执行方式:单片机—串行执行,FPGA—并行执行
语言类型:单片机—汇编语言,FPGA—Verilog HDL/VHDL

FPGA开发流程:
//3-6步quartus帮我们做了
1.设计输入—Verilog HDL/HDL编码
2.RTL功能仿真—验证逻辑功能/数据流—modelsim工具
3.分析综合—将设计映射为器件模型,生成网表文件
4.布局布线—功能映射,指定布线资源
5.门级仿真—根据估计的布局布线延时进行时序仿真
6.时序分析—验证设计是否满足时序和性能要求—timing analyzer工具
7.板级验证—signal tap嵌入式逻辑分析工具

数字电路基础:
组合逻辑电路—特点是任意时刻的输出仅仅取决于该时刻的输入,与电路原来的状态无关。
时序逻辑电路—特点是任意时刻的输出不仅取决于当时的输入信号,而且还取决于电路原来的状态,或者说,还与以前的输入有关。时序逻辑的存储电路一般由锁存器,触发器和寄存器组成。利用触发器的记忆功能即存储一位二进制码,将n个触发器的时钟端口连接起来,构成存储n位二进制码的寄存器。寄存器和锁存器功能相同,区别在于寄存器是时钟控制,锁存器是电平信号控制。D寄存器和D锁存器的区别——一个是边沿触发,一个是电平触发。

HDL,Hardware Description Language,硬件描述语言。所见即所得,描述硬件功能,而不是告知程序如何运行。

Verilog HDL语法基础:

module module_name(); endmodule //模块定义
assign out=in;      //是持续性的赋值;
always@(*)begin end //则是执行语句时的过程赋值。

//总结连续赋值:只要右边表达式任一个变量有变化,
//表达式立即被计算,计算的结果立即赋给左边信号。
parameter MAX_NUM=100    //全局变量
localparam MAX_NUM=100   //局部变量

//用parameter来定义一个标志符代表一个常量,称作符号常量.他可以提高程序的可读性和可维护性。
//parameter是参数型数据的关键字,在每一个赋值语句的右边都必须是一个常数表达式。即该表达式只能包含数字或先前已经定义的参数。
reg  
//寄存器数据类型,reg类型数据的默认初始值为不定值x。
//reg类型的数据只能在always语句和initial语句中被赋值。
//如果过程语句描述的是时序逻辑,即always语句有时钟信号,则寄存器变为触发器;
//如果过程语句描述的是组合逻辑,即always语句没有时钟信号,则该寄存器变为硬件连线。
//reg型只是表示被定义的信号将被用在always模块中,并不是说reg型数据就一定是存储器或触发器的输出。
wire 
//默认wire的位宽为1位,默认为高阻值z。
//线网型数据类型,驱动线网型变量的元件有逻辑门、连续赋值语句(assign)等。
//如果没有驱动元件连接到线网类型的变量上,则该变量就是高阻的,即为Z。
//{}的拼接功能
{
    
      3'b111, 3'b000} => 6'b111000
{
    
      1'b1, 1'b0, 3'b101} => 5'b10101
{
    
      4'ha, 4'd10} => 8'b10101010     // 十进制和十六进制转二进制再拼接

//{}的复制功能
{
    
      5{
    
      1'b1}}           // 5'b11111 (or 5'd31 or 5'h1f)
{
    
      2{
    
      a,b,c}}          // 等同于{a,b,c,a,b,c}
{
    
      3'd5, {2{3'd6}}}   // 9'b101_110_110. 5-->101,6-->110,101和两个重复的110粘连起来。
                 
//将某些信号的某些为列出来,中间用逗号分开,最后用大括号括起来表示一个整体的信号。
//在位拼接的表达式中不允许存在没有指明位数的信号。
b<=a; //非阻塞赋值
//在语句块中,上面语句所赋值的变量不能立即为下面的语句所用;
//块结束后才能完成这次赋值操作,赋值的值为上次赋值得到的;
//在编写可综合的时序逻辑模块时,这是最常用的复制方法。

b=a; //阻塞赋值
//赋值语句完成后,块才结束;
//b的值在赋值语句执行完后立刻改变。

//八大原则
1)时序电路建模时,采用非阻塞赋值;

2)锁存器电路建模时,采用非阻塞赋值;

3)用always块建立组合逻辑模型时,采用阻塞赋值;

4)用always块建立时序和组合逻辑混合电路时,采用非阻塞赋值;

5)不要在同一个always块中同时使用非阻塞赋值和阻塞赋值;

6)不要在一个以上的always块中为同一个变量赋值;

7)用$strobe系统任务来显示用非阻塞赋值的变量值;

8)在赋值时,不要用#0延迟;


第二天

时钟,同步、异步系统

时钟信号是高扇出控制信号,由振荡器(信号源)、定时唤醒器、分频器等组成的电路。
包括晶振和RC振荡器
所谓高扇出是指:当指某一信号高扇出时,是指该信号被后面多个模块使用。具体扇出多少算是高扇出,这跟时钟频率有关系,时钟频率越高,所允许的扇出数越低。
影响:高扇出的直接影响就是net delay 比较大,影响时序收敛。

时钟周期的大小对于数字电路设计的影响主要在于触发器之间的所有逻辑电路需要在一个时钟周期内完成所需的逻辑运算并满足触发器的建立时间和保持时间的要求。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

作用:
1.同步系统的各器件(CPU、内存、总线等)的工作;
2.驱动处理器内核、外设部件(串口数据发送,定时器计数等)

改进:高扇出常用的三种改进方法:
1.复制寄存器;
2.max_fanout 属性;
3.复位信号可使用BUFG优化。
参考.

同步系统:
各个D触发器的时钟端连在一起,并接在系统时钟端,只有在时钟上升沿到来时,电路的状态才会改变。所有触发器的状态变化都与所加时钟脉冲信号同步。
同步电路的时钟之间有固定的因果关系。
优点:
1.避免毛刺
2.利于器件移植
3.利于静态时序分析
4.验证设计时序性能
缺点:
1.时钟偏移,逻辑电路的可用路径缩短,增加设计难度
2.同步设计中,最高时钟频率取决于延迟最大的逻辑电路的路径延迟,即工作速度受到最慢电路的限制,导致部分逻辑电路会浪费一个时钟周期中的部分时间用于等待速度较慢的电路。

异步系统:
电路没有统一时钟,时钟之间没有固定的因果关系,即整个系统由多个时钟或无时钟驱动。
优点:

流水灯及其简单衍生

跑马灯

在这里插入图片描述

关键代码片

always@(posedge clk or negedge rst_n)begin     //不是从复位信号开始的,那么灯泡不亮
   if(!rst_n)begin                             
	led <= 4'b0000;                             //led灯高电平有效,低电平无效,1亮0不亮,这是赋值的方式,不是小于等于,非阻塞赋值
   end
   else if(cnt == 24'd9_999_999&& flag==1)begin          //0.2s  else if(cnt == 25'd10_000_000)begin   led <= {
    
      led[2:0],led[3]};
	       led <= 4'b0001;
	end
	else if(cnt == 25'd20_000_000 - 1'd1&& flag==1)begin  //0.4s  为什么不都是四百万,是因为并行的,用多少给多少
	       led <= 4'b0011;
	end
	else if(cnt == 25'd30_000_000 - 1'd1&& flag==1)begin  //0.6s  0100是二进制,此时表示的是信号,而不是数值
	       led <= 4'b0111;
	end
	else if(cnt == 26'd40_000_000 - 1'd1&& flag==1)begin  //0.8s  非阻塞赋值是指,所有赋值同时发生
	       led <= 4'b1111;
	end
	else if(cnt == 24'd9_999_999&& flag==2)        begin 
	       led <= 4'b1110;
	end
	else if(cnt == 25'd20_000_000 - 1'd1&& flag==2)begin 
	       led <= 4'b1100;
	end
	else if(cnt == 25'd30_000_000 - 1'd1&& flag==2)begin 
	       led <= 4'b1000;
	end
	else if(cnt == 26'd40_000_000 - 1'd1&& flag==2)begin 
	       led <= 4'b0000;
	end
	else begin
	       led <=led;                           //否则让led保持当前状态,之前的状态,直到时钟振动到特定次数之前
   end	
end

信号分析

在这里插入图片描述

演示结果
短视频.

第三天

第四天

第五天

周测

二、第二周