电子设计自动化
电子设计自动化
授课教师:何
授课教师:何
旭
旭
第五章
第五章
分解设计功能的结构
分解设计功能的结构
第一节并行分解
第二节串行分解
第三节并行与串行建模比较
第四节信号与变量赋值
第五节多值驱动的决断
第六节产生共享模块
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;