1. gzyueqian
      13352868059
      首頁 > 新聞中心 > > 正文

      怎樣寫testbench

      更新時(shí)間: 2008-09-02 14:44:26來源: 粵嵌教育瀏覽量:1406

      本文的實(shí)際編程環(huán)境:ISE 6.2i.03
      ModelSim 5.8 SE
      Synplify Pro 7.6
      編程語言 VHDL
      在ISE 中調(diào)用ModelSim 進(jìn)行仿真

      一、 基本概念和基礎(chǔ)知識(shí)
        Testbench 不僅要產(chǎn)生激勵(lì)也就是輸入,還要驗(yàn)證響應(yīng)也就是輸出。當(dāng)然也可以只產(chǎn)生激勵(lì),然后通過波形窗口通過人工的方法去驗(yàn)證波形,這種方法只能適用于小規(guī)模的設(shè)計(jì)。
      在ISE 環(huán)境中,當(dāng)前資源操作窗顯示了資源管理窗口中選中的資源文件能進(jìn)行的相關(guān)操作。在資源管理窗口選中了testbench 文件后,在當(dāng)前資源操作窗顯示的ModelSim Simulator 中顯示了4 種能進(jìn)行的模擬操作,分別是:Simulator Behavioral Model(功能仿真)、Simulator Post-translate VHDL Model(翻譯后仿真)、Simulator Post-Map VHDL Model(映射后仿真)、Simulator Post-Place & Route VHDL Model(布局布線后仿真)。如圖1 所示:

        圖1
                    
        Simulator Behavioral Model 也就是所說的功能仿真、行為仿真、前仿真。驗(yàn)證功能是否正確,這是設(shè)計(jì)的步。功能仿真正確的程序不一定能被正確綜合,也就是硬件實(shí)現(xiàn)。有的在綜合時(shí)報(bào)錯(cuò)誤,有的雖然能綜合但結(jié)果并不正確。當(dāng)然,功能仿真如果都不能通過,以后的步驟也就無法進(jìn)行。這是必做的仿真。
        Simulator Post-translate VHDL Model 也就是翻譯后仿真。對(duì)源程序進(jìn)行編譯后首先排除了語法錯(cuò)誤,對(duì)一些像類屬命令(Generic)、生成語句(Generate)等進(jìn)行了展開。不是必做的仿真。
        Simulator Post-Map VHDL Model也就是映射后仿真。不同的器件內(nèi)部結(jié)構(gòu)也不盡相同,映射的作用就是將綜合后產(chǎn)生的網(wǎng)表文件對(duì)應(yīng)到實(shí)際的器件上去。由于映射不包含布線,也就是要用什么類型的邏輯單元雖然已經(jīng)確定但要用哪個(gè)位置的還沒有確定,因此,映射后仿真不包含布線延時(shí)。不是必做的仿真。
        Simulator Post-Place & Route VHDL Model 也就是所說的布局布線后仿真、時(shí)序仿真、后仿真。這是完整的仿真,既包含邏輯延時(shí)又包含布線延時(shí)。在做布局布線后仿真時(shí)要用到一個(gè)叫SDF的文件。SDF文件包含設(shè)計(jì)中每個(gè)單元(Cell)的延時(shí)和時(shí)序約束數(shù)據(jù)。通過加載這個(gè)文件就能得到完整的時(shí)序情況。它是必做的仿真。
      一般必須進(jìn)行功能仿真和布局布線后仿真。

      常見問題:
        為什么有的testbench在進(jìn)行功能仿真時(shí)能正確進(jìn)行,而在進(jìn)行布局布線后仿真時(shí)就不能運(yùn)行。
      有兩點(diǎn)要注意的地方:
       ?。?)、在做映射后仿真或布局布線后仿真時(shí),都已經(jīng)經(jīng)過了綜合工具的綜合,源程序中的類屬命令(Generic)、生成語句(Generate)等都已經(jīng)進(jìn)行展開。例如,如果用Generic 定義了一個(gè)參數(shù)width,綜合工具進(jìn)行綜合時(shí)已經(jīng)按照一個(gè)確定的width 值進(jìn)行了綜合。它生成的電路已經(jīng)具有一個(gè)確定的結(jié)構(gòu),不能再隨意調(diào)整。所以在映射后仿真和布局布線后仿真的testbench中,往往不能出現(xiàn)Generic 語句。
        (2)映射后仿真和布局布線后仿真都要用到SDF 文件,并且要將SDF文件關(guān)聯(lián)到設(shè)計(jì)中的實(shí)例。所以在映射后仿真和布局布線后仿真的testbench中,,要將你的設(shè)計(jì)聲明成一個(gè)元件。第二,實(shí)例化你設(shè)計(jì)的元件并且實(shí)例名要取為UUT(默認(rèn)的,當(dāng)然也可以改)。

      關(guān)于斷言語句
      在仿真中為了能得到更多信息,經(jīng)常要用到斷言語句(assert)。其語法如下:
      Assert<條件>
      Report<消息>
      Severity<出錯(cuò)級(jí)別>;
      出錯(cuò)級(jí)別共有5 種:

      Note
      Warning
      Error
      Failure
      Fatal
        在VHDL 模型的模擬過程中,一旦斷言語句的條件為假,則發(fā)送消息并將出錯(cuò)級(jí)別發(fā)送給模擬器。通常可以設(shè)置一個(gè)中止模擬器運(yùn)行的出錯(cuò)級(jí)別,一般默認(rèn)的中止運(yùn)行的出錯(cuò)級(jí)別為Failure。
      我們來看一個(gè)例子:
      assert false
      report "********* " & IMAGE(DWIDTH) & "BIT DIVIDER SEQUENCE FINISHED
      AT " & IMAGE(now) & " !" & " *********"
      severity note;
      斷言的條件不是一個(gè)條件表達(dá)式,而直接是false。這說明只要程序執(zhí)行到這里斷言就一定會(huì)成立,送出消息。出錯(cuò)級(jí)別為note,在模擬器的輸出窗口將會(huì)顯示:

      圖2
      再看一個(gè)例子:
      assert (s_cyi((DWIDTH-1)/4) = '0')
      and (s_ovi = '0')
      and (s_qutnt = conv_std_logic_vector(v_quot,DWIDTH))
      and (s_rmndr = conv_std_logic_vector(v_remd,DWIDTH))
      report "ERROR in division!"
      severity failure;
        斷言的條件有4 個(gè)并且是與的關(guān)系,只要其中一個(gè)條件不成立則整個(gè)表達(dá)式為假,斷言成立。如果斷言成立將輸出“ERROR in division!“這個(gè)消息。并且通知模擬器出錯(cuò)級(jí)別為failure,這一般會(huì)停止模擬。這個(gè)斷言實(shí)際是在對(duì)結(jié)果進(jìn)行驗(yàn)證。

      二、實(shí)際testbench分析
        下面將詳細(xì)分析一個(gè)實(shí)際的testbench,它是用來測(cè)試8051 的ALU單元的除法功能的。8 位的除法器,被除數(shù)和除數(shù)的組合共有256×256=65536 種。我們采用的方法是窮舉所有的輸入組合,這樣的代碼覆蓋率可以達(dá)到100%。它的驗(yàn)證必須通過程序自動(dòng)完成,否則通過人工方法工作量太大。
        把要測(cè)試的程序當(dāng)作一個(gè)元件,例如想象成一個(gè)74 系列數(shù)字電路。Testbench 的作用是在被測(cè)試電路的輸入端加上激勵(lì),然后比較被測(cè)試電路的輸出和計(jì)算出來的期望值是否一致。對(duì)我們這個(gè)例子來說,在要仿真的ALU 輸入端產(chǎn)生65536 種輸入組合,然后將ALU產(chǎn)生的對(duì)應(yīng)輸出值和testbench 算出的期望值相比較,如果有錯(cuò)誤產(chǎn)生則停止模擬并輸出信息。ALU 的除法單元的輸入有4 個(gè),分別是被除數(shù)、除數(shù)、進(jìn)位、溢出位;輸出也有4 個(gè),分別是商、余數(shù)、新的進(jìn)位、新的溢出位。
        1、 testbench 的輸出s_dvdnd(被除數(shù))、s_dvsor(除數(shù))、s_cyo(進(jìn)位)、s_ovo(溢出位)連接到ALU 的輸入acc_i(被除數(shù))、ram_data_i(除數(shù))、cy_i(進(jìn)位)、ov_i(溢出位);
        2、 testbench 的輸入s_qutnt(商)、s_rmndr(余數(shù))、s_cyi(進(jìn)位)、s_ovi(溢出位)連接到ALU的輸出result_a_o(商)、 result_b_o(余數(shù))、new_cy_o(進(jìn)位)、new_ov_o(溢出位)。
        3、 總之,testbench 驅(qū)動(dòng)被測(cè)試單元,同時(shí)對(duì)被測(cè)試單元的輸出進(jìn)行驗(yàn)證。
        4、assert (s_cyi((DWIDTH-1)/4) = '0')
      and (s_ovi = '0')
      and (s_qutnt = conv_std_logic_vector(v_quot,DWIDTH))
      and (s_rmndr = conv_std_logic_vector(v_remd,DWIDTH))
      report "ERROR in division!"
      severity failure;
      根據(jù)51 指令系統(tǒng)規(guī)定,除法運(yùn)算的cy 位固定為0,如果除數(shù)為0則ov 置1,否則置0。
      程序中
      s_qutnt = conv_std_logic_vector(v_quot,DWIDTH)
      s_rmndr = conv_std_logic_vector(v_remd,DWIDTH)
      用來對(duì)運(yùn)算結(jié)果進(jìn)行比較。conv_std_logic_vector()是類型轉(zhuǎn)換函數(shù)。

      ――首先是對(duì)庫(kù)的引用
      library IEEE;
      use IEEE.std_logic_1164.all;
      use IEEE.std_logic_arith.all;
      library work;
      use work.mc8051_p.all;
      library STD;
      use STD.textio.all;
      ――定義結(jié)構(gòu)體,testbench程序的結(jié)構(gòu)體是空的。因?yàn)閠estbench是用來仿真的,不存在
      --對(duì)外的接口,所以entity是空的。但是必須要有,這是語法的要求。
      entity TBX_mc8051_alu is
      end TBX_mc8051_alu;
      -------------------------------------------------------------------------------
      architecture TBX_ARCH_DIV of TBX_mc8051_alu is
      ――定義元件,映射后仿真和布局布線后仿真要使用SDF 文件,必須指定實(shí)例名。要實(shí)例
      --化元件首先必須定義元件。
      component mc8051_alu
      port (
      new_ov_o : out STD_LOGIC; ――新的ov位,輸出
      ov_i : in STD_LOGIC := 'X'; ――ov位,輸入
      new_cy_o : out STD_LOGIC_VECTOR ( 1 downto 0 ); ――新的cy位,輸出
      acc_i : in STD_LOGIC_VECTOR ( 7 downto 0 ); ――acc,輸入
      rom_data_i : in STD_LOGIC_VECTOR ( 7 downto 0 ); ――rom_data,輸入
      cmd_i : in STD_LOGIC_VECTOR ( 5 downto 0 ); ――命令,輸入
      ram_data_i : in STD_LOGIC_VECTOR ( 7 downto 0 ); ――ram_data,輸入
      cy_i : in STD_LOGIC_VECTOR ( 1 downto 0 ); ――cy,輸入
      result_b_o : out STD_LOGIC_VECTOR ( 7 downto 0 ); ――結(jié)果b,輸出
      result_a_o : out STD_LOGIC_VECTOR ( 7 downto 0 ) -―結(jié)果a,輸出
      );
      end component;
      ――定義函數(shù)
      -----------------------------------------------------------------------------
      --
      -- IMAGE - Convert a special data type to string --
      --
      This function uses the STD.TEXTIO.WRITE procedure to convert different --
      -- VHDL data types to a string to be able to output the information via --
      -- a report statement to the simulator. --
      -- (VHDL'93 provides a dedicated predefinded attribute 'IMAGE) --
      -----------------------------------------------------------------------------
      ――定義了一個(gè)函數(shù)IMAGE,之所以有兩個(gè)定義,是因?yàn)閷?duì)IMAGE進(jìn)行了重載,一個(gè)是把
      ――time變量轉(zhuǎn)換成string,另一個(gè)是把integer變量轉(zhuǎn)換成string
      function IMAGE (constant tme : time) return string is
      variable v_line : line;
      variable v_tme : string(1 to 20) := (others => ' ');
      begin
      write(v_line, tme);
      v_tme(v_line.all'range) := v_line.all;
      deallocate(v_line);
      return v_tme;
      end IMAGE;
      function IMAGE (constant nmbr : integer) return string is
      variable v_line : line;
      variable v_nmbr : string(1 to 11) := (others => ' ');
      begin
      write(v_line, nmbr);
      v_nmbr(v_line.all'range) := v_line.all;
      deallocate(v_line);
      return v_nmbr;
      end IMAGE;
      ――定義過程,它產(chǎn)生所有的測(cè)試輸入數(shù)據(jù)并將產(chǎn)生結(jié)果和期望值進(jìn)行比較,如果有誤
      ――產(chǎn)生,模擬將停止并輸出一個(gè)錯(cuò)誤信息。注意到testbench要產(chǎn)生被測(cè)試單元的輸入
      ――信號(hào),因此testbench的輸出接到被測(cè)試單元的輸入,被測(cè)試單元的輸出接到
      ――testbench的輸入。
      procedure PROC_DIV_ACC_RAM (
      constant DWIDTH : in positive;
      constant PROP_DELAY : in time;
      signal s_cyi : in std_logic_vector;
      signal s_ovi : in std_logic;
      signal s_qutnt : in std_logic_vector;
      signal s_rmndr : in std_logic_vector;
      signal s_cyo : out std_logic_vector;
      signal s_ovo : out std_logic;
      signal s_dvdnd : out std_logic_vector;
      signal s_dvsor : out std_logic_vector;
      signal s_dvdr_end : out boolean) is
      variable v_quot : integer;
      variable v_remd : integer;
      variable v_flags : std_logic_vector((DWIDTH-1)/4+1 downto 0);
      begin
      s_dvdr_end <= false;
      for j in 0 to 2**DWIDTH-1 loop
      s_dvdnd <= conv_std_logic_vector(j,DWIDTH); ――產(chǎn)生被除數(shù)
      for i in 0 to 2**DWIDTH-1 loop
      s_dvsor <= conv_std_logic_vector(i,DWIDTH); ――產(chǎn)生除數(shù)
      for f in 0 to 2**(((DWIDTH-1)/4)+2)-1 loop ――產(chǎn)生cy和ov
      v_flags := conv_std_logic_vector(f,((DWIDTH-1)/4)+2);
      s_cyo <= v_flags(((DWIDTH-1)/4) downto 0); ――s_cyo和s_ovo輸出到
      s_ovo <= v_flags(v_flags'HIGH); ――mc8051_alu的cy_i和ov_i
      wait for PROP_DELAY; ――等待100ns
      if i /= 0 then
      v_quot := j/i; ――產(chǎn)生期待的商
      v_remd := j rem i; ――產(chǎn)生期待的余數(shù)
      assert (s_cyi((DWIDTH-1)/4) = '0') ――對(duì)結(jié)果進(jìn)行比較
      and (s_ovi = '0')
      and (s_qutnt = conv_std_logic_vector(v_quot,DWIDTH))
      and (s_rmndr = conv_std_logic_vector(v_remd,DWIDTH))
      report "ERROR in division!"
      severity failure;
      else ―― 否則除數(shù)為0
      assert (s_cyi((DWIDTH-1)/4) = '0')
      and (s_ovi = '1')
      report "ERROR in division by zero - flags not correct!"
      severity failure;
      end if;
      end loop; -- f
      end loop; -- i
      end loop; -- j
      assert false ―― 程序執(zhí)行到這里表示沒有問題產(chǎn)生
      report "********* " & IMAGE(DWIDTH) & "BIT DIVIDER SEQUENCE FINISHED AT "
      & IMAGE(now) & " !" & " *********"
      severity note;
      s_dvdr_end <= true;
      wait;
      end PROC_DIV_ACC_RAM;
      -----------------------------------------------------------------------------
      ――定義常數(shù)和信號(hào)
      constant PROP_DELAY : time := 100 ns;
      signal rom_data_DIV_ACC_RAM : std_logic_vector(7 downto 0);
      signal ram_data_DIV_ACC_RAM : std_logic_vector(7 downto 0);
      signal acc_DIV_ACC_RAM : std_logic_vector(7 downto 0);
      signal hlp_DIV_ACC_RAM : std_logic_vector(7 downto 0);
      signal cmd_DIV_ACC_RAM : std_logic_vector(5 downto 0);
      signal cy_DIV_ACC_RAM : std_logic_vector(1 downto 0);
      signal ov_DIV_ACC_RAM : std_logic;
      signal new_cy_DIV_ACC_RAM : std_logic_vector(1 downto 0);
      signal new_ov_DIV_ACC_RAM : std_logic;
      signal result_a_DIV_ACC_RAM : std_logic_vector(7 downto 0);
      signal result_b_DIV_ACC_RAM : std_logic_vector(7 downto 0);
      signal end_DIV_ACC_RAM : boolean;
      -----------------------------------------------------------------------------
      begin
      -----------------------------------------------------------------------------
      -- Test the DIV_ACC_RAM command --
      -----------------------------------------------------------------------------
      rom_data_DIV_ACC_RAM <= conv_std_logic_vector(0,8);
      cmd_DIV_ACC_RAM <= conv_std_logic_vector(43,6); ――43表示除法命令
      UUT : mc8051_alu ――例化元件
      port map (
      rom_data_i => rom_data_DIV_ACC_RAM(7 downto 0),
      ram_data_i => ram_data_DIV_ACC_RAM(7 downto 0),
      acc_i => acc_DIV_ACC_RAM(7 downto 0),
      cmd_i => cmd_DIV_ACC_RAM,
      cy_i => cy_DIV_ACC_RAM(1 downto 0),
      ov_i => ov_DIV_ACC_RAM,
      new_cy_o => new_cy_DIV_ACC_RAM(1 downto 0),
      new_ov_o => new_ov_DIV_ACC_RAM,
      result_a_o => result_a_DIV_ACC_RAM(7 downto 0),
      result_b_o => result_b_DIV_ACC_RAM(7 downto 0));
      ――mc8051_alu的被除數(shù)、除數(shù)、cyi、ovi由PROC_DIV_ACC_RAM產(chǎn)生
      ――注意到PROC_DIV_ACC_RAM的商(s_qutnt)、余數(shù)(s_rmndr)的Port方向是in,
      ――用來連接mc8051_alu的輸出result_a_DIV_ACC_RAM和result_b_DIV_ACC_RAM
      PROC_DIV_ACC_RAM (DWIDTH => 8, ――調(diào)用過程
      PROP_DELAY => PROP_DELAY,
      s_cyi => new_cy_DIV_ACC_RAM(1 downto 0),
      s_ovi => new_ov_DIV_ACC_RAM,
      s_qutnt => result_a_DIV_ACC_RAM(7 downto 0), ――商
      s_rmndr => result_b_DIV_ACC_RAM(7 downto 0), ――余數(shù)
      s_cyo => cy_DIV_ACC_RAM(1 downto 0),
      s_ovo => ov_DIV_ACC_RAM,
      s_dvdnd => acc_DIV_ACC_RAM(7 downto 0), ――被除數(shù)
      s_dvsor => ram_data_DIV_ACC_RAM(7 downto 0), ――除數(shù)
      s_dvdr_end => end_DIV_ACC_RAM);
      -----------------------------------------------------------------------------
      end TBX_ARCH_DIV;
      ――配置,表示TBX_mc8051_alu這個(gè)entity使用TBX_ARCH_DIV這個(gè)architecture
      configuration TBX_CFG_mc8051_alu_TBX_ARCH_DIV of TBX_mc8051_alu is
      for TBX_ARCH_DIV
      end for;
      end TBX_CFG_mc8051_alu_TBX_ARCH_DIV;

      免費(fèi)預(yù)約試聽課

      亚洲另类欧美综合久久图片区_亚洲中文字幕日产无码2020_欧美日本一区二区三区桃色视频_亚洲AⅤ天堂一区二区三区

      
      

      1. 亚洲精品ⅴa在线播放 | 天天爽天天狠久久综合 | 午夜三级中文在线 | 伊人久久大香线蕉AV五月天宝贝 | 日韩中文字幕有码在线 | 亚洲国产综合有精品 |