📄 tb_mc8051_alu_sim.vhd
字号:
--------------------------------------------------------------------------------- ---- X X XXXXXX XXXXXX XXXXXX XXXXXX X ---- XX XX X X X X X X X XX ---- X X X X X X X X X X X X ---- X X X X X X X X X X X X ---- X X X X XXXXXX X X XXXXXX X ---- X X X X X X X X X ---- X X X X X X X X X ---- X X X X X X X X X X ---- X X XXXXXX XXXXXX XXXXXX XXXXXX X ---- ---- ---- O R E G A N O S Y S T E M S ---- ---- Design & Consulting ---- ----------------------------------------------------------------------------------- ---- Web: http://www.oregano.at/ ---- ---- Contact: mc8051@oregano.at ---- ----------------------------------------------------------------------------------- ---- MC8051 - VHDL 8051 Microcontroller IP Core ---- Copyright (C) 2001 OREGANO SYSTEMS ---- ---- This library is free software; you can redistribute it and/or ---- modify it under the terms of the GNU Lesser General Public ---- License as published by the Free Software Foundation; either ---- version 2.1 of the License, or (at your option) any later version. ---- ---- This library is distributed in the hope that it will be useful, ---- but WITHOUT ANY WARRANTY; without even the implied warranty of ---- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ---- Lesser General Public License for more details. ---- ---- Full details of the license can be found in the file LGPL.TXT. ---- ---- You should have received a copy of the GNU Lesser General Public ---- License along with this library; if not, write to the Free Software ---- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---- --------------------------------------------------------------------------------------- Author: Roland H鰈ler---- Filename: tb_mc8051_alu_sim.vhd---- Date of Creation: Mon Aug 9 12:14:48 1999---- Version: $Revision: 1.4 $---- Date of Latest Version: $Date: 2002/01/07 12:16:57 $------ Description: Module level testbench for the mc8051 alu.---------------------------------------------------------------------------------------architecture sim of tb_mc8051_alu is ----------------------------------------------------------------------------- -- -- -- 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) -- ----------------------------------------------------------------------------- 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; ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- -- -- PROC_DA - Test the combinational decimal adjustement command -- -- -- -- Procedure to generate all the input data to test the combinational -- -- divider command. Furthermore the results are compared with the -- -- expected values and the simulation is stopped with an error message -- -- if the test failes. -- ----------------------------------------------------------------------------- procedure PROC_DA ( constant DWIDTH : in integer; constant PROP_DELAY : in time; signal s_datao : out std_logic_vector; signal s_cy : out std_logic_vector; signal s_datai : in std_logic_vector; signal s_cyi : in std_logic_vector; signal s_da_end : out boolean) is type t_nibbles is array (0 to ((DWIDTH-1)/4)) of integer; variable v_flags : std_logic_vector((DWIDTH-1)/4 downto 0); variable v_flags_int : std_logic_vector((DWIDTH-1)/4 downto 0); variable v_newdata : std_logic_vector(DWIDTH-1 downto 0); variable v_tmp : integer; variable v_cy : std_logic; variable v_ext : boolean; begin s_da_end <= false; s_datao <= conv_std_logic_vector(0,DWIDTH); s_cy <= conv_std_logic_vector(0,((DWIDTH-1)/4)+1); v_ext := false; for j in 0 to 2**DWIDTH-1 loop s_datao <= conv_std_logic_vector(j,DWIDTH); for i in 0 to 2**(((DWIDTH-1)/4)+1)-1 loop -- MSB of v_flags is cy. The rest represents the auxiliary carry flags. v_flags := conv_std_logic_vector(i,((DWIDTH-1)/4)+1); v_cy := v_flags(v_flags'HIGH); s_cy <= conv_std_logic_vector(i,((DWIDTH-1)/4)+1); v_tmp := j; v_ext := false; -- Whenever a flag is set the corresponding data cannot be greater than -- 2 (The data is assumed to be the result of an addition of two BCD -- numbers). - Just to reduce simulation runtime. for r in 0 to (DWIDTH-1)/4 loop if j mod 2**((r+1)*4) > 2 and v_flags(r) = '1' then v_ext := true; end if; end loop; -- r next when v_ext = true; for h in 0 to (DWIDTH-1)/4 loop -- Perform adjustement of the following nibbles if v_tmp mod 2**((h+1)*4) > 9*(2**(h*4))+2**(h*4)-1 or v_flags(h) = '1' then v_flags_int := conv_std_logic_vector(0,((DWIDTH-1)/4)+1); for k in h to ((DWIDTH-1)/4) loop if k=h then -- Determine carry flag of the nibble which will be -- incremented by 6. if DWIDTH >= (k+1)*4 then if v_tmp mod 2**((k+1)*4) > 9*(2**(k*4))+2**(k*4)-1 then -- The correction of the nibble needs a carry v_flags_int(k) := '1'; end if; elsif DWIDTH = (k+1)*4-1 or DWIDTH = (k+1)*4-2 then if v_tmp mod 2**((k+1)*4) > 1*(2**(k*4))+2**(k*4)-1 then -- The correction of the nibble needs a carry v_flags_int(k) := '1'; end if; end if; else -- Determine carry flag of the nibbles subsequent to the one -- which will be incremented by 6. if DWIDTH >= (k+1)*4 then if v_tmp mod 2**((k+1)*4) >= 15*(2**(k*4)) and v_flags_int(k-1) = '1' then -- The correction of the nibble needs a carry v_flags_int(k) := '1'; end if; else if v_tmp mod 2**DWIDTH >= (2**(DWIDTH-k*4)-1)*2**(k*4) and v_flags_int(k-1) = '1' then -- The correction of the nibble needs a carry v_flags_int(k) := '1'; end if; end if; end if; end loop; -- k for k in h to ((DWIDTH-1)/4) loop -- Perform correction for the lowest nibble in scope if DWIDTH >= (k+1)*4-1 then if k=h then v_tmp := v_tmp + 6*(2**(h*4)); end if; elsif DWIDTH = (k+1)*4-2 then if k=h then v_tmp := v_tmp + 2*(2**(h*4)); end if; end if; end loop; -- k v_flags := v_flags_int or v_flags; end if; end loop; -- h -- Set expected values. v_newdata := conv_std_logic_vector(v_tmp, DWIDTH); if v_tmp > 2**DWIDTH-1 then v_cy := '1'; end if; -- After waiting for the result, perform checks. wait for PROP_DELAY; assert (s_datai = v_newdata) and (s_cyi((DWIDTH-1)/4) = v_cy) report "ERROR in decimal adjustement of the " & IMAGE(DWIDTH) & " bit data!" & " v_tmp= " & IMAGE(v_tmp) & " j= " & IMAGE(j) & " i= " & IMAGE(i) severity failure; end loop; -- i end loop; -- j assert false report "********* " & IMAGE(DWIDTH) & "BIT DECIMAL ADJUST FUNCTION FINISHED AT " & IMAGE(now) & " !" & " *********" severity note; s_da_end <= true; wait; end PROC_DA; ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- -- -- PROC_DIV_ACC_RAM - Test the combinational divider -- -- -- -- Procedure to generate all the input data to test the combinational -- -- divider command. Furthermore the results are compared with the -- -- expected values and the simulation is stopped with an error message -- -- if the test failes. -- ----------------------------------------------------------------------------- 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); for i in 0 to 2**DWIDTH-1 loop s_dvsor <= conv_std_logic_vector(i,DWIDTH); for f in 0 to 2**(((DWIDTH-1)/4)+2)-1 loop v_flags := conv_std_logic_vector(f,((DWIDTH-1)/4)+2); s_cyo <= v_flags(((DWIDTH-1)/4) downto 0); s_ovo <= v_flags(v_flags'HIGH); wait for PROP_DELAY; if i /= 0 then v_quot := j/i; v_remd := j rem i; 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; else 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 report "********* " & IMAGE(DWIDTH) & "BIT DIVIDER SEQUENCE FINISHED AT " & IMAGE(now) & " !" & " *********" severity note; s_dvdr_end <= true; wait; end PROC_DIV_ACC_RAM; ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- -- -- PROC_MUL_ACC_RAM - Test the combinational multiplier -- -- -- -- Procedure to generate all the input data to test the combinational -- -- multiply command. Furthermore the results are compared with the -- -- expected values and the simulation is stopped with an error message -- -- if the test failes. -- ----------------------------------------------------------------------------- procedure PROC_MUL_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_product : in std_logic_vector; signal s_cyo : out std_logic_vector; signal s_ovo : out std_logic; signal s_mltplcnd : out std_logic_vector; signal s_mltplctr : out std_logic_vector; signal s_mul_end : out boolean) is variable v_product : integer; variable v_flags : std_logic_vector((DWIDTH-1)/4+1 downto 0); begin s_mul_end <= false; for j in 0 to 2**DWIDTH-1 loop s_mltplcnd <= conv_std_logic_vector(j,DWIDTH); for i in 0 to 2**DWIDTH-1 loop s_mltplctr <= conv_std_logic_vector(i,DWIDTH); for f in 0 to 2**(((DWIDTH-1)/4)+2)-1 loop
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -