Tuesday, June 23, 2015

Modeling of digital circuits in VHDL

Modeling of digital circuits in VHDL
VHDL supports the following types of modeling
·         Structural Model
·         Behavioral Model
·         Dataflow Model
·         Mixed Model
Structural Model:
  • An entity is modeled as a set of components connected by signals, i.e., as a netlist.
  • The behavior of the entity is not explicitly apparent from its model.
  • The component instantiation statement is the primary mechanism used for describing such a model of an entity.
Component Declaration:
  • A component instantiated in a structural description must first be declared using a component declaration.
  • A component declaration declares the name and the interface of a component. The interface specifies the mode and the type of ports.
component component-name
port ( list-of-interface-ports ) ;
         end component;
  • The component-name may or may not refer to the name of an already existing entity in a library. If it does not, it must be explicitly bound to an entity; otherwise, the model cannot be simulated.
  • The list-of-interface-ports specify the name, mode, and type for each port of the component in a manner similar to that specified in an entity declaration.
Component Instantiation:
  • A component instantiation statement defines a subcomponent of the entity in which it appears. It associates the signals in the entity with the ports of that subcomponent.
            component-label: component-name port map ( association-list) ;
  • The component-label can be any legal identifier and can be considered as the name of the instance.
  • The component-name must be the name of a component declared earlier using a component declaration.
  • The association-list associates signals in the entity, called actuals, with the ports of a component, called locals.
  • An actual must be an object of class signal. Expressions or objects of class variable or constant are not allowed. An actual may also be the keyword open to indicate a port that is not connected.
  • There are two ways to perform the association of locals with actuals:
1. positional association,
2. named association.
  • In positional association, an association-list is of the form
                        actuali, actualg, actual3, . . ., actual
Each actual in the component instantiation is mapped by position with each port in the component declaration. i.e., the first port in the component declaration corresponds to the first actual in the component instantiation, the second with the second, and so on.
  • In named association, an association-list is of the form
locale => actual1, local2 => actual2, ..., localn => actualn
  • The signals used to interconnect components can also be slices, vectors or array elements.
Dataflow Model:
  • A dataflow model specifies the functionality of the entity without explicitly specifying its structure. This functionality shows the flow of information through the entity, which is expressed primarily using concurrent signal assignment statements and block statements.
  • Concurrent Signal Assignment statement
        One of the primary mechanisms for modeling the dataflow behavior of an entity is by using the concurrent signal assignment statement.
Comparison of Sequential and Concurrent signal assignment Statements
S.No.
Concurrent Signal Assignment
Sequential Signal Assignment
1.
signal assignment statements that appear outside of a process are called concurrent signal assignment statements
signal assignment statements can also appear within the body of a process statement. Such statements are called sequential signal assignment statements
2.
Concurrent signal assignment statements are event triggered, that is, they are executed whenever there is an event on a signal that appears in its expression
sequential signal assignment statements are not event triggered and are executed in sequence in relation to the other sequential statements that appear within the process
3.
Eg:
architecture CON_SIG_ASG of FRAGMENT2 is
begin -- Following are concurrent signal assignment statements:
A<=B;
Z<=A;
end;
Eg:
architecture SEQ_SIG_ASG of FRAGMENT1 is
- A, B and Z are signals.
begin
process (B)
begin -- Following are sequential signal assignment statements:
A<=B;
Z<=A;
end process;
end;
4.
When an event occurs on signal B, say at time T, signal A gets the value of B after delta delay, that is, at time T+Δ and this event on A will trigger the second signal assignment statement that will cause the new value of A to be assigned to Z after another delta delay, that is, at time T+2Δ.
Whenever signal B has an event, say at time T, the first signal assignment statement is executed and then the second signal assignment statement is executed, both in zero time.  Signal A is scheduled to get its new value of B only at time T+Δ, and Z is scheduled to be assigned the old value of A at time T+Δ also.
5.
The concurrent signal assignment statement:

CLEAR <= RESET or PRESET after 15 ns;
-- RESET and PRESET are signals.

