<?xml version="1.0"  encoding="ISO-8859-2"?> 
<!DOCTYPE zprava SYSTEM "techrep.dtd" >
<zprava cislo="17/2003" jazyk="en">  
<nazev>Verification of COMBO6 VHDL Design
    <footnote>This work is supported by the FP5 project No. IST-2001-32603, the CESNET project 02/2003, and the GACR grant No. 201/03/0509.</footnote>
</nazev> 
<autor>Tomáš~Kratochvíla, Vojtěch~Řehák, and Pavel~Šimeček</autor> 
<datum>November 19, 2003</datum> 

<h1>Abstract</h1>
<p>
This technical report presents current results and experiences of the formal
verification of <i>VHDL</i> design of <i>Combo6</i>
hardware accelerator card for packet routing, originating from the
<i>Liberouter</i> project.  The design is quite difficult to prove by
conventional methods, therefore model checking as a method of formal
verification was employed.  We use the symbolic model checker
<b>Cadence SMV</b>.  Information about formal verification
itself is enriched by description of transformation from
<i>VHDL</i> to the <b>Cadence SMV</b>
specification language.  The last part shows the system of assertions
established as a compact way of communication with <i>VHDL</i>
designers.
</p>

<h1>Introduction</h1>

<p>The aim of the Liberouter project~<cite href="LibWWW"></cite> is to design and develop the hardware
accelerated router. The most important part of this project is a development
of the <i>Combo6</i> hardware accelerator card~<cite
href="Nov02"></cite> allowing to route the most of traffic of a
<i>Gigabit Ethernet</i> in the hardware.
</p>
<p>
<i>Combo6</i> is a PCI card based on FPGA (Field Programmable Gate
Array)~<cite href="FPGA"></cite>. The programmable hardware technology
represents a new generation of hardware development. FPGA is the class of
integrated circuits pioneered by <i>Xilinx</i>, in which
the logic function is defined by the developer using
<i>Xilinx</i> development system software. Gate arrays
are another type of integrated circuits whose logic is defined during the
manufacturing process.
</p>
<p>
Developers write the design of <i>Combo6</i> card in the
<i>VHDL</i> (<i>VHSIC</i> Hardware Description
Language)~<cite href="VHDL"></cite>.  <i>VHDL</i> can be used
at many levels of abstraction ranging from algorithmic level to the gate
level.  On the one hand the wide expressive power is positive for
developers, but on the other hand it brings great demands on tools
supporting <i>VHDL</i>. Hence there are many tools supporting different subsets of
<i>VHDL</i> and finally, the wide expressibility leads to the incompatibility of tools
working with <i>VHDL</i>.
</p>
<p>
The following section briefly justifies the choice of the model checker
and describes how to solve problems with incompatibilities between supported
languages.  The next section is focused on verification itself using the
<b>Cadence SMV</b> symbolic model checker and there we also
mention the system of assertions as a communication interface solving
troubles of collaboration with the hardware designing team.
</p>

<h1>Translation from VHDL to SMV</h1>

<p>
<i>VHDL</i> is used by developers of <i>Combo6</i>
card to write down the design loaded to FPGA. Therefore it is also the input
for the formal verification (the model checking technique in our case)~<cite href="Bar02"></cite>. The
most suitable model checking tools for hardware verification are the
symbolic ones (for more details see <a href="#MC">Subsection</a>).
</p>
<p>
Unfortunately, as <i>VHDL</i> is not an input language of any
model checking tool available to us at this moment, we have to translate
<i>VHDL</i>. Currently we do not know about any translator from
<i>VHDL</i> to any model checker specification language that
would be able to translate sufficiently large subset of
<i>VHDL</i>. Fortunately, <b>Cadence
SMV</b> model checker installation package~<cite href="SMV"></cite>
includes the translator from <i>Verilog</i> to
<i>SMV</i> (the input language of this model checker).  The
<i>Verilog HDL</i>~<cite href="Ver"></cite> is a hardware description language of the
same power as <i>VHDL</i>.  Hence we could form a translator from
<i>VHDL</i> to <i>SMV</i> as a composition of
the <b>Cadence SMV</b> translator (called
<b>vl2smv</b>) with a translator from
<i>VHDL</i> to <i>Verilog</i>.
</p>

<p>
Unfortunately, we have found neither the proper translator from
<i>VHDL</i> to <i>Verilog</i>. We have tried
<b>VHDL to Verilog RTL translator v1.0</b> (made by
<i>Ocean Logic</i>) and
<b>VHDL2verilog</b> (demo version made by
<i>Alternative System Concepts</i>) but neither one of
them satisfies our needs. One of them do not support sufficiently large
subset of <i>VHDL</i> and the output of the other one was not a
proper input for <b>vl2smv</b>.
</p>

