学习板:ZYNQ7020
- 一、可编程逻辑器件
- 1、概念
- 2、常见的可编程逻辑器件
- 3、FPGA与单片机的区别
- 4、HDL
- 5、Verilog与C的区别
- 二、逻辑值
- 三、符号
- 1、空白符(White Space)
- 2、注释(Comment)
- 3、标识符(Identifier)
- 4、关键字(Key Word)
- 5、运算符(Operator)
- 四、常量
- 1、整数(Integer)
- 2、实数(real)
- 3、字符串(String)
- 4、字符串中的一类特殊字符
- 五、数据类型
- 1、net型
- (1)wire型
- (2)tri型
- 2、variable型
- (1)reg型
- (2)integer型
- 六、参数
- 1、参数parameter
- 2、参数localparam
- 七、向量
- 1、标量与向量
- 2、位选择和域选择
- 3、储存器
- 八、运算符
- 1、算术运算符
- 2、逻辑运算符
- 3、位运算符
- 4、关系运算符
- 5、等式运算符(有个重要知识点)
- 6、缩减运算符
- 7、移位运算符
- 8、指数运算符
- 9、条件运算符
- 10、位拼接运算符
- 11、运算优先级
对于常见的89C51、STM32、Arduino等等单片机来讲,内部电路连接是固定的,即内部的逻辑功能是固定不变的,要想改变它们的逻辑功能,就必须重新设计电路,改变内部各单元电路的连接。
而对于可编程逻辑器件(Programmable Logic Device)(PLD),用户可以自行修改内部连接,这种PLD内部电路结构可以通过写入编程数据来设置,当然写入后也可以擦除重写。用户可以根据自己的需求来设置内部电路的逻辑功能。
2、常见的可编程逻辑器件常见的可编程逻辑器件有:
(1)CPLD
复杂可编程逻辑器件(Complex Programmable Logic Device)
(2)FPGA
现场可编辑门阵列(Field Programmable Gate Array)
俩者的差异本质差异在于电路结构不同:
CPLD:基于乘积项的与或逻辑阵列
FPGA:基于“查找表”的CLB阵列
3、FPGA与单片机的区别FPGA是一种可通过编程来改变其逻辑功能的数字集成电路;而对单片机编程并不能改变其电路结构。
通过FPGA编程后,生成电路,通过逻辑功能达到我们的目的;而对单片机编程后,会转换指令,单片机处理软件指令:取指、译码、执行…取指、译码、执行…一步步执行下去
4、HDLHDL(Hardware Description Language),硬件描述语言。用于描述数字电路结构和功能的语言。
HDL 可以在不同的层次对数字电路的结构、功能和行为进行描述。它所描述的电路可以通过综合工具(如Vivado软件)将其转换为门级电路网表,然后将门级电路网表与基本元件一一对应起来,再通过布局布线工具转换为电路布线结构。
5、Verilog与C的区别Verilog语言是硬件描述语言,编译下载到FPGA后,会生成电路,而不同模块的电路执行可以独立执行,所以可以说verilog语言是并行执行的。
C语言是软件编程语言,编译下载到单片机后,生成的是指令。单片机必须通过:取指、译码、执行…取指、译码、执行…来完成功能,所以可以理解为是串行执行。
即可以说Verilog语言是并行执行,也可以说FPGA是并行执行;既可以C语言是串行执行,也可以说单片机是串行执行。这既是Verilog与C的区别,也是FPGA与单片机的区别。
二、逻辑值逻辑 0:表示低电平,也就是对应我们电路的 GND;
逻辑 1:表示高电平,也就是对应我们电路的 VCC;
逻辑 X:表示未知,有可能是高电平,也有可能是低电平;
逻辑 Z:表示高阻态,外部没有激励信号时是一个悬空状态。
Verilog程序由各种符号流构成,这些符号包括:空白符(White Space)、运算符(Operator)、数字(Number)、字符串(String)、注释(Comment)、标识符(Identifier)、关键字(Key Word)等
1、空白符(White Space)Verilog语言中的空白符包括:空格、Tab、换行符
verilog语言可以不分行,例如:
initial begin ina=3'b001;inb=3'b011;inc=3'b111;end
等效为:
initial begin ina=3'b001; inb=3'b011; inc=3'b111; end
空白符只是为了使代码错落有致,阅读起来更加方便,在代码被综合时空白符会被忽略。
2、注释(Comment)注释与c语言一样:
(1)单行注释
以“//”开始,到本行结束
(2)多行注释
以“”结束
标识符用于用户在编程时给Verilog对象、模块、端口和实例起名字
标识符由 字母、数字、“$”、和"_"(下划线)组成。并且第一个字符必须是字母或者下划线。标识符最长可包含1023个字符 。
还有一种标识符为转义标识符,它与C语言的转义标识符一样,以反斜杠“”开头,空白符结尾。
4、关键字(Key Word)Verilog的关键字有很多,1995年发布标准后,在2001年又进行了修订,目前最常见关键字有
与C语言类似(本博八中详细总结)
四、常量Verilog的常量主要有三种:整数、实数、字符串
1、整数(Integer)整数的书写格式:
(+或-)(位宽)’(进制符)(值)
进制符与C语言一致:
①二进制:b或B
②八进制:o或O
③十进制:d或D
④十六进制:h或H
例如:
8'b11000111 //位宽为8的二进制数11000111 8'Hd5 //位宽为8的十六进制数d5 变为二进制:11010101 5'O23 //位宽为5的八进制数23 变为二进制:10011 5'd6 //位宽为5的十进制数6,变为二进制:00110
在位宽 与 '之间、进制数与数值之间允许出现空格,格式:
(+或-)(位宽)<空格>’(进制符)<空格>(值)
例如上面的例子,中间插了空格
8 'b 11000111 //位宽为8的二进制数11000111 8 'H d5 //位宽为8的十六进制数d5 变为二进制:11010101 5 'O 23 //位宽为5的八进制数23 变为二进制:10011 5 'd 6 //位宽为5的十进制数6,变为二进制:00110
其它地方出现空格是非法的!
书写整型变量时,注意以下几条规则:
(1)较长的数值可以用下划线分开,不要求每隔4位加一个下划线,可以任意加在某几个位置,它本身没有意义,只是为了代码的可读性(注意第一位不能是下划线)。例:
16'B 1001_1011_1111_0000 13'b 1_0011_0100_1110 13'b 1_001_101_001_110
(2)如果没有定义位宽,则默认为32位,例:
'b 111 //为二进制 0000 0000 0000 0000 0000 0000 0000 0111 'd 123 //10进制数,变为二进制 0000 0000 0000 0000 0000 0000 0111 1011
(3)如果定义的位宽比数值的长度长,需要在前面补零。例:
5'b 111 //为二进制 00111 10'd 123 //为二进制 00 0111 1011
(4)如果定义的位宽比数值长度短,则左边的部分被截掉。例:
5'b 101_1111 //为二进制 11111 3'd123 //为二进制 011
(5)未知态x、高阻态z在二进制中代表1位x或z;在八进制中代表三位x或z;在16进制中代表四位x或z。例:
5'b111zz //为二进制111zz 8'O23z //为二进制10011zzz 18'O12z3z //为二进制 000 001 010 zzz 011 zzz 16'Hz5Ax //为二进制 zzzz 1001 1010 xxxx
(6)整数可以带正负号,并且正负号必须写在最前面。负数通常表示为二进制补码的形式
(7)当位宽和进制符默认时,认为是十进制、32位数。例:
32 //为十进制数32,二进制数:0000 0000 0000 0000 0000 0000 0010 0000 123 //为十进制数123 ,二进制数:0000 0000 0000 0000 0000 0000 0111 1011
(8)在位宽 与 '之间、进制数与数值之间允许出现空格,格式:
(+或-)(位宽)<空格>’(进制符)<空格>(值)
上面总结过了。
(9)在2001修订后,扩展了带符号的整数定义。例:
8'sh3a //一个十六进制带符号整数 3a2、实数(real)
rerilog不像c语言那般,有float、double类型。对于浮点型数据,都是定义为实数(real)类型。
例:
real a,b; initial begin a=16/10; b=16/1.1; end
实数的表示方法有以下几种:
(1)十进制表示法
例如:
1.0 3.1415 0.1
需要注意的是小数点俩边都必须有数字(与c语言不同),如以下表示是错的:
3. 0. .3 //三者都是错误表示法
(2)科学计数法
12_345.56E3 //值为123456.0 314159E-5 //值为3.141593、字符串(String)
字符串是双引号内的字符序列,字符串不能分成多行书写。
Verilog中采用reg类型变量来储存字符串,例如:
reg [8*12:1] stringval; initial begin stringval="Hello world!" ; end4、字符串中的一类特殊字符
例如:
123 //八进制数123对应的ASCII字符,即字符S五、数据类型
Verilog中主要有两种数据类型:net型和Variable
1、net型net型数据相当于电路中的各种物理连接,其特点是输出的值随着输入的值的变化而变化。
net型数据不能储存值,它的值由驱动它的元件所决定。net型变量有两种驱动方式:
①在结构描述中将其连接到一个门元件或模块的输出端;
②用持续赋值语句assign对其进行赋值。
如果没有驱动元件连接到ne类型的变量上,该变量的值为高阻Z(trireg除外)
常用的net型变量:
着重总结一下最常用的两种net型数据类型
(1)wire型Verilog模块中的输入和输出信号没有明确指定数据类型时都被默认为wire型。
wire型信号可用作任何表达式的输入,也可以用作assign语句和实例元件的输出。
wire型取值可为:0、1、x、z,如果wire没有连接到驱动,其值为高阻态z。
wire型变量定义格式:
wire 数据名1,数据名2....数据名n;
例如定义两个位宽为1的wire型变量a,b:
wire a,b;
如果定义多位宽的wire型变量,例如总线,则格式:
wire[n-1:0] 数据名1,数据名2....数据名n;
或者
wire[n:1] 数据名1,数据名2....数据名n;
例:
wire[7:0] databus; //定义位宽为8的数据总线 wire[15:0] addrbus //定义位宽为16的地址总线
或
wire[8:1] databus; //定义位宽为8的数据总线 wire[16:1] addrbus //定义位宽为16的地址总线(2)tri型
tri与wire功能和使用方法完全一致。对应Verilog的综合器来讲,对tri型数据和wire型数据的处理是完全相同的。定义为tri型只是为了增加程序的可读性,可以更清楚地表示该信号综合后的电路连接具有三态的功能。
2、variable型variable型变量必须放在过程语句中,如initial、always,通过赋值语句进行赋值。而且在initial、always等过程块内被赋值的信号必须定义为variable型。在综合器综合时,根据其被赋值的具体情况确定是映射连线还是映射成为存储元件(触发器、寄存器)
常见的variable型变量:
上表中的real、time变量是纯数学的描述,不对应具体的硬件电路,不可被综合。
time主要用于对模拟时间的存储和处理,real表示实数寄存器,主要用于仿真。
(1)reg型reg型变量定义格式:
reg 数据1,数据2,…数据n;
如定义两个位宽为1的reg型变量 a、b:
reg a,b;
定义多位宽的reg型变量:
reg[n-1:0] 数据1,数据2,…数据n;
reg[n:1]数据1,数据2,…数据n;
例如定义位宽为8的reg型变量a:
reg[7:0] a;
或
reg[8:1] a;(2)integer型
integer型变量定义与reg型变量相同,integer型变量多用于表示循环变量,用来表示循环次数等。
如下定义位宽为1的integer型变量a、b和位宽为32的integer型变量c、d:
integer a,b; integer[31:0] c; integer[32:1] d;六、参数 1、参数parameter
用参数parameter来定义一个常亮,通常用来表示时延和变量的宽度,并且只能被赋值一次 。类似于C语言中的#define宏定义。
parameter型参数声明格式:
parameter 参数名1=表达式1,参数名2=表达式2,…参数名n=表达式n;
注意有等于号!与c语言的宏定义区分 。并且参数名最好用大写字母。
如:
parameter SUM=100,SIZE=100; parameter NUM=10, SIZE=NUM*4; parameter PI=3.14159;2、参数localparam
localparam用于定义局部参数,作用范围仅限于本模块内,不能用于参数传递。即在实例化是不能通过层次引用来重新定义,常用于状态机参数的定义。
localparam参数的定义与parameter参数的定义相同。
七、向量 1、标量与向量宽度为1的变量称为标量,如果在变量声明中没有指定位宽,则默认为标量。
如:
wrie a; //线型变量a,为标量 reg clk; //reg型标量clk,位宽为1,为标量
位宽大于1的变量称为向量,格式是[MSB:LSB],MSB表示最高有效位,LSB表示最低有效位。
如:
wire[7:0] bus;//位宽为8的wire型变量 bus,为向量 reg[7:0] a;//位宽为8的reg型变量a,最高有效位和最低有效位分别是a[7]、a[0] reg[0:7] b;//位宽为8的reg型变量a,最高有效位和最低有效位分别是b[0]、b[7]2、位选择和域选择
在表达式中任意选中向量的一位称为位选择,选中向量的多位称为域选择。
如:
a=A[2];//位选择 将A的位2赋值给a变量 b=B[5:3] //域选择 将B的位5:3赋值给b变量
reg[7:0] a,b; reg[3:0] c; reg d; c=a[3:0]+b[7:4];//域选择 d=a[7]&b[7]; //位选择
上面代码的c=a[3:0]+b[7:4];//域选择等效为:
c[3]=a[3]+b[7]; c[2]=a[2]+b[6]; c[1]=a[1]+b[5]; c[0]=a[0]+b[4];
如果不想向量支持位选择和域选择,只作为一个统一的整体进行 *** 作,则在定义时用关键字vectored说明,此时向量变为向量类向量
如果未做说明,则默认为标量类向量,可以进行位选择和域选择。当然也可以用关键字scalared说明 。
如:
wire vectored [7:0] databus; //向量类向量,不能进行位选择和域选择3、储存器
储存器是由一组宽度相同的寄存器构成的阵列,定义储存器时需要定义储存器的容量和字长。
容量表示储存器储存单元的数据量
字长表示每个储存单元的数据宽度
如:
reg[5:0] mymenory[63:0]; //mymenory表示容量为64,前面的部分表示字长为6 //能存储64个数,每个数的位宽为6八、运算符
Verilog的运算符与C语言的基本相同。
1、算术运算符相等和全等的区别:
相等比较(==)参与比较的两个 *** 作数必须逐位相等,结果才能为1。但是如果某些位为不定态x和高阻态z,则比较的结果为不定值。
而全等比较(===)则对这些不定值x或高阻值z也进行比较,两个 *** 作数必须完全一致,其结果才为1 。
所以等于(==)一般用于比较不含不定态的 *** 作数,全等( ===)可用于比较含不定态的 *** 作数。
下面是等于(==)的真值表:
下面是全等(===)的真值表:
例:
a=5'b 11xz0; b=5'b 11xz0; //a==b的值为不定值x //a===b的值为16、缩减运算符
缩减运算符与位运算符的逻辑一样,但缩减运算符是对单个 *** 作数进行与、或、非的递推运算,它放在 *** 作数的前面,将向量缩减为一个标量。
例:
reg[3:0] a; b=&a; //等效为b=(a[0]&a[1]&a[2]&[3])
A=5'b11001; //则有以下结果: &A=0; //1&1&0&0&1=0 ~&A=1; //!(1&1&0&0&1)=1; |A=1; //1|1|0|0|1=1 ~|A=0; //!(1|1|0|0|1)=0 ^A=1; //1^1^0^0^1=1; ~^A=1; //1~^1~^0~^0~^1=1;7、移位运算符
A>>n 可以把 *** 作数A右移n位,A< 如: 算术左移和算术右移是为了区分带符号的 *** 作数,有以下规则: 左移: 右移: 例: 指数运算符用两个星号“**”表示,一般底数为2。 例: 这个与c语言一样,用符号?:表示。 用法: 值=条件?表达式1:表达式2 例: 通过两个花括号{}来进行位拼接,花括号里面的部分用逗号隔开用法: {信号1的某几位,信号2的某几位…信号n的某几位} 例: 拼接运算符可以嵌套。例: 可以用位拼接来实现移位 *** 作 我们知道一个整数乘2,就是整体左移1位;乘4就是整体左移2位;除2就是整体右移1位… 注意: 不是移位运算,移位运算位数不变,这里整体左移2位,则低位补2个零,总位数+2;整体右移2位,则舍去低位的两个0(整除2,则原来数的位1:0一定都是0),可以在高位补2个0让位数保持不变,或者可以不要管,直接让位数-2 。 优先级从高到底排序: 欢迎分享,转载请注明来源:内存溢出A=6'b 101101;
//A>>2的值为6'b 001011
//A<<2的值为6'b 110100
算术左移与逻辑左移不论 *** 作数有无符号,两者结果都一样,都是低位补0。
*** 作数为正整数时,算术右移与逻辑右移一样,都是高位补零。
*** 作数为负整数时,算术右移高位补1,逻辑右移高位补0 。
也就是常说的:有符号算术右移,高位需依次补足符号位的数。A=6'sb 101101; //定义6位的有符号 *** 作数
//A<<2的值为6'b 110100
//A<<<2的值为6'b 110100
//两者一样
//A>>2的值为6'b 001011
//A>>>2的值为6'b 111011
//两者不一样,注意>>>时,符号位为1,所以高2位都要补1
8、指数运算符
parameter WIDTH=16;
parameter DEPTH=8;
reg[WIDTH-1:0] memory[0:(2**DEPTH)-1]
//定义一个储存器,该储存器的每个元素的位宽都为16位
//可储存2^8个元素(256)
9、条件运算符
条件成立则:值=表达式1
条件不成立则:值=表达式2integer a=1,b=2,c;
c=a>b?1:0;
//结果为c=0
10、位拼接运算符
ina=3'b 111;
inb=4'b 1011;
inc=5'b 11001;
output[7] sum;
sum={ina[2:0],inb[2:0],inc[0]};
//拼接后,sum=111_011_1
ina=3'b 111;
inb=4'b 1011;
inc=5'b 11001;
{{ina,inb},{inc,ina}}//结果:111_1011_11001_111
{4{ina},inb[2:0],2{inc[4:3],inb[2]}}
//等价与:{ina,ina,ina,ina,inb[2:0],inc[4:3],inb[2],inc[4:3],inb[2]}
//结果为:111_111_111_111_011_11_0_11_0
则有:input[5:0] a,b;
f=a*4+a/8;
//则可以用以下方法实现:
f={a,2'b00}+{3'b000,a[5:3]}
11、运算优先级
类别 运算符 单目运算符+、-、!、~ 、&、~ &、|、~ |、^、~ ^、 ^~ 指数运算** 算术运算符* 、/ 、% 移位运算符<< 、 >> 、 <<< 、>>> 关系运算符<、<=、>、>= 等式运算符==、!=、 = ==、!= = 位运算符& 、| 逻辑运算符&&、|| 条件运算符?: 位拼接运算符{}、{{}}
评论列表(0条)