is equivalent to the following process statement:

process
begin
CLEAR <= RESET or PRESET after 15 ns;
wait on RESET, PRESET;
end process;
An identical signal assignment statement (a sequential signal assignment) appears in the body of the process statement along with a wait statement whose sensitivity list comprises of signals used in the expression of the concurrent signal assignment statement.


Conditional Signal Assignment Statement:
  • The conditional signal assignment statement selects different values for the target signal based on the specified, possibly different, conditions (it is like an if statement).
Target - signal <= [ waveform-elements when condition else ]
[ waveform-elements when condition else ]
. . .
waveform-elements;
  • Whenever an event occurs on a signal used either in any of the waveform expressions or in any of the conditions, the conditional signal assignment statement is executed by evaluating the conditions one at a time. For the first true condition found, the corresponding value of the waveform is scheduled to be assigned to the target signal.
Z <= IN0 after 10ns when S0 = '0' and S1 = '0' else
IN1 after 10ns when S0 = '1' and S1 = '0' else
IN2 after 10ns when S0 = '0' and S1 = '1' else
IN3 after 10 ns;
Selected Signal Assignment Statement:
  • The selected signal assignment statement selects different values for a target signal based on the value of a select expression (it is like a case statement).
with expression select —This is the select expression.
target-signal <= waveform-elements when choices,
waveform-elements when choices,
waveform-elements when choices ;
  • example
type OP is (ADD, SUB, MUL, DIV);
signal OP_CODE: OP;
. . .
with OP_CODE select
Z <= A+B after ADD_PROP_DLY when ADD,
A - B after SUB_PROP_DLY when SUB,
A * B after MUL_PROP_DLY when MUL,
A / B after DIV_PROP_DLY when DIV;
Block Statement:
  • A block statement is a concurrent statement. It can be used for three major purposes:
1. to disable signal drivers by using guards,
2. to limit signal scope,
3. to represent a portion of a design.
  • A block statement itself has no execution semantics but provides additional semantics for statements that appear within it.
block-label: block [ ( guard-expression ) ]
[ block-header]
[ block-declarations]
begin
concurrent-statements
end block [ block-label ];
  • Example:
B1: block (STROBE = '1')
begin
Z <= guarded not A;
end block B1;
Behavioral Modeling:
Entity Declaration:
  • An entity declaration describes the external interface of the entity, that is, it gives the black-box view. It specifies the name of the entity, the names of interface ports, their mode (i.e., direction), and the type of ports.
entity entity-name is
[ generic ( list-of-generics-and-their-types ) ; ]
[ port ( list-of-interface-port-names-and-their-types) ; ]
[ entity-item-declarations ]
[ begin
entity-statements ]
end [ entity-name ];
  • The entity-name is the name of the entity and the interface ports are the signals through which the entity passes information to and from its external environment. Each interface port can have one of the following modes:
1.      in: the value of an input port can only be read within the entity model.
2.      out: the value of an output port can only be updated within the entity model; it cannot be read.
3.      inout: the value of a bidirectional port can be read and updated within the entity model.
4.      buffer: the value of a buffer port can be read and updated within the entity model. However, it differs from the inout mode in that it cannot have more than one source and that the only kind of signal that can be connected to it can be another buffer port or a signal with at most one source.
Architecture Body:
  • An architecture body describes the internal view of an entity.
  • It describes the functionality or the structure of the entity.
architecture architecture-name of entity-name is
[ architecture-item-declarations ]
begin
concurrent-statements; these are —>
process-statement
block-statement
concurrent-procedure-call
concurrent-assertion-statement
concurrent-signal-assignment-statement
component-instantiation-statement
generate-statement
end [ architecture-name ] ;
Process Statement:
  • A process statement contains sequential statements that describe the functionality of a portion of an entity in sequential terms.
[ process-label: ] process [ ( sensitivity-list ) ]
         [process-item-declarations]