<h2>Translation using a synthesis</h2>

<p>
We found another solution how to translate to <i>Verilog</i>
format.  The <b>LeonardoSpectrum</b> synthesiser~<cite
href="LeoSpec"></cite> (currently used by <i>Combo6</i> hardware
developers) provides ability to write a synthesised code down into
<i>Verilog</i>. For that reason we decided to verify
synthesised code instead of the original one. They should be functionally
equivalent, and hence the verification of such a code is correct (in a sense
of preserving validity of temporal formulas).  Synthesised
<i>Verilog</i> code is a correct input for
<b>vl2smv</b> except for a few syntax entities. We run
synthesis directed by the following TCL script:
</p>

<pre>
set part 2V3000bf957
set process 4
set modgen_select fastest
load_library xcv2
read -design $DESIGN -technology &quot;xcv2&quot; -format vhdl { $MODULES }
set extract_ram FALSE
set tristate_map TRUE
optimize -ta xcv2 -hierarchy preserve
write -downto PRIMITIVES -format Verilog $NAME.v
</pre>

<p>
Where <tt>$DESIGN</tt> contains the name of the top-level design,
<tt>$MODULES</tt> stands for the list of all modules of the design, and
<tt>$NAME</tt> is the name of the output file (without an extension).
</p>

<p>
This TCL script is partially adopted from the synthesis scripts currently
used by our hardware designers. The changes were done in an optimisation
parameters and some special options we use.
</p>

<h3>line <tt>optimize -ta xcv2 -hierarchy preserve</tt></h3>
<p>
   Citation from <b>LeonardoSpectrum</b> User Guide~<cite
   href="LSguide"></cite>:</p>
   
<blockquote>
    <p>
     When <b>LeonardoSpectrum</b> reads an HDL design,
     it infers arithmetic and relational operators (e.g.~adders)
     and implements the operators as blackboxes (there is no
     underlying functionality) in the design. <b>LeonardoSpectrum
     </b> does not implement operators until global area
     optimization when it replaces these blackboxes with technology-specific
     netlists (from the <i>Modgen Library</i>).
    </p>
    <p>&ldots;</p>
    <p>
     Each blackbox operator uses a naming convention to convey parameter
     information such as (type, size, sign, carry), for example:<br/>
       <tt>add_16u_16u_0</tt> (16 bit adder, unsigned operands, no
       carryout)
    </p>
</blockquote>     
  

<p>If there is no optimisation used, the synthesiser infers many black boxes
(entities with no description except for their interface) similar to
<tt>add_16u_16u_0</tt> and verification is absolutely impossible since
the functionality of the most of the hardware design is undefined.
</p>

<p>
We have also tried to change an effort of optimisation to value
<tt>remap</tt> to preserve more from the original structure of <i>VHDL</i> code,
but this level of optimisation generates black boxes similarly as a
synthesis with no optimisation.
</p>

<p>
The hierarchy preserve option (<tt>-hierarchy preserve</tt>) is necessary for
us, because we need to preserve the interface of single parts of a design.
When this option is omitted, the synthesiser usually renames the most of signals
of used components and changes their behaviour; in that way it gives no
sense to ask to check their behaviour in temporal formulas.
</p>

<h3>line <tt>set extract_ram FALSE</tt></h3>
<p>
Synthesiser has a capability to recognise (technology specific) blocks of
RAM in a <i>VHDL</i> code - typically the RAM is inferred from large arrays and
vectors.  This option disables automatic extraction of RAM from arrays,
which are not accessed and used as RAMs. Disabling RAM extraction causes
inferring (usually flip-flop) registers instead of RAM blocks.
Unfortunately, for the arrays which are inevitably used as RAMs (indexation
using a variable) it is inferred a special black box named
<tt>CLOCKED_RAM_*</tt> (we write <tt>*</tt> instead of the suffix of the
name, which differs according to parameters of inferred RAM block).
</p>

<p>
Nevertheless, these black boxes do not worry us too much because we are usually
unable to verify the systems with large blocks of memory and we abstract
away from them (this is more discussed in <a href="#Verif">Section</a>).
</p>

