2 * Copyright (C) 2012 Vermeer Manufacturing Co.
3 * License: GPLv3 with additional permissions (see README).
13 struct migensim_softc
{
14 struct ipc_softc
*ipc
;
18 static int h_go(void *user
)
20 struct migensim_softc
*sc
= (struct migensim_softc
*)user
;
25 static s_vpi_time zero_delay
= {
31 static int h_write(char *name
, int index
, int nchunks
, const unsigned char *chunks
, void *user
)
34 s_vpi_vecval vector
[64];
38 item
= vpi_handle_by_name(name
, NULL
);
40 fprintf(stderr
, "Attempted to write non-existing signal %s\n", name
);
43 if(vpi_get(vpiType
, item
) == vpiMemory
)
44 item
= vpi_handle_by_index(item
, index
);
48 assert(nchunks
<= 255);
53 for(i
=0;i
<nchunks
;i
++)
54 vector
[i
/4].aval
|= chunks
[i
] << 8*(i
% 4);
56 value
.format
= vpiVectorVal
;
57 value
.value
.vector
= vector
;
58 vpi_put_value(item
, &value
, &zero_delay
, vpiInertialDelay
);
63 static int h_read(char *name
, int index
, void *user
)
65 struct migensim_softc
*sc
= (struct migensim_softc
*)user
;
71 unsigned int vals
[64];
73 unsigned char chunks
[255];
75 item
= vpi_handle_by_name(name
, NULL
);
77 fprintf(stderr
, "Attempted to read non-existing signal %s\n", name
);
80 if(vpi_get(vpiType
, item
) == vpiMemory
)
81 item
= vpi_handle_by_index(item
, index
);
85 value
.format
= vpiVectorVal
;
86 vpi_get_value(item
, &value
);
87 size
= vpi_get(vpiSize
, item
);
88 nvals
= (size
+ 31)/32;
91 vals
[i
] = value
.value
.vector
[i
].aval
& ~value
.value
.vector
[i
].bval
;
92 nchunks
= (size
+ 7)/8;
93 assert(nchunks
<= 255);
94 for(i
=0;i
<nchunks
;i
++) {
97 chunks
[i
] = vals
[i
/4] & 0xff;
100 chunks
[i
] = (vals
[i
/4] & 0xff00) >> 8;
103 chunks
[i
] = (vals
[i
/4] & 0xff0000) >> 16;
106 chunks
[i
] = (vals
[i
/4] & 0xff000000) >> 24;
111 if(!ipc_read_reply(sc
->ipc
, nchunks
, chunks
)) {
112 perror("ipc_read_reply");
119 static int process_until_go(struct migensim_softc
*sc
)
125 r
= ipc_receive(sc
->ipc
);
132 static PLI_INT32
connect_calltf(PLI_BYTE8
*user
)
134 struct migensim_softc
*sc
= (struct migensim_softc
*)user
;
140 sys
= vpi_handle(vpiSysTfCall
, 0);
141 argv
= vpi_iterate(vpiArgument
, sys
);
142 item
= vpi_scan(argv
);
143 value
.format
= vpiStringVal
;
144 vpi_get_value(item
, &value
);
146 sc
->ipc
= ipc_connect(value
.value
.str
, h_go
, h_write
, h_read
, sc
);
147 if(sc
->ipc
== NULL
) {
148 perror("ipc_connect");
149 vpi_control(vpiFinish
, 1);
156 static PLI_INT32
tick_calltf(PLI_BYTE8
*user
)
158 struct migensim_softc
*sc
= (struct migensim_softc
*)user
;
161 if(!ipc_tick(sc
->ipc
)) {
163 vpi_control(vpiFinish
, 1);
164 ipc_destroy(sc
->ipc
);
168 r
= process_until_go(sc
);
170 vpi_control(vpiFinish
, r
== 2 ? 0 : 1);
171 ipc_destroy(sc
->ipc
);
179 static struct migensim_softc sc
;
181 static void simple_register(const char *tfname
, PLI_INT32 (*calltf
)(PLI_BYTE8
*))
183 s_vpi_systf_data tf_data
;
185 tf_data
.type
= vpiSysTask
;
186 tf_data
.tfname
= tfname
;
187 tf_data
.calltf
= calltf
;
188 tf_data
.compiletf
= NULL
;
190 tf_data
.user_data
= (void *)&sc
;
191 vpi_register_systf(&tf_data
);
194 static void migensim_register()
196 simple_register("$migensim_connect", connect_calltf
);
197 simple_register("$migensim_tick", tick_calltf
);
200 void (*vlog_startup_routines
[])() = {