begin
         sequential-statements; these are ->
        variable-assignment-statement
        signal-assignment-statement
        wait-statement
        if-statement
        case-statement
        loop-statement
        null-statement
        exit-statement
        next-statement
        assertion-statement
        procedure-call-statement
        return-statement.
end process [ process-label];
Variable Assignment Statement:
  • Variables can be declared and used inside a process statement.
  • A variable is assigned a value using the variable assignment statement that typically has the form
                                                variable-object := expression;
  • The expression is evaluated when the statement is executed and the computed value is assigned to the variable object instantaneously, that is, at the current simulation time.
  • Variables are created at the time of elaboration and retain their values throughout the entire simulation run (like static variables in C high-level programming language). This is because a process is never exited; it is either in an active state, that is, being executed, or in a suspended state, that is, waiting for a certain event to occur.
  • A process is first entered at the start of simulation (during the initialization phase of simulation) at which time it is executed until it suspends because of a wait statement or a sensitivity list.
                                                process (A)
                                                variable EVENTS_ON_A: INTEGER := 0;
                                                begin
                                                EVENTS_ON_A := EVENTS_ON_A+1;
                                                end process;

Signal Assignment Statement:
  • Signals are assigned values using a signal assignment statement The simplest form of a signal assignment statement is
                                                signal-object <= expression [ after delay-value ];
  • A signal assignment statement can appear within a process or outside of a process. If it occurs outside of a process, it is considered to be a concurrent signal assignment statement.
  • When a signal assignment statement is executed, the value of the expression is computed and this value is scheduled to be assigned to the signal after the specified delay.
  • The expression is evaluated at the time the statement is executed (which is the current simulation time) and not after the specified delay. If no after clause is specified, the delay is assumed to be a default delta delay.
COUNTER <= COUNTER+ "0010"; - Assign after a delta delay.
PAR <= PAR xor DIN after 12 ns;
Z <= (AO and A1) or (BO and B1) or (CO and C1) after 6 ns;
Delta Delay:
  • A delta delay is a very small delay (infinitesimally small). It does not correspond to any real delay and actual simulation time does not advance.
  • This delay models hardware where a minimal amount of time is needed for a change to occur in performing zero delay simulation. Delta delay allows for ordering of events that occur at the same simulation time during a simulation.
  • Each unit of simulation time can be considered to be composed of an infinite number of delta delays. Therefore, an event always occurs at a real simulation time plus an integral multiple of delta delays.
  • Eg: events can occur at 15 ns, 15 ns+IA, 15 ns+2A, 15 ns+3A, 22 ns, 22 ns+A, 27 ns, 27 ns+A, and so on.
Fig: Delta Delay
Wait Statement:
  • when a process has a sensitivity list, it always suspends after executing the last sequential statement in the process.
  • The wait statement provides an alternate way to suspend the execution of a process.
  • There are three basic forms of the wait statement.
wait on sensitivity-list;
wait until boolean-expression ;
wait for time-expression ;
  • They may also be combined in a single wait statement. Eg:
                                    wait on sensitivity-list until boolean-expression for time-expression;
  • Eg:
wait on A, B, C;
wait until (A = B);
wait for 10ns;
wait on CLOCK for 20ns;
wait until (SUM > 100) for 50 ms;
If Statement:
  • An if statement selects a sequence of statements for execution based on the value of a condition. The condition can be any expression that evaluates to a boolean value. The general form of an if statement is
if boolean-expressionthen
sequential-statements
[ elsif boolean-expression then -- elsif clause; if stmt can have 0 or
sequential-statements ] -- more elsif clauses.
[ else -- else clause.
sequential-statements ]
end if;
Example:
if SUM <= 100 then -- This is a less-than-or-equal-to operator.
SUM := SUM+10; end if;

if NICKEL_IN then DEPOSITED <=TOTAL_10;
elsif DIME_IN then DEPOSITED <= TOTAL_15;
elsif QUARTERJN then DEPOSITED <= TOTAL_30;
else DEPOSITED <= TOTAL_ERROR; end if;
Case Statement:
  • The format of a case statement is
