ASIC Verification: Simulator Interface

Monday, March 10, 2008

Simulator Interface

In this section, we are going to see how the specman elite 'e' simulator is interfaced with HDL simulator. Following are some of the features of specman elite 'e' simulator.

  • Specman knows and understands the current simulation time
  • Specman can read the values of the HDL signals and assign these signals with new values
  • Specman can wait for a specific signal to get a specific value when a specific event occurs

Any verification tool must be able to write data to DUT inputs or to internal memories, read data from DUT outputs or from internal signals such as state machine registers and respond to specific events that happen on the DUT interfaces.

Compiling 'e' files

First step for any test bench is to make sure that your e code is compilable, to check this, you need to execute command as below:

specman -c "load test1.e"

This will basically check your code of syntax, but will not check any null objects (no run time errors are checked).

Linking Specman Elite with Modelsim

Once we have checked syntax of 'e' code, we can proceed to linking. In order to run Specman Elite with ModelSim, you must load the ModelSim Specman Elite boot library into the simulator at run time. The boot library is available at:

$SPECMAN_HOME/platform/libmti_sn_boot.so

To load libmti_sn_boot.ext into the ModelSim simulator, type

vsim -c -pli $SPECMAN_HOME/platform/libmti_sn_boot.so


Connecting to HDL signals

Here are some guidelines that would help you to minimize the infiltration of HDL signal names into your e code:

(a) Always use relative HDL signal path names - changes in the DUT structure and hierarchy, are by far the most common case of signal names change. Therefore, you should never use a full path to access a specific signal. The use of e units would help you access HDL signals using relative path names.

(b) The actual name of an HDL signal should not be mentioned more than once in your code, at some point where you define this signal. In any other place you should access this signal using some sort of e element - a defined name, a string, or better yet, a port.

(c) Concentrate all specific references to HDL names in a single file.

Writing e code that complies with these three principles was greatly facilitated after ports were introduced into the language.

Here is an example that will clarify how this is done in e.
====================================================================
<'
unit hub_signal_map
{
// An event port emits an event whenever a change in the specified
// direction occurs on the signal that is connected to it.
clk_in : in event_port of bit is instance;
keep bind(clk_in, external);

// reset_n active low reset
reset_in : in simple_port of bit is instance;
keep bind(reset_in, external);

// Data input to the DUT - Bus
data_in : out simple_port of uint(bits :16) is instance;
keep bind(data_in, external);

nak_handshake : out simple_port of bit is instance;
keep bind(nak_handshake, external);

rx_valid : out simple_port of bit is instance;
keep bind(rx_valid, external);

rx_last_byte : out simple_port of bit is instance;
keep bind(rx_last_byte, external);

rx_bs_err : out simple_port of bit is instance;
keep bind(rx_bs_err, external);

// IN token from the DUT
in_token_out : in simple_port of bit is instance;
keep bind(in_token_out, external);

// OUT token from the DUT
out_token_out : in simple_port of bit is instance;
keep bind(out_token_out, external);

// SETUP token from the DUT
setup_token_out : in simple_port of bit is instance;
keep bind(setup_token_out, external);

// Invalid token from the DUT
invalid_token_out : in simple_port of bit is instance;
keep bind(invalid_token_out, external);

// pid_err token from the DUT
pid_error_out : in simple_port of bit is instance;
keep bind(pid_error_out, external);
};


unit hub_env
{
-- Instantiate hub_driver
hub_driver : hub_driver is instance;
keep hub_driver.hdl_path() == "~/pid_dec_TB";
-- Create hub_recevier
hub_receiver : hub_receiver is instance;
keep hub_receiver.hdl_path() == "~/pid_dec_TB";

hub_signal_map : hub_signal_map is instance;
// The port data of hub_signal_map will be connected to the hdl signal
// 'pid_dec_TB/rxvalid'.
// This is a concatenation of the unit hdl path ('pid_dec_TB') and of the signal
// name. The use of relative path names minimizes changes in case of a change
// in the DUT hierarchy. For example in order to change the signal name to
// 'pid_dec_TB/input_level/rxvalid' all you will need to change is the single line above.
keep hub_signal_map.rx_valid.hdl_path() == "rxvalid";

};
// End of unit

-- Create an instance of hub_env object in top level

extend sys {
hub_env : hub_env is instance;
};

'>
====================================================================
(a) is achieved by using units and their hdl_path() property.
(b) is achieved by using ports. You can see the the code uses only the internal names (the port names) and not the actual HDL names. The actual name appears only once where the port is connected to its corresponding HDL signal. Your topmost unit (in this case hub_env) will do quite well as a main depot for the actual connections to the HDL signals, hence achieving (c) as well.

Synchronization

Synchronizing Specman means coordinating its activities with the state of the simulator. Specman and the simulator work together - whenever the simulator reaches a certain time or the DUT arrives at a specific state, the simulator will pass the control over to Specman, so that Specman can do whatever you've told it that it should do. After Specman is done, it returns the control to the simulator, and wait for the next simulation event. Technically speaking, if anyone should care about that, the simulator hands Specman the control by calling a callback function via its PLI interface and it gets back the control when the callback function returns.


2 comments:

NAVANEETHA KRISHNAN said...

this notes is enough for theoretically in practical
i am facing problem to interface ncsim simulator with specman elite tool
at the time of driving it showing the below error msg.

Warning: No Simulator is attached.
Therefore, '@sim' and 'delay' temporal expressions will never occur.

Error: Specman run reached the tick_max configuration limit (10000)
without a call to stop_run().

can anyone tell me how to solve this problem

Saneel said...

we can do following

sys{

setup() is also{
set_config(run,tick_max,100000,exit_on,all);

};

}; //This increases the value of tick_max.