FPGA学习笔记

毕设需要,自学笔记,内容参考来源:
小梅哥爱漂流
野火

0 FPGA概述
0.1 Verilog基础语法
1 开发流程
1.1 案例:控制LED灯
1.2 案例:3-8译码器(比较详细)
2 层次化设计
2.1 案例:全加器


0 FPGA概述

FPGA和CPLD性能比较
器件种类特性FPGACPLD
内部结构查找表乘积表
程序存储内部SRAM结构,外挂EEPROM或Flash存储程序内部EEPROM或Flash
资源类型触发器资源丰富组合逻辑资源丰富
集成度
使用场合完成比较复杂的算法完成控制逻辑
速度
其他资源RAM、PLL、DSP等-
保密性一般不能保密(可以使用加密核)可加密
  1. FPGA技术优势
    (1) 速度快
    (2) 效率高
    (3) 低延时
    (4) 可重构
    (5) 开发灵活方便
    (6) 接口丰富

0.1 Verilog基础语法

逻辑值

0:逻辑低电平,条件为假
1:逻辑高电平,条件为真
z:高阻态,无驱动
x:未知逻辑电平

关键字

module example            // 模块开始    模块名
{
	input            ;     // 输入信号
	inout            ;     //输入输出信号

	output          ;      // 输出信号
}

// 线网性变量
wire          ;     //    可看成直接的连接,在可综合的逻辑中会被映射成一条真实存在的连线

// 寄存器型变量
reg           ;        // 具有对某一时间点状态进行保持的功能,在可综合的逻辑中会被映射成一个真实的物理寄存器

// 参数
parameter                  ;      // 实例化时参数可修改
localparam                 ;      // 只能在模块内部使用,不能进行实例化

//常量
/*
格式:[换算为二进制后位宽的总长度][ ' ][与数值进制符号对应的数值]
如:8'd171   表示位宽8bit,十进制的171
若直接写参数,如100,表示位宽为32bit的十进制数100
*/

// 赋值方式
// 1. 阻塞赋值
a = 1;
b = 2;
c = 3;
begin
	a = b;
	c = a;
end
a = 2;
b = 2;
c = 2;

// 2. 非阻塞赋值 "<=",语句并行执行
a = 1;
b = 2;
c = 3;
begin
	a <= b;   // 同时将b的值赋给c,将a的值赋给c
	c <= a;
end
a = 2;
b = 2;
c = 1;

// always语句

// assign语句

endmodule       // 模块结束    

算数运算符

+ : assign c = a + b;  把a与b的和赋值给c
- 
*
/
% :求模,用在测试文件

归约运算符、按位运算符

以“&”为例
情形一:&作一元运算符表归约与,&m是将m中所有位相与
如:&4'b1111 = 1&1&1&1 = 1'b1

情形二:&作二元运算符表按位与,m&n是将m于n逐位相与
如:4'b1010 & 4'b0101 = 4'b0000
其他操作符类似

逻辑运算符

&&
||
==
!=

移位运算符

左移"<<" ,右移">>",将运算符左边的操作数左移或右移指定位数, 空位用0补充 

位拼接运算符

{ ,}
如:8bit的a,3bit的b,5bit的c,按顺序拼接成16位的d,表示为: d = {a, b, c};

条件运算符

表达式1?表达式2:表达式3

优先级

归约运算符>算数运算符>移位运算符>关系运算符>"=="和"!=">按位运算符>"&&"和"||">关系运算符
可使用"( )"增加优先级

if-else条件分支语句

作用:根据指定的判断条件是否满足来确定下一步要执行的操作。使用形式有三种:

// 第一种,这种写法在always块中会产生latch,不推荐
if (<条件表达式>)
	语句或语句块;

//第二种
if (<条件表达式1>)
	语句或语句块1;
else if (<条件表达式2>)
	语句或语句块2;
	...
else

// 第三种,嵌套,会有优先级问题,最后导致逻辑混乱,不推荐
if (<条件表达式1>)
	if (<条件表达式2>)
		语句或语句块1;
	else
		语句或语句块2;
else
	语句或语句块3;

case分支控制语句

通常用于对微处理器指令译码功能的描述,以及对有限状态机的描述

case (<控制表达式>)
	<分支语句1>: 语句块1;
	<分支语句2>: 语句块2 ;
	<分支语句3>: 语句块3 ;
	...
	<分支语句n>: 语句块n ;
	default: 语句块n+1 ;
endcase

系统函数

Verilog语句预先定义了一些任务和函数,用于完成一些特殊的功能,它们被称为系统任务和系统函数,这些函数大多数只能在Testbench仿真中使用。