case expression is
when choices => sequential-statements -- branch #1
when choices => sequential-statements -- branch #2
-- Can have any number of branches.
[ when others => sequential-statements ] -- last branch
end case;
Example:
type WEEK_DAY is (MON, TUE, WED, THU, FRI, SAT, SUN);
type DOLLARS is range 0 to 10;
variable DAY: WEEK_DAY;
variable POCKET_MONEY: DOLLARS;
case DAY is
when TUE => POCKET_MONEY := 6; -- branch 1
when MON I WED => POCKET_MONEY := 2; -- branch 2
when FRI to SUN => POCKET_MONEY := 7; -- branch 3
when others => POCKET_MONEY := 0; -- branch 4
end case;
Null Statement:
  • The statement
            null;
  • is a sequential statement that does not cause any action to take place and execution continues with the next statement.
  • Eg: use in an if statement or in a case statement where for certain conditions, it may be useful or necessary to explicitly specify that no action needs to be performed.
Loop Statement:
  • A loop statement is used to iterate through a set of sequential statements.
[ loop-label : ] iteration-scheme loop
sequential-statements
end loop [ loop-label ] ;
  • There are three types of iteration schemes. The first is the for iteration scheme that has the form
                                    for identifier in range
  • Example
FACTORIAL := 1;
for NUMBER in 2 to N loop
FACTORIAL := FACTORIAL * NUMBER;
end loop;

  • The second form of the iteration scheme is the while scheme that has the form
                                    while boolean-expression
  • Example:
J:=0;SUM:=10;
WH-LOOP: while J < 20 loop - This loop has a label, WH_LOOP.
SUM := SUM * 2;
J:=J+3;
end loop;

  • The third and final form of the iteration scheme is one where no iteration scheme is specified. In this form of loop statement, all statements in the loop body are repeatedly executed until some other action causes it to exit the loop.

  • These actions can be caused by an exit statement, a next statement, or a return statement.
SUM:=1;J:=0;
L2: loop -- This loop also has a label.
J:=J+21;
SUM := SUM* 10;
exit when SUM > 100;
end loop L2; -- This loop label, if present, must be the same
-- as the initial loop label.

  • The exit statement causes the execution to jump out of loop L2 when SUM becomes greater than 100. If the exit statement were not present, the loop would execute indefinitely.
Exit Statement:
  • The exit statement is a sequential statement that can be used only inside a loop. It causes execution to jump out of the innermost loop or the loop whose label is specified.
                                                exit [ loop-label] [ when condition ]:
  • If no loop label is specified, the innermost loop is exited. If the when clause is used, the specified loop is exited only if the given condition is true, otherwise, execution continues with the next statement.
  • An alternate form for loop L2
SUM := 1; J := 0;
L3: loop
J:=J+21;
SUM := SUM* 10;
if (SUM > 100) then
exit L3; -- "exit;" also would have been sufficient.
end if;
end loop L3;
Next Statement:
  • The next statement is also a sequential statement that can be used only inside a loop. The syntax is the same as that for the exit statement except that the keyword next replaces the keyword exit.
                                                next [ loop-label] [ when condition ];
  • The next statement results in skipping the remaining statements in the current iteration of the specified loop and execution resumes with the first statement in the next iteration of this loop.
  • If no loop label is specified, the innermost loop is assumed. In contrast to the exit statement that causes the loop to be terminated (i.e., exits the specified loop), the next statement causes the current loop iteration of the specified loop to be prematurely terminated and execution resumes with the next iteration.
for J in 10 downto 5 loop
if (SUM < TOTAL_SUM) then
SUM := SUM +2;
elsif (SUM = TOTAL_SUM) then
next;
else
null;
end if;
K:=K+1;
end loop;

  • When the next statement is executed, execution jumps to the end of the loop (the last statement, K:= K+1, is not executed), decrements the value of the loop identifier, J, and resumes loop execution with this new value of J.

