电子设计自动化
电子设计自动化
授课教师:何
授课教师:何
旭
旭
第七章
第七章
编程技巧
编程技巧
第一节VHDL编程方法
第二节定时建模的方法
第三节用错误检查提高建模准确性
第四节提高仿真性能建模
第五节对逻辑操作查表
第六节Process语句—避免无限循环
第七节用VHDL做仿真激励
第一节VHDL编程方法
采用如下方法增强复杂设计的可读性:
?将相关的声明与描述归为一组
?用缩排表示隶属关系
?用空格进行代码分隔
?使相似的字(如保留字)和标点一致
?注释程序功能
?保留字用大写字母,用户定义标识符用小写字母
?对于generic和常数标识符,第一个字母大写,其余小写
?对process,并行程序调用等标号(描述名)
?时刻想着读者。你可能只写一次,但会读多次
第二节定时建模的方法
一、嵌入固定延时参数
例:
ENTITY and2_gate IS
PORT (in0, in1 : IN bit;
out1 : OUT bit);
END and2_gate;
ARCHITECTURE fixed_delay OF and2_gate IS
CONSTANT Typical_delay : time := 8 ns;
BEGIN
out1 <= in0 AND in1 AFTER Typical_delay;
END fixed_delay;
二、嵌入可变延时参数
例:
LIBRARY my_lib;
USE my_lib. Logic_example. ALL;
ENTITY and2_gate IS
PORT (in0, in1 : IN my_lsim_LOGIC;
out1 : OUT my_lsim_LOGIC);
END and2_gate;
ARCHITECTURE variable_delay OF and2_gate IS
CONSTANT Tplh_typ : time := 5 ns;
CONSTANT Tphl_typ : time := 8 ns;
BEGIN
and_inputs : PROCESS (in0, in1)
BEGIN
IF (in0 AND in1) = ‘1’ THEN
out1 <= ‘1’ AFTER Tplh_typ;
ELSIF (in0 AND in1) = ‘0’ THEN
out1 <= ‘0’ AFTER Tphl_typ;
ELSIF (Tplh_typ >= Tphl_typ) THEN
out1 <= ‘X’ AFTER Tplh_typ;
ELSE
out1 <= ‘X’ AFTER Tphl_typ;
END IF;
END PROCESS and_inputs;
END variable_delay;
三、用generic参数化模型
例:
LIBRARY my_lib;
USE my_lib. my_qsim_logic. ALL;
ENTITY test_and2_gate IS
END test_and2_gate;
ARCHITECTURE test_bench OF test_and2_gate IS
COMPONENT and2
GENERIC (Rs, Fl : time);
PORT (a, b : IN my_qsim_12state;
c : OUT my_qsim_12state);
END COMPONENT;
FOR a1 : and2 USE ENTITY and2_gate(behav)
GENERIC MAP (Rs, Fl)
PORT MAP (a, b, c);
SIGNAL x, y, z : my_qsim_12state;
BEGIN
a1 : and2
GENERIC MAP (7 ns, 10 ns);
PORT MAP (x, y, z);
END test_bench;
PACKAGE my_qsim_logic IS
TYPE my_qsim_state IS (‘X’, ‘0’, ‘1’, ‘Z’);
SUBTYPE my_qsim_value IS qsim_state_state RANGE ‘X’ TO ‘1’;
TYPE my_qsim_12state IS (SXR, SXZ, SXS,
SXI, S0R, S0Z,
S0S, S0I, S1R,
S1Z, S1S, S1I);
FUNCTION my_qsim_state_from (val: my_qsim_12state)
RETURN my_qsim_state;
END my_qsim_logic;
USE my_qsim_logic. ALL;
ENTITY and2_gate IS
GENERIC (Out1_rs, Out1_fl : time := 0 ns);
PORT (in0, in1 : IN my_qsim_12state;
out1 : OUT my_qsim_12state);
END and2_gate;
ARCHITECTURE behave OF and2_gate IS
BEGIN
and_inputs : PROCESS (in0, in1)
BEGIN
IF ((my_qsim_state_from (in0) AND my_qsim_state_from (in1)) = ‘1’)
THEN out1 <= S1S AFTER Out1_rs;
ELSIF ((my_qsim_state_from (in0) AND my_qsim_state_from(in1))=‘0’)
THEN out1 <= S0S AFTER Out1_fl;
ELSIF (Out1_rs >= Out1_fl) THEN
out1 <= SXS AFTER Out1_rs;
ELSE
out1 <= SXS AFTER Out1_fl;
END IF;
END PROCESS and_inputs;
END behave;
四、用Generic参数化上升/下降延时
对多值延时进行参数化
例:设在package : my_qsim_extended中
有function 为my_qsim_get_time,
可以将字符串根据定时模式转换为时间值
USE my_lib. My_qsim_logic. ALL; 1bit锁存器实体声明
USE my_lib. My_qsim_extended. ALL;
ENTITY latch IS
GENERIC (
--
--
--
CONSTANT Data_rise : string := “0, 0, 0”;
CONSTANT Data_fall : string := “0, 0, 0”;
CONSTANT Enable_rise : string := “0, 0, 0”;
CONSTANT Enable_fall : string := “0, 0, 0”;
CONSTANT Timing_mode : timing_type := typ);
PORT (enable, data : IN my_qsim_state;
q_out : OUT my_qsim_state);
CONSTANT Data_tplh : time := my_qsim_get_time
(Data_rise, Timing_mode);
CONSTANT Data_tphl : time := my_qsim_get_time
(Data_fall, Timing_mode);
CONSTANT Enable_tplh : time := my_qsim_get_time
(Enable_rise, Timing_mode);
CONSTANT Enable_tphl : time := my_qsim_get_time
(Enable_fall, Timing_mode);
BEGIN
--
END latch;
Test Bench Model latch Entity
timing_mode min, typ, max
Test_latch data 8, 16, 30
上升
data 7, 14, 25
下降
enable 8, 16, 30
上升
enable 5, 7, 15
下降
LIBRARY my_lib; 测试台程序
USE my_lib. My_qsim_logic. ALL;
USE my_lib. My_qsim_extended. ALL;
ENTITY test_latch IS
END test_latch
ARCHITECTURE test_bed OF test_latch IS
COMPONENT latch1
GENERIC (En_width, Da_setup, Da_hold : time;
Da_rise, Da_fall, En_rise, En_fall : string;
Timing_mode : timing_type);
PORT (Da, en : IN my_qsim_state;
q0 : OUT my_qsim_state);
END COMPONENT;
FOR L1 : latch1 USE ENTITY latch (behav1)
GENERIC MAP (En_width, Da_setup, Da_hold,
Da_rise, Da_fall,
En_rise, En_fall, Timing_mode);
PORT MAP (da, en, q0);
SIGNAL data, enable, q_out : my_qsim_state;
BEGIN
L1 : latch1
GENERIC MAP (20 ns, 20 ns, 5 ns,
“8, 16, 30”, “7, 14, 25”,
“8, 16, 30”, “5, 7, 15”, typ);
PORT MAP (data, enable, q_out);
END test_bed;
ARCHITECTURE behav1 OF latch IS 1bit锁存器结构体
BEGIN
PROCESS (enable, data)
BEGIN
IF enable’event THEN
IF enable = ‘1’ THEN
IF data = ‘1’ THEN
q_out <= data AFTER Enable_tplh;
ELSIF data = ‘0’ THEN
q_out <= data AFTER Enable_tphl;
ELSIF Enable_tplh > Enable_tphl THEN
q_out <= ‘X’ AFTER Enable_tplh;
ELSE
q_out <= ‘X’ AFTER Enable_tphl;
END IF;
ELSIF enable /= ‘0’ THEN
IF Enable_tplh >= Enable_tphl THEN
q_out <= ‘X’ AFTER Enable_tplh;
ELSE
q_out <= ‘X’ AFTER Enable_tphl;
END IF;
END IF;
ELSE
IF enable = ‘1’ THEN
IF data = ‘1’ THEN
q_out <= data AFTER Data_tplh;
ELSIF data = ‘0’ THEN
q_out <= data AFTER Data_tphl;
ELSIF Data_tplh >= Data_tphl THEN
q_out <= ‘X’ AFTER Data_tplh;
ELSE
q_out <= ‘X’ AFTER Data_tphl;
END IF;
END IF;
END IF;
END PROCESS;
END behav1;
第三节用错误检查提高建模准确性
进行建立和保持时间检查
USE my_lib. My_qsim_logic. ALL; 1bit锁存器实体声明
USE my_lib. My_qsim_extended. ALL;
ENTITY latch IS
GENERIC (
CONSTANT Enable_width : time := 0 ns;
CONSTANT Data_setup : time := 0 ns;
CONSTANT Data_hold : time := 0 ns;
CONSTANT Data_rise : string := “0, 0, 0”;
CONSTANT Data_fall : string := “0, 0, 0”;
CONSTANT Enable_rise : string := “0, 0, 0”;
CONSTANT Enable_fall : string := “0, 0, 0”;
CONSTANT Timing_mode : timing_type := typ);
PORT (enable, data : IN my_qsim_state;
q_out : OUT my_qsim_state);
CONSTANT Data_tplh : time := my_qsim_get_time
(Data_rise, Timing_mode);
CONSTANT Data_tphl : time := my_qsim_get_time
(Data_fall, Timing_mode);
CONSTANT Enable_tplh : time := my_qsim_get_time
(Enable_rise, Timing_mode);
CONSTANT Enable_tphl : time := my_qsim_get_time
(Enable_fall, Timing_mode);
BEGIN
chk_width : ASSERT (enable = ‘1’) OR (enable’delayed = ‘0’) OR
(enable’delayed’ last_event >= Enable_width)
REPORT “Enable signal has insufficient pulse width.”
SEVERITY error;
chk_setup : ASSERT (enable’ stable) OR (enable /= ‘0’) OR
(data’ last_event >= Data_setup)
REPORT “Data-to-enable setup time violation.”
SEVERITY error;
chk_hold : ASSERT (data’ stable) OR (enable /= ‘0’) OR
(enable’ last_event >= Data_hold)
REPORT “Data-from-enable hold time violation.”
SEVERITY error;
END latch;
20 ns 16 ns
enable
enable’delayed
30 ns 递归1 30 ns 递归2
enable
enable’delayed
’delayed属性示意图
Data_setup Data_hold Data_hold
20 ns 5 ns 3 ns
Enable
data
第四节提高仿真性能建模
一、在循环中用变量代替信号的时机
信号:保存一组波形值,并在递归完成时
进行赋值。
ARCHITECTURE a1 OF en IS
TYPE var_arr IS ARRAY (1 TO 64) OF integer;
SIGNAL sig1 : integer;
BEGIN
PROCESS (cntrl)
VARIABLE max : integer;
VARIABLE var : var_arr;
BEGIN
FOR elmnt IN 1 TO 64 LOOP
IF var (elmnt) > max THEN
sig1 <= var (elmnt);
max := var (elmnt);
END IF;
END LOOP;
END PROCESS;
END a1;
ARCHITECTURE a2 OF en IS
TYPE var_arr IS ARRAY (1 TO 64) OF integer;
SIGNAL sig1 : integer;
BEGIN
PROCESS (cntrl)
VARIABLE max : integer;
VARIABLE var : var_arr;
BEGIN
FOR elmnt IN 1 TO 64 LOOP
IF var (elmnt) > max THEN
max := var (elmnt);
END IF;
END LOOP;
sig1 <= max;
END PROCESS;
END a2;
二、仅当需要时采用决断函数
多信号驱动时需要采用决断函数
因为决断函数仿真资源开销比较大,慎重使用。
例:信号s1需要采用决断函数
SIGNAL s1, s2 : wired_or bit;
例:信号s1需要采用决断函数
SIGNAL s1, s2 : wired_or bit;
应代替为
SIGNAL s1 : wired_or bit;
SIGNAL s2 : bit;
三、用属性’event代替’stable
用更专用的程序模块代替通用的程序模块,
以提高仿真性能。
例:
IF (sig’stable = false) THEN
-- something happened
END IF;
IF (sig’event = true) THEN
-- something happened
END IF;
第五节对逻辑操作查表
对布尔或逻辑操作十分有效
表作为常数
例:实现两个my_lsim_Logic类型信号的与运算
sig3 <= sig1 AND sig2;
PACKAGE logic_example IS
TYPE my_lsim_logic IS (‘0’, ‘1’, ‘X’, ‘Z’);
FUNCTION “AND” (a, b : IN my_lsim_Logic)
RETURN my_lsim_Logic;
END logic_example;
PACKAGE BODY logic_example IS
FUNCTION “AND” (a, b : IN my_lsim_Logic)
RETURN my_lsim_Logic IS
TYPE a2_lookup IS ARRAY
(my_lsim_Logic’(‘0’) TO my_lsim_Logic’(‘Z’),
My_lsim_Logic’(‘0’) TO my_lsim_Logic’(‘Z’))
OF my_lsim_Logic;
CONSTANT Output : a2_lookup :=
-- 0 1 X Z
((‘0’, ‘0’, ‘0’, ‘0’), -- 0
(‘0’, ‘1’, ‘X’, ‘X’), -- 1
(‘0’, ‘X’, ‘X’, ‘X’), -- X
(‘0’, ‘X’, ‘X’, ‘X’)); -- Z
BEGIN
RETURN Output (a, b);
END “AND”;
END logic_example;
第六节Process语句—避免无限循环
Process语句一旦被激活(运行),它将始
终运行下去,直到被某个条件所终止。
终止process语句的条件有:
?敏感表
?Wait语句
?包含wait语句的procedure调用
ARCHITECTURE behav3 OF aoi IS
SIGNAL O1, O2, O3 : my_lsim_logic;
BEGIN
O1 <= A AND B;
O2 <= C AND D;
P1: PROCESS
BEGIN 导致
O3 <= O1 OR O2; 无限循环
END PROCESS;
P2: PROCESS
BEGIN
E <= NOT O3;
END PROCESS;
END behav3;
ARCHITECTURE behav3 OF aoi IS
SIGNAL O1, O2, O3 : my_lsim_logic;
BEGIN
O1 <= A AND B;
O2 <= C AND D;
P1: PROCESS (O1, O2)
BEGIN
O3 <= O1 OR O2;
END PROCESS;
P2: PROCESS
BEGIN
E <= NOT O3;
WAIT ON O3;
END PROCESS;
END behav3;
LIBRARY contains_package;
USE pkg_at_rt. ALL;
ENTITY expl IS
PORT (sig1 : IN bit);
END expl;
ARCHITECTURE behav OF expl IS
BEGIN
PROCESS
VARIABLE var1 : bit;
BEGIN
-- something happens here
procedure1 (var1, sig1);
END PROCESS;
END behav;
PACKAGE pkg_at_rt IS
PROCEDURE procedure1 (
VARIABLE frst : OUT bit;
VARIABLE scnd : IN bit);
END pkg_at_rt;
PACKAGE BODY pkg_at_rt IS
PROCEDURE procedure1 (
VARIABLE frst : OUT bit;
VARIABLE scnd : IN bit) IS
BEGIN
frst := NOT scnd;
WAIT FOR 10 ns;
END procedure1;
END pkg_at_rt;
第七节用VHDL做仿真激励
VHDL仿真激励可有多种,VHDL测试台是其中
的一种
LIBRARY my_lib;
USE my_lib. My_qsim_logic. ALL;
ENTITY test_and2_gate IS
END test_and2_gate;
ARCHITECTURE test_bed OF test_and2_gate IS
COMPONENT and2
GENERIC (Rs, Fl : time);
PORT (a, b : IN my_qsim_12state;
c : OUT my_qsim_12state);
END COMPONENT;
FOR a1 : and2 USE ENTITY and2_gate(behav)
GENERIC MAP (Rs, Fl)
PORT MAP (a, b, c);
SIGNAL x, y, z : my_qsim_12state;
BEGIN
a1 : and2
GENERIC MAP (7 ns, 10 ns);
PORT MAP (x, y, z);
x <= S0S AFTER 10 ns,
S1S AFTER 20 ns,
SXS AFTER 30 ns,
S0S AFTER 40 ns,
S1S AFTER 50 ns,
SXS AFTER 60 ns,
S0S AFTER 70 ns;
y <= S0S AFTER 40 ns,
S1S AFTER 70 ns,
SXS AFTER 130 ns;
END test_bed;