spin is an experimental project and far from beeing available for commercial usage. If you are interrested in spin: mailto://spin@toem.de.

Introducing Spin 3 - Processes

Processes in spin are represented by objects. So a process can have its own data and methods encapsulated in a class. Like in systemC there are 2 basic types of processes represented by 2 base classes.

  • Normal Process (similar to SC_METHOD)

  • Threaded Process (similar to SC_THREAD)

Adding processes

There are basically 3 different methods of adding a new process/ new processes to a module.

Anonymous processes

New processes can be easily defined as anonymous classes, deriving 1 or more given methods like below:

public class Generator extends Module {

	public IOut<Logic> out;

	public Generator(Module parent) {
		super(parent);

		new ThreadedProcess("Generator Process", this) {

			public void initialize() {
				out.init(Logic.FALSE);
			}

			public void run(IRunInfo info) {

				while (true) {
					sleep(Time.ns(100));
					out.write(Logic.TRUE);
					sleep(Time.ns(400));
					out.write(Logic.FALSE);
				}
			}
		};
	}
}
Process as inner classes

The definition of a class gives the option to control the process from within the module via new interfaces (in this case the setWaitTime method).

// Module with declared process class
public class Generator2 extends Module {

	// port
	public IOut<Logic> out;

	// Process class
	class GeneratorProcess extends ThreadedProcess {

		long waitTime = 400;

		public GeneratorProcess(String name, IModule module) {
			super(name, module);
		}

		public void setWaitTime(long time) {
			waitTime = time;
		}

		public void initialize() {
			out.init(Logic.FALSE);
		}

		public void run(IRunInfo info) {

			while (true) {
				log("loop");
				sleep(Time.ns(100));
				out.write(Logic.TRUE);
				sleep(Time.ns(waitTime));
				out.write(Logic.FALSE);
			}
		}
	}
	
	// create the process
	GeneratorProcess process = new GeneratorProcess(null,this);

	// Constructor
	public Generator2(String name,Module parent) {
		super(name,parent);
		
		process.setWaitTime(500);
		
	}
}
Processes from a library (other top-level class)

You may want to define processes independent from a module and re-use this process in different modules. In this example, the process "LGeneratorProcess" is defined in another top-level class. To embed the process to the module, it needs the connector as a parameter.

// Module with process from external lib
public class Generator3 extends Module {

	// port
	public IOut<Logic> out;
	
	// create the process
	LGeneratorProcess process = new LGeneratorProcess(null,this,out);

	// Constructor
	public Generator3(String name,Module parent) {
		super(name,parent);
		
		process.setWaitTime(500);			
	}
}

Controlling normal processes

Normal process are triggered by time or notification from a sensitivity object. The schedule method can be used from inside or outside the process to start the process at a certain point of time. A process can be scheduled multiple times. Once the progress is started, it runs until the end. Normal process can not wait or sleep.

// Simple Process
Process aProcess = new Process(null, this) {

	public void run(IRunInfo info) {
		log("run");
	}
};

aProcess.schedule(Time.ns(100));
aProcess.schedule(Time.ns(200));
Method Example Description
schedule(long delta) schedule(Time.ns(100) Schedule the process at current + delta
sensitive(ISensitivity... sensitivity) sensitive(in1.changed(),in2.changed()) Schedules the process to run, when given sensitivity triggers
insensitive(ISensitivity... sensitivity) insensitive(in2.changed()) Makes the process insensitive for given sensitivity

Controlling threaded processes

A threaded process starts at time 0 and continues until it is finished, interrupted by waits and sleep calls. The await method allows to wait for notification from a sensitivity object (e.g. port changed) whereas the sleep method suspends the process for a given time. Some await methods have additional timeout parameter to stop waiting after that time. 'Await' should not be mismatched with the standrad java 'wait' method. The methods wait and notify should never be used in processes, unless you know what you are doing.

public void run(IRunInfo info) {

	while (true) {
		log("loop");
		sleep(Time.ns(100));
		
		// wait
		await(in1.changed());
		out.write(Logic.TRUE);
		
		// wait with timeout
		await(Time.ns(20),in1.changed());
		out.write(Logic.X);
		
		// wait & explicit sensitive
		sensitive(in2.changed());
		await();
		insensitive(in2.changed());
		out.write(Logic.Z);

		// timeout only
		await(Time.ns(100));
		
		sleep(Time.ns(400));
		out.write(Logic.FALSE);
	}
}
Method Example Description
sleep(long time) sleep(Time.ns(100)) Suspends the process until current + time
await(ISensitivity... sensitivity) await(in2.changed()) Suspends the process until it gets notification from one enabled sensitivity object.
await(long timeout,ISensitivity... sensitivity) await(Time.ns(100),in2.changed()) Suspends the process until it gets notification from one enabled sensitivity object or time > current + timeout .
sensitive(ISensitivity... sensitivity) sensitive(in1.changed(),in2.changed()) Enables senstivitiy for the process
insensitive(ISensitivity... sensitivity) insensitive(in2.changed()) Disables senstivitiy for the process

The run info

Whenever a process is started or exits from waiting, the user can get additional information from the IRunInfo parameter:

  • The current time
  • The sensitivity object that triggered the process
  • Sync/Async information
public void run(IRunInfo info) {

	log(String.valueOf(info.getCurrentTime()));
	log(String.valueOf(info.isSync()));
	log(String.valueOf(info.getSensitivity()));
	
	while (true) {
		log("loop");
		sleep(Time.ns(100));

		// wait
		await(in1.changed());
		out.write(Logic.TRUE);
		
		log(String.valueOf(info.getSensitivity()));

Using time

Time information is always represented as a long value. Actual unit and conversion is handled by the class Time.

Method Example Description
Time.setUnit(Time unit) Time.setUnit(Time.NS) Sets the time units to be used for simulation.
Time.getUnit() Time.getUnit() Returns the current unit.
Time.ns(long time) sleep(Time.ns(100)) Converts ns value into current unit.
Time.fs(...) ... Time.s(...) Time.s(1) Converter methods for fs,ps,ns,us,ms,s.
Time.current()   Returns the current time. Prefer to use the IRunInfo method to get current time.

Using the init method

The init method of processes shall be used to:

  • Init connectors driven by the process
  • To setup sensitivity (usually for normal processes)
  • Optionally to schedule the process (normal processes only)
 new Process(null, this) {

	public void initialize() {
		out.init(0);
		sensitive(in1.changed(), in2.changed());
	}

	public void run(IRunInfo info) {

 

Print

User Rating: 0 / 5

Star InactiveStar InactiveStar InactiveStar InactiveStar Inactive