Assertion Statement:
  • Assertion statements are useful in modeling constraints of an entity. To check if a signal value lies within a specified range, or check the setup and hold times for signals arriving at the inputs of an entity. If the check fails, an error is reported.
  • The syntax of an assertion statement is
assert boolean-expression
[ report string-expression ]
[ severity expression ];
  • If the value of the boolean expression is false, the report message is printed along with the severity level. The expression in the severity clause must generate a value of type SEVERTTY_LEVEL (a predefined enumerated type in the language with values NOTE, WARNING, ERROR, and FAILURE). The severity level is typically used by a simulator to initiate appropriate actions depending on its value.
  • Example: if the severity level is ERROR, the simulator may abort the simulation process and provide relevant diagnostic information. At the very least, the severity level is displayed.
Signal Assignment Statements:
Inertial Delay Model:
  • Inertial delay models the delays often found in switching circuits. It represents the time for which an input value must be stable before the value is allowed to propagate to the output.
  • In addition, the value appears at the output after the specified delay. If the input is not stable for the specified time, no output change occurs.
  • When used with signal assignments, the input value is represented by the value of the expression on the right-hand-side and the output is represented by the target signal.
  • Example of a noninverting buffer with an inertial delay of 10 ns.
Fig.2: Inertial Delay
Transport Delay Model:
  • Transport delay models the delays in hardware that do not exhibit any inertial delay.
  • This delay represents pure propagation delay, that is, any changes on an input is transported to the output, no matter how small, after the specified delay.
  • To use a transport delay model, the keyword transport must be used in a signal assignment statement. Figure 4.4 shows an example of a noninverting buffer using a transport delay of 10 ns.
Fig.3: Transport Delay
§  Example:
Entity WIRE14 is
port (A: in BIT; Z: out BIT);
end WIRE14;
architedture WIRE14_TRANSPORT of WIRE14 is
begin
process (A)
begin
Z <= transport A after 0.1 ms;
end process;
end WIRE14_TRANSPORT;
Need for testing:
1.      To verify the functionality of the design according to specifications.
2.      To perform random testing and hence to reduce the test time of the design.
3.      To detect failures so that bugs (in software code) can be identified and corrected before it gets shipped to costumer. (There are possibilities that error may in the specification itself. Sometimes miscommunications between teams may lead to wrong design.)
A test bench or testing workbench is a virtual environment used to verify the correctness or soundness of a design or model, for example, a software product.
In hardware testing of electronic devices, where an engineer would sit at a lab bench with tools for measurement and manipulation, such as oscilloscopes, multimeters, soldering irons, wire cutters and manually verify the correctness of the device under test (DUT).
In software or firmware or hardware engineering, a test bench refers to an environment in which the product under development is tested with the aid of software and hardware tools.
The software may need to be modified slightly in some cases to work with the test bench but careful coding can ensure that the changes can be undone easily and without introducing bugs.
Components of a test bench:
A test bench has four components:
  1. Input: The entrance criteria or deliverables needed to perform work
  2. Procedures to do: The tasks or processes that will transform the input into the output
  3. Procedures to check: The processes that determine that the output meets the standards
  4. Output: The exit criteria or deliverables produced from the workbench
Kinds of test benches:
The following types of test bench are the most common: Test Benches
  1. Stimulus only — contains only the stimulus driver and DUT; does not contain any results verification.
  2. Full test bench — Contains stimulus driver, known good results, and results comparison.
  3. Simulator specific — the test bench is written in a simulator-specific format.
  4. Hybrid test bench — Combines techniques from more than one test bench style.
  5. Fast test bench — Test bench written to get ultimate speed from simulation.
Test Benches:
To simulate your design, you need both the design under test (DUT) or unit under test (UUT) and the stimulus provided by the test bench. 

A test bench is HDL code that allows you to provide a documented, repeatable set of stimuli that is portable across different simulators.

A test bench can be as simple as a file with clock and input data or a more complicated file that includes error checking, file input and output, and conditional testing.

