今天平头哥来和大家伙聊聊fpga开发语言的事。对于fpga入门者来说,选择用哪种开发语言或许也是一个让人苦恼的问题,目前开发fpga的手段越来越多,这个后面再聊,先来说说对于rtl开发来说最古老的开发语言也就是vhdl和verilog了。vhdl和verilog历史 vhdl的 英 文 全 名 是 very-high-speed integrated circuit hardware descriptionlanguage,诞生于 1982 年。1987 年底,vhdl 被 ieee 和美国国防部确认为标准硬件描述语言。自 ieee 公布了 vhdl 的标准版本 ieee-1076(简称 87 版)之后,各 eda 公司相继推出了自己的 vhdl 设计环境,或宣布自己的设计工具可以提供 vhdl 接口。此后 vhdl 在电子设计领域逐步取代了原有的各种非标准硬件描述语言。1993 年,ieee 对 vhdl 进行了修订,从更高的抽象层次和系统描述能力上扩展 vhdl 的内容,并公布了新版本的 vhdl,即 ieee 标准的 1076-1993版本(简称 93 版)。现在,vhdl 和 verilog hdl 作为 ieee 的工业标准硬件描述语言,在电子工程领域已成为事实上的通用硬件描述语言。
vhdl 在语言形式、描述风格和句法上与一般的计算机高级语言十分相似。vhdl 的程序结构特点是将一项工程设计,或称设计实体(可以是一个元件、一个电路模块或一个系统)分成外部和内部两部分。 外部也可称为可视部分,它描述了此模块的端口,而内部可称为不可视部分,它涉及到实体的功能实现和算法完成。在对一个设计实体定义了外部端口后,一旦其内部开发完成,其他的设计就可以直接调用这个实体。这种将设计实体分成内外部分的概念是vhdl 系统设计的基本点。 一般的 vhdl 程序可以由实体(entity)、结构体(architecture)、配置(configuration)、程序包和程序包体(package)以及库(library)5 个部分组成,它们是 vhdl 程序的设计单元。
其中实体、配置和程序包属于初级设计单元,主要的功能是进行端口、行为、函数等的定义。结构体和程序包体是次级设计单元,包含了所有行为以及函数的实现代码。其中,程序包和程序包体又属于公用设计单元,即它们是被其他程序模块调用的。库则是一批程序包的集合。
verilog是由gateway设计自动化公司的工程师于1983年末创立的。当时gateway设计自动化公司还叫做自动集成设计系统(automated integrated design systems),1985年公司将名字改成了前者。该公司的菲尔·莫比(phil moorby)完成了verilog的主要设计工作。1990年,gateway设计自动化被cadence公司收购。
1990年代初,开放verilog国际(open verilog international, ovi)组织(即现在的accellera)成立,verilog面向公有领域开放。1992年,该组织寻求将verilog纳入电气电子工程师学会标准 。最终,verilog成为了电气电子工程师学会1364-1995标准,即通常所说的verilog-95。
设计人员在使用这个版本的verilog的过程中发现了一些可改进之处。为了解决用户在使用此版本verilog过程中反映的问题,verilog进行了修正和扩展,这部分内容后来再次被提交给电气电子工程师学会。这个扩展后的版本后来成为了电气电子工程师学会1364-2001标准,即通常所说的verilog-2001。verilog-2001是对verilog-95的一个重大改进版本,它具备一些新的实用功能,例如敏感列表、多维数组、生成语句块、命名端口连接等。目前,verilog-2001是verilog的最主流版本,被大多数商业电子设计自动化软件包支持。
1995年,ieee 制定了 verilog hdl 的第一个国际标准,即 ieee std 1364-1995,也称之为 verilog 1.0。
2001 年,ieee 发布 verilog 第二个标准(verilog 2.0),即 ieee std 1364-2001, 简称为 verilog-2001 标准。
vhdl和verilog的区别
原文链接:例说verilog和vhdl的区别,助你选择适合自己的硬件描述语言
hdl 建模能力:verilog与vhdl
首先,让我们讨论一下 verilog 和 vhdl 的硬件建模能力,因为它们都是用于建模硬件的硬件描述语言。下图显示了 verilog 和 vhdl 在硬件抽象行为级别方面的 hdl 建模能力。
图形来源:douglas j. smith,“vhdl 和 verilog 比较和对比加上 用 vhdl、verilog 和 c 编写的建模示例”
低级建模
如上图所示,verilog 和 vhdl 都能够对硬件进行建模。但是,在底层硬件建模方面,verilog优于vhdl。这是合理的,因为 verilog 最初是为建模和模拟逻辑门而创建的。事实上,verilog 具有内置原语或低级逻辑门,因此设计人员可以在 verilog 代码中实例化原语,而 vhdl 则没有。 verilog 的门基元:and、nand、or、nor、xor、xnor、buf、not、bufif0、notif0、bufif1、notif1、pullup、pulldown。 verilog 的开关原语:pmos、nmos、rpmos、rnmos、cmos、rcmos、tran、rtran、tranif0、rtranif0、tranif1、rtranif1。
更重要的是,verilog 支持用户定义基元 (udp),因此设计人员可以定义自己的单元基元。此功能对于 asic 设计人员来说尤其必要。以下是有关如何在 verilog 代码中实例化门基元的 verilog 示例:or #5 u1(x,y,z);and #10 u2(i1,i2,i3);adc_circuit u3(in1,out1,out2,clock); // adc_circuit is an user-defined primitive for // analog to digital converter for example.
verilog 中一些低级内置门基元的 vhdl 等效项可以通过使用逻辑运算符如 not、and、nand、or、nor、xor、xnor 来实现。下面是 verilog 门基元的 vhdl 等效代码示例:or u1(x,y,z); in verilog x <= y or z; in vhdland u2(i1,i2,i3); (verilog) i3 <= i2 and i3; in vhdl
为了支持 verilog 中的 udp 功能,vital(vhdl initiative towards asic libraries-vhdl 面向 asic 库的倡议)问世,使 asic 设计人员能够在符合 vital 的 vhdl 中创建自己的单元基元或 asic 库,如上图所示。尽管如此,vhdl 仍然可能无法实现 verilog 对低级硬件建模的支持。因此,如果我是 asic 设计师,我会更喜欢 verilog 而不是 vhdl。 高级建模
另一方面,如上述图表所示,vhdl 在高级硬件建模方面优于 verilog。与 verilog 相比,vhdl 为高级硬件建模提供了更多功能和构造。以下是在比较 vhdl 和 verilog 时支持高级硬件建模的主要不同功能: vhdl 中的用户定义数据类型
verilog 的数据类型非常简单,都是用 verilog 语言定义的(用户不能在 verilog 中定义自己的数据类型)。verilog 有两种主要的数据类型,包括 net 数据类型(用于将组件连接在一起,例如wire(最流行)、wor、wand、tri、trior 等)和变量数据类型(用于临时存储,例如reg(最流行),整数、时间、实数和实时)。vhdl支持许多不同的数据类型,包括预定义的 vhdl 数据类型和用户定义的数据类型。预定义的 vhdl 数据类型包括位、位向量、字符串、时间、布尔值、字符和数字(实数或整数)。vhdl 允许设计人员根据预定义的 vhdl 数据类型定义不同的类型;对于可能使用许多不同数据类型的复杂和高级系统来说,这是一个很好的功能。以下是用于定义新数据类型的示例 vhdl 代码:type int_8bit is range 0 to 255 -- define 8-bit unsigned numberssignal i : int_8bit;type state_fsm is (idle, start, calculate , finish, delay) -- define symbolic states to represent fsm states.signal current_state, next_state: state_fsm;
vhdl 中的设计重用包
vhdl 中的包通常用于数据类型和子程序的声明。vhdl 包中声明的子程序或数据类型可用于许多不同的实体或体系结构。例如:package fsm_type is type fsm_states is (idle, transmit, receive, stop);end package-- to use the fsm_states type in an entity or architecture-- use the following statement on top of the entityuse work.fsm_type.allentity example is
verilog 中没有包定义。与 vhdl 包最接近的 verilog 等效项是`include verilog 编译器指令。函数或定义可以单独保存在另一个文件中,然后通过使用`include指令在模块中使用它。下面是一个 verilog 示例代码:// below is the content of verilogvsvhdl.h file`define input_verilog ./test_verilogvsvhdl.hex // input file name `define output_vhdl vhdl.bmp // output file name `define verilog_vhdl_difference// then call it in every single module that you want to use the definition above`include verilogvsvhdl.h
vhdl 中的配置语句
一个 vhdl 设计可以为一个实体获得许多具有不同体系结构的设计实体。配置语句将确切的设计实体与设计中的组件实例相关联。当实体中有多个架构时,配置语句会继续指定所需的设计架构分配给实体以进行综合或仿真。当 vhdl 设计人员需要管理大型高级设计时,此功能非常有用。以下是配置语句的 vhdl 示例代码:entity buf is generic (delay : time := 10 ns); port ( buf_in : in bit; buf_out : out bit);end buf;-- the first design architecture for buf architecture struct_buf1 of buf issignal temp: bit;begin buf_out <= not temp after delay; temp in1, buf_out => out1); end for;end for ;end config_buf;
verilog-2001 中还添加了配置块。
vhdl 中的库管理
同时查看 verilog 和 vhdl 代码时,最明显的区别是 verilog 没有库管理,而 vhdl 在代码顶部包含设计库。vhdl 库包含已编译的架构、实体、包和配置。此功能在管理大型设计结构时非常有用。上面已经给出了 vhdl 中的包和配置示例。以下是 vhdl 中库管理的 vhdl 示例代码:-- library management in vhdllibrary ieee;use ieee.std_logic_1164.all;use ieee.numeric_std.all;use work.clock_div.all;
简而言之,vhdl 在高级硬件建模方面比 verilog 更好。由于 fpga 设计流程不需要低级硬件建模,如果我是 fpga 设计师,我更喜欢 vhdl 而不是 verilog。 值得一提的是,systemverilog 的创建是为了通过将 vhdl 中的高级功能和结构添加到 verilog 中进行验证来增强 verilog 语言在高级建模中的弱点。systemverilog 现在广泛用于 ic 验证。 冗长(verboseness:):verilog 与 vhdl vhdl 是强类型的vs verilog 是松散类型的
vhdl 是一种非常强类型的硬件描述语言,因此必须使用匹配和定义的数据类型正确编写 vhdl 代码。这意味着如果在 vhdl 中分配时混合数据类型或不匹配信号,将会出现编译错误。另一方面,verilog 是一种松散类型的语言。在 verilog 中,您可以在分配时混合数据类型或不匹配信号。下面是不匹配信号的 vhdl 示例代码:signal test_reg1: std_logic_vector(3 downto 0); signal test_reg2: std_logic_vector(7 downto 0); test_reg2 <= test_reg1;-- you cannot assign a 4-bit signal to an 8-bit signal -- in vhdl, it will introduce a syntax error below:-- width mismatch. expected width 8, actual width is 4 -- for dimension 1 of test_reg1.
编译上面的vhdl代码时,会出现语法错误“ width mismatch. expected width 8, actual width is 4 ”。如果将vhdl代码改为“ test_reg2 <= 0000&test_reg1; 匹配位宽,则不会出现语法错误。
如果在 verilog 中将 4 位信号分配给 8 位信号会怎样? wire [3:0] test1; wire [7:0] test2; // in verilog, you can assign 4-bit signal to 8-bit signal. assign test2 = test1; // there will be no syntax error during synthesis
当您将 4 位信号分配给 8 位信号时,verilog 编译器不会引入语法错误。在 verilog 中,不同位宽的信号可以相互分配。verilog 编译器将使源信号的宽度适应目标信号的宽度。未使用的位将在综合期间进行优化。
下面是在分配信号时混合数据类型的另一个 vhdl 示例:signal test1: std_logic_vector(7 downto 0);signal test2: integer;test2 <= test1;-- syntax error: type of test2 is incompatile with type of test1
上面的 vhdl 代码会引入一个语法错误“ (type of test2 is incompatible with type of test1)test2 的类型与 test1 的类型不兼容”。你必须转换test1的 分配之前整数数据类型test1到test2如下:library ieee;use ieee.numeric_std.all;signal test1: std_logic_vector(3 downto 0);signal test2: integer;-- use ieee.numberic_std.all library for this conversiontest2 aluout aluout aluout aluout clk, clk_1s => clk_1s); end
或者在包中声明组件以供重用:
library ieee;use ieee.std_logic_1164.all;package clock_div_pack is component clk_div is port ( clk_50: in std_logic; clk_1s : out std_logic );end component clk_div;end package;-- declare the component in a separate package and -- reuse by using the following statement:use work.clock_div_pack.all;entity clock isend clock;architecture behavioral of clock issignal clk, clk_1s: std_logic;begincreate_1s_clock: clk_div port map (clk_50 => clk, clk_1s => clk_1s); end
在 vhdl-93 中直接实例化实体的示例代码:
create_1s_clock: entity work.clk_div port map (clk_50 => clk, clk_1s => clk_1s);
verilog 具有编译器指令,例如`timescale (声明时间单位和延迟精度)、`define (将文本字符串声明为宏名称)、`ifdef、ifndef `else `elseif `endif(条件编译)、`include(包括一个可以包含函数或其他声明的文件)等。vhdl 没有编译器指令。
vhdl 支持枚举和记录数据类型,允许用户为一种数据类型定义多个信号。verilog 不支持枚举和记录类型。下面是枚举和记录类型的 vhdl 代码:
type fsm is (idle, test, verilogvsvhdl, stop, fpga4student);-- enumerated typetype int_4 is range 0 to 15;-- record tye in vhdltype record_example is record data1: integer; data2: int_4; data3: fsm;end record;
等等。
尽管 verilog 和 vhdl 之间存在差异,但它们是两种最流行的硬件描述语言。如果可以,最好同时学习它们。重要的是要记住,在编码时始终考虑逻辑门或硬件以开发硬件编码思维,而在使用 verilog 和 vhdl 编码时忘记软件编程思维,这一点非常重要。 详细对比 表格:
表格转自:verilog hdl和vhdl的区别
作者:比特波特
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 常量表示不一样 用双引号.
例如:b011100 ’
例如: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;endcasedefault没有,不会出现语法错误,但逻辑有可能产生错误
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)beginif (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 注释方法不一样 用- -引导注释信息 用//或/*…*/注释
上面借用别人的文章说了那么多,平头哥提个简单的建议,对于fpga开发者来说,至少熟练掌握一种rtl开发语言,有c语言基础的建议选择verilog,追求严谨的选择vhdl,不管选择哪种语言,都没有本质上的优劣之分,更不要有语言鄙视链的想法,其他高级开发语言我们后面再聊。
关于逻辑和物理架构模型开发之间的迭代
数据分析师如何晋升详细资料分析
HOLTEK新推出BA45F6956复合型感烟与一氧化碳/燃气探测器MCU
新材料产业创新月:企业科技创新能力提升工程暨松山湖材料实验室开放日成功举办
三星宣布完成了7nm EUV工艺的技术流程开发以及产线部署进入量产阶段
FPGA开发语言的选择
智能家居电子锁方案原理电路
交流电机的调速方法 交流电机的分类
小米小爱智能音箱HD拆解:599元绝对值
基于C8O51FO4O的CAN总线中继器设计与实现
升级安卓7.0以后,这三款手机的表现让人意外
物联网技术融合 促进传感器智能化发展
2023年去哪儿找传感器产业万亿市场机会?| 重磅邀请函
滨正红PFA晶圆夹在半导体芯片晶圆处理中的应用
基于STM8S的LCD驱动电路和LCD显示原理分析
软件测试——软件安全质量的保证
荣耀Magic被苹果8和三星S8模仿 这个不知道多少人伤心!
安徽大学选购我司HS-DR-5导热系数测试仪
初中学习机入手指南——科大讯飞AI学习机值得信赖
Linux驱动移植 Linux系统架构优点