新拿到一款裸板子(时间紧可以不读)
写在前面
作者之前学过DSP,但是这两个东西的逻辑完全不同,因为DSP中的所有模块都已经搭建好,官方设计了所有模块的调用接口,我们只需要调用即可,所以大多数引脚都是预定义的,我们最多只能选择复用功能;而FPGA中除了特定的IP核之外所有的模块都需要通过自己来写,所有的引脚都有自己定义是什么功能(user design)
人生第一块中端的FPGA
作者拿到的板子是 Altera C.. E15F15C8N,系统由两块独立的板子组成,外设所在板子(专业名词叫底板),芯片所在板子(专业名词叫核心板);两个板子均可以单独使用,所以都有电源!!!,当两个板子直接相连的时候,可以使用一个即可,如果使用了一个电源下发现烧录没有现象,首先检测两块板子是否插反了!!如果插反了两套电源都上电,+5;-5直接相反通过芯片连接,天下芯片烧糊一个味儿。我的第一块就这么死了,死了,死了。板子走好,给你烧纸埋葬。
问题集合
系统时钟是哪个引脚?
看数据手册。
给FPGA设计点功能:design 模块module by Quartus 2
Quartus 2使用
new project wizard - 工程名 - top module 名称(一定要与写的顶层module的名称一致)
没有ep4ce15f17c8n。不过有ep4ce15f17c8l,这几个能够通用吗?
问题集合
三态逻辑tristate是啥?
允许0,1之外存在高阻态。
TCL脚本文件,是脚本映射文件。
设置引脚定义的几种方式:
- 直接打开assignment -> pin planner 或者直接点击图标打开 pin planner。
- file -> new -> tcl script file -> 定义引脚映射,语法为:set_location_assignment
-to key_in[0](变量名称)
分频计算
step1 原有频率先分频;就是把频率分成原来的多少分之一,然后1/f_now=T_now.
cannot find design entity
找不到设计实体,说白了就是找不到文件。
原因:新建工程之后没有new -> Verilog file 建立新的文件 -> 建立好新的文件之后 -> 添加到工程 。
Verilog
阻塞和非阻塞
初始值
a = 1;b = 2; c= 3;
阻塞 =
b = a;
c = b;
流程分析:代码串行执行,即从上到下每条语句都必须按顺序依次执行,所以执行 b = a时将a的赋值给b; 然后执行 c = b,将更新之后的b的值赋值给a;
结果: c=b=a=1;
非阻塞 <=
b <= a;
c <= b;
流程分析:代码并行执行,把这两条语句看成 a,b同时往左跑,并且同时到终点,所以b和c同时被a和b赋值。
结果: c=2 b=1 a=1
区分
串行和并行的区别!
reg 和 wire的区别
assign & always
reg 能够储存住数据
wire 数据一直跟随等式表达式变化
验证设计的模型module是否工作:仿真
在.v文件中,具有某种功能的.v文件已经设计好了具有某种功能的module,验证这个文件有两种方式,
仿真
方式一
烧到FPGA中,这样module的输入由FPGA片上的模块如时钟和外接引脚来给定,输出由片上指定的外设如LED灯等等来规定。通过给定不同的输入并且观测相应的输出就能够判定设计的module是否能够实现某种功能。
方式二
编写一个程序,给模型module设计输入,检测模型module的输出(时序示波器:就是波形图);然后根据所给输入输出的关系来判定所设计module是否能够实现所需功能。
使用方式二:ModelSim仿真验证
https://www.eefocus.com/nightseas/blog/12-03/242395_7df71.html
将Quartus与ModelSim相互关联
调用EDA库文件,ModelSim中添加win64文件。
工程建立
新建project-》添加文件-》compile -》full dubeg model -》add to wave将信号全部添加到波形窗口 -》 文件所在的路径 -》 路径toggle leaf name 就可以去掉路径只显示信号名。-》unsigned 可以调整为十进制显示。
想要仿真设计的文件,就需要给定输入信号,测定输出信号,然后观察是否符合要求即可。
给定输入,探测输出的程序编写:Testbench编写
Testbench包括三个部分:信号定义,模块接口和功能代码;与verilog相似却不同,
信号定义:
仿真文件的骄傲:我跟verilog就是不一样,如下:
input 和 output 变量的类型
由于module定义中的input变量全部都是wire变量,无法存储当前数值,即外面输入啥就是啥,如果外面输入没有信号,那么module输入就没有信号,这是必须避免的,所以外面提供给module的信号必须要一直存在,即能够储存数值,所以必须使用寄存器reg类型的变量。
同理,由于module的输出变量一直都存在,不能突然消失,所以module的输出变量为reg类型,而要检测输出的reg类型的数值,检测值必须时时刻刻与module的输出值相同,所以为wire类型。
信息如所偷盗的图片所示:
所以仿真文件的module是这样子滴
`timescale <时间延迟精度>/<仿真时间精度> //这句话用来设定仿真的精度
module exam();
reg rst_n;
reg clk;
reg data;
输入信号有什么规定呢? initial块
先来讲讲语法
- 语法一
#<时间数字>
延迟<时间数字>*<时间延迟精度>的时间
`timescale 1ns/1ps
......
#5 <代码> // 代表延迟 5ns在执行<代码> ```
- 语法二
initial
begin
<我是初始值设定代码>
end
begin & end 之间的内容只执行一次。
- 语法三
尽管和Verilog写module文件时有诸多不同,但是有一最核心的点是相同的:在两种文件中每个代码块 都是并行执行的。
- 语法四
while(1)
<想要死循环的代码>
再来说说套路
- 套路一
时钟一般都是用always 完成,但是必须要在initial中初始化一下
initial
begin
mclk = 0;
end
always
begin
#10 mclk = ~mclk;
end
- 套路二
我的always 很少加@()
其实@(<>) 就是 条件判断语句
@(posedge mclk)
if mclk 此时刻是上升沿。
而在 verilog中的
always@(posedge mclk)
翻译一下就是
每当 if mclk 达到上升沿
就执行...
那么always 后不加条件又是什么呢
while(1) //开心地死循环
- 套路三
花式initial:想在这里写时钟
initial
begin
mclk=0;
while(1)
mclk=~mclk
end
有一个必备的条件
复位一定要写
initial
begin
rst_n = 0;
#100 rst_n = 1;
end
写好了 testbench
设置将testbench与quartus相连接即可。
如何连接
接下来就是使用quartus调用modelsim-altera进行仿真!
作者使用Quartus ii 17.0调用自带的modelsim-altera进行仿真时遇到了没有波形的问题,
我是解决方法
FPGA中的spi
厚积薄发,厚积薄发,厚积薄发
通过FPGA能够把一个东西编清楚才是真正的明白!
toggling edge 表明发送数据变化的沿,
sampling edge 表示采集数据的沿。
CPOL=0 规定时钟空闲时为低电平,而不是使能端空闲时为低电平!
CPHA=0(clock phase):只要时钟发生变化,第一个变化的沿就是sampling edge采样沿。
eg. CPOL = 0; CPHA = 0;时钟空闲时为低电平,时钟第一次变化的沿:上升沿即为采样沿。
eg. CPOL = 1; CPHA =0; 时钟空闲时为高电平,时钟第一次变化为下降沿:所以下降沿为采样沿。
Quartus 2 报错
quartus 10170
- 搜索了一下有以下几种可能
出现此错误一般有以下三种情况:
1.某一句代码后面缺少“;”;
2.begin 和end不对应;
3.某一个变量在always语句中等号的左边却没有定义成reg类型。
的确是这种问题,把原来的统统删除,重写就好了!
将出现问题的代码注释掉后发现是顶层实体和定义的module名称不同
FPGA的引脚分配
不是所有引脚都能随便用的(废话,电源地怎么随便用?),所以该怎么用呢?
先看类型,搞清楚这么多符号是什么含义:
别看这么多符号,形状就5个:圆形,三角,正方形,五边形&六边形。
- 三角形:正三角形是电源,倒三角形是GND,三角中间有O是管脚的电源,中间有I是内核电源,
为什么三角形内会写不同的字母呢?因为FPGA中不同的位置需要不同的电压等级,eg.FPGA内核仅仅需要1.2V电压,而外接IO通常是5V,所以为了加以区分使用中间写上字母来加以区分。
所有圆形的引脚都是可以由用户直接使用的。
因为引脚比较多,因此将整个芯片的所有引脚划分成了若干个bank,1-8一共8个bank,正方形且内部有上升下降沿的图标代表全局时钟信号,五边形标记的图标为配置引脚(上图虽然没有,但是在右侧的说明栏中能够找到)
关于引脚的设置,存在以下问题
- I/O standard究竟有什么用途? 按照https://wenku.baidu.com/view/394b592c6137ee06eef9182b.html中所说,一般同一个bank中的I/O standard是相同的,一般不需要修改。
注意:
SPI 通信中CPOL=0;CPHS=0;表示下降沿切换数据,又因为FPGA中非阻塞指令是并行的,因此在发送数据的同时FPGA的时钟信号SCK拉低。在接收端接收信号的同时SCK拉高。
报错:因为仿真文件和module文件名称相同,所以一定注意是哪个在报错!。
逻辑错误:verilog testbench 文件中的 always块只运行一次,代码如下
always @(negedge O_tx_done)
begin
I_tx_en = 0;
#300;
if (I_data_in == 8'hff)
begin
I_data_in = 0'h00;
I_tx_en = 1;
end
else
begin
I_data_in = I_data_in + 8'h01;
I_tx_en = 1;
end
if (cnt == 4'hff)
begin
cnt = 4'h0;
end
else
begin
cnt = cnt + 4'h1;
end
@eachvec;
end