Dismiss
InnovationQ will be updated on Sunday, Oct. 22, from 10am ET - noon. You may experience brief service interruptions during that time.
Browse Prior Art Database

A method of solving inter-thread races in hardware verification languages without creating inter-thread dependencies of execution.

IP.com Disclosure Number: IPCOM000175232D
Original Publication Date: 2008-Oct-06
Included in the Prior Art Database: 2008-Oct-06
Document File: 9 page(s) / 116K

Publishing Venue

IBM

Abstract

Disclosed is a new methodology or style of writing programs in OpenVera and System Verilog, which guaranties no races among the threads and moreover without the concurrent executional threads getting tangled into each other. The method relieves the driver threads (which update a variable or set of variables) from being forced to carry the load of maintaining the correct execution of the dependent threads (which read the the updated variables mentioned above) and thus eliminating the entanglements. The idea is not to allow any of the threads to control each other but to have a mechanism to control each and every thread in a different way.

This text was extracted from a PDF file.
This is the abbreviated version, containing approximately 21% of the total text.

Page 1 of 9

A method of solving inter-thread races in hardware verification languages without creating inter-thread dependencies of execution.

Authors -- Narendra K Rane, Animesh Khare

In this methodology, the zero time duration (zero simulation time) of clock edge is virtually divided into a number of time regions like T1, T2,... Tn (n can be specified by the user) where the time region Tn will get executed after Tn-1 and before Tn+1. The user will create the threads the way he/she wants and only use the blocking sync() system task calls on any of the regions to block the execution as user intends. So, according to the known dependencies, the user will use sync() system task on a time region Tk, for a thread which updates a variable or puts a packet into a queue, which will unblock only in region Tk while any dependent thread(s) will use sync() which will unblock only in region T(k+r) where r can be any positive number. Thus, all the dependent threads will execute only after the driver thread. This allows all the threads to be executed in the order intended by the user and keeping them from getting tangled with each other.

N

     o thread is required to use any other kind of blocking methods and is not required to ensure proper execution of any other thread. How the zero simulation time duration of the clock edge is virtually divided into multiple time regions is shown below. A pair of interlocked concurrent threads, named the arbiter and the reciprocator, is spawned in the very beginning of the verification program and it keeps running in back-ground of the user threads. These two threads which are interlocked with each other, trigger multiple events one after another in an order, while ensuring all the user threads which are to be executed in a particular time region, are executed on triggering of the respective events only. The two interlocked threads vise "The arbiter" thread and "the reciprocator" thread are shown below. Thus the pair of arbiter and reciprocator creates virtual time regions in which the user threads get executed.

The novel mechanism to write race-free program blocks without creating entangling of threads.
1. OpenVera version for the verification code that runs only on positive/negative edge of clock:

global event T00, Tm, Tmm, T1, T11, T2, T22, T3, T33, T4, T44; Fork
{ // The arbiter…

sync(ALL, T00);

while(1)

{

trigger(Tm, ONE

_

sync(ALL, Tmm);

trigger(T1, ONE

_

_

_

SHOT);

SHOT);

sync(ALL, T11);

trigger(T2, ONE

SHOT);

SHOT);

sync(ALL, T22);

trigger(T3, ONE

1

Page 2 of 9

sync(ALL, T33);

@(

posedge clock); // OR @(negedge clock);

}
}
{ // The reciprocator… trigger(T00, ONE

_

BLAST);

while(1)

{

sync(ALL, Tm);

trigger(Tmm, ONE

_

SHOT);

sync(ALL, T1);

trigger(T11, ONE

_

SHOT);

sync(ALL, T2);

trigger(T22, ONE

_

SHOT);

sync(ALL, T3);

trigger(T33, ONE

_

SHOT);

} }

join none

fork
{ // user thread P

sync(ALL, T1); // User code…
}
{ // user thread Q

sync(ALL, T2); // User code…
}
{ // user thread...