FPGA有两种硬件描述语言,一个是Verilog,一个是VHDL。Verilog适合系统级,算法级,寄存器传输级,逻辑级,门级和开关电路级的设计,而VHDL更适合特大型的系统级设计。由于一开始接触的是Verilog,所以学的是verilog。
#程序实例参考手边三本书
1、标准模版
module<模块名>(模块端口列表)
声明语句
模块组项
函数和任务定义
Specify块
endmodule
*这里要分清模块和单元的概念,单元组成模块,有些小的单元(像以后会写到的阻塞赋值,8位乘法器这样的)是有自己的定义的,像时钟产生器这种能当作系统的子单元的才能算模块。(个人理解,有错提出必改正!)
2、声明语句
Parameter:参数声明语句
Input:输入端口声明语句
Output:输出端口声明语句
net-type:连线类型变量声明语句
register-type:寄存器类型变量声明语句
time:时间型变量声明语句
integer:整数类型变量声明语句
real:实数类型变量声明语句
event:有名事件声明语句
*声明语句,用在开头
3,模块(也称建模):行为描述模块,数据流描述模块,结构描述模块
(1),数据流描述方式
主要用assign连续赋值语句,包括显式和隐式两种。
显式:连线型变量类型[连线型变量位宽]连线型变量名
assign#(延时量)连线型变量名=赋值表达式
隐式:连线型变量类型(赋值驱动强度)[连线型变量位置]#(延时量)连线型变量名=赋值表达式
#assign连续赋值语句的功能:当赋值表达式中变量的值发生变化时,重新计算赋值表达式的值,并在指定时延后将所得到的结果赋给左端的连线型变量。
(时延定义了右边的表达式操作数变化时间对左边变量进行赋值时刻之间的延迟时间,如果没有定义,缺省时延为0。)
[assign语句只能用来实现组合功能。]
例:与非门的数据流描述
module NAND(a,b,out);
input a,b;
output out;
assign out=~(a&b);//连续赋值语句
endmodule
*类似于C中的顺序结构吧,但是概念上要广一点,打个不恰当的比方就是:一条流水线,正常运转条件在监控下一点事都没有,一但出了问题赶快采取措施。
(2),行为描述方式
行为语句:initial 语句:只执行一次
always语句:循环执行
(只有寄存器类型数据能在这两种语句中被赋值!!寄存器类型数据在被赋值之前保持原有的数值不变。所有的initial和always语句在0时刻并发执行。)
例:1位加法器(有个长的好像@的符号打不出来,暂时就用@代替了)
module ADDER(a,b,cin,sum,cout);
input a,b,cin;
output sum,cout;
reg sum,cout;
reg t1,t2,t3;
always @(a or b or cin)
sum=(a^b)^cin;
t1=a&cin;
t2=b&cin;
t3=a&b;
cout=(t1|t2)|t3;
end
endmodule
*类似于C中的循环结构,一但不满足条件就跳出循环!
(3),结构描述方式(通过实例进行描述)
把预定义里面的基本元件实例放到语言中,监控实例的输入变化,一旦改变就重新运算并输出相应的值。
四种可用来描述的部件:用户自定义的模块/用户自定义的UDP/内置门级元件/内置开关级元件
例:由两个NAND生成的与门结构型描述
module AND(a,b,out);
input a,b;
output out;
wire w1; //内部连线w1连接两个模块
NAND NAND1(a,b,w1); //实例1
NAND NAD2(w1,w1,out);//实例2
endmodule
*前两种都没有这种直观,这种直接举例说明,把例子引入程序中,如果是正确的就继续,错误的就跳出来。
(4)混合型描述方式
略
*听名字就知道是三种杂糅了。。= =
4,数据类型
(1),物理数据类型
连线型数据 (连线型数据不能储存值,而且必须要受到驱动器或者assign语句的驱动,如果没有驱动,变量为高阻z)
常用变量:wire(单个门驱动或assign驱动),tri(多驱动)
寄存器型数据 (数据存储单元的抽象)
关键字reg(缺省是为1位数)
#reg常用来表示触发器,always内被赋值的每一个信号都必须定义成reg型。
memory型数据(通过扩展reg型数据的地址范围生成)
建立存储器数据的格式:
//存储器的例子
parameter //实时参数
wordsize=16;
memsize=256;
reg[wordsize-1;0]mem[memsize-1;0];
writereg,readreg;
*之前已经说过FPGA的概念了,wire用来连接单元和模块,寄存器用来存储信息,驱动器用来驱动硬件,触发器相当于一个使能端。
(2)抽象数据类型(纯数学的抽象描述,不与任何实际的物理硬件电路相对应)
interger整型,time时间型(常与系统函数$time一起使用),real实型(可用于对延迟时间的计算),parameter参数型。
#以上两种数据的变量在定义时两端需设置位宽,当为缺省状态时位宽默认为1位。变量的每一位可以取0,1,x或z中任意值。
(x表示一个未知初始状态的变量或者由于多个驱动源试图将其设定为不同的值而引起的冲突(FPGA的时序问题),z表示高阻状态或者浮空量)
用户1677248 2014-3-10 12:48
用户444552 2014-3-10 08:51
用户381237 2014-3-8 12:04
Hoki 2014-3-7 15:51
加油