系统函数作用格式
timescale时间尺度预编译指令 时间单位/时间精度`timescale 1ns/1ns
$display输出、打印信息$display("%b+%b=%d",a,b,c);%h、%H表示以十六进制的形式输出
%d、%D表示以十进制的形式输出(默认)
%o、%O表示以八进制的形式输出
%b、%B表示以二进制的形式输出
$write输出、打印信息$write("%b+%b=%d\n",a,b,c);\n换行,其他同上
$strobe输出、打印信息,只在最后执行$strobe("%b+%b=%d",a,b,c);同上
$monitor持续检测变量
(语句中任何一个变量发生变化,就会执行一次语句)
$monitor("%b+%b=%d",a,b,c);同上
$stop暂停仿真
$finish结束仿真
$time时间函数,返回64位当前仿真时间
$random产生随机函数,返回随机数
$readmenb
$readmenh
读二进制文件函数
读十六进制文件函数
$readmenb("<数据文件名>",<存储器名>);

1 开发流程

1. 设计定义
2. 设计输入
3. 分析和综合(quartus II)
4. 功能仿真(modelsim-altera)
5. 布局布线
6. 时序仿真(modelsim-altera)
7. IO分配以及配置文件的生成(modelsim-altera)
8. 配置(烧写FPGA)
9. 在线调试(嵌入式逻辑分析仪或其他分析仪)

1.1 第一个栗子

设计定义

二选一多路器
两个输入IO,a、b,可以是高电平,也可以是低电平
输入按键按下时,LED灯与a端口状态保持一致;输入按键释放时,LED灯与b端口状态保持一致

端口设计

// 以module表示设计模块的开始,以endmodule结尾
module led_test(a,b,key_in,led_out);

	input a; // 输入端口A
	input b; //输入端口B 

	input key_in;  // 按键输入,实现输入通道的选择

	output led_out;  // led控制端口
	
// 当key_in == 0 , led_out = a
	assign led_out = (key_in == 0) ? a : b;   // 条件满足则led_out = a,否则led_out=b
	
endmodule

testbench编写

搭建测试平台
搭建测试平台

//搭建测试平台
`timescale 1ns/1ps  // 定义仿真延时/精度,这里的 ` 为键盘左上角的

module led_test_tb;   // tb即testbench

//  激励信号定义,对应连接到待测试模块的输入端口	
	reg signal_a;
	reg signal_b;
	reg signal_c;

// 待检测信号定义,对应连接到待测试模块的输出端口
	wire led;
	
// 例化待测试模块
	led_test led_test0(
		.a(signal_a),   // a 连接信号源signal_a
		.b(signal_b),
		.key_in(signal_c),
		.led_out(led)  // 前面定义了一个led线,那么只要看led的状态就能知道led_out的状态
	);

// 产生激励,通过驱动三个激励信号源端口的状态,实现驱动待测试模块的三个端口
	initial begin
		signal_a = 0; signal_b = 0; signal_c = 0;
		#100;  //延时100ns
		signal_a = 0; signal_b = 0; signal_c = 1;
		#100;
		signal_a = 0; signal_b = 1; signal_c = 0;
		#100;
		signal_a = 0; signal_b = 1; signal_c = 1;
		#100;
		signal_a = 1; signal_b = 0; signal_c = 0;
		#100;
		signal_a = 1; signal_b = 0; signal_c = 1;
		#100;
		signal_a = 1; signal_b = 1; signal_c = 0;
		#100;
		signal_a = 1; signal_b = 1; signal_c = 1;
		#200;
		$stop;   // 系统函数,停止仿真
		
	end

IO分配

烧入程序

1.2 第二个栗子:3-8译码器

真值表

ABCOUT
0000000 0001
0010000 0010
0100000 0100
0110000 1000
1000001 0000
1010010 0000
1100100 0000
1111000 0000

新建工程

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

设计输入

module my3_8 (a, b, c, out);

// 端口定义
	input a;   // 输入端口A
	input b;   //输入端口B
	input c;   //输入端口C

	output [7:0]out;    // 输出端口,[7:0]定义了一个多位宽的信号,高位在前,低位在后
	reg [7:0] out; // 定义out 为寄存器输出型,在always中必须将out定义为 reg
	
// 逻辑定义
	always@(a, b, c) begin // always块的敏感信号为a,b,c,当这些信号中任意一个发生变化时,就会执行always里面的内容
		case({a, b, c})    // { }将a,b,c拼接成一个三位的信号
			3' b000: out = 8' b0000_0001;      // 3表示信号的位宽,b表示二进制,后面的000分别对应abc
			3' b001: out = 8' b0000_0010;
			3' b010: out = 8' b0000_0100;
			3' b011: out = 8' b0000_1000;
			3' b100: out = 8' b0001_0000;
			3' b101: out = 8' b0010_0000;
			3' b110: out = 8' b0100_0000;
			3' b111: out = 8' b1000_0000;
			// 这里省略了default
		endcase
	end
