赞
踩
这个教程写的很好,可以多看看。本篇还没整理完。
什么是FPGA?一种可通过编程来修改其逻辑功能的数字集成电路(芯片)
与单片机的区别?对单片机编程并不改变其地电路的内部结构,只是根据要求实现的功能来编写运行的程序(指令)。举例:单片机就两个uart,但是我想用4个uart,单片机就没办法了。
什么是HDL?(hardware description language)硬件描述语言,用于描述数字电路结构和功能的语言。
Verilog和C的区别?Verilog是硬件描述语言,在编译下载到FPGA之后,会生成电路,所以Verilog是并行运行的。C语言是软件编程语言,编译下载到单片机之后,是存储器中的一组指令。而单片机处理软件指令需要取指、译码、执行,这个过程是串行执行的。
0:逻辑0,逻辑假。
1:逻辑1,逻辑真。
X:未知,高或低。
Z:高阻态,外部没有激励信号,是一个悬空状态。
二进制(b)、八进制(o)、十进制(d)、十六进制(h)。
- 举例:
- 8'b10101010
- 16'h10c8_fc9a
- //_可以增加可读性
-
- //直接写数字,默认十进制。
- //不指定位宽,编译器自动分配
-
- //负数,按位取反加一,符号位在最高位。
- -15 = -5'b10001
-
- //科学计数法
- 1.2e4 //12000
-
- //字符串
- reg[15*8-1:0] string;
- initial begin
- string = "Hello World!";
- end
用于定义模块名、端口名、信号名。
字母、数字、$符号、_下划线。第一个字符必须是字母或者下划线。
严格区分大小写。
不建议大小写混合使用。
普通内部信号建议全部小写。
- wire[3:0] add;
- reg[7:0] data;
- reg[7:0] counter[3:0];//3个8bit数组
- wire data[7:0][3:0];二维数组
- reg[31:0] data_bits[7:0][2:0][3:0];三维数组
-
- //赋值
- counter[3] = 4'hF ; //将数组counter中第4个元素的值赋值为4bit 十六进制数F,等效于counter[3][3:0] = 4'hF,即可省略宽度;
- assign data[0][1] = 1'b1; //将数组data的第1行第2列的元素赋值为1,这里不能省略第二个访问标号,即 assign data[0] = 1'b1; 是非法的。
常量,类似#define。可以一次定义多个参数,参数与参数之间需要用逗号隔开。每个参数定义的右边必须是一个常数表达式。
1.参数的传递
模块定义的时候传入参数,模块实例化的时候传入参数。
2.时序仿真中的延时
- //延时2.5个时间单位后执行sys_clk_i信号的翻转
- always #2.5 sys_clk_i = ~sys_clk_i;
算数运算符:+、-、*、/、%
关系运算符:>、<、<=、>=、==、!=
逻辑运算符:!、&&、||
条件操作符:?:
位运算符:~、&、|、^
移位运算符:<<、>>;注意:左移位宽要增加、右移位宽不变。
拼接运算符:{}。{a,b[3:0]}
用于定义时延、仿真的单位和精度
`timescale time_unit / time_precision
//、/**/、
模块的结构
一个模块由两部分组成:一部分描述接口,一部分描述逻辑功能。
端口定义、IO说明、内部信号声明、功能定义。
模块的调用
只执行一次。
常用于测试文件的编写,用来产生仿真测试信号(激励信号),或者用于对存储器变量赋初值。
一直不断地重复活动。
但是只有和一定的时间控制结合在一起才有作用。
always时间控制可以是沿触发或者电平触发。敏感列表。
沿触发:
多个信号中间要用or连接。(posedge,negedge)
电平触发:(*)
b = a;
描述组合逻辑时,用阻塞赋值。
b <= a;
只能用于对寄存器类型的变量进行赋值,只能用于initial和always中。
描述时序逻辑时,用非阻塞赋值。
注意:在同一个always块中不要既用非阻塞赋值又要阻塞赋值,不允许在多个always块中对同一个变量进行赋值。
任意时刻输出仅仅取决于该时刻的输入,与电路原来的状态无关。
任意时刻的输出不仅取决于当时的输入信号,而且还取决于电路原来的状态。或者说还与之前的输入有关,因此时序逻辑必须具备记忆功能。
条件语句必须在过程块(initial、always)中使用。
0,x,z按假处理。
if和else后面可以用begin end包含多个语句。
位宽必须相等。
casez,不用考虑表达式中的高阻值。
casex,不用考虑高阻值z和不定值x。
任务在模块中任意位置定义,并在模块内任意位置引用,作用范围也局限于此模块。
模块内子程序出现下面任意一个条件时,则必须使用任务而不能使用函数。
对 output 信号赋值时也不要用关键字 assign。为避免时序错乱,建议 output 信号采用阻塞赋值。
- task task_id ;
- port_declaration ;
- procedural_statement ;
- endtask
- task xor_oper_iner(
- input [N-1:0] numa,
- input [N-1:0] numb,
- output [N-1:0] numco ) ;
- #3 numco = numa ^ numb ;
- endtask
task_id(input1, input2, …,outpu1, output2, …);
输入端连接的模块内信号可以是 wire 型,也可以是 reg 型。输出端连接的模块内信号要求一定是 reg 型。
在有限个状态之间按一定规律转换的时序电路
状态寄存器由一组触发器组成,用来记忆状态机当前所处的状态,状态的改变只发生在时钟的跳变沿。
状态空间定义
状态跳转(时序逻辑)
下个状态判断(组合逻辑)
各个状态下的动作
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。