电子设计自动化 电子设计自动化 授课教师:何 授课教师:何 旭 旭 第七章 第七章 编程技巧 编程技巧 第一节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;