Methods to create the test bench:
  •  Text editor
This is used to verify complex designs. It allows you to use all the features available in the HDL language and gives you flexibility in verifying the design.
Advantages:  It produces more precise and accurate results than using the Test Bench Waveform Editor.
Disadvantages: It is more challenging to create the code.
To assist in creating the test bench, you can create a template that lays out the initial framework, including the instantiation of the UUT and the initializing stimulus for your design. 
  •  Test Bench Waveform Editor
This is used to verify less complicated simulation tasks and is recommended if you are new to HDL simulation. It allows you to graphically enter the test bench to drive the stimulus to your design.
Advantages: Easy to work.
Disadvantages: Implementation and analysis of complex designs.
Test Bench Strategies:
Because the test bench becomes a part of the hierarchy in your code, the following has to be considered:
  •  Make the test bench the top level of the code.
The test bench instantiates the unit under test (UUT), and stimulus is applied from the top-level test bench to the lower-level design or portion of the design being tested.
  •  Use the instance name UUT for the instantiated unit under test.
This is the default instance name that Project Navigator expects.
The same test bench for both functional and timing simulation can be used.

The general recommendations for simulation are:
  •  Initialize all input ports at simulation time zero, but do not drive expected stimulus until after 100 nanoseconds (ns) simulation time.
During timing simulation, a global set/reset signal is automatically pulsed for the first 100 ns of simulation. To keep the test bench consistent for both timing and functional simulation, it is recommended that you hold off input stimulus until the global set/reset has completed.
  •  Do not provide data to the input ports at the same time as the clock.
For non-timing simulation, this can cause some signals to be applied before the clock and some after the clock. Apply data only after the clock is applied to the input ports. This makes it easier to keep track of which clock edge data changes are being applied.
  •  If output checking is performed in the test bench, apply data just before the next clock cycle.
For timing simulation, it could take up to an entire clock cycle for the data to propagate through the logic and settle to a known value. Checking data too early in the clock cycle may yield incorrect results.
Example:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity test is
port (clk : in std_logic;
      count : out std_logic_vector(3 downto 0);
      reset :in std_logic
     );
end test;

