FPGA学习笔记(1)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
笔记(一)
1.声明模块时输入变量(input)必须是是wire型变量,输出变量(output)可以是wire型变量也可以使用reg型变量
2.reg型变量必须在always块中赋值,wire型变量只在assign中赋值
3.if(!rst_n)等价于if(rst_n==0)//需要仔细体会
4.声明端口时可以把放在内部也可以放在外部。
例:
基于接口名称的模块例化(推荐)
module cnt(
input wire sclk,
intput wire rst_n,
input wire [7:0] d,
output reg [7:0] q
);
endmodule
基于顺序的模块例化(不推荐)
module cnt (sclk,ret_n,d,q);
input sclk, rst_n;
input wire [7:0] d;
output reg [7:0] q;
endmodule
总结:推荐使用新规范
5.begin...end在RTL代码中仅仅可以理解为“()”的意思,在在多条语句同时执行时必须要加;而在行为级仿真(编写tb脚本文件)时则表示顺序执行
6.一般低电平有效用“_n”或者“_b”来表示,例:rst_n表示低电平复位
7.一般的时钟、信号、模块名可以使用简写更明确地定义,例:system_clock(系统时钟),可以简写为送sclk
8.initial块中只能对寄存器变量进行赋值,一上电只执行一次
9.例化模块的时候如果原始模块是输出信号,那么括号内必须是wire型变量;如果原始信号是输入信号,括号内可以是wire型变量也可以是reg型变量
10.编写Verilog和testbench时可以直接使用文本文件进行编写,只需将后缀写改为.v即可,打开Modelsm时需要首先新建一个工程,然后将两个都添加进来
笔记(二)
1.对多条语句进行赋值时需要使用begin...end语句将其包含在内
2.case(一个控制选择多个输入端输出)在电路上对应一个编码器或者一个译码器,相对于if...else(每一个if...else会生成一级寄存器)速度上要快很多
3.不同功能的寄存器分开always块来写,这样代码的可维护性强,可读性强
4.再设计硬件电路时心中要有一个大体电路的结构描述,包括对寄存器和各种电路模块的理解
5.initial初始化的目的一上电就执行一次
6.case语句后一定不要忘记加default,否则会产生不必要的电路或者错误
7.alway后的敏感列表必须要完整(赋值语句右边的变量要加全),否则会生成锁存器(危害
极大,延时时间不固定,布线规则不固定,使时序约束无法分析)
8.芯片中的为了能产生较短的延时时钟的布线一律采用金线
9.关于task任务:做一些协议或用testbench产生一些数据时使用十分方便
任务的定义:
task send_data(len); //任务的声明
integer len, i; //变量声明区
begin //必须加begin和end
for(i = 0; i < len; i = i + 1) begin //循环语句
@(posedge sclk); //for语句中必须有延时,否则i加满后自动清零,使之没有数据
i_addr <= i[7:0];
i_data <= i[7:0];
end
i_addr <= 0;
i_data <= 0;
end
endtask
任务的调用:
send_data(100);
笔记(三)
1.有限状态机(FSM):因为FPGA是并行处理的,想要做一些前后顺序的事件处理的时候引入的状态机制
2.有限状态机是由寄存器组和组合逻辑构成的硬件时序电路;其状态(即由寄存器组的0和1组合状态所构成的有限个状态)只能在同一时钟跳变沿的情况下才能从一个状态转向另一个状态;究竟转向哪一状态不但取决于各输入值,还取决于当前状态;状态机可用于产生在时钟跳变沿时刻开关的复杂的控制逻辑,是数字逻辑的控制核心
3.流水线:在组合逻辑中插入寄存器,把一个本身是组合逻辑处理的事件,分成几个寄存器段来进行处理
4.在写状态机时要先画状态迁移图
5.一般在描述状态机时选择用两段式较好,其中一个always模块采用同步时序的方式描述状态转移;另一模块采用组合逻辑的方式判断状态转移条件,描述状态转移规律(状态的输出)
6.独热码:每一个状态用一个bit表示,独热码占用寄存器数量多,但是组合逻辑资源较少,较适用于状态机的编码。例:if(state==4'b0001)综合器会优化为if(satate[0]==1'b1),由四位比较转化为一位比较,所以是高速的
7.使用parameter定义状态的编码
8.Verilog语言对大小写敏感和VHDL语言不同
9.后仿真:带有器件的延时文件的仿真
10..vo是网表;.sdo是标准延时文件
11.状态机代码编写思路:首先要读懂状态迁移图,确定输入、输出以及状态的个数,大概需要几位对状态进行编码;写代码首先把输入、输出定义好;对状态进行编码;采用两段式进行描述第一段写状态的转换(用case语句),第二段写状态的输出(用if...else语句)
笔记(四)
1.声明变量是要统一放在接口区的下面
2.位拼接符:{7’b1010_000,3’b010}转换为10’b1010_000_010;可以实现移位的功能:a=4’b1010;{0,a[3:1]}转换为4’b0101;相当于右移了一位
3.在always块中的组合逻辑使用非阻塞赋值和阻塞赋值所生成的电路没有差别,但是为了统一推荐使用非阻塞赋值
4.always块中写组合逻辑式敏感列表一定要写全:可以在使用*,表示全部的都包含;条件列表里的所有变量,以及赋值语句右边的所有变量
5.端口输出最好加一级寄存器,可以优化时序
6.关于存储器变量的声明:reg [7:0] mem8x16 [15:0];//声明位宽为8位,深度为16的memory变量
7.Modelsim GUI仿真流程:
打开Modelsim软件,建一个工程文件夹,建立Modelsim仿真工程;
在用户窗口界面加入需要仿真的多有代码和库文件;
编译所有文件;
选择testbench顶层文件启动仿真;
选择所要观察的目标信号,并将其加入到波形观察窗口,如需更改bus显示数据格式还需要进一步设置。如进制转换,模拟波形切换;
设置仿真运行时间,启动仿真波形绘制;
如果下一次启动有其他文件更改或者删除还需要重复以上步骤的部分或者全部。
8.Modelsim do文件的自动化仿真
建立库;
映射库到物理目录;
编译源代码;
启动仿真器;
执行仿真。
9.vlib:创建库(就是创建文件夹)。格式vlib
10.vmap:映射逻辑库名,将逻辑库名映射库路径。语法格式vmap work
11.vdir:显示指定库的内容。语法格vlib-lib
12.vlog:编译Verilog源代码,库名缺省编译到work本地库,文件按顺序编译。语法格式vlog-work
13..do文件的注释符号为’#’
14.Modeslim是不识别中文的,输入或者显示中文注释都会是乱码
15.直接在Moedlsim的命令行里输入或者写到文本里quit -sim(退出当前仿真功能),.main clear(清楚命令行显示信息)
16.vlog -work work ./../design/*.v #../表示上一层目录,/*.v用通配符(*)表示添加所有的.v文件
17.vsim -voptargs=+acc work.tb_ex_shift_reg #启动仿真(启动顶层);voptargs=+acc设置优化参数启动仿真,该优化参数不会优化内部的信号(记住该通用方法)
笔记(五)
1.在Quartus中调用IP核时最好新建一个存储IP核的文件夹,文件夹名字最好命名为ipcore_dir(和ISE中自动新建的文件夹的名字一样)