endmodule

testbench编写

testbench 可以看作一个桌子,上面放的是待测试模块、激励信号源、信号观测示波器

·timescale 1ns/1ns
module my3_8_tb;

// reg 定义激励信号源
	reg a;
	reg b;
	reg c;

// wire 输出信号的观测信号
	wire [7:0] out;

//模块例化
	my3_8 u1(
		.a(a), 
		.b(b), 
		.c(c), 
		.out(out) 
	);
// 激励信号产生
	initial begin
		a = 0; b = 0; c = 0;
		#200;
		a = 0; b = 0; c = 1;
		#200;
		a = 0; b = 1; c = 0;
		#200;
		a = 0; b = 1; c = 1;
		#200;
		a = 1; b = 0; c = 0;
		#200;
		a = 1; b = 0; c = 1;
		#200;
		a = 1; b = 1; c = 0;
		#200;
		a = 1; b = 1; c = 1;
		#200;
		$stop;
	
	end

endmodule

仿真

接下来设置链接文件,通过一个链接将my3_8与 my3_8_tb 告诉仿真工具,让其能够直接调用这两个文件进行仿真

操作步骤:assignment >settings >simulation【 netverlog HDL, nativelink settings:comple…】>testbench >new >【test bench name: my3_8_tb, filename(选择my3_8_tb)】>add >ok

然后可以运行仿真在这里插入图片描述

编译

门级仿真

在这里插入图片描述
这里观测波形可能会存在竞争冒险
在这里插入图片描述

2 层次化设计

  1. 自底向上
    从存在的基本单元出发,由基本单元构建高层单元,依次向上
  2. 自顶向下
    从系统级开始,把系统分为基本单元,在把每个单元划分位下一层次的基本单元,直到可以用EDA元件库中的元件来实现为止

2.1 案例:全加器

热门文章

暂无图片
编程学习 ·

Java输出数组的内容

Java输出数组的内容_一万个小时-CSDN博客_java打印数组内容1. 输出内容最常见的方式// List<String>类型的列表List<String> list new ArrayList<String>();list.add("First");list.add("Second");list.add("Third");list.ad…
暂无图片
编程学习 ·

母螳螂的“魅惑之术”

在它们对大蝗虫发起进攻的时候&#xff0c;我认认真真地观察了一次&#xff0c;因为它们突然像触电一样浑身痉挛起来&#xff0c;警觉地面对限前这个大家伙&#xff0c;然后放下自己优雅的身段和祈祷的双手&#xff0c;摆出了一个可怕的姿势。我被眼前的一幕吓到了&#xff0c;…
暂无图片
编程学习 ·

疯狂填词 mad_libs 第9章9.9.2

#win7 python3.7.0 import os,reos.chdir(d:\documents\program_language) file1open(.\疯狂填词_d9z9d2_r.txt) file2open(.\疯狂填词_d9z9d2_w.txt,w) words[ADJECTIVE,NOUN,VERB,NOUN] str1file1.read()#方法1 for word in words :word_replaceinput(fEnter a {word} :)str1…
暂无图片
编程学习 ·

HBASE 高可用

为了保证HBASE是高可用的,所依赖的HDFS和zookeeper也要是高可用的. 通过参数hbase.rootdir指定了连接到Hadoop的地址,mycluster表示为Hadoop的集群. HBASE本身的高可用很简单,只要在一个健康的集群其他节点通过命令 hbase-daemon.sh start master启动一个Hmaster进程,这个Hmast…
暂无图片
编程学习 ·

js事件操作语法

一、事件的绑定语法 语法形式1 事件监听 标签对象.addEventListener(click,function(){}); 语法形式2 on语法绑定 标签对象.onclick function(){} on语法是通过 等于赋值绑定的事件处理函数 , 等于赋值本质上执行的是覆盖赋值,后赋值的数据会覆盖之前存储的数据,也就是on…
暂无图片
编程学习 ·

Photoshop插件--晕影动态--选区--脚本开发--PS插件

文章目录1.插件界面2.关键代码2.1 选区2.2 动态晕影3.作者寄语PS是一款栅格图像编辑软件&#xff0c;具有许多强大的功能&#xff0c;本文演示如何通过脚本实现晕影动态和选区相关功能&#xff0c;展示从互联网收集而来的一个小插件&#xff0c;供大家学习交流&#xff0c;请勿…
暂无图片
编程学习 ·

vs LNK1104 无法打开文件“xxx.obj”