architecture Behavioral of test is
signal c : std_logic_vector(3 downto 0) :=(others => '0');  --initializing count to zero.
begin
count <= c;
process(clk,reset)
begin
if(clk'event and clk='1') then
-- when count reaches its maximum(that is 15) reset it to 0
if(c = "1111") then
c <="0000";
end if;
c <= c+'1';  --increment count at every positive edge of clk.
end if;
if(reset='1') then  --when reset equal to '1' make count equal to 0.
c <=(others => '0');  -- c ="0000"
end if;
end process;
end Behavioral;
 
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;

-- entity declaration for your testbench.Dont declare any ports here
ENTITY test_tb IS
END test_tb;

ARCHITECTURE behavior OF test_tb IS
   -- Component Declaration for the Unit Under Test (UUT)
    COMPONENT test  --'test' is the name of the module needed to be tested.
--just copy and paste the input and output ports of your module as such.
    PORT(
         clk : IN  std_logic;
         count : OUT  std_logic_vector(3 downto 0);
         reset : IN  std_logic
        );
    END COMPONENT;
   --declare inputs and initialize them
   signal clk : std_logic := '0';
   signal reset : std_logic := '0';
   --declare outputs and initialize them
   signal count : std_logic_vector(3 downto 0);
   -- Clock period definitions
   constant clk_period : time := 1 ns;
BEGIN
    -- Instantiate the Unit Under Test (UUT)
   uut: test PORT MAP (
         clk => clk,
          count => count,
          reset => reset
        );      

   -- Clock process definitions( clock with 50% duty cycle is generated here.
   clk_process :process
   begin
        clk <= '0';
        wait for clk_period/2;  --for 0.5 ns signal is '0'.
        clk <= '1';
        wait for clk_period/2;  --for next 0.5 ns signal is '1'.
   end process;
   -- Stimulus process
  stim_proc: process
   begin        
        wait for 7 ns;
        reset <='1';
        wait for 3 ns;
        reset <='0';
        wait for 17 ns;
        reset <= '1';
        wait for 1 ns;
        reset <= '0';
        wait;
  end process;

END;
2. If multiple clocks are to be generated with different frequencies, then clock generation can be simplified if a procedure is called as concurrent procedure call.
library ieee;
use ieee.std_logic_1164.all;

entity tb is
end entity;

architecture sim of tb is

  -- Procedure for clock generation
  procedure clk_gen(signal clk : out std_logic; constant FREQ : real) is
    constant PERIOD    : time := 1 sec / FREQ;        -- Full period
    constant HIGH_TIME : time := PERIOD / 2;          -- High time
    constant LOW_TIME  : time := PERIOD - HIGH_TIME;  -- Low time; always >= HIGH_TIME
  begin
    -- Check the arguments
    assert (HIGH_TIME /= 0 fs) report "clk_plain: High time is zero; time resolution to large for frequency" severity FAILURE;
    -- Generate a clock cycle
    loop
      clk <= '1';
      wait for HIGH_TIME;
      clk <= '0';
      wait for LOW_TIME;
    end loop;
  end procedure;

  -- Clock frequency and signal
  signal clk_166 : std_logic;
  signal clk_125 : std_logic;

begin

  -- Clock generation with concurrent procedure call
  clk_gen(clk_166, 166.667E6);  -- 166.667 MHz clock
  clk_gen(clk_125, 125.000E6);  -- 125.000 MHz clock

  -- Time resolution show
  assert FALSE report "Time resolution: " & time'image(time'succ(0 fs)) severity NOTE;
end architecture;

Simulation Overview
During HDL simulation, the simulator software verifies the functionality and timing of your design or portion of your design. The simulator interprets VHDL or Verilog code into circuit functionality and displays logical results of the described HDL to determine correct circuit operation. Simulation allows you to create and verify complex functions in a relatively small amount of time.

Simulation takes place at several points in the design flow. It is one of the first steps after design entry and one of the last steps after implementation, as part of verifying the end functionality and performance of the design. Simulation is an iterative process, which may require repeating until both design functionality and timing is met. For a typical design, simulation comprises the following high-level steps:
  1. Compilation of the simulation libraries
  2. Creation of the design and test bench  
  3. Functional simulation
  4. Implementation of the design and creation of the timing simulation netlist
  5. Timing simulation
Functional Simulation
After you compile the simulation libraries and create the test bench and design code, you can perform functional simulation on the design.

Functional simulation is an iterative process, which may require multiple simulations to achieve the desired end functionality of the design.

Once the desired functionality is achieved, use the output data to create a self-checking testbench. ISim has the capability to generate a self-checking testbench. It is important to set up the proper infrastructure for this type of simulation; spending time up front may save time in back end design debugging.

The general recommendations are:
  •  Spend time up front to create a good test bench.
Creating a test bench that you can use for both functional and timing simulation can save time.
  •  Ensure that your libraries are properly compiled and mapped.
If your design includes Xilinx CORE Generator cores, make sure that your libraries are properly compiled and mapped to the simulator. If you are using the ISim or the ModelSim Xilinx Edition simulator, this is automatically done for you.
  •  Automate the compilation and elaboration simulation steps.
When you invoke the simulator from within Project Navigator, the ISE® tools automatically run these steps. If you are running the simulator outside of Project Navigator, it is recommended that you create a script or use another method to automate these steps. 
  •  Customize the simulator interface to present the information needed to debug the design.
You may want to include the information console, the structure or hierarchy view, and the waveform viewer as well as other facilities to evaluate the simulation. Customization can improve the simulation experience and can be tied into the automation of the compilation and elaboration steps.
If you are using a waveform viewer as a part of simulation debugging, organize the waveform view to display the proper signals in the proper order with the proper radices. This saves time and helps prevent confusion in interpreting simulation results.






No comments:

Post a Comment