第10章 VHDL入门 2018/11/27 逻辑设计基础
§1 VHDL背景 传统数字电路设计方法不适合设计大规模的系统。工程师不容易理解原理图设计的功能。 众多软件公司开发研制了具有自己特色的电路硬件描述语言(Hardware Description Language,HDL),存在着很大的差异,工程师一旦选用某种硬件描述语言作为输入工具,就被束缚在这个硬件设计环境之中。因此,硬件设计工程师需要一种强大的、标准化的硬件描述语言,作为可相互交流的设计环境。 2018/11/27 逻辑设计基础
美国国防部在80年代初提出了VHSIC(Very High Speed Integrated Circuit)计划,其目标之一是为下一代集成电路的生产,实现阶段性的工艺极限以及完成10万门级以上的设计,建立一项新的描述方法。1981年提出了一种新的HDL,称之为VHSIC Hardware Description Language,简称为VHDL,这种语言的成就有两个方面: 描述复杂的数字电路系统 成为国际的硬件描述语言标准 2018/11/27 逻辑设计基础
VHDL的发展历程 1981年6月,美国成立了VHDL工作小组; 1983年6月,由 Intermitrics, IBM和 Texas Instrument 组成开发小组,任务是: 提出语言版本; 开发其软件环境。 1987年12月,IEEE公布了 IEEE-1076 作为HDL的 第一个标准; 1993年, IEEE公布了VHDL_93; 1999年: VHDL_AMS(Analog Mixed Signal) 1999年: VHDL1076.6(RTL可综合子集); 2000年1月公布了VHDL1076-2000; 2002年5月公布了VHDL1076-2002; 2018/11/27 逻辑设计基础
VHDL的优点 用于设计复杂的、多层次的设计。支持设计库和设计的重复使用 与硬件独立,一个设计可用于不同的硬件结构,而且设计时不必了解过多的硬件细节。 有丰富的软件支持VHDL的综合和仿真,从而能在设计阶段就能发现设计中的Bug,缩短设计时间,降低成本。 更方便地向ASIC过渡 VHDL有良好的可读性,容易理解。 2018/11/27 逻辑设计基础
§2 设计流程 2018/11/27 逻辑设计基础
ARCHITECTURE dataflow OF full_adder IS BEGIN s <= a XOR B XOR cin; ENTITY full_adder IS PORT ( a,b,cin:IN BIT; s,cout:OUT BIT); END full_adder; ---------------------------------------------------------------------------- ARCHITECTURE dataflow OF full_adder IS BEGIN s <= a XOR B XOR cin; cout <= (a AND b) OR (a AND cin) OR (b AND cin) END dataflow; 2018/11/27 逻辑设计基础
VHDL代码到电路的转换 2018/11/27 逻辑设计基础
§3 VHDL语言 VHDL与计算机语言的区别 运行的基础 执行方式 验证方式 计算机语言是在CPU+RAM构建的平台上运行 计算机语言基本上以串行的方式执行 VHDL在总体上是以并行方式工作 验证方式 计算机语言主要关注于变量值的变化 VHDL要实现严格的时序逻辑关系 2018/11/27 逻辑设计基础
§3.1 VHDL标识符(Identifiers) 基本标识符由字母、数字和下划线组成 第一个字符必须是字母 最后一个字符不能是下划线 不允许连续2个下划线 保留字(关键字)不能用于标识符 大小写是等效的 2018/11/27 逻辑设计基础
§3.2 VHDL数据对象 常数(Constant) constant data_bus_width: integer := 8 ; 固定值,不能在程序中被改变 增强程序的可读性,便于修改程序 在综合后,连接到电源和地 可在Library、Entity、Architecture、Process中进行定义,其有效范围也相应限定 语法:constant 常量名 : 类型[取值范围][:=常数]; constant data_bus_width: integer := 8 ; 2018/11/27 逻辑设计基础
signal count:bit_vector(3 downto 0):=“0011”; 信号(Signals) 代表连线,Port也是一种信号 没有方向性,可给它赋值,也可当作输入 在Entity中和Architecture中定义 设定的初始值在综合时没有用,只是在仿真时在开始设定一个起始值。 用 <= 对信号进行赋值 语法:signal 信号名 :类型[取值范围][:=初值]; signal count:bit_vector(3 downto 0):=“0011”; 2018/11/27 逻辑设计基础
variable result : std_logic := ‘0’; 临时数据,没有物理意义 只能在Process和Function中定义,并只在其内部有效 要使其全局有效,先转换为Signal。 用 := 进行赋值 语法:variable 变量名 :类型[取值范围][:=初值]; variable result : std_logic := ‘0’; 2018/11/27 逻辑设计基础
信号与变量的区别 一、变量 二、 信号 1.变量是对暂时数据进行局部存储的。 2.变量的说明和赋值只能在顺序部分进行,即只能在进程、 过程或函数中进行。 3.变量的赋值具有立即性,不包含延时信息,更像高级语言。 4.如果需要将变量的值用于进程之外,只要将变量的值赋予 相同类型的信号即可。 二、 信号 1.有一定的延时性。 2.进程只对信号敏感,不对变量敏感。 2018/11/27 逻辑设计基础
信号与变量的区别 architecture a of start is signal tmp : std_logic; begin process(a_bus) tmp <= '1'; for i in 3 downto 0 loop tmp <= a_bus(i) and tmp; end loop; carryout <= tmp; end process; end a; architecture a of start is begin process(a_bus) variable tmp:std_logic; tmp := '1'; for i in 3 downto 0 loop tmp := a_bus(i) and tmp; end loop; carryout <= tmp; end process; end a; 2018/11/27 逻辑设计基础
§3.3 VHDL数据类型 位(bit): 逻辑‘0’ 或 ‘1’ 布尔(boolean) 整数(integer): -(231-1)~+(231-1) 正整数(positive) 自然数(natural) 实数(real) 字符(character):‘7’、‘A’ 时间(time): ns, us, sec, min, hr 物理类型: 用于表示时间和电压等物理量。 2018/11/27 逻辑设计基础
VHDL数据类型-枚举 列举数据对象可能存在的值,一般用于定义状态机的状态 IEEE1076标准中预定义了两个枚举类型 type states is (idle, start, running, pause, stop); signal current_state : states; IEEE1076标准中预定义了两个枚举类型 type boolean is (False, True); type bit is (‘0’, ‘1’) ; signal a : bit ; 2018/11/27 逻辑设计基础
VHDL数据类型-枚举 IEEE1164标准中预定义了一个枚举类型: type std_logic is (‘U’, ‘X’,‘0’, ‘1’, ‘Z’, ‘W’, ‘L’, ‘H’, ‘-’); ‘U’ 初始不定值 ‘X’ ‘‘强” 不确定值 (综合后为不确定值) ‘0’ ‘‘强” 0 (综合后为0) ‘1’ ‘‘强” 1 (综合后为1) ‘Z’ 高阻态 (综合后为三态缓冲器) ‘W’ ‘‘弱” 不确定值 ‘L’ ‘‘弱” 0 ‘H’ ‘‘弱” 1 ‘-’ 不可能出现的情况 注意:这里的大小写是敏感的 2018/11/27 逻辑设计基础
VHDL数据类型-矢量和标量 标量---单个位 矢量 BIT STD_LOGIC STD_ULOGIC BOOLEAN BIT_VECTOR STD_LOGIC_VECTOR STD_ULOGIC_VECTOR INTEGER , SIGNED , UNSIGNED 2018/11/27 逻辑设计基础
VHDL数据类型-复合类型 数组(array) 多个相同类型成员组成的队列,一般用于定义数据总线、地址总线等。 语法:type 数组类型名 is array 下标范围 of 元素类型; type matrix4x3 is array (1 to 4,1 to 3) of integer; signal matrixA:matrix4x3 :=((1,2,3),(4,5,6),(7,8,9),(10,11,12)) 2018/11/27 逻辑设计基础
VHDL数据类型-复合类型 记录类型(record) 相同或不同类型的元素组成,类似C中的结构体 具有模型抽象能力,用于描述一个功能模块 type iocell is record Enable :bit; DataBus :bit_vector(7 downto 0); end record; singal bus : iocell; bus.Enable <= ‘1’; bus.DataBus <= “00110110”; 2018/11/27 逻辑设计基础
§3.4 VHDL代码结构 VHDL 大小写不敏感 eqcomp4.vhd 库 包 实体 构造体 文件名和实体名一致 --eqcomp4 is a four bit equality comparator Library IEEE; use IEEE.std_logic_1164.all; entity eqcomp4 is port(a, b:in std_logic_vector(3 downto 0); equal :out std_logic); end eqcomp4; architecture dataflow of eqcomp4 is begin equal <= ‘1’ when a=b else ‘0’; End dataflow; 库 包 实体 每行;结尾 关键字end后跟实体名 构造体 关键字begin 关键字end后跟构造体名 VHDL 大小写不敏感 2018/11/27 逻辑设计基础
实体(entity) 语法:entity 实体名 is [ port (端口信号说明);] end [entity] [实体名]; 在芯片级,则代表具体芯片的管脚 语法:entity 实体名 is [ port (端口信号说明);] end [entity] [实体名]; entity eqcomp4 is port (a, b : in std_logic_vector(3 downto 0) ; equal : out std_logic ); end eqcomp4; 2018/11/27 逻辑设计基础
实体-端口的模式 输入( input) 输出(output) 双向(inout):可代替所有其他模式,但降低了程序的可读性,一般用于与CPU的数据总线接口 缓冲(buffer):与output类似,但允许该管脚名作为一些逻辑的输入信号 2018/11/27 逻辑设计基础
Out与Buffer的区别 Entity test2 is Entity test1 is port(a: in std_logic; b : buffer std_logic; c : out std_logic ); end test2; architecture a of test2 is begin b <= not(a); c <= b; end a; Entity test1 is port(a: in std_logic; b,c: out std_logic ); end test1; architecture a of test1 is begin b <= not(a); c <= b;--Error end a; 2018/11/27 逻辑设计基础
结构体(Architecture) 描述实体的内部操作 结构体有三种描述方式 语法:architecture 结构体名 of 实体名 is 行为描述(behavioral) 数据流描述(dataflow) 结构化描述(structural) 语法:architecture 结构体名 of 实体名 is [定义语句] begin 结构体的主体部分 end 结构体名; 2018/11/27 逻辑设计基础
结构体-行为描述 Architecture behavioral of eqcomp4 is begin 实体名称 Architecture behavioral of eqcomp4 is begin comp: process (a,b) if a=b then equal <= ‘1’; else equal <=‘0’; end if; end process comp; end behavioral ; 高层次的功能描述,不必考虑在电路中到底是怎样实现的。 2018/11/27 逻辑设计基础
结构体-数据流描述 描述输入信号经过怎样的变换得到输出信号 Architecture dataflow1 of eqcomp4 is begin equal <= ‘1’ when a=b else ‘0’; end dataflow1; Architecture dataflow2 of eqcomp4 is begin equal <= not(a(0) xor b(0)) and not(a(1) xor b(1)) and not(a(2) xor b(2)) and not(a(3) xor b(3)); end dataflow2; 当a和b的宽度发生变化时,需要修改设计,当宽度过大时,设计非常繁琐 2018/11/27 逻辑设计基础
结构体-结构化描述 类似于电路的网络表,将各个器件通过语言的形式进行连接,与电路有一一对应的关系。 一般用于大规模电路的层次化设计时。 architecture struct of eqcomp4 is begin U0:xnor2 port map(a(0),b(0),x(0)); U1:xnor2 port map(a(1),b(1),x(1)); U2:xnor2 port map(a(2),b(2),x(2)); U3:xnor2 port map(a(3),b(3),x(3)); U4:and4 port map(x(0),x(1),x(2),x(3),equal); end struct; 类似于电路的网络表,将各个器件通过语言的形式进行连接,与电路有一一对应的关系。 一般用于大规模电路的层次化设计时。 2018/11/27 逻辑设计基础
三种描述方式的比较 描述方式 优点 缺点 适用场合 结构化描述 连接关系清晰,电路模块化清晰 电路不易理解、繁琐、复杂 电路层次化设计 数据流描述 布尔函数定义明白 不易描述复杂电路,修改不易 小门数设计 行为描述 电路特性清楚明了 进行综合效率相对较低 大型复杂的电路模块设计 2018/11/27 逻辑设计基础
§3.5 运算操作符和属性 赋值运算符 <= 用于对信号进行赋值 := 用于对变量、常量赋值,也可用于赋初始值 <= 用于对信号进行赋值 := 用于对变量、常量赋值,也可用于赋初始值 => 给矢量中的某些位赋值、或对某些位之外的 其它(用OTHERS表示)位赋值。 VARIABLE y : STD_LOGIC_VECTOR (3 DOWNTO 0) ; SIGNAL w : STD_LOGIC_VECTOR(0 TO 7) ; Y := “0000” ; w <= “10000000 ; w <= (0=>‘1’,OTHERS => ‘0’) ; 2018/11/27 逻辑设计基础
逻辑运算符 关系运算符 算术运算符 移位运算 并置(连接)运算符 AND、OR、NAND、NOR、XOR、NOT =、/=、<、>、<=、>= 算术运算符 +、-、*、/、MOD、REM、ABS 移位运算 sll srl sla sra rol ror 并置(连接)运算符 & (,,,,) 2018/11/27 逻辑设计基础
属性(Attributes) 用于获取数据的相关信息 数值类属性 d’LOW :返回数组索引的下限值 d’HIGH :返回数组索引的下限值 d’LEFT :返回数组索引的左边界值 d’RIGHT :返回数组索引的右边界值 d’LENGTH :返回矢量的长度值 d’RANGE :返回矢量的位宽范围 d’REVERSE_RANGE :按相反的次序,返回 矢量的位宽范围 2018/11/27 逻辑设计基础
signal d: STD_LOGIC_VECTOR (7 downto 0); 则有: d’LOW = 0 d’HIGH = 7 d’LEFT = 7 d’RIGHT = 0 d’LENGTH = 8 d’RANGE = (7 downto 0) d’REVERSE_RANGE = (0 to 7); 2018/11/27 逻辑设计基础
属性(Attributes)–续 信号类属性 s’EVENT :s的值发生了变化,则返回值为TRUE s’STABLE :s的值保持稳定,则返回值为TRUE s’ACTIVE :s的值等于‘1’,则返回值为TRUE s’QUIET<time> :指定时间内无变化,则返回TURE s’LAST_EVENT:上次事件发生到现在所经历的时间值 s’LAST_ACTIVE:最后一次s=‘1’到现在所经历的时间值 s’LAST_VALUE:返回最后一次变化前s的值 s’EVENT 和 s’STABLE可以被综合,其它仿真用。 2018/11/27 逻辑设计基础
§3.6并行语句 并行语句位于process外面,同时执行,不分位置的先后顺序 并行语句包括: 布尔等式: <= with-select-when when-else 2018/11/27 逻辑设计基础
with-select-when语句 Signal s : std_logic_vector(1 downto 0); with Sel_signal select Signal_name <= a when Sel_signal_1, b when Sel_signal_2, c when Sel_signal_3,… x when Sel_signal_x; Signal s : std_logic_vector(1 downto 0); Signal a,b,c,d,x : std_logic; with s select x <= a when “00”, b when “01”, c when “10”, d when others; 2018/11/27 逻辑设计基础
when-else语句 Signal a,b,c,d:std_logic; Signal w,x,y,z:std_logic; Signal_name <= a when condition1 else b when condition2 else c when condition3 else … x ; Signal a,b,c,d:std_logic; Signal w,x,y,z:std_logic; x <= w when a=‘1’ else x when b=‘1’ else y when c=‘1’ else z when d=‘1’ else ‘0’; x <= a when s=“00” else b when s=“01” else c when s=“10” else d; 2018/11/27 逻辑设计基础
实现优先级编码器 encode <= “111” when D(7) = ‘1’ else “000”; 2018/11/27 逻辑设计基础
when-else语句条件语句可以是一个简单的表达式 with-select-when则不能采用表达式作为条件 a <= “0000” when state=idle and state=‘1’ else “0001” when state=idle and state=‘0’ else b when state=running and state=‘1’ else a; 2018/11/27 逻辑设计基础
§3.7顺序语句 Process,Function,Procedure中的语句都是顺序执行。 Process与Process之间,与其他并行语句之间都是并行的关系 if-then-else case-when 2018/11/27 逻辑设计基础
if-then-else if (condition1) then do something ; elsif (condition2) then … else do something different ; end if; 2018/11/27 逻辑设计基础
用于作地址译码 InRam <= ‘0’; Periph1 <= ‘0’; Periph2 <= ‘0’; OutRam<= ‘0’; EEPRom <= ‘1’; If addr >= X “0000” and addr <X “4000” then InRam <= ‘1’; elsif addr >= X “4000” and addr <X “4008” then Periph1 <= ‘1’; elsif addr >= X “4008” and addr <X “4010” then Periph2 <= ‘1’; elsif addr >= X “8000” and addr <X “C000” then OutRam <= ‘1’; elsif addr >= X “C000” then EEPRom <= ‘1’; end if; B:2进制 O:8进制 X:16进制 2018/11/27 逻辑设计基础
case-when case sel_signal is when value_1 => (do sth) … when value_last => end case; 2018/11/27 逻辑设计基础
实现数码管译码器 Process(address) begin case address is when “0000” => decode <= X “3F” when “0001” => decode <= X “06” when “0010” => decode <= X “5B” when “0011” => decode <= X “4F” …… when others => decode <= X “00”; end case; end process; 2018/11/27 逻辑设计基础
几种语句的比较 语句 With-select-when When-else If-else Case-when 选择条件 一个信号的不同值,互斥 多个信号多种组合,不必互斥 语句属性 并行 顺序 用途 编码、译码、多路选择器 优先编码器,地址译码器 状态机 2018/11/27 逻辑设计基础
§3.8包与库 语法: package 包名称 is 包说明语句 end [package] [包名称]; package body 包名称 is 包主体说明语句 end [package body][包名称] 包说明:包含信号定义、常数定义、数据类型、 元件语句、函数定义和过程定义等。 包主体:component描述、函数和过程体。 2018/11/27 逻辑设计基础
经常使用的代码可以采取component、function或者procedure等形式放到package中,然后被编译到目标库中。 2018/11/27 逻辑设计基础
§3.9-VHDL程序示例 Figure 10-1: Gate Circuit 2018/11/27 逻辑设计基础
Figure 10-2: Inverter with Feedback 2018/11/27 逻辑设计基础
Figure 10-3: Three Gates with a Common Input and Different Delays 2018/11/27 逻辑设计基础
Figure 10-4: Array of AND Gates 2018/11/27 逻辑设计基础
Figure 10-5: 2-to-1 Multiplexer 2018/11/27 逻辑设计基础
Figure 10-6: Cascaded 2-to-1 MUXes 2018/11/27 逻辑设计基础
Figure 10-7: 4-to-1 Multiplexer 2018/11/27 逻辑设计基础
Figure 10-8: VHDL Module with Two Gates 2018/11/27 逻辑设计基础
Figure 10-10 -- filename: FullAdder.vhd library ieee; use ieee.std_logic_1164.all; ------------------------------------------------------------ entity FullAdder is port (X,Y,Cin: in bit; --Inputs Cout, Sum: out bit); --Outputs end FullAdder; architecture Equations of FullAdder is begin -- concurrent assignment statements Sum <= X xor Y xor Cin after 10 ns; Cout <= (X and Y) or (X and Cin) or (Y and Cin) after 10 ns; end Equations ; 2018/11/27 逻辑设计基础
Figure 10-11: 4-Bit Binary Adder 2018/11/27 逻辑设计基础
Figure 10-12: Structural Description of a 4-Bit Adder 2018/11/27 逻辑设计基础
2018/11/27 逻辑设计基础
Figure 10-13: VHDL Description of a ROM 1 entity ROM9_17 is 2 port (A, B, C: in bit; F: out bit_vector(0 to 3)); 3 end entity; 4 architecture ROM of ROM9_17 is 5 type ROM8X4 is array (0 to 7) of bit_vector(0 to 3); 6 constant ROM1: ROM8X4 := ("1010", "1010", "0111","0101", "1100", "0001", "1111", "0101"); 7 signal index: Integer range 0 to 7; 8 begin 9 Index <= vec2int(A&B&C); -- A&B&C Is a 3-bit vector 10 -- vec2int is a function that converts this vector to an integer 11 F <= ROM1 (index); 12 -- this statement reads the output from the ROM 13 end ROM; Figure 10-13: VHDL Description of a ROM 2018/11/27 逻辑设计基础
Figure 10-14: Comparator for Integers 2018/11/27 逻辑设计基础
Figure 10-15: NOR-NOR Circuit and Structural VHDL Code Using Library Components 2018/11/27 逻辑设计基础
Figure 10-16: Tri-State Buffer 2018/11/27 逻辑设计基础
Figure 10-17: Tri-State Buffers Driving a Bus 2018/11/27 逻辑设计基础
Figure 10-18: Resolution Function for Two Signals 2018/11/27 逻辑设计基础
Figure 10-19: VHDL Code for Binary Adder 2018/11/27 逻辑设计基础
Figure 10-20: VHDL Code for Bi-Directional I/O Pin entity IC_pin is port(IO_pin: inout std_logic); end entity; architecture bi_dir of IC_pin is component IC port(input: in std_logic; output: out std_logic); end component; signal input, output, en: std_logic; begin -- connections to bi-directional I/O pin IO_pin <= output when en = '1' else 'Z'; input <= IO_pin; IC1: IC port map (input, output); end bi_dir; Figure 10-20: VHDL Code for Bi-Directional I/O Pin 2018/11/27 逻辑设计基础
§3.10-VHDL的ModelSim仿真 <1> 建立一目录modelsimStudy。用任何文本编辑器编辑一个简单 的例子程序,例如counter.vhd。 <2> 打开Modelsim,首先create project,工程名随意取,目录设 在modelsimStudy下,默认的库work不变(这样就不用管什么 建立库之类的东西了)。然后add existing file,把文件加入 当前工程。 <3> 编译此文件,通过之后,work下面会出现counter这个实体。 然后选中它,右键,simulate(左键双击也可)。 <4> 选择view下面的 objects 和 wave窗口就行了。wave窗口刚打开 时是空的,需要在objects窗口的 add -> wave -> signals in region。这时,wave窗口就有counter的相关信号。 <5> 给counter的clk输入激励,在object窗口中选中clk,右键选 clock,给它定义个时钟。 <6>运行Run,看波形。 2018/11/27 逻辑设计基础
2018/11/27 逻辑设计基础