电子设计自动化 电子设计自动化 授课教师:何 授课教师:何 旭 旭 第五章 第五章 分解设计功能的结构 分解设计功能的结构 第一节并行分解 第二节串行分解 第三节并行与串行建模比较 第四节信号与变量赋值 第五节多值驱动的决断 第六节产生共享模块 Delta延迟 Block1 Block2 Process1 CS1 CS2 CS3 CS1 CS2 CS3 SS1 SS2 SS3 递归1 时间 第一节并行分解 构造硬件并行执行的功能 VHDL语言中并行语句有 语言中并行语句有 z并行信号赋值语句 z Process语句 z并行程序(procedure)调用 z并行断言(assertion)语句 z Block语句 z元件实例化语句 z Generate语句 VHDL语言中并行语句有 语言中并行语句有 z并行信号赋值语句 z Process语句 z并行程序(procedure)调用 z并行断言(assertion)语句 z Block语句 z元件实例化语句 z Generate语句 一、Block语句 Block语句是分解硬件功能的主要的 并行语句。它将多个并行语句归入一个 设计单元。 格式: block statement …… label: BLOCK (expression) block_declarative_item BEGIN concurrent_statement END BLOCK label; 例:ENTITY bistable_latch IS PORT (enable, data : IN bit; q, q_not : OUT bit); END bistable_latch; ARCHITECTURE example OF bistable_latch IS BEGIN latch1: BLOCK (enable=‘1’) SIGNAL d_in : bit; BEGIN d_in <= GUARDED data; q <= d_in; q_not <= NOT d_in; END BLOCK latch1; END example; ’behavior 和’structure 识别block是行为级描述或结构级描述。 例: ASSERT latch1’behavior REPORT “Block latch1 is not a behavioral description”; SEVERITY note; ASSERT latch1’structure REPORT “Block latch1 is not a structural description”; SEVERITY note; 二、元件实例化语句 介绍元件声明和元件实例化语句。 (仅用于结构级描述) 元件实例化的顺序: 先声明后实例化 元件声明描述了元件的接口关系 格式: component declaration … COMPONENT identifier generic_clause port_clause END COMPONENT; component instantiation statement……label: name generic_map_aspect port_map_aspect ; generic map aspect …… GENERIC MAP (association_list) port map aspect …… PORT MAP (association_list) Association list …… association_element, association_element … VHDL描述:ENTITY mux IS --实体声明 PORT (d0, d1, sel: IN bit; q: OUT bit ); --端口语句 END mux; --结构体 ARCHITECTURE struct OF mux IS COMPONENT and2 --结构声明部分 PORT(a, b: IN bit; c: OUT bit); END COMPONENT; COMPONENT or2 PORT(a, b: IN bit; c: OUT bit); END COMPONENT; COMPONENT inv PORT (a: IN bit c: OUT bit); END COMPONENT; SIGNAL aa,ab, nsel: bit ; --信号声明 FOR U1 :inv USE ENTITY WORK. Invrt (behav); --配置说明 FOR U2 , U3:and2 USE ENTITY WORK. And_gt(dflw); -- FOR U4 :or 2 USE ENTITY WORK. Or_gt(arch1); -- BEGIN u1: inv PORT MAP (sel, nsel); --结构体描述部分 u2: and2 PORT MAP (nsel, d1, ab); u3: and2 PORT MAP (d0, sel, aa); u4: or2 PORT MAP (aa, ab, q); END struct; 用不同的参数实例化元件—— generic clause 例如:与门中,entity declaration 中有generic clause: prop_delay : time; 在architecture body 中有: generic map : prop_delay => 12 ns; generic map : prop_delay => 10 ns; generic map : prop_delay => 8 ns; 第二节串行分解 硬件功能串行执行的结构 在 在 VHDL语言中可用作串行执行的语句有: 语言中可用作串行执行的语句有: z控制语句(Control Statements) If语句、Case语句、Wait语句 在 在 VHDL语言中可用作串行执行的语句有: 语言中可用作串行执行的语句有: z控制语句(Control Statements) z循环语句(Looping Statements) 在 在 VHDL语言中可用作串行执行的语句有: 语言中可用作串行执行的语句有: z控制语句(Control Statements) z循环语句(Looping Statements) Loop语句、Next语句、Exit语句 在 在 VHDL语言中可用作串行执行的语句有: 语言中可用作串行执行的语句有: z控制语句(Control Statements) z循环语句(Looping Statements) z赋值语句(Assignments) 在 在 VHDL语言中可用作串行执行的语句有: 语言中可用作串行执行的语句有: z控制语句(Control Statements) z循环语句(Looping Statements) z赋值语句(Assignments) 信号赋值、变量赋值 在 在 VHDL语言中可用作串行执行的语句有: 语言中可用作串行执行的语句有: z控制语句(Control Statements) z循环语句(Looping Statements) z赋值语句(Assignments) z断言语句(Assertion Statement) z返回语句(Return Statement) z空语句(Null Statement) z子程序(Subprograms) 在 在 VHDL语言中可用作串行执行的语句有: 语言中可用作串行执行的语句有: z控制语句(Control Statements) z循环语句(Looping Statements) z赋值语句(Assignments) z断言语句(Assertion Statement) z返回语句(Return Statement) z空语句(Null Statement) z子程序(Subprograms) 子程序(Subprograms) 用算法计算值,然后返回 分为: procedure function 子程序结构: 子程序声明(subprogram declaration) 子程序体(subprogram body) subprogram subprogram declaration subprogram body 子程序声明定义子程序与外部环境接口 子程序体为算法或行为描述 通过调用子程序使主程序阅读更为方便 主程序关心的是发生了什么事(What happened) 子程序描述怎么发生的(How happeded) Procedure 与function的区别: function只返回一个值(用return),且不改 变其它值。 procedure可返回多个值(无return),或不 返回值,可改变其它值。 主程序 Procedure Call RAM Load Procedure RAM File Procedure Call RAM Read Procedure Procedure Call Concat RAM Data Procedure Function Call Check Parity Function Op_Code(256) Op_Code(256) RAM_Code(4) Address RAM_Data(4) RAM_Data(4) RAM_Data_Conc RAM_Data_Conc Op_Code_Conc Boolean Value RAM_Package 子程序在package中定义。 主程序在调用前需要用Library语句 和Use语句使之可见。 说明: 子程序声明的格式: PROCEDURE designator (formal_parameter_list); --或者 FUNCTION designator (formal_parameter_list) RETURN type_mark; 子程序体的格式: PROCEDURE designator (formal_parameter_list) IS --或者 FUNCTION designator (formal_parameter_list) RETURN type_mark IS subprogram_declarative_part BEGIN subprogram_statement_part END designator; function调用格式: function call …… name (association_element, …) association_element …… format_part => actual_part procedure调用的格式: 并行调用concurrent procedure call …… label: name (association_element, …); 串行调用procedure call statement …… name (association_element, …); 在实体声明之前需要有: LIBRARY lib_stuff, package_stuff; 在实体声明或结构体的声明部分需要有: USE lib_stuff.ram_package.all; 在ram_package的声明部分有: TYPE op_code_array IS ARRAY (0 TO 255) OF bit_vector(0 TO 7); ------Procedure 声明------ PROCEDURE ram_load (CONSTANT Op_code: IN op_code_array); ------Procedure 体------ PROCEDURE ram_load (CONSTANT Op_code: IN op_code_array) IS FILE ram_cntnts: op_code_array IS IN “/idea/user/vhdl_lib/ram1_file”; BEGIN FOR a IN Op_code’RANGE LOOP write (ram_cntnts, Op_code(a)); END LOOP; END ram_load; 在ram_package的声明部分需要有: TYPE ram_data_array IS ARRAY (0 TO 3) OF bit_vector (0 TO 7); 在预定义的math package中有: FUNCTION rand (seed: real) RETURN real; ------Procedure 声明------ PROCEDURE ram_read (VARIABLE ram_data: OUT ram_data_array; VARIABLE test_add_start: OUT integer); ------Procedure 体------ PROCEDURE ram_read (VARIABLE ram_data: OUT ram_data_array; VARIABLE test_add_start: OUT integer) IS FILE ram_cntnts: op_code_array IS IN “/idea/user/vhdl_lib/ram1_file”; USE std.math.rand; VARIABLE address : integer; VARIABLE op_code: op_code_array; CONSTANT Seed : real := 0.1; BEGIN address := integer ( rand(Seed) * 63.0) * 4; test_add_start := address; FOR a IN 0 TO (address + 3) LOOP read( ram_cntnts, op_code(a)); IF a >= address THEN ram_data( a – address) := op_code(a); END IF; END LOOP; END ram_read; ------Procedure 声明------ PROCEDURE concat_data (CONSTANT Ram_data: IN ram_data_array; VARIABLE ram_data_conc: OUT bit_vector (0 TO 31)); ------Procedure 体------ PROCEDURE concat_data (CONSTANT Ram_data: IN ram_data_array; VARIABLE ram_data_conc: OUT bit_vector (0 TO 31)) IS BEGIN ram_data_conc := Ram_data(0) & Ram_data(1) & Ram_data(2) & Ram_data(3) ; END concat_data; ------ Function声明------ FUNCTION chk_pty ( CONSTANT Ram_data_conc : IN bit_vector (0 TO 31); CONSTANT Op_code_conc : IN bit_vector (0 TO 31)) RETURN boolean; ------ Function 体------ FUNCTION chk_pty ( CONSTANT Ram_data_conc : IN bit_vector (0 TO 31); CONSTANT Op_code_conc : IN bit_vector (0 TO 31)) RETURN boolean IS VARIABLE sum1, sum2 : boolean := false; BEGIN FOR i IN 0 TO 31 LOOP IF Ram_data_conc(i) = ‘1’ THEN sum1 := NOT sum1; END IF; IF Op_code_conc(i) = ‘1’ THEN sum2 := NOT sum2; END IF; END LOOP; RETURN sum1 = sum2 ; END chk_pty; Function调用: Chk_pty (op_code_conc => op_code_c, ram_data_conc => ram_data_c) Procedure调用: Ram_read (ram_data => ram_data_in, test_add_start => start_address) 第三节并行与串行建模对照 并行语句:对全部右端信号敏感 串行语句:逐行执行 ABCDE(输出) 00001 00011 00101 00110 01001 01011 01101 01110 10001 10011 10101 10110 11000 11010 11100 11110 例:实现一个aoi电路,真值表如下: 00 01 11 10 0 1101 011101 1 0000 101101 CD AB 卡诺图表示为: LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY aoi IS PORT (A, B, C, D : IN std_logic; E : OUT std_logic); END aoi; ARCHITECTURE behav1 OF aoi IS BEGIN E <= NOT (( A AND B) OR (C AND D)); END behav1; ARCHITECTURE rtl OF aoi IS SIGNAL O1, O2, O3 : std_logic; BEGIN E <= NOT O3; -- CS1 O1 <= A AND B; -- CS2 O2 <= C AND D; -- CS3 O3 <= O1 OR O2; -- CS4 END rtl; ARCHITECTURE behav2 OF aoi IS BEGIN PROCESS (A, B, C, D) VARIABLE O1, O2, O3 : std_logic; BEGIN O1 := A AND B; -- SS1 O2 := C AND D; -- SS2 O3 := O1 OR O2; -- SS3 E <= NOT O3; -- SS4 END PROCESS; END behav2; 执行步骤图 behav1 rtl behav2 Process CS1 CS2 CS3 递归1 递归1 CS4 递归2 递归2 CS1 递归3 递归1 递归2 SS1 SS2 SS3 SS4 ARCHITECTURE behav2 OF aoi IS BEGIN PROCESS (A, B, C, D) VARIABLE O1, O2, O3 : std_logic; BEGIN O3 := O1 OR O2; O1 := A AND B; O2 := C AND D; E <= NOT O3; END PROCESS; END behav2; ARCHITECTURE behav2 OF aoi IS BEGIN PROCESS (A, B, C, D) VARIABLE O1, O2, O3 : std_logic; BEGIN O3 := O1 OR O2; O1 := A AND B; O2 := C AND D; E <= NOT O3; END PROCESS; END behav2; ERROR! ARCHITECTURE behav3 OF aoi IS SIGNAL O1, O2, O3 : std_logic; BEGIN O1 <= A AND B; O2 <= C AND D; P1: PROCESS (O1, O2) BEGIN O3 <= O1 OR O2; END PROCESS; P2: PROCESS (O3) BEGIN E <= NOT O3; END PROCESS; END behav3; 递归1 P1:Process 递归2 P2:Process 递归3 第四节信号与变量赋值 信号赋值:在Delta延迟后完成 变量赋值:立即赋值 ARCHITECTURE behav4 OF aoi IS SIGNAL O1, O2, O3 : std_logic; BEGIN PROCESS(A, B, C, D) BEGIN O1 <= A AND B; O2 <= C AND D; O3 <= O1 OR O2; E <= NOT O3; END PROCESS; END behav4; ARCHITECTURE behav4 OF aoi IS SIGNAL O1, O2, O3 : std_logic; BEGIN PROCESS(A, B, C, D) BEGIN O1 <= A AND B; O2 <= C AND D; O3 <= O1 OR O2; E <= NOT O3; END PROCESS; END behav4; ERROR! ARCHITECTURE behav5 OF aoi IS SIGNAL O1, O2, O3 : std_logic; BEGIN PROCESS( A, B, C, D) BEGIN O3 <= O1 OR O2; O1 <= A AND B; O2 <= C AND D; E <= NOT O3; END PROCESS; END behav5; ARCHITECTURE behav5 OF aoi IS SIGNAL O1, O2, O3 : std_logic; BEGIN PROCESS( A, B, C, D) BEGIN O3 <= O1 OR O2; O1 <= A AND B; O2 <= C AND D; E <= NOT O3; END PROCESS; END behav5; ERROR! ARCHITECTURE behav4_fixed OF aoi IS SIGNAL O1, O2, O3 : std_logic; BEGIN PROCESS( A, B, C, D, O1, O2, O3) BEGIN O1 <= A AND B; O2 <= C AND D; O3 <= O1 OR O2; E <= NOT O3; END PROCESS; END behav4_fixed; 例:实现一个累加器,从1加到10 ARCHITECTURE arch1 OF ch_val IS TYPE ar1 IS ARRAY (1 TO 10) OF integer; SIGNAL t : integer := 0; SIGNAL arr_a : ar1; BEGIN PROCESS (cntrl) BEGIN FOR i IN 1 TO 10 LOOP t <= t + arr_a(i); END LOOP; END PROCESS; END arch1; 例:实现一个累加器,从1加到10 ARCHITECTURE arch1 OF ch_val IS TYPE ar1 IS ARRAY (1 TO 10) OF integer; SIGNAL t : integer := 0; SIGNAL arr_a : ar1; BEGIN PROCESS (cntrl) BEGIN FOR i IN 1 TO 10 LOOP t <= t + arr_a(i); END LOOP; END PROCESS; END arch1; ERROR! ARCHITECTURE arch_ok OF ch_val IS TYPE ar1 IS ARRAY (1 TO 10) OF integer; SIGNAL t : integer := 0; SIGNAL arr_a : ar1; BEGIN PROCESS (cntrl) VARIABLE a : integer := 0; BEGIN FOR i IN 1 TO 10 LOOP a := a + arr_a(i); END LOOP; t <= a; END PROCESS; END arch1; 第五节多值驱动的决断 电路中存在一个信号被多个驱动器驱动的现象。 VHDL中实现多值驱动的方法:仲裁机制 例:SIGNAL total : wired_or integer; 第六节产生共享模块 --用Package 一、Package用法 用Package搜集一组相关项,供其它 程序模块使用 Package中可包含的有 中可包含的有 z类型和子类型声明 z常数 z子程序(functions 和procedures) z信号 硬件设计Package调用示意图 模块1 模块2 Package 模块3 模块4 例如: 在“standard” Package中有如下定义: PACKAGE standard_portion IS --predefined enumeration types: TYPE bit IS (‘0’, ‘1’); TYPE boolean IS (false, true); --predined array types TYPE string IS ARRAY (positive RANGE<>) OF character; TYPE bit_vector is ARRAY (natural RANGE<>) OF bit; END standard_portion; Package由两部分构成: 由两部分构成: Package声明 声明 ( ( Package Declaration) Package体 体 ( ( Package Body) Package Package Declaration Package Body Package声明在Package以外可见。 格式:PACKAGE identifier IS package_declarative_part END identifier; Package体在Package外不可见。 格式:PACKAGE BODY identifier IS package_body_declarative_part END identifier; Package是独立的库单元 Package体为可选 ——— Package声明必须先于使用它的程序被编译。 Package体可在使用它的程序进行仿真前被编译。 修改package声明:重编译package声明package体 实体声明结构体 修改package体:仅重编译package体 /idea/user/name/sys_1076_tutorial my_package tlc tlc_types tlc_types library_clause behavioral proc_decl procedure use_clause of tlc ENTITY tlc proc_call pkg_hdr pkg_body entity arch1 Package与实体的关系示意图 二、调用package 用library语句指定库 用use语句指定声明 1.在实体前用library语句指定库 2.指定逻辑名物理地址映射 3.在需要使用package内容的地方之 前使用use语句 格式: Library clause …… LIBRARY logical_name_list ; Use clause …… USE prefix.suffix, prefix.suffix, … ; 例如: LIBRARY package_lib, vhdlsim_lib ; USE package_lib. package1. ALL; 例如: LIBRARY package_lib, vhdlsim_lib ; USE package_lib. package1. ALL; 库package package 中的声明 ~~~~~~~~~ ~~~~~~ ~~~~ 例如: USE lib_stf. mem_ops. ram_load; USE lib_stf. mem_ops. ram_read;