testbench怎么写_testbench经典教程VHDL

电子常识

2640人已加入

描述

  testbench是一种验证的手段。首先,任何设计都是会有输入输出的。但是在软环境中没有激励输入,也不会对你设计的输出正确性进行评估。那么此时便有一种,模拟实际环境的输入激励和输出校验的一种“虚拟平台”的产生。在这个平台上你可以对你的设计从软件层面上进行分析和校验,这个就是testbench的含义。

  testbench怎么写

  一个最基本的Testbench包含三个部分,信号定义、模块接口和功能代码。借用一下特权同学总结的编写Testbench的三个基本步骤:

  1、对被测试设计的顶层接口进行例化;

  2、给被测试设计的输入接口添加激励;

  3、判断被测试设计的输出相应是否满足设计要求。

  逐步解决编写Testbench的这三点:

  首先“对被测试设计的顶层接口进行例化”,这一步相对比较简单,例化就是,但端口多时也够喝一壶的,而且要分wire、reg,有时会弄错,别难过,其实可以偷个懒,通过Quartus II自动生成一个Testbench的模板,选择Processing -》 Start -》 Start Test Bench Template Writer,等待完成后打开刚才生成的Testbench,默认是保存在simulation\Modelsim文件夹下的.vt格式文件。这一步就不多讲了,偷懒就挺好。

  其次“给被测试设计的输入接口添加激励”,一般时序设计必然涉及到最基本的两个信号——clk、rst_n(时钟、复位),肯定有童鞋会讲可以没有rst_n,是可以没有,但何必呢,让代码更健壮一点不很好嘛,别钻牛角尖。下面攻克clk、rst_n的写法:

  首先先讲一下timescale,因为想要进行仿真首先要规定时间单位,而且最好在Testbench里面统一规定时间单位,而不要在工程代码里定义,因为不同的模块如果时间单位不同可能会为仿真带来一些问题,而timescale本身对综合也就是实际电路没有影响。 `timescale 1ns/ 1ps表示仿真的单位时间为1ns,精度为1ps。

  vhdl

  上述三种代码的目的就是产生系统时钟,给clk一个初值后,不断重复执行:每10ns翻转一次clk,从而生成一个周期为20ns,频率50MHz的方波信号。第一、二种基本类似,第三种比较简单,少了一个initial,放在了always里初始化。

  三种方法都无一例外地给clk赋了初值,因为信号的缺省值为Z,如果不赋初值,则反相后还是Z,时钟就一直处于高阻Z状态。小编同学一般选中第一种,看个人喜欢。

  根据复位方式的不同,rst_n一般有两种写法:

  vhdl

  上述两种代码的目的基本都是延时复位,但一个异步复位,一个同步复位,用途不同,小编同学一般使用异步复位。

  最后“判断被测试设计的输出相应是否满足设计要求”。首先介绍最常用的两个系统任务函数$stop和$finish。$stop代表暂停仿真后返回软件操作主窗口,将控制权交给user;$finish代表终止仿真后关闭软件操作主窗口。其他任务函数如$monitor、$display 、$time、$fwrite等也比较重要,用到的时候再一一介绍。为直观介绍,使用一个例程来描述,下面是加法器的RTL代码及Testbench:

  vhdl

 

 vhdl 

  注意了clk、rst_n后,其他端口根据需要相应加测试信号即可,然后把RTL代码及Testbench添加到Modelsim仿真观察输出波形等,以验证RTL代码的正确与否,若与预期相符则验证结束,反之则修改代码至与预期相符。

  好了,Testbench就写到这里,但没有结束,实践是检验真理的唯一标准,下一篇将结合Modelsim,以可视化的方式继续探讨Testbench,深入了解仿真的意义。

  testbench经典教程VHDL

  library ieee;

  use ieee.std_logic_1164.all;

  use ieee.std_logic_arith.all;

  --use ieee.std_logic_unsigned.all;

  entity cnt6 is

  port

  (clr,en,clk :in std_logic;

  q :out std_logic_vector(2 downto 0)

  );

  end entity;

  architecture rtl of cnt6 is

  signal tmp :std_logic_vector(2 downto 0);

  begin

  process(clk)

  -- variable q6:integer;

  begin

  if(clk‘event and clk=’1‘) then

  if(clr=’0‘)then

  tmp《=“000”;

  elsif(en=’1‘) then

  if(tmp=“101”)then

  tmp《=“000”;

  else

  tmp《=unsigned(tmp)+’1‘;

  end if;

  end if;

  end if;

  q《=tmp;

  -- qa《=q(0);

  -- qb《=q(1);

  -- qc《=q(2);

  end process;

  end rtl;

  六进制计数器testbench的代码

  library ieee;

  use ieee.std_logic_1164.all;

  entity cnt6_tb is

  end cnt6_tb;

  architecture rtl of cnt6_tb is

  component cnt6

  port(

  clr,en,clk :in std_logic;

  q :out std_logic_vector(2 downto 0)

  );

  end component;

  signal clr :std_logic:=‘0’;

  signal en :std_logic:=‘0’;

  signal clk :std_logic:=‘0’;

  signal q :std_logic_vector(2 downto 0);

  constant clk_period :time :=20 ns;

  begin

  instant:cnt6 port map

  (

  clk=》clk,en=》en,clr=》clr,q=》q

  );

  clk_gen:process

  begin

  wait for clk_period/2;

  clk《=‘1’;

  wait for clk_period/2;

  clk《=‘0’;

  end process;

  clr_gen:process

  begin

  clr《=‘0’;

  wait for 30 ns;

  clr《=‘1’;

  wait;

  end process;

  en_gen:process

  begin

  en《=‘0’;

  wait for 50ns;

  en《=‘1’;

  wait;

  end process;

  end rtl;

  其实testbench也有自己固定的一套格式,总结如下:

  --测试平台文件(testbench)的基本结构

  library ieee;

  use ieee.std_logic_1164.all;

  entity test_bench is --测试平台文件的空实体(不需要端口定义)

  end test_bench;

  architecture tb_behavior of test_bench is

  component entity_under_test --被测试元件的声明

  port(

  list-of-ports-theri-types-and-modes

  );

  end component;

  begin

  instantiation:entity_under_test port map

  (

  port-associations

  );

  process() --产生时钟信号

  ……

  end process;

  process() --产生激励源

  ……

  end process;

  end tb_behavior;

  -------------------------------------------------------------------

  --简单计数程序源码

  library ieee;

  use ieee.std_logic_1164.all;

  use ieee.std_logic_unsigned.all;

  use ieee.std_logic_unsigned.all;

  entity sim_counter is

  port(

  clk :in std_logic;

  reset :in std_logic;

  count :out std_logic_vector(3 downto 0)

  );

  end entity;

  architecture behavioral of sim_counter is

  signal temp :std_logic_vector(3 downto 0);

  begin

  process(clk,reset)

  begin

  if reset=‘1’ then

  temp《=“0000”;

  elsif clk‘event and clk=’1‘ then

  temp《=temp+1;

  end if;

  end process;

  count《=temp;

  end behavioral;

  -------------------------------------------------------------------

  --简单计数程序,测试文件代码(testbench)

  library ieee;

  use ieee.std_logic_1164.all;

  use ieee.std_logic_unsigned.all;

  use ieee.numeric_std.all;

  entity counter_tb_vhd is --测试平台实体

  end counter_tb_vhd;

  architecture behavior of counter_tb_vhd is

  --被测试元件(DUT)的声明

  component sim_counter

  port(

  clk :in std_logic;

  reset :in std_logic;

  count :out std_logic_vector(3 downto 0)

  );

  end component;

  --输入信号

  signal clk:std_logic:=’0‘;

  signal reset :std_logic:=’0‘;

  --输出信号

  signal count :std_logic_vector(3 downto 0);

  constant clk_period :time :=20 ns; --时钟周期的定义

  begin

  dut:sim_counter port map(

  clk=》clk,reset=》reset,counter=》counter

  );

  clk_gen:process

  begin

  clk=’1‘;

  wait for clk_period/2;

  clk=’0‘;

  wait for clk_period/2;

  end process;

  tb:process --激励信号

  begin

  wait for 20 ns;

  reset《=’1‘;

  wait for 20 ns;

  reset《=’0‘;

  wait for 200 ns;

  wait; --will wait forever;

  end process;

  end;

  --激励信号的产生方式

  --1.以一定的离散时间间隔产生激励信号的波形

  --2.基于实体的状态产生激励信号,也就是说基于实体的输出响应产生激励信号

  --两种常用的复位信号

  --1.周期性的激励信号,如时钟

  --2.时序变化的激励型号,如复位

  --eg.产生不对称时钟信号

  w_clk《=’0‘ after period/4 when w_clk=’1‘ else

  ’1‘ after 3*period/4 when w_clk=’0‘ else

  ’0‘;

  --eg.产生堆成时钟信号,process语句

  clk_gen1:process

  constan clk_period := 40 ns;

  begin

  clk=’1‘;

  wait for clk_period/2;

  clk=’0‘;

  wait for clk_period/2;

  end process;

  如果自己不想写这些testbench的这些固定格式,可以在SIE里自动生成testbench文件的模板

  步骤:New Surce -》 VHDL Test Bench, 然后才会生成testbench

  自动生成的testbench模板格式如下:

  -- Copyright (C) 1991-2008 Altera Corporation

  -- Your use of Altera Corporation‘s design tools, logic functions

  -- and other software and tools, and its AMPP partner logic

  -- functions, and any output files from any of the foregoing

  -- (including device programming or simulation files), and any

  -- associated documentation or information are expressly subject

  -- to the terms and conditions of the Altera Program License

  -- Subscription Agreement, Altera MegaCore Function License

  -- Agreement, or other applicable license agreement, including,

  -- without limitation, that your use is for the sole purpose of

  -- programming logic devices manufactured by Altera and sold by

  -- Altera or its authorized distributors. Please refer to the

  -- applicable agreement for further details.

  -- ***************************************************************************

  -- This file contains a Vhdl test bench template that is freely editable to

  -- suit user’s needs .Comments are provided in each section to help the user

  -- fill out necessary details.

  -- ***************************************************************************

  -- Generated on “03/13/2011 20:05:04”

  -- Vhdl Test Bench template for design : cnt6

  --

  -- Simulation tool : ModelSim (VHDL)

  --

  LIBRARY ieee;

  USE ieee.std_logic_1164.all;

  ENTITY cnt6_vhd_tst IS

  END cnt6_vhd_tst;

  ARCHITECTURE cnt6_arch OF cnt6_vhd_tst IS

  -- constants

  -- signals

  SIGNAL clk : STD_LOGIC;

  SIGNAL clr : STD_LOGIC;

  SIGNAL en : STD_LOGIC;

  SIGNAL q : STD_LOGIC_VECTOR(2 DOWNTO 0);

  COMPONENT cnt6

  PORT (

  clk : IN STD_LOGIC;

  clr : IN STD_LOGIC;

  en : IN STD_LOGIC;

  q : OUT STD_LOGIC_VECTOR(2 DOWNTO 0)

  );

  END COMPONENT;

  BEGIN

  i1 : cnt6

  PORT MAP (

  -- list connections between master ports and signals

  clk =》 clk,

  clr =》 clr,

  en =》 en,

  q =》 q

  );

  init : PROCESS

  -- variable declarations

  BEGIN

  -- code that executes only once

  WAIT;

  END PROCESS init;

  always : PROCESS

  -- optional sensitivity list

  -- ( )

  -- variable declarations

  BEGIN

  -- code executes for every event on sensitivity list

  WAIT;

  END PROCESS always;

  END cnt6_arch;

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分