简介
- 所用芯片: Cyclone IV EP4CE10F17C8
- 所用软件: Quartus-13.0.0.156 modelsim-altera
软件安装
解压
- 分别安装3个
或者
安装Quartus-13
这里,
第 1 项为 quartus 软件主包,为必装选项;
第 2 项为 quartus 软件 64 位系统支持
包,如果你的系统是 64 位的,就需要安装此包,若为 32 位的即可不用勾选,
第 3 项为 quartus的帮助选项,建议安装。
第 4 项为 modelsim –altera 的初学者版本,如果只是基础的学习和仿真,不涉及到相当多的代码内容,安装初学者版本即可完全满足条件。
如果需要仿真很大的内容,就需要选择安装第 5 项,第 5 项使用需要 license,我们可以也可以选择破解,但是不容易破解成功,所以如果没实在的必要,就只安装初学者版本即可。
第 6 项为 dspbuilder,涉及到与 matlab 联合使用,进行相关数字信号处理的开发。
安装 modelsim-altera
Quartus 破解
- 可以通过在 Quartus II 中依次点击【Tools】->【License Setup】来重新打开
- 用Quartus_II_13.0_x64破解器.exe破解C:\altera\13.0\quartus\bin64下的sys_cpt.dll文件(运行Quartus_II_13.0_x64破解器.exe后,直接点击“应用补丁”,如果出现“未找到该文件。搜索该文件吗?”,点击“是”,(如果直接把该破解器Copy到C:\altera\13.0\quartus\bin64下,就不会出现这个对话框,而是直接开始破解!)然后选中sys_cpt.dll,点击“打开”。安装默认的sys_cpt.dll路径是在C:\altera\13.0\quartus\bin下)。
- 把license.dat里的XXXXXXXXXXXX 用网卡号替换
- 在Quartus II 13.0的Tools菜单下选择License Setup,然后选择License file,最后点击OK。
- 注意:license文件存放的路径名称不能包含汉字和空格,空格可以用下划线代替。
modelsim破解
1.安装完成后复制MentorKG.exe和patch_dll.bat到Modelsim安装目录的win32aloem文件夹下
2.编辑patch_dll.bat文件,将内容改为:(路径需修改成自己的路径)
attrib -r D:\modeltech_10.1c\win32\mgls.dll
pause
attrib +r D:\modeltech_10.1c\win32\mgls.dll
pause
3.运行CMD,输入:
CD D:\modeltech_10.1c\win32
D:
attrib -r mgls.dll
attrib -r mgls64.dll
MentorKG.exe -patch .\
4.将生成的LICENSE.TXT复制到D:\modeltech_10.1c文件夹里(自己的路径)
5.添加环境变量
变量名:MGLS_LICENSE_FILE
变量值:D:\modeltech_10.1c\LICENSE.TXT(自己的路径)
安装器件库
FPGA介绍
电源供电
运行配置
原理图设计方式
新建工程
新建原理图文件
添加元器件
- 根据原理图设计一个按键按下就电亮LED,松手就熄灭的逻辑电路
编译
仿真
下载
基于原理图的宏功能模块设计
(波形发生器)
放置计数器模块
设置参数
建立内存文件
添加ROM模块
设置端口
设置(修改mydds.mif中的数据)好后进行编译.
新建嵌入式逻辑分析仪文件
设置嵌入式逻辑分析仪的时钟管脚,采样深度,硬件连接和观察变量等.
设置图形显示
下载编译运行
运行结果
正弦波生成的c代码
#include <stdio.h>
#include "math.h"
main()
{
int i,k;
for(i=0;i<256;i++)
{
k=128+128*sin(360.0*i/256.0*3.1415926/180);
printf("%d : %d;\n",i,k);
}
return 0;
}
基于verilog设计
新建工程及代码
- 新建工程
- 新建.v文件
- 二选一多路器代码如下
module alternative(
input a,
input b,
input s,
output out
);
assign out = s ? a : b;
endmodule
- 使用大学仿真,新建仿真文档
- 选择管脚
- 设置并仿真
使用modelsim仿真
- 确认安装的modelsim软件版本
- 设置quartus软件和modelsim关联路径
- 设计仿真激励: testbench
- 设置nativelink
- 运行仿真
新建.v文件用于设计仿真激励
仿真激励代码如下
`timescale 1ns/1ns //时间刻度
module alternative_testbench();
//定义激励源
reg s1,s2,s3;
wire led;
//配置模块并将激励输入模块
alternative alternative_simulation(
.a(s1),
.b(s2),
.s(s3),
.out(led)
);
//仿真
initial begin
s1 = 0; s2 = 0; s3 = 0;//改变激励
#100;//延时100个时间刻度
s1 = 1; s2 = 0; s3 = 0;//改变激励
#100;//延时100个时间刻度
s1 = 0; s2 = 1; s3 = 0;//改变激励
#100;//延时100个时间刻度
s1 = 1; s2 = 1; s3 = 0;
#100;
s1 = 0; s2 = 0; s3 = 1;
#100;
s1 = 1; s2 = 0; s3 = 1;
#100;
s1 = 0; s2 = 1; s3 = 1;
#100;
s1 = 1; s2 = 1; s3 = 1;
#100;
$stop;
end
endmodule
配置软件关联
新建脚本文件
添加脚本文件
配置modelsim路径
开始功能仿真,(下面那个是时序仿真)
放大窗口
下载
加载文件
verilog语法
模块module - endmodule
- Verilog HDL程序是由模块构成的。
- 每个模块的内容都是嵌在module和endmodule两个语句之间。
- 每个模块实现特定的功能。
- 模块可以进行层次嵌套。
模块的结构
module <模块名> (<端口列表>)
<I/O说明>
<内部信号声明>
<功能定义>
endmodule
module led (
/* 端口列表 */
input clk, //输入端口
output [3:0]follow_led //输出端口4个
);
endmodule
always过程块
- 当敏感信号表达式的值改变时候,就执行一遍块内语句。
- 同时always过程块是不能够嵌套使用的。
模板
always @(<敏感信号表达式>)
begin
//过程赋值
//if语句
//case语句
//while、repeat、for语句
//task、function调用
end
//上升沿触发,高电平清0有效
always @(posedge clk or posedge clear)
always @(posedge clk or negedge clear)
begin
if(!clear)//当clear==0时候,always会由事件驱动
qout=0;
else
qout=in;
end
initial过程块
-
initial语句主要面向功能模拟,通常不具有可综合性。
-
模拟0时刻开始执行,只执行一次
-
同一模块内的多个initial过程块,模拟0时刻开始并行执行。
-
initial与always语句一样,是不能嵌套使用的。即在initial语句中不能再次嵌套initial语句块。
initial模板
initial
begin
语句1;
语句2;
......
end
对变量和存贮器初始化
initial
begin
reg1=0;
for(addr=0;addr<size;addr=addr+1)
memory[addr]=0;
end
计数器
always @(posedge clk)begin
if(count == 25'd24_999_999)
count <= 25'd0;
else
count <= count + 1'b1;
end
数据类型
寄存器类型reg
-
在Verilog语言中,主要有三大类数据类型
寄存器数据类型、线网数据类型和参数数据类型。 -
reg类型的数据只能在always语句和initial语句中被赋值。
-
初始化不能赋初值.
//关键字reg
reg [31:0] cnt;
//定义一个32位的寄存器
如果该过程语句描述的是时序逻辑,即always语句带有时钟信号,则该寄存器变量对应为触发器,
如果该过程语句描述的是组合逻辑,即always语句不带有时钟信号,则该寄存器变量对应为硬件连线;
线网类型
- 线网数据类型表示结构实体(例如门)之间的物理连线。
- 线网类型的变量不能储存值,它的值是由驱动它的元件所决定的。
- 驱动线网类型变量的元件有门、连续赋值语句、assign等。
- 如果没有驱动元件连接到线网类型的变量上,则该变量就是高阻的,即其值为z。
- 线网数据类型包括wire型和tri型,其中最常用的就是wire.类型。
- 线网类型可以理解为模块与模块,逻辑门与逻辑门之间的连线
wire flag;
wire [1:0] cnt;
参数类型
- 参数其实就是一个常量,在Verilog HDL中用parameter定义常量。
- 我们可以一次定义多个参数,参数与参数之间需要用逗号隔开。
- 每个参数定义的右边必须是一个常数表达式。
parameter A = 4'b1010;
运算符
Verilog中的操作符按照功能可以分为下述类型。
- 算术运算符
- 关系运算符
- 逻辑运算符
- 条件运算符
- 位运算符
- 移位运算符
- 拼接运算符
算术运算符
注意除法只能整除,小数部分将被省略.
关系运算符
逻辑运算符
条件运算符
result = (a >= b) ? a : b;
位运算符
- 地位宽与高位宽运算,会将低位宽前面补零变成相同的位宽,然后再进行运算.
移位运算符
两种移位运算都用0米填补移出的空位。
左移时,位宽增加,右移时,位宽不变。
4’b1001 < < 2 = 6’b100100;
4’b1001 > > 1 = 4’b0100;
拼接运算符
c ={ a, b[3:0]
//将a和b进行拼接,然后生成c
//假设a和b都是8位宽,那么c是12位宽.
注释
- //或 /* */
//注释
/*
注释
*/
关键字
常用关键字
功能定义
- 功能定义部分有三种方法
- 1、assign语句
描述组合逻辑 - 2、always语句
描述组合/时序逻辑 - 3、例化实例元件
and #2 u1(q,a,b);
-
上述三种逻辑功能是并行的
-
注意
在always块中,逻辑是顺序执行的。
而多个always块之间是并行的。
结构语句
- #20表示延时20个单位时间.
initial语句
- initial语句它在模块中只执行一次。
它常用于测试文件的编写,用来产生仿真测试信号
激励信号),或者用于对存储器变虽赋初值。
always语句
- always语句一直在不断地重复活动
但是只有和一定的时间控制结合在一起才有作用 - always 的时间控制可以是边沿触发,也可以是电平触发.
- posedge表示上升沿
- negedge表示下降沿
- 多个信号用or进行连接
- always语句后紧跟的过程块是否运行,要看它的触发条件是否满足。
- 沿触发的always块常常描述时序逻辑行为。
- 由关键词or连接的多个事件名或信号名组成的列表称为“敏感列表”
- 电平触发的always块常常描述组合逻辑行为。
- @(* )表示对后面语句块中所有输入变量的变化都是敏感的。
或
赋值语句
Verilog HDL语言中,信号有两种赋值方式
- 阻塞赋值( blocking),如b=a,
- 非阻塞赋值( Non_Blocking),如b<=a;
所谓阻塞的概念是指,在同一个a Iways
块中,后面的赋值语句是在前一句赋值
语句结束后才开始赋值的。
所谓非阻塞的概念是指,在计算非阻塞赋值
的RHS以及更新LHS期间,允许其他的非阻塞
赋值语句同时计算RHS和更新LHS。
非阻塞赋值只能用于对寄存器类型的变量进
行赋值,因此只能用在initial块和a Iways
块等过程块中。
=和<=和的使用情况
-
组合逻辑使用阻塞赋值.
-
时序逻辑使用非阻塞赋值.
-
在描述组合逻辑的always块中用阻塞赋值=,综合成组合逻辑的电路结构;种电路结构只与输入电平的变化有关系
-
在描述时序逻辑的always块中用非阻塞赋值<=,综合成时序逻辑的电路结构;这种电路结构往往与触发沿有关系,只有在触发沿时才可能发生赋值的变化;
-
注意:在同一个aIways块中不要既用非阻塞赋值又用阻塞赋值
-
不允许在多个always块中对同一个变量进行赋值!
条件语句
if _else语句
if (a > b) begin
out = data;
end
if (a > b) out = data;
if (a > b) begin
out = data1;
end
else begin
out = data2;
end
if (a > b)
out = data;
else
out = data2;
if(表达式1)
语法1;
else if(表达式2)
语法2;
else if(表达式3)
语法3;
else
语法4;
- 条件语句必须在过程块中使用。
- 过程块语句是指由initial和always语句引导的块语句
- if语句对表达式的值进行判断,若为0,x,z 则按假处理,若为1,按真处理。
- if和else后 面的操作语句可以用beg in和end包含多个语句。
- 允许if语句的嵌套。
if(表达式1)
语法1;
else if(表达式2)
语法2;
else if(表达式3)
语法3;
else begin
if(表达式1)
语法1;
else
语法2;
end
避免锁存器
- if else要一对使用,不要只使用if,否则会生成锁存器,锁存器毛刺较多.
case语句(多分支选择语句)
- 分支表达式的值互不相同
- 所有表达式的位宽必须相等,不能用 'bx来代替n’bx,'bx默认为32位宽.
- casez
比较时,不考虑表达式中的高阻值 - casex.
不考虑高阻值z和不定值x
reg [7:0]sel; //1100_0011
casez(sel)
8'b1100_zzzz:语句1;
endcese
reg [7:0]sel; //1100_0011
casex(sel)
8'b1100_xxzz:语句1;
endcese
程序框架
模块的结构
- Verilog的基本设计单元是“模块”( block )。
- 一个模块是由两部分组成的,一部分描述接口,另一部分描述逻辑功能。
- 每个Verilog程序包括4个主要的部分
端口定义、I0说明、内部信号声明、功能定义。 - 可综合表示可以生成电路网表.
模块的调用
- 在模块调用时,信号通过模块端口在模块之间传递。
- 模块的调用也叫例化.
例化使用模块名作为关键字,然后重新起一个名字.
模块的可以被多次例化.
模块例化可以将需要使用的端口进行连接.
- 模块例化注意需要输入输出端口的位宽需一致.
第一种方式
或者
第二种方式
(该方法需要严格按照端口的排列顺序执行)
注意事项
锁存器的产生
- 组合逻辑中只使用if不使用else会产生锁存器.
- case语句中的条件没给全且不使用default会生成锁存器.