📄 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: 8051@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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -