VHDL 与 VerilogHDL 的不同点 |
---|
序号 | 区别之处 | VHDL | Verilog |
---|---|---|---|
1 | 文件的扩展名不一样 | .vhd | .v |
2 | 结构不一样 | 包含库、实体、结构体。 ENTITY 实体名 IS PORT(端口说明) END 实体名 ; ARCHITECTURE 结构体名 OF 实体名 IS 说明部分 BEGIN 赋值语句/ 元件语句/ 进程语句 END 结构体名 ; | 模块结构 (module… endmodule) module 模块名 (端口列表) ; 输入/输出端口说明; 变量类型说明; assign 语句 (连续赋值语句) ; 元件例化语句; always@(敏感列表) begin … end endmodule 其中assign语句、元件例化语句、always语句的顺序可以更换 |
3 | 对库文件的要求不一样 | 须有相应的库或程序包支持,实体间调用子程序,需要将子程序打成程序包 | 没有专门的库文件 (只有基本门的库),模块可以通过例化直接调用,不需要打成程序包 |
4 | 端口定义的地方不一样 | 实体中定义 | module的模块名后面先列出端口列表,再在模块中用input,output等定义 |
5 | 端口定义方式不一样 | 端口名(端口名,端口名) : 方向 数据类型名(Default Value) ; 例如: Q1 : IN Std_Logic_Vector(31 DOWNTO 0) ; | 端口类型 端口1,端口2,端口3,…; 例如: inout [31:0]Q; |
6 | 端口定义类型不一样 | 有IN, OUT, INOUT, BTFFER 四种 | 有input ,output, inout 三种 |
7 | 内部信号(SIGNAL)声明不一样 | 在结构体中声明,有些局部变量还可在进程中声明 | 在端口定义后进行声明内部变量 |
8 | 标识符规则不一样 | 不区分大小写 | 区分大小写 |
9 | 关键词要求不一样 | 允许大小写混写 例如: EnTity | 关键词必须小写 |
10 | 常量定义的关键词和格式表示不一样 | CONSTANT 常量名:数据类型 :=数值; | parameter 常量名1 = 数值1, 常量名2 = 数值2,…,常量名n = 数值n; |
11 | 常量表示不一样 | 用双引号. 例如: B"011100" | <位宽>’<进制符号><数字> 例如: 8’b10110011 |
12 | 数组定义方式不一样 | 定义4位数组A: A(3 DOWNTO 0 ) 或者A(0 TO 3) | 定义4位数组A: A[3:0] 或者A[0:3] |
13 | 下标名表示不一样 | 用小括号表示, 例如: a(0) | 用中括号表示, 例如: a[0] |
14 | 数据对象不一样,且二者变量的含义不一样 | 常量,变量,信号. 变量是一个局部量,只能在进程和子程序中使用。变量的赋值是一种理想化的数据传输,是立即发生,不存在任何延时的行为。 信号是描述硬件系统的基本数据对象,它类似于连接线。信号可以作为设计实体中并行语句模块间的信息交流通道。 数据对象没有默认 | 常量,变量 变量是在程序运行时其值可以改变的量。变量默认为wire型 |
15 | 数据默认值 | 默认值为本类型的最小非负值(某个类型的范围是以0为对称的) | wire类型默认值为 z, reg类型默认值为x ; |
16 | 变量定义的格式不一样 | VARIABLE 变量名:数据类型 :=初始值 例如: VARIABLE k:Integer RANGE 0 TO 7; | 数据类型 [位宽] 变量1,变量2,…,变量n; |
17 | 数据类型不一样 | 布尔(BOOLEAN)、位(BIT)、位矢量(BIT_VECTOR)、标准逻辑位(STD_LOGIC)、标准逻辑矢量(STD_LOGIC_VECTOR)。 VHDL的数据类型比较复杂。 | wire,tri,reg,interger,real,time型,主要是wire和reg型,比较简单。 |
18 | 赋值不一样 | 按数据对象赋值分,变量赋值使用“:=”,信号赋值使用"<=" | 按语句的执行情况分,assign语句和阻塞语句用“=”赋值,非阻塞语句用“<=” |
19 | 赋值要求不一样 | 强类型语言,赋值两边的赋值目标和表达式的数据类型必须一样。不同类型和宽度的数据之间不能运算和赋值,需要调用包来完成转换; 例如: A:IN STD_LOGIC_VECTOR(2 DOWNTO 0) B:IN STD_LOGIC_VECTOR(2 DOWNTO 0) C:OUT STD_LOGIC_VECTOR(3 DOWNTO 0) 则C<=A OR B;会出错 | 不是强类型语言,可以自动完成不同类型数据的运算和赋值; 例如: input [2:0]a; input [2:0]b; output [3:0]c; assign c=a&b;不会出错 |
20 | 操作符不一样 | 逻辑操作符(Logica Operator)、关系操作符(Relationa Operator)、算术操作符(Arithmetic Operator)、符号操作符(Sign Operator),没有缩减操作符,没有三目的条件操作符 | 操作符比较丰富,有算数操作符,逻辑操作符,位运算、关系操作符,等式操作符,缩减操作符,转移操作符,条件操作符,位并接操作符 |
21 | 条件中,等于判断符号不一样 | 等于= ; 不等于 /= | 等于(= =)或全等(= = =) 不等于(! =)或不全等(! = =) |
22 | 逻辑操作符不一样 | AND, NAND, NOT, OR, NOR, XNOR, XOR等 该逻辑操作符运算结果跟Verilog HDL的位运算一样 | &&(逻辑与), || (逻辑或), !(逻辑非), ~ (按位取反), &(按位与), |(按位或), ^(按位异或), ^~ 或~ ^(按位同或) |
23 | 移位操作符不一样 | 除了逻辑左移SLL、逻辑右移SRL之外,还有算数左移SLA、算数右移SRA、循环左移ROL、循环右移ROR。其中逻辑左移SLL、逻辑右移SRL与Verilog HDL的左移<<, 右移>>一致 | 只有逻辑左移<< 和逻辑右移>>,没有算数左移、算数右移、循环左移、循环右移。 |
24 | 并置操作符不一样 | 用&并置, 例如: a&b | 用{ }并置, 例如: {a, b} |
25 | 并行赋值语句不一样 | 信号赋值语句 (直接赋值、条件赋值、选择赋值) | assign语句 (连续赋值) 只对wire型 |
26 | 顺序语句不一样 | 信号赋值 变量赋值(变量赋值只能在进程和子进程中进行) | 阻塞语句 非阻塞语句 |
27 | 并行语句中的进程语句不一样 | PROCESS(敏感列表) BEGIN 顺序语句; END PROCESS; | always@ (敏感列表) begin 顺序语句; end |
28 | 条件判断语句if的格式不一样 | IF 条件1 THEN 顺序描述语句; ELSIF 条件2 THEN 顺序描述语句; … ELSE 顺序描述语句; END IF; | if (条件1) 顺序描述语句; else if (条件2) 顺序描述语句; … else 顺序描述语句; |
29 | 条件控制语句case的格式不一样 | CASE 表达式 IS WHEN 条件表达式1 => 顺序描述语句; WHEN 条件表达式2 => 顺序描述语句; WHEN 条件表达式3 => 顺序描述语句; … WHEN 条件表达式n => 顺序描述语句; END CASE 如果没有列举出CASE和IS之间的表达式的全部取值,则WHEN OTHERS =>必不可少 | case (表达式) 选择值1:语句1; 选择值2:语句2; 选择值3:语句3; … 选择值n:语句n; default:语句n+1; endcase default没有,不会出现语法错误,但逻辑有可能产生错误 |
30 | case语句的应用范围也不一样 | 在CASE语句中,条件表达式是没有优先级的,如优先级编码器可以用IF语句进行描述,但不可以使用CASE语句描述 | 除了case以外,还有相关的casex和casez语句,如用casex可以实现优先编码器 |
31 | 循环控制语句不一样 | 循环控制语句有:FOR_LOOP循环语句、WHILE_LOOP循环语句、NEXT语句、EXIT语句 | for语句、repeat语句、while语句、和forever语句 |
32 | for循环控制语句格式不一样 | [标号:] FOR 循环变量 IN 循环次数范围 LOOP 顺序语句 END LOOP [标号]; | for(循环指针=初值; 循环指针<终值; 循环指针=循环指针+步长值) begin 顺序语句; … end |
33 | for循环中的循环变量存在区别 | 循环变量不需要定义 | 循环指针需要定义 |
34 | while语句格式不一样 | [标号:] WHILE 条件 LOOP 顺序描述语句; END LOOP [标号]; 在循环体内,必须包含条件式中判别变量的赋值语句。 | while(循环执行条件表达式) begin 重复执行语句; 修改循环条件语句; end |
35 | 元件例化不一样 | COMPONENT 元件名 IS GENERIC 说明; PORT 说明; END COMPONENT 元件名; | 设计模块名 <例化电路名> (端口列表) ; |
36 | 时钟定义不一样 | 时钟列在PROCESS的敏感列表中,如若上升沿有效,则 PROCESS(clk) BEGIN IF (clk’EVENT AND clk=‘1’) THEN … END PROCESS; | 在always结构中,上升沿直接体现在always的敏感列表中。如 always@ (posedge clk) begin … end |
37 | 时钟边沿定义方式不一样 | 上升沿(clk’EVENT AND clk=‘1’) 下降沿(clk’EVENT AND clk=‘0’) | 上升沿posedge clk 下降沿negedge clk |
38 | 生成重复结构的能力不同 | 有生成语句(GENERATE)生成由大量相同单元构成的模块,格式为: [标号:] FOR 循环变量 IN 取值范围 GENERATE [说明部分] BEGIN [并行语句]; - -元件例化语句,以重复产生并行元件。 END GENERATE [标号]; 或者 IF 条件 GENERATE [说明部分] BEGIN [并行语句] END GENERATE [标号]; | 没有对应的生成语句,有相近的实例数组,格式为: <模块名字> <实例名字> <范围> (<端口>); |
39 | 子程序不一样 | procedure和function | task 和 function |
40 | 注释方法不一样 | 用- -引导注释信息 | 用//或/*…*/注释 |