<h3>line <tt>set tristate_map TRUE</tt></h3>
<p>
As it is discussed in <a href="#coderefine">Subsection</a>, we have some
troubles with modeling high impedance signal <tt>'z'</tt> in
<i>SMV</i>. Therefore we enable this option in order to remove
all tristate values wherever it is possible. However some tristate signals
are quite often necessary to preserve functionality of the design.
</p>

<h3>line <tt>write -downto PRIMITIVES -format Verilog $NAME.v</tt></h3>
<p>
This line of TCL code makes the final <i>Verilog</i>
output. The most important option here is the <tt>-downto PRIMITIVES</tt> option
forcing synthesiser to write down also the behavioural descriptions of basic
entities from the library <i>Primitives</i> (e.g.~<tt>LATRS</tt>,
<tt>DFFRS</tt>, <tt>GND</tt>, etc.).
</p>

<h3>Synthesising a signal as a <tt>dumb</tt> signal</h3>
<p>
If two signals have the same behaviour, the synthesiser can flatten these
signals to the only single one. If <tt>hierarchy preserve</tt> option is
set, then one such signal is preserved and the second one is tied to
<tt>GND</tt> component (ground).
</p>

<p>
This optimisation can be prohibited by writing attribute
<tt>preserve_signal</tt> to the <i>VHDL</i> code or to the
constraint file. As the occurrence of two signals with the same behaviour is
quite rare, we currently solve this situation by using the name of preserved
signal in temporal formulas instead of the name of the flattened one.
</p>

