
| VHDL simulation startup usually fills the screen with assert
warnings from std_logic_arith
functions such as:
calls:
is no longer intercepted. Actually, if the argument was "clean" at time zero the std_logic_arith function call would never be intercepted. VHDL simulation startup usually fills the screen with assert warnings such as: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es). CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand,
and it has been converted
These std_logic_arith function warnings typically go away after the TestBench has applied enough stimulus and the unit_under_simulation has "flushed" the stimulus through the design. These warnings are issued every time the function call is encountered,
and for every bit of a bus in
1) Don't turn off the warnings; Intelligently intercept the std_logic_arith function calls. 2) Assert your own warning message just the first time a function call argument is contiguously "is_x". 3) Assert your own warning message about "is_x" on a bus, not every bit of the bus. 4) After the offending function call argument is "clean" (is_x = false) the std_logic_arith function call is no longer intercepted. Actually, if the argument was "clean" at time zero the std_logic_arith function call would never be intercepted. 5) List of std_logic_arith operator functions with annoying messages when arguments contain std_ulogic, std_logic_vector, unsigned, or signed inputs: ieee.std_logic_arith."+" ieee.std_logic_arith."-" ieee.std_logic_arith."*" ieee.std_logic_arith."<" ieee.std_logic_arith."<=" ieee.std_logic_arith.">" ieee.std_logic_arith.">=" ieee.std_logic_arith."=" ieee.std_logic_arith."/=" ieee.std_logic_arith.shl ieee.std_logic_arith.shr ieee.std_logic_arith.conv_integer ieee.std_logic_arith.conv_unsigned ieee.std_logic_arith.conv_signed ieee.std_logic_arith.conv_std_logic_vector ieee.std_logic_arith.ext ieee.std_logic_arith.sxt 6) The intercept code can be put into a component, then instantiated. 7) This technique can and should be tailored to your unique simulation "problems". To implement this "silencer" create a separate process for each signal that's causing the annoying warning messages: a) Determine if the signal has a 'U'|'X'|'W'|'Z'|'-' in any position by using the ieee.std_logic_1164.is_x function. b) When the signal comes "clean" set an ok signal to true, then suspend the process forever. c) Use the ok signal to conditionally call the offending std_logic_arith function.Here's an example of the process: -- synopsys translate_off a_ok_process : process variable first : boolean; begin if a_ok then wait; else if is_x(a) then assert first report "is_x reported in a" severity warning; first := true; else a_ok <= true; end if; end if; wait on a; end process a_ok_process; -- synopsys translate_on Here's the full example with 1 entity and 4 architectures:
-- model supplier: Johan Sandstrom Cell: 310.977.9435 -- home: 909.585.5488 -- mail: johan@sandstrom.org -- project: Home study. -- description: Intercept overloaded operators. -- filename: silencer.vhd -- design_unit(s): silencer(rtl) = entity(architecture) -- synthesizable? Yes. -- yyyy/mm/dd Modifier Description of Change -- ---------- -------- ------------------------------------- -- 1996/11/20 Johan Work In Process. library ieee; use ieee.std_logic_1164.all;
entity silencer is port(w : in std_logic; a : in std_logic_vector(3 downto 0); b : in std_logic_vector(3 downto 0); y : out std_logic_vector(3 downto 0)); end silencer; architecture before_concurrent of silencer is
y <= signed(a) + signed(b);end before_concurrent; architecture after_concurrent of silencer is signal a_ok : boolean; signal b_ok : boolean; begin y <= signed(a) + signed(b) -- synopsys translate_off when a_ok and b_ok else (others => 'X') -- synopsys translate_on ; -- synopsys translate_off a_ok_process : process variable first : boolean; begin if a_ok then wait; else if is_x(a) then assert first report "is_x reported in a" severity warning; first := true; else a_ok <= true; end if; end if; wait on a; end process a_ok_process; -- synopsys translate_on -- synopsys translate_off b_ok_process : process variable first : boolean; begin if b_ok then wait; else if is_x(b) then assert first report "is_x reported in b" severity warning; first := true; else b_ok <= true; end if; end if; wait on b; end process b_ok_process; -- synopsys translate_on end after_concurrent; architecture before_sequential of silencer is type mem_type is array (0 to 15) of std_logic_vector(3 downto 0); begin combinatorial : process(a, b, w) variable memory : mem_type; begin if w = '1' then memory(conv_integer(unsigned(a))) := b; -- write elsif w = '0' then y <= memory(conv_integer(unsigned(a))); -- read end if; end process combinatorial; end before_sequential; architecture after_sequential of silencer is type mem_type is array (0 to 15) of std_logic_vector(3 downto 0); signal a_ok : boolean; begin combinatorial : process(a, b, w, a_ok) variable memory : mem_type; begin -- synopsys translate_off if a_ok then -- synopsys translate_on if w = '1' then memory(conv_integer(unsigned(a))) := b; -- write elsif w = '0' then y <= memory(conv_integer(unsigned(a))); -- read end if; -- synopsys translate_off else y <= (others => 'X'); end if; -- synopsys translate_on end process combinatorial; -- synopsys translate_off a_ok_process : process variable first : boolean; begin if a_ok then wait; else if is_x(a) then assert first report "is_x reported in a" severity warning; first := true; else a_ok <= true; end if; end if; wait on a; end process a_ok_process; -- synopsys translate_on end after_sequential; Here's the TestBench: -- model supplier: Johan Sandstrom Cell: 310.977.9435 -- home: 909.585.5488 -- email: johan@sandstrom.org -- project: Home study -- description: Intercept overloaded operators. -- filename: silencer_tb.vhd -- design_unit(s): silencer_tb(bhv) = entity(architecture) -- synthesizable? No. -- yyyy/mm/dd Modifier Description of Change -- ---------- -------- ------------------------------------- -- 1996/11/20 Johan Work In Process. library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity silencer_tb is end silencer_tb; architecture bhv of silencer_tb is component silencer port(w : in std_logic; a : in std_logic_vector(3 downto 0); b : in std_logic_vector(3 downto 0); y : out std_logic_vector(3 downto 0)); end component; signal clk : std_logic := '1'; signal w : std_logic := '1'; signal a : std_logic_vector(3 downto 0); signal b : std_logic_vector(3 downto 0); signal y : std_logic_vector(3 downto 0); begin i1 : silencer port map(w => w, a => a, b => b, y => y); clk <= not(clk) after 5 ns; process begin stimulus_loop : for i in 0 to 15 loop case i is when 0 => a <= "UUUU"; w <= '0'; when 1 => b <= "000X"; w <= '1'; when 2 => a <= "00Z0"; w <= '0'; when 3 => b <= "00ZZ"; w <= '1'; when 4 => a <= "0X00"; w <= '0'; when 5 => b <= "0101"; w <= '1'; when 6 => a <= "0110"; w <= '0'; when 7 => b <= "0111"; w <= '1'; when 8 => a <= "1000"; w <= '0'; when 9 => b <= "X00X"; w <= '1'; when 10 => a <= "1010"; w <= '0'; when 11 => b <= "1011"; w <= '1'; when 12 => a <= "XX00"; w <= '0'; when 13 => b <= "1101"; w <= '1'; when 14 => a <= "1110"; w <= '0'; when 15 => b <= "1111"; w <= '1'; end case; wait until rising_edge(clk); end loop stimulus_loop; assert false report "Not really a failure, just ending the simulation." severity failure; wait; end process; end bhv; configuration silencer_tb_cfg of silencer_tb is for bhv -- choose one of the following: -- for i1: silencer use entity work.silencer(before_concurrent); end for; -- for i1: silencer use entity work.silencer(after_concurrent); end for; -- for i1: silencer use entity work.silencer(before_sequential); end for; for i1: silencer use entity work.silencer(after_sequential); end for; end for; end silencer_tb_cfg; Here's the before_concurrent simulation transcript and listing: Loading work.silencer(before_concurrent) ** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Failure: Not really a failure,
just ending the simulation.
ns delta w
a b y
Here's the after_concurrent simulation transcript and listing: Loading work.silencer(after_concurrent) ** Warning: is_x reported in b
** Warning: is_x reported in a
** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Warning: There is an 'U'|'X'|'W'|'Z'|'-'
in an arithmetic operand,
** Failure: Not really a failure,
just ending the simulation.
ns delta w a
b y
Here's the before_sequential simulation transcript and listing: Loading work.silencer(before_sequential) ** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Warning: CONV_INTEGER: There is
an 'U'|'X'|'W'|'Z'|'-' in an arithmetic
** Failure: Not really a failure,
just ending the simulation.
ns delta w a
b y
Summary: I've demonstrated an elementary implementation of this interception technique: a) Starting at simulation
time zero.
This intercept technique can also be
applied to user written routines that use textio or
You can make your VHDL simulator much more efficient! |