写在前面&#xff1a; 向大家推荐两本新书&#xff0c;《深度学习计算机视觉实战》和《学习OpenCV4&#xff1a;基于Python的算法实战》。 《深度学习计算机视觉实战》讲了计算机视觉理论基础&#xff0c;讲了案例项目&#xff0c;讲了模型部署&#xff0c;这些项目学会之后可以…
暂无图片
编程学习 ·

工业元宇宙的定义与实施路线图

工业元宇宙的定义与实施路线图 李正海 1 工业元宇宙 给大家做一个关于工业元宇宙的定义。对于工业&#xff0c;从设计的角度来讲&#xff0c;现在的设计人员已经做到了普遍的三维设计&#xff0c;但是进入元宇宙时代&#xff0c;就不仅仅只是三维设计了&#xff0c;我们的目…
暂无图片
编程学习 ·

【leectode 2022.1.15】完成一半题目

有 N 位扣友参加了微软与力扣举办了「以扣会友」线下活动。主办方提供了 2*N 道题目&#xff0c;整型数组 questions 中每个数字对应了每道题目所涉及的知识点类型。 若每位扣友选择不同的一题&#xff0c;请返回被选的 N 道题目至少包含多少种知识点类型。 示例 1&#xff1a…
暂无图片
编程学习 ·

js 面试题总结

一、js原型与原型链 1. prototype 每个函数都有一个prototype属性&#xff0c;被称为显示原型 2._ _proto_ _ 每个实例对象都会有_ _proto_ _属性,其被称为隐式原型 每一个实例对象的隐式原型_ _proto_ _属性指向自身构造函数的显式原型prototype 3. constructor 每个prot…
暂无图片
编程学习 ·

java练习代码

打印自定义行数的空心菱形练习代码如下 import java.util.Scanner; public class daYinLengXing{public static void main(String[] args) {System.out.println("请输入行数");Scanner myScanner new Scanner(System.in);int g myScanner.nextInt();int num g%2;//…
暂无图片
编程学习 ·

RocketMQ-什么是死信队列?怎么解决

目录 什么是死信队列 死信队列的特征 死信消息的处理 什么是死信队列 当一条消息初次消费失败&#xff0c;消息队列会自动进行消费重试&#xff1b;达到最大重试次数后&#xff0c;若消费依然失败&#xff0c;则表明消费者在正常情况下无法正确地消费该消息&#xff0c;此时…
暂无图片
编程学习 ·

项目 cg day04

第4章 lua、Canal实现广告缓存 学习目标 Lua介绍 Lua语法 输出、变量定义、数据类型、流程控制(if..)、循环操作、函数、表(数组)、模块OpenResty介绍(理解配置) 封装了Nginx&#xff0c;并且提供了Lua扩展&#xff0c;大大提升了Nginx对并发处理的能&#xff0c;10K-1000K Lu…
暂无图片
编程学习 ·

输出三角形

#include <stdio.h> int main() { int i,j; for(i0;i<5;i) { for(j0;j<i;j) { printf("*"); } printf("\n"); } }
暂无图片
编程学习 ·

stm32的BOOTLOADER学习1

序言 最近计划学习stm32的BOOTLOADER学习,把学习过程记录下来 因为现在网上STM32C8T6还是比较贵的,根据我的需求flash空间小一些也可以,所以我决定使用stm32c6t6.这个芯片的空间是32kb的。 #熟悉芯片内部的空间地址 1、flash ROM&#xff1a; 大小32KB&#xff0c;范围&#xf…
暂无图片
编程学习 ·

通过awk和shell来限制IP多次访问之学不会你打死我

学不会你打死我 今天我们用shell脚本&#xff0c;awk工具来分析日志来判断是否存在扫描器来进行破解网站密码——限制访问次数过多的IP地址&#xff0c;通过Iptables来进行限制。代码在末尾 首先我们要先查看日志的格式&#xff0c;分析出我们需要筛选的内容&#xff0c;日志…
暂无图片
编程学习 ·

Python - 如何像程序员一样思考

在为计算机编写程序之前&#xff0c;您必须学会如何像程序员一样思考。学习像程序员一样思考对任何学生都很有价值。以下步骤可帮助任何人学习编码并了解计算机科学的价值——即使他们不打算成为计算机科学家。 顾名思义&#xff0c;Python经常被想要学习编程的人用作第一语言…
暂无图片
编程学习 ·

蓝桥杯python-数字三角形

问题描述 虽然我前后用了三种做法&#xff0c;但是我发现只有“优化思路_1”可以通过蓝桥杯官网中的测评&#xff0c;但是如果用c/c的话&#xff0c;每个都通得过&#xff0c;足以可见python的效率之低&#xff08;但耐不住人家好用啊&#xff08;哭笑&#xff09;&#xff09…