<h2 id="furtherwork">Further work with a synthesised code</h2>
<p>
The synthesised code (in a <i>Verilog</i> format) has many
advantages, but also some disadvantages. The main (and very important)
advantage is that there is used only small fragment of
<i>Verilog</i> language in a synthesised code.  Therefore the
portability of such a code is much better then of the original one. In the
synthesised code we can also trust that every output signal has assigned a
value (<tt>0</tt>,<tt>1</tt>, or some special value like <tt>'bz</tt>) -
this claim holds for the entire code except for black boxes and behavioural
descriptions of components from included libraries.  It is also important
that the synthesis encloses the definition of the most of components used in
the design (including those from the library <i>Primitives</i>).
</p>

<p>
The main disadvantages are as follows. The code gained from a synthesis is
quite large and untransparent. There are preserved only signals in the
interfaces of entities (except for the signals with the same behaviour which
can be flattened into one signal). Therefore if we want to check the values
of inner signals of entities, we have to work around it.
</p>

<h3 id="innersignals">How to preserve inner signals</h3>
<p>
The <tt>hierarchy preserve</tt> option allows us only to preserve
the signals in the interfaces of entities. But we can (mis)use it
also for preserving inner signals of entities. Anyway we can define
a new entity (called for example <tt>export_signals</tt>) with
the only one output signal and one input signal
for each signal which should be exported. Architecture of such an entity
can be a large logical <tt>AND</tt> of input signals.
</p>

<h2 id="coderefine">Refining Verilog code</h2>
<p>
As was mentioned above, the synthesised <i>Verilog</i> code is
the correct input for <b>vl2smv</b> except for logical
connectives, assignment using <tt>buf</tt> module, and the name of the
top-level entity.  The needed translation from a synthesised
<i>Verilog</i> to the <i>Verilog</i> suitable
for <b>vl2smv</b> is shown in <a href="#mojetabulka">Table</a>.
</p>

<tab sloupce="ll" id="mojetabulka">
<tr><td><tt>xor(a,b,c)</tt></td><td><tt>assign a = &vlnka;(b | c)</tt></td></tr>
<tr><td><tt>nand(a,b,c)</tt></td><td><tt>assign a = &vlnka;(b &amp; c)</tt></td></tr>
<tr><td><tt>and(a,b,c)</tt></td><td><tt>assign a = a &amp; c</tt></td></tr>
<tr><td><tt>or(a,b,c)</tt></td><td><tt>assign a = (b | c)</tt></td></tr>
<tr><td><tt>buf(a,b)</tt></td><td><tt>assign a = b</tt></td></tr>
<tr><td>the first occurrence of <tt>module &lt;name&gt;</tt></td><td><tt>module main</tt></td></tr>
<tr><td><tt>`bz</tt></td><td><tt>bz_OUR_ALIAS</tt></td></tr>
<nazev>Table of translations</nazev>
</tab>

<p>
The last row of the table is used to translate <tt>'bz</tt> signal to the
other name. It is used to get around a bug in <b>vl2smv</b>
that translates <tt>`bz</tt> to the meaningless sequence of zeros finished
by so called <tt>weak</tt> value, whereas we need it to translate to the
single value <tt>weak</tt>.
</p>

<p>
Signal <tt>'bz</tt> is usually used to model an access to a bus.  We
translate it to the <tt>weak</tt> signal.  But it is not correct when a
signal of a bus is declared only as an output signal of some entity:
assigning <tt>weak</tt> value to such signal causes <tt>undefined</tt> value
of such signal.  We do not know whether it is another bug in
<b>Cadence SMV</b>, but we have to get around this behaviour so
that we replace output signals with input-output signals (it can be simply
done by removing keyword <tt>output</tt> in the <i>SMV</i>
code).  There we use the big advantage of synthesised code: value of each
output signal in a synthesised code is defined (except for black boxes and
behavioural descriptions of components from included libraries, e.g.~library
<i>Primitives</i>).  Therefore we do not change the behaviour of the
design (except for assigning <tt>weak</tt> values but this change is
correct).
</p>

<h2>Black boxes</h2>
<p>
The synthesiser knows the behavioural descriptions of components from
the library <i>Primitives</i>. But it does not know behavioural
descriptions of components from library <i>xcv2</i> that is
used to synthesise our <i>VHDL</i> sources for a Xilinx platform.
</p>

<p>
There are two cases for components from <i>xcv2</i>:</p>

<ul>
 <li>there exists a behavioural description of a component in the documentation
	 (e.g.~entity <tt>SRL16E</tt>)</li>
 <li>there exists no such a description (e.g.~<tt>RAMB16_S18_S18</tt> and
	 the rest of block-RAM components)</li>
</ul>

<p>In the first case we can (manually) copy the description from the
documentation of <i>xcv2</i> to the <i>Verilog</i> source and thus we replace
the black box by a fully functional component.</p>

<p>
In the second case we have to abstract away from the behaviour of such
a component (and take it into account when we create temporal
formulas).
</p>

<h2>Translation of latch registers</h2>
<p>
As stated, there is no problem with translation of synthesised
code because of its simplicity - synthesised code is composed from
a large amount of assignments and many connected copies of components.
But when we also include behavioural descriptions of components
from libraries <i>Primitives</i> and <i>xcv2</i> we
clutter up the <i>Verilog</i> code with a relatively complex
codes of included entities.
</p>

<p>
Therefore there has occurred further (meantime) manual work for us.
It is necessary to check out, whether there is a block of code, from which it is inferred
the latch register. It can be recognised by the keyword <tt>reg</tt>
in a <i>Verilog</i> source code. <b>vl2smv</b>
seems to have no support for a register data type in <i>Verilog</i>.
</p>

<p>
If the identifier is declared as a register (<tt>reg</tt> in
<i>Verilog</i>, <tt>variable</tt> in
<i>VHDL</i>) then its value is changed immediately after any
assignment and it is preserved until next change (independently on a clock
edge).  Assignment to these registers is realized in the <tt>always</tt>
blocks (in <i>Verilog</i>). The keyword <tt>always</tt> is
followed by the sensitivity list with neither <tt>posedge</tt> nor
<tt>negedge</tt> keyword.  Furthermore the code in the <tt>always</tt> block
need not to assign these registers (because latch registers should preserve
its value).  For example the <i>Verilog</i> code of the entity
<tt>LATRS</tt> is unfortunately translated to the <i>SMV</i>
code as follows.  ~<br/> ~<br/>
<i>Verilog</i> code:</p>

<pre>
module LATRS ( set, reset, in, clk, out );
 input set;
 input reset;
 input in;
 input clk;
 output out;
 reg out;
 
 always @ (in or clk or reset or set)
  begin
   if (set) out = 1;
   else if (reset) out = 0;
   else if (clk) out = in;
  end
</pre>

<p><i>SMV</i> code:</p>
<pre>
module LATRS (set, reset, in, clk, out)
{
 input set : boolean resolve;
 input reset : boolean resolve;
 input in : boolean resolve;
 input clk : boolean resolve;
 output out : boolean resolve;

 out : boolean resolve;
 do
  {
   if (set) out := 1;
   else if (reset) out := 0;
   else if (clk) out := in;
  }
}
</pre>

<p>
The declaration of register <tt>out</tt> has turned to
redeclaration of a signal <tt>out</tt> (the redeclaration is not the main
mistake in this code - actually it is ignored). The main mistake in the
resulting code is a transformation of the register into the ordinary signal
(that cannot preserve its value).
</p>
<p>
The only way how to correct this mistake seems to be the simulation of
registers by flip-flop registers (in <i>SMV</i>). We can always store the last value of a
signal to the flip-flop register (<tt>previous</tt> in our example) and
during the next tick of clock we can assign its value as a default value of
the signal representing the register. Thus the mentioned <tt>LATRS</tt>
example
is changed to the following one.</p>

<pre>
module LATRS (set, reset, in, clk, out)
{
 input set : boolean resolve;
 input reset : boolean resolve;
 input in : boolean resolve;
 input clk : boolean resolve;

 out : boolean resolve;
 previous : boolean resolve;  -- flip-flop register

 init(previous) := undefined; -- at the first time the notion
                              -- 'previous' has no sense

 do
  {
   out := previous;           -- default set to previous
   if (set) out := 1;
   else if(reset) out := 0;
   else if(clk) out := in;
  }

 next(previous) := out ;
}
</pre>

<p>
After all these translations we can start with a real formal
verification. The way we translated the sources have a significant influence
to techniques of verification.
</p>


<h1 id="Verif">Verification of design in SMV language</h1>

<p>This section describes ways how to deal with <i>SMV</i>
codes obtained from translation described in the previous section. Since
the synthesis has been already made, this codes are no longer in the behavioural
level. Some problems arise from the synthesis and the others from the state
explosion.</p>

<h2 id="MC">Model checking</h2>

<p>The <i>VHDL</i> tools allow to simulate the system written
in <i>VHDL</i> source codes.  Each simulation run of the
system checks whether the model is correct in this particular run. To ensure
that our <i>VHDL</i> source code is correct and really works
as it is intended, we need to simulate all possible runs. Using
<i>VHDL</i> simulators one can check only a small test set.
</p>

<p>To check all possible runs of the model we use formal methods of
verification.  We specialise to model checking methods, which allow to
automatically prove whether a system satisfies the specification at some
level of abstraction (for more details see~<cite href="Bar02"></cite>).</p>

<h3>State explosion</h3>

<p>
The number of states may grow exponentially with respect to the number of
storage elements of a system written in <i>VHDL</i> source
codes, and thus even for small sized examples the state space becomes
infeasible.  Linear grow up of variables in <i>SMV</i> may
cause the exponential grow up of states in the system, which has to be
checked.</p>

<p>
The state explosion problem is inherent to explicit state model checking of
asynchronous concurrent systems.  The states can be symbolically
represented such as representing states using a Binary Decision Diagram
(BDD).
<!-- Stavova exploze - konkretni priklad, mozna uz ne.. -->
</p>

<p>In order to handle large designs, we have to abstract away parts of the
data path, or the whole entities, or even the components.</p>

<p>Taking into an account that <b>Cadence SMV</b> for CTL
(branching time logic) formula in the form <tt>AG (subformula)</tt> has to
verify whether <tt>subformula</tt> is satisfied, it obviously has to take
in notice every possible run of the system.  For formula in the form <tt>EF
(subformula)</tt> it is again necessary to verify that <tt>subformula</tt>
is not satisfied for every possible run of the system, before concluding that
formula <tt>EF (subformula)</tt> is not satisfied.
</p>

<p><b>Cadence SMV</b> as a symbolic based model checker
has some advantages in comparison with explicit state approach to model checking.
It manipulates with the set of states with a specific property and
not with every state explicitly.
</p>


<h2>Providing assertions in VHDL code</h2>

<h3>Native assertions in VHDL</h3>

<p><i>VHDL</i> itself contains the following command:</p>

<p><tt>assert </tt><i>condition</i><tt> [report </tt><i>error_string</i><tt>]
                           [severity </tt><i>severity_value</i><tt>]</tt></p>

<p>We can verify this assertions better than <i>VHDL</i> simulators
in the sense that simulator makes only selected runs of the system, whereas we 
check all possible runs of the system.
</p>

<h3>Using special assertion comments</h3>

<p>We also support several ways to include verification formulas as comments in
the <i>VHDL</i> design. Briefly we are supporting following forms of
comments:
</p>

<p>The most simple form is useful when property
is very complicated:</p>
<p><tt>-- assert </tt><i>Informal description in English.</i></p>

<p>For more complicated properties there could be added a <tt>LEMMA</tt>
with an attached email and the <i>unique_mark</i> referring to that
property:</p>
<p>
<tt>-- assert LEMMA </tt><i>unique_mark</i>
</p>

<p>The corresponding attached email should have the following form:</p>
<p>
<tt>To: </tt><i>ipv6-ver@liberouter.org</i><br/>
<tt>Subject: LEMMA </tt><i>file.vhd-unique_mark</i><br/>
<tt>Content: </tt><i>Description of properties of your <i>VHDL</i> code.</i>
</p>

<p>Description of properties in the <i>VHDL</i> boolean expressions
(extended by implication, cycle, branching and more) which should be always
true:</p>
<p>
<tt>-- assert globally </tt><i>extended_VHDL_bool_expression</i>
</p>

<p>From others we mention only one example how
signals, ports, variables, or registers, which never falls to have constant
value, could be described.
</p>
<p>
<tt>-- assert alive </tt><i>boolean_expression</i></p>
<p>
This property is known as a liveness.
</p>

<p>We have written a <i>Verification cookbook</i>~<cite href="VC"></cite>,
the manual for <i>VHDL</i> designers.
It contains detailed information how to write assertions.
Its purpose is to help them to write the assertions down into the code
in some of the forms described above.
</p>


<h2>SMV model checker in practice</h2>

<h3>The automatic tests</h3>

<p>There is no need to explicitly write
the deadlock free requirement on the modeled system.
The <b>Cadence SMV</b> automatically
checks whether the system has a state
with no successors.
</p>

<h3>Using preconditions and lemmas</h3>

<p>Except of a command <tt>assert</tt> the tool
<b>Cadence SMV</b> supports more
sophisticated constructions.</p>

<p>
At first all formulas can be uniquely entitled to
enable one to refer to it.
For example:</p>

<pre>lemma_RW_mutual_exclusion: assert G (! ( \plx_wr &amp; \plx_rd ) );</pre>


<p>There is a need for preconditions on formulas.
The most of preconditions we obtain from the exact position
of formulas in <i>VHDL</i> source.
The formula have to be valid in the states of system
corresponding to the position in <i>VHDL</i> source.
Rarely it is satisfied even in the other places.</p>

<p>For example <tt>lemma1</tt> in the following <i>VHDL</i>
code is intended for verification with a precondition.</p>
<pre>
 if RESET = '1' then
      WR_REQ      &lt;= '1';
      WR_STATE    &lt;= "1000";
   elsif FSM_RD = '1' then  -- assert LEMMA lemma1
      WR_REQ      &lt;= '0';
</pre>
<p>In <i>SMV</i> there can be the proof with precondition
expressed as follows.</p>
<pre>
precondition_reset: assert (~RESET &amp; FSM_RD)
using precondition_reset prove lemma1;
</pre>

<h3>Disappearing of the inner signals</h3>

<p>When we obtain for example this <i>VHDL</i> source code:</p>
<pre>
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity counter is                       -- configurable counter
        Generic (N : integer := 8);
        Port (CLK     : in std_logic;   -- counted signal
              AS_RESET: in std_logic;   -- asynchronous reset
              RESET   : in std_logic;   -- synchronous reset
              CE      : in std_logic;   -- count enable
              OUTPUT  : out std_logic_vector(N-1 downto 0)
             );                         -- actual counter value
end counter;

architecture Behavioral of counter is
signal VALUE: std_logic_vector(N-1 downto 0); -- internal value
begin</pre>

<p><tt><b> -- assert active VALUE when CE</b></tt></p>

<pre>        process (CLK,AS_RESET)
        begin
        if AS_RESET='1' then
        VALUE &lt;= (others =&gt; '0');
          elsif CLK='1' and CLK'event then
                if RESET='1' then
                        VALUE &lt;= (others =&gt; '0');
                elsif CE='1' then
                        VALUE &lt;= VALUE + 1;
           end if;
        end if;
        end process;

        OUTPUT &lt;= VALUE;
end Behavioral;
</pre>

<p>We have to deal with the following problem: Our task is to check whether
the formula <tt>active VALUE when CE</tt> is satisfied or not. The problem
is that signal <tt>VALUE</tt> is internal only and due to synthesis, it
is neither in <i>Verilog</i>, nor in <i>SMV</i>.
</p>

<p>One way is to fetch up the signal <tt>VALUE</tt> to the port list
in <i>VHDL</i> source.
The entity <tt>counter</tt> should contain
one of the following lines in the port list:<br/>
<tt>VALUE : out std_logic_vector(N-1 downto 0);</tt><br/>
<tt>VALUE : inout std_logic_vector(N-1 downto 0);</tt><br/>
<tt>VALUE : buffer std_logic_vector(N-1 downto 0);</tt>
</p>

<p>
The problem is that the line<br/> 
<tt>VALUE : out std_logic_vector(N-1 downto 0);</tt><br/>
results in the following error message:<br/>
<tt>Error, cannot read output: VALUE; use mode buffer or inout.</tt>
</p>

<p>
The other possible lines with <tt>inout</tt> or <tt>buffer</tt> works
(<i>VHDL</i> source can be synthesised) and these lines are
correct with respect to our actual formula as it happens.  In general
this ways of fetching up the signal <tt>VALUE</tt> are incorrect as it changes
the model of system in a nonequivalent manner. The solution is described in
<a href="#innersignals">Part</a>.
</p>

<p>The another way is to find out that in <i>VHDL</i> behavioural
description of <tt>counter</tt> there are two processes:</p>

<pre>process (CLK,AS_RESET)
OUTPUT &lt;= VALUE;</pre>

<p>These processes run in parallel  and the process <tt>OUTPUT &lt;=
VALUE;</tt> causes that signals <tt>OUTPUT</tt> and <tt>VALUE</tt> are
connected. This observation could be hard to find. But when it is found it
enables to check the formula without intervention to <i>VHDL</i> source.</p>


<h3>From counterexample to a new precondition</h3>

<p>Counterexample gives us a new precondition or a negative result
in the following way:</p>

<p>When we obtain a counterexample, we analyse it and
as far as this trace could not occur in real hardware
we add new preconditions to the formula. We may obtain
a counterexample again which often results to many
preconditions.</p>

<p>Ordinary counterexample may than have the following effect:<br/>
From <tt>using pre1, &ldots;, prek prove lemma;</tt> makes<br/>
<tt>using pre1, &ldots;, prek, newpre prove lemma;</tt>
</p>

<p>
Than we proceed as long as we obtain a positive or a negative result.</p>

<h3>How to deal with a huge trace table</h3>

<p>The counterexample is represented as a trace table.
The rows are assigned to variables of <i>SMV</i> corresponding
to signals, ports, variables, or registers of <i>VHDL</i>
and each column contains values of these variables in one state.
Values are expressed by 0, 1, or  - (standing for undefined value).
</p>

<obr src="hugetrace">Huge trace in <b>Cadence SMV</b></obr>

<p>If one wants to see only changes, then it is useful
to choose <tt>view</tt> and then <tt>zoom out</tt> in the trace table
but it helps only a little.
</p>

<p>We are working with huge traces and <b>Cadence SMV</b>
shows only a very small part of a trace at once.
Therefore we save trace to a file and work on
it out of <b>Cadence SMV</b>. We compare interesting
states of a trace using the program <b>diff</b>.
</p> 

<h2>XML format for reporting results</h2>

<p>We need a uniform format for publishing our results.
For this purpose we define our own <i>XML</i> structure
<tt>verification</tt>. For each version of verified design we add
a verification report (element <tt>ver</tt>) that contains all important
information about performed verification.
Every verification report consist of:</p>

<ul>
  <li>Tree of files in which the design is described
      and its time of creation.</li>
  <li>List of preconditions, which could be referred by formulas.</li>
  <li>List of formulas, where each formula contains its code, information
      about duration time, detailed description, possible differences
      from the original code for verification purposes,
      and last but not least the result
      -- whether it is valid or not. If formula is not valid,
      the counterexample is present as well.</li>
</ul>

<p>
We have created a <tt>verification.dtd</tt> and every <i>verification report</i>
have to be valid against it.
The following example of <i>verification report</i>
should make some details clear:
</p>

<pre>
&lt;verification&gt;
  &lt;ver author="Tomas Kratochvila" toplevel="ee"&gt;
    &lt;note&gt;Only an example, not real verification.&lt;/note&gt;
    &lt;vhdlsourcelist src="liberouter.old/hw/edit_engine/new_cvs/"
                    exportdate="2003-10-31"&gt;
      &lt;directory name="edit_engine"&gt;
        &lt;directory name="dram_u"&gt;
          &lt;file type="vhdl" name="dram_u_fsm_mem.vhd"/&gt;
          &lt;file type="vhdl" name="dram_u_fsm.vhd"/&gt;
          &lt;file type="vhdl" name="dram_u.vhd"/&gt;
        &lt;/directory&gt;
        &lt;file type="vhdl" name="send_u/send_u.vhd"/&gt;
        &lt;file type="vhdl" name="alu/alu.vhd"/&gt;
        &lt;file type="vhdl" name="ee.vhd"/&gt;
      &lt;/directory&gt;
    &lt;/vhdlsourcelist&gt;
    &lt;preconditions&gt;
      &lt;precondition name="simplepre0"&gt;G ( F \START)&lt;/precondition&gt;
      &lt;precondition name="pre3"&gt;
         G ((\START) -&gt; F (\DRAM_ACK))&lt;/precondition&gt;
    &lt;/preconditions&gt;
    &lt;formulas&gt;
      &lt;formula name="simplerw" result="true"&gt;
        &lt;code&gt;G (! ( \plx_wr &amp; \plx_rd ) )&lt;/code&gt;
        &lt;description&gt;Simple RW mutual exclusion.&lt;/description&gt;
        &lt;note&gt;&lt;/note&gt;
        &lt;time&gt;0.1 s&lt;/time&gt;
      &lt;/formula&gt;
      &lt;formula name="hardcorerw"
                preconditions="simplepre0, pre3"
                result="false"&gt;
        &lt;code&gt;G (\START -&gt; (! (\plx_wr &amp; \plx_rd) ))&lt;/code&gt;
        &lt;counterexample&gt;not important&lt;/counterexample&gt;
        &lt;description&gt;Hard-core RW mutual exclusion.&lt;/description&gt;
        &lt;diff&gt;&lt;/diff&gt;
      &lt;/formula&gt;
    &lt;/formulas&gt;
  &lt;/ver&gt;
&lt;/verification&gt;
</pre>

<h1>Conclusion</h1>

<p>We have made the translation from <i>VHDL</i> to <i>SMV</i>
almost automatic and we would like to bring the automatisation further.
We have successfully verified various properties of
selected parts of a hardware design and we are planning to verify larger pieces
of hardware in order to check the interaction between selected components.
The possible state explosion problems can be reduced by the symbolic methods of
<b>Cadence SMV</b>.
</p>
<p>
The universal system of verification reports is created to
easily report results using <i>XML</i>.
</p>
<p>
We provide several ways to write assertions into
the <i>VHDL</i> source code.
These assertions are reformulated to temporal formulas and included
into the <i>SMV</i> source code obtained from the translation.
Although the system of assertions is quite comfortable we have to
study the informal descriptions of parts of the design and formulate
our own assertions, because hardware designers are often not aware of all
presumptions they use to believe that their source codes are correct.
</p>
<p>

</p>

  <!-- References -->
  <seznamknih>
    <kniha id="Bar02">
      Barnat J., Brázdil T., Krčál P., Řehák V., and Šafránek D.:
      <i>Model checking in IPv6 Hardware Router Design</i><br/>
      CESNET technical report 8/2002
    </kniha>

    <kniha id="FPGA">
      Xilinx, Inc.:
      <i>DS031-1 Virtex-II 1.5V Field Programable Gate Arrays</i><br/>
      October 2001
    </kniha>

    <kniha id="LeoSpec">
      LeonardoSpectrum: 
      <i>LeonardoSpectrum WWW Pages</i><br/> 
      <tt>http://www.mentor.com/leonardospectrum/</tt>
    </kniha>

    <kniha id="LibWWW">
      Liberouter:      
      <i>Liberouter Project WWW Pages</i><br/> 
      <tt>http://www.liberouter.org/</tt>
    </kniha>

    <kniha id="LSguide">
      Mentor Graphics:
      <i>LeonardoSpectrum User's Manual</i><br/> 
      <tt>http://www.mentor.com/leonardospectrum/customer/documentation/</tt>
    </kniha>

    <kniha id="Nov02">
      Novotný J., Fučík O., Kokotek R.:
      <i>Schematics and PCB of COMBO6 card</i><br/>
      CESNET technical report 14/2002
    </kniha>

    <kniha id="SMV">
      Cadence SMV:
      <i>Cadence SMV WWW Pages</i><br/> 
      <tt>http://www-cad.eecs.berkeley.edu/&vlnka;kenmcmil/smv/</tt>       
    </kniha>

    <kniha id="VC">
      Tomáš Kratochvíla:
      <i>Verification cookbook (Liberouter policy WWW Pages)</i><br/>
      <tt>http://www.liberouter.org/policy.html</tt>
    </kniha>

    <kniha id="Ver">
      Daniel C. Hyde:
      <i>Handbook on Verilog HDL</i><br/>
      <tt>www.eg.bucknell.edu/&vlnka;cs320/1995-fall/manual.pdf</tt>
    </kniha>

    <kniha id="VHDL">
      Ashenden Peter J.:
      <i>The VHDL Cookbook</i><br/>
      <tt>http://tech-www.informatik.uni-hamburg.de/<br/>vhdl/doc/cookbook/VHDL-Cookbook.pdf</tt>
    </kniha>

  </seznamknih>

</zprava>




