VCS 2.4.1 does not allow acc_set_value() to assign a value to a wire.
However, Verilog XL 1.7 and above allow the operation.
As I understand it, this was only done for internal use, but was semi-officially
anounced via the Talk-Verilog forum on version 1.8. The functionality never made
it into the PLI 1.0 IEEE standard so clone makers do not have to support it.
The VCS guys ignored every attempt of mine to make them adopt this capability, but other clones may support it.
It should however be in the PLI 2.0 IEEE standard, so if your clone supports it, you may need to look into switching to using PLI 2.0.
---
Solamente lo barato, se compra con el dinero.
____________________________________________________________________________
Marco Zelada, R&D, mze...@microchip.com, Tel: 602 786 7550, Fax: 786 7578 |
Microchip Technology Inc., 2355 W. Chandler Blvd., Chandler AZ, 85224, USA |
----------------------------------------------------------------------------
Force has the drawback that force overrides all other drivers.
The continuous assign interpretation allows using a PLI system task or
function to set up instance I/O port correspondences including inout
ports for a component modeled using the PLI 2.0 where all PLI 2.0 C call
vpi_put_value driving and vpi_get_value reading happens independent from
the system task or function invocation or connection changes using
PLI 2.0 callbacks. Execution of the system task or function just sets
up the model.
This semantic's is implemented in Pragmatic C's Pver simulator PLI 2.0
interface and at least so far no problems with this semantics has turned up.
/Steve
m...@webnexus.com (Michael McNamara) writes:
>In article <DqEL...@tarek.com> posted on Thu, 25 Apr 1996
>In article <4lo784$5...@titan.Microchip.COM> posted on 25 Apr 1996
>mze...@themis.mchip (Marco Zelada) writes:
>>
>> Verilog XL allows write to wires in only a limitted way, it only
>> really works 100 % of the time in noDelay mode, it will work most of
>> the time in inertial mode, but you take your chances of it core
>> dumping on you in any other mode.
>>
>> As I understand it, this was only done for internal use, but was
>> semi-officially anounced via the Talk-Verilog forum on version
>> 1.8. The functionality never made it into the PLI 1.0 IEEE standard
>> so clone makers do not have to support it.
>>
>> The VCS guys ignored every attempt of mine to make them adopt this
>> capability, but other clones may support it.
>>
>> It should however be in the PLI 2.0 IEEE standard, so if your clone
>> supports it, you may need to look into switching to using PLI 2.0.
>>
>acc_set_value() can be used to _force_ a value on a wire;
>First, it makes no sense to "write" a value to a wire. One is not
>allowed to write a value to a wire in procedural code either.
>module bar;
> wire [3:0] net;
> initial begin
> #20
> net = 4'bx01z; // illegal!!
> force net = 4'bx01z; // legal
> end
>endmodule
>Think of the use of acc_set_value() in the pli as if you are in
>procedural code: you can write to registers, you can assign/deassign
>registers, and you can force/release wires or registers.
>You could set up a force of the value x01z to a 4 bit wide wire named
>"net" in scope top.foo.bar roughly as follows: (Warning! code typed in
>on the fly!!)
>int force_top_foo_bar_net(){
> static s_setval_delay d = {{accRealTime},accForceFlag};
> static s_setval_value v = {accBinStrVal};
> handle w = acc_handle_by_name("top.foo.bar.net",NULL);
> value_s.value.str = "x01z";
> delay_s.time.real = 0.0;
> acc_set_value(w,&v,&d);
>}
>Some tools will require you to reduce the level of optimization in
>order to use this capability; however, they should not core dump.
>-mac
>--
>Michael McNamara
>Silicon Sorcery
>m...@mti.sgi.com
>m...@webnexus.com
--
Steve Meyer Phone: (415) 296-7017
Pragmatic C Software Corp. Fax: (415) 781-1116
220 Montgomery St., Suite 925 email: sjm...@crl.com
San Francisco, CA 94104
In article <4lp082$e...@crl8.crl.com> posted on 25 Apr 1996
sjm...@crl.com (Steve Meyer) writes:
>
> I disagree. I think it makes sense to assign to a wire using either
> the PLI 1.0 acc_set_value or the PLI 2.0 vpi_set_value.
> The obvious behavior is for the wire argument to have one added acc_set_value
> or vpi_set_value driver (semantics of a continuous assign). If the wire
> has other drivers, normal bus contention is used to determine wire value.
> Although the wire will probably appear as an argument to a system task
> or function at least for PLI 1.0, the system task or function should be
> thought of as a sort of software pod (like the old ICE microprocessor
> pods) that plugs into behavorial code. The vpi_set_value (or acc_set_value)
> assignment can be removed if needed by assigning value z.
You are welcome to disagree. You are also welcome to add
extensions to your implementation of the language. However, it is the
case that using acc_set_value() on a wire is only guaranteed by
IEEE-1364 to give the user undefined behavior. The acc_set_value is
analogous to behavioral assignments, which can be writes to register
class items, procedural assigns or deassigns of register class
objects, or forces/releases of register or net class objects.
The IEEE-1364 also defines a vpi_put_value(), which can be
used to assign (or schedule the assign of) a value to net, register,
integer, memory element, system function, or UDP class object, and has
all the semantics that you have described. Presumably this is what you
meant when you typed "vpi_set_value"?
Sorry, you are right. I assumed the acc_set_value routine has the same
semantics as vpi_put_value, but I did not look. My impression is that
the PLI 2.0 is intended over time to supercede PLI 1.0. Is that also
not true?
/Steve
> You are welcome to disagree. You are also welcome to add
>extensions to your implementation of the language. However, it is the
>case that using acc_set_value() on a wire is only guaranteed by
>IEEE-1364 to give the user undefined behavior. The acc_set_value is
>analogous to behavioral assignments, which can be writes to register
>class items, procedural assigns or deassigns of register class
>objects, or forces/releases of register or net class objects.
> The IEEE-1364 also defines a vpi_put_value(), which can be
>used to assign (or schedule the assign of) a value to net, register,
>integer, memory element, system function, or UDP class object, and has
>all the semantics that you have described. Presumably this is what you
>meant when you typed "vpi_set_value"?
> -mac
>--
>Michael McNamara
>Silicon Sorcery
>m...@mti.sgi.com
>m...@webnexus.com
Regards, Yehoshua
*****************************************************************
* Yehoshua Shoshan * tel int + 46 8 719 5422 *
* Ericsson Telecom AB * ECN 8509 5422 *
* AV/ETX/B/DGF 367:083 * Fax int + 46 8 727 4360 *
* Varuvagen 9 B * New Memo ETXT.ETXYESH *
* S-126 25 Alvsjo * New email etx...@etxb.ericsson.se *
* Sweden * *
*****************************************************************
In article <4m3qg9$n...@crl11.crl.com> posted on 29 Apr 1996
sjm...@crl.com (Steve Meyer) writes:
> My impression is that the PLI 2.0 is intended over time to supercede
> PLI 1.0. Is that also not true? /Steve
It was the intention of the creators of the Verilog Procedural
Interface to create a complete, comprehensive interface to the
information contained in a Verilog design, as well as the complete
capability to interact programmatically with a dynamic execution of a
design coded in the Verilog-HDL. Everything you can do in with acc
routines and the tf routines, can also be done with the vpi routines,
as well as more. In this it seems the goal was achieved.
However, this in itself is not enough to supersede a standard:
especially one that is ensconced in thousands of ASIC librarys, delay
calculators, test vector generation and application routines, waveform
viewers, model debuggers, model decompilers, cosimulation libraries,
and hardware interfaces, all which use strictly a subset of the acc
and tf routines.
As Yehoshua Shoshan indicates in another article, adoption of new
standard features also requires market pressure on vendors to
implement new features. It is relatively easy to get consensus on a
standard (actually its never _easy_) when you are documenting existing
practice, codifying a de facto standard; building new functionality at
the committee meeting (and getting it implemented) is a much more
difficult process.
Real concerns about the limitations to optimization posed by the vpi
routines were voiced by members of the IEEE-1364 committee (including
myself, I must add). However, folks said you couldn't compile the
language; folks said you couldn't infer cycle semantics from the
language; see where we are now!
Because of all of this, the IEEE 1364 committee directed the PLI task
force to include the vpi, acc and tf routines in the 1364 standard,
with no language about "deprecated interface" or "intended
supersedence".
1) The new 2.0 API is much easier and simpler to use.
PLI 2.0 has about 12 basic routines (not counting I/O and utility routines)
and 28 total and is documented by 27 pages in chapter 22 and 30
pages in chapter 23. The PLI 1.0 acc_ interface has over 100 routines
that have grown haphazardly over the years and takes 37 pages in chaper 18
and 174 pages in chapter 19 to document.
2) PLI 2.0 uses uniform basic objects
PLI 2.0 handles (objects) carry their own type information while
PLI 1.0 requires constant global context checking and setting.
Since PLI 1.0 acc_ routines grew over time each vendor implemented
the interface differently so different approaches are needed in each
for efficiency. PLI 2.0 also has basic property carrying time and value
objects.
3) It is not proven that PLI 2.0 interface is slower. At worst pragmas
could be defined to allow PLI 2.0 optimization just as such extra
lanaguage information is needed by C compilers to get maximum optimization.
Also just because XL was optimized for fast gate evaluation at the cost
of procedural execution, does not show that compiled simulation is faster
than interpretation in general. Most Verilog operations are canned
multi-instruction sequences that can be made to fit in caches better
in interpreters. There are now some new algorithm interpretive simulators
(such as Pragmatic C's Pver) but there has not been a widely circulated
bench mark comparison for two year.
I better stop before I turn into a fanatic <G>.
/Steve
In any case, the example below shows how easy it is to write models in C
that can be combined with any Verilog models (including the ability to
mix and match high level C and gate level ASICs). This simplest C
behavioral model works asynchronously on input change, but synchronous
C models are also possible.
---- cut here for ascync.c PLI 2.0 C model ----
/*
* simplest asynchronously driven not "CPU" model
*/
#include <stdio.h>
/* better to install the in include directory and use <> */
/* do not need the PLI 1.0 includes, but do not hurt */
#include "../pli_incs/veriuser.h"
#include "../pli_incs/pvtfuser.h"
#include "../pli_incs/vpi_user.h"
/* Pver specific include only defines vpiExprVar change submitted to P1364 */
#include "../pli_incs/pvpiuser.h"
extern void register_my_systfs();
extern int do_pli_not();
/* really need per instance for each of these probably in malloced storage */
static vpiHandle outh, inh, eventh;
static s_vpi_value inval;
static s_cb_data cbrec, ecbrec;
/*
* one call in procedural code to set up not model
*/
int pli_not()
{
int numargs;
vpiHandle href, iter, ref;
s_vpi_time tmptim;
s_vpi_value outval;
s_cb_data *cbp;
href = vpi_handle(vpiSysTfCall, NULL);
iter = vpi_iterate(vpiArgument, href);
/* maybe ... <code to check arguments (include bad_args label)> */
numargs = vpi_get(vpiSize, iter);
if ((ref = vpi_scan(iter)) == NULL)
{
bad_args:
/* need error message here */
return;
}
/* Pver LRM change to allow converting "real" expression object */
/* to vpiNet lvalue handle */
/* vpiExprVar needed since Pver has separate expression type object */
/* that must be converted to variable - needed for cross module */
/* references and change submitted to P1364x committee */
if ((outh = vpi_handle(vpiExprVar, ref)) == NULL) goto bad_args;
if ((ref = vpi_scan(iter)) == NULL) goto bad_args;
if ((inh = vpi_handle(vpiExprVar, ref)) == NULL) goto bad_args;
/* make sure output starts as x */
outval.format = vpiScalarVal;
outval.value.scalar = vpiX;
/* all values here can be freed on return */
vpi_put_value(outh, &outval, NULL, vpiNoDelay);
/* cb records must be in global storage because used inside PLI */
cbp = &cbrec;
cbp->reason = cbValueChange;
cbp->cb_rtn = do_pli_not;
cbp->obj = inh;
/* do not need to have input handle change time recorded */
tmptim.type = vpiSuppressTime;
cbp->time = &tmptim;
/* but need changed input value - records value on change */
inval.format = vpiScalarVal;
cbp->value = &inval;
cbp->user_data = NULL;
vpi_register_cb(cbp);
}
/*
* call back routine - called whenever not input changes (model goes here)
*/
int do_pli_not(cbp)
s_cb_data *cbp;
{
int outv, inv;
s_vpi_value outval;
s_vpi_time tmptim;
/* better would be to use callback value field */
inv = cbp->value->value.scalar;
if (inv == vpi1) outv = vpi0;
else if (inv == vpi0) outv = vpi1;
else outv = vpiX;
/* assume all nots have delay 5 - could be vpiNoDelay */
tmptim.type = vpiScaledRealTime;
tmptim.real = 5.0;
outval.format = vpiScalarVal;
outval.value.scalar = outv;
/* return event but not used in not version 1 */
/* could use eventh to implement CPU pin C code timing checks */
eventh = vpi_put_value(outh, &outval, &tmptim,
(vpiInertialDelay | vpiReturnEvent));
}
/*
* routine to build an error indication string
* I usually start by running under debugger with breakpoint here
*/
my_error_handler(cbp)
struct t_cb_data *cbp;
{
struct t_vpi_error_info einfotab;
struct t_vpi_error_info *einfop;
char s1[128];
einfop = &einfotab;
vpi_chk_error(einfop);
if (einfop->state == vpiCompile) strcpy(s1, "vpiCompile");
else if (einfop->state = vpiPLI) strcpy(s1, "vpiPLI");
else if (einfop->state = vpiPLI) strcpy(s1, "vpiRun");
else strcpy(s1, "**unknown**");
vpi_printf("**ERR(%s) %s (level %d) at **%s(%d):\n %s\n",
einfop->code, s1, einfop->level, einfop->file, einfop->line,
einfop->message);
/* if serious error give up */
if (einfop->level == vpiError || einfop->level == vpiSystem
|| einfop->level == vpiInternal)
{
vpi_printf("**FATAL: encountered error - giving up\n");
tf_dofinish();
}
}
void register_cbs()
{
vpiHandle href;
p_cb_data ecbp;
/* notice cb records must be in global storage */
ecbp = &ecbrec;
ecbp->reason = cbError;
ecbp->cb_rtn = my_error_handler;
ecbp->obj = NULL;
ecbp->time = NULL;
ecbp->value = NULL;
ecbp->user_data = NULL;
/* probably should check for error here */
if ((href = vpi_register_cb(ecbp)) == NULL)
vpi_printf("**ERR: can not regiser register error handler callback.\n");
}
void (*vlog_startup_routines[]) () =
{
register_my_systfs,
register_cbs,
0
};
void register_my_systfs()
{
p_vpi_systf_data systf_data_p;
static s_vpi_systf_data systf_data_list[] = {
{ vpiSysTask, 0, "$pli_not", pli_not, NULL, NULL, NULL },
{ 0, 0, NULL, NULL, NULL, NULL, NULL }
};
systf_data_p = &(systf_data_list[0]);
while (systf_data_p->type != 0) vpi_register_systf(systf_data_p++);
}
---- end of async.c ----
---- cut here for makefile ----
# makefile rules for linux - pverobj.o is pver including main
# veriuser.o is dummy PLI 1.0 file - replaced if tf_ systfs also used
async: async.o veriuser.o
$(CC) $(LFLAGS) ../linux/pverobj.o aysnc.o veriuser.o \
$(LIBS) -o async
async.o: async.c
$(CC) $(CFLAGS) -c async.c
---- end of makefile ----
---- verilog test of async.c not model file async.v ----
/*
* async driven not gate cpu PLI model .v file
*/
module top;
wire z;
reg a;
initial
begin
$monitor($stime,, "z=%b, a=%b", z, a);
$pli_not(z, a);
end
initial
begin
#10 a = 1'bz;
#10 a = 1;
#10 a = 0;
#10 a = 1;
// notice glitch that PLI model maybe should catch
#1 a = 0;
end
endmodule
---- end of async.v ----
---- Pver verilog.log output for "async async.v" ----
PVER_1.53_1 of 04/25/96 (Linux).
Copyright (c) 1991-1996 Pragmatic C Software Corp.
Licensed software containing confidential and proprietary
information belonging to Pragmatic C Software Corp.
Today is Mon Apr 29 22:09:17 1996.
LIC: Licensed to: "Linux test ---++x783????."
Compiling source file "async.v"
Highest level modules:
top
0 z=x, a=x
10 z=x, a=z
15 z=x, a=z
20 z=x, a=1
25 z=0, a=1
30 z=0, a=0
35 z=1, a=0
40 z=1, a=1
41 z=1, a=0
46 z=1, a=0
11 simulation events and 0 declarative immediate assigns processed.
12 behavioral statements executed (0 procedural suspends).
Times (in sec.): Translate 0.1, load/optimize 0.1, simulation 0.1.
There were 0 error(s), 0 warning(s), and 2 inform(s).
End of PVER_1.53_1 at Mon Apr 29 22:09:17 1996 (elapsed 0.2 seconds).
---- end of verilog.log file ----
m...@webnexus.com (Michael McNamara) writes:
OK. Thats true. However it is so much easy to use PLI2.0 that it makes it accessible even for HW design
teams. Maybe there should be a "professional PLI" for waveform designers etc, that is fast and
complicated and a "HW desginer's PLI" that is fast and uncomplicated for those who wants to use some
special C routines in their test benches.
>adoption of new standard features also requires market pressure on vendors.....
Tell your CAD vendor you want PLI2.0 in the next Verilog release.
Yehoshua
*****************************************************************
* Yehoshua Shoshan * tel int + 46 8 719 5422 *
* Ericsson Telecom AB * ECN 8509 5422 *
* AV/ETX/B/DGF 367:083 * Fax int + 46 8 719 ???? *